512 lines
14 KiB
C++
512 lines
14 KiB
C++
#include "main.h"
|
|
#include <qwindowsstyle.h>
|
|
#include <qstylefactory.h>
|
|
#include <qstyle.h>
|
|
#include <qpalette.h>
|
|
#include <qradiobutton.h>
|
|
#include <qcheckbox.h>
|
|
#include <qbuttongroup.h>
|
|
#include <qtooltip.h>
|
|
#include <qtimer.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "instr_hosts.h"
|
|
#include "utils.h"
|
|
|
|
QPoint firstPos;
|
|
|
|
FILE *fil;
|
|
char preffile[PATH_MAX]="";
|
|
int prefdirlen = 0;
|
|
char prefil[80]="";
|
|
char homeinstr[64]="";
|
|
const char *instr;
|
|
//char prefinstr[64]="";
|
|
char frominstr[128];
|
|
|
|
const char *fullinstr(const char *host, const char *instr) {
|
|
static char buf[128];
|
|
if (strncasecmp(host, instr, strlen(instr)) == 0) {
|
|
return host;
|
|
}
|
|
snprintf(buf, sizeof buf, "%s at %s", host, strtoupper(instr));
|
|
return buf;
|
|
}
|
|
|
|
SeaApp::SeaApp(int &argc, char **argv) : QApplication(argc, argv) {
|
|
char *arg;
|
|
char *style=0;
|
|
char instrList[1024];
|
|
QString deviceList;
|
|
int i;
|
|
|
|
int port;
|
|
char host[64];
|
|
int query;
|
|
struct tm tm;
|
|
time_t startupTime, now, range;
|
|
QString tip;
|
|
SicsConnection *seaman;
|
|
char *remotehost;
|
|
char *remoteinstr;
|
|
char *hostname;
|
|
char warning[256];
|
|
int x, y, w, h;
|
|
QFont afont = font();
|
|
afont.setPointSize(12);
|
|
setFont(afont);
|
|
|
|
time(&lastActive);
|
|
time(&lastTimer);
|
|
tab = NULL;
|
|
sleepTime = 3600;
|
|
sleeping = false;
|
|
frominstr[0] = 0;
|
|
|
|
home = InstrHost("sea", "", homeinstr, sizeof homeinstr, host, sizeof host, &port);
|
|
if (port == 0) {
|
|
homeinstr[0]='\0';
|
|
}
|
|
remoteinstr = InstrHostRemoteInstr();
|
|
hostname = InstrHostName();
|
|
remotehost = InstrHostRemoteName();
|
|
instr = NULL;
|
|
query = -1;
|
|
range = 1800;
|
|
setprintit(0);
|
|
for (i=1; i<argc; i++) {
|
|
arg = argv[i];
|
|
if (strcmp(arg,"-q") == 0) {
|
|
query = 1; /* ask for instrument */
|
|
} else if (strcmp(arg,"-r") == 0) {
|
|
/* disable verbose startup, obsolete */
|
|
} else if (strcmp(arg,"-v") == 0) {
|
|
/* verbose startup */
|
|
setprintit(2);
|
|
} else if (strcmp(arg,"-d") == 0) {
|
|
/* give date & time, +- 0.5 h */
|
|
i++;
|
|
if (i<argc) {
|
|
time(&now);
|
|
tm = *localtime(&now);
|
|
strptime(argv[i], "%Y-%m-%d:%H:%M:%S", &tm);
|
|
range = mktime(&tm);
|
|
}
|
|
} else if (strcmp(arg,"-s") == 0) {
|
|
/* select style */
|
|
i++;
|
|
if (i>=argc) {
|
|
QStringList keys=QStyleFactory::keys();
|
|
printf("styles: %s\n", keys.join(", ").latin1());
|
|
ciao();
|
|
}
|
|
style = argv[i];
|
|
} else if (strcasecmp(arg,"-h") == 0) {
|
|
/* ??? */
|
|
home = 1;
|
|
} else if (strcasecmp(arg,"-p") == 0) {
|
|
i++;
|
|
/* ignore obsolete pid file option */
|
|
} else if (strcasecmp(arg,"-c") == 0) {
|
|
i++;
|
|
/* ignore obsolete watch/restart option */
|
|
} else if (strcasecmp(arg,"-t") == 0) {
|
|
/* set sleep time (1 h by default) */
|
|
i++;
|
|
if (i<argc) {
|
|
sleepTime = atoi(argv[i]);
|
|
if (sleepTime == 0) {
|
|
sleepTime = 365 * 24 * 3600;
|
|
}
|
|
}
|
|
} else if (strcasecmp(arg,"start") == 0) {
|
|
printf("'start' is an illegal argument\n");
|
|
fail();
|
|
} else if (arg[0] !='-') {
|
|
/* an instrument or a hostname */
|
|
if (query < 0) query = 0;
|
|
if (home == 1 && strcasecmp(homeinstr, arg) != 0) {
|
|
snprintf(frominstr, sizeof frominstr, "but logged in to %s", fullinstr(hostname, homeinstr));
|
|
//prefinstr[0] = 0;
|
|
} else if (remoteinstr[0] && strcasecmp(remoteinstr, arg) != 0) {
|
|
snprintf(frominstr, sizeof frominstr, "but logged in from %s", fullinstr(remotehost, remoteinstr));
|
|
//prefinstr[0] = 0;
|
|
}
|
|
/*
|
|
else if (home == 1 && strcasecmp(homeinstr, arg) == 0) {
|
|
prefinstr[0] = 0;
|
|
} else if (prefinstr[0] && strcasecmp(prefinstr, arg) != 0) {
|
|
snprintf(frominstr, sizeof frominstr, "but preferred instrument is %s", strtoupper(prefinstr));
|
|
}
|
|
*/
|
|
instr = strdup(arg);
|
|
port = -1;
|
|
}
|
|
}
|
|
if (query < 0) {
|
|
if (remoteinstr[0] && home == 1 && strcasecmp(remoteinstr, homeinstr) != 0) {
|
|
snprintf(frominstr, sizeof frominstr, "but logged in from %s", fullinstr(remotehost, remoteinstr));
|
|
query = 2; /* no checkbox for default instrument */
|
|
instr = homeinstr;
|
|
} else if (home == 1) { /* one instr found with home as host */
|
|
instr = homeinstr;
|
|
query = 0;
|
|
printf("\nconnect to %s as started from %s (other selection: sea -q)\n", strtoupper(instr), hostname);
|
|
/*
|
|
} else if (prefinstr[0] != 0) { // a default instrument is defined
|
|
instr = prefinstr;
|
|
query = 0;
|
|
printf("\nconnect to %s by preference (other selection: sea -q)\n", strtoupper(prefinstr));
|
|
*/
|
|
} else {
|
|
query = 1;
|
|
}
|
|
}
|
|
if (instr == NULL) {
|
|
instr = ""; //prefinstr;
|
|
}
|
|
QColor bgr(221, 221, 221);
|
|
if (style) {
|
|
if (setStyle(style)) {
|
|
printf("set style to %s\n", style);
|
|
}
|
|
} else {
|
|
setStyle("windows");
|
|
QPalette pal = palette();
|
|
pal.setColor(QColorGroup::Background, bgr);
|
|
pal.setColor(QColorGroup::Button, bgr);
|
|
setPalette(pal);
|
|
}
|
|
|
|
QDialog menu(0);
|
|
QButtonGroup bg(&menu);
|
|
QGridLayout grid(&menu,1,1,12,12);
|
|
QRadioButton *rb;
|
|
|
|
if (port == 0 || query) {
|
|
if (instr[0] == 0) {
|
|
/* determine default instrument */
|
|
if (home == 1) {
|
|
instr = homeinstr;
|
|
/*
|
|
} else if (prefinstr[0]) {
|
|
instr = prefinstr;
|
|
*/
|
|
} else if (remoteinstr[0]) {
|
|
instr = remoteinstr;
|
|
}
|
|
}
|
|
|
|
InstrList("graph", instrList, sizeof instrList);
|
|
QStringList list(QStringList::split(' ', instrList, true));
|
|
QString seamancmd = list.join(",");
|
|
seamancmd.insert(0, "_tcl get_devices ");
|
|
|
|
seaman = new SicsConnection(&menu);
|
|
seaman->setHost("seaman", "sea");
|
|
seaman->setUser("seauser seaser\n");
|
|
|
|
seaman->command(seamancmd.latin1());
|
|
if (!seaman->getLine(deviceList)) {
|
|
deviceList = "";
|
|
}
|
|
QStringList devlist(QStringList::split(',', deviceList, true));
|
|
|
|
seaman->disconnect();
|
|
|
|
int row = 1, col=0, cols = 4;
|
|
|
|
menu.setCaption("Sea");
|
|
// grid.setMargin(5);
|
|
|
|
QLabel *label = new QLabel("Select instrument", &menu);
|
|
QFont font = label->font();
|
|
font.setPointSize(18);
|
|
label->setFont(font);
|
|
QFont tooltipfont = QToolTip::font();
|
|
QToolTip::setFont(font);
|
|
grid.addMultiCellWidget(label, 0, 0, 0, cols-1);
|
|
|
|
QStringList::Iterator dit = devlist.begin();
|
|
for (QStringList::Iterator it = list.begin(); it != list.end(); ++it, ++dit) {
|
|
if ((*it).isEmpty()) {
|
|
if (col >= 0) {
|
|
col = 0;
|
|
row++;
|
|
}
|
|
} else {
|
|
rb = new QRadioButton(*it, &menu);
|
|
rb->setFont(font);
|
|
if (!(*dit).isEmpty()) {
|
|
QToolTip::add(rb, *dit);
|
|
}
|
|
grid.addWidget(rb, row, col);
|
|
QObject::connect(rb, SIGNAL(clicked()), &menu, SLOT(accept()));
|
|
bg.insert(rb);
|
|
col++;
|
|
if (col >= cols) {
|
|
col = 0;
|
|
row++;
|
|
}
|
|
if ((*it).compare(instr) == 0) {
|
|
rb->setChecked(true);
|
|
}
|
|
}
|
|
}
|
|
if (col > 0) {
|
|
row++;
|
|
col = 0;
|
|
}
|
|
|
|
if (query == 1) {
|
|
/*
|
|
QString cbtext("default instrument when started from ");
|
|
cbtext += remotehost;
|
|
defi = new QCheckBox(cbtext, &menu);
|
|
if (prefinstr[0]) defi->setChecked(true);
|
|
grid.addMultiCellWidget(defi, row, row, 0, cols-1);
|
|
row++;
|
|
*/
|
|
}
|
|
|
|
QPushButton ok("OK", &menu);
|
|
ok.setDefault(true);
|
|
ok.setFont(font);
|
|
connect(&ok, SIGNAL(clicked()), &menu, SLOT(accept()));
|
|
grid.addWidget(&ok, row, 0);
|
|
|
|
QPushButton cancel("Quit", &menu);
|
|
cancel.setFont(font);
|
|
connect(&cancel, SIGNAL(clicked()), &menu, SLOT(reject()));
|
|
grid.addWidget(&cancel, row, cols-1);
|
|
|
|
bg.hide();
|
|
|
|
if (printit()) {
|
|
printf("Instrument selection\n");
|
|
}
|
|
if (menu.exec() == QDialog::Rejected) ciao();
|
|
rb = dynamic_cast<QRadioButton *>(bg.selected());
|
|
if (!rb) ciao();
|
|
instr = strdup(rb->text());
|
|
/*
|
|
if (defi) {
|
|
if (defi->isChecked()) {
|
|
snprintf(prefinstr, sizeof prefinstr, "%s", instr);
|
|
} else {
|
|
prefinstr[0] = 0;
|
|
}
|
|
}
|
|
*/
|
|
QToolTip::setFont(tooltipfont);
|
|
}
|
|
|
|
|
|
if (frominstr[0]) {
|
|
snprintf(warning, sizeof warning, "WARNING: connected to %s,\n%s\n", strtoupper(instr), frominstr);
|
|
printf("\n%s\n", warning);
|
|
} else {
|
|
warning[0] = 0;
|
|
}
|
|
time(&startupTime);
|
|
if (printit()) {
|
|
printf("Sea %s starting,\n", instr);
|
|
}
|
|
|
|
// read preferences
|
|
// include the screen size into the name: this helps if clients are used
|
|
// remotely from different screen sizes
|
|
|
|
// new pref. file: include remote host name
|
|
snprintf(preffile, sizeof preffile, "%s/.seapref/%s_%s_%dx%d",
|
|
getenv("HOME"), remotehost, instr, desktop()->width(), desktop()->height());
|
|
prefdirlen = strstr(preffile, "seapref/") + 7 - preffile;
|
|
fil = fopen(preffile, "r");
|
|
if (fil) { /* new style pref file */
|
|
char header[128];
|
|
fgets(header, sizeof header, fil); // skip header
|
|
if (4 != fscanf(fil, "%d %d %d %d", &x, &y, &w, &h)) {
|
|
x = -1;
|
|
}
|
|
fclose(fil);
|
|
prefil[0] = 0;
|
|
} else {
|
|
// old style pref. file
|
|
snprintf(prefil, sizeof prefil, ".sea_%dx%d_%s",
|
|
desktop()->width(), desktop()->height(), instr);
|
|
fil = fopen(prefil, "r");
|
|
if (fil) {
|
|
if (4 != fscanf(fil, "%d %d %d %d", &x, &y, &w, &h)) {
|
|
x = -1;
|
|
}
|
|
fclose(fil);
|
|
} else {
|
|
x = -1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
tab = new Tab(strdup(instr), 0, range, warning);
|
|
if (tab->graph == NULL) ciao();
|
|
connect(tab->device, SIGNAL(restart(const char*)), tab->graph->set, SLOT(restart(const char *)));
|
|
|
|
if (x >= 0) {
|
|
tab->initSize(w, h);
|
|
tab->move(x, y);
|
|
} else {
|
|
tab->initSize(1000, 800);
|
|
}
|
|
tab->show();
|
|
/*
|
|
QBoxLayout *lay = dynamic_cast<QBoxLayout *>(tab->layout());
|
|
|
|
QLayoutIterator it = lay->iterator();
|
|
QLayoutItem *child;
|
|
while ( (child = it.current()) != 0 ) {
|
|
if (child->widget()) {
|
|
printf("- widget %s\n", child->widget()->name());
|
|
} else if (child->spacerItem()) {
|
|
printf("- spacer\n");
|
|
} else if (child->layout()) {
|
|
printf("- layout\n");
|
|
} else {
|
|
printf("- null\n");
|
|
}
|
|
++it;
|
|
}
|
|
lay->insertWidget(3,tab->split);
|
|
*/
|
|
firstPos = tab->pos();
|
|
tab->move(firstPos);
|
|
time(&now);
|
|
if (range > 365*24*3600) {
|
|
tip.sprintf("initially off");
|
|
} else if ((int)(now - startupTime) < 7) {
|
|
tip.sprintf("initially on\n%d sec for startup:\nconnection seems fast enough", (int)(now - startupTime));
|
|
tab->graph->liveBox->setChecked(true);
|
|
} else {
|
|
tip.sprintf("initially off\n%d sec for startup:\nconnection seems slow", (int)(now - startupTime));
|
|
}
|
|
QToolTip::add(tab->graph->liveBox, tip);
|
|
|
|
connect(this, SIGNAL(lastWindowClosed()), this, SLOT(quit()));
|
|
// connect(this, SIGNAL(lastWindowClosed()), this, SLOT(ciao()));
|
|
|
|
connect(tab->exportXY, SIGNAL(procEvt()), this, SLOT(procEvt()));
|
|
connect(tab->settings->set, SIGNAL(gotoTime(time_t, time_t, time_t, bool)),
|
|
tab->report, SLOT(gotoTime(time_t, time_t, time_t, bool)));
|
|
connect(tab->report, SIGNAL(setMarker(time_t)),
|
|
tab->settings->set, SLOT(setMarker(time_t)));
|
|
connect(tab->settings->set->ec, SIGNAL(progress(int)), tab->exportXY, SLOT(progress(int)));
|
|
return;
|
|
}
|
|
|
|
void Exit(int code) {
|
|
exit(code);
|
|
}
|
|
|
|
void SeaApp::ciao() {
|
|
Exit(0);
|
|
}
|
|
|
|
void SeaApp::fail() {
|
|
Exit(257);
|
|
}
|
|
|
|
void SeaApp::procEvt() {
|
|
processEvents(100);
|
|
}
|
|
|
|
QRect savedWinGeo;
|
|
|
|
bool moveOrResize = true;
|
|
|
|
bool SeaApp::notify(QObject *receiver, QEvent *e) {
|
|
time_t now;
|
|
bool result;
|
|
|
|
QEvent::Type t = e->type();
|
|
switch (t) {
|
|
case QEvent::MouseButtonPress:
|
|
case QEvent::MouseButtonDblClick:
|
|
case QEvent::KeyPress:
|
|
lastActive = time(NULL);
|
|
if (tab) {
|
|
if (sleeping) {
|
|
tab->wake();
|
|
sleeping = FALSE;
|
|
}
|
|
tab->graph->set->runningMarkerOff(true);
|
|
result = QApplication::notify(receiver, e);
|
|
tab->graph->set->runningMarkerOff(false);
|
|
return result;
|
|
}
|
|
break;
|
|
case QEvent::Timer:
|
|
time(&now);
|
|
if (now > lastActive + sleepTime) {
|
|
if (frominstr[0])
|
|
exit();
|
|
if (lastTimer < now - 120) {
|
|
lastActive = now + 120 - sleepTime;
|
|
}
|
|
// if (home != 1 && now > lastActive + 24*3600) {
|
|
// exit(); // exit when not on instrument computer after one day
|
|
// }
|
|
if (now > lastActive + 24*3600) {
|
|
exit(); // exit anyway when not active for one day
|
|
}
|
|
if (!sleeping && tab != NULL) {
|
|
tab->sleep("sleeping ... click to wake up");
|
|
sleeping = TRUE;
|
|
}
|
|
}
|
|
if (moveOrResize && now != lastTimer && tab != NULL &&
|
|
tab->settings->set->sc->state != disconnected) {
|
|
moveOrResize = false;
|
|
QRect winGeo(tab->pos(), tab->size());
|
|
if (winGeo != savedWinGeo) {
|
|
savedWinGeo = winGeo;
|
|
fil = fopen(preffile, "w");
|
|
if (fil == NULL) {
|
|
preffile[prefdirlen] = 0;
|
|
mkdir(preffile, 0755);
|
|
chmod(preffile, 0755);
|
|
preffile[prefdirlen] = '/';
|
|
fil = fopen(preffile, "w");
|
|
}
|
|
if (fil) {
|
|
fprintf(fil, "#seaclient preferences V1.1\n%d %d %d %d\n",
|
|
winGeo.x(), winGeo.y(),
|
|
winGeo.width(), winGeo.height());
|
|
fclose(fil);
|
|
}
|
|
}
|
|
}
|
|
lastTimer = now;
|
|
break;
|
|
case QEvent::Move:
|
|
case QEvent::Resize:
|
|
moveOrResize = true;
|
|
break;
|
|
case QEvent::WindowDeactivate:
|
|
// printf("deact\n");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return QApplication::notify(receiver, e);
|
|
}
|
|
|
|
int main(int argc, char ** argv) {
|
|
SeaApp sea(argc, argv);
|
|
// printf("exit %d\n", sea.exec());
|
|
// return 0;
|
|
return sea.exec();
|
|
}
|