MeOS version 3.6.1086

This commit is contained in:
Erik Melin 2019-06-18 22:30:29 +02:00
parent 55d526c3e4
commit a4e2689418
43 changed files with 1142 additions and 492 deletions

View File

@ -135,9 +135,9 @@ void SportIdent::setCRC(BYTE *bf)
bf[len+3]=LOBYTE(crc); bf[len+3]=LOBYTE(crc);
} }
bool SportIdent::checkCRC(BYTE *bf) bool SportIdent::checkCRC(BYTE *bf, DWORD maxLen)
{ {
DWORD len=bf[1]; DWORD len=min(DWORD(bf[1]), maxLen);
WORD crc=calcCRC(bf, len+2); WORD crc=calcCRC(bf, len+2);
return bf[len+2]==HIBYTE(crc) && bf[len+3]==LOBYTE(crc); return bf[len+2]==HIBYTE(crc) && bf[len+3]==LOBYTE(crc);
@ -167,7 +167,7 @@ bool SportIdent::readSystemData(SI_StationInfo *si, int retry)
if (buff[0] == 0xFF && buff[1] == STX) if (buff[0] == 0xFF && buff[1] == STX)
offset++; offset++;
if (1){ if (1){
if (checkCRC(LPBYTE(buff+1 + offset))){ if (checkCRC(LPBYTE(buff+1 + offset), 100)){
si->data.resize(1); si->data.resize(1);
SI_StationData &da = si->data[0]; SI_StationData &da = si->data[0];
da.stationNumber=511 & MAKEWORD(buff[4 + offset], buff[3 + offset]); da.stationNumber=511 & MAKEWORD(buff[4 + offset], buff[3 + offset]);
@ -245,7 +245,7 @@ bool SportIdent::readSystemDataV2(SI_StationInfo &si)
int SportIdent::analyzeStation(BYTE *db, SI_StationData &si) { int SportIdent::analyzeStation(BYTE *db, SI_StationData &si) {
DWORD size = 0; DWORD size = 0;
DWORD addr = 0x70; DWORD addr = 0x70;
if (checkCRC(LPBYTE(db+1))) { if (checkCRC(LPBYTE(db+1), 256)) {
size = DWORD(db[2]) + 6; size = DWORD(db[2]) + 6;
bool dongle = db[0x11] == 0x6f && db[0x12] == 0x21; bool dongle = db[0x11] == 0x6f && db[0x12] == 0x21;
@ -385,6 +385,10 @@ bool SportIdent::openCom(const wchar_t *com)
si->data.clear(); si->data.clear();
if (si->ComPort == L"TEST") {
return true;
}
wstring comfile=wstring(L"//./")+com; wstring comfile=wstring(L"//./")+com;
si->hComm = CreateFile( comfile.c_str(), si->hComm = CreateFile( comfile.c_str(),
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
@ -510,6 +514,13 @@ bool SportIdent::openCom(const wchar_t *com)
SI_StationInfo *SportIdent::findStation(const wstring &com) SI_StationInfo *SportIdent::findStation(const wstring &com)
{ {
if (com == L"TEST" && n_SI_Info < 30) {
if (n_SI_Info == 0 || SI_Info[n_SI_Info - 1].ComPort != com) {
SI_Info[n_SI_Info].ComPort = com;
n_SI_Info++;
}
}
for(int i=0;i<n_SI_Info; i++) for(int i=0;i<n_SI_Info; i++)
if (com == SI_Info[i].ComPort) if (com == SI_Info[i].ComPort)
return &SI_Info[i]; return &SI_Info[i];
@ -583,7 +594,7 @@ int SportIdent::readByte(BYTE &byte, HANDLE hComm)
#ifdef DEBUG_SI2 #ifdef DEBUG_SI2
char t[64]; char t[64];
sprintf_s(t, 64, "read=%02X\n", (int)byte); sprintf_s(t, 64, "read=%02X\n", (int)byte);
OutputDebugString(t); debugLog(t);
#endif #endif
if (dwRead) if (dwRead)
return 1; return 1;
@ -636,12 +647,12 @@ int SportIdent::readBytes_delay(BYTE *byte, DWORD buffSize, DWORD len, HANDLE h
#ifdef DEBUG_SI2 #ifdef DEBUG_SI2
char t[64]; char t[64];
sprintf_s(t, 64, "retry=%d\n", d); sprintf_s(t, 64, "retry=%d\n", d);
OutputDebugString(t); debugLog(t);
for (int k = 0; k < read; k++) { for (int k = 0; k < read; k++) {
char t[64]; char t[64];
sprintf_s(t, 64, "mreadd=%02X\n", (int)byte[k]); sprintf_s(t, 64, "mreadd=%02X\n", (int)byte[k]);
OutputDebugString(t); debugLog(t);
} }
#endif #endif
@ -661,7 +672,7 @@ int SportIdent::readBytes(BYTE *byte, DWORD len, HANDLE hComm)
for (int k = 0; k < dwRead; k++) { for (int k = 0; k < dwRead; k++) {
char t[64]; char t[64];
sprintf_s(t, 64, "mread=%02X\n", (int)byte[k]); sprintf_s(t, 64, "mread=%02X\n", (int)byte[k]);
OutputDebugString(t); debugLog(t);
} }
#endif #endif
return dwRead; return dwRead;
@ -693,7 +704,7 @@ int SportIdent::readBytesDLE_delay(BYTE *byte, DWORD buffSize, DWORD len, HANDL
#ifdef DEBUG_SI2 #ifdef DEBUG_SI2
char t[64]; char t[64];
sprintf_s(t, 64, "retry=%d\n", d); sprintf_s(t, 64, "retry=%d\n", d);
OutputDebugString(t); debugLog(t);
#endif #endif
return read; return read;
@ -909,6 +920,45 @@ int SportIdent::MonitorTCPSI(WORD port, int localZeroTime)
return 1; return 1;
} }
bool SportIdent::MonitorTEST(SI_StationInfo &si)
{
int longSleepIter = 0;
while (true) {
if (testCards.empty())
return true;
TestCard tc = *testCards.begin();
testCards.erase(testCards.begin());
SICard card(ConvertedTimeStatus::Hour12);
card.StartPunch.Code = 1;
int t = card.StartPunch.Time = 3600*8 + rand()%1000;
card.FinishPunch.Code = 2;
card.FinishPunch.Time = card.StartPunch.Time + 1800 + rand() % 3600;
card.CardNumber = tc.cardNo;
for (size_t k = 0; k < tc.punches.size(); k++) {
card.Punch[k].Code = tc.punches[k];
int w = max<int>(1, tc.punches.size() - k - rand()%3);
t = card.Punch[k].Time = (card.FinishPunch.Time + t*w)/(w+1);
card.nPunch++;
}
addCard(card);
//Sleep(300 + rand()%600);
Sleep(0);
if (++longSleepIter > 20) {
Sleep(100 + rand() % 600);
longSleepIter = 0;
OutputDebugString(L"Long sleep\n");
}
}
OutputDebugString(L"--- Test Finished \n");
}
bool SportIdent::MonitorSI(SI_StationInfo &si) bool SportIdent::MonitorSI(SI_StationInfo &si)
{ {
HANDLE hComm=si.hComm; HANDLE hComm=si.hComm;
@ -942,7 +992,7 @@ bool SportIdent::MonitorSI(SI_StationInfo &si)
BYTE bf[32]; BYTE bf[32];
bf[0]=chRead; bf[0]=chRead;
readBytes(bf+1, 17, hComm); readBytes(bf+1, 17, hComm);
if (checkCRC(LPBYTE(bf))) if (checkCRC(LPBYTE(bf), 32))
{ {
WORD Station=MAKEWORD(bf[3], bf[2]); WORD Station=MAKEWORD(bf[3], bf[2]);
@ -1014,7 +1064,7 @@ bool SportIdent::MonitorSI(SI_StationInfo &si)
readBytes(bf+1, 10, hComm); readBytes(bf+1, 10, hComm);
//ReadByte(chRead); //ETX! //ReadByte(chRead); //ETX!
if (checkCRC(LPBYTE(bf))) if (checkCRC(LPBYTE(bf), 32))
getSI6DataExt(hComm); getSI6DataExt(hComm);
break; break;
@ -1024,7 +1074,7 @@ bool SportIdent::MonitorSI(SI_StationInfo &si)
bf[0]=0xE5; bf[0]=0xE5;
readBytes(bf+1, 10, hComm); readBytes(bf+1, 10, hComm);
if (checkCRC(LPBYTE(bf))) if (checkCRC(LPBYTE(bf), 32))
getSI5DataExt(hComm); getSI5DataExt(hComm);
break; break;
@ -1067,7 +1117,7 @@ bool SportIdent::MonitorSI(SI_StationInfo &si)
readBytes(bf+1, 10, hComm); readBytes(bf+1, 10, hComm);
//ReadByte(chRead); //ETX! //ReadByte(chRead); //ETX!
if (checkCRC(LPBYTE(bf))) if (checkCRC(LPBYTE(bf), 32))
getSI9DataExt(hComm); getSI9DataExt(hComm);
break; break;
@ -1163,7 +1213,7 @@ void SportIdent::getSI5DataExt(HANDLE hComm)
if (bf[0]==STX && bf[1]==0xB1) if (bf[0]==STX && bf[1]==0xB1)
{ {
if (checkCRC(bf+1)) if (checkCRC(bf+1, 254))
{ {
c[0]=ACK; c[0]=ACK;
WriteFile(hComm, c, 1, &written, NULL); WriteFile(hComm, c, 1, &written, NULL);
@ -1186,7 +1236,7 @@ void SportIdent::getSI6DataExt(HANDLE hComm)
BYTE c[16]; BYTE c[16];
// STX, 0xE1, 0x01, BN, CRC1, // STX, 0xE1, 0x01, BN, CRC1,
//CRC0, ETX //CRC0, ETX
OutputDebugString(L"STARTREAD EXT-"); debugLog(L"STARTREAD EXT-");
int blocks[7]={0,6,7,2,3,4,5}; int blocks[7]={0,6,7,2,3,4,5};
DWORD written=0; DWORD written=0;
@ -1211,13 +1261,13 @@ void SportIdent::getSI6DataExt(HANDLE hComm)
int read=readBytes(bf, 128+9, hComm); int read=readBytes(bf, 128+9, hComm);
if (read==0) { if (read==0) {
OutputDebugString(L"TIMING"); debugLog(L"TIMING");
Sleep(300); Sleep(300);
read = readBytes(bf, 128+9, hComm); read = readBytes(bf, 128+9, hComm);
} }
if (bf[0]==STX && bf[1]==0xE1) { if (bf[0]==STX && bf[1]==0xE1) {
if (checkCRC(bf+1)) { if (checkCRC(bf+1, 250)) {
memcpy(b+k*128, bf+6, 128); memcpy(b+k*128, bf+6, 128);
LPDWORD ptr = LPDWORD(bf + 6); LPDWORD ptr = LPDWORD(bf + 6);
@ -1225,12 +1275,12 @@ void SportIdent::getSI6DataExt(HANDLE hComm)
break; //No need to read more break; //No need to read more
} }
else { else {
OutputDebugString(L"-FAIL-"); debugLog(L"-FAIL-");
return; return;
} }
} }
else { else {
OutputDebugString(L"-FAIL-"); debugLog(L"-FAIL-");
return; return;
} }
} }
@ -1239,7 +1289,7 @@ void SportIdent::getSI6DataExt(HANDLE hComm)
c[0]=ACK; c[0]=ACK;
WriteFile(hComm, c, 1, &written, NULL); WriteFile(hComm, c, 1, &written, NULL);
OutputDebugString(L"-ACK-"); debugLog(L"-ACK-");
SICard card(ConvertedTimeStatus::Hour24); SICard card(ConvertedTimeStatus::Hour24);
getCard6Data(b, card); getCard6Data(b, card);
@ -1253,7 +1303,7 @@ void SportIdent::getSI9DataExt(HANDLE hComm)
BYTE c[16]; BYTE c[16];
// STX, 0xE1, 0x01, BN, CRC1, // STX, 0xE1, 0x01, BN, CRC1,
//CRC0, ETX //CRC0, ETX
OutputDebugString(L"STARTREAD9 EXT-"); debugLog(L"STARTREAD9 EXT-");
int blocks_8_9_p_t[2]={0,1}; int blocks_8_9_p_t[2]={0,1};
int blocks_10_11_SIAC[5]={0,4,5,6,7}; int blocks_10_11_SIAC[5]={0,4,5,6,7};
@ -1281,13 +1331,13 @@ void SportIdent::getSI9DataExt(HANDLE hComm)
int read=readBytes(bf, 128+9, hComm); int read=readBytes(bf, 128+9, hComm);
if (read==0) { if (read==0) {
OutputDebugString(L"TIMING"); debugLog(L"TIMING");
Sleep(300); Sleep(300);
read = readBytes(bf, 128+9, hComm); read = readBytes(bf, 128+9, hComm);
} }
if (bf[0]==STX && bf[1]==0xEf) { if (bf[0]==STX && bf[1]==0xEf) {
if (checkCRC(bf+1)) { if (checkCRC(bf+1, 200)) {
memcpy(b+k*128, bf+6, 128); memcpy(b+k*128, bf+6, 128);
if (k == 0) { if (k == 0) {
@ -1304,12 +1354,12 @@ void SportIdent::getSI9DataExt(HANDLE hComm)
} }
else { else {
OutputDebugString(L"-FAIL-"); debugLog(L"-FAIL-");
return; return;
} }
} }
else { else {
OutputDebugString(L"-FAIL-"); debugLog(L"-FAIL-");
return; return;
} }
} }
@ -1318,7 +1368,7 @@ void SportIdent::getSI9DataExt(HANDLE hComm)
c[0]=ACK; c[0]=ACK;
WriteFile(hComm, c, 1, &written, NULL); WriteFile(hComm, c, 1, &written, NULL);
OutputDebugString(L"-ACK-"); debugLog(L"-ACK-");
SICard card(ConvertedTimeStatus::Hour24); SICard card(ConvertedTimeStatus::Hour24);
if (getCard9Data(b, card)) if (getCard9Data(b, card))
@ -1333,7 +1383,7 @@ bool SportIdent::readSI6Block(HANDLE hComm, BYTE *data)
int read=readBytesDLE(bf, 4, hComm); int read=readBytesDLE(bf, 4, hComm);
if (read==0){ if (read==0){
OutputDebugString(L"TIMING"); debugLog(L"TIMING");
Sleep(1000); Sleep(1000);
read=readBytesDLE(bf, 4, hComm); read=readBytesDLE(bf, 4, hComm);
} }
@ -1369,7 +1419,7 @@ void SportIdent::getSI6Data(HANDLE hComm)
BYTE c[16]; BYTE c[16];
// STX, 0xE1, 0x01, BN, CRC1, // STX, 0xE1, 0x01, BN, CRC1,
//CRC0, ETX //CRC0, ETX
OutputDebugString(L"STARTREAD-"); debugLog(L"STARTREAD-");
//int blocks[3]={0,6,7}; //int blocks[3]={0,6,7};
DWORD written=0; DWORD written=0;
@ -1390,7 +1440,7 @@ void SportIdent::getSI6Data(HANDLE hComm)
if (!readSI6Block(hComm, b+k*128)) { if (!readSI6Block(hComm, b+k*128)) {
if (k<=2) { if (k<=2) {
OutputDebugString(L"-FAIL-"); debugLog(L"-FAIL-");
return; return;
} }
else else
@ -1418,7 +1468,7 @@ void SportIdent::getSI6Data(HANDLE hComm)
c[0]=ACK; c[0]=ACK;
WriteFile(hComm, c, 1, &written, NULL); WriteFile(hComm, c, 1, &written, NULL);
OutputDebugString(L"-ACK-"); debugLog(L"-ACK-");
SICard card(ConvertedTimeStatus::Hour24); SICard card(ConvertedTimeStatus::Hour24);
getCard6Data(b, card); getCard6Data(b, card);
@ -1688,7 +1738,8 @@ bool SportIdent::getCard6Data(BYTE *data, SICard &card)
} }
string2Wide(lastNameByte, lastName); string2Wide(lastNameByte, lastName);
wcsncpy_s(card.lastName, lastName.c_str(), 20); wcsncpy(card.lastName, lastName.c_str(), 20);
card.lastName[20] = 0;
memcpy(firstNameByte, data+32+20, 20); memcpy(firstNameByte, data+32+20, 20);
firstNameByte[20] = 0; firstNameByte[20] = 0;
@ -1698,7 +1749,8 @@ bool SportIdent::getCard6Data(BYTE *data, SICard &card)
} }
string2Wide(firstNameByte, firstName); string2Wide(firstNameByte, firstName);
wcsncpy_s(card.firstName, firstName.c_str(), 20); wcsncpy(card.firstName, firstName.c_str(), 20);
card.firstName[20] = 0;
data+=128-16; data+=128-16;
@ -1974,20 +2026,29 @@ void start_si_thread(void *ptr)
si->Current_SI_Info=0; si->Current_SI_Info=0;
LeaveCriticalSection(&si->SyncObj); LeaveCriticalSection(&si->SyncObj);
try {
if (si_info.ComPort == L"TCP") { if (si_info.ComPort == L"TCP") {
si->MonitorTCPSI(si_info.tcpPort, si_info.localZeroTime); si->MonitorTCPSI(si_info.tcpPort, si_info.localZeroTime);
} }
else if (si_info.ComPort == L"TEST") {
si->MonitorTEST(si_info);
}
else { else {
if (!si_info.hComm) MessageBox(NULL, L"ERROR", 0, MB_OK); if (!si_info.hComm) MessageBox(NULL, L"ERROR", 0, MB_OK);
si->MonitorSI(si_info); si->MonitorSI(si_info);
} }
} }
catch (...) {
return;
}
}
void SportIdent::startMonitorThread(const wchar_t *com) void SportIdent::startMonitorThread(const wchar_t *com)
{ {
SI_StationInfo *si = findStation(com); SI_StationInfo *si = findStation(com);
if (si && (si->hComm || si->ComPort==L"TCP")) if (si && (si->hComm || si->ComPort==L"TCP" || si->ComPort == L"TEST"))
{ {
if (si->ComPort==L"TCP") if (si->ComPort==L"TCP")
tcpPortOpen=0; tcpPortOpen=0;
@ -2366,3 +2427,11 @@ void SICard::deserializePunches(const string &arg) {
if (out.size() == 1) if (out.size() == 1)
punchOnly = true; punchOnly = true;
} }
void SportIdent::addTestCard(int cardNo, const vector<int> &punches) {
testCards.emplace(cardNo, punches);
}
void SportIdent::debugLog(const wchar_t *msg) {
}

View File

@ -9,6 +9,8 @@
#pragma once #pragma once
#endif // _MSC_VER > 1000 #endif // _MSC_VER > 1000
#include <set>
/************************************************************************ /************************************************************************
MeOS - Orienteering Software MeOS - Orienteering Software
Copyright (C) 2009-2019 Melin Software HB Copyright (C) 2009-2019 Melin Software HB
@ -176,7 +178,7 @@ protected:
SI_StationInfo *Current_SI_Info; //Current SI_Info in use (for thread startup); SI_StationInfo *Current_SI_Info; //Current SI_Info in use (for thread startup);
WORD calcCRC(BYTE *data, DWORD length); WORD calcCRC(BYTE *data, DWORD length);
bool checkCRC(BYTE *bf); bool checkCRC(BYTE *bf, DWORD maxLen);
void setCRC(BYTE *bf); void setCRC(BYTE *bf);
bool getCard5Data(BYTE *data, SICard &card); bool getCard5Data(BYTE *data, SICard &card);
@ -204,12 +206,31 @@ protected:
volatile int tcpPortOpen; volatile int tcpPortOpen;
volatile unsigned int serverSocket; volatile unsigned int serverSocket;
bool MonitorTEST(SI_StationInfo &si);
bool MonitorSI(SI_StationInfo &si); bool MonitorSI(SI_StationInfo &si);
int MonitorTCPSI(WORD port, int localZeroTime); int MonitorTCPSI(WORD port, int localZeroTime);
struct TestCard {
int cardNo;
vector<int> punches;
bool operator<(const TestCard &c) const {
return cardNo < c.cardNo;
}
TestCard(int cardNo, const vector<int> &punches) : cardNo(cardNo),
punches(punches) {
}
};
set<TestCard> testCards;
public: public:
SI_StationInfo *findStation(const wstring &com); SI_StationInfo *findStation(const wstring &com);
/** Log debug data. */
void debugLog(const wchar_t *ptr);
void getInfoString(const wstring &com, vector<wstring> &info); void getInfoString(const wstring &com, vector<wstring> &info);
bool isPortOpen(const wstring &com); bool isPortOpen(const wstring &com);
bool autoDetect(list<int> &ComPorts); bool autoDetect(list<int> &ComPorts);
@ -220,6 +241,7 @@ public:
void addCard(const SICard &sic); void addCard(const SICard &sic);
void addPunch(DWORD Time, int Station, int Card, int Mode=0); void addPunch(DWORD Time, int Station, int Card, int Mode=0);
void addTestCard(int cardNo, const vector<int> &punches);
void EnumrateSerialPorts(list<int> &ports); void EnumrateSerialPorts(list<int> &ports);

View File

@ -406,7 +406,7 @@ int TabClass::multiCB(gdioutput &gdi, int type, void *data)
throw std::exception("Klassen finns ej."); throw std::exception("Klassen finns ej.");
int total, finished, dns; int total, finished, dns;
oe->getNumClassRunners(pc->getId(), 0, total, finished, dns); pc->getNumResults(0, total, finished, dns);
oEvent::PredefinedTypes newType = oEvent::PredefinedTypes(gdi.getSelectedItem("Predefined").first); oEvent::PredefinedTypes newType = oEvent::PredefinedTypes(gdi.getSelectedItem("Predefined").first);
int nstages = gdi.getTextNo("NStage"); int nstages = gdi.getTextNo("NStage");
@ -1865,14 +1865,14 @@ int TabClass::classCB(gdioutput &gdi, int type, void *data)
gdi.addString("", boldLarge, L"Dela klass: X#" + pc->getName()); gdi.addString("", boldLarge, L"Dela klass: X#" + pc->getName());
gdi.dropLine(); gdi.dropLine();
int tot, fin, dns; int tot, fin, dns;
oe->getNumClassRunners(pc->getId(), 0, tot, fin, dns); pc->getNumResults(0, tot, fin, dns);
if (pc->isQualificationFinalBaseClass()) { if (pc->isQualificationFinalBaseClass()) {
set<int> base; set<int> base;
pc->getQualificationFinal()->getBaseClassInstances(base); pc->getQualificationFinal()->getBaseClassInstances(base);
for (int i : base) { for (int i : base) {
if (pc->getVirtualClass(i)) { if (pc->getVirtualClass(i)) {
int tot2 = 0; int tot2 = 0;
oe->getNumClassRunners(pc->getVirtualClass(i)->getId(), 0, tot2, fin, dns); pc->getVirtualClass(i)->getNumResults(0, tot2, fin, dns);
tot += tot2; tot += tot2;
} }
} }
@ -2849,10 +2849,10 @@ void TabClass::multiCourse(gdioutput &gdi, int nLeg) {
} }
if (hasRelay) { if (hasRelay) {
headXPos[5]=gdi.getCX(); headXPos[5]=gdi.getCX();
gdi.addInput(string("RestartRope")+legno, L"", 5, MultiCB); gdi.addInput(string("RestartRope")+legno, L"", 7, MultiCB);
headXPos[6]=gdi.getCX(); headXPos[6]=gdi.getCX();
gdi.addInput(string("Restart")+legno, L"", 5, MultiCB); gdi.addInput(string("Restart")+legno, L"", 7, MultiCB);
} }
gdi.dropLine(-0.1); gdi.dropLine(-0.1);

View File

@ -2398,7 +2398,8 @@ void TabCompetition::loadAboutPage(gdioutput &gdi) const
"\n\nRussian Translation by Paul A. Kazakov and Albert Salihov" "\n\nRussian Translation by Paul A. Kazakov and Albert Salihov"
"\n\nOriginal French Translation by Jerome Monclard" "\n\nOriginal French Translation by Jerome Monclard"
"\n\nAdaption to French conditions and extended translation by Pierre Gaufillet" "\n\nAdaption to French conditions and extended translation by Pierre Gaufillet"
"\n\nCzech Translation by Marek Kustka"); "\n\nCzech Translation by Marek Kustka"
"\n\nHelp with English documentation: Torbjörn Wikström");
gdi.dropLine(); gdi.dropLine();
gdi.addString("", 0, "Det här programmet levereras utan någon som helst garanti. Programmet är "); gdi.addString("", 0, "Det här programmet levereras utan någon som helst garanti. Programmet är ");

View File

@ -939,7 +939,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
gdi.registerEvent("DataUpdate", ListsEventCB); gdi.registerEvent("DataUpdate", ListsEventCB);
gdi.setData("DataSync", 1); gdi.setData("DataSync", 1);
gdi.registerEvent(bi.id, ListsCB); gdi.registerEvent(bi.id, ListsCB);
currentList.getParam().pageBreak = true;
oe->generateMinuteStartlist(gdi); oe->generateMinuteStartlist(gdi);
baseButtons(gdi, 0); baseButtons(gdi, 0);
gdi.refresh(); gdi.refresh();

View File

@ -1568,13 +1568,15 @@ void TabRunner::showRunnerReport(gdioutput &gdi) {
} }
void TabRunner::generateRunnerReport(oEvent &oe, gdioutput &gdi, vector<pair<int, bool>> &runnersToReport) { void TabRunner::generateRunnerReport(oEvent &oe, gdioutput &gdi, vector<pair<int, bool>> &runnersToReport) {
oe.synchronizeList({ oListId::oLRunnerId, oListId::oLTeamId, oListId::oLPunchId });
gdi.fillDown(); gdi.fillDown();
cTeam t = 0; cTeam t = 0;
set<int> clsSet; set<int> clsSet;
for (size_t k = 0; k < runnersToReport.size(); k++) { for (size_t k = 0; k < runnersToReport.size(); k++) {
pRunner r = oe.getRunner(runnersToReport[k].first, 0); pRunner r = oe.getRunner(runnersToReport[k].first, 0);
if (!r)
continue;
clsSet.insert(r->getClassId(true)); clsSet.insert(r->getClassId(true));
if (r && r->getTeam()) { if (r && r->getTeam()) {
pClass cls = r->getClassRef(true); pClass cls = r->getClassRef(true);
@ -1676,7 +1678,7 @@ void TabRunner::runnerReport(oEvent &oe, gdioutput &gdi, int id, bool compact) {
if (r->statusOK()) { if (r->statusOK()) {
int total, finished, dns; int total, finished, dns;
oe.getNumClassRunners(r->getClassId(true), r->getLegNumber(), total, finished, dns); r->getClassRef(true)->getNumResults(r->getLegNumber(), total, finished, dns);
if (r->getTeam() == 0) { if (r->getTeam() == 0) {
gdi.addString("", fontMediumPlus, L"Tid: X, nuvarande placering Y/Z.#" + str + L"#" + r->getPlaceS() + L"#" + itow(finished)); gdi.addString("", fontMediumPlus, L"Tid: X, nuvarande placering Y/Z.#" + str + L"#" + r->getPlaceS() + L"#" + itow(finished));

View File

@ -48,6 +48,8 @@
#include "recorder.h" #include "recorder.h"
#include "autocomplete.h" #include "autocomplete.h"
constexpr bool addTestPort = false;
TabSI::TabSI(oEvent *poe):TabBase(poe), activeSIC(ConvertedTimeStatus::Unknown) { TabSI::TabSI(oEvent *poe):TabBase(poe), activeSIC(ConvertedTimeStatus::Unknown) {
editCardData.tabSI = this; editCardData.tabSI = this;
directEntryGUI.tabSI = this; directEntryGUI.tabSI = this;
@ -184,6 +186,8 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
if (lbi.text.substr(0, 3) == L"TCP") if (lbi.text.substr(0, 3) == L"TCP")
port = L"TCP"; port = L"TCP";
else if (lbi.text == L"TEST")
port = L"TEST";
if (gSI->isPortOpen(port)) { if (gSI->isPortOpen(port)) {
gSI->closeCom(port.c_str()); gSI->closeCom(port.c_str());
@ -211,6 +215,20 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
gdi.refresh(); gdi.refresh();
return 0; return 0;
} }
else if (port == L"TEST") {
vector<pRunner> runners;
oe->getRunners(0, 0, runners, false);
for (pRunner r : runners) {
if (r->getCard() || r->getCardNo() == 0)
continue;
vector<int> pl;
auto c = r->getCourse(true);
if (c) {
pl = c->getControlNumbers();
gSI->addTestCard(r->getCardNo(), pl);
}
}
}
gdi.addStringUT(0, lang.tl(L"Startar SI på ") + port + L"..."); gdi.addStringUT(0, lang.tl(L"Startar SI på ") + port + L"...");
gdi.refresh(); gdi.refresh();
@ -1567,6 +1585,9 @@ void TabSI::refillComPorts(gdioutput &gdi)
else else
gdi.addItem("ComPort", L"TCP"); gdi.addItem("ComPort", L"TCP");
if (addTestPort)
gdi.addItem("ComPort", L"TEST");
if (active){ if (active){
gdi.selectItemByData("ComPort", active); gdi.selectItemByData("ComPort", active);
gdi.setText("StartSI", lang.tl("Koppla ifrån")); gdi.setText("StartSI", lang.tl("Koppla ifrån"));

View File

@ -83,17 +83,21 @@ int TimeStamp::getAge() const
return CTime-Time; return CTime-Time;
} }
string TimeStamp::getStamp() const const string &TimeStamp::getStamp() const
{ {
if (stampCodeTime == Time)
return stampCode;
stampCodeTime = Time;
__int64 ft64=(__int64(Time)+minYearConstant*365*24*3600)*10000000; __int64 ft64=(__int64(Time)+minYearConstant*365*24*3600)*10000000;
FILETIME &ft=*(FILETIME*)&ft64; FILETIME &ft=*(FILETIME*)&ft64;
SYSTEMTIME st; SYSTEMTIME st;
FileTimeToSystemTime(&ft, &st); FileTimeToSystemTime(&ft, &st);
char bf[64];
sprintf_s(bf, 32, "%d%02d%02d%02d%02d%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
stampCode = bf;
char bf[32]; return stampCode;
sprintf_s(bf, "%d%02d%02d%02d%02d%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
return bf;
} }
wstring TimeStamp::getStampString() const wstring TimeStamp::getStampString() const
@ -109,7 +113,7 @@ wstring TimeStamp::getStampString() const
return bf; return bf;
} }
void TimeStamp::setStamp(string s) void TimeStamp::setStamp(const string &s)
{ {
if (s.size()<14) if (s.size()<14)
return; return;

View File

@ -30,12 +30,14 @@
************************************************************************/ ************************************************************************/
class TimeStamp class TimeStamp {
{
unsigned int Time; unsigned int Time;
mutable string stampCode;
mutable int stampCodeTime = 0;
public: public:
void setStamp(string s); void setStamp(const string &s);
string getStamp() const; const string &getStamp() const;
wstring getStampString() const; wstring getStampString() const;
int getAge() const; int getAge() const;
unsigned int getModificationTime() const {return Time;} unsigned int getModificationTime() const {return Time;}

View File

@ -723,13 +723,13 @@ int csvparser::selectPunchIndex(const wstring &competitionDate, const vector<wst
for (size_t k = 0; k < sp.size(); k++) { for (size_t k = 0; k < sp.size(); k++) {
processGeneralTime(sp[k], pt, date); processGeneralTime(sp[k], pt, date);
if (!pt.empty()) { if (!pt.empty()) {
if (ti == -1) { //if (ti == -1) {
ti = k; ti = k;
pt.swap(processedTime); pt.swap(processedTime);
} // }
else { // else {
return -1; // Not a unique time // return -1; // Not a unique time
} // }
if (!date.empty()) { if (!date.empty()) {
date.swap(processedDate); date.swap(processedDate);
di = k; di = k;

View File

@ -2428,3 +2428,7 @@ Lagändringblankett = Team Change Form
Mappa rootadresssen (http:///localhost:port/) till funktion = Map root address (http:///localhost:port/) to function Mappa rootadresssen (http:///localhost:port/) till funktion = Map root address (http:///localhost:port/) to function
ClassAvailableMaps = Available maps for class ClassAvailableMaps = Available maps for class
ClassTotalMaps = Total number of maps for class ClassTotalMaps = Total number of maps for class
Kunde inte öppna databasen (X) = Could not connect to database (X)
Kunde inte ladda upp löpardatabasen (X) = Could not upload runner database (X)
Runner check time = Runner check time
ClassNumEntries = Number of entries in class

View File

@ -1,4 +1,4 @@
encoding = ANSI encoding = ANSI
%s m = %s m %s m = %s m
%s meter = %s mètres %s meter = %s mètres
%s, block: %d = %s, bloc: %d %s, block: %d = %s, bloc: %d
@ -18,7 +18,7 @@ Alla = Tous
Alla banfiler = Tous les fichiers de circuit -oli Alla banfiler = Tous les fichiers de circuit -oli
Alla deltagare måste ha ett namn = Tous les concurrents doivent avoir un nom Alla deltagare måste ha ett namn = Tous les concurrents doivent avoir un nom
Alla fakturor = Toutes les factures Alla fakturor = Toutes les factures
Alla händelser = Tous les evenements Alla händelser = Tous les évènements
Alla lag måste ha ett namn = Toutes les équipes doivent avoir un nom Alla lag måste ha ett namn = Toutes les équipes doivent avoir un nom
Alla listor = Toutes les listes Alla listor = Toutes les listes
Alla lopp = Toutes les courses Alla lopp = Toutes les courses
@ -31,7 +31,7 @@ Ange om kontrollen fungerar och hur den ska användas = Indiquez si le boîtier
Ange startintervall för minutstart = Entrez l'intervalle de départ pour le départ Ange startintervall för minutstart = Entrez l'intervalle de départ pour le départ
Ange tiden relativt klassens första start = Entrez l'écart en temps par rapport au premier départ de la catégorie. Ange tiden relativt klassens första start = Entrez l'écart en temps par rapport au premier départ de la catégorie.
Anm. avg. = Tarifs d'inscription Anm. avg. = Tarifs d'inscription
Anm. avgift = Tarif d'incription Anm. avgift = Tarif d'inscription
Anm. datum = Date d'inscription Anm. datum = Date d'inscription
Anmäl = Entrer Anmäl = Entrer
Anmäl X = Entrer X pour la compétition Anmäl X = Entrer X pour la compétition
@ -56,7 +56,7 @@ Antal kartor = Nombre de cartes
Antal klasser = Nombre de catégorie Antal klasser = Nombre de catégorie
Antal löpare = Nombre de coureurs Antal löpare = Nombre de coureurs
Antal löpare på vanligaste banan X = Nombre de coureurs sur le circuit le plus utilisé: X Antal löpare på vanligaste banan X = Nombre de coureurs sur le circuit le plus utilisé: X
Antal misslyckade: X = Nombre d'inscriptions =erronnées: X Antal misslyckade: X = Nombre d'inscriptions
Antal startande per block = Nombre de départ par bloc Antal startande per block = Nombre de départ par bloc
Antal startande per intervall (inklusive redan lottade) = Nombre de départs par intervalle (y compris ceux déjà affectés) Antal startande per intervall (inklusive redan lottade) = Nombre de départs par intervalle (y compris ceux déjà affectés)
Antal sträckor = Nombre de branches Antal sträckor = Nombre de branches
@ -96,7 +96,7 @@ Avgörande händelser = Evènement décisif
Avgörs X = Prêt à X Avgörs X = Prêt à X
Avgörs kl = Prêt à Avgörs kl = Prêt à
Avläsning/radiotider = Lecture des puces/radio Avläsning/radiotider = Lecture des puces/radio
Avmarkera allt = Tout déselectionner Avmarkera allt = Tout désélectionner
Avrundad tävlingsavgift = Droits d'inscriptions, arrondis Avrundad tävlingsavgift = Droits d'inscriptions, arrondis
Avsluta = Quitter Avsluta = Quitter
Bad file format = Mauvais format Bad file format = Mauvais format
@ -139,7 +139,7 @@ BoldLarge = Gras, grand
BoldSmall = Gras, petit BoldSmall = Gras, petit
Bommade kontroller = Erreurs de poste Bommade kontroller = Erreurs de poste
Bomtid = Temps perdu Bomtid = Temps perdu
Bomtid (max) = Temsp perdu (max) Bomtid (max) = Temps perdu (max)
Bomtid (medel) = Temps perdu (moyenne) Bomtid (medel) = Temps perdu (moyenne)
Bomtid (median) = Temps perdu (médiane) Bomtid (median) = Temps perdu (médiane)
Bomtid: X = Temps perdu: X Bomtid: X = Temps perdu: X
@ -168,7 +168,7 @@ ClubName = Nom du club
ClubRunner = Club / Coureur ClubRunner = Club / Coureur
CmpDate = Date de la compétition CmpDate = Date de la compétition
CmpName = Nom de la compétition CmpName = Nom de la compétition
CourseClimb = Dénivellée circuit CourseClimb = Dénivelée circuit
CourseLength = Longueur circuit CourseLength = Longueur circuit
CourseName = Nom du circuit CourseName = Nom du circuit
CourseResult = Résultat du circuit CourseResult = Résultat du circuit
@ -178,12 +178,12 @@ Databasvarning: X = Base de donnée, warning : X
Datorröst som läser upp förvarningar = Annonce vocales des coureurs Datorröst som läser upp förvarningar = Annonce vocales des coureurs
Datum = Date Datum = Date
Decimalseparator = Séparateur décimal Decimalseparator = Séparateur décimal
DefaultFont = Formattage standard DefaultFont = Formatage standard
Dela = temps intermédiaires Dela = Scinder
Dela efter ranking = Temps intermédiaire par classement Dela efter ranking = Scinder par classement
Dela klass: X = Temps intermédiaires catégorie: X Dela klass: X = Scinder la catégorie: X
Dela klassen = Temps intermédiaires par catégorie Dela klassen = Scinder la catégorie
Dela klubbvis = Temps intermédiaire par club Dela klubbvis = Scinder par club
Deltagare = Coureurs Deltagare = Coureurs
Deltagare %d = Coureur %d Deltagare %d = Coureur %d
Deltagaren 'X' deltar i patrullklassen 'Y' men saknar patrull. Klassens start- och resultatlistor kan därmed bli felaktiga = Le coureur 'X' est dans la catégorie d'équipe 'Y', mais n'a pas d'équipe. Les résultats dans cette catégorie pourraient être faussés. Deltagaren 'X' deltar i patrullklassen 'Y' men saknar patrull. Klassens start- och resultatlistor kan därmed bli felaktiga = Le coureur 'X' est dans la catégorie d'équipe 'Y', mais n'a pas d'équipe. Les résultats dans cette catégorie pourraient être faussés.
@ -194,7 +194,7 @@ Denna etapps nummer = Numéro d'étape
Destinationskatalog = répertoire de destination Destinationskatalog = répertoire de destination
Det går endast att sätta in vakanser på sträcka 1 = Vous pouvez ajouter des places vacantes seulement sur le premier partiel Det går endast att sätta in vakanser på sträcka 1 = Vous pouvez ajouter des places vacantes seulement sur le premier partiel
Det här programmet levereras utan någon som helst garanti. Programmet är = Ce programme est fourni tel quel, sans aucune garantie. Ce programme est Det här programmet levereras utan någon som helst garanti. Programmet är = Ce programme est fourni tel quel, sans aucune garantie. Ce programme est
Direktanmälan = Saisie rapide Direktanmälan = Inscription rapide
Disk. = Disq. Disk. = Disq.
Distriktskod = Code de la Ligue Distriktskod = Code de la Ligue
Don't know how to align with 'X' = Impossible d'aligner avec 'X' Don't know how to align with 'X' = Impossible d'aligner avec 'X'
@ -223,7 +223,7 @@ Ej tidtagning = non chronométré
Ekonomisk sammanställning = Synthèse financière Ekonomisk sammanställning = Synthèse financière
Elektronisk = Electronique Elektronisk = Electronique
Elektronisk godkänd = Accepté électroniquement Elektronisk godkänd = Accepté électroniquement
Elit = Elite Elit = Élite
Elitavgift = Frais d'inscription pour les Elites Elitavgift = Frais d'inscription pour les Elites
Elitklasser = Catégorie Elite Elitklasser = Catégorie Elite
En gafflad sträcka = Un embranchement En gafflad sträcka = Un embranchement
@ -237,7 +237,7 @@ Etappresultat = Résultats des étapes
Eventorkoppling = Connexion à Eventor Eventorkoppling = Connexion à Eventor
Export av resultat/sträcktider = Export résultats / temps intermédiaires Export av resultat/sträcktider = Export résultats / temps intermédiaires
Exportera = Exporter Exportera = Exporter
Exportera / Säkerhetskopiera = Export / Backup Exportera / Säkerhetskopiera = Export / Sauvegarde
Exportera alla till HTML = Exporter tout en HTML Exportera alla till HTML = Exporter tout en HTML
Exportera datafil = Export des données Exportera datafil = Export des données
Exportera elektroniska fakturor = Exporter les factures électroniques Exportera elektroniska fakturor = Exporter les factures électroniques
@ -245,7 +245,7 @@ Exportera inställningar och löpardatabaser = Export de la configuration et des
Exportera löpardatabas = Export de la base des coureurs Exportera löpardatabas = Export de la base des coureurs
Exportera nu = Exporter maintenant Exportera nu = Exporter maintenant
Exportera på fil = Exporter dans un fichier Exportera på fil = Exporter dans un fichier
Exportera resultat på fil = Exporter les resultats dans un fichier Exportera resultat på fil = Exporter les résultats dans un fichier
Exportera startlista på fil = Exporter les listes de départ dans un fichier Exportera startlista på fil = Exporter les listes de départ dans un fichier
Exportera sträcktider = Export des temps intermédiaires Exportera sträcktider = Export des temps intermédiaires
Exportera tävlingsdata = Export des données Exportera tävlingsdata = Export des données
@ -273,7 +273,7 @@ Felst. = PM
Fil att exportera till = Fichier à exporter vers Fil att exportera till = Fichier à exporter vers
Fil: X = Nom de fichier: X Fil: X = Nom de fichier: X
Filnamn = Nom de fichier Filnamn = Nom de fichier
Filnamn (OCAD banfil) = Nom de fichier (circuitx OCAD) Filnamn (OCAD banfil) = Nom de fichier (circuit OCAD)
Filnamn IOF (xml) med klubbar = Nom de fichier IOF (xml) avec clubs Filnamn IOF (xml) med klubbar = Nom de fichier IOF (xml) avec clubs
Filnamn IOF (xml) med löpare = Nom de fichier IOF (xml) avec coureurs Filnamn IOF (xml) med löpare = Nom de fichier IOF (xml) avec coureurs
Filnamnet får inte vara tomt = Le nom de fichier ne peut être vide Filnamnet får inte vara tomt = Le nom de fichier ne peut être vide
@ -294,7 +294,7 @@ Flytta höger = Vers la droite
Flytta vänster = Vers la gauche Flytta vänster = Vers la gauche
Format = Format Format = Format
Formaterat webbdokument (html) = Document web (html) Formaterat webbdokument (html) = Document web (html)
Formateringsregler = Règles de formattage Formateringsregler = Règles de formatage
Formulärläge = Mode formulaire Formulärläge = Mode formulaire
Fortsätt = Continue Fortsätt = Continue
Fri anmälningsimport = Inscriptions en format libre Fri anmälningsimport = Inscriptions en format libre
@ -309,7 +309,7 @@ Följande deltagare har bytt klass = Les coureurs suivants ont changé de catég
Följande deltagare har bytt klass (inget totalresultat) = Les coureurs suivants ont changé de catégorie (pas de résultat total) Följande deltagare har bytt klass (inget totalresultat) = Les coureurs suivants ont changé de catégorie (pas de résultat total)
Följande deltagare har tilldelats en vakant plats = Les coureurs suivants ont pris une place vacante Följande deltagare har tilldelats en vakant plats = Les coureurs suivants ont pris une place vacante
Följande deltagare är anmälda till nästa etapp men inte denna = Les coureurs suivants sont enregistrés pour l'étape suivante mais pas celle-ci Följande deltagare är anmälda till nästa etapp men inte denna = Les coureurs suivants sont enregistrés pour l'étape suivante mais pas celle-ci
Följande deltagare är nyanmälda = Les coureurs suivants générès de nouvelles inscriptions Följande deltagare är nyanmälda = Les coureurs suivants générés de nouvelles inscriptions
Följande deltagare överfördes ej = Les coureurs suivant ont été ignorés Följande deltagare överfördes ej = Les coureurs suivant ont été ignorés
För att ändra måltiden måste löparens målstämplingstid ändras = Pour modifier le temps de course, l'heure de poinçonnage de l'arrivée doit être changée För att ändra måltiden måste löparens målstämplingstid ändras = Pour modifier le temps de course, l'heure de poinçonnage de l'arrivée doit être changée
För muspekaren över en markering för att få mer information = Survoler avec le pointeur de la souris une zone pour obtenir plus d'information För muspekaren över en markering för att få mer information = Survoler avec le pointeur de la souris une zone pour obtenir plus d'information
@ -418,9 +418,9 @@ Index = Index
Individuell = par catégorie Individuell = par catégorie
Individuell resultatlista, alla lopp = liste de résultat par nom, toute les courses Individuell resultatlista, alla lopp = liste de résultat par nom, toute les courses
Individuell resultatlista, sammanställning av flera lopp = liste de résultat par nom, résumé Individuell resultatlista, sammanställning av flera lopp = liste de résultat par nom, résumé
Individuell resultatlista, visst lopp = liste de résultat par nom, specifique Individuell resultatlista, visst lopp = liste de résultat par nom, spécifique
Individuell resultatlista, visst lopp (STOR) = liste de résultat par nom, specifique (GRAND) Individuell resultatlista, visst lopp (STOR) = liste de résultat par nom, spécifique (GRAND)
Individuell startlista, visst lopp = Liste de départ par nom, spécifi Individuell startlista, visst lopp = Liste de départ par nom, spécifique
Individuella deltagare = Coureurs individuels Individuella deltagare = Coureurs individuels
Individuella slutresultat = Résultats finaux individuels Individuella slutresultat = Résultats finaux individuels
Individuella totalresultat = Résultats totaux individuels Individuella totalresultat = Résultats totaux individuels
@ -460,7 +460,7 @@ Klart. X deltagare importerade = Terminé. X coureurs importés
Klart. X lag importerade = Terminé. X équipes importées Klart. X lag importerade = Terminé. X équipes importées
Klart. X patruller importerade = Terminé. X patrouille importées Klart. X patruller importerade = Terminé. X patrouille importées
Klart: alla klasser lottade = Tirage de toutes les catégories terminé Klart: alla klasser lottade = Tirage de toutes les catégories terminé
Klart: inga klasser behövde lottas = Terminé:aucune catégorie ne necessite un nouveau tirage Klart: inga klasser behövde lottas = Terminé : aucune catégorie ne nécessite un nouveau tirage
Klass = Catégorie Klass = Catégorie
Klass %d = Catégorie %d Klass %d = Catégorie %d
Klass saknad = Catégorie absente Klass saknad = Catégorie absente
@ -474,7 +474,7 @@ Klassen måste ha ett namn = La catégorie doit avoir un nom
Klassens bana = Circuit de la catégorie Klassens bana = Circuit de la catégorie
Klasser = Catégories Klasser = Catégories
Klasser (IOF, xml) = Catégories (IOF, xml) Klasser (IOF, xml) = Catégories (IOF, xml)
Klasser där nyanmälningar ska överföras = Catégories dans laquelle les nouvelles inscriptions vont être transferrées Klasser där nyanmälningar ska överföras = Catégories dans laquelle les nouvelles inscriptions vont être transférées
Klassinställningar = Configuration des catégories Klassinställningar = Configuration des catégories
Klassnamn = Nom de la catégorie Klassnamn = Nom de la catégorie
Klasstyp = Type de la catégorie Klasstyp = Type de la catégorie
@ -530,13 +530,13 @@ Källkatalog = Répertoire source
Kön = Sexe Kön = Sexe
Kör kontroll inför tävlingen = Vérification de la compétition Kör kontroll inför tävlingen = Vérification de la compétition
Ladda upp öppnad tävling på server = Upload de la compétition sur le serveur Ladda upp öppnad tävling på server = Upload de la compétition sur le serveur
Lag = Equipe Lag = Équipe
Lag %d = Equipe %d Lag %d = Équipe %d
Lag(flera) = Equipes Lag(flera) = Équipes
Laget 'X' saknar klass = L'équipe 'X' n'a pas de catégorie Laget 'X' saknar klass = L'équipe 'X' n'a pas de catégorie
Laget hittades inte = Equipe non trouvée Laget hittades inte = Équipe non trouvée
Lagnamn = Nom de l'équipe Lagnamn = Nom de l'équipe
Lagrade säkerhetskopior = Copies sauvergardées Lagrade säkerhetskopior = Copies sauvegardées
Land = Pays Land = Pays
LargeFont = Texte en grand LargeFont = Texte en grand
Latitud = Latitude Latitud = Latitude
@ -586,7 +586,7 @@ Lägger till klubbar = Ajout de club
Lägger till löpare = Ajout de participants Lägger till löpare = Ajout de participants
Längd (m) = Distance (m) Längd (m) = Distance (m)
Länk till resultatlistan = Lien vers les résultats Länk till resultatlistan = Lien vers les résultats
Länk till startlistan = Lien vers les listes de départr Länk till startlistan = Lien vers les listes de départ
Läs brickor = Lecture de puce Läs brickor = Lecture de puce
Läser klubbar = Lecture de clubs Läser klubbar = Lecture de clubs
Läser löpare = Lecture de coureurs Läser löpare = Lecture de coureurs
@ -653,7 +653,7 @@ Namn = Nom
Nationalitet = Nationalité Nationalitet = Nationalité
Nollställ avgifter = RAZ des frais d'inscription Nollställ avgifter = RAZ des frais d'inscription
Nollställ databaser = RAZ base de données Nollställ databaser = RAZ base de données
Nollställde avgift för X deltagare = Effacement des droits d'inscription pour X competiteur(s) Nollställde avgift för X deltagare = Effacement des droits d'inscription pour X coureur(s)
Nolltid = Heure zéro Nolltid = Heure zéro
None = Aucun None = Aucun
Normal = Normal Normal = Normal
@ -700,7 +700,7 @@ Omstart = Redémarrage
Omstart i stafettklasser = Redémarrage du relais Omstart i stafettklasser = Redémarrage du relais
Omstartstid = Heure de redémarrage Omstartstid = Heure de redémarrage
Omvänd jaktstart = Chasse inversée Omvänd jaktstart = Chasse inversée
Oparad = Non apairés Oparad = Non appairés
Operationen misslyckades = Echec de l'opération Operationen misslyckades = Echec de l'opération
Operationen stöds ej = Opération non supportée Operationen stöds ej = Opération non supportée
Optimerar startfördelning = Optimisation de la distribution des horaires de départ Optimerar startfördelning = Optimisation de la distribution des horaires de départ
@ -708,9 +708,9 @@ Ordinarie anmälningsdatum = Date de dernière inscription
Ordinarie avgift = Frais d'inscription normaux Ordinarie avgift = Frais d'inscription normaux
Organisation = Organisation Organisation = Organisation
Oväntad kontroll 'X' i bana Y = Poste 'X' non prévu dans le circuit Y Oväntad kontroll 'X' i bana Y = Poste 'X' non prévu dans le circuit Y
Packar upp löpardatabas = Expension de la base des coureurs Packar upp löpardatabas = Extension de la base des coureurs
Par- eller singelklass = Catégorie pour patrouille ou individuel Par- eller singelklass = Catégorie pour patrouille ou individuel
Para ihop = Apairage Para ihop = Appairage
Para ihop bricka X med en deltagare = Association de la puce X avec un coureur Para ihop bricka X med en deltagare = Association de la puce X avec un coureur
Parallell = Parallèle Parallell = Parallèle
PatrolClubNameNames = Clubs des coureurs (ou de la patrouille) PatrolClubNameNames = Clubs des coureurs (ou de la patrouille)
@ -757,7 +757,7 @@ Ranking (IOF, xml, csv) = Classement (IOF, xml, csv)
Rapport inför = Rapport pour Rapport inför = Rapport pour
Rapporter = Rapports Rapporter = Rapports
Rapportläge = Mode rapport Rapportläge = Mode rapport
Red. avg. efteranm = Retardat. réduit Red. avg. efteranm = Retardat. Réduit
Red. avgift = Réduit Red. avgift = Réduit
Redigera deltagaren = Editer le coureur Redigera deltagaren = Editer le coureur
Redigera lista = Editer la liste Redigera lista = Editer la liste
@ -780,6 +780,7 @@ Resultat - X = Résultats - X
Resultat banvis per klass = Résultat circuit-wise par catégorie Resultat banvis per klass = Résultat circuit-wise par catégorie
Resultat efter klass och bana - X = Résultats par catégorie et circuit - X Resultat efter klass och bana - X = Résultats par catégorie et circuit - X
Resultat efter sträcka %d = Résultats après le relayeur %d Resultat efter sträcka %d = Résultats après le relayeur %d
Resultat efter sträcka X = Résultats après le partiel X
Resultat efter sträckan = Résultats après le relayeur Resultat efter sträckan = Résultats après le relayeur
Resultat för ett visst lopp = Résultats pour une course donnée Resultat för ett visst lopp = Résultats pour une course donnée
Resultat lopp X - Y = Résultats pour la course X - Y Resultat lopp X - Y = Résultats pour la course X - Y
@ -795,11 +796,11 @@ Resultatlistor = Résultats
Resultatutskrift = Imprimer les résultats Resultatutskrift = Imprimer les résultats
Resultatutskrift / export = Imprimer / Exporter les résultats Resultatutskrift / export = Imprimer / Exporter les résultats
Rogaining = Course au score Rogaining = Course au score
Rogaining, individuell = Course au score indivduelle Rogaining, individuell = Course au score individuelle
Rogaining-poäng = Points (course au score) Rogaining-poäng = Points (course au score)
RogainingPunch = Poinçon (course au score) RogainingPunch = Poinçon (course au score)
Rubrik = Titre Rubrik = Titre
Rulla upp och ner automatiskt = Défillement vertical automatique Rulla upp och ner automatiskt = Défilement vertical automatique
Runner = Coureur Runner = Coureur
RunnerBib = Dossard du coureur RunnerBib = Dossard du coureur
RunnerCard = Puce du coureur RunnerCard = Puce du coureur
@ -833,7 +834,7 @@ RunnerTotalTime = Temps consolidé du coureur
RunnerTotalTimeAfter = Retard consolidé du coureur RunnerTotalTimeAfter = Retard consolidé du coureur
RunnerTotalTimeStatus = Temps / statut consolidé du coureur RunnerTotalTimeStatus = Temps / statut consolidé du coureur
RunnerUMMasterPoint = Master points Uppsala möte RunnerUMMasterPoint = Master points Uppsala möte
SI X inläst. Brickan tillhör Y som saknar klass = La puce X a été lue. La puce appartientt à Y, qui n'a pas de catégorie SI X inläst. Brickan tillhör Y som saknar klass = La puce X a été lue. La puce appartient à Y, qui n'a pas de catégorie
SI X inläst. Brickan är inte knuten till någon löpare (i skogen) = La puce X a été lue. La puce est associé à aucun coureur (en forêt) SI X inläst. Brickan är inte knuten till någon löpare (i skogen) = La puce X a été lue. La puce est associé à aucun coureur (en forêt)
SI X är redan inläst. Använd interaktiv inläsning om du vill läsa brickan igen = La puce X a déjà été lue. Utiliser la lecture interactive pour la relire. SI X är redan inläst. Använd interaktiv inläsning om du vill läsa brickan igen = La puce X a déjà été lue. Utiliser la lecture interactive pour la relire.
SI X är redan inläst. Ska den läsas in igen? = La puce X a déjà été lue. La relire ? SI X är redan inläst. Ska den läsas in igen? = La puce X a déjà été lue. La relire ?
@ -932,10 +933,10 @@ Stafett - sammanställning = Relais - résumé
Stafett - sträcka = Relais - relayeur Stafett - sträcka = Relais - relayeur
Stafett - total = Relais - total Stafett - total = Relais - total
Stafettklasser = Catégories pour le relais Stafettklasser = Catégories pour le relais
Stafettresultat, delsträckor = Résulats du relais, detail relayeurs Stafettresultat, delsträckor = Résultats du relais, détail relayeurs
Stafettresultat, lag = Résulats du relais, équipe Stafettresultat, lag = Résultats du relais, équipe
Stafettresultat, sträcka = Résulats du relais, par relayeur Stafettresultat, sträcka = Résultats du relais, par relayeur
Stafettresultat, sträcka (STOR) = Résulats du relais, par relayeur (GRAND) Stafettresultat, sträcka (STOR) = Résultats du relais, par relayeur (GRAND)
Start = Départ Start = Départ
Start nr = Départ no. Start nr = Départ no.
StartTime = Neure de départ, nom StartTime = Neure de départ, nom
@ -1018,7 +1019,7 @@ Synkronisera med Eventor = Synchroniser avec Eventor
Säkerhetskopiera = Sauvegarder/Enregistrer sous Säkerhetskopiera = Sauvegarder/Enregistrer sous
Sätt okända löpare utan registrering till <Ej Start> = Définir le statut <Did Not Start> pour les coureurs non enregistrés Sätt okända löpare utan registrering till <Ej Start> = Définir le statut <Did Not Start> pour les coureurs non enregistrés
Sätt som oparad = Non appairé Sätt som oparad = Non appairé
Sätter reptid (X) och omstartstid (Y) för = Appliquer le temps de corde [Applying rope time] (X) et l'heure de redémarrage (Y) pour Sätter reptid (X) och omstartstid (Y) för = Temps de corde (X) et heure de redémarrage (Y) appliqués pour
Sök = Rechercher Sök = Rechercher
Sök (X) = Rechercher (X) Sök (X) = Rechercher (X)
Sök deltagare = Rechercher un coureur Sök deltagare = Rechercher un coureur
@ -1035,7 +1036,7 @@ Ta bort stämpling = Supprimer le poinçon
Ta bort valda rader från tabellen (X) = Supprimer les lignes sélectionnées de la table (X) Ta bort valda rader från tabellen (X) = Supprimer les lignes sélectionnées de la table (X)
Tabell = Table Tabell = Table
Tabelläge = Mode table Tabelläge = Mode table
Team = Equipe Team = Équipe
TeamBib = Dossard de l'équipe TeamBib = Dossard de l'équipe
TeamClub = Club de l'équipe TeamClub = Club de l'équipe
TeamLegTimeAfter = Retard de l'équipe au relayeur TeamLegTimeAfter = Retard de l'équipe au relayeur
@ -1083,7 +1084,7 @@ Tilldelning av hyrbrickor = Affecter les puces louées
Tillgängliga automater = Services disponibles Tillgängliga automater = Services disponibles
Tillsatte vakans = Vacants utilisés Tillsatte vakans = Vacants utilisés
Tillsätt vakans = Remplir les vacants Tillsätt vakans = Remplir les vacants
Tillämpa parstart = Démarrer l'apairage Tillämpa parstart = Démarrer l'appairage
Tillåt decimaler = Autoriser les décimales Tillåt decimaler = Autoriser les décimales
Tillåt direktanmälan = Autoriser la saisie rapide Tillåt direktanmälan = Autoriser la saisie rapide
Tillåt valutauttryck med decimaler = Autoriser les expressions monétaires avec décimales Tillåt valutauttryck med decimaler = Autoriser les expressions monétaires avec décimales
@ -1157,7 +1158,7 @@ Vakanser och efteranmälda = Vacants et retardataires
Vakanser stöds ej i stafett = Les vacants ne sont pas supporté en relais Vakanser stöds ej i stafett = Les vacants ne sont pas supporté en relais
Vakant = Vacant Vakant = Vacant
Val av export = Choisir Export Val av export = Choisir Export
Valbar = Optionel Valbar = Optionnel
Vald bricka = Puce choisie Vald bricka = Puce choisie
Valuta = Devise Valuta = Devise
Valutakod = Code devise Valutakod = Code devise
@ -1188,7 +1189,7 @@ Vill du skapa en ny klass? = Voulez-vous créer une nouvelle catégorie ?
Vill du spara ändringar? = Voulez-vous enregistrer les changements ? Vill du spara ändringar? = Voulez-vous enregistrer les changements ?
Vill du verkligen radera alla starttider i X? = Voulez-vous vraiment effacer les horaires de départ dans X? Vill du verkligen radera alla starttider i X? = Voulez-vous vraiment effacer les horaires de départ dans X?
Vill du verkligen radera starttider i X klasser? = Voulez-vous vraiment effacer les horaires de départ de la catégorie X ? Vill du verkligen radera starttider i X klasser? = Voulez-vous vraiment effacer les horaires de départ de la catégorie X ?
Vill du verkligen radera tävlingen? = Sohaitez-vous supprimer la compétition ? Vill du verkligen radera tävlingen? = Souhaitez-vous supprimer la compétition ?
Vill du verkligen stänga MeOS? = Souhaitez-vous fermer MeOS ? Vill du verkligen stänga MeOS? = Souhaitez-vous fermer MeOS ?
Vill du verkligen ta bort laget? = Souhaitez-vous supprimer l'équipe ? Vill du verkligen ta bort laget? = Souhaitez-vous supprimer l'équipe ?
Vill du verkligen ta bort löparen? = Souhaitez-vous supprimer le coureur ? Vill du verkligen ta bort löparen? = Souhaitez-vous supprimer le coureur ?
@ -1210,13 +1211,13 @@ Visualisera startfältet = Visualisation des champs de départ
Vuxen = Adulte Vuxen = Adulte
Vuxenklasser = Catégories adultes Vuxenklasser = Catégories adultes
Vuxna = Adultes Vuxna = Adultes
Välj Spara för att lagra brickorna. Interaktiv inläsning är INTE aktiverad = Clicker sur <Enregistrer> pour enregistrer la puce. La lecture interactive n'est pas activée Välj Spara för att lagra brickorna. Interaktiv inläsning är INTE aktiverad = Cliquer sur <Enregistrer> pour enregistrer la puce. La lecture interactive n'est pas activée
Välj Spara för att lagra brickorna. Interaktiv inläsning är aktiverad = Clicker sur <Enregistrer> pour enregistrer les puces. La lecture interactive est activée Välj Spara för att lagra brickorna. Interaktiv inläsning är aktiverad = clinker sur <Enregistrer> pour enregistrer les puces. La lecture interactive est activée
Välj alla = Sélectionner tout Välj alla = Sélectionner tout
Välj alla klasser = Sélectionner toutes les catégories Välj alla klasser = Sélectionner toutes les catégories
Välj allt = Sélectionner tout Välj allt = Sélectionner tout
Välj automatiskt = Sélection automatique Välj automatiskt = Sélection automatique
Välj den etapp som föregår denna tävling = Sélectionner l'étape précdente Välj den etapp som föregår denna tävling = Sélectionner l'étape précédente
Välj den etapp som kommer efter denna tävling = Sélectionner l'étape suivante Välj den etapp som kommer efter denna tävling = Sélectionner l'étape suivante
Välj en vakant plats nedan = Choisissez une place vacante ci-dessous Välj en vakant plats nedan = Choisissez une place vacante ci-dessous
Välj ingen = Désélectionner Välj ingen = Désélectionner
@ -1238,7 +1239,7 @@ Välj skrivare = Choisir une imprimante
Välj tävling = Choisir une compétition Välj tävling = Choisir une compétition
Välj vilka klasser och kontroller du vill bevaka = Choisir les catégories et les postes que vous souhaitez observer Välj vilka klasser och kontroller du vill bevaka = Choisir les catégories et les postes que vous souhaitez observer
Välj vilka klasser och kontroller som bevakas = Sélectionner les catégories et les postes à observer Välj vilka klasser och kontroller som bevakas = Sélectionner les catégories et les postes à observer
Välj vilka kolumner du vill visa = Choisr les colonnes à afficher Välj vilka kolumner du vill visa = Choisir les colonnes à afficher
Välj vy = Choisir la vue Välj vy = Choisir la vue
Välkommen till MeOS = Bienvenue dans MeOS Välkommen till MeOS = Bienvenue dans MeOS
Vänligen betala senast = Merci de régler au plus tard le Vänligen betala senast = Merci de régler au plus tard le
@ -1271,7 +1272,7 @@ ask:addpunches = Aucune puce n'a été lue pour ce coureur. Voulez-vous ajouter
ask:changedclassfee = Le tarif a été modifié pour certaines catégories. Voulez-vous appliquer les nouveaux tarifs aux coureurs déjà présents dans ces catégories ?\n\nAttention: les frais d'inscription affectés manuellement seront écrasés. ask:changedclassfee = Le tarif a été modifié pour certaines catégories. Voulez-vous appliquer les nouveaux tarifs aux coureurs déjà présents dans ces catégories ?\n\nAttention: les frais d'inscription affectés manuellement seront écrasés.
ask:changedcmpfee = Les tarifs ont été modifiés. Voulez-vous appliquer les nouveaux tarifs aux coureurs et classes existantes ?\n\nAttention les frais d'inscription affectés manuellement seront écrasés. ask:changedcmpfee = Les tarifs ont été modifiés. Voulez-vous appliquer les nouveaux tarifs aux coureurs et classes existantes ?\n\nAttention les frais d'inscription affectés manuellement seront écrasés.
ask:firstasstart = Il existe des coureurs ayant des résultats pour ce circuit. Si vous utilisez le premier poste comme départ, les heures de départ seront écrasées.\n\nSouhaitez-vous continuer ? ask:firstasstart = Il existe des coureurs ayant des résultats pour ce circuit. Si vous utilisez le premier poste comme départ, les heures de départ seront écrasées.\n\nSouhaitez-vous continuer ?
ask:kiosk = Quand vous démarrez le kiosque de résultats, vous mettez MeOS dans un mode où il est uniquement possible d'afficher les résultats. Aucune autre opération n'est autorisée jusqu'à ce que le programme soir redémarré. S'il y a un boîtier SI actif raccordé à l'ordinateur, MeOS affichera automatiquement les résultats pour la dernière puce lue.\n\nVous devriez penser à protéger la base de donnée avec un mot de passe, si la diffusion est rendue publique.\n\nVoulez-vous démarrer la difusion des résultats ? ask:kiosk = Quand vous démarrez le kiosque de résultats, vous mettez MeOS dans un mode où il est uniquement possible d'afficher les résultats. Aucune autre opération n'est autorisée jusqu'à ce que le programme soir redémarré. S'il y a un boîtier SI actif raccordé à l'ordinateur, MeOS affichera automatiquement les résultats pour la dernière puce lue.\n\nVous devriez penser à protéger la base de donnée avec un mot de passe, si la diffusion est rendue publique.\n\nVoulez-vous démarrer la diffusion des résultats ?
ask:missingcourse = Des catégories (X) n'ont pas de circuit.\n\nMeOS utilise les circuits lors du tirage pour éviter que les coureurs ayant le même premier poste ne partent en même temps.\n\nVoulez-vous continuer tout de même ? ask:missingcourse = Des catégories (X) n'ont pas de circuit.\n\nMeOS utilise les circuits lors du tirage pour éviter que les coureurs ayant le même premier poste ne partent en même temps.\n\nVoulez-vous continuer tout de même ?
ask:overwrite_server = La compétition est déjà sur le serveur. Voulez-vous écraser la compétition présente sur le serveur ? ask:overwrite_server = La compétition est déjà sur le serveur. Voulez-vous écraser la compétition présente sur le serveur ?
ask:overwriteconfirm = Vous avez choisi d'écraser la compétition. Vérifiez que personne d'autre n'est connecté.\n\nSouhaitez vous continuer ? ask:overwriteconfirm = Vous avez choisi d'écraser la compétition. Vérifiez que personne d'autre n'est connecté.\n\nSouhaitez vous continuer ?
@ -1292,13 +1293,14 @@ fritt att använda och du är välkommen att distribuera det under vissa villkor
fyra = quatrième fyra = quatrième
går i mål på X plats med tiden Y = termine X en Y går i mål på X plats med tiden Y = termine X en Y
går i mål på X plats, efter Y, på tiden Z = termine X, derrière Y, en Z går i mål på X plats, efter Y, på tiden Z = termine X, derrière Y, en Z
går upp i delad ledning med tiden X = partage la tête de la course avec un temps de X går i mål på delad X plats med tiden Y = finit ex-aequo en Xème place, en Y
går upp i delad ledning med tiden X = partage la tête de la course en X
handskakning = authentification handskakning = authentification
har startat = a démarré har startat = a démarré
help:10000 = Un service dans MeOS est un petit programme qui, de temps à autre ou lorsque les données de la compétition changent, fait des choses automatiquement. help:10000 = Un service dans MeOS est un petit programme qui, de temps à autre ou lorsque les données de la compétition changent, fait des choses automatiquement.
help:12138 = Choisr une catégorie à fusionner avec la catégorie choisie. Si le tirage des catégories a été effectué, vous devez refaire un tirage, car les coureurs conservent leur horaire de départ. help:12138 = Choisir une catégorie à fusionner avec la catégorie choisie. Si le tirage des catégories a été effectué, vous devez refaire un tirage, car les coureurs conservent leur horaire de départ.
help:12290 = La compétition a été créée avec une autre version de MeOS et ne peut pas être ouverte depuis le serveur. Vous pouvez toutefois la compétition depuis un fichier. help:12290 = La compétition a été créée avec une autre version de MeOS et ne peut pas être ouverte depuis le serveur. Vous pouvez toutefois importer la compétition depuis un fichier.
help:12352 = Cette opération supprime le club que vous avez choisi (%s, id=%d) et déplace tous les coureurs de ce club vers le club que vous choisissez ci-dessous. L'opération ne peut être annulée. help:12352 = Cette opération supprime le club que vous avez choisi (%s, id
help:12662 = Ajoutez des postes en ajoutant une séquence de numéros de postes. Vous ne devez pas préciser l'arrivée. Exemple: 31, 50, 36, 50, 37, 100. help:12662 = Ajoutez des postes en ajoutant une séquence de numéros de postes. Vous ne devez pas préciser l'arrivée. Exemple: 31, 50, 36, 50, 37, 100.
help:14070 = Le port TCP est utilisé pour recevoir les poinçons par TCP depuis d'autres machines. Précisez le port utilisé. L'instant initial du protocole est 00:00:00. help:14070 = Le port TCP est utilisé pour recevoir les poinçons par TCP depuis d'autres machines. Précisez le port utilisé. L'instant initial du protocole est 00:00:00.
help:14343 = Une liste avec la puce lue est affichée. Pour affecter un coureur à une autre puce, double cliquez sur la puce ou le coureur que vous souhaitez déplacer. help:14343 = Une liste avec la puce lue est affichée. Pour affecter un coureur à une autre puce, double cliquez sur la puce ou le coureur que vous souhaitez déplacer.
@ -1311,23 +1313,23 @@ help:26963 = Un ensemble de circuits est utilisé pour définir un ensemble de p
help:29191 = Vous pouvez installer les configurations, clubs et base de données des coureurs à partir d'un répertoire source spécifié. Vos configurations locales sont écrasées. MeOS devrait être redémarré après l'installation.\n\nLe bouton <Exporter> vous conduit à une page où vous pouvez exporter votre configuration courante. help:29191 = Vous pouvez installer les configurations, clubs et base de données des coureurs à partir d'un répertoire source spécifié. Vos configurations locales sont écrasées. MeOS devrait être redémarré après l'installation.\n\nLe bouton <Exporter> vous conduit à une page où vous pouvez exporter votre configuration courante.
help:29758 = Ici vous gérez les clubs et l'impression des factures. Vous pouvez définir un tarif prenant en compte le type de catégorie et la date d'inscription. Les clubs en double (mal orthographiés) peuvent être regroupés dans le club correct. Vous pouvez également mettre à jour les adresses de clubs à partir du tableau de comptes. help:29758 = Ici vous gérez les clubs et l'impression des factures. Vous pouvez définir un tarif prenant en compte le type de catégorie et la date d'inscription. Les clubs en double (mal orthographiés) peuvent être regroupés dans le club correct. Vous pouvez également mettre à jour les adresses de clubs à partir du tableau de comptes.
help:30750 = Vous pouvez créer un grand nombre de listes et rapports différents. Ceux-ci peuvent être visualisés à l'écran, imprimés, ou sauvés dans un format web. La liste est automatiquement mise à jour lorsque des données liées à la compétition changent. L'impression automatique des résultats s'obtient à partir de la page Services. Pour exporter les données de la compétition, par exemple les temps intermédiaires, aller à la page Compétition. help:30750 = Vous pouvez créer un grand nombre de listes et rapports différents. Ceux-ci peuvent être visualisés à l'écran, imprimés, ou sauvés dans un format web. La liste est automatiquement mise à jour lorsque des données liées à la compétition changent. L'impression automatique des résultats s'obtient à partir de la page Services. Pour exporter les données de la compétition, par exemple les temps intermédiaires, aller à la page Compétition.
help:31661 = Un nouveau départ (en masse) est défini par une barrière horaire et une heure de reprise. A la barrière horaire les passages de relais sont terminés et aucun compétiteur n'est autorisé à partir en forêt. Les concurrents restants partent à l'heure de la barrière horaire. Il est possible de spécifier différents horaires pour des partiels précis, mais en utilisant cett efonction vous pouvez rapidement prendre en charge des catégories entières. help:31661 = Un nouveau départ (en masse) est défini par une barrière horaire et une heure de reprise. A la barrière horaire les passages de relais sont terminés et aucun compétiteur n'est autorisé à partir en forêt. Les concurrents restants partent à l'heure de la barrière horaire. Il est possible de spécifier différents horaires pour des partiels précis, mais en utilisant cette fonction vous pouvez rapidement prendre en charge des catégories entières.\n\nSi des équipes refusent le départ en masse des attardés (possible aux CFC par exemple), il suffit de cocher dans la page Équipes la case 'Empêcher le redémarrage' des équipes concernées.
help:33940 = Importer les inscriptions en format texte libre. Spécifier le nom, le club, la catégorie et le numéro de puce (éventuellement l'heure de départ), de préférence séparés par des virgules, une personne (équipe) par ligne. Il est également possible de spécifier plusieurs compétiteurs dans le même club / catégorie en laissant partiellement vides ces champs. Il est également possible d'importer des données formatées par d'autres moyens. help:33940 = Importer les inscriptions en format texte libre. Spécifier le nom, le club, la catégorie et le numéro de puce (éventuellement l'heure de départ), de préférence séparés par des virgules, une personne (équipe) par ligne. Il est également possible de spécifier plusieurs compétiteurs dans le même club / catégorie en laissant partiellement vides ces champs. Il est également possible d'importer des données formatées par d'autres moyens.
help:41072 = Sélectionner un poinçon dans la liste pour le modifier ou le supprimer. Vous pouvez ajouter des poinçons manquants à partir du modèle de course. Si l'heure d'arrivée est manquante, le coureur obtient le statut <Did Not Finish>. Si un poinçon est manquant, le statut est <Poinçon Manquant>. Il est impossible d'assigner un statut incompatible avec les poinçons. S'il y a un poinçon d'arrivée, vous devez le modifier pour pouvoir définir manuellement l'heure d'arrivée. Le même principe s'applique au poinçon de départ. help:41072 = Sélectionner un poinçon dans la liste pour le modifier ou le supprimer. Vous pouvez ajouter des poinçons manquants à partir du modèle de course. Si l'heure d'arrivée est manquante, le coureur obtient le statut <Aband.>. Si un poinçon est manquant, le statut est <PM>. Il est impossible d'assigner un statut incompatible avec les poinçons. S'il y a un poinçon d'arrivée, vous devez le modifier pour pouvoir définir manuellement l'heure d'arrivée. Le même principe s'applique au poinçon de départ.
help:41641 = Entrez un premier horaire de départ et un intervalle. Tirage Aléatoire affecte un ordre de départ totalement aléatoire. La Méthode de Tirage Suédoie utilise des règles spéciales pour répartir les coureurs d'un même club. Départ groupé signifie que la catégorie complète part par petits groupes pendant la durée spécifiée (Départ en masse étendu). Dans le champ Partiel vous pouvez spécifier quel partiel doit être tiré au hasard si la catégorie en a plusieurs. help:41641 = Entrez un premier horaire de départ et un intervalle. Tirage Aléatoire affecte un ordre de départ totalement aléatoire. La Méthode de Tirage Suédoise utilise des règles spéciales pour répartir les coureurs d'un même club. Départ groupé signifie que la catégorie complète part par petits groupes pendant la durée spécifiée (Départ en masse étendu). Dans le champ Partiel vous pouvez spécifier quel partiel doit être tiré au hasard si la catégorie en a plusieurs.
help:425188 = Vous pouvez gérer automatiquement les compétiteurs qui ne sont pas partis en lisant les boîtiers SI (clear/check/start/controls) dans SIConfig. Sauvegarder les données lues en tant que fichier texte dont les colonnes sont séparées par des points-virgules, et importez ce fichier dans MeOS. Les compétiteurs figurant dans cet import reçoivent un enregistrement. Vous pouvez alors donner le statut DNS à tous les compétiteurs n'ayant pas d'enregistrement. Si ultérieurement vous importez d'autres coureurs, vous pouvez réinitialiser le statut (de DNS à Inconnu) sur les compétiteurs alors importés. help:425188 = Vous pouvez gérer automatiquement les compétiteurs qui ne sont pas partis en lisant les boîtiers SI (clear/check/start/control) dans SI Config. Sauvegarder les données lues en tant que fichier texte dont les colonnes sont séparées par des points-virgules, et importez ce fichier dans MeOS. Les compétiteurs figurant dans cet import reçoivent un enregistrement. Vous pouvez alors donner le statut Non partant à tous les compétiteurs n'ayant pas d'enregistrement. Si ultérieurement vous importez d'autres coureurs, vous pouvez réinitialiser le statut (de Non partant à Inconnu) sur les compétiteurs alors importés.
help:471101 = Activez le boîtier SI en sélectionnant son port COM ou en recherchant les boîtiers SI installés. Appuyez sur Information pour obtenir le statut du port sélectionné.\n\nLecture Interactive vous permet de gérer directement les problèmes tels qu'un numéro de puce erroné. N'utilisez pas cette possibilité quand les compétiteurs ayant des problèmes sont pris en charge séparément.\n\nLa base de données des compétiteurs est utilisée si vous voulez ajouter automatiquement de nouveaux compétiteurs. Les poinçons sont utilisés pour trouver (détecter) la bonne catégorie. help:471101 = Activez le boîtier SI en sélectionnant son port COM ou en recherchant les boîtiers SI installés. Appuyez sur Information pour obtenir le statut du port sélectionné.\n\nLecture Interactive vous permet de gérer directement les problèmes tels qu'un numéro de puce erroné. N'utilisez pas cette possibilité quand les compétiteurs ayant des problèmes sont pris en charge séparément.\n\nLa base de données des compétiteurs est utilisée si vous voulez ajouter automatiquement de nouveaux compétiteurs. Les poinçons sont utilisés pour trouver (détecter) la bonne catégorie.
help:50431 = Vous êtes désormais connecté à un serveur. Pour ouvrir une compétition sur le serveur, sélectionnez le dans la liste et cliquer Ouvrir. Ajoutez une compétition au serveur, ouvrez la compétition en local et sélectionnez Télécharger. Quand vous aurez ouvert une compétition sur le serveur, vous pourrez voir tous les autres clients MeOS connectés. help:50431 = Vous êtes désormais connecté à un serveur. Pour ouvrir une compétition sur le serveur, sélectionnez le dans la liste et cliquer Ouvrir. Ajoutez une compétition au serveur, ouvrez la compétition en local et sélectionnez Télécharger. Quand vous aurez ouvert une compétition sur le serveur, vous pourrez voir tous les autres clients MeOS connectés.
help:52726 = Connectez vous à un serveur ci-dessous.\n\nInstallation\nTélécharger et installer MySQL 5 (Community Edition) depuis www.mysql.com. Vous pouvez utiliser la configuration par défaut. Il est uniquement nécessaire d'installer MySQL sur l'ordinateur servant de serveur. Quand MySQL est installé, démarrer MySQL Command Line Client et créez un compte utilisateur pour MeOS. Ecrire quelque chose du genre :\n\n> CREATE USER meos;\nGRANT ALL ON *.* TO meos;\n\nVous avez maintenant un utilisateur meos sans mot de passe. Entrez le nom du serveur ci-dessous (vous pouvez avoir à configurer les pare-feu pour laisser passer le traffic).\n\nComme alternative vous pouvez utiliser le compte root d'origine de MySQL. Le nom d'utilisateur est 'root' et le mot de passe est celui donné lors de l'installation de MySQL. help:52726 = Connectez vous à un serveur ci-dessous.\n\nInstallation\nTélécharger et installer MySQL 5 (Community Edition) depuis www.mysql.com. Vous pouvez utiliser la configuration par défaut. Il est uniquement nécessaire d'installer MySQL sur l'ordinateur servant de serveur. Quand MySQL est installé, démarrer MySQL Command Line Client et créez un compte utilisateur pour MeOS. Ecrire quelque chose du genre :\n\n> CREATE USER MeOS;\nGRANT ALL ON *.* TO MeOS;\n\nVous avez maintenant un utilisateur MeOS sans mot de passe. Entrez le nom du serveur ci-dessous (vous pouvez avoir à configurer les pare-feu pour laisser passer le traffic).\n\nComme alternative vous pouvez utiliser le compte root d'origine de MySQL. Le nom d'utilisateur est 'root' et le mot de passe est celui donné lors de l'installation de MySQL.
help:5422 = Pas de boîtier SI trouvé. Sont-ils connectés et démarrés ? help:5422 = Pas de boîtier SI trouvé. Sont-ils connectés et démarrés ?
help:59395 = Dans ce formulaire, vous pouvez rapidement effectuer des réglages de base en une seule opération pour plusieurs catégories.\n\nDépart est le nom du départ tel qu'il apparaît sur les liste d'horaire de départ.\n\nUn Bloc est un nombre entre 0 et 100 qui peut fournir une distribution des compétiteurs encore plus fine. Les catégories dans le même bloc seront imprimées dans la même minute sur les horaires de départ. \n\nIndex est une clé de tri. Les catégories sont triées à l'aide de cette clé dans toutes les listes.\n\nLe circuit peut être défini pour les catégories ayant exactement un circuit; s'il y a plusieurs circuits possibles vous devez utiliser le formulaire standard de catégorie.\n\nSaisie rapide détermine si la catégorie accepte les inscriptions rapides. help:59395 = Dans ce formulaire, vous pouvez rapidement effectuer des réglages de base en une seule opération pour plusieurs catégories.\n\nDépart est le nom du départ tel qu'il apparaît sur les liste d'horaire de départ.\n\nUn Bloc est un nombre entre 0 et 100 qui peut fournir une distribution des compétiteurs encore plus fine. Les catégories dans le même bloc seront imprimées dans la même minute sur les horaires de départ. \n\nIndex est une clé de tri. Les catégories sont triées à l'aide de cette clé dans toutes les listes.\n\nLe circuit peut être défini pour les catégories ayant exactement un circuit; s'il y a plusieurs circuits possibles vous devez utiliser le formulaire standard de catégorie.\n\nSaisie rapide détermine si la catégorie accepte les inscriptions rapides.
help:59395_more = The class fees, which shows if you have activated Economy features, are used for new entries. If you change a fee, MeOS will ask if you wish to apply the change to existing competitors.\n\nFor bibs you have the options None, Consecutive and Manual. You can also type the first bib in the class, for example A100, or 50. Consecutive means that the last number of the preceeding class is used to define the first number in this class. Reserved bib numbers gives a gap (of the specified width) in the numbering between classes.\n\nMeOS updates bibs when you draw start times or change the settings. Manual means that MeOS will never automatically update bibs.\n\nFor classes with teams the setting Team member controls the relation between the team number and the bibs. It can be the same, increasing (100, 101, 102), leg dependent (100-1, 100-2, etc.) or completely independent. help:59395_more = Les tarifs par catégories sont appliqués aux nouvelles inscriptions, si vous avez activé Gestion et frais d'inscriptions. Si vous modifiez un tarif, MeOS vous demandera si vous voulez appliquer ce nouveau tarifs aux coureurs déjà inscrits. \n\nPour les dossards, vous avez le chois entre Aucun, Consécutif et Manuel. Vous pouvez aussi spécifier le premier dossard de la catégorie, par exemple A100, ou 50. Consécutif signifie que le dernier dossard d'une catégorie est utilisé pour définir le premier de la suivante. Des dossards réservés permettent de garder un écart de numérotation entre les catégories, dont vous choisissez la valeur. \n\nMeOS met à jour les dossards si vous modifiez l'architecture ou les horaires des listes de départ. Manuel signifie que MeOS ne mettra jamais à jour automatiquement les dossards.\n\nPour les catégories comportant des équipes, le paramètre équipe contrôle le rapport entre la place dans l'équipe et le dossard. Il peut être Identique (même dossard pour toute l'équipe), Croissant (100, 101, 102), par Relayeur (100-1, 100-2, etc.) ou complètement indépendant.
help:7618 = Le nombre de compétiteurs dans l'équipe est défini dans la page Catégories. help:7618 = Le nombre de compétiteurs dans l'équipe est défini dans la page Catégories.
help:7620 = Intervalle (secondes). Laisser le champ vide pour qu'il soit mis à jour quand la compétition évolue. help:7620 = Intervalle (secondes). Laisser le champ vide pour qu'il soit mis à jour quand la compétition évolue.
help:89064 = Pour chaque poste, vous devez spécifier un ou plusieurs numéro de code (codes SI). Dans un circuit, vous faites référence à un poste par son identifiant (ID). Habituellement vous n'avez pas besoin d'ajouter des postes manuellement puisque MeOS ajoute automatiquement tous les postes nécessaires.\n\nL'utilisation de plus d'un code SI est utile lorsque l'on veut remplacer un boîtier défectueux ou pour créer des fourches simples. Pour un poste ordinaire, il est exigé que le compétiteur poinçonne un des postes spécifiés. Si le statut du poste est <Multiple>, tous les postes spécifiés doivent être poinçonnés (dans un ordre quelconque). Si le statut est <Défectueux>, le boîtier est ignoré.\n\nSi vous spécifiez un nom de poste, il est possible d'imprimer les résultats avec les temps intermédiaires aux postes nommés.\n\nUn réajustement de l'heure du poste peut être effectué s'il apparaît que le boîtier n'était pas à l'heure. Le format de l'heure est +/-MM:SS ou +/-HH:MM:SS.\n\nLe temps de partiel le plus court définit le temps le plus court possible sur ce partiel. Aucun concurrent n'aura un temps plus court pour aller à ce poste, aussi rapide soit-il. Cela peut être utilisé, par exemple, si une route dangereuse doit être traversée.\n\nLe statut <Pas de chronométrage> signifie que le temps pour aller au poste est ignoré; le temps total sera le même quel que soit le temps réellement mis pour se rendre au poste. help:89064 = Pour chaque poste, vous devez spécifier un ou plusieurs numéro de code (codes SI). Dans un circuit, vous faites référence à un poste par son identifiant (ID). Habituellement vous n'avez pas besoin d'ajouter des postes manuellement puisque MeOS ajoute automatiquement tous les postes nécessaires.\n\nL'utilisation de plus d'un code SI est utile lorsque l'on veut remplacer un boîtier défectueux ou pour créer des fourches simples. Pour un poste ordinaire, il est exigé que le compétiteur poinçonne un des postes spécifiés. Si le statut du poste est <Multiple>, tous les postes spécifiés doivent être poinçonnés (dans un ordre quelconque). Si le statut est <Défectueux>, le boîtier est ignoré.\n\nSi vous spécifiez un nom de poste, il est possible d'imprimer les résultats avec les temps intermédiaires aux postes nommés.\n\nUn réajustement de l'heure du poste peut être effectué s'il apparaît que le boîtier n'était pas à l'heure. Le format de l'heure est +/-MM:SS ou +/-HH:MM:SS.\n\nLe temps de partiel le plus court définit le temps le plus court possible sur ce partiel. Aucun concurrent n'aura un temps plus court pour aller à ce poste, aussi rapide soit-il. Cela peut être utilisé, par exemple, si une route dangereuse doit être traversée.\n\nLe statut <Pas de chronométrage> signifie que le temps pour aller au poste est ignoré; le temps total sera le même quel que soit le temps réellement mis pour se rendre au poste.
help:9373 = Donnez un ou plusieurs numéro de postes (codes SI) utilisés pour ce poste.\nExemple: 31, 32, 33. help:9373 = Donnez un ou plusieurs numéro de postes (codes SI) utilisés pour ce poste.\nExemple: 31, 32, 33.
help:9615 = Aucune réponse reçue. Voulez-vous ouvrir le port en mode passif ? MeOS doit-il être à l'écoute de poinçons à venir ? help:9615 = Aucune réponse reçue. Voulez-vous ouvrir le port en mode passif ? MeOS doit-il être à l'écoute de poinçons à venir ?
help:assignfee = MeOS va prendre en charge automatiquement pour vous les droits d'inscription dans la plupart des cas. Le tarif est basé sur l'âge et la date d'inscrition des compétiteurs (vous pouvez définir les limites dans Configuration de la compétition). Chaque catégorie définit un tarif. Vous fournissez une valeur par défaut pour différentes catégories dans Configuration de la Compétition, mais vous pouvez également reconfigurer la catégorie en utilisant Configuration Rapide pour cette catégorie.\n\nCette page vous permet d'utiliser différentes limites en âges et date limites d'inscription pour différents tarifs. Sur la page des Compétiteurs, vous pouvez ajuster manuellement le tarif pour chaque compétiteur en cas de besoin. help:assignfee = MeOS va prendre en charge automatiquement pour vous les droits d'inscription dans la plupart des cas. Le tarif est basé sur l'âge et la date d'inscription des compétiteurs (vous pouvez définir les limites dans Configuration de la compétition). Chaque catégorie définit un tarif. Vous fournissez une valeur par défaut pour différentes catégories dans Configuration de la Compétition, mais vous pouvez également reconfigurer la catégorie en utilisant Configuration Rapide pour cette catégorie.\n\nCette page vous permet d'utiliser différentes limites en âges et date limites d'inscription pour différents tarifs. Sur la page des Compétiteurs, vous pouvez ajuster manuellement le tarif pour chaque compétiteur en cas de besoin.
help:baudrate = Vitesse de transmission (baudrate) : utilisez 4800 ou 38400. help:baudrate = Vitesse de transmission (baudrate) : utilisez 4800 ou 38400.
help:computer_voice = Un poinçon arrivant est mis en correspondance avec un numéro de départ et joue le fichier <N.wav> où N est le numéro de départ. Les fichiers sont situés dans le répertoire ci-dessous. Si le compétiteur/équipe a une nationalité NAT d'affectée, MeOS essaie en priorité de jouer le fichier <NAT/N.wav>, qui se doit de contenir le nombre dans la version de langue appropriée. help:computer_voice = Un poinçon arrivant est mis en correspondance avec un numéro de départ et joue le fichier <N.wav> où N est le numéro de départ. Les fichiers sont situés dans le répertoire ci-dessous. Si le compétiteur/équipe a une nationalité NAT d'affectée, MeOS essaie en priorité de jouer le fichier <NAT/N.wav>, qui se doit de contenir le nombre dans la version de langue appropriée.
help:dbage = La base de donnée des compétiteurs date de plus de deux mois. Souhaitez vous télécharger une nouvelle base à partir d'Eventor ? help:dbage = La base de donnée des compétiteurs date de plus de deux mois. Souhaitez vous télécharger une nouvelle base à partir d'Eventor ?
@ -1337,20 +1339,20 @@ help:fullscreen = Vous pouvez ajuster la vitesse de défilement en utilisant Ctr
help:import_entry_data = Vous pouvez importer des compétiteurs, des catégories, des clubs et des inscriptions à partir de divers formats texte et XML. Il n'est pas nécessaire de fournir tous les fichiers ci-dessous. Par exemple, un fichier CSV de OE avec les inscriptions contient les clubs et les catégories, aussi dans ce cas ces champs devraient-ils être laissés vides.\n\nSi le même compétiteur est importé plusieurs fois vous n'obtiendrez pas plusieurs copies de ce compétiteur, mais son inscription sera modifiée. Cela signifie qu'il est sans danger de ré-importer ou d'importer un fichier d'inscription qui a été étendu. help:import_entry_data = Vous pouvez importer des compétiteurs, des catégories, des clubs et des inscriptions à partir de divers formats texte et XML. Il n'est pas nécessaire de fournir tous les fichiers ci-dessous. Par exemple, un fichier CSV de OE avec les inscriptions contient les clubs et les catégories, aussi dans ce cas ces champs devraient-ils être laissés vides.\n\nSi le même compétiteur est importé plusieurs fois vous n'obtiendrez pas plusieurs copies de ce compétiteur, mais son inscription sera modifiée. Cela signifie qu'il est sans danger de ré-importer ou d'importer un fichier d'inscription qui a été étendu.
help:importcourse = Vous pouvez importer des circuits et des catégories à partir (par exemple) d'exports OCAD ou Condes. help:importcourse = Vous pouvez importer des circuits et des catégories à partir (par exemple) d'exports OCAD ou Condes.
help:ocad13091 = Si vous avez accès aux circuits (par exemple à partir d'OCAD ou Condes) vous pouvez fournir les fichiers contenant les circuits ici. Autrement, vous pourrez ajouter les circuits ultérieurement. help:ocad13091 = Si vous avez accès aux circuits (par exemple à partir d'OCAD ou Condes) vous pouvez fournir les fichiers contenant les circuits ici. Autrement, vous pourrez ajouter les circuits ultérieurement.
help:relaysetup = Utilisez le guide ci-dessous pour choisir parmis les formulaires de compétitions prédéfinis. Après avoir appliqué la configuration, il est possible d'adapter manuellement la configuration pour chaque partiel et configurer les circuits.\n\nQuelques explications :\n- Relais est utilisé pour différent type de relais.\n- Relais par paire signifie que deux compétiteurs forme une équipe et courent à tour de rôle.\n- Un relais en Co-compétition est parfois utilisé dans les catégories jeunes et permet d'avoir plus d'un compétiteur sur certains partiels. (le premier compétiteur change d'une fois à l'autre).\n- Une patrouille peut s'effectuer avec une ou deux puces.\n- Prologue et poursuite est une compétition individuelle mais constitué de deux courses.\n- Un pool de circuit signifie qu'il y a plusieurs variantes, mais qu'il n'est pas décidé à l'avance qui court sur quelle variante; la décision est prise automatiquement lorsque le coureur a terminé. help:relaysetup = Utilisez le guide ci-dessous pour choisir parmi les formulaires de compétitions prédéfinis. Après avoir appliqué la configuration, il est possible d'adapter manuellement la configuration pour chaque partiel et configurer les circuits.\n\nQuelques explications :\n- Relais est utilisé pour différent type de relais.\n- Relais par paire signifie que deux compétiteurs forme une équipe et courent à tour de rôle.\n- Un relais en Co-compétition est parfois utilisé dans les catégories jeunes et permet d'avoir plus d'un compétiteur sur certains partiels. (le premier compétiteur change d'une fois à l'autre).\n- Une patrouille peut s'effectuer avec une ou deux puces.\n- Prologue et poursuite est une compétition individuelle mais constitué de deux courses.\n- Un pool de circuit signifie qu'il y a plusieurs variantes, mais qu'il n'est pas décidé à l'avance qui court sur quelle variante; la décision est prise automatiquement lorsque le coureur a terminé.
help:restore_backup = Choisissez une sauvegarde à restaurer en cliquant la date à laquelle la sauvegarde a été faite. help:restore_backup = Choisissez une sauvegarde à restaurer en cliquant la date à laquelle la sauvegarde a été faite.
help:runnerdatabase = En important une base de donnée de clubs et de coureurs, MeOS reconnaitra automatiquement les coureurs inconnus (par leur numéro de puce), et vous aurez les adresses et numéros de téléphone du club. help:runnerdatabase = En important une base de donnée de clubs et de coureurs, MeOS reconnaitra automatiquement les coureurs inconnus (par leur numéro de puce), et vous aurez les adresses et numéros de téléphone du club.
help:save = MeOS sauve automatiquement toutes les configurations lorsque c'est nécessaire. help:save = MeOS sauve automatiquement toutes les configurations lorsque c'est nécessaire.
help:speaker_setup = Choisissez les catégories et circuits que vous voulez surveiller. help:speaker_setup = Choisissez les catégories et circuits que vous voulez surveiller.
help:speakerprio = Cochez les coureurs/équipes que vous souhaitez surveiller dès le départ et tant que tout va bien. Mettre deux coches pour surveiller même si le résultat n'est plus très bon. Aucune coche signifie que la surveillance n'est activée que si le coureur/l'équipe a de bons résultats (donc pas forcément depuis le départ). help:speakerprio = Cochez les coureurs/équipes que vous souhaitez surveiller dès le départ et tant que tout va bien. Mettre deux coches pour surveiller même si le résultat n'est plus très bon. Aucune coche signifie que la surveillance n'est activée que si le coureur/l'équipe a de bons résultats (donc pas forcément depuis le départ).
help:splitexport = Décidez si vous voulez exporter les résultats individuellement ou globalement pour chaque course. Si vous choisissez d'exporter toutes les courses, des fichiers numérotés seront créés. help:splitexport = Décidez si vous voulez exporter les résultats individuellement ou globalement pour chaque course. Si vous choisissez d'exporter toutes les courses, des fichiers numérotés seront créés.
help:startmethod = MeOS utilisera automatiquement la méthode de départ choisie. Quoi que vous choisissiez ici, vous pourez dans tous les cas changer la méthode de départ ou refaire le tirage plus tard. help:startmethod = MeOS utilisera automatiquement la méthode de départ choisie. Quoi que vous choisissiez ici, vous pourrez dans tous les cas changer la méthode de départ ou refaire le tirage plus tard.
help:winsplits_auto = Ce service sauvegarde les temps intermédiaires dans un fichier IOF (xml) à intervalles réguliers. Si vous ouvrez ce fichier dans WinSplits, les temps intermédiaires seront mis à jour en temps réel. help:winsplits_auto = Ce service sauvegarde les temps intermédiaires dans un fichier IOF (xml) à intervalles réguliers. Si vous ouvrez ce fichier dans Winslet, les temps intermédiaires seront mis à jour en temps réel.
help:zero_time = Définissez l'heure zéro à une heure avant le premier départ prévu. help:zero_time = Définissez l'heure zéro à une heure avant le premier départ prévu.
help:long_times = La date de compétition est la date à laquelle toutes les catégories commencent. L'heure zéro est à minuit. help:long_times = La date de compétition est la date à laquelle toutes les catégories commencent. L'heure zéro est à minuit.
help_autodraw = Fournit une première heure de départ (ordinaire), un intervalle minimal (pour une catégorie) et le pourcentage de vacants. Vous pouvez également choisir la méthode utilisée pour le tirage au sort et si les personnes inscrites tardivement doivent partir avant ou après les autres coureurs. Le premier horaire de départ doit être postérieur l'heure zéro de la compétition.\n\nSi vous cliquez sur <Tirage automatique>, MeOS vérifie toutes les catégories. Si la catégorie n'a pas eu de tirage celui-ci est effectué. S'il y a des personnes inscrites tardivement sans horaires de départ dans une catégorie, leur horaire de départ sera tiré au sort.\n\nMeOS garantit que les coureurs ayant des circuits similaires ne partent pas simultanément, et de la place est réservée pour permettre l'accueil de coureurs inscrits tardivement dans les même conditions.\n\nSi au contraire vous cliquez sur <Tirage manuel> vous pouvez contrôler exactement quelle catégories sont tirées au sort et avec quels paramètres. help_autodraw = Fournit une première heure de départ (ordinaire), un intervalle minimal (pour une catégorie) et le pourcentage de vacants. Vous pouvez également choisir la méthode utilisée pour le tirage au sort et si les personnes inscrites tardivement doivent partir avant ou après les autres coureurs. Le premier horaire de départ doit être supérieur à l'heure zéro de la compétition.\n\nSi vous cliquez sur <Tirage automatique>, MeOS vérifie toutes les catégories. Si la catégorie n'a pas eu de tirage celui-ci est effectué. S'il y a des personnes inscrites tardivement sans horaires de départ dans une catégorie, leur horaire de départ sera tiré au sort.\n\nMeOS garantit que les coureurs ayant des circuits similaires ne partent pas simultanément, et de la place est réservée pour permettre l'accueil de coureurs inscrits tardivement dans les même conditions.\n\nSi au contraire vous cliquez sur <Tirage manuel> vous pouvez contrôler exactement quelle catégories sont tirées au sort et avec quels paramètres.
help_draw = Le tirage au sort des horaire de départ se fait en deux temps. Premièrement vous choisissez les catégories et entrz quelques paramètres. Quand vous appuyez sur <Répartir les horaires> MeOS utilise vos paramètres pour attribuer les plages d'horaires entre les catégories. MeOS garantit que les catégories ayant des circuits similaires ne partent pas ne même temps en prenant en compte toutes les catégories ayant déjà eu un tirage. L'objectif est une répartition uniforme des partants.\n\nLa répartition calculée se présente sous la forme d'une table dans laquelle vous pouvez effectuer vos propres modifications, ou laisser MeOS mettre à jour sa répartition en prenant en compte vos modifications. Lorsque vous êtes satisfaits avec la répartition, vous laisser MeOS faire le tirage au sort des catégories sélectionnées.\n\nLes paramétrages que vous devez effectuer consistent à fournir l'heure du premier départ possible, et le plus petit intervalle de temps entre coureur autorisé. Le nombre maximal de départ en parallèle détermine combien de coureurs peuvent prendre le départ en même temps. Une valeur plus importante conduit à une durée de départ plus faible.\n\nLe pourcentage de vacants détermine le nombre d'horaires laissés disponibles. Si vous n'en voulez aucune, entrez 0%. Le nombre prévu de retardataires réserve de la place pour ces derniers dans la liste de départ, avec la garantie qu'aucun coureur prenant le départ au même moment n'aura un circuit identique. help_draw = Le tirage au sort des horaire de départ se fait en deux temps. Premièrement vous choisissez les catégories et entrez quelques paramètres. Quand vous appuyez sur <Répartir les horaires> MeOS utilise vos paramètres pour attribuer les plages d'horaires entre les catégories. MeOS garantit que les catégories ayant des circuits similaires ne partent pas ne même temps en prenant en compte toutes les catégories ayant déjà eu un tirage. L'objectif est une répartition uniforme des partants.\n\nLa répartition calculée se présente sous la forme d'une table dans laquelle vous pouvez effectuer vos propres modifications, ou laisser MeOS mettre à jour sa répartition en prenant en compte vos modifications. Lorsque vous êtes satisfaits avec la répartition, vous laisser MeOS faire le tirage au sort des catégories sélectionnées.\n\nLes paramétrages que vous devez effectuer consistent à fournir l'heure du premier départ possible, et le plus petit intervalle de temps entre coureur autorisé. Le nombre maximal de départ en parallèle détermine combien de coureurs peuvent prendre le départ en même temps. Une valeur plus importante conduit à une durée de départ plus faible.\n\nLe pourcentage de vacants détermine le nombre d'horaires laissés disponibles. Si vous n'en voulez aucune, entrez 0%. Le nombre prévu de retardataires réserve de la place pour ces derniers dans la liste de départ, avec la garantie qu'aucun coureur prenant le départ au même moment n'aura un circuit identique.
info:multieventnetwork = Pour prendre en charge plus d'une étape vous devez travailler localement. Faite une copie de sauvergarde de la compétition, ouvrez-la en local et transferrez les résultats à l'étape suivante. Enfin, remontez l'étape suivante sur le serveur. info:multieventnetwork = Pour prendre en charge plus d'une étape vous devez travailler localement. Faite une copie de sauvegarde de la compétition, ouvrez-la en local et transférez les résultats à l'étape suivante. Enfin, remontez l'étape suivante sur le serveur.
info:readout_action = X: Puce no. Y lue.\nDes actions manuelles sont requises. info:readout_action = X: Puce no. Y lue.\nDes actions manuelles sont requises.
info:readout_queue = X: Puce no. Y lue.\nLa puce a été mise en file d'attente. info:readout_queue = X: Puce no. Y lue.\nLa puce a été mise en file d'attente.
inforestwarning = Aucun concurrent ne semble être encore en forêt. Comme les données qui ont servi à émettre cette conclusion peuvent être erronées, vous devez vérifier qu'aucun concurrent n'est encore en forêt par d'autres moyens. inforestwarning = Aucun concurrent ne semble être encore en forêt. Comme les données qui ont servi à émettre cette conclusion peuvent être erronées, vous devez vérifier qu'aucun concurrent n'est encore en forêt par d'autres moyens.
@ -1376,7 +1378,7 @@ sjätte = sixième
skicka stämplar = envoyer les poinçons skicka stämplar = envoyer les poinçons
sortering: X, antal rader: Y = ordre de tri: X, nombre de lignes: Y sortering: X, antal rader: Y = ordre de tri: X, nombre de lignes: Y
starten (X) = le départ (X) starten (X) = le départ (X)
sträcka %d = variation %d sträcka X = Partiel X
stämplade vid = a poinçonné stämplade vid = a poinçonné
stämplar vid X som Y, på tiden Z = poinçonne à X en tant que Y, en Z stämplar vid X som Y, på tiden Z = poinçonne à X en tant que Y, en Z
tar ledningen med tiden X = prend la tête en X tar ledningen med tiden X = prend la tête en X
@ -1406,8 +1408,8 @@ warn:changedtimezero = Changer l'heure zéro d'une compétition ayant des résul
warn:olddbversion = La base de donnée est utilisée par une version postérieure de MeOS. Une mise à jour est recommandée. warn:olddbversion = La base de donnée est utilisée par une version postérieure de MeOS. Une mise à jour est recommandée.
warning:dbproblem = ATTENTION. Problèmes rencontrés avec la connexion à la base: 'X'. La connexion sera automatiquement restaurée. Vous pouvez continuer à travailler normalement. warning:dbproblem = ATTENTION. Problèmes rencontrés avec la connexion à la base: 'X'. La connexion sera automatiquement restaurée. Vous pouvez continuer à travailler normalement.
warning:drawresult = La catégorie a déjà des résultats, les heures de départ seront écrasées. Voulez-vous continuer ? warning:drawresult = La catégorie a déjà des résultats, les heures de départ seront écrasées. Voulez-vous continuer ?
warning:has_entries = La catégorie a déjà des coureurs . Changer la réparition des variations à ce stade peut entraîner un eperte de données.\n\nVoulez-vous continuer ? warning:has_entries = La catégorie a déjà des coureurs . Changer la répartition des variations à ce stade peut entraîner une perte de données.\n\nVoulez-vous continuer ?
warning:has_results = La catégorie a déjà des résultats. Changer la réparition des variations à ce stade est inhabituel.\n\nVoulez-vous continuer ? warning:has_results = La catégorie a déjà des résultats. Changer la répartition des variations à ce stade est inhabituel.\n\nVoulez-vous continuer ?
xml-data = données xml xml-data = données xml
Äldre protokoll = Protocole périmé Äldre protokoll = Protocole périmé
Ändra = Modifier Ändra = Modifier
@ -1428,7 +1430,7 @@ xml-data = données xml
Återgå = Retour Återgå = Retour
Återställ = Restaurer Återställ = Restaurer
Återställ / uppdatera klasstillhörighet = Réinitialiser / modifier la catégorie du coureur Återställ / uppdatera klasstillhörighet = Réinitialiser / modifier la catégorie du coureur
Återställ löpare <Ej Start> med registrering till <Status Okänd> = Passer le statut <DNS> à <Inconnu> pour les coureurs inscrits Återställ löpare <Ej Start> med registrering till <Status Okänd> = Passer le statut <Non partant> à <Inconnu> pour les coureurs inscrits
Återställ säkerhetskopia = Restaurer la sauvegarde Återställ säkerhetskopia = Restaurer la sauvegarde
Återställ tabeldesignen och visa allt = Restaurer la présentation de la table Återställ tabeldesignen och visa allt = Restaurer la présentation de la table
ÅÅÅÅ-MM-DD = AAAA-MM-JJ ÅÅÅÅ-MM-DD = AAAA-MM-JJ
@ -1442,12 +1444,12 @@ xml-data = données xml
Öppna i ett nytt fönster = Ouvrir dans une nouvelle fenêtre Öppna i ett nytt fönster = Ouvrir dans une nouvelle fenêtre
Öppna klasser, ungdom = Ouvrir les catégories jeunes Öppna klasser, ungdom = Ouvrir les catégories jeunes
Öppna klasser, vuxna = Ouvrir les catégories adultes Öppna klasser, vuxna = Ouvrir les catégories adultes
Öppna nästa = Ouvrir le sivant Öppna nästa = Ouvrir le suivant
Öppna nästa etapp = Ouvrir l'étape suivante Öppna nästa etapp = Ouvrir l'étape suivante
Öppna tävling = Ouvrir la compétition Öppna tävling = Ouvrir la compétition
Öppna vald tävling = Ouvrir la compétition sélectionnée Öppna vald tävling = Ouvrir la compétition sélectionnée
Öppnad tävling = Compétition ouverte Öppnad tävling = Compétition ouverte
Överför anmälda = [Transfer entires] Överför anmälda = [Transfert soumis]
Överför nya deltagare i ej valda klasser med status "deltar ej" = Transférer les nouveaux coureurs dans les catégories non sélectionnées avec le statut "Ne participe pas" Överför nya deltagare i ej valda klasser med status "deltar ej" = Transférer les nouveaux coureurs dans les catégories non sélectionnées avec le statut "Ne participe pas"
Överför resultat = Transférer les résultats Överför resultat = Transférer les résultats
Överför resultat till X = Transfert des résultats à X Överför resultat till X = Transfert des résultats à X
@ -1465,7 +1467,7 @@ xml-data = données xml
åttonde = huitième åttonde = huitième
Kopia (X) = Copier (X) Kopia (X) = Copier (X)
Tillåt samma bana inom basintervall = Autoriser le même circuit dans l'intervalle de base ($1467) Tillåt samma bana inom basintervall = Autoriser le même circuit dans l'intervalle de base ($1467)
Välj X = Selectionner X Välj X = Sélectionner X
Ett startblock spänner över flera starter: X/Y = Un bloc de départ couvre plus d'un départ: X/Y Ett startblock spänner över flera starter: X/Y = Un bloc de départ couvre plus d'un départ: X/Y
Bricka X = Puce X Bricka X = Puce X
RunnerTimePerKM = Allure min/km RunnerTimePerKM = Allure min/km
@ -1519,7 +1521,7 @@ Nej = Non
På banan = Sur le circuit På banan = Sur le circuit
Stämpelkod = Code du poste Stämpelkod = Code du poste
Tidpunkt = Temps Tidpunkt = Temps
Antal deltagare = Competiteurs Antal deltagare = Compétiteurs
Förekomst = Occurrence Förekomst = Occurrence
Exporterar om = Export dans Exporterar om = Export dans
Exportformat = Format d'export Exportformat = Format d'export
@ -1538,6 +1540,7 @@ URL = URL
URL måste anges = URL manquant URL måste anges = URL manquant
Tidsintervall (sekunder) = Intervalle de temps (secondes) Tidsintervall (sekunder) = Intervalle de temps (secondes)
Antal skickade uppdateringar X (Y kb) = Nombre de mise à jour X (Y kb) Antal skickade uppdateringar X (Y kb) = Nombre de mise à jour X (Y kb)
Filename OE (csv) with runners and clubs = Nom de fichier OE (csv) avec coureurs et clubs
Filen finns redan: X = La destination existe déjà: X Filen finns redan: X = La destination existe déjà: X
Misslyckades med att ladda upp onlineresultat = Echec lors de la monté des résultats sur Internet Misslyckades med att ladda upp onlineresultat = Echec lors de la monté des résultats sur Internet
Onlineservern svarade felaktigt = Le serveur distant a fourni une réponse inattendue (Configuration incorrecte ?) Onlineservern svarade felaktigt = Le serveur distant a fourni une réponse inattendue (Configuration incorrecte ?)
@ -1545,7 +1548,7 @@ Onlineservern svarade: ZIP stöds ej = Réponse du serveur distant : ZIP non sup
Onlineservern svarade: Serverfel = Réponse du serveur distant: Erreur du serveur Onlineservern svarade: Serverfel = Réponse du serveur distant: Erreur du serveur
Onlineservern svarade: Felaktigt lösenord = Réponse du serveur distant : Mot de passe incorrect Onlineservern svarade: Felaktigt lösenord = Réponse du serveur distant : Mot de passe incorrect
Onlineservern svarade: Felaktigt tävlings-id = Réponse du serveur distant : Identifiant de compétition incorrect Onlineservern svarade: Felaktigt tävlings-id = Réponse du serveur distant : Identifiant de compétition incorrect
Online Results Error X = Erreur dans les résulatts en ligne X Online Results Error X = Erreur dans les résultats en ligne X
PDF = PDF PDF = PDF
ClassTeamLeg = Catégorie, équipe, relayeur ClassTeamLeg = Catégorie, équipe, relayeur
Okänd = Inconnu Okänd = Inconnu
@ -1625,7 +1628,7 @@ Brickan används av X = La puce est utilisée par X
DATABASE ERROR = ERREUR DE BASE DE DONNEE DATABASE ERROR = ERREUR DE BASE DE DONNEE
Lyssnar på X = Ecoute de X Lyssnar på X = Ecoute de X
vid kontroll X = au poste X vid kontroll X = au poste X
info:runnerdbonline = Comme vous êtes connecté à un serveur, il n'est pas possible d'étiter les bases de données club et compétiteurs manuellement. Effectuez les changements avant d'uploader la compétition sur un serveur. Il est également possible de remplacer la base de données existante sur le serveur en important une nouvelle base (à partir de IOF XML). info:runnerdbonline = Comme vous êtes connecté à un serveur, il n'est pas possible d'éditer les bases de données club et compétiteurs manuellement. Effectuez les changements avant d'uploader la compétition sur un serveur. Il est également possible de remplacer la base de données existante sur le serveur en important une nouvelle base (à partir de IOF XML).
ask:cleardb = Voulez-vous effacer les données club et compétiteurs ? ask:cleardb = Voulez-vous effacer les données club et compétiteurs ?
Banan saknar rogainingkontroller = La compétition n'a pas de poste de type course au score Banan saknar rogainingkontroller = La compétition n'a pas de poste de type course au score
Banans kontroller ger för få poäng för att täcka poängkravet = Les postes de type course au score n'attribuent pas assez de points Banans kontroller ger för få poäng för att täcka poängkravet = Les postes de type course au score n'attribuent pas assez de points
@ -1648,7 +1651,7 @@ Standard = Standard
TeamRogainingPointTotal = Total des points de l'équipe TeamRogainingPointTotal = Total des points de l'équipe
The forking is fair = Les variations sont équitables The forking is fair = Les variations sont équitables
Underfilter = Sous filtre Underfilter = Sous filtre
Ogiltigt lag på rad X = Equipe invalide ligne X Ogiltigt lag på rad X = Équipe invalide ligne X
Okänd klass på rad X = Catégorie inconnue ligne X Okänd klass på rad X = Catégorie inconnue ligne X
Klassen X är individuell = La catégorie X est individuelle Klassen X är individuell = La catégorie X est individuelle
Använd befintliga deltagare = Utiliser les compétiteurs déjà inscrits Använd befintliga deltagare = Utiliser les compétiteurs déjà inscrits
@ -1660,18 +1663,18 @@ Club and runner database = Base de donnée des clubs et compétiteurs
Clubs = Clubs Clubs = Clubs
Economy and fees = Gestion et frais d'inscription Economy and fees = Gestion et frais d'inscription
Forked individual courses = Circuit individuel avec variations Forked individual courses = Circuit individuel avec variations
General = General General = Général
Manual point reductions and adjustments = Réduction des points et ajustements Manual point reductions and adjustments = Réduction des points et ajustements
Manual time penalties and adjustments = Pénalités en temps et ajustements Manual time penalties and adjustments = Pénalités en temps et ajustements
MeOS Features = Fonctionnalités de MeOS MeOS Features = Fonctionnalités de MeOS
MeOS Funktioner = MeOS Fonctionnalités MeOS Funktioner = MeOS Fonctionnalités
Patrols = Equipe Patrols = Équipe
Prepare start lists = Preparation des listes de départ Prepare start lists = Préparation des listes de départ
Relays = Relais Relays = Relais
Several MeOS Clients in a network = Plusieurs clients MeOS en réseau Several MeOS Clients in a network = Plusieurs clients MeOS en réseau
Several races for a runner = Plusieurs compétitions pour un concurrent Several races for a runner = Plusieurs compétitions pour un concurrent
Spara laguppställningar = Enregistrer la constitution de l'équipe [Save Team Line-Ups] Spara laguppställningar = Enregistrer la constitution de l'équipe [Save Team Line-UPS]
Teams and forking = Equipes et variations Teams and forking = Équipes et variations
Track runners in forest = Suivi des coureurs en forêt Track runners in forest = Suivi des coureurs en forêt
Vacancies and entry cancellations = Places disponibles et annulation des inscriptions Vacancies and entry cancellations = Places disponibles et annulation des inscriptions
Banan saknas = Circuit manquant Banan saknas = Circuit manquant
@ -1687,17 +1690,17 @@ The forking is not fair = Les variations ne sont pas équitables
Unfair control legs = Branche non équitable Unfair control legs = Branche non équitable
Växel = Passage Växel = Passage
help:teamlineup = Ici vous pouvez importer un alignement d'équipe à partir d'un fichier texte structuré qu'il est facile de produire manuellement à partir d'un tableur. Le fichier doit avoir le format suivant :\n\nCatégorie;Nom de l'équipe;[Club]\nCompétiteur 1;[No de puce];[Club];[Circuit];[Catégorie du compétiteur]\nCompétiteur 2;[No de puce];[Club];[Circuit];[Catégorie du compétiteur]\n...\nCatégorie;Nom de l'équipe;[Club]\n...\n\nLes champs marqués entre crochets [] sont optionnels. Notez que les catégories et circuits utilisées doivent exister, et que le nombre de branches dans la catégorie doit correspondre au nombre de ligne définissant les compétiteurs après la catégorie. Des lignes vides peuvent être utilisées s'il n'y a pas de compétiteur. L'option <Utiliser des compétiteurs déjà inscrits> signifie que seulement les compétiteurs déjà inscrits à la compétition sont ajoutés à l'équipe; les autres compétiteurs spécifiés sont ignorés. help:teamlineup = Ici vous pouvez importer un alignement d'équipe à partir d'un fichier texte structuré qu'il est facile de produire manuellement à partir d'un tableur. Le fichier doit avoir le format suivant :\n\nCatégorie;Nom de l'équipe;[Club]\nCompétiteur 1;[No de puce];[Club];[Circuit];[Catégorie du compétiteur]\nCompétiteur 2;[No de puce];[Club];[Circuit];[Catégorie du compétiteur]\n...\nCatégorie;Nom de l'équipe;[Club]\n...\n\nLes champs marqués entre crochets [] sont optionnels. Notez que les catégories et circuits utilisées doivent exister, et que le nombre de branches dans la catégorie doit correspondre au nombre de ligne définissant les compétiteurs après la catégorie. Des lignes vides peuvent être utilisées s'il n'y a pas de compétiteur. L'option <Utiliser des compétiteurs déjà inscrits> signifie que seulement les compétiteurs déjà inscrits à la compétition sont ajoutés à l'équipe; les autres compétiteurs spécifiés sont ignorés.
Poängjustering = Point d'ajustment Poängjustering = Point d'ajustement
Use initials in names = Utiliser les initiales comme noms Use initials in names = Utiliser les initiales comme noms
Exportera klubbar (IOF-XML) = Export des clubs (IOF-XML) Exportera klubbar (IOF-XML) = Export des clubs (IOF-XML)
Exportera personer (IOF-XML) = Export des personnes (IOF-XML) Exportera personer (IOF-XML) = Export des personnes (IOF-XML)
Töm databasen = Effacement des données Töm databasen = Effacement des données
Several stages = Plusieurs étapes Several stages = Plusieurs étapes
Assign courses and apply forking to X = Assigner un circuit et appliquer la variation à X Assign courses and apply forking to X = Assigner un circuit et appliquer la variation à X
Assign selected courses to selected legs = Assigner les circuits sélectionnés aux branches sélectioonnées Assign selected courses to selected legs = Assigner les circuits sélectionnés aux branches sélectionnées
Calculate and apply forking = Calculer et utiliser les variations Calculate and apply forking = Calculer et utiliser les variations
Clear selections = Effacer les sélections Clear selections = Effacer les sélections
Define forking = Definir les variations Define forking = Définir les variations
Forking setup = Configuration des variations Forking setup = Configuration des variations
Leg X: Do not modify = Branche X: Ne pas modifier Leg X: Do not modify = Branche X: Ne pas modifier
Legs = Branches Legs = Branches
@ -1706,7 +1709,7 @@ Leg X = Branche X
Leg X: Use Y = La branche X: utilise Y Leg X: Use Y = La branche X: utilise Y
Created X distinct forkings using Y courses = X variations distinctes ont été créées à partir de Y circuits Created X distinct forkings using Y courses = X variations distinctes ont été créées à partir de Y circuits
Clear Memory = Effacement de la mémoire Clear Memory = Effacement de la mémoire
Create Competition = Creation de la compétition Create Competition = Création de la compétition
Print Card Data = Imprimer les données de la puce Print Card Data = Imprimer les données de la puce
Print card data = Imprimer les données de la puce Print card data = Imprimer les données de la puce
help:analyzecard = Cette fonction vous permet d'imprimer les données de la puce sans utiliser une quelconque compétition, comme le ferait une borne d'impression autonome. Sélectionner 'Imprimer les temps intermédiaires' pour choisir et configurer l'imprimante.\n\nLes puces sont également conservées en mémoire (mais pas dans la compétition). Vous pouvez éditer le nom et le club pour une puce en cliquant le nom (ou 'inconnu'). Vous pouvez également enregistrer les puces dans un fichier (Enregistrer) ou créer une nouvelle compétition à partir des données des puces. Notez que si une compétition est ouverte, vous devez la fermer pour rendre cette option disponible. help:analyzecard = Cette fonction vous permet d'imprimer les données de la puce sans utiliser une quelconque compétition, comme le ferait une borne d'impression autonome. Sélectionner 'Imprimer les temps intermédiaires' pour choisir et configurer l'imprimante.\n\nLes puces sont également conservées en mémoire (mais pas dans la compétition). Vous pouvez éditer le nom et le club pour une puce en cliquant le nom (ou 'inconnu'). Vous pouvez également enregistrer les puces dans un fichier (Enregistrer) ou créer une nouvelle compétition à partir des données des puces. Notez que si une compétition est ouverte, vous devez la fermer pour rendre cette option disponible.
@ -1723,7 +1726,7 @@ Första tillåtna starttid = Heure du premier départ possible
Importera anmälda = Importer les inscriptions Importera anmälda = Importer les inscriptions
Individuell tävling = Compétition individuelle Individuell tävling = Compétition individuelle
Namn och tidpunkt = Nom et heure Namn och tidpunkt = Nom et heure
Skapar tävling = Creation de la compétition Skapar tävling = Création de la compétition
Tävling med lag = Compétition en équipe Tävling med lag = Compétition en équipe
Tävlingen måste avgöras mellan X och Y = La compétition doit se dérouler entre X et Y Tävlingen måste avgöras mellan X och Y = La compétition doit se dérouler entre X et Y
Tävlingens namn = Nom de la compétition Tävlingens namn = Nom de la compétition
@ -1731,7 +1734,7 @@ Välj från lista = Sélection détaillée
Välj vilka funktioner du vill använda = Sélectionnez les fonctionnalités de MeOS dont vous avez besoin pour cette compétition Välj vilka funktioner du vill använda = Sélectionnez les fonctionnalités de MeOS dont vous avez besoin pour cette compétition
Individuellt, gafflat = Individuel, avec variations Individuellt, gafflat = Individuel, avec variations
Skapa tävlingen = Créer la compétition Skapa tävlingen = Créer la compétition
newcmp:featuredesc = Selectionnez les fonctionnalités de MeOS dont vous avez besoin pour cette compétition. Vous pouvez ajouter ou supprimer des fonctionnalités à tout moment en sélectionnant <Fonctionnalités MeOS> sur la page Compétition. newcmp:featuredesc = Sélectionnez les fonctionnalités de MeOS dont vous avez besoin pour cette compétition. Vous pouvez ajouter ou supprimer des fonctionnalités à tout moment en sélectionnant <Fonctionnalités MeOS> sur la page Compétition.
Exportera till fil = Exporter dans un fichier Exportera till fil = Exporter dans un fichier
FilterPrelResult = Résultats prél. FilterPrelResult = Résultats prél.
FinishTimeReverse = Temps inversés (le dernier en premier) FinishTimeReverse = Temps inversés (le dernier en premier)
@ -1742,8 +1745,8 @@ Result score calculation for runner = Détermination du score pour un compétite
Result score calculation for team = Détermination du score pour une équipe Result score calculation for team = Détermination du score pour une équipe
ResultDescription = Nom du type de résultat ResultDescription = Nom du type de résultat
Skapa = Créer Skapa = Créer
Status calculation for runner = Détermination du status pour un compétiteur Status calculation for runner = Détermination du statut pour un compétiteur
Status calculation for team = Détermination du status pour une équipe Status calculation for team = Détermination du statut pour une équipe
Support time from control = Temps depuis le poste [Support time from control] Support time from control = Temps depuis le poste [Support time from control]
Support time to control = Temps vers le poste [Support time to control] Support time to control = Temps vers le poste [Support time to control]
Time calculation for runner = Calcul du temps pour un compétiteur Time calculation for runner = Calcul du temps pour un compétiteur
@ -1800,28 +1803,28 @@ Runner/team finish time = Heure d'arrivée compétiteur/équipe
Runner/team input place = Place initiale compétiteur/équipe Runner/team input place = Place initiale compétiteur/équipe
Runner/team input points = Points initiaux compétiteur/équipe Runner/team input points = Points initiaux compétiteur/équipe
Runner/team input running time = Temps de course initial compétiteur/équipe Runner/team input running time = Temps de course initial compétiteur/équipe
Runner/team input status = Status initial compétiteur/équipe Runner/team input status = Statut initial compétiteur/équipe
Runner/team place = Place compétiteur/équipe Runner/team place = Place compétiteur/équipe
Runner/team rogaining overtime = Dépassement du temps pour compétiteur/équipe (course au score) Runner/team rogaining overtime = Dépassement du temps pour compétiteur/équipe (course au score)
Runner/team rogaining points = Point compétiteur/équipe (course au score) Runner/team rogaining points = Point compétiteur/équipe (course au score)
Runner/team rogaining points adjustment = Ajustement des points compétiteur/équipe (course au score) Runner/team rogaining points adjustment = Ajustement des points compétiteur/équipe (course au score)
Runner/team running time = Temps de course compétiteur/équipe Runner/team running time = Temps de course compétiteur/équipe
Runner/team start time = Heure de départ compétiteur/équipe Runner/team start time = Heure de départ compétiteur/équipe
Runner/team status = Status compétiteur/équipe Runner/team status = Statut compétiteur/équipe
Runner/team time adjustment = Ajustement du temps compétiteur/équipe Runner/team time adjustment = Ajustement du temps compétiteur/équipe
Runner/team total place = Place finale compétiteur/équipe Runner/team total place = Place finale compétiteur/équipe
Runner/team total running time = Temps total de course compétiteur/équipe Runner/team total running time = Temps total de course compétiteur/équipe
Runner/team total status = Status final compétiteur/équipe Runner/team total status = Statut final compétiteur/équipe
Shortest time in class = Meilleur temps de la catégorie Shortest time in class = Meilleur temps de la catégorie
Status as computed by your status method = Status tel que calculé par votre méthode Status as computed by your status method = Statut tel que calculé par votre méthode
Status code for a missing punch = Code de status pour un poinçon manquant Status code for a missing punch = Code de statut pour un poinçon manquant
Status code for a time over the maximum = Code de status en cas de dépassement du temps Status code for a time over the maximum = Code de statut en cas de dépassement du temps
Status code for a valid result = Code de status pour un résultat valide Status code for a valid result = Code de statut pour un résultat valide
Status code for an unknown result = Code de status pour un résultat inconnu Status code for an unknown result = Code de statut pour un résultat inconnu
Status code for disqualification = Code de status pour une disqualification Status code for disqualification = Code de statut pour une disqualification
Status code for not competing = Code de status en cas d'absence Status code for not competing = Code de statut en cas d'absence
Status code for not finishing = Code de status en cas d'abandon Status code for not finishing = Code de statut en cas d'abandon
Status code for not starting = Code de status en cas de non prise de départ Status code for not starting = Code de statut en cas de non prise de départ
Points as computed by your point method = Points tels que calculés par votre méthode Points as computed by your point method = Points tels que calculés par votre méthode
Time as computed by your time method = Temps tel que calculé par votre méthode Time as computed by your time method = Temps tel que calculé par votre méthode
Time after leg winner = Temps après le vainqueur du partiel Time after leg winner = Temps après le vainqueur du partiel
@ -1835,7 +1838,7 @@ Runner's method output numbers = Méthode de génération de nombre pour les com
Runner's method output times = Méthode de génération des temps pour les compétiteurs [Runner's method output times] Runner's method output times = Méthode de génération des temps pour les compétiteurs [Runner's method output times]
Running time for each team member = Temps de course pour chaque équipier Running time for each team member = Temps de course pour chaque équipier
Start time for each team member = Heure de départ pour chaque équipier Start time for each team member = Heure de départ pour chaque équipier
Status for each team member = Status de cahque équipier Status for each team member = Statut de chaque équipier
Check: X = Vérification : X Check: X = Vérification : X
Debug = Debug Debug = Debug
Debug Output = Sortie de debug Debug Output = Sortie de debug
@ -1850,26 +1853,26 @@ Symboler = Symboles
TeamPointAdjustment = Ajustement des points de l'équipe TeamPointAdjustment = Ajustement des points de l'équipe
TeamTimeAdjustment = Ajustement du temps de l'équipe TeamTimeAdjustment = Ajustement du temps de l'équipe
Variabler = Variables Variabler = Variables
Check: X = Véfification : X Check: X = Vérification : X
Choose result module = Choisir le module de résultat Choose result module = Choisir le module de résultat
Result Modules = Modules de résultat Result Modules = Modules de résultat
Error in result module X, method Y (Z) = Erreur dans le module de résultat 'X', méthode 'Y'\n\nZ Error in result module X, method Y (Z) = Erreur dans le module de résultat 'X', méthode 'Y'\n\nZ
Invalid operator X = Opérateur invalide X Invalid operator X = Opérateur invalide X
Unknown symbol X = Symbole inconnu X Unknown symbol X = Symbole inconnu X
RunnerGlobal = Competiteur (catégories regroupées) RunnerGlobal = Compétiteur (catégories regroupées)
TeamGlobal = Equipe (catégories regroupées) TeamGlobal = Équipe (catégories regroupées)
List Error: X = Erreur de liste : X List Error: X = Erreur de liste : X
Rader markerade med (*) kommer från en lista i tävlingen = Les lignes avec une (*) proviennent d'une liste de la compétition Rader markerade med (*) kommer från en lista i tävlingen = Les lignes avec une (*) proviennent d'une liste de la compétition
Resultatmodulen används i X = Le module de résultat est utilisé dans X Resultatmodulen används i X = Le module de résultat est utilisé dans X
Valfri = Optionnel Valfri = Optionnel
Vill du sätta resultatet från tidigare etapper till <Deltar ej>? = Voulez-vous modifier le résultat des étapes précédentes en <NPT> (Not taking part = absent)? Vill du sätta resultatet från tidigare etapper till <Deltar ej>? = Voulez-vous modifier le résultat des étapes précédentes en <Ne Participe Pas> ?
Hantera deltagare som bytt klass = Traitement des compétiteurs qui ont changé de catégorie Hantera deltagare som bytt klass = Traitement des compétiteurs qui ont changé de catégorie
Välj klasser med nya anmälningar = Spécifiez les catégories pour lesquelles de nouvelles inscriptions sont autorisées Välj klasser med nya anmälningar = Spécifiez les catégories pour lesquelles de nouvelles inscriptions sont autorisées
Byt till rätt klass (behåll eventuell starttid) = Basculer vers la bonne catégorie (conserver l'heure de départ) Byt till rätt klass (behåll eventuell starttid) = Basculer vers la bonne catégorie (conserver l'heure de départ)
Byt till vakansplats i rätt klass (om möjligt) = Déplacer vers un horaire vacant dans la bonne catagorie (si possible) Byt till vakansplats i rätt klass (om möjligt) = Déplacer vers un horaire vacant dans la bonne catégorie (si possible)
Tillåt ny klass, behåll resultat från annan klass = Autoriser de nouvelles catégories et conserver les résultats des autres catégories Tillåt ny klass, behåll resultat från annan klass = Autoriser de nouvelles catégories et conserver les résultats des autres catégories
Tillåt ny klass, inget totalresultat = Autoriser de nouvelels catégories mais sans résultat global Tillåt ny klass, inget totalresultat = Autoriser de nouvelles catégories mais sans résultat global
tooltip_explain_status = - = Status inconnu (pas encore de résultat)\nOK = Résultat valide\nDNS = Did Not Start (non parti)\nMP = Missing Punch (poiçon manquant)\nDNF = Did Not Finish (abandon)\nDISQ = Disqualifié\nOMT = Over Maximum Time (dépassement du temps maxi)\nNTP = Not Taking Part (absent) tooltip_explain_status = -
Placering = Place Placering = Place
Resultat från tidigare etapper = Résultats des étapes précédentes Resultat från tidigare etapper = Résultats des étapes précédentes
Input Results = Saisir les résultats [Input Results] Input Results = Saisir les résultats [Input Results]
@ -1915,7 +1918,7 @@ Ultra Long = Ultra Longue
Tillgängliga filer installerades. Starta om MeOS. = Les configurations ont été installées. Redémarrez MeOS S.V.P. Tillgängliga filer installerades. Starta om MeOS. = Les configurations ont été installées. Redémarrez MeOS S.V.P.
edit_in_forest = Gérer\nCompétiteurs en forêt edit_in_forest = Gérer\nCompétiteurs en forêt
Latest Results = Résultats récents Latest Results = Résultats récents
warning:direct_result = Notez que l'utilisation de <Resultat sur le poinçon d'arrivée> nécessite que tous les poinçons de tous les postes du circuit aient été transmis comme poste radio, ou que MeOS soit utilisé pour chronométrer uniquement sans tenir compte du circuit.\n\nUtiliser les résultats sur poinçon d'arrivée ? warning:direct_result = Notez que l'utilisation de <Résultat sur le poinçon d'arrivée> nécessite que tous les poinçons de tous les postes du circuit aient été transmis comme poste radio, ou que MeOS soit utilisé pour chronométrer uniquement sans tenir compte du circuit.\n\nUtiliser les résultats sur poinçon d'arrivée ?
Inställningar startbevis = Configuration de l'impression des tickets de départ Inställningar startbevis = Configuration de l'impression des tickets de départ
Skrivarinställningar = Configuration de l'impression Skrivarinställningar = Configuration de l'impression
Skrivarinställningar för sträcktider och startbevis = Configuration de l'impression des tickets de temps intermédiaires et de départ Skrivarinställningar för sträcktider och startbevis = Configuration de l'impression des tickets de temps intermédiaires et de départ
@ -1938,7 +1941,7 @@ info_shortening = Sélectionnez un circuit existant qui raccourcit le circuit s
Tilldela starttider = Attribuer des heures de départ Tilldela starttider = Attribuer des heures de départ
Avkortar: X = Raccourcit: X Avkortar: X = Raccourcit: X
Vill du nollställa alla manuellt tilldelade banor? = Voulez-vous effacer tous les circuits manuellement attribués ? Vill du nollställa alla manuellt tilldelade banor? = Voulez-vous effacer tous les circuits manuellement attribués ?
Ange löpande numrering eller första nummer i klassen = Spécifier une numérotatin consécutive entre catégories ou le premier numéro de la catégorie Ange löpande numrering eller första nummer i klassen = Spécifier une numérotation consécutive entre catégories ou le premier numéro de la catégorie
Ange relation mellan lagets och deltagarnas nummerlappar = Spécifier la relation entre le dossard de l'équipe et les dossards des coureurs de l'équipe Ange relation mellan lagets och deltagarnas nummerlappar = Spécifier la relation entre le dossard de l'équipe et les dossards des coureurs de l'équipe
Lagmedlem = Membre de l'équipe Lagmedlem = Membre de l'équipe
Löpande = Consécutif Löpande = Consécutif
@ -1966,7 +1969,7 @@ Laguppställningen hade fel, som har rättats = La constitution de l'équipe a
ControlClasses = Catégories du poste ControlClasses = Catégories du poste
ControlCodes = Numéros du poste ControlCodes = Numéros du poste
ControlCourses = Circuits du poste ControlCourses = Circuits du poste
ControlMaxLostTime = Potse, temps perdu, maximum ControlMaxLostTime = Poste, temps perdu, maximum
ControlMedianLostTime = Poste, temps perdu, médian ControlMedianLostTime = Poste, temps perdu, médian
ControlMistakeQuotient = Poste, pourcentage de coureurs avec perte de temps ControlMistakeQuotient = Poste, pourcentage de coureurs avec perte de temps
ControlName = Nom du poste ControlName = Nom du poste
@ -1981,7 +1984,7 @@ Control = Poste
Control Statistics = Statistiques du poste Control Statistics = Statistiques du poste
Control Statistics - X = Statistiques du poste - X Control Statistics - X = Statistiques du poste - X
Course = Course Course = Course
FilterSameParallel = Collect parallel legs ($1984) FilterSameParallel = Variations identiques
Kontrollrapport - X = Rapport du poste - X Kontrollrapport - X = Rapport du poste - X
Maxbom = Erreur maximale Maxbom = Erreur maximale
Control Overview = Aperçut général du poste Control Overview = Aperçut général du poste
@ -1994,7 +1997,7 @@ Tillsätt tillfälliga anonyma lagmedlemmar = Ajouter des membres d'équipe anon
Tillsätt = Nommer Tillsätt = Nommer
help:anonymous_team = Créer et nommer des membres (temporaires) d'équipe pour toutes les équipes, auxquels vous pouvez assigner une puce, un circuit, etc. help:anonymous_team = Créer et nommer des membres (temporaires) d'équipe pour toutes les équipes, auxquels vous pouvez assigner une puce, un circuit, etc.
Anonymt namn = Nom anonyme Anonymt namn = Nom anonyme
Med anmälningsavgift (lagets klubb) = Avec les frais d'insciption (pour le club de l'équipe) Med anmälningsavgift (lagets klubb) = Avec les frais d'inscription (pour le club de l'équipe)
Tar bort X = Retrait de X Tar bort X = Retrait de X
Källa = Source Källa = Source
Ta bort eventuella avanmälda deltagare = Supprimer les inscriptions annulées si nécessaire Ta bort eventuella avanmälda deltagare = Supprimer les inscriptions annulées si nécessaire
@ -2002,15 +2005,15 @@ Verktyg = Outils
Automatisk = Automatique Automatisk = Automatique
Avstånd = Distance Avstånd = Distance
Extra avstånd ovanför textblock = Distance additionnelle Extra avstånd ovanför textblock = Distance additionnelle
FilterSameParallelNotFirst = Recueillir les variations parallèles, ignorer la première ($2005) FilterSameParallelNotFirst = Variations identiques sauf la première
RunnerLeg = Concurrent (variation spécifique) RunnerLeg = Concurrent (variation spécifique)
Texten ska innehålla tecknet X, som byts ut mot tävlingsspecifik data = Le texte doit inclure le symbole X, qui est remplacé par les données spécifiques à la compétition Texten ska innehålla tecknet X, som byts ut mot tävlingsspecifik data = Le texte doit inclure le symbole X, qui est remplacé par les données spécifiques à la compétition
Tabellverktyg = Outils table Tabellverktyg = Outils table
Antal reserverade nummerlappsnummer mellan klasser = Nombre de dossards réservés entre les catégories Antal reserverade nummerlappsnummer mellan klasser = Nombre de dossards réservés entre les catégories
help:bibs = Vous pouvez gérer les dossards manuellement ou automatiquement. Ici vous pouvez assigner les dossards manuellement pour une certaine catégorie en spécifiant la méthode Manuelle et en fournissant le premier numéro pour cette catégorie.\n\nLa méthode automatique fonctionne de la même façon, avec la différence que MeOS mettra à jour les dossards de toutes les catégories d'un coup. Bien qu'il soit possible de faire ce paramétrage ici, il est préférable d'utiliser le Paramétrage rapide pour les catégories afin d'avoir une vue d'ensemble de toutes les catégories.\n\nUtiliser la méthode Automatique avec les méthodes Aucun ou Consécutifs, qui indique que le dernier numéro de la catégorie précédente est utilisé comme premier numéro. Le nombre de dossards réservés définit le saut de numérotation entre catégories.\n\nPour les catégories d'équipes vous pouvez spécifier la relation existant entre les numéros de dossard des équipiers et celui de l'équipe. Il peut être Identique, Indépendant, Croissant (Equipe 1: 101, 102, 103, 104, Equipe 2: 111, 112, 113, 114 etc.) ou par Combinaison (100-1, 100-2, 100-3 etc). help:bibs = Vous pouvez gérer les dossards manuellement ou automatiquement. Ici vous pouvez assigner les dossards manuellement pour une certaine catégorie en spécifiant la méthode Manuelle et en fournissant le premier numéro pour cette catégorie.\n\nLa méthode automatique fonctionne de la même façon, avec la différence que MeOS mettra à jour les dossards de toutes les catégories d'un coup. Bien qu'il soit possible de faire ce paramétrage ici, il est préférable d'utiliser le Paramétrage rapide pour les catégories afin d'avoir une vue d'ensemble de toutes les catégories.\n\nUtiliser la méthode Automatique avec les méthodes Aucun ou Consécutifs, qui indique que le dernier numéro de la catégorie précédente est utilisé comme premier numéro. Le nombre de dossards réservés définit le saut de numérotation entre catégories.\n\nPour les catégories d'équipes vous pouvez spécifier la relation existant entre les numéros de dossard des équipiers et celui de l'équipe. Il peut être Identique, Indépendant, Croissant (Équipe 1: 101, 102, 103, 104, Équipe 2: 111, 112, 113, 114 etc.) ou par Combinaison (100-1, 100-2, 100-3 etc).
RunnerGeneralPlace = Classement individuel ou par équipe du concurrent ($2011) RunnerGeneralPlace = Classement individuel ou par équipe du concurrent ($2011)
RunnerGeneralTimeAfter = Retard individuel ou par équipe du concurrent ($2012) RunnerGeneralTimeAfter = Retard individuel ou par équipe du concurrent ($2012)
RunnerGeneralTimeStatus = Temps / status individuel ou de l'équipe du concurrent ($2013) RunnerGeneralTimeStatus = Temps / statut individuel ou de l'équipe du concurrent ($2013)
open_error = Impossible d'ouvrir X.\n\nY. open_error = Impossible d'ouvrir X.\n\nY.
open_error_locked = Cette compétition est déjà ouverte dans MeOS.\n\nVous devez utiliser une base de données pour ouvrir plus d'un exemplaire d'une compétition. open_error_locked = Cette compétition est déjà ouverte dans MeOS.\n\nVous devez utiliser une base de données pour ouvrir plus d'un exemplaire d'une compétition.
Ogiltigt bricknummer = Numéro de puce invalide Ogiltigt bricknummer = Numéro de puce invalide
@ -2029,18 +2032,18 @@ Vill du att X tar sträckan istället för Y? = Voulez-vous que X coure cette va
Ändra lagets gaffling = Changer les variations de l'équipe Ändra lagets gaffling = Changer les variations de l'équipe
Deltagarens klass styrs av laget = La catégorie est définie par l'équipe Deltagarens klass styrs av laget = La catégorie est définie par l'équipe
För att delta i en lagklass måste deltagaren ingå i ett lag = Pour participer à une catégorie d'équipe vous devez assigner une équipe au compétiteur För att delta i en lagklass måste deltagaren ingå i ett lag = Pour participer à une catégorie d'équipe vous devez assigner une équipe au compétiteur
Dela upp = Temps intermédiaires Dela upp = Scinder
Alla sträckor = Toutes les variantes Alla sträckor = Toutes les variantes
Liveresultat, deltagare = Résultats en direct, individuels Liveresultat, deltagare = Résultats en direct, individuels
Använd enhets-id istället för tävlings-id = Utiliser l'identifiant de l'appareil au lieu de l'identifiant de la compétition ($2035) Använd enhets-id istället för tävlings-id = Utiliser l'identifiant de l'appareil au lieu de l'identifiant de la compétition ($2035)
Enhetens ID-nummer (MAC) = Identifiant de l'appareil (MAC) Enhetens ID-nummer (MAC) = Identifiant de l'appareil (MAC)
Antal deltagare: X = Nombre de compétiteurs : X Antal deltagare: X = Nombre de compétiteurs : X
Dela efter placering = Temps intermédiaires par résultat ($2038) Dela efter placering = Scinder par résultat
Dela efter tid = Temps intermédiaires par temps ($2039) Dela efter tid = scinder par temps
Dela slumpmässigt = Temps intermédiaire par aléatoire Dela slumpmässigt = Scinder aléatoirement
Jämna klasser (placering) = Make equal classes (result) ($2041) Jämna klasser (placering) = Faire des catégories égales (résultats)
Jämna klasser (ranking) = Make equal classes (ranking) ($2042) Jämna klasser (ranking) = Faire des catégories égales (classement)
Jämna klasser (tid) = Make equal classes (time) ($2043) Jämna klasser (tid) = Faire des catégories égales (Temps)
Klass X = Catégorie X Klass X = Catégorie X
Not yet implemented = Non encore implémenté Not yet implemented = Non encore implémenté
Tidstillägg = Pénalité (M:S) Tidstillägg = Pénalité (M:S)
@ -2048,7 +2051,7 @@ help:seeding_info = L'allocation ensemencée des heures de départ signifie qu'u
Ange en gruppstorlek (som repeteras) eller flera kommaseparerade gruppstorlekar = Fournir une taille de groupe (qui sera répétée) ou plusieurs tailles séparées par des virgules Ange en gruppstorlek (som repeteras) eller flera kommaseparerade gruppstorlekar = Fournir une taille de groupe (qui sera répétée) ou plusieurs tailles séparées par des virgules
Hindra att deltagare från samma klubb startar på angränsande tider = Empêcher que des coureurs du même club partent à des horaires consécutifs. Hindra att deltagare från samma klubb startar på angränsande tider = Empêcher que des coureurs du même club partent à des horaires consécutifs.
Låt de bästa start först = Faire ne sorte que le mieux classé parte en premier Låt de bästa start först = Faire ne sorte que le mieux classé parte en premier
Seedningsgrupper = Groupes ensemensés Seedningsgrupper = Groupes ensemencés
Seedningskälla = Données d'ensemencement Seedningskälla = Données d'ensemencement
error:invalidmethod = La méthode sélectionnée ne génère pas de distribution. Les données d'ensemencement sont insuffisantes. error:invalidmethod = La méthode sélectionnée ne génère pas de distribution. Les données d'ensemencement sont insuffisantes.
Ogiltig storlek på seedningsgrupper X = Taille des groupes d'ensemencement invalide : X Ogiltig storlek på seedningsgrupper X = Taille des groupes d'ensemencement invalide : X
@ -2090,7 +2093,7 @@ prefsEMail = Courriel
prefsEliteFee = Tarif par défaut pour les élites prefsEliteFee = Tarif par défaut pour les élites
prefsEntryFee = Tarif par défaut prefsEntryFee = Tarif par défaut
prefsEventorBase = URL d'Eventor prefsEventorBase = URL d'Eventor
prefsFirstInvoice = Premier numéro de fature prefsFirstInvoice = Premier numéro de facture
prefsFirstTime = Premier départ prefsFirstTime = Premier départ
prefsHomepage = Site web prefsHomepage = Site web
prefsInteractive = Gestion interactive des puces prefsInteractive = Gestion interactive des puces
@ -2153,7 +2156,7 @@ Ej startstämpling = Ignorer le poinçon de départ
Extraplatser = Places supplémentaires Extraplatser = Places supplémentaires
Fritt = Libre Fritt = Libre
Från lag = De l'équipe Från lag = De l'équipe
Lag + sträcka = Equipe + variation Lag + sträcka = Équipe + variation
Nummerlappshantering = Gestion des dossards Nummerlappshantering = Gestion des dossards
Oordnade parallella = Unordered parallel ($2158) Oordnade parallella = Unordered parallel ($2158)
Spara starttider = Enregistrer les heures de départ Spara starttider = Enregistrer les heures de départ
@ -2166,7 +2169,7 @@ Inget filter = Pas de filtre
Inlästa stämplar = Lire les poinçons Inlästa stämplar = Lire les poinçons
Löpare saknas = Aucun coureur Löpare saknas = Aucun coureur
Klasserna X och Y har samma externa id. Använd tabelläget för att ändra id = Les catégories X et Y ont le même identifiant externe. Utiliser le mode table pour corriger l'identifiant. Klasserna X och Y har samma externa id. Använd tabelläget för att ändra id = Les catégories X et Y ont le même identifiant externe. Utiliser le mode table pour corriger l'identifiant.
Vill du koppla isär X från inläst bricka Y? = Would you like to disconnect X from the read out card Y ? ($2169) Vill du koppla isär X från inläst bricka Y? = Voulez-vous délier X de na puce numéro Y ?
RunnerRogainingPointGross = Points avant pénalités RunnerRogainingPointGross = Points avant pénalités
Samlade poäng = Points acquis Samlade poäng = Points acquis
Tidsavdrag = Pénalités Tidsavdrag = Pénalités
@ -2212,30 +2215,220 @@ leder med X = est en tête avec X
delar placering med X = est à égalité avec X delar placering med X = est à égalité avec X
sekund = seconde sekund = seconde
skickar ut X = envoyer X skickar ut X = envoyer X
Import names as "surname, first name" = Importer les noms sous la forme "nom de famille, prénoms"
Use French Federation of Orienteering mapping = Utiliser le format de la Fédération Française de CO
Export language = Langue Export language = Langue
Export Split Times = Exporter les temps intermédiaires Use French Federation of Orienteering mapping = Utiliser le format de la Fédération Française de CO
Filename OE (csv) with runners and clubs = Nom de fichier OE (csv) avec coureurs et clubs Export split times = Exporter les temps intermédiaires
Climb (m) = Dénivelée (m) Climb (m) = Dénivelée (m)
Utrymme: X = Taille : X Utrymme: X = Taille : X
[Radera] = [Supprimer] [Radera] = [Supprimer]
prefsNumSplitsOnePage = Nombre de puces par page
prefsPayModes = Modes de paiement
prefsSplitPrintMaxWait = Temps d'attente maximum lors de l'impression des temps intermédiaires
prefsWideSplitFormat = Imprimer les temps intermédiaires en grand format
ClassTeamLegResult = Résultat par catégorie et relayeur ClassTeamLegResult = Résultat par catégorie et relayeur
SortLastNameOnly = Nom de famille
Databaskälla = Base de donnée source Databaskälla = Base de donnée source
Export split times = Exporter les temps intermédiaires
Filnamn IOF (xml) eller OE (csv) med löpare = Fichier IOF (xml) ou OE (csv) avec coureurs Filnamn IOF (xml) eller OE (csv) med löpare = Fichier IOF (xml) ou OE (csv) avec coureurs
Importinställning = Préférences d'importation Importinställning = Préférences d'importation
Längsta tid i sekunder att vänta med utskrift = Délai maximum d'attente de l'impression en seconde
Max antal brickor per sida = Nombre maximum de puces par page
Resultat efter sträcka X = Résultats après le partiel X
SortLastNameOnly = Nom de famille
Sträcktider i kolumner (f?r standardpapper) = Temps en colonnes (papier standard)
prefsExportCSVSplits = Inclure les temps intermédiaires dans l'export csv prefsExportCSVSplits = Inclure les temps intermédiaires dans l'export csv
prefsExportFormat = Format d'exportation par défaut prefsExportFormat = Format d'exportation par défaut
prefsImportOptions = Options d'importation par défaut prefsImportOptions = Options d'importation par défaut
prefsNumSplitsOnePage = Nombre de puces par page
prefsPayModes = Modes de paiement
prefsSplitLateFees = Séparer les frais d'inscription en frais standards et frais d'inscription tardive pour l'exportation IOF XML prefsSplitLateFees = Séparer les frais d'inscription en frais standards et frais d'inscription tardive pour l'exportation IOF XML
prefsSplitPrintMaxWait = Temps d'attente maximum lors de l'impression des temps intermédiaires Längsta tid i sekunder att vänta med utskrift = Délai maximum d'attente de l'impression en seconde
prefsWideSplitFormat = Imprimer les temps intermédiaires en grand format Max antal brickor per sida = Nombre maximum de puces par page
sträcka X = Partiel X Sträcktider i kolumner (för standardpapper) = Temps en colonnes (pour imprimante A4)
Spara inmatade tider i tävlingen utan att tilldela starttider = Enregistrer les paramètres et les heures de départ de chaque catégorie pour y revenir plus tard
SRR Dongle = Dongle SRR
red channel = Chaine rouge
blue channel = Chaine bleue
Printing failed (X: Y) Z = Port par défaut
prefsNameMode = Format du nom : X
Kommunikationen med en SI-enhet avbröts = Connection perdue à la base SI-master
Varning: avgiften kan ej faktureras = Attention : impossible de générer de facture pour ce montant
Gamla brickor utan stöd för långa tider = Puces anciennes ne prenant pas en charge les longues courses
ask:convert_to_patrol = Certaines catégories contiennent des requêtes pour que certains coureurs aient la même heure de départ. Voulez-vous convertir ces catégories en catégories pour co-compétiteurs (type raid) ?
Antal som inte importerades: X = Nombre d'inscriptions sautées : X
Det finns anmälningsdata för flera etapper = Il y a des données pour plusieurs étapes
Välj etapp att importera = Sélectionner l'étape à importer
ask:savespeaker = Voulez-vous sauvegarder les paramètres d'affichage et de catégorie sur cet ordinateur ?
Spara fönster- och speakerinställningar på datorn = Enregistrer la fenêtre et les paramètres sur cet ordinateur
ask:loadspeaker = Voulez-vous recréer des fenêtres sauvegardées précédemment sur cet ordinateur ?
Återskapa = Régénérer
Återskapa tidigare sparade fönster- och speakerinställningar = Régénérer les fenêtres et paramètres enregistrés précédemment
Inkludera resultat från tidigare etapper = Inclure les résultats de toutes les étapes
Animation = Animation
Bakgrund = Arrière plan
Bakgrundsfärg = Couleur de fond
Fullskärm (rullande) = Plein écran (déroulant)
Fullskärm (sidvis) = Plein écran (page par page)
Fönster = Fenêtre
Fönster (rullande) = Fenêtre (déroulant)
Justera visningsinställningar = Ajuster les paramètres de visualisation
Marginal = Marge
Sidor per skärm = Pages par écran
Textfärg = Couleur du texte
Utseende = Apparence
Visningsinställningar för 'X' = Paramètres d'affichage pour 'X'
Visningstid = Afficher le temps
Visning = Mode d'affichage
ask:hasVacant = Il y a toujours des vacants.\n\nVoulez-vous retirer tous les vacants avant d'exporter les résultats ?
warn:missingResult = X coureurs ne sont toujours pas rentrés et ne sont donc pas classés.\n\nVous pouvez aller dans l'onglet 'Coureurs restants' et les passer en statut <Non partant>
Återställ <Ej Start> till <Status Okänd> = Remettre <Non partant> en <Inconnu>
Återbud[status] = Annulé
Lås gafflingar = Verrouiller les variations
Markera för att förhindra oavsiktlig ändring av gafflingsnycklar = Vérifier pour empêcher toute erreur dans la répartition des variations
Tillåt gafflingsändringar = Déverrouiller les variations
ask:updatetimes = Voulez-vous conserver autant que possible les horaires de départ déjà assignés ? Répondez Non pour décaler la compétition dans le temps
X har en tid (Y) som inte är kompatibel med förändringen = X a une heure de départ (Y) ce qui n'est pas compatible avec ce changement
warn:latestarttime = Utiliser des heures de départ plus de X heures après l'heure zéro n'est pas conseillé
Anm. tid = Heure d'inscription
RunnerEntryDate = Date d'inscription
RunnerEntryTime = Heure d'inscription
RunnerPaid = Payé
RunnerPayMethod = Méthode de payement
EntryTime = Heure d'inscription
Ekonomihantering, X = Gestion financière, X
Manuellt gjorda justeringar = Ajustements manuels
Antal förfrågningar: X = Nombre de requêtes
Genomsnittlig svarstid: X ms = Temps moyen de réponse : X
Informationsserver = Informations serveur
Längsta svarstid: X ms = Temps de réponse maximal : X
MeOS Informationsserver REST-API = MeOS Information Server REST-API
Testa servern = Tester le serveur
help:rest = MeOS REST API vous permet d'accéder à la compétition via le web. Vous pouvez afficher les résultats directement sur un navigateur, mais aussi exporter les données de la course en XML pour les envoyer vers d'autres applications et programmes.
Server startad på X = Serveur sur le port X
Inconsistent qualification rule, X = Règle de qualification incohérente, X
help:LockStartList = MeOS ne va mas modifier les heures de départ d'une catégorie verrouillée, même si les résultats des qualifications sont modifiées
Kval/final-schema = Schéma de qualifications/finale
Lås startlista = Verrouiller la liste de départ
FilterNoCancel = Pas annulés
CourseStartTime = Circuit, heure de départ
Startlista, banvis = Liste de départ par circuit
Stämplingsintervall, rogaining-patrull = Intervalle de poinçonnage dans la patrouille
Patrullresultat (STOR) = Résultats de la patrouille (GRAND)
Patrol Team Rogaining = Course au score en patrouille
Rogaining results for a patrol = Résultats de course au score pour binôme (ou plus)
Exportera ett kalkylblad med lottningsinställningar som du kan redigera och sedan läsa in igen = 0
Kalkylblad/csv = Tableur/csv
Importerar lottningsinställningar = Importer les paramètres des listes de départ
help:exportdraw = Vous pouvez exporter un tableur en CSV avec les catégories, le nombre d'inscrits et les paramètres des listes de départ par catégories. Il est ensuite possible d'éditer ces données et de les ré-importer dans MeOS pour créer les listes de départ.
prefsDrawInterlace = Entrelacer catégorie/circuits dans la liste de départ
prefsServicePort = Port par défaut X
Ingen nummerlapp = Num de dossard
Rogaining results for a team, where each team member collects points individually = Résultats de course au score pour binôme où chaque membre collecte des points de façon individuelle
prefsCodePage = Code table pour l'import/export en 8 bits
Inga klasser tillåter direktanmälan. På sidan klasser kan du ändra denna egenskap. = Aucune catégorie n'autorise les inscriptions rapides.\n\nVous pouvez modifier ce paramètre à la page 'Catégories'.
Database is used and cannot be deleted = La base de donnée est utilisée et ne peut être supprimée
Classes together = Catégories regroupées
Finish order = Ordre d'arrivée
First to finish = Premier qui a fini
Individual result by finish time = Résultat individuel sur l'heure d'arrivée
Endast tidtagning = Chronométrage seul
AllPunches = Tous les poinçons
CoursePunches = Poinçons (sur le circuit)
FilterNamedControl = Postes nommés
FilterNotFinish = Uniquement les arrivés
LineBreak = Saut de ligne
PunchAbsTime = Poinçon, heure réelle
PunchTimeSinceLast = Temps entre les postes
PunchTotalTime = Temps au poste
PunchName = Poinçon, code du poste
PunchNamedSplit = Temps depuis le dernier poste nommé
PunchSplitTime = Temps depuis le dernier poste (temps intermédiaire)
ClassLiveResult = Live results (temps radios), par catégorie
Felaktigt datum 'X' (Använd YYYY-MM-DD) = Date incorrecte (Mettre AAAA-MM-JJ)
FilterAnyResult = Avec temps radios/résultats
Liveresultat, radiotider = Résultats en direct avec radios
PunchTotalTimeAfter = Temps passé au poste
RunnerCheck = Heure de contrôle
RunnerId = Licence/ID
StartTimeClass = Heure de départ, catégorie
ask:outofmaps = Plus de cartes disponibles. Voulez-vous tout de même inscrire ce coureur ?
Varning: Kartorna är slut = Attention : plus de cartes disponibles
X går vidare, klass enligt ranking = X qualifiés, catégorie par le ranking
Vill du ta bort schemat? = Voulez-vous supprimer le schéma ?
ask:removescheme = Si vous retirez le schéma de qualification, les résultats seront perdus. Voulez-vous continuer ?
ClassKnockoutTotalResult = Class, knock-out total result
Support intermediate legs = Supporter les variations spécifiques en relais
help:custom_text_lines = Vous pouvez insérer du texte spécifique en ajoutant en dessous [DonnéeSpécifique]. Les infos disponibles sont visibles dans le tableau déroulant à droite.\n\nPar exemple : Bravo [RunnerName] !
Importerar ranking = Importer le ranking
Klart. X värden tilldelade = Terminé. X valeurs assignées
Felaktigt rankingformat i X. Förväntat: Y = Format de classement incorrect pour X.\nY attendu
Importerar RAID patrull csv-fil = Importer les données RAID en csv
Varning: Följande deltagare har ett osäkert resultat = Attention : les informations sur ce coureur ne sont pas claires
Direkt tidtagning = Chronométrage en direct
Klassval för 'X' = Sélection de la catégorie pour 'X'
Endast tidtagning (utan banor) = Chronométrage seul (pas de circuits)
Knockout total = Résumé des éliminations
Varvräkning = Compter les tours
Varvräkning med mellantid = Compter les tours en temps supplémentaire
Without courses = Sans circuit
Timekeeping = Chronométrage
Endast grundläggande (enklast möjligt) = Fonctionnalités de base
Endast tidtagning (utan banor), stafett = Chronométrage seul (pas de circuits), relais
Individuellt = Individuel
Lag och stafett = Équipe et relais
Övrigt = Divers
htmlhelp = Le HTML peut être exporté comme un tableur structuré ou comme un document formaté librement
HTML Export = Export HTML
HTML Export för 'X' = Export HTML pour 'X'
Lagra inställningar = Enregistrer les paramètres
Kolumner = Colonnes
Rader = Lignes
HTML formaterad genom listinställningar = HTML formaté par les paramètres de la liste
Begränsa antal rader per sida = Nombre max de lignes par page
Färre slingor = Moins de boucles
RunnerGrossTime = Temps avant modifications
TeamGrossTime = Temps de l'équipe avant modification
Visa detaljerad rapport för viss deltagare = Afficher le rapport détaillé pour un coureur spécifique
Förhindra att laget deltar i någon omstart = Permet à l'équipe de ne pas prendre part au départ en masse des attardés
Förhindra omstart = Empêcher le redémarrage
Ej omstart = Pas de redémarrage
Visa rubrik mellan listorna = Afficher le titre entre les listes
Slå ihop med befintlig lista = Fusionner avec une liste existante
Från löpardatabasen = De la base de donnée coureurs
Från löpardatabasen i befintliga klubbar = De la base de donnée coureurs dan les clubs existants
Med direktanmälan = Avec inscription directe
Tillåt anmälan = Autoriser les inscriptions
Anyone = N'importe qui
Bricknummer = Numéro de puce
Anmäl andra = Nouvelle inscription
Anmälan mottagen = Inscription acceptée
Automatisk omladdning = Mise à jour automatique
Till vilka klasser = Pour quelles catégories
Vem får anmäla sig = Qui peut s'inscrire
Anmälan måste hanteras manuellt = Votre inscription nécessite un traitement manuel
EFilterAPIEntry = Inscriptions via API
Visa rubrik = Afficher le titre
Rad X är ogiltig = La ligne X est invalide
Klassen X är listad flera gånger = La catégorie X est listée plusieurs fois
Ogiltig starttid X = Heure de départ invalide : X
Ogiltigt startintervall X = Intervalle de départ invalide : X
Hittar inte klass X = Impossible de trouver la catégorie X
MeOS utvecklinsstöd = Aide au développement de MeOS
info:pageswithcolumns = Montrer la liste page par page, avec un nombre spécifié de colonnes. Les infos sont mises à jour à chaque bouclage.
Pages with columns = Pages avec colonnes
Pages with columns, no header = Pages avec colonnes, sans titre
Externa adresser = Liens externes
info:advanceinfo = Le service de transfert instantané des résultats a planté. Les résultats seront reçus avec quelques secondes de délais. C'est ce qui risque d'arriver si plus d'un service est lancé depuis cet ordinateur.
Klassen är full = La catégorie est déjà complète
Flytta upp = Monter
Flytta ner = Descendre
EFilterWrongFee = Frais d'inscription inattendu
RunnerExpectedFee = Tarif d'inscription attendu
Unexpected Fee = Tarifs d'inscription inattendus
Anmälningsdatum = Date d'inscription
Förväntad = Attendu
Registrera hyrbrickor = Pré-inscrire les puces louées
Vill du sätta hyrbricka på befintliga löpare med dessa brickor? = Voulez-vous distribuer les puces comptées comme louées à des coureurs déjà inscrits ?
Vill du ta bort brickan från hyrbrickslistan? = Voulez-vous retirer la puce de la liste des puces à louer ?
Vill du tömma listan med hyrbrickor? = Voulez-vous supprimer la liste des puces à louer ?
prefsLastExportTarget = Cible du dernier export
prefsServiceRootMap = Fonctions standard pour la source du serveur Web
prefsshowheader = Afficher les titres
help:registerhiredcards = Pré-inscrivez des puces comme puces louées pour assigner automatiquement le statut et le tarif correspondant quand cette puce est assignée.
Lagändringblankett = Modifications d'équipes
Mappa rootadresssen (http:///localhost:port/) till funktion = Map root address (http:///localhost:port/) to function ($2428)
ClassAvailableMaps = Cartes disponibles pour la catégorie
ClassTotalMaps = Nombre total de cartes pour la catégorie
Export split times = Exporter les temps intermédiaires

View File

@ -59,6 +59,7 @@ const int timeSeconds = 1<<14;
const int timerIgnoreSign = 1<<15; const int timerIgnoreSign = 1<<15;
const int Capitalize = 1<<16; const int Capitalize = 1<<16;
const int absolutePosition = 1 << 17; const int absolutePosition = 1 << 17;
const int skipBoundingBox = 1 << 18;
enum GDICOLOR {colorBlack = RGB(0,0,0), enum GDICOLOR {colorBlack = RGB(0,0,0),
colorRed = RGB(128,0,0), colorRed = RGB(128,0,0),

View File

@ -311,6 +311,7 @@ void gdioutput::initCommon(double _scale, const wstring &font)
Background=CreateSolidBrush(GetSysColor(COLOR_WINDOW)); Background=CreateSolidBrush(GetSysColor(COLOR_WINDOW));
fontHeightCache.clear();
fonts[currentFont].init(scale, currentFont, L""); fonts[currentFont].init(scale, currentFont, L"");
} }
@ -846,10 +847,37 @@ TextInfo &gdioutput::addStringUT(int yp, int xp, int format, const string &text,
return addStringUT(yp, xp, format, widen(text), xlimit, cb, fontFace); return addStringUT(yp, xp, format, widen(text), xlimit, cb, fontFace);
} }
int gdioutput::getFontHeight(int format, const wstring &fontFace) const {
format = format & 0xFF;
auto res = fontHeightCache.find(make_pair(format, fontFace));
if (res != fontHeightCache.end())
return res->second;
TextInfo TI;
TI.format = format;
TI.xp = 0;
TI.yp = 0;
TI.text = L"M1y|";
TI.xlimit = 100;
TI.callBack = 0;
TI.font = fontFace;
calcStringSize(TI);
int h = TI.textRect.bottom - TI.textRect.top;
fontHeightCache.emplace(make_pair(format, fontFace), h);
return h;
}
TextInfo &gdioutput::addStringUT(int yp, int xp, int format, const wstring &text, TextInfo &gdioutput::addStringUT(int yp, int xp, int format, const wstring &text,
int xlimit, GUICALLBACK cb, const wchar_t *fontFace) int xlimit, GUICALLBACK cb, const wchar_t *fontFace)
{ {
TextInfo TI; bool skipBBCalc = (format & skipBoundingBox) == skipBoundingBox;
format &= ~skipBoundingBox;
TL.emplace_back();
TextInfo &TI = TL.back();
itTL = TL.begin();
TI.format=format; TI.format=format;
TI.xp=xp; TI.xp=xp;
TI.yp=yp; TI.yp=yp;
@ -859,6 +887,20 @@ TextInfo &gdioutput::addStringUT(int yp, int xp, int format, const wstring &text
if (fontFace) if (fontFace)
TI.font = fontFace; TI.font = fontFace;
if (!skipTextRender(format)) { if (!skipTextRender(format)) {
if (skipBBCalc) {
assert(xlimit > 0);
int h = getFontHeight(format, fontFace);
TI.textRect.left = xp;
TI.textRect.top = yp;
TI.textRect.right = xp + xlimit;
TI.textRect.bottom = yp + h;
TI.realWidth = xlimit;
updatePos(TI.textRect.right + OffsetX, TI.yp, scaleLength(10),
TI.textRect.bottom - TI.textRect.top + scaleLength(2));
}
else {
HDC hDC = GetDC(hWndTarget); HDC hDC = GetDC(hWndTarget);
if (hWndTarget && !manualUpdate) if (hWndTarget && !manualUpdate)
@ -874,8 +916,8 @@ TextInfo &gdioutput::addStringUT(int yp, int xp, int format, const wstring &text
updatePos(TI.xp, TI.yp, TI.realWidth + scaleLength(10), updatePos(TI.xp, TI.yp, TI.realWidth + scaleLength(10),
TI.textRect.bottom - TI.textRect.top + scaleLength(2)); TI.textRect.bottom - TI.textRect.top + scaleLength(2));
} }
ReleaseDC(hWndTarget, hDC); ReleaseDC(hWndTarget, hDC);
}
if (renderOptimize && !TL.empty()) { if (renderOptimize && !TL.empty()) {
if (TL.back().yp > TI.yp) if (TL.back().yp > TI.yp)
@ -889,9 +931,6 @@ TextInfo &gdioutput::addStringUT(int yp, int xp, int format, const wstring &text
TI.textRect.top = yp; TI.textRect.top = yp;
} }
TL.push_back(TI);
itTL=TL.begin();
return TL.back(); return TL.back();
} }
@ -6076,15 +6115,13 @@ void gdioutput::liftCommandLock() const {
} }
int gdioutput::getLineHeight(gdiFonts font, const wchar_t *face) const { int gdioutput::getLineHeight(gdiFonts font, const wchar_t *face) const {
TextInfo ti; int h;
ti.xp = 0; if (face == nullptr)
ti.yp = 0; h = getFontHeight(font, _EmptyWString);
ti.format = font; else
ti.text = L"&abc_M|!I"; h = getFontHeight(font, face);
if (face)
ti.font = face; return (11*h)/10;
calcStringSize(ti);
return (11*(ti.textRect.bottom - ti.textRect.top))/10;
} }
GDIImplFontSet::GDIImplFontSet() { GDIImplFontSet::GDIImplFontSet() {

View File

@ -184,6 +184,8 @@ protected:
HBRUSH Background; HBRUSH Background;
mutable map<pair<int, wstring>, int> fontHeightCache;
map<wstring, GDIImplFontSet> fonts; map<wstring, GDIImplFontSet> fonts;
const GDIImplFontSet &getCurrentFont() const; const GDIImplFontSet &getCurrentFont() const;
const GDIImplFontSet &getFont(const wstring &font) const; const GDIImplFontSet &getFont(const wstring &font) const;
@ -596,9 +598,7 @@ public:
bool clearList(const string &id); bool clearList(const string &id);
bool hasField(const string &id) const; bool hasField(const string &id) const;
/*const wstring &getText(const wchar_t *id, bool acceptMissing = false) const {
return getText(toNarrow(id).c_str(), acceptMissing);
}*/
const wstring &getText(const char *id, bool acceptMissing = false) const; const wstring &getText(const char *id, bool acceptMissing = false) const;
BaseInfo &getBaseInfo(const char *id) const; BaseInfo &getBaseInfo(const char *id) const;
@ -616,6 +616,8 @@ public:
// Insert text and notify "focusList" // Insert text and notify "focusList"
bool insertText(const string &id, const wstring &text); bool insertText(const string &id, const wstring &text);
int getFontHeight(int format, const wstring &fontFace) const;
// The html version should be UTF-8. // The html version should be UTF-8.
void copyToClipboard(const string &html, void copyToClipboard(const string &html,
const wstring &txt) const; const wstring &txt) const;

View File

@ -963,6 +963,7 @@ void DynamicResult::declareSymbols(DynamicMethods m, bool clear) const {
parser.declareSymbol("LegPlace", "Place on course leg", true); parser.declareSymbol("LegPlace", "Place on course leg", true);
parser.declareSymbol("Leg", "Leg number in team, zero indexed", false); parser.declareSymbol("Leg", "Leg number in team, zero indexed", false);
parser.declareSymbol("BirthYear", "Year of birth", false); parser.declareSymbol("BirthYear", "Year of birth", false);
parser.declareSymbol("CheckTime", "Runner check time", false);
} }
else { else {
parser.declareSymbol("RunnerStatus", "Status for each team member", true); parser.declareSymbol("RunnerStatus", "Status for each team member", true);
@ -1276,6 +1277,7 @@ void DynamicResult::prepareCalculations(oRunner &runner) const {
parser.addSymbol("LegPlace", place); parser.addSymbol("LegPlace", place);
parser.addSymbol("Leg", runner.getLegNumber()); parser.addSymbol("Leg", runner.getLegNumber());
parser.addSymbol("BirthYear", runner.getBirthYear()); parser.addSymbol("BirthYear", runner.getBirthYear());
parser.addSymbol("CheckTime", runner.getCheckTime());
} }
void DynamicResult::storeOutput(vector<int> &times, vector<int> &numbers) const { void DynamicResult::storeOutput(vector<int> &times, vector<int> &numbers) const {

View File

@ -812,6 +812,7 @@ void xmlbuffer::startXML(xmlparser &xml, const wstring &dest) {
} }
bool xmlbuffer::commit(xmlparser &xml, int count) { bool xmlbuffer::commit(xmlparser &xml, int count) {
vector<wstring> p2;
while (count>0 && !blocks.empty()) { while (count>0 && !blocks.empty()) {
block &block = blocks.front(); block &block = blocks.front();
@ -819,12 +820,20 @@ bool xmlbuffer::commit(xmlparser &xml, int count) {
xml.write(block.tag.c_str(), block.prop, block.value); xml.write(block.tag.c_str(), block.prop, block.value);
} }
else { else {
vector<wstring> p2; if (block.prop.size() > 1) {
p2.resize(block.prop.size() * 2);
for (size_t k = 0; k < block.prop.size(); k++) { for (size_t k = 0; k < block.prop.size(); k++) {
p2.push_back(gdi_main->widen(block.prop[k].first)); p2[k * 2] = gdi_main->widen(block.prop[k].first);
p2.push_back(block.prop[k].second); p2[k * 2 + 1] = std::move(block.prop[k].second);
} }
xml.startTag(block.tag.c_str(), p2); xml.startTag(block.tag.c_str(), p2);
}
else if (block.prop.size() == 1) {
xml.startTag(block.tag.c_str(), block.prop[0].first.c_str(), block.prop[0].second);
}
else if (block.prop.empty()) {
xml.startTag(block.tag.c_str());
}
for (size_t k = 0; k < block.subValues.size(); k++) for (size_t k = 0; k < block.subValues.size(); k++)
block.subValues[k].commit(xml, numeric_limits<int>::max()); block.subValues[k].commit(xml, numeric_limits<int>::max());

View File

@ -106,6 +106,13 @@ void IOF30Interface::readCourseData(gdioutput &gdi, const xmlobject &xo, bool up
failed++; failed++;
} }
vector<pCourse> allC;
oe.getCourses(allC);
for (pCourse pc : allC) {
if (!courses.count(pc->getName()))
courses[pc->getName()] = pc;
}
if (!updateClass) if (!updateClass)
return; return;
@ -399,6 +406,13 @@ void IOF30Interface::teamCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
if (!bib.empty()) { if (!bib.empty()) {
teamText = bib; teamText = bib;
t = bib2Team[bib]; t = bib2Team[bib];
if (t == nullptr) {
int ibib = _wtoi(bib.c_str());
if (ibib > 0) {
wstring bib2 = itow(ibib);
t = bib2Team[bib2];
}
}
} }
if (t == 0) { if (t == 0) {
@ -2534,9 +2548,9 @@ void IOF30Interface::getLocalDateTime(const string &date, const string &time,
SystemTimeToTzSpecificLocalTime(0, &st, &localTime); SystemTimeToTzSpecificLocalTime(0, &st, &localTime);
char bf[64]; char bf[64];
sprintf(bf, "%02d:%02d:%02d", localTime.wHour, localTime.wMinute, localTime.wSecond); sprintf_s(bf, "%02d:%02d:%02d", localTime.wHour, localTime.wMinute, localTime.wSecond);
timeOut = bf; timeOut = bf;
sprintf(bf, "%d-%02d-%02d", localTime.wYear, localTime.wMonth, localTime.wDay); sprintf_s(bf, "%d-%02d-%02d", localTime.wYear, localTime.wMonth, localTime.wDay);
dateOut = bf; dateOut = bf;
} }
else { else {
@ -3529,7 +3543,8 @@ bool IOF30Interface::readXMLCompetitorDB(const xmlobject &xCompetitor) {
return true; return true;
} }
void IOF30Interface::writeXMLCompetitorDB(xmlparser &xml, const RunnerWDBEntry &rde) const { void IOF30Interface::writeXMLCompetitorDB(xmlparser &xml, const RunnerDB &db,
const RunnerWDBEntry &rde) const {
wstring s = rde.getSex(); wstring s = rde.getSex();
xml.startTag("Competitor"); xml.startTag("Competitor");
@ -3566,10 +3581,19 @@ void IOF30Interface::writeXMLCompetitorDB(xmlparser &xml, const RunnerWDBEntry &
if (rde.dbe().clubNo > 0) { if (rde.dbe().clubNo > 0) {
pClub clb = db.getClub(rde.dbe().clubNo);
if (clb) {
uint64_t extId = clb->getExtIdentifier();
if (extId != 0) {
xml.startTag("Organisation"); xml.startTag("Organisation");
xml.write("Id", rde.dbe().clubNo); xml.write("Id", int(extId));
xml.endTag(); xml.endTag();
} }
else {
writeClub(xml, *clb, false);
}
}
}
xml.endTag(); // Competitor xml.endTag(); // Competitor
} }
@ -3926,7 +3950,7 @@ void IOF30Interface::writeRunnerDB(const RunnerDB &db, xmlparser &xml) const {
const vector<RunnerWDBEntry> &rdb = db.getRunnerDB(); const vector<RunnerWDBEntry> &rdb = db.getRunnerDB();
for (size_t k = 0; k < rdb.size(); k++) { for (size_t k = 0; k < rdb.size(); k++) {
if (!rdb[k].isRemoved()) if (!rdb[k].isRemoved())
writeXMLCompetitorDB(xml, rdb[k]); writeXMLCompetitorDB(xml, db, rdb[k]);
} }
xml.endTag(); xml.endTag();

View File

@ -232,7 +232,7 @@ class IOF30Interface {
int getStageNumber(); int getStageNumber();
bool readXMLCompetitorDB(const xmlobject &xCompetitor); bool readXMLCompetitorDB(const xmlobject &xCompetitor);
void writeXMLCompetitorDB(xmlparser &xml, const RunnerWDBEntry &rde) const; void writeXMLCompetitorDB(xmlparser &xml, const RunnerDB &db, const RunnerWDBEntry &rde) const;
int getStartIndex(const wstring &startId); int getStartIndex(const wstring &startId);

View File

@ -30,7 +30,7 @@
//V35: abcdef //V35: abcdef
//V36: abcdef //V36: abcdef
int getMeosBuild() { int getMeosBuild() {
string revision("$Rev: 895 $"); string revision("$Rev: 912 $");
return 174 + atoi(revision.substr(5, string::npos).c_str()); return 174 + atoi(revision.substr(5, string::npos).c_str());
} }
@ -42,12 +42,12 @@ int getMeosBuild() {
//V33: abcdefghij //V33: abcdefghij
//V34: abcdfge //V34: abcdfge
wstring getMeosDate() { wstring getMeosDate() {
wstring date(L"$Date: 2019-05-11 07:26:35 +0200 (lö, 11 maj 2019) $"); wstring date(L"$Date: 2019-06-16 10:37:59 +0200 (sö, 16 jun 2019) $");
return date.substr(7,10); return date.substr(7,10);
} }
wstring getBuildType() { wstring getBuildType() {
return L""; // No parantheses (...) return L"Update 1"; // No parantheses (...)
} }
wstring getMajorVersion() { wstring getMajorVersion() {
@ -130,5 +130,8 @@ void getSupporters(vector<wstring> &supp, vector<wstring> &developSupp)
supp.emplace_back(L"IP Skogen Göteborg"); supp.emplace_back(L"IP Skogen Göteborg");
supp.emplace_back(L"Smedjebackens Orientering"); supp.emplace_back(L"Smedjebackens Orientering");
supp.emplace_back(L"Gudhems IF"); supp.emplace_back(L"Gudhems IF");
supp.emplace_back(L"Kexholm SK");
supp.emplace_back(L"Utby IK");
supp.emplace_back(L"JWOC 2019");
reverse(supp.begin(), supp.end()); reverse(supp.begin(), supp.end());
} }

View File

@ -549,6 +549,8 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
oPrintPost *last = 0; oPrintPost *last = 0;
oPrintPost *base = 0; oPrintPost *base = 0;
auto indexPosToWidthSrc = indexPosToWidth;
int totalWidth = pos.getWidth(); int totalWidth = pos.getWidth();
for (map<pair<int, int>, int>::iterator it = linePostCount.begin(); it != linePostCount.end(); ++it) { for (map<pair<int, int>, int>::iterator it = linePostCount.begin(); it != linePostCount.end(); ++it) {
if (it->second == 1) { if (it->second == 1) {
@ -606,7 +608,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
added.resultModuleIndex = getResultModuleIndex(oe, li, mp); added.resultModuleIndex = getResultModuleIndex(oe, li, mp);
setFixedWidth(added, indexPosToWidth, MLHead, j, k); setFixedWidth(added, indexPosToWidth, MLHead, j, k);
added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLHead, j, k)];
added.color = mp.color; added.color = mp.color;
if (!mp.mergeWithPrevious) if (!mp.mergeWithPrevious)
base = &added; base = &added;
@ -657,7 +659,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
added.resultModuleIndex = getResultModuleIndex(oe, li, mp); added.resultModuleIndex = getResultModuleIndex(oe, li, mp);
setFixedWidth(added, indexPosToWidth, MLSubHead, j, k); setFixedWidth(added, indexPosToWidth, MLSubHead, j, k);
added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLSubHead, j, k)];
added.color = mp.color; added.color = mp.color;
if (!mp.mergeWithPrevious) if (!mp.mergeWithPrevious)
base = &added; base = &added;
@ -703,6 +705,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
added.resultModuleIndex = getResultModuleIndex(oe, li, mp); added.resultModuleIndex = getResultModuleIndex(oe, li, mp);
setFixedWidth(added, indexPosToWidth, MLList, j, k); setFixedWidth(added, indexPosToWidth, MLList, j, k);
added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLList, j, k)];
added.color = mp.color; added.color = mp.color;
if (!mp.mergeWithPrevious) if (!mp.mergeWithPrevious)
@ -756,6 +759,7 @@ void MetaList::interpret(oEvent *oe, const gdioutput &gdi, const oListParam &par
added.resultModuleIndex = getResultModuleIndex(oe, li, mp); added.resultModuleIndex = getResultModuleIndex(oe, li, mp);
setFixedWidth(added, indexPosToWidth, MLSubList, j, k); setFixedWidth(added, indexPosToWidth, MLSubList, j, k);
added.xlimit = indexPosToWidthSrc[tuple<int, int, int>(MLSubList, j, k)];
if (last && mp.mergeWithPrevious) { if (last && mp.mergeWithPrevious) {
last->doMergeNext = true; last->doMergeNext = true;
@ -1656,6 +1660,7 @@ void MetaList::initSymbols() {
typeToSymbol[lClassResultFraction] = L"ClassResultFraction"; typeToSymbol[lClassResultFraction] = L"ClassResultFraction";
typeToSymbol[lClassAvailableMaps] = L"ClassAvailableMaps"; typeToSymbol[lClassAvailableMaps] = L"ClassAvailableMaps";
typeToSymbol[lClassTotalMaps] = L"ClassTotalMaps"; typeToSymbol[lClassTotalMaps] = L"ClassTotalMaps";
typeToSymbol[lClassNumEntries] = L"ClassNumEntries";
typeToSymbol[lCourseLength] = L"CourseLength"; typeToSymbol[lCourseLength] = L"CourseLength";
typeToSymbol[lCourseName] = L"CourseName"; typeToSymbol[lCourseName] = L"CourseName";
typeToSymbol[lCourseClimb] = L"CourseClimb"; typeToSymbol[lCourseClimb] = L"CourseClimb";

View File

@ -65,7 +65,6 @@ oCard::~oCard()
bool oCard::Write(xmlparser &xml) bool oCard::Write(xmlparser &xml)
{ {
if (Removed) return true; if (Removed) return true;
xml.startTag("Card"); xml.startTag("Card");
xml.write("CardNo", cardNo); xml.write("CardNo", cardNo);
xml.write("Punches", getPunchString()); xml.write("Punches", getPunchString());
@ -137,17 +136,13 @@ void oCard::addPunch(int type, int time, int matchControlId)
updateChanged(); updateChanged();
} }
string oCard::getPunchString() const string &oCard::getPunchString() const {
{ punchString.clear();
oPunchList::iterator it; punchString.reserve(punches.size() * 16);
for(auto &p : punches) {
string pstring; p.appendCodeString(punchString);
for(it=punches.begin(); it != punches.end(); ++it){
pstring += it->codeString();
} }
return punchString;
return pstring;
} }
void oCard::importPunches(const string &s) { void oCard::importPunches(const string &s) {

View File

@ -69,6 +69,8 @@ protected:
void changedObject(); void changedObject();
mutable string punchString;
public: public:
// Returns true if the card was constructed from punches. // Returns true if the card was constructed from punches.
@ -126,7 +128,7 @@ public:
const wstring &getCardNoString() const; const wstring &getCardNoString() const;
void setCardNo(int c); void setCardNo(int c);
void importPunches(const string &s); void importPunches(const string &s);
string getPunchString(); const string &getPunchString() const;
void Set(const xmlobject &xo); void Set(const xmlobject &xo);
bool Write(xmlparser &xml); bool Write(xmlparser &xml);

View File

@ -103,7 +103,6 @@ oClass::~oClass()
bool oClass::Write(xmlparser &xml) bool oClass::Write(xmlparser &xml)
{ {
if (Removed) return true; if (Removed) return true;
xml.startTag("Class"); xml.startTag("Class");
xml.write("Id", Id); xml.write("Id", Id);
@ -359,26 +358,145 @@ void oClass::importLegMethod(const string &legMethods)
apply(); apply();
} }
string oClass::getCountTypeKey(int leg, CountKeyType type, bool countVacant) {
return itos(leg) + ":" + itos(type) + (countVacant ? "V" : "");
}
int oClass::getNumRunners(bool checkFirstLeg, bool noCountVacant, bool noCountNotCompeting) const { int oClass::getNumRunners(bool checkFirstLeg, bool noCountVacant, bool noCountNotCompeting) const {
int nRunners=0; if (tTypeKeyToRunnerCount.first != oe->dataRevision) {
oRunnerList::iterator it; for (auto &c : oe->Classes) {
c.tTypeKeyToRunnerCount.second.clear();
c.tTypeKeyToRunnerCount.first = oe->dataRevision;
}
}
string key = getCountTypeKey(checkFirstLeg ? 0 : -1,
noCountNotCompeting ? CountKeyType::All : CountKeyType::IncludeNotCompeting,
!noCountVacant);
for (it=oe->Runners.begin(); it != oe->Runners.end(); ++it) { auto res = tTypeKeyToRunnerCount.second.find(key);
if (it->getClassId(true)==Id) { if (res != tTypeKeyToRunnerCount.second.end())
if (it->skip()) return res->second;
unordered_map<int, int> nRunners;
for (auto &r : oe->Runners) {
if (r.isRemoved() || !r.Class)
continue; continue;
if (checkFirstLeg && it->tLeg > 0) if (checkFirstLeg && (r.tLeg > 0 && !r.Class->isQualificationFinalBaseClass()))
continue; continue;
if (noCountVacant && it->isVacant()) if (noCountVacant && r.isVacant())
continue; continue;
if (noCountNotCompeting && it->getStatus() == StatusNotCompetiting) if (noCountNotCompeting && r.getStatus() == StatusNotCompetiting)
continue; continue;
nRunners++;
} int id = r.getClassId(true);
} ++nRunners[id];
return nRunners;
} }
for (auto &c : oe->Classes) {
if (!c.isRemoved())
c.tTypeKeyToRunnerCount.second[key] = nRunners[c.Id];
}
return nRunners[Id];
}
void oClass::getNumResults(int leg, int &total, int &finished, int &dns) const {
if (tTypeKeyToRunnerCount.first != oe->dataRevision) {
for (auto &c : oe->Classes) {
c.tTypeKeyToRunnerCount.second.clear();
c.tTypeKeyToRunnerCount.first = oe->dataRevision;
}
}
string keyTot = getCountTypeKey(leg, CountKeyType::ExpectedStarting, false);
string keyFinished = getCountTypeKey(leg, CountKeyType::Finished, false);
string keyDNS = getCountTypeKey(leg, CountKeyType::DNS, false);
auto rTot = tTypeKeyToRunnerCount.second.find(keyTot);
auto rFinished = tTypeKeyToRunnerCount.second.find(keyFinished);
auto rDNS = tTypeKeyToRunnerCount.second.find(keyDNS);
if (rTot != tTypeKeyToRunnerCount.second.end() &&
rFinished != tTypeKeyToRunnerCount.second.end() &&
rDNS != tTypeKeyToRunnerCount.second.end()) {
total = rTot->second;
finished = rFinished->second;
dns = rDNS->second;
return;
}
struct Cnt {
bool team = false;
bool singleClass = false;
int maxleg = 0;
int total = 0;
int finished = 0;
int dns = 0;
};
//Search runners
unordered_map<int, Cnt> cnt;
for (auto &c : oe->Classes) {
if (c.isRemoved())
continue;
ClassType ct = c.getClassType();
auto &cc = cnt[c.Id];
cc.maxleg = c.getLastStageIndex();
if (ct == oClassKnockout)
cc.singleClass = true || cc.maxleg == 1;
if (!(ct == oClassIndividual || ct == oClassIndividRelay || ct == oClassKnockout))
cnt[c.Id].team = true;
}
for (auto &r : oe->Runners) {
if (r.isRemoved() || !r.Class || r.tStatus == StatusNotCompetiting || r.tStatus == StatusCANCEL)
continue;
auto &c = cnt[r.getClassId(true)];
if (c.team)
continue;
int tleg = leg > 0 ? leg : c.maxleg;
if (r.tLeg == tleg || c.singleClass) {
c.total++;
if (r.tStatus != StatusUnknown)
c.finished++;
if (r.tStatus == StatusDNS)
c.dns++;
}
}
for (auto &t : oe->Teams) {
if (t.isRemoved() || !t.Class || t.tStatus == StatusNotCompetiting || t.tStatus == StatusCANCEL)
continue;
auto &c = cnt[t.getClassId(true)];
if (!c.team)
continue;
c.total++;
if (t.tStatus != StatusUnknown || t.getLegStatus(leg, false) != StatusUnknown)
c.finished++;
}
for (auto &c : oe->Classes) {
auto &cc = cnt[c.Id];
c.tTypeKeyToRunnerCount.second[keyDNS] = cc.dns;
c.tTypeKeyToRunnerCount.second[keyFinished] = cc.finished;
c.tTypeKeyToRunnerCount.second[keyTot] = cc.total;
}
auto &cc = cnt[Id];
dns = cc.dns;
total = cc.total;
finished = cc.finished;
}
void oClass::setCourse(pCourse c) void oClass::setCourse(pCourse c)
{ {
@ -1532,62 +1650,6 @@ ClassType oClass::getClassType() const
return oClassIndividual; return oClassIndividual;
} }
void oEvent::getNumClassRunners(int id, int leg, int &total, int &finished, int &dns) const
{
total=0;
finished=0;
dns = 0;
//Search runners
const oClass *pc = getClass(id);
if (!pc)
return;
ClassType ct=pc->getClassType();
if (ct == oClassIndividual || ct == oClassIndividRelay || ct == oClassKnockout) {
oRunnerList::const_iterator it;
int maxleg = pc->getLastStageIndex();
for (it = Runners.begin(); it != Runners.end(); ++it) {
if (!it->skip() && it->getClassId(true) == id && it->getStatus() != StatusNotCompetiting) {
if (leg == 0) {
total++;
if (it->tStatus != StatusUnknown)
finished++;
else if (it->tStatus == StatusDNS || it->tStatus == StatusCANCEL)
dns++;
}
else {
int tleg = leg > 0 ? leg : maxleg;
const pRunner r = it->getMultiRunner(tleg);
if (r) {
total++;
if (r->tStatus != StatusUnknown)
finished++;
else if (it->tStatus == StatusDNS || it->tStatus == StatusCANCEL)
dns++;
}
}
}
}
}
else {
oTeamList::const_iterator it;
for (it=Teams.begin(); it != Teams.end(); ++it) {
if (it->getClassId(true)==id) {
total++;
if (it->tStatus!=StatusUnknown ||
it->getLegStatus(leg, false)!=StatusUnknown)
finished++;
}
}
}
}
int oClass::getNumMultiRunners(int leg) const int oClass::getNumMultiRunners(int leg) const
{ {
int ndup=0; int ndup=0;
@ -3130,6 +3192,20 @@ void oClass::calculateSplits() {
LegResult legRes; LegResult legRes;
LegResult legBestTime; LegResult legBestTime;
vector<pRunner> rCls;
if (isQualificationFinalBaseClass() || isQualificationFinalBaseClass()) {
for (auto &r : oe->Runners) {
if (!r.isRemoved() && r.getClassRef(true) == this)
rCls.push_back(&r);
}
}
else {
for (auto &r : oe->Runners) {
if (!r.isRemoved() && r.Class == this)
rCls.push_back(&r);
}
}
for (set<pCourse>::iterator cit = cSet.begin(); cit!= cSet.end(); ++cit) { for (set<pCourse>::iterator cit = cSet.begin(); cit!= cSet.end(); ++cit) {
pCourse pc = *cit; pCourse pc = *cit;
@ -3142,9 +3218,7 @@ void oClass::calculateSplits() {
vector< vector<int> > splitsAcc(nc+1); vector< vector<int> > splitsAcc(nc+1);
vector<bool> acceptMissingPunch(nc+1, true); vector<bool> acceptMissingPunch(nc+1, true);
for (oRunnerList::iterator it = oe->Runners.begin(); it != oe->Runners.end(); ++it) { for (pRunner it : rCls) {
if (it->isRemoved() || it->getClassRef(true) != this)
continue;
pCourse tpc = it->getCourse(false); pCourse tpc = it->getCourse(false);
if (tpc != pc || tpc == 0) if (tpc != pc || tpc == 0)
continue; continue;
@ -3161,10 +3235,8 @@ void oClass::calculateSplits() {
} }
} }
} }
for (oRunnerList::iterator it = oe->Runners.begin(); it != oe->Runners.end(); ++it) {
if (it->isRemoved() || it->getClassRef(true) != this)
continue;
for (pRunner it : rCls) {
pCourse tpc = it->getCourse(false); pCourse tpc = it->getCourse(false);
if (tpc != pc) if (tpc != pc)

View File

@ -284,6 +284,19 @@ protected:
mutable int tMapsUsed; mutable int tMapsUsed;
mutable int tMapsUsedNoVacant; mutable int tMapsUsedNoVacant;
// First is data revision, second is key
mutable pair<int, map<string, int>> tTypeKeyToRunnerCount;
enum CountKeyType {
All,
Finished,
ExpectedStarting,
DNS,
IncludeNotCompeting
};
static string getCountTypeKey(int leg, CountKeyType type, bool countVacant);
void configureInstance(int instance, bool allowCreation) const; void configureInstance(int instance, bool allowCreation) const;
public: public:
@ -543,6 +556,7 @@ public:
// Get total number of runners running this class. // Get total number of runners running this class.
// Use checkFirstLeg to only check the number of runners running leg 1. // Use checkFirstLeg to only check the number of runners running leg 1.
int getNumRunners(bool checkFirstLeg, bool noCountVacant, bool noCountNotCompeting) const; int getNumRunners(bool checkFirstLeg, bool noCountVacant, bool noCountNotCompeting) const;
void getNumResults(int leg, int &total, int &finished, int &dns) const;
//Get remaining maps for class (or int::minvalue) //Get remaining maps for class (or int::minvalue)
int getNumRemainingMaps(bool forceRecalculate) const; int getNumRemainingMaps(bool forceRecalculate) const;

View File

@ -415,8 +415,7 @@ bool oCourse::fillCourse(gdioutput &gdi, const string &name)
return true; return true;
} }
void oCourse::getControls(vector<pControl> &pc) void oCourse::getControls(vector<pControl> &pc) const {
{
pc.clear(); pc.clear();
pc.reserve(nControls); pc.reserve(nControls);
for(int k=0;k<nControls;k++){ for(int k=0;k<nControls;k++){
@ -424,6 +423,14 @@ void oCourse::getControls(vector<pControl> &pc)
} }
} }
vector<int> oCourse::getControlNumbers() const {
vector<int> ret;
for (int k = 0; k<nControls; k++) {
ret.push_back(Controls[k]->getFirstNumber());
}
return ret;
}
int oCourse::distance(const SICard &card) int oCourse::distance(const SICard &card)
{ {
int matches=0; int matches=0;

View File

@ -211,7 +211,9 @@ public:
pControl addControl(int Id); pControl addControl(int Id);
void Set(const xmlobject *xo); void Set(const xmlobject *xo);
void getControls(vector<pControl> &pc); void getControls(vector<pControl> &pc) const;
vector<int> getControlNumbers() const;
string getControls() const; string getControls() const;
string getLegLengths() const; string getLegLengths() const;

View File

@ -1134,11 +1134,19 @@ bool oEvent::open(const xmlparser &xml) {
ZeroTime = 0; ZeroTime = 0;
xo = xml.getObject("Date"); xo = xml.getObject("Date");
if (xo) Date=xo.getw(); if (xo) {
wstring fDate = xo.getw();
if (convertDateYMS(fDate, true) > 0)
Date = fDate;
}
Name.clear();
xo = xml.getObject("Name"); xo = xml.getObject("Name");
if (xo) Name=xo.getw(); if (xo) Name=xo.getw();
if (Name.empty()) {
Name = lang.tl("Ny tävling");
}
xo = xml.getObject("Annotation"); xo = xml.getObject("Annotation");
if (xo) Annotation = xo.getw(); if (xo) Annotation = xo.getw();
@ -1719,6 +1727,7 @@ pRunner oEvent::addRunner(const oRunner &r, bool updateStartNo) {
Runners.push_back(r); Runners.push_back(r);
pRunner pr=&Runners.back(); pRunner pr=&Runners.back();
//cardToRunnerHash.reset();
if (cardToRunnerHash && r.getCardNo() != 0) { if (cardToRunnerHash && r.getCardNo() != 0) {
cardToRunnerHash->emplace(r.getCardNo(), pr); cardToRunnerHash->emplace(r.getCardNo(), pr);
} }
@ -2637,13 +2646,12 @@ void oEvent::removeRunner(const vector<int> &ids)
continue; //Already found. continue; //Already found.
//Remove a singe runner team //Remove a singe runner team
autoRemoveTeam(r); for (size_t k = 0; k < r->multiRunner.size(); k++) {
for (size_t k=0;k<r->multiRunner.size();k++)
if (r->multiRunner[k]) if (r->multiRunner[k])
toRemove.insert(r->multiRunner[k]->getId()); toRemove.insert(r->multiRunner[k]->getId());
}
toRemove.insert(Id); autoRemoveTeam(r);
toRemove.insert(r->Id);
} }
if (toRemove.empty()) if (toRemove.empty())
@ -4797,8 +4805,7 @@ wstring oEvent::getPropertyStringDecrypt(const char *name, const string &def)
return prop2; return prop2;
} }
void oEvent::setPropertyEncrypt(const char *name, const string &prop) void oEvent::setPropertyEncrypt(const char *name, const string &prop) {
{
wchar_t bf[MAX_COMPUTERNAME_LENGTH + 1]; wchar_t bf[MAX_COMPUTERNAME_LENGTH + 1];
DWORD len = MAX_COMPUTERNAME_LENGTH + 1; DWORD len = MAX_COMPUTERNAME_LENGTH + 1;
GetComputerName(bf, &len); GetComputerName(bf, &len);
@ -4822,18 +4829,11 @@ void oEvent::setPropertyEncrypt(const char *name, const string &prop)
setProperty(name, gdibase.widen(prop2)); setProperty(name, gdibase.widen(prop2));
} }
void oEvent::setProperty(const char *name, int prop) void oEvent::setProperty(const char *name, int prop) {
{
eventProperties[name]=itow(prop); eventProperties[name]=itow(prop);
} }
/*
void oEvent::setProperty(const char *name, const string &prop)
{
eventProperties[name]=gdibase.toWide(prop);
}*/
void oEvent::setProperty(const char *name, const wstring &prop) void oEvent::setProperty(const char *name, const wstring &prop) {
{
eventProperties[name] = prop; eventProperties[name] = prop;
} }
@ -5762,10 +5762,11 @@ void oEvent::sanityCheck(gdioutput &gdi, bool expectResult, int onlyThisClass) {
if (!it->tInTeam) { if (!it->tInTeam) {
ClassType type = it->Class->getClassType(); ClassType type = it->Class->getClassType();
int cid = it->Class->getId();
if (type == oClassIndividRelay) { if (type == oClassIndividRelay) {
it->setClassId(0, true); it->setClassId(0, true);
it->setClassId(it->Class->getId(), true); it->setClassId(cid, true);
it->synchronize(); it->synchronizeAll();
} }
else if (type == oClassRelay) { else if (type == oClassRelay) {
if (!warnNoTeam) { if (!warnNoTeam) {

View File

@ -650,8 +650,6 @@ public:
void calculateSplitResults(int controlIdFrom, int controlIdTo); void calculateSplitResults(int controlIdFrom, int controlIdTo);
// Get total number of completed runner for given class and leg.
void getNumClassRunners(int id, int leg, int &total, int &finished, int &dns) const;
pTeam findTeam(const wstring &s, int lastId, unordered_set<int> &filter) const; pTeam findTeam(const wstring &s, int lastId, unordered_set<int> &filter) const;
pRunner findRunner(const wstring &s, int lastId, const unordered_set<int> &inputFilter, unordered_set<int> &filter) const; pRunner findRunner(const wstring &s, int lastId, const unordered_set<int> &inputFilter, unordered_set<int> &filter) const;
@ -826,7 +824,7 @@ protected:
mutable multimap<int, oAbstractRunner*> bibStartNoToRunnerTeam; mutable multimap<int, oAbstractRunner*> bibStartNoToRunnerTeam;
mutable shared_ptr<unordered_multimap<int, pRunner>> cardToRunnerHash; mutable shared_ptr<unordered_multimap<int, pRunner>> cardToRunnerHash;
unordered_multimap<int, pRunner> &getCardToRunner() const; vector<pRunner> getCardToRunner(int cardNo) const;
mutable set<int> hiredCardHash; mutable set<int> hiredCardHash;
mutable int tHiredCardHashDataRevision = -1; mutable int tHiredCardHashDataRevision = -1;

View File

@ -61,7 +61,6 @@ oFreePunch::~oFreePunch(void)
bool oFreePunch::Write(xmlparser &xml) bool oFreePunch::Write(xmlparser &xml)
{ {
if (Removed) return true; if (Removed) return true;
xml.startTag("Punch"); xml.startTag("Punch");
xml.write("CardNo", CardNo); xml.write("CardNo", CardNo);
xml.write("Time", Time); xml.write("Time", Time);

View File

@ -2255,7 +2255,7 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
xml.startTag("ResultList"); xml.startTag("ResultList");
xml.write("IOFVersion", "version", L"2.0.3"); xml.write("IOFVersion", "version", L"2.0.3");
wstring hhmmss = L"HH:MM:SS";
exportIOFEvent(xml); exportIOFEvent(xml);
bool ClassStarted=false; bool ClassStarted=false;
@ -2304,13 +2304,13 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
xml.startTag("Result"); xml.startTag("Result");
xml.startTag("StartTime"); xml.startTag("StartTime");
xml.write("Clock", "clockFormat", L"HH:MM:SS", formatTimeIOF(it->getStartTime(), ZeroTime)); xml.write("Clock", "clockFormat", hhmmss, formatTimeIOF(it->getStartTime(), ZeroTime));
xml.endTag(); xml.endTag();
xml.startTag("FinishTime"); xml.startTag("FinishTime");
xml.write("Clock", "clockFormat", L"HH:MM:SS", formatTimeIOF(it->getLegFinishTime(-1), ZeroTime)); xml.write("Clock", "clockFormat", hhmmss, formatTimeIOF(it->getLegFinishTime(-1), ZeroTime));
xml.endTag(); xml.endTag();
xml.write("Time", "timeFormat", L"HH:MM:SS", formatTimeIOF(it->getLegRunningTime(-1, false), 0)); xml.write("Time", "timeFormat", hhmmss, formatTimeIOF(it->getLegRunningTime(-1, false), 0));
xml.write("ResultPosition", it->getLegPlaceS(-1, false)); xml.write("ResultPosition", it->getLegPlaceS(-1, false));
xml.write("CompetitorStatus", "value", it->Runners[0]->getIOFStatusS()); xml.write("CompetitorStatus", "value", it->Runners[0]->getIOFStatusS());
@ -2333,7 +2333,7 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
xml.startTag("SplitTime", "sequence", itos(no++)); xml.startTag("SplitTime", "sequence", itos(no++));
xml.write("ControlCode", pcourse->Controls[k]->getFirstNumber()); xml.write("ControlCode", pcourse->Controls[k]->getFirstNumber());
if (unsigned(k)<sp.size() && sp[k].time>0) if (unsigned(k)<sp.size() && sp[k].time>0)
xml.write("Time", "timeFormat", L"HH:MM:SS", formatTimeIOF(sp[k].time-it->tStartTime, 0)); xml.write("Time", "timeFormat", hhmmss, formatTimeIOF(sp[k].time-it->tStartTime, 0));
else else
xml.write("Time", L"--:--:--"); xml.write("Time", L"--:--:--");
@ -2410,13 +2410,13 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
xml.write("CCardId", it->getCardNo()); xml.write("CCardId", it->getCardNo());
xml.endTag(); xml.endTag();
xml.startTag("StartTime"); xml.startTag("StartTime");
xml.write("Clock", "clockFormat", L"HH:MM:SS", formatTimeIOF(it->getStartTime(), ZeroTime)); xml.write("Clock", "clockFormat", hhmmss, formatTimeIOF(it->getStartTime(), ZeroTime));
xml.endTag(); xml.endTag();
xml.startTag("FinishTime"); xml.startTag("FinishTime");
xml.write("Clock", "clockFormat", L"HH:MM:SS", formatTimeIOF(it->getFinishTimeAdjusted(), ZeroTime)); xml.write("Clock", "clockFormat", hhmmss, formatTimeIOF(it->getFinishTimeAdjusted(), ZeroTime));
xml.endTag(); xml.endTag();
xml.write("Time", "timeFormat", L"HH:MM:SS", formatTimeIOF(it->getRunningTime(),0)); xml.write("Time", "timeFormat", hhmmss, formatTimeIOF(it->getRunningTime(),0));
xml.write("ResultPosition", it->getPlaceS()); xml.write("ResultPosition", it->getPlaceS());
xml.write("CompetitorStatus", "value", it->getIOFStatusS()); xml.write("CompetitorStatus", "value", it->getIOFStatusS());
@ -2438,7 +2438,7 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
xml.startTag("SplitTime", "sequence", itos(no++)); xml.startTag("SplitTime", "sequence", itos(no++));
xml.write("ControlCode", pcourse->Controls[k]->getFirstNumber()); xml.write("ControlCode", pcourse->Controls[k]->getFirstNumber());
if (unsigned(k)<sp.size() && sp[k].time>0) if (unsigned(k)<sp.size() && sp[k].time>0)
xml.write("Time", "timeFormat", L"HH:MM:SS", formatTimeIOF(sp[k].time - it->tStartTime, 0)); xml.write("Time", "timeFormat", hhmmss, formatTimeIOF(sp[k].time - it->tStartTime, 0));
else else
xml.write("Time", L"--:--:--"); xml.write("Time", L"--:--:--");
@ -2459,6 +2459,7 @@ void oEvent::exportIOFResults(xmlparser &xml, bool selfContained, const set<int>
void oEvent::exportTeamSplits(xmlparser &xml, const set<int> &classes, bool oldStylePatrol) void oEvent::exportTeamSplits(xmlparser &xml, const set<int> &classes, bool oldStylePatrol)
{ {
wstring hhmmss = L"HH:MM:SS";
vector<SplitData> dummy; vector<SplitData> dummy;
bool ClassStarted=false; bool ClassStarted=false;
int Id=-1; int Id=-1;
@ -2531,13 +2532,13 @@ void oEvent::exportTeamSplits(xmlparser &xml, const set<int> &classes, bool oldS
xml.write("BibNumber", it->getStartNo()); xml.write("BibNumber", it->getStartNo());
xml.startTag("StartTime"); xml.startTag("StartTime");
xml.write("Clock", "clockFormat", L"HH:MM:SS", formatTimeIOF(it->getStartTime(), ZeroTime)); xml.write("Clock", "clockFormat", hhmmss, formatTimeIOF(it->getStartTime(), ZeroTime));
xml.endTag(); xml.endTag();
xml.startTag("FinishTime"); xml.startTag("FinishTime");
xml.write("Clock", "clockFormat", L"HH:MM:SS", formatTimeIOF(it->getFinishTimeAdjusted(), ZeroTime)); xml.write("Clock", "clockFormat", hhmmss, formatTimeIOF(it->getFinishTimeAdjusted(), ZeroTime));
xml.endTag(); xml.endTag();
xml.write("Time", "timeFormat", L"HH:MM:SS", formatTimeIOF(it->getRunningTime(), 0)); xml.write("Time", "timeFormat", hhmmss, formatTimeIOF(it->getRunningTime(), 0));
xml.write("ResultPosition", it->getPlaceS()); xml.write("ResultPosition", it->getPlaceS());
xml.write("TeamStatus", "value", it->getIOFStatusS()); xml.write("TeamStatus", "value", it->getIOFStatusS());
@ -2556,13 +2557,13 @@ void oEvent::exportTeamSplits(xmlparser &xml, const set<int> &classes, bool oldS
xml.startTag("Result"); { xml.startTag("Result"); {
xml.write("TeamSequence", k+1); xml.write("TeamSequence", k+1);
xml.startTag("StartTime"); xml.startTag("StartTime");
xml.write("Clock", "clockFormat", L"HH:MM:SS", formatTimeIOF(r->getStartTime(), ZeroTime)); xml.write("Clock", "clockFormat", hhmmss, formatTimeIOF(r->getStartTime(), ZeroTime));
xml.endTag(); xml.endTag();
xml.startTag("FinishTime"); xml.startTag("FinishTime");
xml.write("Clock", "clockFormat", L"HH:MM:SS", formatTimeIOF(r->getFinishTimeAdjusted(), ZeroTime)); xml.write("Clock", "clockFormat", hhmmss, formatTimeIOF(r->getFinishTimeAdjusted(), ZeroTime));
xml.endTag(); xml.endTag();
xml.write("Time", "timeFormat", L"HH:MM:SS", formatTimeIOF(r->getRunningTime(), 0)); xml.write("Time", "timeFormat", hhmmss, formatTimeIOF(r->getRunningTime(), 0));
xml.write("ResultPosition", r->getPlaceS()); xml.write("ResultPosition", r->getPlaceS());
xml.write("CompetitorStatus", "value", r->getIOFStatusS()); xml.write("CompetitorStatus", "value", r->getIOFStatusS());
@ -2590,7 +2591,7 @@ void oEvent::exportTeamSplits(xmlparser &xml, const set<int> &classes, bool oldS
xml.startTag("SplitTime", "sequence", itos(no++)); xml.startTag("SplitTime", "sequence", itos(no++));
xml.write("ControlCode", pcourse->Controls[k]->getFirstNumber()); xml.write("ControlCode", pcourse->Controls[k]->getFirstNumber());
if (unsigned(k)<sp.size() && sp[k].time>0) if (unsigned(k)<sp.size() && sp[k].time>0)
xml.write("Time", "timeFormat", L"HH:MM:SS", formatTimeIOF(sp[k].time - it->tStartTime, 0)); xml.write("Time", "timeFormat", hhmmss, formatTimeIOF(sp[k].time - it->tStartTime, 0));
else else
xml.write("Time", L"--:--:--"); xml.write("Time", L"--:--:--");

View File

@ -284,7 +284,7 @@ int oListInfo::getMaxCharWidth(const oEvent *oe,
const vector< pair<EPostType, wstring> > &typeFormats, const vector< pair<EPostType, wstring> > &typeFormats,
gdiFonts font, gdiFonts font,
const wchar_t *fontFace, const wchar_t *fontFace,
bool large, int minSize) { bool large, int minSize) const {
vector<oPrintPost> pps; vector<oPrintPost> pps;
for (size_t k = 0; k < typeFormats.size(); k++) { for (size_t k = 0; k < typeFormats.size(); k++) {
pps.push_back(oPrintPost()); pps.push_back(oPrintPost());
@ -1057,7 +1057,7 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
case lClassResultFraction: case lClassResultFraction:
if (pc && !invalidClass) { if (pc && !invalidClass) {
int total, finished, dns; int total, finished, dns;
oe->getNumClassRunners(pc->getId(), par.getLegNumber(pc), total, finished, dns); pc->getNumResults(par.getLegNumber(pc), total, finished, dns);
swprintf_s(wbf, L"(%d / %d)", finished, total); swprintf_s(wbf, L"(%d / %d)", finished, total);
} }
break; break;
@ -1091,6 +1091,13 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
} }
break; break;
case lClassNumEntries:
if (pc) {
int n = pc->getNumRunners(true, true, true);
wsptr = &itow(n);
}
break;
case lCourseClimb: case lCourseClimb:
if (r) { if (r) {
pCourse crs = r->getCourse(false); pCourse crs = r->getCourse(false);
@ -1658,7 +1665,7 @@ const wstring &oEvent::formatListStringAux(const oPrintPost &pp, const oListPara
case lRunnerUMMasterPoint: case lRunnerUMMasterPoint:
if (r) { if (r) {
int total, finished, dns; int total, finished, dns;
oe->getNumClassRunners(pc->getId(), par.getLegNumber(pc), total, finished, dns); pc->getNumResults(par.getLegNumber(pc), total, finished, dns);
int percent = int(floor(0.5+double((100*(total-dns-r->getPlace()))/double(total-dns)))); int percent = int(floor(0.5+double((100*(total-dns-r->getPlace()))/double(total-dns))));
if (r->getStatus()==StatusOK) if (r->getStatus()==StatusOK)
swprintf_s(wbf, L"%d", percent); swprintf_s(wbf, L"%d", percent);
@ -2296,7 +2303,7 @@ bool oEvent::formatPrintPost(const list<oPrintPost> &ppli, PrintPostInfo &ppi,
continue; continue;
} }
int limit = 0; int limit = ppit->xlimit;
bool keepNext = false; bool keepNext = false;
//Skip merged entities //Skip merged entities
@ -2337,20 +2344,20 @@ bool oEvent::formatPrintPost(const list<oPrintPost> &ppli, PrintPostInfo &ppi,
if ((pp.type == lRunnerName || pp.type == lRunnerCompleteName || if ((pp.type == lRunnerName || pp.type == lRunnerCompleteName ||
pp.type == lRunnerFamilyName || pp.type == lRunnerGivenName || pp.type == lRunnerFamilyName || pp.type == lRunnerGivenName ||
pp.type == lTeamRunner || (pp.type == lPatrolNameNames && !t)) && rr) { pp.type == lTeamRunner || (pp.type == lPatrolNameNames && !t)) && rr) {
ti = &ppi.gdi.addStringUT(y + pdy, x + pdx, pp.format, text, ti = &ppi.gdi.addStringUT(y + pdy, x + pdx, pp.format | skipBoundingBox, text,
ppi.gdi.scaleLength(limit), ppi.par.cb, pp.fontFace.c_str()); ppi.gdi.scaleLength(limit), ppi.par.cb, pp.fontFace.c_str());
ti->setExtra(rr->getId()); ti->setExtra(rr->getId());
ti->id = "R"; ti->id = "R";
} }
else if ((pp.type == lTeamName || pp.type == lPatrolNameNames) && t) { else if ((pp.type == lTeamName || pp.type == lPatrolNameNames) && t) {
ti = &ppi.gdi.addStringUT(y + pdy, x + pdx, pp.format, text, ti = &ppi.gdi.addStringUT(y + pdy, x + pdx, pp.format | skipBoundingBox, text,
ppi.gdi.scaleLength(limit), ppi.par.cb, pp.fontFace.c_str()); ppi.gdi.scaleLength(limit), ppi.par.cb, pp.fontFace.c_str());
ti->setExtra(t->getId()); ti->setExtra(t->getId());
ti->id = "T"; ti->id = "T";
} }
else { else {
ti = &ppi.gdi.addStringUT(y + pdy, x + pdx, ti = &ppi.gdi.addStringUT(y + pdy, x + pdx,
pp.format, text, ppi.gdi.scaleLength(limit), 0, pp.fontFace.c_str()); pp.format | skipBoundingBox, text, ppi.gdi.scaleLength(limit), 0, pp.fontFace.c_str());
} }
if (ti && ppi.keepToghether) if (ti && ppi.keepToghether)
ti->lineBreakPrioity = -1; ti->lineBreakPrioity = -1;
@ -2733,11 +2740,26 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
PrintPostInfo printPostInfo(gdi, li.lp); PrintPostInfo printPostInfo(gdi, li.lp);
//oCounter counter; //oCounter counter;
//Render header //Render header
vector< pair<EPostType, wstring> > v;
for (auto &listPostList : { &li.Head, &li.subHead, &li.listPost, &li.subListPost }) {
for (auto &lp : *listPostList) {
if (lp.xlimit == 0) {
v.clear();
v.emplace_back(lp.type, lp.text);
gdiFonts font = lp.getFont();
lp.xlimit = li.getMaxCharWidth(this, gdi, li.getParam().selection, v, font, lp.fontFace.c_str());
}
}
}
if (formatHead && li.getParam().showHeader) { if (formatHead && li.getParam().showHeader) {
for (auto &h : li.Head) { for (auto &h : li.Head) {
if (h.type == lCmpName || h.type == lString) { if (h.type == lCmpName || h.type == lString) {
v.clear();
const_cast<wstring&>(h.text) = li.lp.getCustomTitle(h.text); const_cast<wstring&>(h.text) = li.lp.getCustomTitle(h.text);
v.emplace_back(h.type, h.text);
gdiFonts font = h.getFont();
h.xlimit = li.getMaxCharWidth(this, gdi, li.getParam().selection, v, font, h.fontFace.c_str());
break; break;
} }
} }

View File

@ -53,6 +53,7 @@ enum EPostType
lClassResultFraction, lClassResultFraction,
lClassAvailableMaps, lClassAvailableMaps,
lClassTotalMaps, lClassTotalMaps,
lClassNumEntries,
lCourseLength, lCourseLength,
lCourseName, lCourseName,
lCourseClimb, lCourseClimb,
@ -297,6 +298,7 @@ struct oPrintPost {
GDICOLOR color; GDICOLOR color;
int dx; int dx;
int dy; int dy;
mutable int xlimit = 0;
int legIndex; int legIndex;
bool linearLegIndex; bool linearLegIndex;
gdiFonts getFont() const {return gdiFonts(format & 0xFF);} gdiFonts getFont() const {return gdiFonts(format & 0xFF);}
@ -573,7 +575,7 @@ public:
gdiFonts font, gdiFonts font,
const wchar_t *fontFace = 0, const wchar_t *fontFace = 0,
bool large = false, bool large = false,
int minSize = 0); int minSize = 0) const;
int getMaxCharWidth(const oEvent *oe, int getMaxCharWidth(const oEvent *oe,
@ -583,7 +585,7 @@ public:
gdiFonts font, gdiFonts font,
const wchar_t *fontFace = 0, const wchar_t *fontFace = 0,
bool large = false, bool large = false,
int minSize = 0) { int minSize = 0) const {
vector< pair<EPostType, wstring> > typeFormats(1, make_pair(type, formats)); vector< pair<EPostType, wstring> > typeFormats(1, make_pair(type, formats));
return getMaxCharWidth(oe, oe->gdiBase(), clsSel, typeFormats, font, fontFace, largeSize, minSize); return getMaxCharWidth(oe, oe->gdiBase(), clsSel, typeFormats, font, fontFace, largeSize, minSize);
} }

View File

@ -63,6 +63,12 @@ string oPunch::codeString() const
return bf; return bf;
} }
void oPunch::appendCodeString(string &dst) const {
char bf[32];
sprintf_s(bf, 32, "%d-%d;", Type, Time);
dst.append(bf);
}
void oPunch::decodeString(const string &s) void oPunch::decodeString(const string &s)
{ {
Type=atoi(s.c_str()); Type=atoi(s.c_str());

View File

@ -97,6 +97,8 @@ public:
enum SpecialPunch {PunchStart=1, PunchFinish=2, PunchCheck=3, HiredCard=11111}; enum SpecialPunch {PunchStart=1, PunchFinish=2, PunchCheck=3, HiredCard=11111};
void decodeString(const string &s); void decodeString(const string &s);
string codeString() const; string codeString() const;
void appendCodeString(string &dst) const;
oPunch(oEvent *poe); oPunch(oEvent *poe);
virtual ~oPunch(); virtual ~oPunch();

View File

@ -1916,6 +1916,12 @@ bool oRunner::operator<(const oRunner &c) const {
return true; return true;
else if (tStartTime > c.tStartTime) else if (tStartTime > c.tStartTime)
return false; return false;
const wstring &b1 = getBib();
const wstring &b2 = c.getBib();
if (b1 != b2) {
return compareBib(b1, b2);
}
} }
else if (oe->CurrentSortOrder == SortByStartTimeClass) { else if (oe->CurrentSortOrder == SortByStartTimeClass) {
if (tStartTime < c.tStartTime) if (tStartTime < c.tStartTime)
@ -2558,7 +2564,7 @@ pRunner oRunner::nextNeedReadout() const {
return nullptr; return nullptr;
} }
unordered_multimap<int, pRunner> &oEvent::getCardToRunner() const { vector<pRunner> oEvent::getCardToRunner(int cardNo) const {
if (!cardToRunnerHash || cardToRunnerHash->size() > Runners.size() * 2) { if (!cardToRunnerHash || cardToRunnerHash->size() > Runners.size() * 2) {
cardToRunnerHash = make_shared<unordered_multimap<int, pRunner>>(); cardToRunnerHash = make_shared<unordered_multimap<int, pRunner>>();
for (auto &rc : Runners) { for (auto &rc : Runners) {
@ -2570,16 +2576,33 @@ unordered_multimap<int, pRunner> &oEvent::getCardToRunner() const {
cardToRunnerHash->emplace(cno, r); // The cache is "to large" -> filter is needed when looking into it. cardToRunnerHash->emplace(cno, r); // The cache is "to large" -> filter is needed when looking into it.
} }
} }
return *cardToRunnerHash; vector<pRunner> res;
set<int> ids;
auto rng = cardToRunnerHash->equal_range(cardNo);
for (auto it = rng.first; it != rng.second; ++it) {
pRunner r = it->second;
if (!r->isRemoved() && r->getCardNo() == cardNo) {
if (ids.insert(r->getId()).second)
res.push_back(r);
for (pRunner r2 : r->multiRunner) {
if (r2 && r2->getCardNo() == cardNo) {
if (ids.insert(r2->getId()).second)
res.push_back(r2);
}
}
}
}
return res;
} }
pRunner oEvent::getRunnerByCardNo(int cardNo, int time, CardLookupProperty prop) const { pRunner oEvent::getRunnerByCardNo(int cardNo, int time, CardLookupProperty prop) const {
auto range = getCardToRunner().equal_range(cardNo); auto range = getCardToRunner(cardNo);
bool skipDNS = (prop == CardLookupProperty::SkipNoStart || prop == CardLookupProperty::CardInUse); bool skipDNS = (prop == CardLookupProperty::SkipNoStart || prop == CardLookupProperty::CardInUse);
if (range.first != range.second && std::distance(range.first, range.second) == 1) { if (range.size() == 1) {
// Single hit // Single hit
pRunner r = range.first->second; pRunner r = range[0];
if (r->isRemoved() || r->getCardNo() != cardNo) if (r->isRemoved() || r->getCardNo() != cardNo)
return nullptr; return nullptr;
if (skipDNS && (r->getStatus() == StatusDNS || r->getStatus() == StatusCANCEL)) if (skipDNS && (r->getStatus() == StatusDNS || r->getStatus() == StatusCANCEL))
@ -2594,11 +2617,7 @@ pRunner oEvent::getRunnerByCardNo(int cardNo, int time, CardLookupProperty prop)
vector<pRunner> cand; vector<pRunner> cand;
bool forceRet = false; bool forceRet = false;
for (auto it = range.first; it != range.second; ++it) { for (auto r : range) {
pRunner r = it->second;
if (r->isRemoved() || r->getCardNo() != cardNo)
continue;
if (skipDNS && (r->getStatus() == StatusDNS || r->getStatus() == StatusCANCEL)) if (skipDNS && (r->getStatus() == StatusDNS || r->getStatus() == StatusCANCEL))
continue; continue;
@ -2700,11 +2719,8 @@ void oEvent::getRunnersByCardNo(int cardNo, bool sortUpdate, CardLookupProperty
const_cast<oEvent *>(this)->synchronizeList(oListId::oLRunnerId); const_cast<oEvent *>(this)->synchronizeList(oListId::oLRunnerId);
if (cardNo != 0) { if (cardNo != 0) {
auto range = getCardToRunner().equal_range(cardNo); auto range = getCardToRunner(cardNo);
for (auto it = range.first; it != range.second; ++it) { for (auto r : range) {
pRunner r = it->second;
if (r->isRemoved() || r->getCardNo() != cardNo)
continue;
if (skipDNS && (r->getStatus() == StatusDNS || r->getStatus() == StatusCANCEL)) if (skipDNS && (r->getStatus() == StatusDNS || r->getStatus() == StatusCANCEL))
continue; continue;
if (prop == CardLookupProperty::OnlyMainInstance && r->getRaceNo() != 0) if (prop == CardLookupProperty::OnlyMainInstance && r->getRaceNo() != 0)
@ -4657,6 +4673,7 @@ bool oRunner::matchName(const wstring &pname) const
split(tRealName, L" ", myNames); split(tRealName, L" ", myNames);
split(pname, L" ", inNames); split(pname, L" ", inNames);
int numInNames = inNames.size();
for (size_t k = 0; k < myNames.size(); k++) for (size_t k = 0; k < myNames.size(); k++)
myNames[k] = canonizeName(myNames[k].c_str()); myNames[k] = canonizeName(myNames[k].c_str());
@ -4677,7 +4694,7 @@ bool oRunner::matchName(const wstring &pname) const
} }
} }
return nMatched >= min<int>(myNames.size(), 2); return nMatched >= min<int>(max<int>(numInNames, myNames.size()), 2);
} }
oRunner::BibAssignResult oRunner::autoAssignBib() { oRunner::BibAssignResult oRunner::autoAssignBib() {
@ -5999,3 +6016,17 @@ void oAbstractRunner::preventRestart(bool state) {
tPreventRestartCache.first = state; tPreventRestartCache.first = state;
tPreventRestartCache.second = oe->dataRevision; tPreventRestartCache.second = oe->dataRevision;
} }
int oRunner::getCheckTime() const {
oPunch *p = nullptr;
if (Card) {
p = Card->getPunchByType(oPunch::PunchCheck);
}
else {
p = oe->getPunch(Id, oPunch::PunchCheck, getCardNo());
}
if (p && p->Time > 0)
return p->Time;
return 0;
}

View File

@ -567,6 +567,9 @@ public:
// Returns true if there are radio control results, provided result calculation oEvent::ResultType::PreliminarySplitResults was invoked. // Returns true if there are radio control results, provided result calculation oEvent::ResultType::PreliminarySplitResults was invoked.
bool hasOnCourseResult() const { return !tOnCourseResults.empty() || getFinishTime() > 0 || getStatus() != RunnerStatus::StatusUnknown; } bool hasOnCourseResult() const { return !tOnCourseResults.empty() || getFinishTime() > 0 || getStatus() != RunnerStatus::StatusUnknown; }
/** Returns a check time (or zero for no time). */
int getCheckTime() const;
/** Get a runner reference (drawing) */ /** Get a runner reference (drawing) */
pRunner getReference() const; pRunner getReference() const;

View File

@ -205,18 +205,20 @@ void pdfwriter::generatePDF(const gdioutput &gdi,
maxX *= scaleXFactor; maxX *= scaleXFactor;
float w = HPDF_Page_GetWidth(page); float w = HPDF_Page_GetWidth(page);
float h = HPDF_Page_GetHeight(page); float h = HPDF_Page_GetHeight(page);
float scale = (w / maxX) * 0.85f; float scale = (w / maxX) * 0.95f;
float fontScale = 1.5f;
vector<RenderedPage> pages; vector<RenderedPage> pages;
PageInfo pageInfo; PageInfo pageInfo;
pageInfo.topMargin = h * 0.05f; pageInfo.topMargin = h * 0.03f;
pageInfo.scaleX = scale * scaleXFactor; pageInfo.scaleX = scale * scaleXFactor;
pageInfo.scaleY = scale; pageInfo.scaleY = scale * 1.1f;
pageInfo.leftMargin = w * 0.07f; pageInfo.leftMargin = w * 0.03f;
pageInfo.bottomMargin = pageInfo.topMargin * 1.0f; pageInfo.bottomMargin = pageInfo.topMargin * 1.0f;
pageInfo.pageY = h; pageInfo.pageY = h;
pageInfo.printHeader = true; pageInfo.printHeader = true;
pageInfo.yMM2PrintC = pageInfo.xMM2PrintC = 1199.551f / 420.f; pageInfo.yMM2PrintC = pageInfo.xMM2PrintC = 1199.551f / 420.f;
pageInfo.yMM2PrintC *= fontScale;
pageInfo.xMM2PrintK = 0; pageInfo.xMM2PrintK = 0;
pageInfo.yMM2PrintK = 0; pageInfo.yMM2PrintK = 0;
@ -227,9 +229,11 @@ void pdfwriter::generatePDF(const gdioutput &gdi,
if (!pinfo.empty()) { if (!pinfo.empty()) {
selectFont(page, fs, fontSmall, scale); selectFont(page, fs, fontSmall, scale);
HPDF_Page_BeginText (page); HPDF_Page_BeginText (page);
float df = min(w, h) * 0.02f; float df = min(w, h) * 0.04f;
float sw = HPDF_Page_TextWidth(page, gdi.toUTF8(pinfo).c_str()); float sw = HPDF_Page_TextWidth(page, gdi.toUTF8(pinfo).c_str());
HPDF_Page_TextOut (page, w - sw - df , h - df * 2.5f, gdi.toUTF8(pinfo).c_str()); float sy = HPDF_Page_TextWidth(page, "MMM");
HPDF_Page_TextOut (page, w - sw - df , h - sy, gdi.toUTF8(pinfo).c_str());
HPDF_Page_EndText(page); HPDF_Page_EndText(page);
} }
@ -269,7 +273,7 @@ void pdfwriter::generatePDF(const gdioutput &gdi,
} }
} }
selectFont(page, fonts[info[k].ti.font], info[k].ti.format, scale); selectFont(page, fonts[info[k].ti.font], info[k].ti.format, scale*fontScale);
HPDF_Page_BeginText (page); HPDF_Page_BeginText (page);
float r = GetRValue(info[k].ti.color); float r = GetRValue(info[k].ti.color);
float g = GetGValue(info[k].ti.color); float g = GetGValue(info[k].ti.color);
@ -278,14 +282,14 @@ void pdfwriter::generatePDF(const gdioutput &gdi,
string nt = gdi.toUTF8(info[k].ti.text); string nt = gdi.toUTF8(info[k].ti.text);
if (info[k].ti.format & textRight) { if (info[k].ti.format & textRight) {
float w = float(info[k].ti.xlimit) * scale; float w = float(info[k].ti.xlimit) * scale*fontScale;
float sw = HPDF_Page_TextWidth(page, nt.c_str()); float sw = HPDF_Page_TextWidth(page, nt.c_str());
float space = info[k].ti.xlimit > 0 ? 2 * HPDF_Page_GetCharSpace(page) : 0; float space = info[k].ti.xlimit > 0 ? 2 * HPDF_Page_GetCharSpace(page) : 0;
HPDF_Page_TextOut (page, info[k].xp + w - sw - space, h - info[k].yp, HPDF_Page_TextOut (page, info[k].xp + w - sw - space, h - info[k].yp,
nt.c_str()); nt.c_str());
} }
else if (info[k].ti.format & textCenter) { else if (info[k].ti.format & textCenter) {
float w = float(info[k].ti.xlimit) * scale; float w = float(info[k].ti.xlimit) * scale*fontScale;
float sw = HPDF_Page_TextWidth(page, nt.c_str()); float sw = HPDF_Page_TextWidth(page, nt.c_str());
HPDF_Page_TextOut (page, info[k].xp + w - sw/2, h - info[k].yp, HPDF_Page_TextOut (page, info[k].xp + w - sw/2, h - info[k].yp,
nt.c_str()); nt.c_str());

View File

@ -2436,3 +2436,7 @@ Patrol score, rogaining = Patrullpoäng, rogaining
Rogaining points before automatic reduction = Rogainingpoäng före automatisk reduktion Rogaining points before automatic reduction = Rogainingpoäng före automatisk reduktion
Runner's course id = Deltagares banans id Runner's course id = Deltagares banans id
Status code for cancelled entry = Statuskod för återbud Status code for cancelled entry = Statuskod för återbud
Kunde inte öppna databasen (X) = Kunde inte öppna databasen (X)
Kunde inte ladda upp löpardatabasen (X) = Kunde inte ladda upp löpardatabasen (X)
Runner check time = Checktid
ClassNumEntries = Antal anmälda i klassen

View File

@ -98,10 +98,21 @@ const string &xmlparser::encodeXML(const string &input) {
void xmlparser::write(const char *tag, const wstring &Value) void xmlparser::write(const char *tag, const wstring &Value)
{ {
if (!cutMode || !Value.empty()) { if (!cutMode || !Value.empty()) {
auto &valEnc = encodeXML(Value);
if (valEnc.length() > 400) {
fOut() << "<" << tag << ">" fOut() << "<" << tag << ">"
<< encodeXML(Value) << valEnc
<< "</" << tag << ">" << endl; << "</" << tag << ">" << endl;
} }
else {
char bf[512];
sprintf_s(bf, "<%s>%s</%s>\n", tag, valEnc.c_str(), tag);
fOut() << bf;
}
/*fOut() << "<" << tag << ">"
<< encodeXML(Value)
<< "</" << tag << ">" << endl;*/
}
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
} }
@ -109,17 +120,49 @@ void xmlparser::write(const char *tag, const wstring &Value)
void xmlparser::write(const char *tag, const string &Value) void xmlparser::write(const char *tag, const string &Value)
{ {
if (!cutMode || Value!="") { if (!cutMode || Value!="") {
auto &valEnc = encodeXML(Value);
if (valEnc.length() > 400) {
fOut() << "<" << tag << ">" fOut() << "<" << tag << ">"
<< encodeXML(Value) << valEnc
<< "</" << tag << ">" << endl; << "</" << tag << ">" << endl;
} }
else {
char bf[512];
sprintf_s(bf, "<%s>%s</%s>\n", tag, valEnc.c_str(), tag);
fOut() << bf;
}
}
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
} }
void xmlparser::write(const char *tag, const char *Value)
{
if (!cutMode || Value != "") {
auto &valEnc = encodeXML(Value);
if (valEnc.length() > 400) {
fOut() << "<" << tag << ">"
<< valEnc
<< "</" << tag << ">" << endl;
}
else {
char bf[512];
sprintf_s(bf, "<%s>%s</%s>\n", tag, valEnc.c_str(), tag);
fOut() << bf;
}
}
if (!fOut().good())
throw meosException("Writing to XML file failed.");
}
void xmlparser::write(const char *tag) void xmlparser::write(const char *tag)
{ {
fOut() << "<" << tag << "/>" << endl; char bf[128];
sprintf_s(bf, "<%s/>\n", tag);
fOut() << bf;
//fOut() << "<" << tag << "/>" << endl;
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
} }
@ -128,7 +171,7 @@ void xmlparser::write(const char *tag, const char *Property, const string &Value
{ {
if (!cutMode || Value!="") { if (!cutMode || Value!="") {
fOut() << "<" << tag << " " << Property << "=\"" fOut() << "<" << tag << " " << Property << "=\""
<< encodeXML(Value) << "\"/>" << endl; << encodeXML(Value) << "\"/>\n";
} }
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -138,7 +181,7 @@ void xmlparser::write(const char *tag, const char *Property, const wstring &Valu
{ {
if (!cutMode || !Value.empty()) { if (!cutMode || !Value.empty()) {
fOut() << "<" << tag << " " << Property << "=\"" fOut() << "<" << tag << " " << Property << "=\""
<< encodeXML(Value) << "\"/>" << endl; << encodeXML(Value) << "\"/>\n";
} }
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -146,7 +189,8 @@ void xmlparser::write(const char *tag, const char *Property, const wstring &Valu
void xmlparser::write(const char *tag, const char *prop, const wchar_t *value) void xmlparser::write(const char *tag, const char *prop, const wchar_t *value)
{ {
write(tag, prop, wstring(value)); encodeString = value;
write(tag, prop, encodeString);
} }
void xmlparser::writeBool(const char *tag, const char *prop, bool value) void xmlparser::writeBool(const char *tag, const char *prop, bool value)
@ -173,7 +217,7 @@ void xmlparser::write(const char *tag, const char *Property, const wstring &Prop
if (!cutMode || Value != L"" || PropValue != L"") { if (!cutMode || Value != L"" || PropValue != L"") {
fOut() << "<" << tag << " " << Property << "=\"" fOut() << "<" << tag << " " << Property << "=\""
<< encodeXML(PropValue) << "\">" << encodeXML(Value) << encodeXML(PropValue) << "\">" << encodeXML(Value)
<< "</" << tag << ">" << endl; << "</" << tag << ">\n";
} }
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -222,10 +266,10 @@ void xmlparser::write(const char *tag, const vector< pair<string, wstring> > &pr
} }
if (!value.empty()) { if (!value.empty()) {
fOut() << ">" << encodeXML(value) fOut() << ">" << encodeXML(value)
<< "</" << tag << ">" << endl; << "</" << tag << ">\n";
} }
else else
fOut() << "/>" << endl; fOut() << "/>\n";
} }
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -239,7 +283,10 @@ void xmlparser::write(const char *tag, const char *prop,
void xmlparser::writeBool(const char *tag, const char *prop, void xmlparser::writeBool(const char *tag, const char *prop,
bool propValue, const wstring &value) { bool propValue, const wstring &value) {
write(tag, prop, propValue ? L"true" : L"false", value); static const wstring wTrue = L"true";
static const wstring wFalse = L"false";
write(tag, prop, propValue ? wTrue : wFalse, value);
} }
/* /*
void xmlparser::write(const char *tag, const char *prop, void xmlparser::write(const char *tag, const char *prop,
@ -255,9 +302,12 @@ void xmlparser::write(const char *tag, const char *prop,
void xmlparser::write(const char *tag, int Value) void xmlparser::write(const char *tag, int Value)
{ {
if (!cutMode || Value!=0) { if (!cutMode || Value!=0) {
fOut() << "<" << tag << ">" char bf[256];
<< Value sprintf_s(bf, "<%s>%d</%s>\n", tag, Value, tag);
<< "</" << tag << ">" << endl; fOut() << bf;
//fOut() << "<" << tag << ">"
// << Value
// << "</" << tag << ">" << endl;
} }
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -266,9 +316,16 @@ void xmlparser::write(const char *tag, int Value)
void xmlparser::writeBool(const char *tag, bool value) void xmlparser::writeBool(const char *tag, bool value)
{ {
if (!cutMode || value) { if (!cutMode || value) {
fOut() << "<" << tag << ">" if (value) {
<< (value ? "true" : "false") char bf[256];
<< "</" << tag << ">" << endl; sprintf_s(bf, "<%s>true</%s>\n", tag, tag);
fOut() << bf;
}
else {
char bf[256];
sprintf_s(bf, "<%s>false</%s>\n", tag, tag);
fOut() << bf;
}
} }
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -280,7 +337,7 @@ void xmlparser::write64(const char *tag, __int64 Value)
if (!cutMode || Value!=0) { if (!cutMode || Value!=0) {
fOut() << "<" << tag << ">" fOut() << "<" << tag << ">"
<< Value << Value
<< "</" << tag << ">" << endl; << "</" << tag << ">\n";
} }
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -289,7 +346,16 @@ void xmlparser::write64(const char *tag, __int64 Value)
void xmlparser::startTag(const char *tag, const char *prop, const wstring &Value) void xmlparser::startTag(const char *tag, const char *prop, const wstring &Value)
{ {
if (tagStackPointer<32) { if (tagStackPointer<32) {
const string &valEnc = encodeXML(Value);
if (valEnc.length() < 128) {
char bf[256];
sprintf_s(bf, "<%s %s=\"%s\">\n", tag, prop, valEnc.c_str());
fOut() << bf;
}
else {
fOut() << "<" << tag << " " << prop << "=\"" << encodeXML(Value) << "\">" << endl; fOut() << "<" << tag << " " << prop << "=\"" << encodeXML(Value) << "\">" << endl;
}
tagStack[tagStackPointer++]=tag; tagStack[tagStackPointer++]=tag;
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -302,7 +368,16 @@ void xmlparser::startTag(const char *tag, const char *prop, const wstring &Value
void xmlparser::startTag(const char *tag, const char *prop, const string &Value) void xmlparser::startTag(const char *tag, const char *prop, const string &Value)
{ {
if (tagStackPointer<32) { if (tagStackPointer<32) {
const string &valEnc = encodeXML(Value);
if (valEnc.length() < 128) {
char bf[256];
sprintf_s(bf, "<%s %s=\"%s\">\n", tag, prop, valEnc.c_str());
fOut() << bf;
}
else {
fOut() << "<" << tag << " " << prop << "=\"" << encodeXML(Value) << "\">" << endl; fOut() << "<" << tag << " " << prop << "=\"" << encodeXML(Value) << "\">" << endl;
}
tagStack[tagStackPointer++]=tag; tagStack[tagStackPointer++]=tag;
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -318,7 +393,7 @@ void xmlparser::startTag(const char *tag, const vector<string> &propvalue)
for (size_t k=0;k<propvalue.size(); k+=2) { for (size_t k=0;k<propvalue.size(); k+=2) {
fOut() << propvalue[k] << "=\"" << encodeXML(propvalue[k+1]) << "\" "; fOut() << propvalue[k] << "=\"" << encodeXML(propvalue[k+1]) << "\" ";
} }
fOut() << ">" << endl; fOut() << ">\n";
tagStack[tagStackPointer++]=tag; tagStack[tagStackPointer++]=tag;
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -330,11 +405,11 @@ void xmlparser::startTag(const char *tag, const vector<string> &propvalue)
void xmlparser::startTag(const char *tag, const vector<wstring> &propvalue) void xmlparser::startTag(const char *tag, const vector<wstring> &propvalue)
{ {
if (tagStackPointer<32) { if (tagStackPointer<32) {
fOut() << "<" << tag << " "; fOut() << "<" << tag ;
for (size_t k=0;k<propvalue.size(); k+=2) { for (size_t k=0;k<propvalue.size(); k+=2) {
fOut() << encodeXML(propvalue[k]) << "=\"" << encodeXML(propvalue[k+1]) << "\" "; fOut() << " " << encodeXML(propvalue[k]) << "=\"" << encodeXML(propvalue[k+1]) << "\"";
} }
fOut() << ">" << endl; fOut() << ">\n";
tagStack[tagStackPointer++]=tag; tagStack[tagStackPointer++]=tag;
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -346,7 +421,9 @@ void xmlparser::startTag(const char *tag, const vector<wstring> &propvalue)
void xmlparser::startTag(const char *tag) void xmlparser::startTag(const char *tag)
{ {
if (tagStackPointer<32) { if (tagStackPointer<32) {
fOut() << "<" << tag << ">" << endl; char bf[128];
sprintf_s(bf, "<%s>\n", tag);
fOut() << bf;
tagStack[tagStackPointer++]=tag; tagStack[tagStackPointer++]=tag;
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
@ -358,7 +435,11 @@ void xmlparser::startTag(const char *tag)
void xmlparser::endTag() void xmlparser::endTag()
{ {
if (tagStackPointer>0) { if (tagStackPointer>0) {
fOut() << "</" << tagStack[--tagStackPointer] << ">" << endl; char bf[128];
const char *tag = tagStack[--tagStackPointer].c_str();
sprintf_s(bf, "</%s>\n", tag);
fOut() << bf;
if (!fOut().good()) if (!fOut().good())
throw meosException("Writing to XML file failed."); throw meosException("Writing to XML file failed.");
} }

View File

@ -115,6 +115,7 @@ protected:
gdioutput *utfConverter; gdioutput *utfConverter;
mutable wstring encodeString;
public: public:
void access(int index); void access(int index);
@ -158,6 +159,8 @@ public:
void write(const char *tag, const vector< pair<string, wstring> > &propValue, const wstring &value); void write(const char *tag, const vector< pair<string, wstring> > &propValue, const wstring &value);
void write(const char *tag, const string &value); void write(const char *tag, const string &value);
void write(const char *tag, const char *value);
void write(const char *tag, const wstring &value); void write(const char *tag, const wstring &value);
void write(const char *tag, int value); void write(const char *tag, int value);