meos-2024/code/TabAuto.cpp
2018-04-21 21:59:00 +02:00

1183 lines
34 KiB
C++

/************************************************************************
MeOS - Orienteering Software
Copyright (C) 2009-2018 Melin Software HB
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Melin Software HB - software@melin.nu - www.melin.nu
Eksoppsvägen 16, SE-75646 UPPSALA, Sweden
************************************************************************/
#include "stdafx.h"
#include "resource.h"
#include <commctrl.h>
#include <commdlg.h>
#include "oEvent.h"
#include "xmlparser.h"
#include "gdioutput.h"
#include "csvparser.h"
#include "SportIdent.h"
#include "classconfiginfo.h"
#include "onlineresults.h"
#include "onlineinput.h"
#include "RestService.h"
#include "TabAuto.h"
#include "TabSI.h"
#include "meos_util.h"
#include <shellapi.h>
#include "gdiconstants.h"
#include "meosexception.h"
static TabAuto *tabAuto = 0;
int AutoMachine::uniqueId = 1;
extern HWND hWndMain;
extern HWND hWndWorkspace;
TabAuto::TabAuto(oEvent *poe):TabBase(poe)
{
synchronize=false;
synchronizePunches=false;
}
AutoMachine *AutoMachine::getMachine(int id) {
if (tabAuto)
return tabAuto->getMachine(id);
throw meosException("Internal error");
}
AutoMachine* AutoMachine::construct(Machines ms) {
switch(ms) {
case mPrintResultsMachine:
return new PrintResultMachine(0);
case mSplitsMachine:
return new SplitsMachine();
case mPrewarningMachine:
return new PrewarningMachine();
case mPunchMachine:
return new PunchMachine();
case mOnlineInput:
return new OnlineInput();
case mOnlineResults:
return new OnlineResults();
case mSaveBackup:
return new SaveMachine();
case mInfoService:
return new RestService();
}
throw meosException("Invalid machine");
}
AutoMachine *TabAuto::getMachine(int id) {
if (id == 0)
return 0;
list<AutoMachine *>::iterator it;
for (it=machines.begin(); it!=machines.end(); ++it) {
if (*it != 0 && (*it)->getId() == id) {
return *it;
}
}
throw meosException("Service X not found.#" + itos(id));
}
TabAuto::~TabAuto(void)
{
list<AutoMachine *>::iterator it;
for (it=machines.begin(); it!=machines.end(); ++it) {
delete *it;
*it=0;
}
tabAuto=0;
}
void tabAutoKillMachines()
{
if (tabAuto)
tabAuto->killMachines();
}
void tabAutoRegister(TabAuto *ta)
{
tabAuto=ta;
}
void tabAutoAddMachinge(const AutoMachine &am)
{
if (tabAuto) {
tabAuto->addMachine(am);
}
}
void tabForceSync(gdioutput &gdi, pEvent oe)
{
if (tabAuto)
tabAuto->syncCallback(gdi);
}
int AutomaticCB(gdioutput *gdi, int type, void *data)
{
if (!tabAuto)
throw std::exception("tabAuto undefined.");
switch(type){
case GUI_BUTTON: {
//Make a copy
ButtonInfo bu=*static_cast<ButtonInfo *>(data);
return tabAuto->processButton(*gdi, bu);
}
case GUI_LISTBOX:{
ListBoxInfo lbi=*static_cast<ListBoxInfo *>(data);
return tabAuto->processListBox(*gdi, lbi);
}
}
return 0;
}
void TabAuto::syncCallback(gdioutput &gdi)
{
wstring msg;
try {
list<AutoMachine *>::iterator it;
for (it=machines.begin(); it!=machines.end(); ++it) {
AutoMachine *am=*it;
if (am && am->synchronize && !am->isEditMode())
am->process(gdi, oe, SyncDataUp);
}
}
catch (meosException &ex) {
msg = ex.wwhat();
}
catch(std::exception &ex) {
msg = gdi.widen(ex.what());
}
catch(...) {
msg = L"Ett okänt fel inträffade.";
}
if (!msg.empty()) {
gdi.alert(msg);
gdi.setWaitCursor(false);
}
}
void TabAuto::updateSyncInfo()
{
list<AutoMachine *>::iterator it;
synchronize=false;
synchronizePunches=false;
for (it=machines.begin(); it!=machines.end(); ++it) {
AutoMachine *am=*it;
if (am){
am->synchronize= am->synchronize || am->synchronizePunches;
synchronize=synchronize || am->synchronize;
synchronizePunches=synchronizePunches || am->synchronizePunches;
}
}
}
void TabAuto::timerCallback(gdioutput &gdi)
{
DWORD tc=GetTickCount();
list<AutoMachine *>::iterator it;
bool reload=false;
for (it=machines.begin(); it!=machines.end(); ++it) {
AutoMachine *am=*it;
if (am && am->interval && tc >= am->timeout && !am->isEditMode()) {
am->process(gdi, oe, SyncTimer);
setTimer(am);
reload=true;
}
}
DWORD d=0;
if (reload && !editMode && gdi.getData("AutoPage", d) && d)
loadPage(gdi);
}
void TabAuto::setTimer(AutoMachine *am)
{
DWORD tc=GetTickCount();
if (am->interval>0) {
DWORD to=am->interval*1000+tc;
if (to<tc) { //Warp-around. No reasonable way to handle it
to=DWORD(0);
am->interval=0;
}
am->timeout=to;
}
}
int TabAuto::processButton(gdioutput &gdi, const ButtonInfo &bu)
{
if (bu.id=="GenerateCMP") {
#ifndef MEOSDB
int nClass=gdi.getTextNo("nClass");
int nRunner=gdi.getTextNo("nRunner");
if (nRunner>0 &&
gdi.ask(L"Vill du dumpa aktuellt tävling och skapa en testtävling?")) {
oe->generateTestCompetition(nClass, nRunner, gdi.isChecked("UseRelay"));
gdi.getTabs().get(TCmpTab)->loadPage(gdi);
return 0;
}
#endif
}
else if (bu.id == "BrowseFolder") {
const wchar_t *edit = bu.getExtra();
wstring currentPath = gdi.getText(gdi.narrow(edit));
wstring newPath = gdi.browseForFolder(currentPath, 0);
if (!newPath.empty())
gdi.setText(edit, newPath);
}
else if (bu.id == "StartBackup") {
SaveMachine *sm=dynamic_cast<SaveMachine*>(getMachine(bu.getExtraInt()));
if (sm)
sm->saveSettings(gdi);
updateSyncInfo();
loadPage(gdi);
}
else if (bu.id=="Result") {
PrintResultMachine *sm=dynamic_cast<PrintResultMachine*>(getMachine(bu.getExtraInt()));
settings(gdi, sm, mPrintResultsMachine);
}
else if (bu.id == "BrowseFile") {
static int index = 0;
vector< pair<wstring, wstring> > ext;
ext.push_back(make_pair(L"Webbdokument", L"*.html;*.htm"));
wstring file = gdi.browseForSave(ext, L"html", index);
if (!file.empty())
gdi.setText("ExportFile", file);
}
else if (bu.id == "BrowseScript") {
vector< pair<wstring, wstring> > ext;
ext.push_back(make_pair(L"Skript", L"*.bat;*.exe;*.js"));
wstring file = gdi.browseForOpen(ext, L"bat");
if (!file.empty())
gdi.setText("ExportScript", file);
}
else if (bu.id == "DoExport") {
bool stat = gdi.isChecked(bu.id);
gdi.setInputStatus("ExportFile", stat);
gdi.setInputStatus("ExportScript", stat);
gdi.setInputStatus("BrowseFile", stat);
gdi.setInputStatus("BrowseScript", stat);
gdi.setInputStatus("HTMLRefresh", stat);
gdi.setInputStatus("StructuredExport", stat);
}
else if (bu.id == "DoPrint") {
bool stat = gdi.isChecked(bu.id);
gdi.setInputStatus("PrinterSetup", stat);
}
else if (bu.id=="Splits") {
SplitsMachine *sm=dynamic_cast<SplitsMachine*>(getMachine(bu.getExtraInt()));
settings(gdi, sm, mSplitsMachine);
}
else if (bu.id=="Prewarning") {
PrewarningMachine *sm=dynamic_cast<PrewarningMachine*>(getMachine(bu.getExtraInt()));
settings(gdi, sm, mPrewarningMachine);
}
else if (bu.id=="Punches") {
PunchMachine *sm=dynamic_cast<PunchMachine*>(getMachine(bu.getExtraInt()));
settings(gdi, sm, mPunchMachine);
}
else if (bu.id=="OnlineResults") {
OnlineResults *sm=dynamic_cast<OnlineResults*>(getMachine(bu.getExtraInt()));
settings(gdi, sm, mOnlineResults);
}
else if (bu.id=="OnlineInput") {
OnlineInput *sm=dynamic_cast<OnlineInput*>(getMachine(bu.getExtraInt()));
settings(gdi, sm, mOnlineInput);
}
else if (bu.id=="SaveBackup") {
SaveMachine *sm=dynamic_cast<SaveMachine*>(getMachine(bu.getExtraInt()));
settings(gdi, sm, mSaveBackup);
}
else if (bu.id == "InfoService") {
settings(gdi, getMachine(bu.getExtraInt()), mInfoService);
}
else if (bu.id=="StartResult") {
#ifndef MEOSDB
wstring minute=gdi.getText("Interval");
int t=convertAbsoluteTimeMS(minute);
if (t<2 || t>7200) {
gdi.alert("Intervallet måste anges på formen MM:SS.");
}
else {
PrintResultMachine *prm=dynamic_cast<PrintResultMachine*>(getMachine(bu.getExtraInt()));
if (prm) {
prm->interval = t;
prm->doExport = gdi.isChecked("DoExport");
prm->doPrint = gdi.isChecked("DoPrint");
prm->exportFile = gdi.getText("ExportFile");
prm->exportScript = gdi.getText("ExportScript");
prm->structuredExport = gdi.isChecked("StructuredExport");
prm->htmlRefresh = gdi.isChecked("HTMLRefresh") ? t : 0;
if (!prm->readOnly) {
gdi.getSelection("Classes", prm->classesToPrint);
ListBoxInfo lbi;
if (gdi.getSelectedItem("ListType", lbi)) {
oListParam par;
par.selection=prm->classesToPrint;
par.listCode = EStdListType(lbi.data);
par.pageBreak = gdi.isChecked("PageBreak");
par.showInterTimes = gdi.isChecked("ShowInterResults");
par.splitAnalysis = gdi.isChecked("SplitAnalysis");
int legNr = gdi.getSelectedItem("LegNumber").first;
if (legNr >= 0)
par.setLegNumberCoded(legNr);
else
par.setLegNumberCoded(0);
oe->generateListInfo(par, gdi.getLineHeight(), prm->listInfo);
}
}
prm->po.onlyChanged = gdi.isChecked("OnlyChanged");
prm->pageBreak = gdi.isChecked("PageBreak");
prm->showInterResult = gdi.isChecked("ShowInterResults");
prm->splitAnalysis = gdi.isChecked("SplitAnalysis");
prm->synchronize=true; //To force continuos data sync.
setTimer(prm);
}
updateSyncInfo();
loadPage(gdi);
}
#endif
}
else if (bu.id=="StartSplits") {
wstring ivt = gdi.getText("Interval");
int iv = gdi.getTextNo("Interval");
const wstring &file=gdi.getText("FileName");
if (!ivt.empty() && (iv < 1 || iv > 7200)) {
throw meosException(L"Ogiltigt antal sekunder: X#" + gdi.getText("Interval"));
}
if (file.empty()) {
throw meosException("Filnamnet får inte vara tomt");
}
//Try exporting.
oe->exportIOFSplits(oEvent::IOF20, file.c_str(), true, false,
set<int>(), -1, false, true, true, false);
SplitsMachine *sm=dynamic_cast<SplitsMachine*>(getMachine(bu.getExtraInt()));
if (sm) {
sm->interval=iv;
sm->file=file;
sm->synchronize=true;
setTimer(sm);
}
updateSyncInfo();
loadPage(gdi);
}
else if (bu.id=="Save") { // General save
AutoMachine *sm=getMachine(bu.getExtraInt());
if (sm) {
sm->save(*oe, gdi);
setTimer(sm);
}
updateSyncInfo();
loadPage(gdi);
}
else if (bu.id=="StartPrewarning") {
PrewarningMachine *pwm=dynamic_cast<PrewarningMachine*>(getMachine(bu.getExtraInt()));
if (pwm) {
pwm->waveFolder=gdi.getText("WaveFolder");
gdi.getSelection("Controls", pwm->controls);
oe->synchronizeList(oLPunchId);
oe->clearPrewarningSounds();
pwm->synchronizePunches=true;
pwm->controlsSI.clear();
for (set<int>::iterator it=pwm->controls.begin();it!=pwm->controls.end();++it) {
pControl pc=oe->getControl(*it, false);
if (pc)
pwm->controlsSI.insert(pc->Numbers, pc->Numbers+pc->nNumbers);
}
}
updateSyncInfo();
loadPage(gdi);
}
else if (bu.id=="StartPunch") {
wstring minute=gdi.getText("Interval");
int t=_wtoi(minute.c_str());
if (t<1 || t>7200) {
throw meosException(L"Ogiltigt antal sekunder: X#" + minute);
}
else {
PunchMachine *pm=dynamic_cast<PunchMachine*>(getMachine(bu.getExtraInt()));
if (pm) {
pm->interval=t;
pm->radio=gdi.getTextNo("Radio");
setTimer(pm);
}
}
updateSyncInfo();
loadPage(gdi);
}
else if (bu.id == "Cancel") {
loadPage(gdi);
}
else if (bu.id == "Stop") {
if (bu.getExtraInt())
stopMachine(getMachine(bu.getExtraInt()));
updateSyncInfo();
loadPage(gdi);
}
else if (bu.id == "PrinterSetup") {
PrintResultMachine *prm =
dynamic_cast<PrintResultMachine*>(getMachine(bu.getExtraInt()));
if (prm) {
gdi.printSetup(prm->po);
}
}
else if (bu.id == "PrintNow") {
PrintResultMachine *prm =
dynamic_cast<PrintResultMachine*>(getMachine(bu.getExtraInt()));
if (prm) {
prm->process(gdi, oe, SyncNone);
setTimer(prm);
loadPage(gdi);
}
}
else if (bu.id == "SelectAll") {
const wchar_t *ctrl = bu.getExtra();
set<int> lst;
lst.insert(-1);
gdi.setSelection(ctrl, lst);
}
else if (bu.id == "SelectNone") {
const wchar_t *ctrl= bu.getExtra();
set<int> lst;
gdi.setSelection(ctrl, lst);
}
else if (bu.id == "TestVoice") {
PrewarningMachine *pwm=dynamic_cast<PrewarningMachine*>(getMachine(bu.getExtraInt()));
if (pwm)
oe->tryPrewarningSounds(pwm->waveFolder, rand()%400+1);
}
else if ( bu.id == "WaveBrowse") {
wstring wf=gdi.browseForFolder(gdi.getText("WaveFolder"), 0);
if (wf.length()>0)
gdi.setText("WaveFolder", wf);
}
else if ( bu.id == "BrowseSplits") {
int index=0;
vector< pair<wstring, wstring> > ext;
ext.push_back(make_pair(L"Sträcktider", L"*.xml"));
wstring wf = gdi.browseForSave(ext, L"xml", index);
if (!wf.empty())
gdi.setText("FileName", wf);
}
return 0;
}
int TabAuto::processListBox(gdioutput &gdi, const ListBoxInfo &bu)
{
return 0;
}
bool TabAuto::stopMachine(AutoMachine *am)
{
list<AutoMachine *>::iterator it;
for (it=machines.begin(); it!=machines.end(); ++it)
if (am==*it) {
if (am->stop()) {
delete am;
machines.erase(it);
return true;
}
}
return false;
}
void TabAuto::settings(gdioutput &gdi, AutoMachine *sm, Machines ms) {
editMode=true;
bool createNew = (sm==0);
if (!sm) {
sm = AutoMachine::construct(ms);
machines.push_back(sm);
}
gdi.restore("", false);
gdi.dropLine();
int cx = gdi.getCX();
int cy = gdi.getCY();
int d = gdi.scaleLength(6);
gdi.setCX(cx + d);
sm->setEditMode(true);
sm->settings(gdi, *oe, createNew);
int w = gdi.getWidth();
int h = gdi.getHeight();
RECT rc;
rc.top = cy - d;
rc.bottom = h + d;
rc.left = cx - d;
rc.right = w + d;
gdi.addRectangle(rc, colorLightBlue, true, true);
gdi.refresh();
}
void TabAuto::killMachines()
{
while(!machines.empty()) {
machines.back()->stop();
delete machines.back();
machines.pop_back();
}
AutoMachine::resetGlobalId();
}
bool TabAuto::loadPage(gdioutput &gdi)
{
oe->checkDB();
tabAuto=this;
editMode=false;
gdi.selectTab(tabId);
DWORD isAP = 0;
gdi.getData("AutoPage", isAP);
int storedOY = 0;
int storedOX = 0;
if (isAP) {
storedOY = gdi.GetOffsetY();
storedOX = gdi.GetOffsetX();
}
gdi.clearPage(false);
gdi.setData("AutoPage", 1);
gdi.addString("", boldLarge, "Automater");
gdi.setRestorePoint();
gdi.addString("", 10, "help:10000");
gdi.dropLine();
gdi.addString("", fontMediumPlus, "Tillgängliga automater").setColor(colorDarkBlue);
gdi.dropLine();
gdi.fillRight();
gdi.pushX();
gdi.addButton("Result", "Resultatutskrift / export", AutomaticCB, "tooltip:resultprint");
gdi.addButton("OnlineResults", "Resultat online", AutomaticCB, "Publicera resultat direkt på nätet");
gdi.addButton("OnlineInput", "Inmatning online", AutomaticCB, "Hämta stämplingar m.m. från nätet");
gdi.popX();
gdi.dropLine(2.5);
gdi.addButton("SaveBackup", "Säkerhetskopiering", AutomaticCB);
gdi.addButton("InfoService", "Informationsserver", AutomaticCB);
gdi.addButton("Punches", "Stämplingstest", AutomaticCB, "Simulera inläsning av stämplar");
gdi.popX();
gdi.dropLine(2.5);
gdi.addButton("Splits", "Sträcktider (WinSplits)", AutomaticCB, "Spara sträcktider till en fil för automatisk synkronisering med WinSplits");
gdi.addButton("Prewarning", "Förvarningsröst", AutomaticCB, "tooltip:voice");
gdi.fillDown();
gdi.dropLine(3);
gdi.popX();
if (!machines.empty()) {
gdi.addString("", fontMediumPlus, "Startade automater").setColor(colorDarkBlue);;
list<AutoMachine *>::iterator it;
int baseX = gdi.getCX();
int dx = gdi.scaleLength(6);
for (it=machines.begin(); it!=machines.end(); ++it) {
AutoMachine *am=*it;
if (am) {
RECT rc;
rc.left = baseX;
rc.right = gdi.scaleLength(500);
rc.top = gdi.getCY();
gdi.dropLine(0.5);
gdi.setCX(baseX+dx);
am->setEditMode(false);
am->status(gdi);
gdi.setCX(baseX);
gdi.dropLine(0.5);
rc.bottom = gdi.getCY();
gdi.addRectangle(rc, colorLightGreen, true, true);
gdi.dropLine();
}
}
gdi.dropLine();
}
if (isAP) {
gdi.setOffset(storedOY, storedOY, true);
}
gdi.refresh();
return true;
}
void AutoMachine::settingsTitle(gdioutput &gdi, char *title) {
gdi.dropLine(0.5);
gdi.addString("", fontMediumPlus, title).setColor(colorDarkBlue);
gdi.dropLine(0.5);
}
void AutoMachine::startCancelInterval(gdioutput &gdi, char *startCommand, bool created, IntervalType type, const wstring &intervalIn) {
gdi.pushX();
gdi.fillRight();
if (type == IntervalMinute)
gdi.addInput("Interval", intervalIn, 7, 0, L"Tidsintervall (MM:SS):");
else if (type == IntervalSecond)
gdi.addInput("Interval", intervalIn, 7, 0, L"Tidsintervall (sekunder):");
gdi.dropLine(1);
gdi.addButton(startCommand, created ? "Starta automaten" : "OK", AutomaticCB).setExtra(getId());
if (!created)
gdi.addButton("Cancel", "Avbryt", AutomaticCB).setExtra(getId());
gdi.addButton("Stop", created ? "Avbryt" : "Stoppa automaten", AutomaticCB).setExtra(getId());
gdi.popX();
gdi.fillDown();
gdi.dropLine(2.5);
int dx = gdi.scaleLength(3);
RECT rc;
rc.left = gdi.getCX() - dx;
rc.right = rc.left + gdi.scaleLength(450);
rc.top = gdi.getCY();
rc.bottom = rc.top + dx;
gdi.addRectangle(rc, colorDarkBlue, false, false);
gdi.dropLine();
}
void PrintResultMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
settingsTitle(gdi, "Resultatutskrift / export");
wstring time=created ? L"10:00" : getTimeMS(interval);
startCancelInterval(gdi, "StartResult", created, IntervalMinute, time);
if (created) {
oe.getAllClasses(classesToPrint);
}
gdi.pushX();
gdi.fillRight();
gdi.addCheckbox("DoPrint", "Skriv ut", AutomaticCB, doPrint);
gdi.dropLine(-0.5);
gdi.addButton("PrinterSetup", "Skrivare...", AutomaticCB, "Välj skrivare...").setExtra(getId());
gdi.dropLine(4);
gdi.popX();
gdi.addCheckbox("DoExport", "Exportera", AutomaticCB, doExport);
gdi.dropLine(-1);
int cx = gdi.getCX();
gdi.addInput("ExportFile", exportFile, 32, 0, L"Fil att exportera till:");
gdi.dropLine(0.7);
gdi.addButton("BrowseFile", "Bläddra...", AutomaticCB);
gdi.setCX(cx);
gdi.dropLine(2.3);
gdi.addCheckbox("StructuredExport", "Strukturerat exportformat", 0, structuredExport);
gdi.addCheckbox("HTMLRefresh", "HTML med AutoRefresh", 0, htmlRefresh != 0);
gdi.dropLine(1.2);
gdi.setCX(cx);
gdi.addInput("ExportScript", exportScript, 32, 0, L"Skript att köra efter export:");
gdi.dropLine(0.7);
gdi.addButton("BrowseScript", "Bläddra...", AutomaticCB);
gdi.dropLine(3);
gdi.popX();
gdi.setInputStatus("ExportFile", doExport);
gdi.setInputStatus("ExportScript", doExport);
gdi.setInputStatus("BrowseFile", doExport);
gdi.setInputStatus("BrowseScript", doExport);
gdi.setInputStatus("StructuredExport", doExport);
gdi.setInputStatus("HTMLRefresh", doExport);
gdi.setInputStatus("PrinterSetup", doPrint);
if (!readOnly) {
gdi.fillDown();
gdi.addString("", 1, "Listval");
gdi.dropLine();
gdi.fillRight();
gdi.addListBox("Classes", 150,300,0, L"", L"", true);
gdi.pushX();
gdi.fillDown();
vector< pair<wstring, size_t> > d;
gdi.addItem("Classes", oe.fillClasses(d, oEvent::extraNone, oEvent::filterNone));
gdi.setSelection("Classes", classesToPrint);
gdi.addSelection("ListType", 200, 100, 0, L"Lista");
oe.fillListTypes(gdi, "ListType", 1);
if (notShown) {
notShown = false;
ClassConfigInfo cnf;
oe.getClassConfigurationInfo(cnf);
int type = EStdResultListLARGE;
if (cnf.hasRelay())
type = EStdTeamAllLegLARGE;
else if (cnf.hasPatrol())
type = EStdPatrolResultListLARGE;
gdi.selectItemByData("ListType", type);
}
else
gdi.selectItemByData("ListType", listInfo.getListCode());
gdi.addSelection("LegNumber", 140, 300, 0, L"Sträcka:");
set<int> clsUnused;
vector< pair<wstring, size_t> > out;
oe.fillLegNumbers(clsUnused, listInfo.isTeamList(), true, out);
gdi.addItem("LegNumber", out);
gdi.selectItemByData("LegNumber", listInfo.getLegNumberCoded());
gdi.addCheckbox("PageBreak", "Sidbrytning mellan klasser", 0, pageBreak);
gdi.addCheckbox("ShowInterResults", "Visa mellantider", 0, showInterResult,
"Mellantider visas för namngivna kontroller.");
gdi.addCheckbox("SplitAnalysis", "Med sträcktidsanalys", 0, splitAnalysis);
gdi.addCheckbox("OnlyChanged", "Skriv endast ut ändade sidor", 0, po.onlyChanged);
gdi.popX();
gdi.addButton("SelectAll", "Välj allt", AutomaticCB, "").setExtra(L"Classes");
gdi.popX();
gdi.addButton("SelectNone", "Välj inget", AutomaticCB, "").setExtra(L"Classes");
}
else {
gdi.fillDown();
gdi.addString("", 1, L"Lista av typ 'X'#" + listInfo.getName());
gdi.addCheckbox("OnlyChanged", "Skriv endast ut ändade sidor", 0, po.onlyChanged);
}
}
void PrintResultMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
{
if (lock)
return;
if (ast!=SyncDataUp) {
wstring printError;
lock = true;
try {
gdioutput gdiPrint("print", gdi.getScale());
gdiPrint.clearPage(false);
oe->generateList(gdiPrint, true, listInfo, false);
if (doPrint) {
gdiPrint.refresh();
try {
gdiPrint.print(po, oe);
}
catch (const meosException &ex) {
printError = ex.wwhat();
if (printError.empty())
printError = L"Printing failed (X: Y) Z#Auto#0#Unknown";
}
}
if (doExport) {
if (!exportFile.empty()) {
if (structuredExport)
gdiPrint.writeTableHTML(exportFile, oe->getName(), htmlRefresh);
else
gdiPrint.writeHTML(exportFile, oe->getName(), htmlRefresh);
if (!exportScript.empty()) {
ShellExecute(NULL, NULL, exportScript.c_str(), exportFile.c_str(), NULL, SW_HIDE);
}
}
}
}
catch (...) {
lock = false;
throw;
}
lock = false;
if (!printError.empty() && !errorLock) {
errorLock = true;
gdi.alert(printError);
errorLock = false;
}
}
}
void PrintResultMachine::status(gdioutput &gdi)
{
gdi.fillRight();
gdi.pushX();
gdi.addString("", 0, name);
gdi.addString("", 0, listInfo.getName());
gdi.dropLine();
if (doExport) {
gdi.popX();
gdi.addString("", 0, "Målfil: ");
gdi.addStringUT(0, exportFile).setColor(colorRed);
gdi.dropLine();
}
gdi.fillRight();
gdi.popX();
if (interval>0){
gdi.addString("", 0, "Automatisk utskrift / export: ");
gdi.addTimer(gdi.getCY(), gdi.getCX(), timerIgnoreSign, (GetTickCount()-timeout)/1000);
}
else {
}
gdi.popX();
gdi.dropLine(2);
gdi.addButton("Stop", "Stoppa automaten", AutomaticCB).setExtra(getId());
gdi.addButton("PrintNow", "Exportera nu", AutomaticCB).setExtra(getId());
gdi.fillDown();
gdi.addButton("Result", "Inställningar...", AutomaticCB).setExtra(getId());
gdi.popX();
}
void PrewarningMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
settingsTitle(gdi, "Förvarningsröst");
startCancelInterval(gdi, "StartPrewarning", created, IntervalNone, L"");
gdi.addString("", 10, "help:computer_voice");
gdi.pushX();
gdi.fillRight();
gdi.addInput("WaveFolder", waveFolder, 32, 0, L"Ljudfiler, baskatalog.");
gdi.fillDown();
gdi.dropLine();
gdi.addButton("WaveBrowse", "Bläddra...", AutomaticCB);
gdi.popX();
gdi.addListBox("Controls", 100, 200, 0, L"", L"", true);
gdi.pushX();
gdi.fillDown();
vector< pair<wstring, size_t> > d;
oe.fillControls(d, oEvent::CTCourseControl);
gdi.addItem("Controls", d);
gdi.setSelection("Controls", controls);
gdi.popX();
gdi.addButton("SelectAll", "Välj alla", AutomaticCB, "").setExtra(L"Controls");
gdi.popX();
}
void PrewarningMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
{
oe->playPrewarningSounds(waveFolder, controlsSI);
}
void PrewarningMachine::status(gdioutput &gdi)
{
gdi.addString("", 1, name);
string info="Förvarning på (SI-kod): ";
bool first=true;
if (controls.empty())
info+="alla stämplingar";
else {
for (set<int>::iterator it=controlsSI.begin();it!=controlsSI.end();++it) {
char bf[32];
_itoa_s(*it, bf, 10);
if (!first) info+=", ";
else first=false;
info+=bf;
}
}
gdi.addString("", 0, info);
gdi.fillRight();
gdi.pushX();
gdi.popX();
gdi.dropLine(0.3);
gdi.addButton("Stop", "Stoppa automaten", AutomaticCB).setExtra(getId());
gdi.addButton("TestVoice", "Testa rösten", AutomaticCB).setExtra(getId());
gdi.fillDown();
gdi.addButton("Prewarning", "Inställningar...", AutomaticCB).setExtra(getId());
gdi.popX();
}
void PunchMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
settingsTitle(gdi, "Test av stämplingsinläsningar");
wstring time=created ? L"10" : itow(interval);
startCancelInterval(gdi, "StartPunch", created, IntervalSecond, time);
gdi.addString("", 10, "help:simulate");
gdi.pushX();
gdi.fillRight();
gdi.dropLine();
gdi.addString("", 0, "Radiotider, kontroll:");
gdi.dropLine(-0.2);
gdi.addInput("Radio", L"", 6, 0);
gdi.fillDown();
gdi.popX();
gdi.dropLine(5);
gdi.addString("", 1, "Generera testtävling");
gdi.fillRight();
gdi.addInput("nRunner", L"100", 10, 0, L"Antal löpare");
gdi.addInput("nClass", L"10", 10, 0, L"Antal klasser");
gdi.dropLine();
gdi.addCheckbox("UseRelay", "Med stafettklasser");
gdi.addButton("GenerateCMP", "Generera testtävling", AutomaticCB);
}
void PunchMachine::status(gdioutput &gdi)
{
gdi.addString("", 1, name);
gdi.fillRight();
gdi.pushX();
if (interval>0){
gdi.addString("", 0, "Stämplar om: ");
gdi.addTimer(gdi.getCY(), gdi.getCX(), timerIgnoreSign|timeSeconds, (GetTickCount()-timeout)/1000);
gdi.addString("", 0, "(sekunder)");
}
else {
}
gdi.popX();
gdi.dropLine(2);
gdi.addButton("Stop", "Stoppa automaten", AutomaticCB).setExtra(getId());
gdi.fillDown();
gdi.addButton("Punches", "Inställningar...", AutomaticCB).setExtra(getId());
gdi.popX();
}
void PunchMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
{
#ifndef MEOSDB
SICard sic(ConvertedTimeStatus::Hour24);
SportIdent &si = TabSI::getSI(gdi);
if (radio == 0) {
oe->generateTestCard(sic);
if (!sic.empty()) {
if (!radio) si.addCard(sic);
}
else gdi.addInfoBox("", L"Failed to generate card.", interval * 2);
}
else {
SICard sic(ConvertedTimeStatus::Hour24);
vector<pRunner> rr;
oe->getRunners(0, 0, rr);
vector<pRunner> cCand;
vector<pFreePunch> pp;
for (auto r : rr) {
if (r->getStatus() == StatusUnknown && r->startTimeAvailable()) {
auto pc = r->getCourse(false);
if (radio < 10 || pc->hasControlCode(radio)) {
pp.clear();
oe->getPunchesForRunner(r->getId(), pp);
bool hit = false;
for (auto p : pp) {
if (p->getTypeCode() == radio)
hit = true;
}
if (!hit)
cCand.push_back(r);
}
}
}
if (cCand.size() > 0) {
int ix = rand() % cCand.size();
pRunner r = cCand[ix];
sic.convertedTime = ConvertedTimeStatus::Done;
sic.CardNumber = r->getCardNo();
sic.punchOnly = true;
sic.nPunch = 1;
sic.Punch[0].Code = radio;
sic.Punch[0].Time = 600 + rand() % 1200 + r->getStartTime();
si.addCard(sic);
}
}
#endif
}
void SplitsMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
wstring time;
if (interval>0)
time = itow(interval);
else if (created)
time = L"30";
settingsTitle(gdi, "Sträcktider / WinSplits");
startCancelInterval(gdi, "StartSplits", created, IntervalSecond, time);
gdi.addString("", 0, "Intervall (sekunder). Lämna blankt för att uppdatera när "
"tävlingsdata ändras.");
gdi.dropLine();
gdi.addString("", 10, "help:winsplits_auto");
gdi.dropLine();
gdi.fillRight();
gdi.addInput("FileName", file, 30, 0, L"Filnamn:");
gdi.dropLine(0.9);
gdi.addButton("BrowseSplits", "Bläddra...", AutomaticCB);
gdi.popX();
gdi.dropLine(2);
}
void SplitsMachine::status(gdioutput &gdi)
{
gdi.addString("", 1, name);
if (!file.empty()) {
gdi.fillRight();
gdi.pushX();
gdi.addString("", 0, L"Fil: X#" + file);
if (interval>0){
gdi.popX();
gdi.dropLine(1);
gdi.addString("", 0, "Skriver sträcktider om: ");
gdi.addTimer(gdi.getCY(), gdi.getCX(), timerIgnoreSign|timeSeconds, (GetTickCount()-timeout)/1000);
gdi.addString("", 0, "(sekunder)");
}
else {
gdi.dropLine(1);
gdi.addString("", 0, "Skriver sträcktider när tävlingsdata ändras.");
}
gdi.popX();
}
gdi.dropLine(2);
gdi.addButton("Stop", "Stoppa automaten", AutomaticCB).setExtra(getId());
gdi.fillDown();
gdi.addButton("Splits", "Inställningar...", AutomaticCB).setExtra(getId());
gdi.popX();
}
void SplitsMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast)
{
if ((interval>0 && ast==SyncTimer) || (interval==0 && ast==SyncDataUp)) {
if (!file.empty())
oe->exportIOFSplits(oEvent::IOF20, file.c_str(), true, false, classes,
leg, false, true, true, false);
}
}
void SaveMachine::status(gdioutput &gdi) {
gdi.addString("", 1, name);
if (!baseFile.empty()) {
gdi.fillRight();
gdi.pushX();
gdi.addString("", 0, L"Destination: X#" + baseFile);
if (interval>0){
gdi.popX();
gdi.dropLine(1);
gdi.addString("", 0, "Säkerhetskopierar om: ");
gdi.addTimer(gdi.getCY(), gdi.getCX(), timerIgnoreSign, (GetTickCount()-timeout)/1000);
}
gdi.popX();
}
gdi.dropLine(2);
gdi.addButton("Stop", "Stoppa automaten", AutomaticCB).setExtra(getId());
gdi.fillDown();
gdi.addButton("SaveBackup", "Inställningar...", AutomaticCB).setExtra(getId());
gdi.popX();
}
void SaveMachine::process(gdioutput &gdi, oEvent *oe, AutoSyncType ast) {
if (interval>0 && ast==SyncTimer) {
if (!baseFile.empty()) {
wstring file = baseFile + L"meos_backup_" + oe->getDate() + L"_" + itow(saveIter++) + L".xml";
oe->autoSynchronizeLists(true);
oe->save(file);
}
}
}
void SaveMachine::settings(gdioutput &gdi, oEvent &oe, bool created) {
settingsTitle(gdi, "Säkerhetskopiering");
wstring time=created ? L"10:00" : getTimeMS(interval);
startCancelInterval(gdi, "StartBackup", created, IntervalMinute, time);
int cx = gdi.getCX();
gdi.addInput("BaseFile", baseFile, 32, 0, L"Mapp:");
gdi.dropLine(0.7);
gdi.addButton("BrowseFolder", "Bläddra...", AutomaticCB).setExtra(L"BaseFile");
gdi.setCX(cx);
}
void SaveMachine::saveSettings(gdioutput &gdi) {
wstring minute=gdi.getText("Interval");
int t=convertAbsoluteTimeMS(minute);
if (t<2 || t>7200) {
throw meosException("Intervallet måste anges på formen MM:SS.");
}
wstring f = gdi.getText("BaseFile");
if (f.empty()) {
throw meosException("Filnamnet får inte vara tomt");
}
if (*f.rbegin() != '\\' && *f.rbegin() != '/')
f += L"\\";
wstring sample = f + L"sample.txt";
ofstream fout(sample.c_str(), ios_base::trunc|ios_base::out);
bool bad = false;
if (fout.bad())
bad = true;
else {
fout << "foo" << endl;
fout.close();
bad = fout.bad();
_wremove(sample.c_str());
}
if (bad)
throw meosException(L"Ogiltig destination X#" + f);
baseFile = f;
interval = t;
}
void TabAuto::clearCompetitionData() {
}