most files - check if this is all we need
This commit is contained in:
386
Makefile_rhel7
Normal file
386
Makefile_rhel7
Normal file
@ -0,0 +1,386 @@
|
||||
#############################################################################
|
||||
# Makefile for building: rhel7/SeaClient
|
||||
# Generated by qmake (1.07a) (Qt 3.3.4) on: Thu Apr 6 11:05:39 2017
|
||||
# Project: SeaClient.pro
|
||||
# Template: app
|
||||
# Command: $(QMAKE) -o Makefile_rhel7 SeaClient.pro
|
||||
#############################################################################
|
||||
|
||||
####### Compiler, tools and options
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
LEX = flex
|
||||
YACC = yacc
|
||||
CFLAGS = -pipe -Wall -W -g -D_REENTRANT -DQT_THREAD_SUPPORT -DQT_SHARED
|
||||
CXXFLAGS = -pipe -Wall -W -Wno-non-virtual-dtor -Wno-unused-parameter -Wno-write-strings -Wno-unused-but-set-variable -Wno-type-limits -g -D_REENTRANT -DQT_THREAD_SUPPORT -DQT_SHARED
|
||||
LEXFLAGS =
|
||||
YACCFLAGS= -d
|
||||
INCPATH = -I/afs/psi.ch/user/z/zolliker/public/qt64/mkspecs/default -I. -I../qtx64/qt-x11-free-3.3.4/include -I../qtx64/qwt-4.2.0/include -I$(QTDIR)/include -I.ui/ -I.moc/
|
||||
LINK = g++
|
||||
LFLAGS = -Wl,-rpath,$(QTDIR)/lib
|
||||
LIBS = $(SUBLIBS) -L$(QTDIR)/lib -L/usr/X11R6/lib -L/afs/psi.ch/user/z/zolliker/public/qwt64/lib -lqwt -lqt-mt -lXext -lX11 -lm -lpthread
|
||||
AR = ar cqs
|
||||
RANLIB =
|
||||
MOC = $(QTDIR)/bin/moc
|
||||
UIC = $(QTDIR)/bin/uic
|
||||
QMAKE = qmake
|
||||
TAR = tar -cf
|
||||
GZIP = gzip -9f
|
||||
COPY = cp -f
|
||||
COPY_FILE= $(COPY)
|
||||
COPY_DIR = $(COPY) -r
|
||||
INSTALL_FILE= $(COPY_FILE)
|
||||
INSTALL_DIR = $(COPY_DIR)
|
||||
DEL_FILE = rm -f
|
||||
SYMLINK = ln -sf
|
||||
DEL_DIR = rmdir
|
||||
MOVE = mv -f
|
||||
CHK_DIR_EXISTS= test -d
|
||||
MKDIR = mkdir -p
|
||||
|
||||
####### Output directory
|
||||
|
||||
OBJECTS_DIR = rhel7/
|
||||
|
||||
####### Files
|
||||
|
||||
HEADERS = main.h \
|
||||
seaset.h \
|
||||
seaplot.h \
|
||||
sicsconn.h \
|
||||
tab.h \
|
||||
settings.h \
|
||||
command.h \
|
||||
graph.h \
|
||||
utils.h \
|
||||
export.h \
|
||||
report.h \
|
||||
device.h
|
||||
SOURCES = main.cpp \
|
||||
seaset.cpp \
|
||||
seaplot.cpp \
|
||||
instr_hosts.cpp \
|
||||
sicsconn.cpp \
|
||||
tab.cpp \
|
||||
settings.cpp \
|
||||
command.cpp \
|
||||
graph.cpp \
|
||||
utils.cpp \
|
||||
export.cpp \
|
||||
report.cpp \
|
||||
device.cpp
|
||||
OBJECTS = rhel7/main.o \
|
||||
rhel7/seaset.o \
|
||||
rhel7/seaplot.o \
|
||||
rhel7/instr_hosts.o \
|
||||
rhel7/sicsconn.o \
|
||||
rhel7/tab.o \
|
||||
rhel7/settings.o \
|
||||
rhel7/command.o \
|
||||
rhel7/graph.o \
|
||||
rhel7/utils.o \
|
||||
rhel7/export.o \
|
||||
rhel7/report.o \
|
||||
rhel7/device.o
|
||||
FORMS =
|
||||
UICDECLS =
|
||||
UICIMPLS =
|
||||
SRCMOC = .moc/moc_main.cpp \
|
||||
.moc/moc_seaset.cpp \
|
||||
.moc/moc_seaplot.cpp \
|
||||
.moc/moc_sicsconn.cpp \
|
||||
.moc/moc_tab.cpp \
|
||||
.moc/moc_settings.cpp \
|
||||
.moc/moc_command.cpp \
|
||||
.moc/moc_graph.cpp \
|
||||
.moc/moc_utils.cpp \
|
||||
.moc/moc_export.cpp \
|
||||
.moc/moc_report.cpp \
|
||||
.moc/moc_device.cpp
|
||||
OBJMOC = rhel7/moc_main.o \
|
||||
rhel7/moc_seaset.o \
|
||||
rhel7/moc_seaplot.o \
|
||||
rhel7/moc_sicsconn.o \
|
||||
rhel7/moc_tab.o \
|
||||
rhel7/moc_settings.o \
|
||||
rhel7/moc_command.o \
|
||||
rhel7/moc_graph.o \
|
||||
rhel7/moc_utils.o \
|
||||
rhel7/moc_export.o \
|
||||
rhel7/moc_report.o \
|
||||
rhel7/moc_device.o
|
||||
DIST = SeaClient.pro
|
||||
QMAKE_TARGET = SeaClient
|
||||
DESTDIR = rhel7/
|
||||
TARGET = rhel7/SeaClient
|
||||
|
||||
first: all
|
||||
####### Implicit rules
|
||||
|
||||
.SUFFIXES: .c .o .cpp .cc .cxx .C
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
|
||||
|
||||
.cc.o:
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
|
||||
|
||||
.cxx.o:
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
|
||||
|
||||
.C.o:
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
|
||||
|
||||
####### Build rules
|
||||
|
||||
all: Makefile_rhel7 $(TARGET)
|
||||
|
||||
$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC)
|
||||
test -d rhel7/ || mkdir -p rhel7/
|
||||
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(OBJCOMP) $(LIBS)
|
||||
|
||||
mocables: $(SRCMOC)
|
||||
uicables: $(UICDECLS) $(UICIMPLS)
|
||||
|
||||
$(MOC):
|
||||
( cd $(QTDIR)/src/moc && $(MAKE) )
|
||||
|
||||
Makefile_rhel7: SeaClient.pro /afs/psi.ch/user/z/zolliker/public/qt64/mkspecs/default/qmake.conf ../qt64/lib/libqt-mt.prl
|
||||
$(QMAKE) -o Makefile_rhel7 SeaClient.pro
|
||||
qmake:
|
||||
@$(QMAKE) -o Makefile_rhel7 SeaClient.pro
|
||||
|
||||
dist:
|
||||
@mkdir -p rhel7/SeaClient && $(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) rhel7/SeaClient/ && ( cd `dirname rhel7/SeaClient` && $(TAR) SeaClient.tar SeaClient && $(GZIP) SeaClient.tar ) && $(MOVE) `dirname rhel7/SeaClient`/SeaClient.tar.gz . && $(DEL_FILE) -r rhel7/SeaClient
|
||||
|
||||
mocclean:
|
||||
-$(DEL_FILE) $(OBJMOC)
|
||||
-$(DEL_FILE) $(SRCMOC)
|
||||
|
||||
uiclean:
|
||||
|
||||
yaccclean:
|
||||
lexclean:
|
||||
clean: mocclean
|
||||
-$(DEL_FILE) $(OBJECTS)
|
||||
-$(DEL_FILE) *~ core *.core
|
||||
|
||||
|
||||
####### Sub-libraries
|
||||
|
||||
distclean: clean
|
||||
-$(DEL_FILE) rhel7/$(TARGET) $(TARGET)
|
||||
|
||||
|
||||
FORCE:
|
||||
|
||||
####### Compile
|
||||
|
||||
rhel7/main.o: main.cpp main.h \
|
||||
instr_hosts.h \
|
||||
tab.h \
|
||||
graph.h \
|
||||
settings.h \
|
||||
device.h \
|
||||
export.h \
|
||||
report.h \
|
||||
seaset.h \
|
||||
sicsconn.h \
|
||||
seaplot.h \
|
||||
command.h \
|
||||
utils.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/main.o main.cpp
|
||||
|
||||
rhel7/seaset.o: seaset.cpp seaset.h \
|
||||
utils.h \
|
||||
sicsconn.h \
|
||||
seaplot.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/seaset.o seaset.cpp
|
||||
|
||||
rhel7/seaplot.o: seaplot.cpp seaplot.h \
|
||||
utils.h \
|
||||
seaset.h \
|
||||
sicsconn.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/seaplot.o seaplot.cpp
|
||||
|
||||
rhel7/instr_hosts.o: instr_hosts.cpp instr_hosts.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/instr_hosts.o instr_hosts.cpp
|
||||
|
||||
rhel7/sicsconn.o: sicsconn.cpp sicsconn.h \
|
||||
instr_hosts.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/sicsconn.o sicsconn.cpp
|
||||
|
||||
rhel7/tab.o: tab.cpp tab.h \
|
||||
graph.h \
|
||||
settings.h \
|
||||
device.h \
|
||||
export.h \
|
||||
report.h \
|
||||
seaset.h \
|
||||
sicsconn.h \
|
||||
seaplot.h \
|
||||
command.h \
|
||||
utils.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/tab.o tab.cpp
|
||||
|
||||
rhel7/settings.o: settings.cpp settings.h \
|
||||
utils.h \
|
||||
seaset.h \
|
||||
device.h \
|
||||
sicsconn.h \
|
||||
seaplot.h \
|
||||
command.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/settings.o settings.cpp
|
||||
|
||||
rhel7/command.o: command.cpp command.h \
|
||||
utils.h \
|
||||
sicsconn.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/command.o command.cpp
|
||||
|
||||
rhel7/graph.o: graph.cpp graph.h \
|
||||
seaset.h \
|
||||
utils.h \
|
||||
sicsconn.h \
|
||||
seaplot.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/graph.o graph.cpp
|
||||
|
||||
rhel7/utils.o: utils.cpp utils.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/utils.o utils.cpp
|
||||
|
||||
rhel7/export.o: export.cpp export.h \
|
||||
seaset.h \
|
||||
sicsconn.h \
|
||||
seaplot.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/export.o export.cpp
|
||||
|
||||
rhel7/report.o: report.cpp report.h \
|
||||
sicsconn.h \
|
||||
utils.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/report.o report.cpp
|
||||
|
||||
rhel7/device.o: device.cpp device.h \
|
||||
utils.h \
|
||||
seaset.h \
|
||||
command.h \
|
||||
sicsconn.h \
|
||||
seaplot.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/device.o device.cpp
|
||||
|
||||
rhel7/moc_main.o: .moc/moc_main.cpp main.h tab.h \
|
||||
graph.h \
|
||||
settings.h \
|
||||
device.h \
|
||||
export.h \
|
||||
report.h \
|
||||
seaset.h \
|
||||
sicsconn.h \
|
||||
seaplot.h \
|
||||
command.h \
|
||||
utils.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_main.o .moc/moc_main.cpp
|
||||
|
||||
rhel7/moc_seaset.o: .moc/moc_seaset.cpp seaset.h sicsconn.h \
|
||||
seaplot.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_seaset.o .moc/moc_seaset.cpp
|
||||
|
||||
rhel7/moc_seaplot.o: .moc/moc_seaplot.cpp seaplot.h seaset.h \
|
||||
sicsconn.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_seaplot.o .moc/moc_seaplot.cpp
|
||||
|
||||
rhel7/moc_sicsconn.o: .moc/moc_sicsconn.cpp sicsconn.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_sicsconn.o .moc/moc_sicsconn.cpp
|
||||
|
||||
rhel7/moc_tab.o: .moc/moc_tab.cpp tab.h graph.h \
|
||||
settings.h \
|
||||
device.h \
|
||||
export.h \
|
||||
report.h \
|
||||
seaset.h \
|
||||
sicsconn.h \
|
||||
seaplot.h \
|
||||
command.h \
|
||||
utils.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_tab.o .moc/moc_tab.cpp
|
||||
|
||||
rhel7/moc_settings.o: .moc/moc_settings.cpp settings.h seaset.h \
|
||||
device.h \
|
||||
sicsconn.h \
|
||||
seaplot.h \
|
||||
command.h \
|
||||
utils.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_settings.o .moc/moc_settings.cpp
|
||||
|
||||
rhel7/moc_command.o: .moc/moc_command.cpp command.h sicsconn.h \
|
||||
utils.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_command.o .moc/moc_command.cpp
|
||||
|
||||
rhel7/moc_graph.o: .moc/moc_graph.cpp graph.h seaset.h \
|
||||
sicsconn.h \
|
||||
seaplot.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_graph.o .moc/moc_graph.cpp
|
||||
|
||||
rhel7/moc_utils.o: .moc/moc_utils.cpp utils.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_utils.o .moc/moc_utils.cpp
|
||||
|
||||
rhel7/moc_export.o: .moc/moc_export.cpp export.h seaset.h \
|
||||
sicsconn.h \
|
||||
seaplot.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_export.o .moc/moc_export.cpp
|
||||
|
||||
rhel7/moc_report.o: .moc/moc_report.cpp report.h sicsconn.h \
|
||||
utils.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_report.o .moc/moc_report.cpp
|
||||
|
||||
rhel7/moc_device.o: .moc/moc_device.cpp device.h seaset.h \
|
||||
command.h \
|
||||
sicsconn.h \
|
||||
seaplot.h \
|
||||
utils.h
|
||||
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o rhel7/moc_device.o .moc/moc_device.cpp
|
||||
|
||||
.moc/moc_main.cpp: $(MOC) main.h
|
||||
$(MOC) main.h -o .moc/moc_main.cpp
|
||||
|
||||
.moc/moc_seaset.cpp: $(MOC) seaset.h
|
||||
$(MOC) seaset.h -o .moc/moc_seaset.cpp
|
||||
|
||||
.moc/moc_seaplot.cpp: $(MOC) seaplot.h
|
||||
$(MOC) seaplot.h -o .moc/moc_seaplot.cpp
|
||||
|
||||
.moc/moc_sicsconn.cpp: $(MOC) sicsconn.h
|
||||
$(MOC) sicsconn.h -o .moc/moc_sicsconn.cpp
|
||||
|
||||
.moc/moc_tab.cpp: $(MOC) tab.h
|
||||
$(MOC) tab.h -o .moc/moc_tab.cpp
|
||||
|
||||
.moc/moc_settings.cpp: $(MOC) settings.h
|
||||
$(MOC) settings.h -o .moc/moc_settings.cpp
|
||||
|
||||
.moc/moc_command.cpp: $(MOC) command.h
|
||||
$(MOC) command.h -o .moc/moc_command.cpp
|
||||
|
||||
.moc/moc_graph.cpp: $(MOC) graph.h
|
||||
$(MOC) graph.h -o .moc/moc_graph.cpp
|
||||
|
||||
.moc/moc_utils.cpp: $(MOC) utils.h
|
||||
$(MOC) utils.h -o .moc/moc_utils.cpp
|
||||
|
||||
.moc/moc_export.cpp: $(MOC) export.h
|
||||
$(MOC) export.h -o .moc/moc_export.cpp
|
||||
|
||||
.moc/moc_report.cpp: $(MOC) report.h
|
||||
$(MOC) report.h -o .moc/moc_report.cpp
|
||||
|
||||
.moc/moc_device.cpp: $(MOC) device.h
|
||||
$(MOC) device.h -o .moc/moc_device.cpp
|
||||
|
||||
####### Install
|
||||
|
||||
install:
|
||||
|
||||
uninstall:
|
||||
|
47
SeaClient.pro
Normal file
47
SeaClient.pro
Normal file
@ -0,0 +1,47 @@
|
||||
TEMPLATE = app
|
||||
LANGUAGE = C++
|
||||
|
||||
CONFIG += qt-mt warn_on thread debug static
|
||||
|
||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-non-virtual-dtor -Wno-unused-parameter -Wno-write-strings \
|
||||
-Wno-unused-but-set-variable -Wno-type-limits
|
||||
|
||||
LIBS += -L$$(QWTDIR)/lib -lqwt
|
||||
|
||||
INCLUDEPATH += $$(QTDIR)/include
|
||||
INCLUDEPATH += $$(QWTDIR)/include
|
||||
|
||||
HEADERS += main.h \
|
||||
seaset.h \
|
||||
seaplot.h \
|
||||
sicsconn.h \
|
||||
tab.h \
|
||||
settings.h \
|
||||
command.h \
|
||||
graph.h \
|
||||
utils.h \
|
||||
export.h \
|
||||
report.h \
|
||||
device.h
|
||||
|
||||
SOURCES += main.cpp \
|
||||
seaset.cpp \
|
||||
seaplot.cpp \
|
||||
instr_hosts.cpp \
|
||||
sicsconn.cpp \
|
||||
tab.cpp \
|
||||
settings.cpp \
|
||||
command.cpp \
|
||||
graph.cpp \
|
||||
utils.cpp \
|
||||
export.cpp \
|
||||
report.cpp \
|
||||
device.cpp
|
||||
|
||||
unix {
|
||||
UI_DIR = .ui
|
||||
MOC_DIR = .moc
|
||||
OBJECTS_DIR = $$(linuxsys)
|
||||
DESTDIR = $$(linuxsys)
|
||||
}
|
||||
|
351
command.cpp
Normal file
351
command.cpp
Normal file
@ -0,0 +1,351 @@
|
||||
#include "command.h"
|
||||
#include <qlayout.h>
|
||||
#include <qlabel.h>
|
||||
#include <qfont.h>
|
||||
#include <qcolor.h>
|
||||
#include <qlabel.h>
|
||||
#include <qcheckbox.h>
|
||||
#include <qevent.h>
|
||||
#include <qtimer.h>
|
||||
#include <qstylesheet.h>
|
||||
#include <assert.h>
|
||||
#include "utils.h"
|
||||
|
||||
class CmdLine : public QLineEdit {
|
||||
public:
|
||||
CmdLine(QWidget *parent, const char *name) : QLineEdit(parent, name), history(""), edit("") {
|
||||
p = history.end();
|
||||
atEnd = true;
|
||||
}
|
||||
void keyPressEvent(QKeyEvent *e) {
|
||||
int key = e->key();
|
||||
if (key == Qt::Key_Up) {
|
||||
if (p == history.end()) {
|
||||
if (text().isEmpty()) {
|
||||
if (!edit.isEmpty()) {
|
||||
setText(edit);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
edit = text();
|
||||
}
|
||||
}
|
||||
if (p != history.begin()) {
|
||||
--p;
|
||||
setText(*p);
|
||||
}
|
||||
} else if (key == Qt::Key_Down) {
|
||||
if (p != history.end()) {
|
||||
p++;
|
||||
}
|
||||
if (p == history.end()) {
|
||||
if (edit.compare(text()) == 0) {
|
||||
setText("");
|
||||
} else {
|
||||
setText(edit);
|
||||
}
|
||||
} else {
|
||||
setText(*p);
|
||||
}
|
||||
} else if (key == Qt::Key_Return || key == Qt::Key_Enter) {
|
||||
edit="";
|
||||
QLineEdit::keyPressEvent(e);
|
||||
} else {
|
||||
QLineEdit::keyPressEvent(e);
|
||||
if (p == history.end()) {
|
||||
edit = text();
|
||||
}
|
||||
}
|
||||
}
|
||||
void addToHistory(const QString &txt) {
|
||||
p = history.find(txt);
|
||||
if (p != history.end()) {
|
||||
history.remove(p);
|
||||
}
|
||||
history.append(txt);
|
||||
p = history.end();
|
||||
while (history.count() > 256) {
|
||||
history.remove(history.begin());
|
||||
}
|
||||
}
|
||||
private:
|
||||
QStringList history;
|
||||
QStringList::Iterator p;
|
||||
QString edit;
|
||||
bool atEnd;
|
||||
};
|
||||
|
||||
Command::Command(QWidget * parent, const char *name, SicsConnection *initConn)
|
||||
: QWidget(parent, name, 0)
|
||||
{
|
||||
//QGridLayout *grid;
|
||||
QVBoxLayout *vbox;
|
||||
QFont monospace("Courier");
|
||||
|
||||
getHistory = true;
|
||||
//grid = new QGridLayout(this, 2, 2, 4, 4, "grid");
|
||||
vbox = new QVBoxLayout(this, 4, 4, "cmdBox");
|
||||
|
||||
logStartupState = 1;
|
||||
|
||||
log = new MyTextEdit(this, "log");
|
||||
log->setReadOnly(TRUE);
|
||||
//add_to_log(" ");
|
||||
log->setBuffered(true);
|
||||
|
||||
vbox->addWidget(new QLabel("Input/Output History:", this));
|
||||
vbox->addWidget(log);
|
||||
ownCommand = false;
|
||||
quiet = false;
|
||||
|
||||
vbox->addWidget(new QLabel("Command Input:", this));
|
||||
monospace.setStyleHint(QFont::TypeWriter);
|
||||
cmd = new CmdLine(this, "cmd");
|
||||
cmd->setFont(monospace);
|
||||
vbox->addWidget(cmd,3,0);
|
||||
clearWState(WState_Polished);
|
||||
conn=0;
|
||||
cmd->setFocusPolicy(StrongFocus);
|
||||
setConn(initConn);
|
||||
scrollH = 0;
|
||||
QTimer *timer = new QTimer(this, "repeat");
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(handler()));
|
||||
timer->start(10);
|
||||
checktmo = false;
|
||||
|
||||
/*
|
||||
dirtyLog = 0;
|
||||
|
||||
QTimer *logTimer = new QTimer(this);
|
||||
connect(logTimer, SIGNAL(timeout()), SLOT(showLog()));
|
||||
logTimer->start(50);
|
||||
|
||||
connect(log, SIGNAL(contentsMoving(int, int)), this, SLOT(scrolling(int, int)));
|
||||
*/
|
||||
}
|
||||
|
||||
void Command::showIt(bool yes) {
|
||||
setShown(yes);
|
||||
}
|
||||
|
||||
void Command::showText() {
|
||||
printf("%s\n", log->text().latin1());
|
||||
}
|
||||
|
||||
int str_beg(const char *text, const char *name) {
|
||||
return (strncmp(text, name, strlen(name)) == 0);
|
||||
}
|
||||
|
||||
void Command::add_to_log(QString line, Style style) {
|
||||
/*
|
||||
QFont f = font();
|
||||
static bool x=true;
|
||||
if (x) {
|
||||
printf("family %s size %d %d s %d\n", f.family().latin1(), f.pointSize(), f.pixelSize(), f.styleStrategy());
|
||||
x = false;
|
||||
}
|
||||
*/
|
||||
if (ownCommand) {
|
||||
log->appendHtml("<b>");
|
||||
}
|
||||
switch (style) {
|
||||
case style_command: log->appendHtml("<font color=#0000FF>"); break;
|
||||
case style_error: log->appendHtml("<font color=#FF0000>"); break;
|
||||
case style_normal: break;
|
||||
}
|
||||
log->appendText(line);
|
||||
if (style > 0) {
|
||||
log->appendHtml("</font>");
|
||||
}
|
||||
if (ownCommand) {
|
||||
log->appendHtml("</b>");
|
||||
}
|
||||
log->appendText("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
void Command::showLog(void) {
|
||||
if (dirtyLog) {
|
||||
dirtyLog = 0;
|
||||
log->setText(logText);
|
||||
log->scrollToBottom();
|
||||
}
|
||||
}
|
||||
|
||||
void Command::scrolling(int x, int y) {
|
||||
scrolled = true;
|
||||
}
|
||||
*/
|
||||
|
||||
void Command::handleSics(const char * text, bool *done) {
|
||||
if (str_beg(text, "TRANSACTIONFINISHED")) {
|
||||
if (logStartupState) {
|
||||
log->setBuffered(false);
|
||||
}
|
||||
ownCommand = false;
|
||||
if (done) *done = false;
|
||||
return;
|
||||
}
|
||||
if (str_beg(text, "Deleting connection") ||
|
||||
str_beg(text, "Accepted connection") ||
|
||||
(str_beg(text, "User ") && strstr(text, " privilege") != 0) ||
|
||||
str_beg(text, "Change of Authorisation") ||
|
||||
str_beg(text, "fulltransact config ") ||
|
||||
str_beg(text, "UserRights =") ||
|
||||
str_beg(text, "fulltransact status") ||
|
||||
(str_beg(text, "OK") && strlen(text) <= 3) ||
|
||||
str_beg(text, "fulltransact commandlog tail") ||
|
||||
str_beg(text, "Login OK")) {
|
||||
if (done) *done = false;
|
||||
return;
|
||||
}
|
||||
|
||||
activate();
|
||||
if (str_beg(text, "fulltransact") || str_beg(text, "transact") || str_beg(text, "TRANSACTIONSTART")) {
|
||||
if (str_beg(text, "TRANSACTIONSTART config listen")) {
|
||||
if (done) *done = false;
|
||||
return;
|
||||
}
|
||||
if (text[0] == 'f') {
|
||||
text += 13;
|
||||
} else if (text[0] == 'T') {
|
||||
text += 17;
|
||||
ownCommand = true;
|
||||
} else {
|
||||
text += 8;
|
||||
}
|
||||
// if (!blankLine) {
|
||||
// add_to_log(" ");
|
||||
// }
|
||||
if (strcmp(text, " ") > 0) {
|
||||
add_to_log(" ");
|
||||
if (timeStamp != "") {
|
||||
add_to_log(timeStamp);
|
||||
timeStamp = "";
|
||||
}
|
||||
add_to_log(text, style_command);
|
||||
// printf("*** BB {%s}\n", text);
|
||||
if (getHistory) {
|
||||
((CmdLine *)cmd)->addToHistory(text);
|
||||
}
|
||||
}
|
||||
} else if (strstr(text, "transAct") == text || strstr(text, "fulltransAct") == text) { // hide these commands
|
||||
// quiet = true;
|
||||
return;
|
||||
} else if (strstr(text, "ERROR:")) {
|
||||
add_to_log(text, style_error);
|
||||
// printf("*** RR %s\n", text);
|
||||
} else if (quiet) {
|
||||
quiet = false; /* swallow only one line. this is for nicos read -> frappy read -> sea spam*/
|
||||
} else {
|
||||
if (strcmp(text, " ") > 0) {
|
||||
if (str_beg(text, "===")) {
|
||||
timeStamp = text;
|
||||
} else {
|
||||
if (timeStamp != "") {
|
||||
add_to_log(timeStamp);
|
||||
timeStamp = "";
|
||||
}
|
||||
add_to_log(text);
|
||||
}
|
||||
// printf("*** N %s %s %s\n", text);
|
||||
}
|
||||
}
|
||||
if (done) *done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
void Command::handler() {
|
||||
int iret;
|
||||
|
||||
iret = conn->handleBuffer(0);
|
||||
if (iret == -2) { // connect_error
|
||||
// printf("*** reconnect\n");
|
||||
conn->reconnect();
|
||||
if (getCommandLog == 0) {
|
||||
getCommandLog = 1; /* force config listen to be done on the new connection */
|
||||
}
|
||||
} else if (iret > 0) { // success
|
||||
checktmo = false;
|
||||
if (getCommandLog == 2) {
|
||||
conn->sendCommand("commandlog tail 999");
|
||||
getCommandLog = 1;
|
||||
} else if (getCommandLog == 1) {
|
||||
conn->getResponse();
|
||||
getCommandLog = 0;
|
||||
conn->sendCommand("config listen 1");
|
||||
// printf("*** config listen\n");
|
||||
} else if (!cmdbuffer.isEmpty()) {
|
||||
if (sendCmd1(cmdbuffer.first().latin1())) {
|
||||
tmot.start();
|
||||
checktmo = true;
|
||||
cmdbuffer.pop_front();
|
||||
}
|
||||
}
|
||||
} else if (checktmo && tmot.elapsed() > 10000) {
|
||||
tmot.start();
|
||||
// printf("*** timeout\n");
|
||||
handleSics("ERROR: timeout -> reconnect\n");
|
||||
conn->reconnect();
|
||||
getCommandLog = 1; /* force config listen to be done on the new connection */
|
||||
}
|
||||
|
||||
if (height() < scrollH) {
|
||||
printf("%d\n", scrollH);
|
||||
log->scrollToBottom();
|
||||
}
|
||||
scrollH = height();
|
||||
if (conn) {
|
||||
conn->handleMessages(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Command::sendCmd(const char *command) {
|
||||
QString qs(command);
|
||||
cmdbuffer.append(qs);
|
||||
((CmdLine *)cmd)->addToHistory(command);
|
||||
}
|
||||
|
||||
int Command::sendCmd1(const char *command) {
|
||||
int iret;
|
||||
QString line;
|
||||
QString cCmd;
|
||||
|
||||
iret = conn->sendCommand(command);
|
||||
if (iret < 0) {
|
||||
handleSics("ERROR: connection failed\n");
|
||||
return 0;
|
||||
}
|
||||
// if (!blankLine) {
|
||||
// add_to_log(" ");
|
||||
// }
|
||||
// add_to_log(command, style_command);
|
||||
cmd->setText("");
|
||||
log->scrollToBottom();
|
||||
|
||||
while ((iret=conn->getLine(line)) > 0) {
|
||||
handleSics(line.latin1());
|
||||
}
|
||||
// add_to_log(" ");
|
||||
// blankLine = true;
|
||||
log->scrollToBottom();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Command::handleCmd() {
|
||||
if (getHistory) {
|
||||
getHistory = false;
|
||||
}
|
||||
sendCmd(cmd->text().latin1());
|
||||
}
|
||||
|
||||
void Command::setConn(SicsConnection *conn) {
|
||||
assert(conn);
|
||||
if (this->conn != conn) {
|
||||
this->conn = conn;
|
||||
connect(conn, SIGNAL(handle(const char *, bool *)), this, SLOT(handleSics(const char *, bool *)));
|
||||
connect(cmd, SIGNAL(returnPressed()), this, SLOT(handleCmd()));
|
||||
getCommandLog = 2;
|
||||
}
|
||||
getHistory = true;
|
||||
}
|
51
command.h
Normal file
51
command.h
Normal file
@ -0,0 +1,51 @@
|
||||
#include <stddef.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qtextedit.h>
|
||||
#include <qdialog.h>
|
||||
#include <qdatetime.h>
|
||||
#include "sicsconn.h"
|
||||
#include "utils.h"
|
||||
|
||||
class QCheckBox;
|
||||
|
||||
class Command : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Command(QWidget *parent, const char *name, SicsConnection *conn);
|
||||
void setConn(SicsConnection *conn);
|
||||
void showText();
|
||||
QLineEdit *cmd;
|
||||
MyTextEdit *log;
|
||||
enum Style {style_normal, style_command, style_error};
|
||||
|
||||
signals:
|
||||
void activate();
|
||||
|
||||
public slots:
|
||||
void handleSics(const char *text, bool *done = NULL);
|
||||
void sendCmd(const char *cmd);
|
||||
void handleCmd();
|
||||
void handler();
|
||||
void showIt(bool show);
|
||||
// void showLog();
|
||||
// void scrolling(int x, int y);
|
||||
|
||||
private:
|
||||
void add_to_log(QString text, Style style = style_normal);
|
||||
int sendCmd1(const char *cmd);
|
||||
|
||||
SicsConnection *conn;
|
||||
int scrollH;
|
||||
bool getHistory;
|
||||
bool ownCommand;
|
||||
bool quiet; /* for suppressing 'spam' when reading values from nicos/frappy */
|
||||
bool blankLine;
|
||||
QString timeStamp;
|
||||
int getCommandLog;
|
||||
QStringList cmdbuffer;
|
||||
QTime tmot;
|
||||
bool checktmo;
|
||||
int logStartupState;
|
||||
// bool dirtyLog;
|
||||
};
|
1458
device.cpp
Normal file
1458
device.cpp
Normal file
File diff suppressed because it is too large
Load Diff
267
device.h
Normal file
267
device.h
Normal file
@ -0,0 +1,267 @@
|
||||
#include <stddef.h>
|
||||
#include <qlayout.h>
|
||||
#ifndef DEVICE_H
|
||||
#define DEVICE_H
|
||||
|
||||
#include <qdict.h>
|
||||
#include <qtabbar.h>
|
||||
#include <qgrid.h>
|
||||
#include <qvbox.h>
|
||||
#include <qscrollview.h>
|
||||
#include <qcheckbox.h>
|
||||
#include <qcombobox.h>
|
||||
#include <qradiobutton.h>
|
||||
#include "seaset.h"
|
||||
#include "command.h"
|
||||
|
||||
class Device;
|
||||
class Group;
|
||||
|
||||
class LineInput : public QHBox {
|
||||
Q_OBJECT
|
||||
public:
|
||||
LineInput(QWidget *parent, QString &labelText, const char *var);
|
||||
void setLength(int l);
|
||||
int stdWidth();
|
||||
void setEraseColor(const QColor & color);
|
||||
signals:
|
||||
void sendCmd(const char *cmd);
|
||||
void changed();
|
||||
public slots:
|
||||
void handleReturn();
|
||||
void focusLost();
|
||||
void setValue(const QString &value);
|
||||
public:
|
||||
QLineEdit *le;
|
||||
QLabel *label;
|
||||
// bool graphOn;
|
||||
private:
|
||||
QString value;
|
||||
};
|
||||
|
||||
class RdOnly : public QHBox {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RdOnly(QWidget *parent, QString &labelText, QString &val, const char *var);
|
||||
void setLength(int l);
|
||||
public slots:
|
||||
void setValue(const QString &val);
|
||||
public:
|
||||
QLabel *label, *value;
|
||||
private:
|
||||
unsigned int len;
|
||||
};
|
||||
|
||||
class CheckBox : public QCheckBox {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CheckBox(const QString &label, QWidget *parent, const char *var);
|
||||
signals:
|
||||
void sendCmd(const char *cmd);
|
||||
void changed();
|
||||
public slots:
|
||||
void handleReturn();
|
||||
void setValue(const QString &value);
|
||||
};
|
||||
|
||||
class ClickButton : public QPushButton {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ClickButton(QWidget *parent, const char *var);
|
||||
void setLabel(const QString &label);
|
||||
signals:
|
||||
void sendCmd(const char *cmd);
|
||||
void changed();
|
||||
public slots:
|
||||
void handleReturn();
|
||||
private:
|
||||
int dx;
|
||||
};
|
||||
|
||||
class RadioButton : public QRadioButton {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RadioButton(const QString &label, QWidget *parent, const QString &cmd, const char *value);
|
||||
signals:
|
||||
void sendCmd(const char *cmd);
|
||||
void clearOthers(const QString &cmd);
|
||||
void changed();
|
||||
public slots:
|
||||
void handleClick();
|
||||
void setValue(const QString &value);
|
||||
private:
|
||||
QString cmd;
|
||||
};
|
||||
|
||||
class Menu : public QComboBox {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Menu(const QString &label, QWidget *parent, const char *var);
|
||||
signals:
|
||||
void sendCmd(const char *cmd);
|
||||
void changed();
|
||||
public slots:
|
||||
void handleAct(const QString &value);
|
||||
void setValue(const QString &value);
|
||||
};
|
||||
|
||||
class ColorMenu : public QComboBox {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ColorMenu(QWidget *parent, const char *var);
|
||||
ColorMenu(QString &color, QWidget *parent);
|
||||
int getColorIndex();
|
||||
void setLength(int min, int max=0);
|
||||
signals:
|
||||
void sendCmd(const char *cmd);
|
||||
void changed();
|
||||
public slots:
|
||||
void handleAct(int index);
|
||||
void handleChange(const QString &value);
|
||||
void setValue(const QString &value);
|
||||
private:
|
||||
QString value;
|
||||
void init();
|
||||
bool nochange;
|
||||
};
|
||||
|
||||
class Item {
|
||||
public:
|
||||
QWidget *w;
|
||||
bool used;
|
||||
char wStyle;
|
||||
QFont normalFont;
|
||||
Group *grp;
|
||||
// QPushButton *graphButton;
|
||||
Item() {
|
||||
this->used = true;
|
||||
this->w = 0;
|
||||
this->wStyle = 0;
|
||||
// this->graphButton = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
class GraphButton : public QPushButton {
|
||||
Q_OBJECT
|
||||
public:
|
||||
GraphButton(QWidget *parent, const char *name);
|
||||
signals:
|
||||
void selectItem(const char *id);
|
||||
void changed();
|
||||
public slots:
|
||||
void handleClick();
|
||||
};
|
||||
*/
|
||||
|
||||
class Group : public QVBox {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Group(Device *p, const char *name, bool selectMenu=false);
|
||||
Group(Group *p, const QString &tit, const char *name);
|
||||
void updateLayout(QStringList::Iterator &it);
|
||||
void appendTo(QString &c);
|
||||
void hideContents();
|
||||
void autocloseAll();
|
||||
bool openGroup(QString &path);
|
||||
Group* findGroup(QString &path);
|
||||
bool shown;
|
||||
bool autoclose;
|
||||
|
||||
signals:
|
||||
void changeHeight();
|
||||
void clearRadioButtons(const QString &except);
|
||||
|
||||
public slots:
|
||||
void toggle();
|
||||
|
||||
private:
|
||||
void init();
|
||||
void add(Item *item, QWidget *w = 0);
|
||||
void initItem(Item *item, QWidget *w, const char *line, bool active = false);
|
||||
Item *findItem(const char *name);
|
||||
void showIt(bool show);
|
||||
void newline();
|
||||
|
||||
QPushButton *arrow;
|
||||
QLabel *title;
|
||||
Device *device;
|
||||
Group *parentGroup;
|
||||
QDict<Item> items;
|
||||
int indent; // x indentation
|
||||
bool sameRow;
|
||||
bool tight;
|
||||
QString tip;
|
||||
char wStyle;
|
||||
bool isSelectMenu;
|
||||
int colDiv;
|
||||
//bool closeLater;
|
||||
};
|
||||
|
||||
typedef enum {select_idle, select_open} SelectState;
|
||||
|
||||
class Device : public QScrollView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class Group;
|
||||
|
||||
public:
|
||||
Device(QWidget* parent);
|
||||
void init(Command *command, SeaSet *initSet);
|
||||
|
||||
signals:
|
||||
void restart(const char *vars);
|
||||
|
||||
public slots:
|
||||
void update(bool refresh = true);
|
||||
void timedUpdate();
|
||||
void switchLayout();
|
||||
void selectIt();
|
||||
void setSelectCmd(const char *cmd);
|
||||
// void graphToggle();
|
||||
// void selectGraphItem(const char *id);
|
||||
void rebuild();
|
||||
void activate();
|
||||
void closeMarkedGroups();
|
||||
void openGrps(const char *groups);
|
||||
|
||||
private:
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
void updateStart();
|
||||
void updateComplete();
|
||||
|
||||
QString selectCmd;
|
||||
SeaSet *set;
|
||||
Group *mainGroup;
|
||||
Group *device;
|
||||
Group *select;
|
||||
Command *com;
|
||||
// GraphButton *gButton;
|
||||
QStringList code;
|
||||
int x, y;
|
||||
int nextY;
|
||||
int maxWid;
|
||||
int xspace, yspace;
|
||||
int labelWidth;
|
||||
int leWidth;
|
||||
int columnWidth;
|
||||
// int graphButtonWidth;
|
||||
int lineHeight;
|
||||
QString graphDesc;
|
||||
// bool graphOn;
|
||||
// QString visibleGr;
|
||||
// bool doJump;
|
||||
QString openGroup; /* group path to open */
|
||||
SelectState selectState;
|
||||
//int yJump;
|
||||
bool stopUpdate;
|
||||
double updateInterval;
|
||||
double lastUpdate;
|
||||
double rebuildTime;
|
||||
// Group *closeGroup;
|
||||
enum {update_idle, update_start, update_complete} updateMode;
|
||||
QTime tmot;
|
||||
};
|
||||
|
||||
#endif
|
373
export.cpp
Normal file
373
export.cpp
Normal file
@ -0,0 +1,373 @@
|
||||
#include "export.h"
|
||||
#include <qapplication.h>
|
||||
#include <qvariant.h>
|
||||
#include <qdialog.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <qcheckbox.h>
|
||||
#include <qlabel.h>
|
||||
#include <qlayout.h>
|
||||
#include <qtooltip.h>
|
||||
#include <qwhatsthis.h>
|
||||
#include <stdio.h>
|
||||
#include <qvalidator.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
#include <qtimer.h>
|
||||
#include <qdatetime.h>
|
||||
#include <qsizepolicy.h>
|
||||
#include <qfiledialog.h>
|
||||
#include "seaset.h"
|
||||
#include "sicsconn.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void Export::addRow(QString label, QWidget *widget, QString tip) {
|
||||
QLabel *labelW;
|
||||
if (label != "") {
|
||||
labelW = new QLabel(label, this);
|
||||
lay->addWidget(labelW, row, 0);
|
||||
if (tip != "") {
|
||||
QToolTip::add(labelW, tip);
|
||||
}
|
||||
}
|
||||
lay->addWidget(widget, row, 1);
|
||||
if (tip != "") {
|
||||
QToolTip::add(widget, tip);
|
||||
}
|
||||
row++;
|
||||
}
|
||||
|
||||
Export::Export(SeaSet *setArg, QWidget *parent, const char *instr)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QPushButton *ok, *cancel;
|
||||
char wd[PATH_MAX];
|
||||
|
||||
set = setArg;
|
||||
row = 0;
|
||||
instrument = instr;
|
||||
|
||||
lay = new QGridLayout(this, 1, 3, 3, -1, "exportLayout");
|
||||
lay->setColStretch(2,1);
|
||||
|
||||
addRow("export: ", new QLabel("all active curves", this), "");
|
||||
|
||||
lay->addWidget(new QLabel("step [sec]", this), 1, 0);
|
||||
stepLE = new QLineEdit(this);
|
||||
QValidator* validator = new QIntValidator( 1, 24*3600, this );
|
||||
stepLE->setValidator(validator);
|
||||
stepLE->setText("auto");
|
||||
stepLE->setAlignment(Qt::AlignRight);
|
||||
stepLE->setFixedWidth(100);
|
||||
addRow("step [sec]", stepLE,
|
||||
"time step [sec] (auto: 5 sec or more, max. 1000 points)"
|
||||
);
|
||||
|
||||
scaleLE = new QLineEdit(this);
|
||||
scaleLE->setText("1");
|
||||
scaleLE->setAlignment(Qt::AlignRight);
|
||||
scaleLE->setFixedWidth(100);
|
||||
addRow("x-scale [sec]", scaleLE, "enter 60 for minutes / 3600 for hours");
|
||||
|
||||
noneLE = new QLineEdit(this);
|
||||
noneLE->setText("NaN");
|
||||
noneLE->setFixedWidth(100);
|
||||
addRow("none value", noneLE, "value to be used for undefined numbers");
|
||||
|
||||
filePath = getcwd(wd, sizeof wd);
|
||||
filePath.append("/seaexport.dat");
|
||||
|
||||
cancel = new QPushButton("Quit", this);
|
||||
lay->addWidget(cancel, row, 0);
|
||||
connect(cancel, SIGNAL(clicked()), this, SIGNAL(finish()));
|
||||
|
||||
ok = new QPushButton("Export", this);
|
||||
lay->addWidget(ok, 5, 1);
|
||||
ok->setDefault(true);
|
||||
ok->setFixedWidth(100);
|
||||
addRow("", ok, "");
|
||||
connect(ok, SIGNAL(clicked()), this, SLOT(exportXY()));
|
||||
|
||||
message = new QLabel("", this);
|
||||
lay->addWidget(message, row, 1);
|
||||
row++;
|
||||
|
||||
lay->setRowStretch(row,1);
|
||||
}
|
||||
|
||||
void Export::showMe() {
|
||||
show();
|
||||
updateCurveList();
|
||||
}
|
||||
|
||||
void Export::updateCurveList() {
|
||||
QString text("The following curves are active and to be exported:");
|
||||
int cnt=0;
|
||||
SeaData *d;
|
||||
|
||||
if (isHidden()) return;
|
||||
for (d = set->dataList.first(); d != 0; d = set->dataList.next()) {
|
||||
if (d->isActive()) {
|
||||
text.append("\n ");
|
||||
text.append(d->label);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
if (cnt == 0) {
|
||||
text = "no active curves";
|
||||
}
|
||||
text.append("\n\ncurves are de-/activated by clicking on their legend");
|
||||
message->setText(text);
|
||||
show();
|
||||
}
|
||||
|
||||
void Export::progress(int bytes) {
|
||||
QString text;
|
||||
|
||||
if (progressBytes < 0) return;
|
||||
if (isHidden()) return;
|
||||
progressBytes += bytes;
|
||||
if (progressBytes >= 0 && lastProgress.elapsed() > 250) {
|
||||
lastProgress.start();
|
||||
text.sprintf("%.2f MBytes read", progressBytes * 0.000001);
|
||||
message->setText(text);
|
||||
show();
|
||||
procEvt();
|
||||
}
|
||||
}
|
||||
|
||||
void Export::exportXY() {
|
||||
|
||||
QString cmd;
|
||||
QString line;
|
||||
int iret, cnt, icol;
|
||||
bool ok;
|
||||
time_t dt, t, from, to, step, lastRead, basis;
|
||||
time_t i, lasti, len, siz, scale, mag, endi;
|
||||
int prec;
|
||||
SeaData *d;
|
||||
QString text;
|
||||
double val;
|
||||
double *data;
|
||||
double yy, yy0;
|
||||
FILE *fil;
|
||||
QString fileResult;
|
||||
double eps;
|
||||
static double undefpluseps = 0;
|
||||
|
||||
fileResult = QFileDialog::getSaveFileName(
|
||||
filePath, QString::null, this,
|
||||
"save file dialog",
|
||||
"select file to save exported data"
|
||||
);
|
||||
if (fileResult == "") {
|
||||
return;
|
||||
}
|
||||
filePath = fileResult;
|
||||
|
||||
from = set->startRange;
|
||||
to = set->endRange;
|
||||
step = stepLE->text().toInt();
|
||||
if (step == 0) { /* auto */
|
||||
step = ((to - from) / 5000 + 1) * 5;
|
||||
}
|
||||
from = (from / step) * step;
|
||||
scale = scaleLE->text().toInt();
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
len = (to - from - 1) / step;
|
||||
to = from + len * step;
|
||||
|
||||
if (step == 1) {
|
||||
cmd.sprintf("graph %ld %ld text", from, to);
|
||||
} else {
|
||||
cmd.sprintf("graph %ld %ld np %ld", from, to, to - from + 2);
|
||||
}
|
||||
|
||||
cnt = 0;
|
||||
for (d = set->dataList.first(); d != 0; d = set->dataList.next()) {
|
||||
if (d->isActive()) {
|
||||
cmd.append(" ");
|
||||
cmd.append(d->name);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
if (cnt == 0) {
|
||||
message->setText("no curves active");
|
||||
show();
|
||||
return;
|
||||
}
|
||||
siz = len * cnt;
|
||||
data = (double *)malloc(siz * sizeof(*data));
|
||||
if (data == NULL) {
|
||||
message->setText("no memory");
|
||||
show();
|
||||
return;
|
||||
}
|
||||
|
||||
progressBytes = 0;
|
||||
message->setText("waiting for server");
|
||||
procEvt();
|
||||
lastProgress.start();
|
||||
iret = set->ec->command(cmd);
|
||||
progressBytes = -1;
|
||||
|
||||
if (iret < 0) {
|
||||
message->setText("can not connect to the GraphServer");
|
||||
goto err2;
|
||||
}
|
||||
//printf("%s\n", cmd.latin1());
|
||||
|
||||
text = "Curves:";
|
||||
message->setText(text);
|
||||
procEvt();
|
||||
|
||||
iret = set->ec->getLine(line);
|
||||
if (iret <= 0) {
|
||||
message->setText("can not get response 1");
|
||||
goto err2;
|
||||
}
|
||||
//printf("> %s\n", line.latin1());
|
||||
|
||||
/* get returned absolute time */
|
||||
lastRead = line.toLong();
|
||||
//sscanf(line, "%ld", &lastRead);
|
||||
|
||||
iret = set->ec->getLine(line);
|
||||
if (iret <= 0) {
|
||||
message->setText("can not get response 2");
|
||||
goto err2;
|
||||
}
|
||||
//printf("> %s\n", line.latin1());
|
||||
if (!line.startsWith("*")) {
|
||||
message->setText("missing *");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
icol = 0;
|
||||
fil = fopen(filePath.latin1(), "w");
|
||||
fprintf(fil, "# SEA export from %s\n", instrument);
|
||||
fprintf(fil, "# col 1: Time/%d sec since %s 0:00\n", (int)scale, set->dateLabel(0).latin1());
|
||||
|
||||
endi = 0;
|
||||
for (d = set->dataList.first(); d != 0; set->dataList.findRef(d), d = set->dataList.next()) {
|
||||
if (d->isActive()) {
|
||||
yy0 = DATA_UNDEF;
|
||||
yy = DATA_UNDEF;
|
||||
lasti = -1;
|
||||
//printf("- %s\n", d->label.latin1());
|
||||
fprintf(fil, "# col %d: %s (%s) %s\n",
|
||||
icol + 2, d->name.latin1(), d->label.latin1(),
|
||||
d->row->tagLabel->text().latin1());
|
||||
text.append("\n ");
|
||||
text.append(d->label);
|
||||
line = line.section(' ', 0, 0);
|
||||
if (d->name == line.mid(1)) {
|
||||
t = 0;
|
||||
do {
|
||||
iret = set->ec->getLine(line);
|
||||
if (iret <= 0) {
|
||||
message->setText("can not get line");
|
||||
goto err;
|
||||
}
|
||||
//printf("> %s\n", line.latin1());
|
||||
if (line.startsWith("*")) {
|
||||
i = len;
|
||||
} else {
|
||||
/* decode line to x[n] / y[n] */
|
||||
dt = line.section(' ', 0, 0).toLong(&ok);
|
||||
/*
|
||||
iret = sscanf(line, "%ld %n", &dt, &pos);
|
||||
if (iret < 1) {
|
||||
*/
|
||||
if (!ok) {
|
||||
message->setText("bad timestep");
|
||||
goto err;
|
||||
}
|
||||
t += dt;
|
||||
i = (t - from) / step;
|
||||
yy0 = yy;
|
||||
yy = line.section(' ', 1, 1).toDouble(&ok);
|
||||
//iret = sscanf(line + pos, "%lf", &yy);
|
||||
// printf("scan %8ld %9.4f\n", t - from, yy);
|
||||
if (!ok) { // not a valid value
|
||||
yy = DATA_UNDEF;
|
||||
} else {
|
||||
if (yy == DATA_UNDEF) { // by chance
|
||||
if (undefpluseps == 0) { // create closest possible (but different) value to DATA_UNDEF
|
||||
undefpluseps = yy;
|
||||
eps = undefpluseps * 1e-9;
|
||||
while (undefpluseps == DATA_UNDEF) {
|
||||
undefpluseps += eps;
|
||||
eps = eps * 2;
|
||||
}
|
||||
}
|
||||
yy = undefpluseps;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---*/
|
||||
|
||||
if (lasti < i) {
|
||||
if (lasti < 0) {
|
||||
lasti = 0;
|
||||
}
|
||||
while (lasti < i - 1 && lasti < len) {
|
||||
assert(lasti * cnt + icol < siz);
|
||||
data[lasti*cnt + icol] = yy0;
|
||||
lasti++;
|
||||
}
|
||||
if (lasti < len) {
|
||||
data[lasti*cnt + icol] = yy;
|
||||
// printf("%ld %9.4f\n", lasti, yy);
|
||||
if (yy != DATA_UNDEF) {
|
||||
if (lasti > endi && lasti != len) endi = lasti;
|
||||
}
|
||||
}
|
||||
lasti++;
|
||||
}
|
||||
} while (!line.startsWith("*"));
|
||||
} else {
|
||||
for (i = 0; i<len; i++) {
|
||||
assert(i * cnt + icol < siz);
|
||||
data[i*cnt + icol] = DATA_UNDEF;
|
||||
}
|
||||
}
|
||||
icol++;
|
||||
message->setText(text);
|
||||
procEvt();
|
||||
}
|
||||
}
|
||||
//fprintf(fil, "\n");
|
||||
basis = (from - set->base) / step;
|
||||
//printf("endi %ld\n", endi);
|
||||
for (i = 0; i < endi; i++) {
|
||||
if (scale == 1) {
|
||||
fprintf(fil, "%ld", (basis + i) * step);
|
||||
} else {
|
||||
mag = 10 * scale / step;
|
||||
for (prec = 0; mag > 1; prec++,mag/=10);
|
||||
fprintf(fil, "%.*f", prec, (double)(basis + i) * step / scale);
|
||||
}
|
||||
for (icol = 0; icol < cnt; icol++) {
|
||||
val = data[i*cnt + icol];
|
||||
if (val == DATA_UNDEF) {
|
||||
fprintf(fil, "\t%s", noneLE->text().latin1());
|
||||
} else {
|
||||
// fprintf(fil, "\t%.7g", val);
|
||||
// we might write here full precision, this will not watse space in case step is not 1
|
||||
fprintf(fil, "\t%.14g", val);
|
||||
}
|
||||
}
|
||||
fprintf(fil,"\n");
|
||||
}
|
||||
text.append("\n\nwritten to\n");
|
||||
text.append(filePath.latin1());
|
||||
message->setText(text);
|
||||
err:
|
||||
fclose(fil);
|
||||
err2:
|
||||
free(data);
|
||||
show();
|
||||
}
|
39
export.h
Normal file
39
export.h
Normal file
@ -0,0 +1,39 @@
|
||||
#include <stddef.h>
|
||||
#include <qdialog.h>
|
||||
#include <qcombobox.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qlabel.h>
|
||||
#include <qbutton.h>
|
||||
#include <qlayout.h>
|
||||
#include <qstring.h>
|
||||
#include <qdatetime.h>
|
||||
#include "seaset.h"
|
||||
|
||||
class Export : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Export(SeaSet *setArg, QWidget *parent=0, const char *instr=0);
|
||||
void showMe();
|
||||
private:
|
||||
QLineEdit *stepLE;
|
||||
QLineEdit *noneLE;
|
||||
QLineEdit *scaleLE;
|
||||
QLabel *message;
|
||||
SeaSet *set;
|
||||
QGridLayout *lay;
|
||||
int row;
|
||||
QString filePath;
|
||||
const char *instrument;
|
||||
int progressBytes;
|
||||
QTime lastProgress;
|
||||
signals:
|
||||
void finish();
|
||||
void procEvt();
|
||||
public slots:
|
||||
void updateCurveList();
|
||||
void exportXY();
|
||||
void addRow(QString label, QWidget *widget, QString tip);
|
||||
void progress(int bytes);
|
||||
};
|
355
graph.cpp
Normal file
355
graph.cpp
Normal file
@ -0,0 +1,355 @@
|
||||
#include "graph.h"
|
||||
#include <qapplication.h>
|
||||
#include <qvariant.h>
|
||||
#include <qdialog.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <qcheckbox.h>
|
||||
#include <qlabel.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qlayout.h>
|
||||
#include <qtooltip.h>
|
||||
#include <qwhatsthis.h>
|
||||
#include <qpixmap.h>
|
||||
#include <qimage.h>
|
||||
#include <stdio.h>
|
||||
#include <qpixmap.h>
|
||||
#include <qvalidator.h>
|
||||
#include <math.h>
|
||||
#include <qtimer.h>
|
||||
#include <qdatetime.h>
|
||||
#include <qcombobox.h>
|
||||
#include <qsplitter.h>
|
||||
#include <qsizepolicy.h>
|
||||
#include <stdlib.h>
|
||||
#include "seaset.h"
|
||||
#include "utils.h"
|
||||
|
||||
static char *xZoomPix[] = {
|
||||
"16 16 2 1",
|
||||
" c None",
|
||||
"X c #000000",
|
||||
" ",
|
||||
" ",
|
||||
" X X ",
|
||||
" XX XX ",
|
||||
" XX XX ",
|
||||
" XX XX ",
|
||||
" XX XX ",
|
||||
" XX XX ",
|
||||
" XX XX ",
|
||||
" XX XX ",
|
||||
" XX XX ",
|
||||
" XX XX ",
|
||||
" XX XX ",
|
||||
" X X ",
|
||||
" ",
|
||||
" "
|
||||
};
|
||||
|
||||
static char *leftPix[] = {
|
||||
"16 16 2 1",
|
||||
" c None",
|
||||
"X c #000000",
|
||||
" ",
|
||||
" ",
|
||||
" X ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" X ",
|
||||
" ",
|
||||
" "
|
||||
};
|
||||
|
||||
static char *rightPix[] = {
|
||||
"16 16 2 1",
|
||||
" c None",
|
||||
"X c #000000",
|
||||
" ",
|
||||
" ",
|
||||
" X ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" X ",
|
||||
" ",
|
||||
" "
|
||||
};
|
||||
|
||||
static char *undoPix[] = {
|
||||
"16 16 2 1",
|
||||
" c None",
|
||||
"X c #000000",
|
||||
" ",
|
||||
" XXXXXXXXX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" X ",
|
||||
" X ",
|
||||
" X ",
|
||||
" X X ",
|
||||
" XX XX ",
|
||||
" XX XX ",
|
||||
" XXXXXXXXXXXX ",
|
||||
" XX ",
|
||||
" XX ",
|
||||
" X ",
|
||||
" ",
|
||||
" "
|
||||
};
|
||||
|
||||
Graph::Graph(const char* arg, QWidget *parent, long range)
|
||||
: QWidget(parent, 0)
|
||||
{
|
||||
QPixmap pmOut((const char **)xZoomPix);
|
||||
QPixmap pmLeft((const char **)leftPix);
|
||||
QPixmap pmRight((const char **)rightPix);
|
||||
QPixmap pmUndo((const char **)undoPix);
|
||||
QString str;
|
||||
//QHBox *buttonBar;
|
||||
QPushButton* buttonOk;
|
||||
QPushButton* buttonAll;
|
||||
QPushButton* buttonUndo;
|
||||
QPushButton* buttonLeft;
|
||||
QPushButton* buttonOut;
|
||||
QPushButton* buttonRight;
|
||||
QPushButton* buttonSettings;
|
||||
QPushButton* buttonXY;
|
||||
QSplitter *graphSplit;
|
||||
QVBoxLayout* graphLayout;
|
||||
QHBoxLayout* buttonLayout;
|
||||
int w,h;
|
||||
const char * vars;
|
||||
|
||||
setName("Graph");
|
||||
|
||||
graphLayout = new QVBoxLayout(this, 0, 0, "graphLayout");
|
||||
|
||||
graphSplit = new QSplitter(Qt::Vertical, this, "splitter");
|
||||
graphLayout->add(graphSplit);
|
||||
|
||||
buttonLayout = new QHBoxLayout(0, 6, 2, "buttonBar");
|
||||
graphLayout->addLayout(buttonLayout);
|
||||
|
||||
buttonLayout->addWidget(new QLabel("Range", this));
|
||||
|
||||
lineEditRange = new QComboBox(true, this);
|
||||
//SetLength(lineEditRange, 5, 6);
|
||||
buttonLayout->addWidget(lineEditRange);
|
||||
QToolTip::add(lineEditRange, "enter a number and m,h or d");
|
||||
|
||||
buttonOk = new QPushButton(this);
|
||||
buttonOk->setDefault(true);
|
||||
buttonOk->setText("OK");
|
||||
ShrinkButton(buttonOk);
|
||||
buttonLayout->addWidget(buttonOk);
|
||||
|
||||
buttonSettings = new QPushButton(this);
|
||||
buttonSettings->setText("Settings");
|
||||
ShrinkButton(buttonSettings);
|
||||
buttonLayout->addWidget(buttonSettings);
|
||||
QToolTip::add(buttonSettings, "edit shown curves");
|
||||
|
||||
buttonAll = new QPushButton(this);
|
||||
buttonAll->setText("Show All");
|
||||
ShrinkButton(buttonAll);
|
||||
buttonLayout->addWidget(buttonAll);
|
||||
QToolTip::add(buttonAll, "show all curves");
|
||||
|
||||
buttonXY = new QPushButton(this);
|
||||
buttonXY->setText("export");
|
||||
ShrinkButton(buttonXY);
|
||||
buttonLayout->addWidget(buttonXY);
|
||||
QToolTip::add(buttonXY, "export data");
|
||||
|
||||
liveBox = new QCheckBox(this);
|
||||
liveBox->setText("live mode");
|
||||
buttonLayout->addWidget(liveBox);
|
||||
liveBox->setChecked(false);
|
||||
|
||||
buttonLayout->addStretch(1);
|
||||
|
||||
buttonUndo = new QPushButton(this);
|
||||
buttonUndo->setPixmap(pmUndo);
|
||||
w = QMAX(22, buttonUndo->sizeHint().width() - 6);
|
||||
h = QMAX(22, buttonUndo->sizeHint().height() - 6);
|
||||
if (w > h) { // Mac like
|
||||
h += 6;
|
||||
w -= 6;
|
||||
}
|
||||
buttonUndo->setFixedSize(w, h);
|
||||
buttonLayout->addWidget(buttonUndo);
|
||||
buttonUndo->setEnabled(false);
|
||||
QToolTip::add(buttonUndo, "undo zoom or shift action");
|
||||
|
||||
buttonLeft = new QPushButton(this);
|
||||
buttonLeft->setPixmap(pmLeft);
|
||||
buttonLeft->setFixedSize(w, h);
|
||||
buttonLayout->addWidget(buttonLeft);
|
||||
QToolTip::add(buttonLeft, "scroll left");
|
||||
|
||||
buttonRight = new QPushButton(this);
|
||||
buttonRight->setPixmap(pmRight);
|
||||
buttonRight->setFixedSize(w, h);
|
||||
buttonLayout->addWidget(buttonRight);
|
||||
QToolTip::add(buttonRight, "scroll right");
|
||||
|
||||
buttonOut = new QPushButton(this);
|
||||
buttonOut->setPixmap(pmOut);
|
||||
buttonOut->setFixedSize(w, h);
|
||||
buttonLayout->addWidget(buttonOut);
|
||||
QToolTip::add(buttonOut, "zoom out horizontally");
|
||||
|
||||
str="Sea ";
|
||||
str.append(arg);
|
||||
topLevelWidget()->setCaption(str);
|
||||
|
||||
clearWState(WState_Polished);
|
||||
|
||||
unit='m';
|
||||
str="30m";
|
||||
|
||||
set = new SeaSet(graphSplit, range, "seaset");
|
||||
|
||||
const char *items[]={
|
||||
"1m","2m","5m","10m","15m","30m"
|
||||
,"1h","2h","4h","8h","16h"
|
||||
,"1d","2d","4d","8d",0};
|
||||
lineEditRange->insertStrList(items);
|
||||
lineEditRange->setSizeLimit(15);
|
||||
lineEditRange->setMaxCount(15);
|
||||
lineEditRange->setEditText(str);
|
||||
lineEditRange->lineEdit()->selectAll();
|
||||
|
||||
connect(lineEditRange, SIGNAL(activated(int)),
|
||||
this, SLOT(activateRange()));
|
||||
connect(buttonOk, SIGNAL(clicked()),
|
||||
this, SLOT(activateRange()));
|
||||
connect(buttonAll, SIGNAL(clicked()),
|
||||
set, SLOT(showAll()));
|
||||
connect(buttonSettings, SIGNAL(clicked()),
|
||||
this, SIGNAL(gotoSettings()));
|
||||
connect(buttonXY, SIGNAL(clicked()),
|
||||
this, SIGNAL(openExport()));
|
||||
connect(buttonUndo, SIGNAL(clicked()),
|
||||
set, SLOT(undoZoom()));
|
||||
connect(buttonLeft, SIGNAL(clicked()),
|
||||
set, SLOT(shiftLeft()));
|
||||
connect(buttonOut, SIGNAL(clicked()),
|
||||
set, SLOT(zoomOutX()));
|
||||
connect(buttonRight, SIGNAL(clicked()),
|
||||
set, SLOT(shiftRight()));
|
||||
connect(liveBox, SIGNAL(toggled(bool)),
|
||||
set, SLOT(setLive(bool)));
|
||||
connect(set, SIGNAL(undoEnabled(bool)),
|
||||
buttonUndo, SLOT(setEnabled(bool)));
|
||||
connect(lineEditRange->lineEdit(), SIGNAL(textChanged(const QString &)),
|
||||
this, SLOT(autoReturn(const QString &)));
|
||||
|
||||
set->setHost(arg);
|
||||
|
||||
if (printit()) {
|
||||
printf("reading curve list,\n");
|
||||
}
|
||||
if (range < 365*24*3600) {
|
||||
vars = "now";
|
||||
} else {
|
||||
vars = NULL;
|
||||
}
|
||||
set->autoCurves(vars);
|
||||
if (printit()) {
|
||||
printf("opening window.\n");
|
||||
}
|
||||
//lineEditRange->selectAll();
|
||||
|
||||
|
||||
QTimer *timer = new QTimer(this, "repeat");
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(liveUpdate()));
|
||||
timer->start(2500);
|
||||
}
|
||||
|
||||
void Graph::liveUpdate() {
|
||||
if (isShown() && width() > 3) {
|
||||
set->liveUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void Graph::showIt(bool yes) {
|
||||
if (yes) {
|
||||
set->liveUpdate();
|
||||
show();
|
||||
} else {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void Graph::activateRange() {
|
||||
long fact;
|
||||
QString t;
|
||||
double rng;
|
||||
unsigned int j;
|
||||
|
||||
//setFocus();
|
||||
t = lineEditRange->currentText();
|
||||
for (j = 0; j < t.length(); j++) {
|
||||
if (t[j] > '9') {
|
||||
unit = t.latin1()[j];
|
||||
t.truncate(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (unit) {
|
||||
case 'D': unit='d';
|
||||
case 'd': fact = 24*3600; break;
|
||||
case 'H': unit='h';
|
||||
case 'h': fact = 3600; break;
|
||||
case 'M': unit='m';
|
||||
case 'm': fact = 60; break;
|
||||
case 'S': unit='s';
|
||||
case 's': fact = 1; break;
|
||||
default: fact = 60; unit = 'm';
|
||||
}
|
||||
rng = t.toDouble() * fact;
|
||||
//printf("%s %lf %ld\n", t.latin1(), rng, fact);
|
||||
if (rng > SEA_MAX_RANGE) {
|
||||
unit = 'd';
|
||||
t.sprintf("%d%c", (SEA_MAX_RANGE + 36000) / 24 / 3600, unit);
|
||||
lineEditRange->setEditText(t);
|
||||
rng = SEA_MAX_RANGE;
|
||||
} else if (rng < 59.5) {
|
||||
rng = 60;
|
||||
if (unit == 's') {
|
||||
lineEditRange->setEditText("60s");
|
||||
} else {
|
||||
unit = 'm';
|
||||
lineEditRange->setEditText("1m");
|
||||
}
|
||||
} else {
|
||||
t.append(unit);
|
||||
lineEditRange->setEditText(t);
|
||||
}
|
||||
set->rescaleRange(long(rng));
|
||||
lineEditRange->lineEdit()->selectAll();
|
||||
}
|
||||
|
||||
void Graph::autoReturn(const QString &text) {
|
||||
if (0 == text.find(QRegExp("\\d{1,4}[DdHhMmSs]"))) {
|
||||
activateRange();
|
||||
} else if (0 == text.find(QRegExp("[Qq]"))) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
44
graph.h
Normal file
44
graph.h
Normal file
@ -0,0 +1,44 @@
|
||||
#include <stddef.h>
|
||||
#include <qvariant.h>
|
||||
#include <qdialog.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qcheckbox.h>
|
||||
#include <qptrlist.h>
|
||||
#include <qcombobox.h>
|
||||
#include <qptrcollection.h>
|
||||
|
||||
#include "seaset.h"
|
||||
|
||||
class QVBoxLayout;
|
||||
class QHBoxLayout;
|
||||
class QSpacerItem;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
|
||||
class Graph : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Graph(const char* host = 0, QWidget *parent=0, long range=1800);
|
||||
|
||||
SeaSet *set;
|
||||
QComboBox* lineEditRange;
|
||||
QCheckBox* liveBox;
|
||||
|
||||
public slots:
|
||||
void activateRange();
|
||||
void autoReturn(const QString &);
|
||||
void showIt(bool show);
|
||||
void liveUpdate();
|
||||
signals:
|
||||
void gotoSettings();
|
||||
void openExport();
|
||||
|
||||
private:
|
||||
char unit;
|
||||
void init();
|
||||
};
|
||||
|
||||
|
||||
|
1
instr_hosts.cpp
Symbolic link
1
instr_hosts.cpp
Symbolic link
@ -0,0 +1 @@
|
||||
../six/instr_hosts.c
|
1
instr_hosts.h
Symbolic link
1
instr_hosts.h
Symbolic link
@ -0,0 +1 @@
|
||||
../six/instr_hosts.h
|
521
main.cpp
Normal file
521
main.cpp
Normal file
@ -0,0 +1,521 @@
|
||||
#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"
|
||||
|
||||
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];
|
||||
|
||||
char *strtoupper(const char *str) {
|
||||
static char buf[128];
|
||||
int i;
|
||||
for (i = 0; i < 127; i++) {
|
||||
if (str[i] == 0) break;
|
||||
buf[i] = toupper(str[i]);
|
||||
}
|
||||
buf[i] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
26
main.h
Normal file
26
main.h
Normal file
@ -0,0 +1,26 @@
|
||||
#include <stddef.h>
|
||||
#include <qapplication.h>
|
||||
#include <qstring.h>
|
||||
#include "tab.h"
|
||||
|
||||
class SeaApp : public QApplication {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SeaApp(int &argc, char **argv);
|
||||
|
||||
Tab *tab;
|
||||
int home;
|
||||
time_t sleepTime;
|
||||
|
||||
public slots:
|
||||
void ciao();
|
||||
void fail();
|
||||
void procEvt();
|
||||
|
||||
private:
|
||||
bool notify(QObject *recevier, QEvent *e);
|
||||
time_t lastActive;
|
||||
time_t lastTimer;
|
||||
bool sleeping;
|
||||
};
|
182
report.cpp
Normal file
182
report.cpp
Normal file
@ -0,0 +1,182 @@
|
||||
#include "report.h"
|
||||
#include <stddef.h>
|
||||
#include <qlayout.h>
|
||||
#include <qdatetime.h>
|
||||
#include <qcolor.h>
|
||||
|
||||
Report::Report(QWidget *parent, SicsConnection *conn) : QWidget(parent, "report")
|
||||
{
|
||||
QVBoxLayout *vbox = new QVBoxLayout(this, 0, 0, "report_vbox");
|
||||
QHBoxLayout *hdr = new QHBoxLayout(0, 3, 3, "report_hdr");
|
||||
|
||||
this->conn = conn;
|
||||
|
||||
editButton = new QPushButton("edit", this);
|
||||
hdr->addWidget(editButton);
|
||||
|
||||
varEdit = new QLineEdit("tt.main", this);
|
||||
hdr->addWidget(varEdit);
|
||||
|
||||
leaveButton = new QPushButton("close", this);
|
||||
hdr->addWidget(leaveButton);
|
||||
|
||||
vbox->addLayout(hdr);
|
||||
|
||||
textedit = new MyTextEdit(this, "report_edit");
|
||||
textedit->setReadOnly(TRUE);
|
||||
textedit->setSelectionAttributes(1, QColor(255,255,128), FALSE);
|
||||
|
||||
vbox->addWidget(textedit, 1);
|
||||
|
||||
timer = new QTimer(this, "reportTimer");
|
||||
|
||||
connect(leaveButton, SIGNAL(clicked()), this, SIGNAL(leave()));
|
||||
connect(editButton, SIGNAL(clicked()), this, SLOT(editReport()));
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(updatePos()));
|
||||
|
||||
}
|
||||
|
||||
void Report::gotoTime(time_t from, time_t at, time_t to, bool silent) {
|
||||
char cmd[128];
|
||||
int iret;
|
||||
QString line;
|
||||
time_t lastRead, t, dt;
|
||||
bool ok;
|
||||
QString message;
|
||||
QDateTime datim;
|
||||
int l;
|
||||
int p;
|
||||
|
||||
if (isHidden()) {
|
||||
if (silent) return;
|
||||
openMe();
|
||||
}
|
||||
if (variable != varEdit->text() || from != this->from || to != this->to) {
|
||||
|
||||
this->to = to;
|
||||
this->from = from;
|
||||
times.clear();
|
||||
|
||||
variable = varEdit->text();
|
||||
snprintf(cmd, sizeof cmd, "graph %ld %ld text np %ld %s",
|
||||
from, to, to - from, variable.latin1());
|
||||
|
||||
textedit->clear();
|
||||
conn->command(cmd);
|
||||
|
||||
iret = conn->getLine(line);
|
||||
if (iret <= 0) {
|
||||
message = ("can not get response 1");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* get returned absolute time */
|
||||
lastRead = line.toLong();
|
||||
|
||||
iret = conn->getLine(line);
|
||||
if (iret <= 0) {
|
||||
message = "can not get response 2";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!line.startsWith("*" + variable)) {
|
||||
message = "response '" + line + "' must start with '*" + variable + "'";
|
||||
goto err;
|
||||
}
|
||||
|
||||
t = 0;
|
||||
for (;;) {
|
||||
iret = conn->getLine(line);
|
||||
if (iret <= 0) {
|
||||
message = "can not get line";
|
||||
goto err;
|
||||
}
|
||||
//printf("> %s\n", line.latin1());
|
||||
if (line.startsWith("*")) {
|
||||
break;
|
||||
}
|
||||
dt = line.section(' ', 0, 0).toLong(&ok);
|
||||
if (!ok) {
|
||||
message = "bad timestep";
|
||||
goto err;
|
||||
}
|
||||
t += dt;
|
||||
times.append(t);
|
||||
datim.setTime_t(t);
|
||||
textedit->appendHtml("<font color=#00FF00>" + datim.toString("hh:mm:ss ") + "</font>");
|
||||
textedit->appendText(
|
||||
line.section(' ', 1).replace("\\n","\n").replace("\\t","\t").replace("\\\\","\\")
|
||||
+"\n"
|
||||
);
|
||||
}
|
||||
textedit->append("\n");
|
||||
pos = -1;
|
||||
}
|
||||
l = times.count();
|
||||
|
||||
p = l - 1;
|
||||
for (int ipos = 0; ipos < l; ipos++) {
|
||||
if (times[ipos] >= at) {
|
||||
p = ipos - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p < 0) p = 0;
|
||||
if (pos < 0) {
|
||||
pos = l;
|
||||
}
|
||||
setCursorPos(p);
|
||||
timer->start(200);
|
||||
return;
|
||||
err:
|
||||
textedit->append("error: "+message);
|
||||
}
|
||||
|
||||
void Report::setCursorPos(int newpos) {
|
||||
int index;
|
||||
|
||||
textedit->setCursorPosition(newpos, 0);
|
||||
if (newpos > pos) {
|
||||
textedit->moveCursor(QTextEdit::MoveDown, false);
|
||||
textedit->moveCursor(QTextEdit::MoveDown, false);
|
||||
} else {
|
||||
textedit->moveCursor(QTextEdit::MoveUp, false);
|
||||
textedit->moveCursor(QTextEdit::MoveUp, false);
|
||||
}
|
||||
textedit->getCursorPosition(&posc, &index);
|
||||
pos = newpos;
|
||||
textedit->setSelection(pos, 0, pos+1, 0, 1);
|
||||
textedit->setCursorPosition(posc, 0);
|
||||
textedit->ensureCursorVisible();
|
||||
}
|
||||
|
||||
void Report::updatePos() {
|
||||
int para, index;
|
||||
|
||||
textedit->getCursorPosition(¶, &index);
|
||||
if (para == pos) return;
|
||||
if (para == posc && index == 0) {
|
||||
// cursor repositioning pending
|
||||
posc = pos;
|
||||
textedit->setCursorPosition(posc, 0);
|
||||
textedit->ensureCursorVisible();
|
||||
} else {
|
||||
setCursorPos(para);
|
||||
}
|
||||
if (pos < (int)times.count()) {
|
||||
setMarker(times[pos]);
|
||||
}
|
||||
}
|
||||
|
||||
void Report::editReport() {
|
||||
QString text;
|
||||
|
||||
if (textedit->isReadOnly()) {
|
||||
textedit->setReadOnly(FALSE);
|
||||
timer->stop();
|
||||
setMarker(0);
|
||||
} else {
|
||||
printf("%s\n", textedit->text().latin1());
|
||||
textedit->setText(textedit->text());
|
||||
}
|
||||
}
|
38
report.h
Normal file
38
report.h
Normal file
@ -0,0 +1,38 @@
|
||||
#include <stddef.h>
|
||||
#include <qtextedit.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qvaluevector.h>
|
||||
#include <qtimer.h>
|
||||
#include <time.h>
|
||||
#include "sicsconn.h"
|
||||
#include "utils.h"
|
||||
|
||||
class Report : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Report(QWidget *parent, SicsConnection *conn);
|
||||
signals:
|
||||
void leave();
|
||||
void openMe();
|
||||
void setMarker(time_t t);
|
||||
public slots:
|
||||
void gotoTime(time_t from, time_t at, time_t to, bool silent);
|
||||
void updatePos();
|
||||
void editReport();
|
||||
private:
|
||||
void setCursorPos(int newpos);
|
||||
MyTextEdit *textedit;
|
||||
QPushButton *editButton;
|
||||
QPushButton *leaveButton;
|
||||
QLineEdit *varEdit;
|
||||
time_t atTime;
|
||||
QString variable;
|
||||
SicsConnection *conn;
|
||||
int pos;
|
||||
int posc;
|
||||
time_t from, to;
|
||||
QValueVector<time_t> times;
|
||||
QTimer *timer;
|
||||
};
|
722
seaplot.cpp
Normal file
722
seaplot.cpp
Normal file
@ -0,0 +1,722 @@
|
||||
#include "seaplot.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <qfont.h>
|
||||
#include <qgrid.h>
|
||||
#include <qtooltip.h>
|
||||
#include <qwt_plot_layout.h>
|
||||
#include <qwt_scale.h>
|
||||
#include "utils.h"
|
||||
|
||||
#define SEA_RESOLUTION 0.00005 /* chagned from 0.0005 for Amy, July 2020 */
|
||||
|
||||
LegendButton::LegendButton(QWidget *parent, SeaPlot *plot, SeaCurve *crv) : QwtLegendButton(parent) {
|
||||
this->plot = plot;
|
||||
this->crv = crv;
|
||||
connect(this, SIGNAL(clicked()), this, SLOT(legendClicked()));
|
||||
connect(&clickTimer, SIGNAL(timeout()), this, SLOT(handleClickTimer()));
|
||||
label = new FlatButton(crv->title(), parent);
|
||||
setFixedHeight(label->sizeHint().height());
|
||||
setFixedWidth(16);
|
||||
connect(label, SIGNAL(clicked()), this, SLOT(legendClicked()));
|
||||
connect(label, SIGNAL(mousePressed()), this, SLOT(mousePressed()));
|
||||
};
|
||||
|
||||
void LegendButton::init(SeaPlot *plot, SeaCurve *crv) {
|
||||
this->plot = plot;
|
||||
this->crv = crv;
|
||||
};
|
||||
|
||||
void LegendButton::mousePressed() {
|
||||
clickDone = false;
|
||||
clickTimer.stop();
|
||||
clickTimer.start(300);
|
||||
}
|
||||
|
||||
void LegendButton::handleClickTimer() {
|
||||
if (!clickDone) {
|
||||
clickTimer.stop();
|
||||
clickDone = true;
|
||||
longClick();
|
||||
}
|
||||
}
|
||||
|
||||
void LegendButton::legendClicked() {
|
||||
if (!clickDone) {
|
||||
clickDone = true;
|
||||
clickTimer.stop();
|
||||
plot->switchBold(crv);
|
||||
}
|
||||
};
|
||||
|
||||
void LegendButton::longClick() {
|
||||
plot->setOneBold(crv);
|
||||
};
|
||||
|
||||
|
||||
void LegendButton::mousePressEvent(QMouseEvent *e) {
|
||||
mousePressed();
|
||||
QwtLegendButton::mousePressEvent(e);
|
||||
}
|
||||
|
||||
void LegendButton::setTitle(const QString &title) {
|
||||
label->setText(title);
|
||||
}
|
||||
|
||||
class TimeScaleDraw: public QwtScaleDraw {
|
||||
public:
|
||||
TimeScaleDraw(SeaSet *set) : QwtScaleDraw() {
|
||||
this->set = set;
|
||||
}
|
||||
virtual QString label(double v) const {
|
||||
QTime time;
|
||||
QwtScaleDiv div = scaleDiv();
|
||||
double step = div.majStep();
|
||||
int itic0 = lround(div.lBound() / step + 0.5001);
|
||||
int itic1 = lround(div.hBound() / step - 0.5001);
|
||||
int itic = lround(v / step);;
|
||||
int m;
|
||||
|
||||
if (step < 23*3600) {
|
||||
m = 2;
|
||||
if (step > 59 && step < 121) {
|
||||
m = 5;
|
||||
} else if (lround(step) == 600) {
|
||||
m = 3;
|
||||
}
|
||||
} else {
|
||||
m = (itic1 - itic0) / 5 + 1;
|
||||
}
|
||||
time.setHMS(0,0,0);
|
||||
itic0 = lround(div.lBound() / step / m + 0.5001);
|
||||
itic1 = lround(div.hBound() / step / m - 0.5001);
|
||||
if (itic1 - itic0 > 1 && v > div.hBound() - step) {
|
||||
return ""; //do not show last label
|
||||
} else if (itic % m == 0) {
|
||||
if (step < 3599) {
|
||||
return time.addSecs(lround(v)).toString("hh:mm");
|
||||
} else if (lround(v/3600) % 24 == 0) {
|
||||
return set->dateLabel(lround(v/(24*3600)));
|
||||
} else {
|
||||
return time.addSecs(lround(v)).toString("hh").append("h");
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
SeaSet *set;
|
||||
};
|
||||
|
||||
class YScaleDraw: public QwtScaleDraw {
|
||||
public:
|
||||
YScaleDraw(SeaSet *set) : QwtScaleDraw() {
|
||||
this->set = set;
|
||||
}
|
||||
virtual int maxLabelWidth(const QFontMetrics &fm) const {
|
||||
return set->leftLabelWidth(QwtScaleDraw::maxLabelWidth(fm));
|
||||
}
|
||||
SeaSet *set;
|
||||
};
|
||||
|
||||
class SeaZoomer: public QwtPlotZoomer {
|
||||
friend class SeaPlot;
|
||||
public:
|
||||
SeaZoomer(SeaPlot *p) :
|
||||
QwtPlotZoomer(QwtPlot::xBottom, QwtPlot::yLeft,
|
||||
QwtPicker::DragSelection, QwtPicker::AlwaysOff,
|
||||
p->canvas()) {
|
||||
yAuto = true;
|
||||
displayMarker = false;
|
||||
pl = p;
|
||||
doZoom = false;
|
||||
};
|
||||
SeaPlot *pl;
|
||||
bool yAuto;
|
||||
bool setMark;
|
||||
bool displayMarker;
|
||||
bool track;
|
||||
bool doZoom;
|
||||
int xp, yp;
|
||||
QTime t;
|
||||
|
||||
protected:
|
||||
QwtDoubleSize minZoomSize() const {
|
||||
const QwtScaleDiv *scy = pl->axisScale(QwtPlot::yLeft);
|
||||
double hei = fabs(scy->hBound() + scy->lBound()) * SEA_RESOLUTION;
|
||||
return QwtDoubleSize(60., hei);
|
||||
};
|
||||
|
||||
void rescale() {
|
||||
QwtDoubleRect r = zoomRect();
|
||||
if (doZoom && r != scaleRect()) {
|
||||
pl->zoomTo(scaleRect(), r);
|
||||
}
|
||||
}
|
||||
|
||||
void enableMarker() {
|
||||
if (!displayMarker) {
|
||||
QWidget *parent = parentWidget();
|
||||
track = parent->hasMouseTracking();
|
||||
parent->setMouseTracking(true);
|
||||
displayMarker = true;
|
||||
}
|
||||
}
|
||||
|
||||
void disableMarker() {
|
||||
if (displayMarker) {
|
||||
QWidget *parent = parentWidget();
|
||||
displayMarker = false;
|
||||
parent->setMouseTracking(track);
|
||||
}
|
||||
}
|
||||
|
||||
void widgetMousePressEvent(QMouseEvent *e) {
|
||||
//printf("*** mousePress %d %d\n", e->x(), e->y());
|
||||
xp = e->x();
|
||||
yp = e->y();
|
||||
if (pl->set->markerFix) {
|
||||
setMark = true;
|
||||
} else {
|
||||
setMark = !pl->set->markerWasOn;
|
||||
}
|
||||
pl->set->markerFix = false;
|
||||
t.start();
|
||||
QwtPlotZoomer::widgetMousePressEvent(e);
|
||||
}
|
||||
|
||||
void widgetMouseReleaseEvent(QMouseEvent *e) {
|
||||
//printf("*** mouseRelease %d %d %d\n", e->x(), e->y(), t.elapsed());
|
||||
// mechanism for avoiding unintended zooms:
|
||||
// do not allow if the rectangle is too small
|
||||
// or if the mouse was pressed for less than 200 ms
|
||||
doZoom = abs(e->x() - xp) + abs(e->y() - yp) > 2 && t.elapsed() > 200;
|
||||
QwtPlotZoomer::widgetMouseReleaseEvent(e);
|
||||
if (!doZoom && !displayMarker && setMark) {
|
||||
QwtDoublePoint p = invTransform(e->pos());
|
||||
pl->set->setMarker(p.x());
|
||||
}
|
||||
}
|
||||
|
||||
void widgetMouseDoubleClickEvent(QMouseEvent *e) {
|
||||
//printf("*** mouseDoubleClick %d %d %d\n", e->x(), e->y(), t.elapsed());
|
||||
setMark = true;
|
||||
pl->set->markerFix = true;
|
||||
QwtDoublePoint at =invTransform(e->pos());
|
||||
//pl->set->gotoTime(at.x(), FALSE);
|
||||
}
|
||||
|
||||
void widgetMouseMoveEvent(QMouseEvent *e) {
|
||||
if (displayMarker) {
|
||||
QwtDoublePoint p = invTransform(e->pos());
|
||||
if (!pl->set->markerFix) {
|
||||
pl->set->setMarker(p.x());
|
||||
pl->set->gotoTime(p.x(), TRUE);
|
||||
}
|
||||
} else {
|
||||
QwtPlotZoomer::widgetMouseMoveEvent(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SeaCurve::SeaCurve(QwtPlot *parent, const QString &title) : QwtPlotCurve(parent, title) {
|
||||
leg = NULL;
|
||||
iColor = -1;
|
||||
};
|
||||
|
||||
void SeaCurve::draw(QPainter *p, const QwtDiMap &xMap, const QwtDiMap &yMap,
|
||||
int from, int to) {
|
||||
int i, start;
|
||||
double ylowlim;
|
||||
|
||||
if (leg->plot->logarithmic) {
|
||||
ylowlim = 1e-30;
|
||||
} else {
|
||||
ylowlim = DATA_UNDEF;
|
||||
}
|
||||
start = -1;
|
||||
if (to < 0) {
|
||||
to = dataSize() - 1;
|
||||
if (to < 0) return;
|
||||
}
|
||||
for (i=from; i<=to; i++) {
|
||||
if (i > 0 && y(i) <= ylowlim) { /* undefined value */
|
||||
if (start >= 0) {
|
||||
QwtPlotCurve::draw(p, xMap, yMap, start, i-1);
|
||||
start = -1;
|
||||
}
|
||||
} else {
|
||||
if (start < 0) start = i;
|
||||
}
|
||||
}
|
||||
if (start >= 0) {
|
||||
QwtPlotCurve::draw(p, xMap, yMap, start, to);
|
||||
}
|
||||
};
|
||||
|
||||
void SeaCurve::setPen(const QPen &p) {
|
||||
QwtCurve::setPen(p);
|
||||
if (leg) leg->setCurvePen(p);
|
||||
};
|
||||
|
||||
void SeaCurve::setTitle(const QString &t) {
|
||||
QwtCurve::setTitle(t);
|
||||
if (leg) leg->setTitle(t);
|
||||
};
|
||||
|
||||
void SeaCurve::yBounds(double from, double to, double &ymin, double &ymax) {
|
||||
int i, n = dataSize();
|
||||
double y1, y2;
|
||||
double ya, yb, yc, yd, yi;
|
||||
int k, n1, n2, nn;
|
||||
bool done;
|
||||
double ylowlim;
|
||||
|
||||
// implementing a mechanism to ignore spikes:
|
||||
// after the first pass, the whole range is divided into 3 ranges.
|
||||
// in the next pass, only the points in the middle range are taken into account
|
||||
// for minimum and maximum, the others are counted only. When the number of points
|
||||
// in the upper or in the lower part are less than 2 %, the range is reduced by
|
||||
// the upper and/or the lower part and a next pass is done
|
||||
|
||||
if (leg->plot->logarithmic) {
|
||||
ylowlim = 1e-30;
|
||||
} else {
|
||||
ylowlim = DATA_UNDEF;
|
||||
}
|
||||
y1 = 1e30;
|
||||
y2 = -1e30;
|
||||
ya = -1e30;
|
||||
yb = -1e30;
|
||||
yc = 1e30;
|
||||
yd = 1e30;
|
||||
k = 0;
|
||||
yi = 1e30;
|
||||
while (1) {
|
||||
n1 = 0;
|
||||
n2 = 0;
|
||||
nn = 0;
|
||||
for (i=0; i<n; i++) {
|
||||
if (x(i)>= from) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; i<n; i++) {
|
||||
if (x(i) > to) {
|
||||
break;
|
||||
}
|
||||
yi = y(i);
|
||||
if (yi > ylowlim) { // and therefore yi != DATA_UNDEF
|
||||
if (yi < yb) {
|
||||
n1++;
|
||||
} else if (yi > yc) {
|
||||
n2++;
|
||||
} else {
|
||||
nn++;
|
||||
if (yi > y2) {
|
||||
y2 = yi;
|
||||
}
|
||||
if (yi < y1) {
|
||||
y1 = yi;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i == n && yi > ylowlim) {
|
||||
if (yi < y1) y1 = yi;
|
||||
if (yi > y2) y2 = yi;
|
||||
}
|
||||
if (k == 0) {
|
||||
ya = y1;
|
||||
yd = y2;
|
||||
} else {
|
||||
done = true;
|
||||
if (n1 * 49 < nn + n2 && y1 >= yb) {
|
||||
ya = y1;
|
||||
done = false;
|
||||
}
|
||||
if (n2 * 49 < nn + n1 && y2 <= yc) {
|
||||
yd = y2;
|
||||
done = false;
|
||||
}
|
||||
if (done || k > 20 || ya == yd) {
|
||||
break;
|
||||
}
|
||||
//printf("%s %d %d %d %d %f %f\n", data->label.latin1(), k, n1, n2, nn, ya, yd);
|
||||
}
|
||||
k++;
|
||||
yb = ya + (yd - ya) / 3;
|
||||
yc = yd - (yd - ya) / 3;
|
||||
y1 = yc;
|
||||
y2 = yb;
|
||||
}
|
||||
if (yi < 0.9e30) {
|
||||
ymin = QMIN(ymin, ya);
|
||||
ymax = QMAX(ymax, yd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void SeaCurve::changeBold() {
|
||||
int i;
|
||||
if (iColor == -1) {
|
||||
i = Convert2ColorIndex("black");
|
||||
} else {
|
||||
i = iColor;
|
||||
}
|
||||
leg->plot->set->saveBoldState(data);
|
||||
if (data->bold) {
|
||||
setPen(thisPen(i, 0));
|
||||
QToolTip::add(leg, "hide curve (long click: show this curve only)");
|
||||
QToolTip::add(leg->label, "hide curve (long click: show this curve only)");
|
||||
} else {
|
||||
setPen(thisPen(i, 1));
|
||||
QToolTip::add(leg, "show curve (long click: this curve only)");
|
||||
QToolTip::add(leg->label, "show curve (long click: this curve only)");
|
||||
}
|
||||
}
|
||||
|
||||
SeaPlot::SeaPlot(QWidget *p, SeaSet *set, const QString &name) : QwtPlot(p, name) {
|
||||
QTime now(QTime::currentTime());
|
||||
QTime midnight(0,0,0);
|
||||
double dnow;
|
||||
|
||||
//setAutoLegend( TRUE );
|
||||
//setLegendPosition( QwtPlot::Left , 0.5);
|
||||
this->set = set;
|
||||
|
||||
dnow = midnight.secsTo(now);
|
||||
setAxisScale(QwtPlot::xBottom, dnow-1800, dnow+600, 300.0);
|
||||
setAxisScale(QwtPlot::yLeft, 0.0, 0.9999);
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new TimeScaleDraw(set));
|
||||
setAxisScaleDraw(QwtPlot::yLeft, new YScaleDraw(set));
|
||||
setAxisLabelFormat(QwtPlot::yLeft, 'g', 5);
|
||||
zoom = new SeaZoomer(this);
|
||||
zoom->setRubberBand(QwtPlotZoomer::RectRubberBand);
|
||||
zoom->setRubberBandPen(QPen(Qt::red));
|
||||
plotLayout()->setCanvasMargin(0, SeaPlot::yLeft);
|
||||
plotLayout()->setCanvasMargin(0, SeaPlot::yRight);
|
||||
canvas()->setPaletteBackgroundColor(QColor(238,238,238));
|
||||
setGridPen(QPen(QColor(221, 221, 221), 1));
|
||||
logarithmic = false;
|
||||
removeAll();
|
||||
};
|
||||
|
||||
void SeaPlot::removeAll() {
|
||||
tag = "";
|
||||
removeCurves();
|
||||
marker = insertCurve("Marker");
|
||||
// setCurvePen(marker, QPen(Qt::white, 3));
|
||||
setCurvePen(marker, QPen(Qt::black, 1));
|
||||
}
|
||||
|
||||
void SeaPlot::setMarker(double x) {
|
||||
const QwtScaleDiv *s = axisScale(yLeft);
|
||||
double xval[2], yval[2], h;
|
||||
SeaCurve *crv;
|
||||
QwtPlotCurveIterator itc = curveIterator();
|
||||
|
||||
if (x == DATA_UNDEF) {
|
||||
zoom->disableMarker();
|
||||
xval[0] = DATA_UNDEF;
|
||||
xval[1] = DATA_UNDEF;
|
||||
} else {
|
||||
zoom->enableMarker();
|
||||
xval[0] = x;
|
||||
xval[1] = x;
|
||||
}
|
||||
h = s->hBound() - s->lBound();
|
||||
if (logarithmic) {
|
||||
yval[0] = s->lBound() * 0.5;
|
||||
} else {
|
||||
yval[0] = s->lBound() - h;
|
||||
}
|
||||
yval[1] = s->hBound() + h;
|
||||
setCurveData(marker, xval, yval, 2);
|
||||
|
||||
for (QwtPlotCurve *c = itc.toFirst(); c != 0; c = ++itc ) {
|
||||
crv = dynamic_cast<SeaCurve *>(c);
|
||||
if (crv) {
|
||||
crv->data->showValueAt(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SeaPlot::refresh() {
|
||||
const QwtScaleDiv *s = axisScale(xBottom);
|
||||
replotRange(s->lBound(), s->hBound(), s->majStep());
|
||||
};
|
||||
|
||||
void SeaPlot::autoColors() {
|
||||
SeaCurve *crv;
|
||||
QwtPlotCurveIterator itc = curveIterator();
|
||||
int i;
|
||||
|
||||
usedColors.fill(false, N_SEACOLORS);
|
||||
usedColors.setBit(0); // do not use white
|
||||
|
||||
for (QwtPlotCurve *c = itc.toFirst(); c != 0; c = ++itc ) {
|
||||
crv = dynamic_cast<SeaCurve *>(c);
|
||||
if (crv) {
|
||||
if (crv->iColor >= 0 && crv->iColor < N_SEACOLORS) {
|
||||
usedColors.setBit(crv->iColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i=0;
|
||||
for (QwtPlotCurve *c = itc.toFirst(); c != 0; c = ++itc ) {
|
||||
crv = dynamic_cast<SeaCurve *>(c);
|
||||
if (crv) {
|
||||
if (crv->iColor < 0) {
|
||||
while (i < N_SEACOLORS && usedColors.at(i)) {
|
||||
i++;
|
||||
}
|
||||
if (i >= N_SEACOLORS) {
|
||||
crv->iColor = Convert2ColorIndex("black");
|
||||
} else {
|
||||
crv->iColor = i;
|
||||
usedColors.setBit(i);
|
||||
crv->changeBold();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LegendButton *SeaPlot::putCurve(SeaData *d, QWidget *parent, LegendButton *legButton) {
|
||||
SeaCurve *crv = new SeaCurve(this, d->label);
|
||||
|
||||
d->plot = this;
|
||||
d->key = insertCurve(crv);
|
||||
|
||||
if (legButton) {
|
||||
legButton->init(this, crv);
|
||||
} else {
|
||||
legButton = new LegendButton(parent, this, crv);
|
||||
}
|
||||
legButton->setTitle(d->label);
|
||||
|
||||
//QFont myfont(legButton->font());
|
||||
//myfont.setPointSize(12);
|
||||
//legButton->setFont(myfont);
|
||||
//legButton->setFixedHeight(legButton->fontMetrics().height()+2);
|
||||
|
||||
crv->leg = legButton;
|
||||
//crv->leg->setTitle(crv->title());
|
||||
//crv->leg->setTitle("");
|
||||
//if (d->style >= 0 && d->style <= N_SEACOLORS) {
|
||||
if (d->style >= 0) {
|
||||
crv->iColor = d->style;
|
||||
crv->autoColor = false;
|
||||
} else {
|
||||
crv->iColor = -1;
|
||||
crv->autoColor = true;
|
||||
}
|
||||
crv->data = d;
|
||||
crv->changeBold();
|
||||
crv->setStyle(QwtCurve::Lines);
|
||||
d->modified = true;
|
||||
d->update();
|
||||
return legButton;
|
||||
}
|
||||
|
||||
void SeaPlot::showAgain() {
|
||||
SeaCurve *crv;
|
||||
QwtPlotCurveIterator itc = curveIterator();
|
||||
for (QwtPlotCurve *c = itc.toFirst(); c != 0; c = ++itc ) {
|
||||
crv = dynamic_cast<SeaCurve *>(c);
|
||||
if (crv) {
|
||||
crv->data->bold = true;
|
||||
crv->changeBold();
|
||||
}
|
||||
}
|
||||
autoColors();
|
||||
//refresh();
|
||||
set->replotAnyway();
|
||||
}
|
||||
|
||||
bool SeaPlot::toggleLinLog() {
|
||||
logarithmic = ! logarithmic;
|
||||
if (logarithmic) {
|
||||
setAxisOptions(QwtPlot::yLeft, QwtAutoScale::Logarithmic);
|
||||
} else {
|
||||
setAxisOptions(QwtPlot::yLeft, QwtAutoScale::None);
|
||||
}
|
||||
refresh();
|
||||
return logarithmic;
|
||||
}
|
||||
|
||||
void SeaPlot::zoomMax() {
|
||||
autoZoom(true);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void SeaPlot::autoZoom(bool on) {
|
||||
zoom->yAuto = on;
|
||||
setAutoOff(!on);
|
||||
}
|
||||
|
||||
void SeaPlot::undoZoom(QwtDoubleRect &r) {
|
||||
setAxisScale(QwtPlot::yLeft, r.y1(), r.y2());
|
||||
zoom->setZoomBase();
|
||||
}
|
||||
|
||||
void SeaPlot::zoomTo(QwtDoubleRect old, QwtDoubleRect &r) {
|
||||
set->saveRange(this, old, zoom->yAuto);
|
||||
autoZoom(false);
|
||||
setAxisScale(QwtPlot::yLeft, r.y1(), r.y2());
|
||||
set->rescale(r.x1(), r.x2());
|
||||
zoom->setZoomBase();
|
||||
}
|
||||
|
||||
void SeaPlot::zoomOut() {
|
||||
QwtDoubleRect r = zoom->zoomRect();
|
||||
QwtDoubleRect old= zoom->scaleRect();
|
||||
|
||||
set->saveRange(this, old, zoom->yAuto);
|
||||
if (logarithmic) {
|
||||
double h = log(r.y2()) - log(r.y1());
|
||||
r.setY2(exp(log(r.y2()) + h / 2));
|
||||
r.setY1(exp(log(r.y1()) - h / 2));
|
||||
} else {
|
||||
double h = r.y2() - r.y1();
|
||||
r.setY2(r.y2() + h / 2);
|
||||
r.setY1(r.y1() - h / 2);
|
||||
}
|
||||
zoom->setZoomBase(r);
|
||||
zoom->zoom(0);
|
||||
autoZoom(false);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void SeaPlot::shiftUp() {
|
||||
QwtDoubleRect r = zoom->zoomRect();
|
||||
double h = (r.y2() - r.y1()) * 0.5;
|
||||
QwtDoubleRect old= zoom->scaleRect();
|
||||
|
||||
set->saveRange(this, old, zoom->yAuto);
|
||||
r.setY2(r.y2() + h);
|
||||
r.setY1(r.y1() + h);
|
||||
zoom->setZoomBase(r);
|
||||
zoom->zoom(r);
|
||||
zoom->setZoomBase();
|
||||
zoom->zoom(0);
|
||||
autoZoom(false);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void SeaPlot::shiftDown() {
|
||||
QwtDoubleRect r = zoom->zoomRect();
|
||||
double h = (r.y2() - r.y1()) * 0.5;
|
||||
QwtDoubleRect old= zoom->scaleRect();
|
||||
|
||||
set->saveRange(this, old, zoom->yAuto);
|
||||
r.setY2(r.y2() - h);
|
||||
r.setY1(r.y1() - h);
|
||||
zoom->setZoomBase(r);
|
||||
zoom->zoom(r);
|
||||
zoom->setZoomBase();
|
||||
zoom->zoom(0);
|
||||
autoZoom(false);
|
||||
refresh();
|
||||
}
|
||||
|
||||
int SeaPlot::replotRange(double from, double to, double tick) {
|
||||
SeaCurve *crv;
|
||||
QwtDoubleRect r;
|
||||
double ymin, ymax, yminA, ymaxA, y0, res;
|
||||
int result;
|
||||
bool nobold;
|
||||
|
||||
result = 1;
|
||||
ymin = 1e30;
|
||||
ymax = -1e30;
|
||||
yminA = ymin;
|
||||
ymaxA = ymax;
|
||||
nobold = true;
|
||||
QwtPlotCurveIterator itc = curveIterator();
|
||||
for (QwtPlotCurve *c = itc.toFirst(); c != 0; c = ++itc ) {
|
||||
crv = dynamic_cast<SeaCurve *>(c);
|
||||
if (crv) {
|
||||
crv->yBounds(from, to, yminA, ymaxA);
|
||||
if (crv->data->bold) {
|
||||
crv->yBounds(from, to, ymin, ymax);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ymin > ymax) {
|
||||
ymin = yminA;
|
||||
ymax = ymaxA;
|
||||
if (ymin > ymax) {
|
||||
ymin = 0;
|
||||
ymax = 1;
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
r = zoom->zoomRect();
|
||||
if (zoom->yAuto) {
|
||||
res = 0.1;
|
||||
} else {
|
||||
ymin = r.y1();
|
||||
ymax = r.y2();
|
||||
res = SEA_RESOLUTION;
|
||||
}
|
||||
if (logarithmic) {
|
||||
if (ymax <= 0) {
|
||||
ymax = ymaxA;
|
||||
ymin = yminA;
|
||||
} else if (ymin <= 0) {
|
||||
ymin = QMIN(ymax, yminA);
|
||||
}
|
||||
y0 = (log(ymin) + log(ymax)) / 2;
|
||||
if ((log(ymax) - log(ymin)) < res) {
|
||||
ymin = exp(y0 - res * 0.4999);
|
||||
ymax = exp(y0 + res * 0.5);
|
||||
}
|
||||
} else {
|
||||
y0 = (ymin + ymax) / 2;
|
||||
if ((ymax - ymin) < y0 * res) {
|
||||
ymin = y0 * (1 - res * 0.4999);
|
||||
ymax = y0 * (1 + res * 0.5);
|
||||
}
|
||||
}
|
||||
setAxisMaxMinor(QwtPlot::xBottom, 0);
|
||||
setAxisScale(QwtPlot::xBottom, from, to, tick);
|
||||
setAxisScale(QwtPlot::yLeft, ymin, ymax);
|
||||
replot();
|
||||
if (zoom->zoomRectIndex() == 0) {
|
||||
zoom->setZoomBase();
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
int SeaPlot::replotRange() {
|
||||
const QwtScaleDiv *scx = axisScale(QwtPlot::xBottom);
|
||||
return replotRange(scx->lBound(), scx->hBound(), scx->majStep());
|
||||
};
|
||||
|
||||
void SeaPlot::switchBold(SeaCurve *crv) {
|
||||
crv->data->bold = !crv->data->bold;
|
||||
crv->changeBold();
|
||||
crv->leg->update();
|
||||
set->replotAnyway();
|
||||
set->updateCurveList();
|
||||
}
|
||||
|
||||
void SeaPlot::setOneBold(SeaCurve *selectedCrv) {
|
||||
QwtPlotCurveIterator itc = curveIterator();
|
||||
SeaCurve *crv;
|
||||
|
||||
for (QwtPlotCurve *c = itc.toFirst(); c != 0; c = ++itc ) {
|
||||
crv = dynamic_cast<SeaCurve *>(c);
|
||||
if (crv) { // omit Marker
|
||||
crv->data->bold = crv == selectedCrv;
|
||||
crv->changeBold();
|
||||
crv->leg->update();
|
||||
}
|
||||
}
|
||||
autoZoom(true);
|
||||
set->replotAnyway();
|
||||
set->updateCurveList();
|
||||
}
|
||||
|
97
seaplot.h
Normal file
97
seaplot.h
Normal file
@ -0,0 +1,97 @@
|
||||
#ifndef SEAPLOT_H
|
||||
#define SEAPLOT_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <qwt_plot.h>
|
||||
#include <qlayout.h>
|
||||
#include <qbitarray.h>
|
||||
#include "seaset.h"
|
||||
|
||||
class SeaSet;
|
||||
class SeaData;
|
||||
class SeaZoomer;
|
||||
class SeaCurve;
|
||||
class LegendButton;
|
||||
class QGrid;
|
||||
class QLineEdit;
|
||||
|
||||
class SeaPlot : public QwtPlot
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SeaPlot(QWidget *p, SeaSet *set, const QString &name);
|
||||
void removeAll();
|
||||
LegendButton *putCurve(SeaData *d, QWidget *parent, LegendButton *legButton = NULL);
|
||||
int replotRange(double from, double to, double tick);
|
||||
int replotRange();
|
||||
void refresh();
|
||||
void switchBold(SeaCurve *crv);
|
||||
void setOneBold(SeaCurve *crv);
|
||||
void showAgain();
|
||||
SeaSet *set;
|
||||
QString tag;
|
||||
void autoZoom(bool on);
|
||||
QwtDoubleRect undoRect;
|
||||
void zoomTo(QwtDoubleRect old, QwtDoubleRect &r);
|
||||
void undoZoom(QwtDoubleRect &r);
|
||||
bool toggleLinLog();
|
||||
void autoColors();
|
||||
long marker;
|
||||
void setMarker(double x);
|
||||
bool logarithmic;
|
||||
QBitArray usedColors;
|
||||
signals:
|
||||
void setAutoOff(bool off);
|
||||
private slots:
|
||||
void zoomOut();
|
||||
void zoomMax();
|
||||
void shiftUp();
|
||||
void shiftDown();
|
||||
private:
|
||||
SeaZoomer *zoom;
|
||||
double y1, y2;
|
||||
};
|
||||
|
||||
class FlatButton;
|
||||
|
||||
class LegendButton : public QwtLegendButton {
|
||||
Q_OBJECT
|
||||
public:
|
||||
LegendButton(QWidget *parent, SeaPlot *plot, SeaCurve *crv);
|
||||
void init(SeaPlot *plot, SeaCurve *crv);
|
||||
void setTitle(const QString &title);
|
||||
FlatButton *label;
|
||||
QLabel *valueLabel;
|
||||
SeaPlot *plot;
|
||||
QTimer clickTimer;
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
public slots:
|
||||
void legendClicked();
|
||||
void longClick();
|
||||
void handleClickTimer();
|
||||
void mousePressed();
|
||||
private:
|
||||
SeaCurve *crv;
|
||||
bool clickDone;
|
||||
};
|
||||
|
||||
|
||||
class SeaCurve : public QwtPlotCurve {
|
||||
public:
|
||||
SeaCurve(QwtPlot *parent, const QString &title);
|
||||
void draw(QPainter *p, const QwtDiMap &xMap, const QwtDiMap &yMap, int from, int to);
|
||||
void setPen(const QPen &p);
|
||||
void setTitle(const QString &t);
|
||||
void yBounds(double from, double to, double &ymin, double &ymax);
|
||||
void changeBold();
|
||||
|
||||
SeaData *data;
|
||||
bool bold;
|
||||
int iColor;
|
||||
bool autoColor;
|
||||
LegendButton *leg;
|
||||
};
|
||||
|
||||
#endif
|
1901
seaset.cpp
Normal file
1901
seaset.cpp
Normal file
File diff suppressed because it is too large
Load Diff
228
seaset.h
Normal file
228
seaset.h
Normal file
@ -0,0 +1,228 @@
|
||||
#ifndef SEASET_H
|
||||
#define SEASET_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <qstring.h>
|
||||
#include <qlayout.h>
|
||||
#include <qdatetime.h>
|
||||
#include <qdict.h>
|
||||
#include <qwt_plot.h>
|
||||
#include <qwt_plot_zoomer.h>
|
||||
#include <qptrlist.h>
|
||||
#include <qptrcollection.h>
|
||||
#include <qsplitter.h>
|
||||
#include <qhbox.h>
|
||||
#include <qvbox.h>
|
||||
#include <qlabel.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qtimer.h>
|
||||
#include <qdatetime.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <qpixmap.h>
|
||||
#include "sicsconn.h"
|
||||
#include "seaplot.h"
|
||||
|
||||
#define SEA_MAX_RANGE (240*3600-60)
|
||||
|
||||
// values lower or equal than this value are considered as undefined
|
||||
#define DATA_UNDEF (-1e33)
|
||||
|
||||
class SeaPlot;
|
||||
class SeaSet;
|
||||
class SeaRow;
|
||||
class QGrid;
|
||||
class LegendButton;
|
||||
|
||||
class SeaData {
|
||||
public:
|
||||
SeaData(const QString &name, const QString &label, const QString &plotName, int color=0);
|
||||
~SeaData();
|
||||
int addValue(double xx, QString value);
|
||||
bool update();
|
||||
void init(time_t step, int siz);
|
||||
void showValueAt(double at);
|
||||
bool isActive();
|
||||
|
||||
QString name;
|
||||
QString label;
|
||||
QString plotName;
|
||||
int size;
|
||||
double *x; // x[0..size_m-1]
|
||||
double *y; // y[0..size_m-1]
|
||||
double step_m;
|
||||
double lastx;
|
||||
int size_m;
|
||||
bool clr;
|
||||
bool dirty;
|
||||
bool modified;
|
||||
bool bold;
|
||||
bool exact;
|
||||
double period; // update period
|
||||
long key;
|
||||
SeaPlot *plot;
|
||||
SeaRow *row;
|
||||
QLabel *shownValue;
|
||||
int decipos;
|
||||
long style;
|
||||
};
|
||||
|
||||
typedef enum {hiddenRow, shownRow, newRow} RowState;
|
||||
|
||||
class SeaRow: public QScrollView {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SeaRow(QWidget *parent);
|
||||
QHBox *hBox;
|
||||
// QScrollView *left;
|
||||
SeaPlot *plot;
|
||||
QGrid *leg;
|
||||
QScrollView *legScroll;
|
||||
QVBox *right;
|
||||
SeaSet *set;
|
||||
QPtrList<LegendButton> legendList;
|
||||
uint usedLegend;
|
||||
QHBox *bBox;
|
||||
RowState state;
|
||||
QPushButton *lBut;
|
||||
QPixmap pmLin, pmLog;
|
||||
QLabel *tagLabel;
|
||||
QLabel *timeLabel;
|
||||
void setInnerHeights(bool isfirstrow, int rowH);
|
||||
void setTag(QString tag);
|
||||
|
||||
virtual void resizeEvent(QResizeEvent *e);
|
||||
virtual QSize minimumSizeHint() const;
|
||||
public slots:
|
||||
void hideRow();
|
||||
void linLog();
|
||||
};
|
||||
|
||||
typedef enum {liveOff, liveAuto, liveOn} LiveState;
|
||||
|
||||
typedef struct GetArg {
|
||||
bool all, append;
|
||||
time_t from, to;
|
||||
} GetArg;
|
||||
|
||||
typedef struct AutoArg {
|
||||
QString vars;
|
||||
} AutoArg;
|
||||
|
||||
class SeaSet : public QObject {
|
||||
Q_OBJECT
|
||||
friend class SeaPlot;
|
||||
friend class SeaRow;
|
||||
public:
|
||||
SeaSet( QSplitter *parent, long range, const char *name);
|
||||
SeaRow *newPlot(const char *name = "");
|
||||
int leftLabelWidth(int in);
|
||||
void insertData(const QString &cName, const QString &label, const QString &pName, const int color);
|
||||
void clrDataList();
|
||||
void finishDataList();
|
||||
QString dateLabel(long dayOffset);
|
||||
QPtrList<SeaData> dataList;
|
||||
void readNewReplot();
|
||||
void rescaleRange(time_t range);
|
||||
void rescale(time_t from, time_t to);
|
||||
void rescale(double from, double to);
|
||||
void calcBase(time_t from);
|
||||
void saveRange();
|
||||
void saveRange(SeaPlot *plot, QwtDoubleRect &old, bool yAuto);
|
||||
void hideRow();
|
||||
void adjustSizes();
|
||||
int sicsCommand(QString &cmd, int graph=0); // blocking
|
||||
int sendSicsCommand(QString &cmd, int graph=0); // non-blocking
|
||||
void setMarker(double x);
|
||||
void setTimeLabel(double x);
|
||||
void runningMarkerOff(bool beforeEvent);
|
||||
void saveRowHeight(SeaRow *row, int height);
|
||||
int getRowHeight(SeaRow *row);
|
||||
void saveBoldState(SeaData *data);
|
||||
void getBoldState(SeaData *data);
|
||||
void setFirstRow();
|
||||
void gotoTime(double at, bool silent);
|
||||
|
||||
SicsConnection *sc, *uc, *gc, *ec;
|
||||
int legendWidth, actLegendWidth;
|
||||
QString hostport;
|
||||
time_t startRange, endRange;
|
||||
time_t base;
|
||||
double markerPos;
|
||||
bool markerWasOn;
|
||||
bool markerFix;
|
||||
SeaRow *firstRow;
|
||||
double lastTime;
|
||||
|
||||
public slots:
|
||||
void autoCurves(const char *vars = 0);
|
||||
void setHost(const QString &hostport);
|
||||
void setTimeRange(time_t start, long seconds);
|
||||
void showAll();
|
||||
void liveUpdate();
|
||||
//void handleSics(const char *line);
|
||||
void shiftLeft();
|
||||
void zoomOutX();
|
||||
void shiftRight();
|
||||
void undoZoom();
|
||||
void setLive(bool on);
|
||||
void restart(const char *vars);
|
||||
void replot();
|
||||
void replotAnyway();
|
||||
void asyncHandler();
|
||||
void setMarker(time_t t);
|
||||
|
||||
signals:
|
||||
void putCurve(const QString &name, const QString &plot);
|
||||
void undoEnabled(bool on);
|
||||
void updateCurveList();
|
||||
void gotoTime(time_t from, time_t at, time_t to, bool silent);
|
||||
|
||||
private:
|
||||
void setBase();
|
||||
void setDate();
|
||||
void getCurves(bool all, time_t from, time_t to);
|
||||
SeaData *findData(const QString &name);
|
||||
void calcLeftLabelWidth();
|
||||
|
||||
bool autoCurvesP1();
|
||||
void autoCurvesP2();
|
||||
int getCurvesP1();
|
||||
void getCurvesP2();
|
||||
|
||||
QSplitter *split;
|
||||
QLayout *layout;
|
||||
time_t lastRead; // time of last read on server
|
||||
bool compressed;
|
||||
QPtrList<SeaRow> rows;
|
||||
int nplots;
|
||||
QwtPlotZoomer *zoom;
|
||||
int labelWidth;
|
||||
int labelMode;
|
||||
bool reread;
|
||||
int refresh;
|
||||
LiveState live;
|
||||
time_t liveTime;
|
||||
SeaPlot *undoPlot;
|
||||
QwtDoubleRect undoRect;
|
||||
time_t undoStart, undoEnd;
|
||||
bool undoAuto;
|
||||
bool initSizes;
|
||||
int xSize;
|
||||
time_t curveStep;
|
||||
// asynchronous stuff:
|
||||
enum {async_idle, async_auto, async_get} async_mode;
|
||||
AutoArg autoArg, autoArgDo;
|
||||
GetArg getArg, getArgDo;
|
||||
bool autoDo, getDo, getNewData;
|
||||
QTimer *asyncTimer;
|
||||
QTime meas;
|
||||
QTime tmot;
|
||||
bool showPlot;
|
||||
QDict<int> rowHeightDict;
|
||||
QDict<bool> boldDict;
|
||||
};
|
||||
|
||||
void setprintit(int p);
|
||||
int printit(void);
|
||||
|
||||
#endif
|
339
settings.cpp
Normal file
339
settings.cpp
Normal file
@ -0,0 +1,339 @@
|
||||
#include "settings.h"
|
||||
#include <qapplication.h>
|
||||
#include <qdialog.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <qcheckbox.h>
|
||||
#include <qlabel.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qlayout.h>
|
||||
#include <qtooltip.h>
|
||||
#include <qwhatsthis.h>
|
||||
#include <qvalidator.h>
|
||||
#include <qscrollview.h>
|
||||
#include <qvbox.h>
|
||||
#include <qgrid.h>
|
||||
#include <qstringlist.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
void SetLength(QLineEdit *lineEdit, int min, int max) {
|
||||
lineEdit->setMaxLength(max);
|
||||
int w0 = lineEdit->fontMetrics().width('0');
|
||||
int w = lineEdit->frameWidth() * 2 + 6;
|
||||
lineEdit->setMinimumWidth(w + w0 * min);
|
||||
lineEdit->setMaximumWidth(w + w0 * max);
|
||||
}
|
||||
|
||||
Settings::Settings(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QHBoxLayout *buttonLayout;
|
||||
QVBoxLayout *vbox;
|
||||
QString str;
|
||||
time_t now;
|
||||
struct tm date;
|
||||
|
||||
vbox = new QVBoxLayout(this, 0, 0, "vBox");
|
||||
|
||||
setName("Settings");
|
||||
|
||||
table = new QScrollView(this, "table");
|
||||
form = new QWidget(table->viewport(), "form");
|
||||
formVL = new QVBoxLayout(form, 0, 0, "formVL");
|
||||
formLayout = new QGridLayout(0, 3, 3, 6, 3);
|
||||
formVL->addLayout(formLayout);
|
||||
formVL->addStretch(1);
|
||||
/*
|
||||
formBox = new QHBox(table->viewport(), "formBox");
|
||||
form = new QGrid(4, formBox, "form");
|
||||
*/
|
||||
table->addChild(form);
|
||||
table->setHScrollBarMode(QScrollView::AlwaysOff);
|
||||
|
||||
buttonLayout = new QHBoxLayout(0, 3, 3, "buttonLayout");
|
||||
|
||||
newButton = new QPushButton(this, "newButton");
|
||||
newButton->setText("New Curve");
|
||||
buttonLayout->addWidget(newButton);
|
||||
|
||||
/*
|
||||
autoButton = new QPushButton(this, "autoButton");
|
||||
autoButton->setText("Auto");
|
||||
buttonLayout->addWidget(autoButton);
|
||||
*/
|
||||
|
||||
cancelButton = new QPushButton(this, "cancelButton");
|
||||
cancelButton->setText("Cancel");
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
|
||||
okButton = new QPushButton(this, "okButton");
|
||||
okButton->setText("OK");
|
||||
buttonLayout->addWidget(okButton);
|
||||
okButton->setDefault(true);
|
||||
|
||||
buttonLayout->addStretch(1);
|
||||
time(&now);
|
||||
date = *localtime(&now);
|
||||
|
||||
buttonLayout->addWidget(new QLabel("# Days", this));
|
||||
rLE = new QLineEdit(this);
|
||||
SetLength(rLE, 2, 2);
|
||||
rLE->setText(str);
|
||||
rLE->setValidator(new QIntValidator(0, 99, this));
|
||||
buttonLayout->addWidget(rLE);
|
||||
|
||||
buttonLayout->addWidget(new QLabel("starting from", this));
|
||||
dLE = new QLineEdit(this);
|
||||
SetLength(dLE, 2, 2);
|
||||
str.sprintf("%d", date.tm_mday);
|
||||
dLE->setText(str);
|
||||
dLE->setValidator(new QIntValidator(0, 31, this));
|
||||
buttonLayout->addWidget(dLE);
|
||||
|
||||
buttonLayout->addWidget(new QLabel(".", this));
|
||||
mLE = new QLineEdit(this);
|
||||
SetLength(mLE, 2, 2);
|
||||
str.sprintf("%d", date.tm_mon+1);
|
||||
mLE->setText(str);
|
||||
mLE->setValidator(new QIntValidator(1, 12, this));
|
||||
buttonLayout->addWidget(mLE);
|
||||
|
||||
buttonLayout->addWidget(new QLabel(".", this));
|
||||
yLE = new QLineEdit(this);
|
||||
SetLength(yLE, 4, 4);
|
||||
str.sprintf("%d", date.tm_year+1900);
|
||||
yLE->setText(str);
|
||||
yLE->setValidator(new QIntValidator(2001, date.tm_year+1900, this));
|
||||
buttonLayout->addWidget(yLE);
|
||||
|
||||
hrLE = new QLineEdit(this);
|
||||
SetLength(hrLE, 5, 5);
|
||||
hrLE->setText("00:00");
|
||||
buttonLayout->addWidget(hrLE);
|
||||
|
||||
vbox->addLayout(buttonLayout);
|
||||
vbox->addWidget(table, 1);
|
||||
//vbox->addStretch(1);
|
||||
|
||||
formLayout->addWidget(new QLabel("Curve", form), 0, 0);
|
||||
formLayout->addWidget(new QLabel("Label", form), 0, 1);
|
||||
formLayout->addWidget(new QLabel("Unit", form), 0, 2);
|
||||
formLayout->addWidget(new QLabel("Color", form), 0, 3);
|
||||
|
||||
/*
|
||||
new QLabel("Curve", form);
|
||||
new QLabel("Label", form);
|
||||
new QLabel("Plot", form);
|
||||
new QLabel("Color", form);
|
||||
*/
|
||||
|
||||
row = 1;
|
||||
|
||||
connect(newButton, SIGNAL(clicked()),
|
||||
this, SLOT(addEmpty()));
|
||||
connect(okButton, SIGNAL(clicked()),
|
||||
this, SLOT(ok()));
|
||||
/*
|
||||
connect(autoButton, SIGNAL(clicked()),
|
||||
this, SLOT(autoCurves()));
|
||||
*/
|
||||
connect(cancelButton, SIGNAL(clicked()),
|
||||
this, SLOT(cancel()));
|
||||
|
||||
connect(rLE, SIGNAL(textChanged(const QString &)),
|
||||
this, SLOT(checkRange(const QString &)));
|
||||
/*
|
||||
connect(dLE, SIGNAL(textChanged(const QString &)),
|
||||
this, SLOT(calcDate(const QString &)));
|
||||
connect(mLE, SIGNAL(textChanged(const QString &)),
|
||||
this, SLOT(calcDate(const QString &)));
|
||||
connect(yLE, SIGNAL(textChanged(const QString &)),
|
||||
this, SLOT(calcDate(const QString &)));
|
||||
*/
|
||||
clearWState(WState_Polished);
|
||||
}
|
||||
|
||||
|
||||
void Settings::updateHeight() {
|
||||
form->setMinimumHeight(table->visibleHeight());
|
||||
}
|
||||
|
||||
void Settings::resizeEvent(QResizeEvent *e) {
|
||||
updateHeight();
|
||||
form->setFixedWidth(table->visibleWidth());
|
||||
QWidget::resizeEvent(e);
|
||||
}
|
||||
|
||||
void Settings::showIt(bool yes) {
|
||||
if (yes) {
|
||||
clear();
|
||||
putCurves(&set->dataList);
|
||||
show();
|
||||
} else {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
#define YEAR (24*3600*360)
|
||||
|
||||
void Settings::checkRange(const QString &str0) {
|
||||
if (str0.compare("") == 0) {
|
||||
dLE->setEnabled(false);
|
||||
mLE->setEnabled(false);
|
||||
yLE->setEnabled(false);
|
||||
hrLE->setEnabled(false);
|
||||
} else {
|
||||
dLE->setEnabled(true);
|
||||
mLE->setEnabled(true);
|
||||
yLE->setEnabled(true);
|
||||
hrLE->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::putCurve(const QString &name, const QString &label,
|
||||
const QString &plotName, long colorIndex) {
|
||||
QLineEdit *n, *p;
|
||||
ColorMenu *cm;
|
||||
unsigned int idx;
|
||||
QString colortext;
|
||||
|
||||
idx = row - 1;
|
||||
|
||||
if (idx < names.count()) {
|
||||
n = names.at(idx);
|
||||
} else {
|
||||
n = new QLineEdit(form);
|
||||
SetLength(n, 8, 64);
|
||||
formLayout->addWidget(n, row, 0);
|
||||
names.append(n);
|
||||
}
|
||||
n->setText(name);
|
||||
n->show();
|
||||
|
||||
if (idx < labels.count()) {
|
||||
p = labels.at(idx);
|
||||
} else {
|
||||
p = new QLineEdit(form);
|
||||
SetLength(p, 8, 64);
|
||||
formLayout->addWidget(p, row, 1);
|
||||
labels.append(p);
|
||||
}
|
||||
p->setText(label);
|
||||
p->show();
|
||||
|
||||
if (idx < plots.count()) {
|
||||
p = plots.at(idx);
|
||||
} else {
|
||||
p = new QLineEdit(form);
|
||||
SetLength(p, 4, 8);
|
||||
formLayout->addWidget(p, row, 2);
|
||||
plots.append(p);
|
||||
}
|
||||
p->setText(plotName);
|
||||
p->show();
|
||||
|
||||
Convert2ColorName(colorIndex, colortext);
|
||||
if (idx < colors.count()) {
|
||||
cm = colors.at(idx);
|
||||
cm->setCurrentItem(0);
|
||||
cm->setCurrentText(colortext);
|
||||
} else {
|
||||
cm = new ColorMenu(colortext, form);
|
||||
cm->setLength(12, 32);
|
||||
formLayout->addWidget(cm, row, 3);
|
||||
colors.append(cm);
|
||||
}
|
||||
cm->show();
|
||||
|
||||
row++;
|
||||
}
|
||||
|
||||
|
||||
void Settings::putCurves(QPtrList<SeaData> *dataList) {
|
||||
SeaData *c;
|
||||
for (c = dataList->first(); c != 0; c = dataList->next()) {
|
||||
putCurve(c->name, c->label, c->plotName, c->style);
|
||||
}
|
||||
updateHeight();
|
||||
}
|
||||
|
||||
void Settings::addEmpty() {
|
||||
putCurve("","","",-1);
|
||||
updateHeight();
|
||||
/*
|
||||
names.last()->show();
|
||||
labels.last()->show();
|
||||
plots.last()->show();
|
||||
colors.last()->show();
|
||||
*/
|
||||
}
|
||||
|
||||
void Settings::apply() {
|
||||
int i, n;
|
||||
long days;
|
||||
time_t t;
|
||||
struct tm date;
|
||||
QStringList hr_min;
|
||||
|
||||
if (rLE->text().compare("") != 0) {
|
||||
days = rLE->text().toLong();
|
||||
|
||||
time(&t);
|
||||
date = *localtime(&t);
|
||||
date.tm_mday = dLE->text().toInt();
|
||||
date.tm_mon = mLE->text().toInt() - 1;
|
||||
date.tm_year = yLE->text().toInt() - 1900;
|
||||
hr_min = QStringList::split(":", hrLE->text());
|
||||
date.tm_hour = (int)hr_min[0].toFloat();
|
||||
if (hr_min.size() > 1) {
|
||||
date.tm_min = (int)hr_min[1].toFloat();
|
||||
} else {
|
||||
date.tm_min = 0;
|
||||
}
|
||||
date.tm_sec = 0;
|
||||
date.tm_isdst = -1;
|
||||
|
||||
set->setTimeRange(mktime(&date), 24*3600*QMAX(1, days));
|
||||
set->autoCurves();
|
||||
} else {
|
||||
set->clrDataList();
|
||||
n = names.count();
|
||||
for (i = 0; i < n; i++) {
|
||||
//printf("%s\n", names.at(i)->text().latin1());
|
||||
set->insertData(names.at(i)->text(), labels.at(i)->text(), plots.at(i)->text(), colors.at(i)->getColorIndex());
|
||||
}
|
||||
set->finishDataList();
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::ok() {
|
||||
apply();
|
||||
leaveSettings();
|
||||
}
|
||||
|
||||
void Settings::cancel() {
|
||||
leaveSettings();
|
||||
}
|
||||
|
||||
void Settings::clear() {
|
||||
int i, n;
|
||||
n = names.count();
|
||||
for (i = 0; i < n; i++) {
|
||||
names.at(i)->setText("");
|
||||
plots.at(i)->setText("");
|
||||
labels.at(i)->setText("");
|
||||
colors.at(i)->setValue(0);
|
||||
}
|
||||
row = 1;
|
||||
rLE->setText("");
|
||||
}
|
||||
|
||||
void Settings::autoCurves() {
|
||||
clear();
|
||||
set->autoCurves();
|
||||
putCurves(&set->dataList);
|
||||
}
|
||||
|
||||
|
52
settings.h
Normal file
52
settings.h
Normal file
@ -0,0 +1,52 @@
|
||||
#include <stddef.h>
|
||||
#include <qdialog.h>
|
||||
#include <qptrlist.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qlabel.h>
|
||||
#include <qcheckbox.h>
|
||||
#include <qlayout.h>
|
||||
#include "seaset.h"
|
||||
// for ColorMenu:
|
||||
#include "device.h"
|
||||
|
||||
class Settings : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Settings(QWidget* parent = 0);
|
||||
//~Settings();
|
||||
|
||||
void clear();
|
||||
void putCurves(QPtrList<SeaData> *curves);
|
||||
void apply();
|
||||
SeaSet *set;
|
||||
QPushButton *okButton, *cancelButton, *newButton;
|
||||
/* QPushButton *autoButton; */
|
||||
QLineEdit *rLE, *dLE, *mLE, *yLE, *hrLE;
|
||||
signals:
|
||||
void leaveSettings();
|
||||
public slots:
|
||||
void addEmpty();
|
||||
void ok();
|
||||
void cancel();
|
||||
void autoCurves();
|
||||
void checkRange(const QString &str);
|
||||
void showIt(bool show);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
protected:
|
||||
void putCurve(const QString &name, const QString &label, const QString &plotName, long colorIndex);
|
||||
void updateHeight();
|
||||
QScrollView *table;
|
||||
QWidget *form;
|
||||
QVBoxLayout *formVL;
|
||||
QGridLayout *formLayout;
|
||||
QPtrList<QLineEdit> names;
|
||||
QPtrList<QLineEdit> labels;
|
||||
QPtrList<QLineEdit> plots;
|
||||
QPtrList<ColorMenu> colors;
|
||||
int row;
|
||||
|
||||
};
|
||||
|
||||
|
601
sicsconn.cpp
Normal file
601
sicsconn.cpp
Normal file
@ -0,0 +1,601 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/select.h>
|
||||
#include <string.h>
|
||||
#include "sicsconn.h"
|
||||
#include "instr_hosts.h"
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
|
||||
|
||||
int printit(void);
|
||||
|
||||
int uselect(int nfds,
|
||||
fd_set * readfds, fd_set * writefds, fd_set * exceptfds,
|
||||
struct timeval *timeout)
|
||||
{
|
||||
|
||||
sigset_t sigmask;
|
||||
struct timespec tmo, *tmoPtr;
|
||||
int result;
|
||||
|
||||
sigfillset(&sigmask);
|
||||
if (timeout) {
|
||||
tmo.tv_sec = timeout->tv_sec;
|
||||
tmo.tv_nsec = timeout->tv_usec * 1000;
|
||||
tmoPtr = &tmo;
|
||||
} else {
|
||||
tmoPtr = NULL;
|
||||
}
|
||||
result = pselect(nfds, readfds, writefds, exceptfds, tmoPtr, &sigmask);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int sigpipe_ignored = 0;
|
||||
|
||||
int SicsSockAdr(struct sockaddr_in *sockaddr, const char *hostport,
|
||||
int defaultPort, const char *server) {
|
||||
// create sockadr from hostport (hostname and port number separated with colon)
|
||||
// hostport may also be an instrument name, in this case server has to be defined
|
||||
|
||||
struct hostent *hostent; /* Host database entry */
|
||||
struct in_addr addr; /* For 64/32 bit madness */
|
||||
char *p;
|
||||
char host[128], instr[32];
|
||||
int port;
|
||||
int l;
|
||||
|
||||
(void) memset((char *) sockaddr, '\0', sizeof(struct sockaddr_in));
|
||||
if (hostport == NULL) hostport="";
|
||||
p = strchr((char *)hostport, ':');
|
||||
if (p != NULL) {
|
||||
l = p - hostport;
|
||||
port = atoi(p+1);
|
||||
} else {
|
||||
InstrHost((char *)server, (char *)hostport, instr, sizeof instr,
|
||||
host, sizeof host, &port);
|
||||
if (port == 0) {
|
||||
port = atoi(hostport);
|
||||
if (port != 0) {
|
||||
l = 0;
|
||||
} else {
|
||||
l = strlen(hostport);
|
||||
}
|
||||
} else {
|
||||
l = -1;
|
||||
}
|
||||
}
|
||||
if (l>= 0) {
|
||||
if (l >= (int)sizeof host) return -1;
|
||||
strncpy(host, hostport, l);
|
||||
host[l]='\0';
|
||||
}
|
||||
if (port == 0) port = defaultPort;
|
||||
if (port == 0) return -1;
|
||||
|
||||
sockaddr->sin_family = AF_INET;
|
||||
sockaddr->sin_port = htons((unsigned short) (port & 0xFFFF));
|
||||
|
||||
if (host[0]=='\0') {
|
||||
addr.s_addr = INADDR_ANY;
|
||||
} else {
|
||||
hostent = gethostbyname(host);
|
||||
if (hostent != NULL) {
|
||||
memcpy((char *) &addr,
|
||||
(char *) hostent->h_addr_list[0], (size_t) hostent->h_length);
|
||||
} else {
|
||||
addr.s_addr = inet_addr(host);
|
||||
if (addr.s_addr == (unsigned long)-1) {
|
||||
return -1; /* error */
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* There is a rumor that this assignment may require care on
|
||||
* some 64 bit machines.
|
||||
*/
|
||||
sockaddr->sin_addr.s_addr = addr.s_addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SicsConnect(const char *hostport, const char *server, bool async) {
|
||||
struct sockaddr_in sadr;
|
||||
int iret, fd;
|
||||
int oldopts;
|
||||
|
||||
iret = SicsSockAdr(&sadr, hostport, 8641, server);
|
||||
if (iret < 0) return -1;
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0) return -1;
|
||||
if (async) {
|
||||
oldopts = fcntl(fd, F_GETFL, 0);
|
||||
fcntl(fd, F_SETFL, oldopts | O_NONBLOCK);
|
||||
}
|
||||
iret = connect(fd, (struct sockaddr *)&sadr, sizeof(sadr));
|
||||
if (iret < 0) {
|
||||
switch (errno) {
|
||||
case EINPROGRESS:
|
||||
case EALREADY:
|
||||
case EISCONN:
|
||||
return fd;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int SicsConnectSuccess(int fd)
|
||||
{
|
||||
// returns 1 on success, 0 when pending, -1 on error
|
||||
fd_set wmask, rmask;
|
||||
struct timeval tmo = { 0, 0 };
|
||||
int oldopts;
|
||||
int ret;
|
||||
|
||||
oldopts = fcntl(fd, F_GETFL, 0);
|
||||
assert(oldopts | O_NONBLOCK); /* fd must be in non-blocking mode */
|
||||
|
||||
FD_ZERO(&wmask);
|
||||
FD_ZERO(&rmask);
|
||||
FD_SET(fd, &wmask);
|
||||
FD_SET(fd, &rmask);
|
||||
ret = uselect(fd + 1, &rmask, &wmask, NULL, &tmo);
|
||||
if (ret > 0) {
|
||||
if (FD_ISSET(fd, &rmask)) { /* there may already be data for read */
|
||||
if (recv(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */
|
||||
ret = -1; /* first recv failed */
|
||||
}
|
||||
} else {
|
||||
if (FD_ISSET(fd,&wmask)) {
|
||||
if (send(fd, NULL, 0, 0) < 0) { /* zero length, check only return value */
|
||||
ret = -2; /* first send failed */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fcntl(fd, F_SETFL, oldopts & ~O_NONBLOCK); /* reset to blocking mode */
|
||||
return ret;
|
||||
}
|
||||
|
||||
SicsConnection::SicsConnection(QObject *parent) : QObject(parent) {
|
||||
hostport = NULL;
|
||||
userpass = NULL;
|
||||
server = NULL;
|
||||
state = disconnected;
|
||||
bufline = "";
|
||||
bufstate = buf_got_line;
|
||||
connect_state = connect_start;
|
||||
command2send = "";
|
||||
tmo = 0;
|
||||
if (!sigpipe_ignored) {
|
||||
signal (SIGPIPE, SIG_IGN);
|
||||
sigpipe_ignored = 1;
|
||||
}
|
||||
rdbuffer = "";
|
||||
progressPos = 0;
|
||||
rdpos = 0;
|
||||
debug = 0;
|
||||
}
|
||||
|
||||
//SicsConnection::SicsConnection(SicsConnection *copy) {
|
||||
// hostport = strdup(copy->hostport);
|
||||
// userpass = NULL;
|
||||
// state = disconnected;
|
||||
//}
|
||||
|
||||
SicsConnection::~SicsConnection() {
|
||||
if (state != disconnected) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
if (hostport) free(hostport);
|
||||
if (userpass) free(userpass);
|
||||
if (server) free(server);
|
||||
}
|
||||
|
||||
void SicsConnection::setHost(const char *hostport, const char *server) {
|
||||
if (this->hostport != NULL) free(this->hostport);
|
||||
if (hostport != NULL) {
|
||||
this->hostport = strdup(hostport);
|
||||
} else {
|
||||
this->hostport = NULL;
|
||||
}
|
||||
if (this->server != NULL) free(this->server);
|
||||
this->server = strdup(server);
|
||||
}
|
||||
|
||||
void SicsConnection::setUser(const char *userpass) {
|
||||
if (this->userpass != NULL) free(this->userpass);
|
||||
if (userpass != NULL) {
|
||||
this->userpass = strdup(userpass);
|
||||
} else {
|
||||
this->userpass = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int SicsConnection::handleBuffer(void) {
|
||||
return handleBuffer(0);
|
||||
}
|
||||
|
||||
int SicsConnection::handleBuffer(int tmo) {
|
||||
fd_set mask;
|
||||
struct timeval tmov;
|
||||
int iret = 1;
|
||||
int pos;
|
||||
char ch;
|
||||
char line[128];
|
||||
|
||||
switch (connect_state) {
|
||||
case connect_start:
|
||||
fd = SicsConnect(hostport, server, true);
|
||||
if (fd < 0) {
|
||||
connect_state = connect_error; // what else?
|
||||
return -1;
|
||||
}
|
||||
connect_state = connect_wait;
|
||||
return 0;
|
||||
case connect_wait:
|
||||
iret = SicsConnectSuccess(fd);
|
||||
if (iret <= 0) {
|
||||
if (startServer) {
|
||||
iret = system(startServer);
|
||||
if (iret) {
|
||||
printf("can not connect to sea and failed to start the sea server\n");
|
||||
printf("\n");
|
||||
pos = strcspn(hostport, ":");
|
||||
printf("please execute 'sea start' from the instrument account of %.*s\n", pos, hostport);
|
||||
printf("\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
iret = 1;
|
||||
}
|
||||
startServer = NULL;
|
||||
return iret;
|
||||
}
|
||||
connect_state = connect_login;
|
||||
return 0;
|
||||
case connect_login:
|
||||
if (userpass == NULL) {
|
||||
snprintf(line, sizeof line, "Spy 007\n");
|
||||
} else {
|
||||
snprintf(line, sizeof line, "%s", userpass);
|
||||
}
|
||||
bufstate = buf_sent_line;
|
||||
send(fd, line, strlen(line), 0);
|
||||
connect_state = connect_waitlogin;
|
||||
// if (strcmp(server, "sea") == 0 && userpass != NULL) {
|
||||
// printf("*** send login (%s %s)\n", server, line);
|
||||
// }
|
||||
return 0;
|
||||
case connect_error:
|
||||
return -2;
|
||||
default: break;
|
||||
}
|
||||
|
||||
FD_ZERO(&mask);
|
||||
while (bufstate > buf_got_finished) {
|
||||
do {
|
||||
FD_SET(fd, &mask);
|
||||
tmov.tv_sec = tmo;
|
||||
tmov.tv_usec = 0;
|
||||
iret = select(fd+1, &mask, NULL, NULL, &tmov);
|
||||
if (iret < 0) {
|
||||
perror("select");
|
||||
close(fd);
|
||||
fd = -1;
|
||||
connect_state = connect_error;
|
||||
state = disconnected;
|
||||
return -2;
|
||||
} else if (iret == 0) {
|
||||
return -1; /* no more data */
|
||||
}
|
||||
iret = recv(fd, &ch, 1, 0);
|
||||
if (iret <= 0) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
connect_state = connect_error;
|
||||
state = disconnected;
|
||||
if (printit()) printf("zero on receive -> disconnected\n");
|
||||
// printf("*** disconnected (zero on receive)\n");
|
||||
return -2;
|
||||
}
|
||||
bufline.append(ch);
|
||||
} while (ch != '\n');
|
||||
iret = 0;
|
||||
rdbuffer += bufline;
|
||||
if (debug) {
|
||||
// printf("%s bufline{%s}\n", debug, bufline.latin1());
|
||||
}
|
||||
if ((int)rdbuffer.length() >= progressPos + 1000) {
|
||||
progress(rdbuffer.length() - progressPos);
|
||||
progressPos = rdbuffer.length();
|
||||
}
|
||||
// if (strcmp(server, "sea") == 0 && userpass != NULL) {
|
||||
// printf("*** bufline %s", bufline.latin1());
|
||||
// }
|
||||
if (bufstate == buf_got_start && bufline.startsWith("TRANSACTIONFINISHED")) {
|
||||
bufstate = buf_got_finished;
|
||||
iret = 1;
|
||||
}
|
||||
if (bufstate == buf_sent_transact && bufline.startsWith("TRANSACTIONSTART")) {
|
||||
bufstate = buf_got_start;
|
||||
}
|
||||
if (bufstate == buf_sent_line) {
|
||||
bufstate = buf_got_line;
|
||||
if (connect_state == connect_waitlogin) {
|
||||
if (debug) {
|
||||
printf("connectlogin %s\n", bufline.latin1());
|
||||
}
|
||||
if (bufline.startsWith("Login OK\n")) {
|
||||
connect_state = connect_done;
|
||||
state = connected;
|
||||
if (command2send != "") {
|
||||
sendThis(command2send.latin1());
|
||||
command2send = "";
|
||||
if (state == disconnected) {
|
||||
return -1;
|
||||
}
|
||||
bufstate = buf_sent_transact;
|
||||
}
|
||||
} else {
|
||||
bufstate = buf_sent_line;
|
||||
}
|
||||
} else {
|
||||
iret = 1;
|
||||
}
|
||||
}
|
||||
bufline = "";
|
||||
}
|
||||
|
||||
return iret;
|
||||
}
|
||||
|
||||
int SicsConnection::getLine(QString &line) {
|
||||
QString qline;
|
||||
int pos, len;
|
||||
|
||||
if (state == disconnected) {
|
||||
return -1;
|
||||
}
|
||||
handleBuffer(0);
|
||||
if (rdpos >= (int)rdbuffer.length() && tmo > 0) {
|
||||
if (handleBuffer(tmo) < 0) {
|
||||
printf("timeout %d\n", tmo);
|
||||
}
|
||||
}
|
||||
if (rdpos < (long)rdbuffer.length()) {
|
||||
pos = rdbuffer.find('\n', rdpos);
|
||||
if (pos < rdpos) { // lf not found, return up to end of buffer (is this correct?)
|
||||
return 0; /***/
|
||||
len = rdbuffer.length() - rdpos;
|
||||
line = rdbuffer.mid(rdpos);
|
||||
progressPos -= rdbuffer.length();
|
||||
rdbuffer="";
|
||||
rdpos = 0;
|
||||
} else {
|
||||
len = pos - rdpos;
|
||||
line = rdbuffer.mid(rdpos,len);
|
||||
rdpos = pos + 1;
|
||||
//rdbuffer.remove(0, pos + 1);
|
||||
}
|
||||
if (debug) {
|
||||
//printf("%s getLine{%s}{%s}\n", debug, line.latin1(), rdbuffer.mid(rdpos,9).latin1());
|
||||
printf("%s getLine{%s}\n", debug, line.latin1());
|
||||
}
|
||||
if (line.startsWith("TRANSACTIONFINISHED")) {
|
||||
if (state == replying) {
|
||||
state = connected;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
} else {
|
||||
if (debug) {
|
||||
// printf("%s error\n", debug);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SicsConnection::swallow() {
|
||||
QString line;
|
||||
bool done;
|
||||
|
||||
if (debug) {
|
||||
printf("%s swallow start\n", debug);
|
||||
}
|
||||
while (state == replying) {
|
||||
if (getLine(line) > 0) {
|
||||
done = false;
|
||||
handle(line, &done);
|
||||
if (!done) {
|
||||
//printf("*** swallow {%s}\n", line);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (debug) {
|
||||
printf("%s swallow end\n", debug);
|
||||
}
|
||||
}
|
||||
|
||||
int SicsConnection::sendThis(const char *str) {
|
||||
int l, iret;
|
||||
if (state != disconnected) {
|
||||
l = strlen(str);
|
||||
// if (strcmp(server, "sea") == 0 && userpass != NULL) {
|
||||
// printf("*** send {%s}\n", str);
|
||||
// }
|
||||
iret = send(fd, str, l, 0);
|
||||
if (iret != l) {
|
||||
printf("sent %d of %d, disconnect\n", iret, l);
|
||||
close(fd);
|
||||
fd = -1;
|
||||
state = disconnected;
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SicsConnection::reconnect(void) {
|
||||
if (state != disconnected) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
state = disconnected;
|
||||
}
|
||||
connect_state = connect_start;
|
||||
command2send.sprintf("fulltransact config listen 1\n");
|
||||
}
|
||||
|
||||
void SicsConnection::disconnect(void) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
state = disconnected;
|
||||
}
|
||||
|
||||
int SicsConnection::sendCommand(const char *cmd) {
|
||||
char *nl;
|
||||
|
||||
if (debug) {
|
||||
printf("%s swallow before %s\n", debug, cmd);
|
||||
}
|
||||
swallow();
|
||||
if (debug) {
|
||||
printf("%s sendCommand %s\n", debug, cmd);
|
||||
}
|
||||
nl = strrchr((char *)cmd, '\n'); /* check if we have to add a final line break */
|
||||
if (nl == NULL || nl[1] != '\0') {
|
||||
command2send.sprintf("fulltransact %s\n", cmd);
|
||||
} else {
|
||||
command2send.sprintf("fulltransact %s", cmd);
|
||||
}
|
||||
|
||||
if (state == disconnected) {
|
||||
// printf("*** reconnect!\n");
|
||||
connect_state = connect_start;
|
||||
} else {
|
||||
sendThis(command2send.latin1());
|
||||
bufstate = buf_sent_transact;
|
||||
command2send = "";
|
||||
if (state == disconnected) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SicsConnection::getResponse() { // get BEGINNING of response
|
||||
int iret;
|
||||
QString line;
|
||||
|
||||
state = connected;
|
||||
tmo = 10;
|
||||
while (1) {
|
||||
iret = getLine(line);
|
||||
if (iret <= 0) {
|
||||
if (iret == -2) {
|
||||
if (printit()) printf("timeout on sea command\n");
|
||||
}
|
||||
//printf("error in getLine %d\n", iret);
|
||||
if (debug) {
|
||||
printf("%s error in getResponse {%s}\n", debug, rdbuffer.latin1() + rdpos);
|
||||
}
|
||||
return iret;
|
||||
}
|
||||
if (line.startsWith("TRANSACTIONSTART")) break;
|
||||
if (debug) {
|
||||
printf("%s getResponse handle %s\n", debug, line.latin1());
|
||||
}
|
||||
handle(line.latin1());
|
||||
};
|
||||
state = replying;
|
||||
if (debug) {
|
||||
printf("%s gotResponse\n", debug);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SicsConnection::command(const char *cmd) {
|
||||
int iret;
|
||||
int cnt, tries;
|
||||
|
||||
tries = 3;
|
||||
do {
|
||||
cnt = 5;
|
||||
while (cnt > 0 && (connect_state != connect_done || bufstate > buf_got_finished)) {
|
||||
handleBuffer(1);
|
||||
cnt--;
|
||||
}
|
||||
iret = sendCommand(cmd);
|
||||
handleBuffer(5);
|
||||
iret = getResponse();
|
||||
tries--;
|
||||
} while (iret < 0 && tries > 0);
|
||||
return iret;
|
||||
}
|
||||
|
||||
int SicsConnection::handleMessages(int tmoArg) {
|
||||
int iret;
|
||||
QString line;
|
||||
bool bs=false;
|
||||
|
||||
tmo = tmoArg;
|
||||
if (bufstate <= buf_got_finished) {
|
||||
bufstate = buf_sent_line;
|
||||
bs = true;
|
||||
}
|
||||
iret = getLine(line);
|
||||
tmo = 0;
|
||||
while (iret >= 0) {
|
||||
if (iret > 0) {
|
||||
handle(line.latin1());
|
||||
}
|
||||
iret = getLine(line);
|
||||
}
|
||||
if (bs && bufstate == buf_sent_line) {
|
||||
bufstate = buf_got_line;
|
||||
}
|
||||
return iret;
|
||||
}
|
||||
|
||||
#ifdef TESTSC
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void) {
|
||||
SicsConnection *sc;
|
||||
char line[256];
|
||||
char *lin;
|
||||
int iret;
|
||||
|
||||
sc = SicsNewConnection("lnsl15", 13006);
|
||||
if (sc == NULL) return -1;
|
||||
while (1) {
|
||||
printf("> ");
|
||||
lin = fgets(line, sizeof line, stdin);
|
||||
if (lin == NULL) return 1;
|
||||
iret = SicsCommand(sc, line);
|
||||
if (iret < 0) return 2;
|
||||
while (1) {
|
||||
iret = getLine(line);
|
||||
if (iret == 0) break;
|
||||
if (iret < 0) return 3;
|
||||
if (iret > 0) {
|
||||
printf("(%s)\n", line.latin1());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
72
sicsconn.h
Normal file
72
sicsconn.h
Normal file
@ -0,0 +1,72 @@
|
||||
#ifndef SICSCONN_H
|
||||
#define SICSCONN_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <qobject.h>
|
||||
|
||||
typedef enum { disconnected, connected, replying } ConnState;
|
||||
|
||||
class SicsConnection : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SicsConnection(QObject *parent);
|
||||
~SicsConnection();
|
||||
void setHost(const char *hostport, const char *server);
|
||||
void setUser(const char *userpass);
|
||||
int command(const char *cmd);
|
||||
/* send a command (and connect before, if necessary)
|
||||
return values: 1 on success
|
||||
-1 on error (no connection)
|
||||
0 on empty response (should not happen)
|
||||
*/
|
||||
|
||||
int sendCommand(const char *cmd);
|
||||
// send, but do not wait
|
||||
|
||||
int getResponse();
|
||||
// get beginning of response
|
||||
|
||||
int getLine(QString &line);
|
||||
/* get answer from command
|
||||
the return value is:
|
||||
- the number of characters read (excluding line break, but at least 1)
|
||||
- 0 when the response is at its end
|
||||
- negative on error
|
||||
*/
|
||||
int handleMessages(int tmo);
|
||||
/* handle pending messages */
|
||||
|
||||
int handleBuffer(int tmo);
|
||||
void swallow();
|
||||
char *debug;
|
||||
ConnState state;
|
||||
char *startServer = NULL;
|
||||
|
||||
signals:
|
||||
void handle(const char *line, bool *done = NULL);
|
||||
void reconnected(void);
|
||||
void progress(int bytes);
|
||||
|
||||
public slots:
|
||||
void reconnect(void);
|
||||
void disconnect(void);
|
||||
int handleBuffer(void);
|
||||
|
||||
private:
|
||||
int sendThis(const char *cmd);
|
||||
int fd;
|
||||
char *hostport;
|
||||
char *userpass;
|
||||
char *server;
|
||||
int tmo;
|
||||
enum {buf_got_line, buf_got_finished, buf_sent_line, buf_got_start, buf_sent_transact} bufstate;
|
||||
enum {connect_done, connect_start, connect_wait, connect_login, connect_waitlogin, connect_error} connect_state;
|
||||
QString command2send;
|
||||
QString bufline;
|
||||
QString rdbuffer;
|
||||
int rdpos;
|
||||
int progressPos;
|
||||
long tim;
|
||||
};
|
||||
|
||||
#endif
|
267
tab.cpp
Normal file
267
tab.cpp
Normal file
@ -0,0 +1,267 @@
|
||||
#include "tab.h"
|
||||
#include <unistd.h>
|
||||
#include <qapplication.h>
|
||||
#include <stdio.h>
|
||||
#include <qstring.h>
|
||||
#include <qregexp.h>
|
||||
#include <unistd.h>
|
||||
#include <qtimer.h>
|
||||
#include <qsizepolicy.h>
|
||||
#include <qdialog.h>
|
||||
#include <qtabbar.h>
|
||||
#include <qpainter.h>
|
||||
#include <qstyle.h>
|
||||
#include <qlayout.h>
|
||||
#include <assert.h>
|
||||
|
||||
enum {GRAPH, SETTINGS, DEVICE, COMMAND};
|
||||
|
||||
void Tab::checkSplit(SplitNo splitNo) {
|
||||
assert(widgetno == splitNo);
|
||||
widgetno++;
|
||||
}
|
||||
|
||||
//Tab::Tab(const char* instr, QWidget *parent, long range, const char *warning)
|
||||
// : QDialog(parent, "tab", false, Qt::WType_TopLevel | Qt::WStyle_Minimize)
|
||||
Tab::Tab(const char* instr, QWidget *parent, long range, const char *warning)
|
||||
: QMainWindow(parent, "tab", Qt::WType_TopLevel | Qt::WStyle_Minimize)
|
||||
{
|
||||
//QBoxLayout *vbox;
|
||||
QApplication::style().polish(this);
|
||||
|
||||
actFocus = -1;
|
||||
|
||||
//vbox = new QVBoxLayout(this, 0, 0, "vbx");
|
||||
split = new QSplitter(Qt::Horizontal, this);
|
||||
setCentralWidget(split);
|
||||
//vbox->addWidget(split);
|
||||
|
||||
widgetno = 0;
|
||||
leftWidgetNo = graph_split;
|
||||
rightWidgetNo = right_split;
|
||||
|
||||
graph = new Graph(instr, split, range);
|
||||
if (graph->set == NULL) {
|
||||
graph = NULL;
|
||||
return;
|
||||
}
|
||||
checkSplit(graph_split);
|
||||
|
||||
graph->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, 1, 1));
|
||||
connect(graph, SIGNAL(gotoSettings()), this, SLOT(gotoSettings()));
|
||||
settings = new Settings(split);
|
||||
settings->set = graph->set;
|
||||
connect(settings, SIGNAL(leaveSettings()),
|
||||
this, SLOT(leaveSettings()));
|
||||
settings->hide();
|
||||
checkSplit(settings_split);
|
||||
|
||||
rightSplit = new QSplitter(Qt::Vertical, split, "rightSplit");
|
||||
rightSplit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, 1, 1));
|
||||
checkSplit(right_split);
|
||||
|
||||
if (warning[0]) {
|
||||
foreignwarn = new QVBox(rightSplit);
|
||||
warnlabel = new QLabel(warning, foreignwarn);
|
||||
showparbutton = new QPushButton("show parameters", foreignwarn);
|
||||
QSize siz = foreignwarn->minimumSizeHint();
|
||||
foreignwarn->setFixedHeight(siz.height());
|
||||
warnlabel->setEraseColor(QColor(255,127,0));
|
||||
}
|
||||
|
||||
device = new Device(rightSplit);
|
||||
if (warning[0]) {
|
||||
device->hide();
|
||||
connect(showparbutton, SIGNAL(clicked()), this, SLOT(showPars()));
|
||||
}
|
||||
|
||||
command = new Command(rightSplit, "Command", graph->set->uc);
|
||||
connect(command->cmd, SIGNAL(returnPressed()), device, SLOT(update()));
|
||||
connect(command, SIGNAL(activate()), device, SLOT(activate()));
|
||||
device->init(command, graph->set);
|
||||
|
||||
QTimer *timer = new QTimer(this, "repeat");
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(handler()));
|
||||
timer->start(100);
|
||||
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
|
||||
|
||||
exportXY = new Export(graph->set, split, instr);
|
||||
exportXY->hide();
|
||||
exportXY->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, 1, 1));
|
||||
connect(exportXY, SIGNAL(finish()), this, SLOT(finishExport()));
|
||||
connect(graph, SIGNAL(openExport()), this, SLOT(openExport()));
|
||||
connect(graph->set, SIGNAL(updateCurveList()), exportXY, SLOT(updateCurveList()));
|
||||
checkSplit(export_split);
|
||||
|
||||
report = new Report(split, graph->set->ec);
|
||||
report->hide();
|
||||
checkSplit(report_split);
|
||||
connect(report, SIGNAL(leave()), this, SLOT(leaveReport()));
|
||||
connect(report, SIGNAL(openMe()), this, SLOT(openReport()));
|
||||
|
||||
message = new QLabel(split);
|
||||
message->hide();
|
||||
|
||||
for (int i = 0; i < 2 * 3; i++) {
|
||||
oldSizes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Tab::shown(QWidget *w) {
|
||||
return w->isShown() && w->width() > 3 && w->height() > 3;
|
||||
}
|
||||
|
||||
void Tab::showPars() {
|
||||
QValueList<int> splitsizes;
|
||||
int h;
|
||||
|
||||
showparbutton->hide();
|
||||
QSize siz = warnlabel->minimumSizeHint();
|
||||
foreignwarn->setFixedHeight(siz.height());
|
||||
device->show();
|
||||
splitsizes = rightSplit->sizes();
|
||||
h = (splitsizes[1] + splitsizes[2]) / 2;
|
||||
splitsizes[1] = h;
|
||||
splitsizes[2] = h;
|
||||
rightSplit->setSizes(splitsizes);
|
||||
device->update();
|
||||
}
|
||||
|
||||
bool Tab::splitChange(SplitNo splitNo) {
|
||||
int lw = 0, rw = 0;
|
||||
int i;
|
||||
int tot;
|
||||
float s;
|
||||
|
||||
sizes = split->sizes();
|
||||
lw = sizes[leftWidgetNo];
|
||||
rw = sizes[rightWidgetNo];
|
||||
i = leftWidgetNo + 2 * (rightWidgetNo - right_split);
|
||||
if (splitNo < right_split) {
|
||||
if (splitNo == leftWidgetNo) return FALSE;
|
||||
leftWidgetNo = splitNo;
|
||||
} else {
|
||||
if (splitNo == rightWidgetNo) return FALSE;
|
||||
rightWidgetNo = splitNo;
|
||||
}
|
||||
tot = lw + rw;
|
||||
if (rw > 1 && lw > 1) {
|
||||
oldSizes[i] = lw / float(tot);
|
||||
}
|
||||
s = oldSizes[leftWidgetNo + 2 * (rightWidgetNo - right_split)];
|
||||
if (s != 0) {
|
||||
lw = s * tot + 0.5;
|
||||
rw = tot - lw;
|
||||
}
|
||||
for (i = 0; i < n_split; i++) {
|
||||
sizes[i] = 0;
|
||||
}
|
||||
sizes[leftWidgetNo] = lw;
|
||||
sizes[rightWidgetNo] = rw;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void Tab::gotoSettings() {
|
||||
if (splitChange(settings_split)) {
|
||||
graph->showIt(false);
|
||||
settings->showIt(true);
|
||||
split->setSizes(sizes);
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::leaveSettings() {
|
||||
if (splitChange(graph_split)) {
|
||||
settings->showIt(false);
|
||||
graph->showIt(true);
|
||||
}
|
||||
split->setSizes(sizes);
|
||||
}
|
||||
|
||||
void Tab::openExport() {
|
||||
if (splitChange(export_split)) {
|
||||
rightSplit->hide();
|
||||
exportXY->showMe();
|
||||
split->setSizes(sizes);
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::finishExport() {
|
||||
if (splitChange(right_split)) {
|
||||
exportXY->hide();
|
||||
rightSplit->show();
|
||||
split->setSizes(sizes);
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::openReport() {
|
||||
if (splitChange(report_split)) {
|
||||
rightSplit->hide();
|
||||
report->show();
|
||||
split->setSizes(sizes);
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::leaveReport() {
|
||||
if (splitChange(right_split)) {
|
||||
report->hide();
|
||||
rightSplit->show();
|
||||
split->setSizes(sizes);
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::sleep(const char *text) {
|
||||
graph->hide();
|
||||
rightSplit->hide();
|
||||
message->setText(text);
|
||||
message->show();
|
||||
}
|
||||
|
||||
void Tab::wake() {
|
||||
graph->show();
|
||||
rightSplit->show();
|
||||
exportXY->hide();
|
||||
report->hide();
|
||||
message->hide();
|
||||
graph->set->sc->disconnect();
|
||||
graph->set->uc->disconnect();
|
||||
graph->set->gc->disconnect();
|
||||
graph->set->ec->disconnect();
|
||||
graph->set->sc->reconnect();
|
||||
/* uc is connected automatically with sc */
|
||||
graph->set->gc->reconnect();
|
||||
graph->set->ec->reconnect();
|
||||
}
|
||||
|
||||
void Tab::initSize(int w, int h) {
|
||||
QSize qs = QSize(w, h).expandedTo(split->minimumSizeHint());
|
||||
resize(qs);
|
||||
sizes = split->sizes();
|
||||
sizes[0] = w/2;
|
||||
sizes[2] = w/2;
|
||||
split->setSizes(sizes);
|
||||
}
|
||||
|
||||
void Tab::handler() {
|
||||
command->handler();
|
||||
if (shown(command) && command->cmd->hasFocus()) {
|
||||
actFocus = COMMAND;
|
||||
}
|
||||
if (shown(graph) && graph->lineEditRange->hasFocus()) {
|
||||
actFocus = GRAPH;
|
||||
}
|
||||
if (!shown(settings) && !shown(device)) {
|
||||
if (actFocus == COMMAND) {
|
||||
command->cmd->setFocus();
|
||||
} else {
|
||||
if (!graph->lineEditRange->hasFocus()) {
|
||||
graph->lineEditRange->setFocus();
|
||||
graph->lineEditRange->lineEdit()->selectAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::resizeEvent(QResizeEvent *e) {
|
||||
//QDialog::resizeEvent(e);
|
||||
QMainWindow::resizeEvent(e);
|
||||
}
|
64
tab.h
Normal file
64
tab.h
Normal file
@ -0,0 +1,64 @@
|
||||
#include <stddef.h>
|
||||
#include <qprocess.h>
|
||||
#include <qstring.h>
|
||||
#include <qvbox.h>
|
||||
#include <qbutton.h>
|
||||
#include <qmainwindow.h>
|
||||
#include "graph.h"
|
||||
#include "settings.h"
|
||||
#include "device.h"
|
||||
#include "export.h"
|
||||
#include "report.h"
|
||||
|
||||
//class Tab : public QDialog
|
||||
class Tab : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Tab(const char* instr, QWidget *parent, long range, const char *fromInstr);
|
||||
void initSize(int w, int h);
|
||||
void sleep(const char *text);
|
||||
void wake();
|
||||
|
||||
Graph *graph;
|
||||
Settings *settings;
|
||||
Command *command;
|
||||
Device *device;
|
||||
Export *exportXY;
|
||||
Report *report;
|
||||
QSplitter *split;
|
||||
QSplitter *rightSplit;
|
||||
QLabel *message;
|
||||
QVBox *foreignwarn;
|
||||
QPushButton *showparbutton;
|
||||
QLabel *warnlabel;
|
||||
|
||||
public slots:
|
||||
void leaveSettings();
|
||||
void gotoSettings();
|
||||
void handler();
|
||||
void openExport();
|
||||
void finishExport();
|
||||
void openReport();
|
||||
void leaveReport();
|
||||
void showPars();
|
||||
|
||||
signals:
|
||||
void restart();
|
||||
|
||||
private:
|
||||
int actFocus;
|
||||
int watchSocket;
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
bool shown(QWidget *w);
|
||||
|
||||
enum SplitNo {graph_split, settings_split, right_split, export_split, report_split, n_split};
|
||||
|
||||
void checkSplit(SplitNo splitNo);
|
||||
bool splitChange(SplitNo splitNo);
|
||||
|
||||
int widgetno;
|
||||
float oldSizes[2*3];
|
||||
SplitNo leftWidgetNo, rightWidgetNo;
|
||||
QValueList<int> sizes;
|
||||
};
|
462
utils.cpp
Normal file
462
utils.cpp
Normal file
@ -0,0 +1,462 @@
|
||||
#include "utils.h"
|
||||
#include <qpixmap.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <assert.h>
|
||||
|
||||
void SetEraseColor(QWidget *widget, QWidget *from, bool inclBgr) {
|
||||
const QPixmap *p;
|
||||
p = from->erasePixmap();
|
||||
if (p) {
|
||||
widget->setErasePixmap(*p);
|
||||
if (inclBgr) {
|
||||
widget->setPaletteBackgroundPixmap(*p);
|
||||
}
|
||||
} else {
|
||||
widget->setEraseColor(from->eraseColor());
|
||||
if (inclBgr) {
|
||||
widget->setPaletteBackgroundColor(from->eraseColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FlatButton::FlatButton(const QString &label, QWidget *parent, const char *name)
|
||||
: QLabel(label, parent, name) {
|
||||
x = -1;
|
||||
}
|
||||
|
||||
void FlatButton::mousePressEvent(QMouseEvent *e) {
|
||||
x = e->x();
|
||||
y = e->y();
|
||||
mousePressed();
|
||||
}
|
||||
|
||||
void FlatButton::mouseReleaseEvent(QMouseEvent *e) {
|
||||
if (x >= 0 && abs(e->x() - x) + abs(e->y() - y) < 5) {
|
||||
clicked();
|
||||
}
|
||||
x = -1;
|
||||
}
|
||||
|
||||
void ShrinkButton(QPushButton *b) {
|
||||
int margin;
|
||||
QString text(b->text());
|
||||
b->setText("This is a long text");
|
||||
margin = b->sizeHint().width() - b->fontMetrics().width(b->text());
|
||||
b->setText(text);
|
||||
b->setFixedWidth(b->fontMetrics().width(text) + margin);
|
||||
}
|
||||
|
||||
double DoubleTime(void)
|
||||
{
|
||||
struct timeval now;
|
||||
/* the resolution of this function is usec, if the machine supports this
|
||||
and the mantissa of a double is 51 bits or more (31 for sec and 20 for milliseconds)
|
||||
*/
|
||||
gettimeofday(&now, NULL);
|
||||
return now.tv_sec + now.tv_usec / 1e6;
|
||||
}
|
||||
|
||||
static char *coltab[N_SEACOLORS*2] = {
|
||||
"X c #FFFFFF", "white",
|
||||
"X c #FF0000", "red",
|
||||
"X c #00FF00", "lime", // was green
|
||||
"X c #0000FF", "blue",
|
||||
"X c #FF00FF", "magenta", // fuchsia
|
||||
"X c #FFFF00", "yellow",
|
||||
"X c #00FFFF", "cyan", // aqua
|
||||
"X c #000000", "black",
|
||||
"X c #FFA500", "orange",
|
||||
"X c #006400", "dark_green",
|
||||
"X c #9400D3", "dark_violet",
|
||||
"X c #A52A2A", "brown",
|
||||
"X c #87CEEB", "sky_blue",
|
||||
"X c #808080", "gray",
|
||||
"X c #FF69B4", "hot_pink",
|
||||
"X c #FFFFE0", "light_yellow",
|
||||
"X c #00FF7F", "spring_green",
|
||||
"X c #000080", "navy",
|
||||
"X c #1E90FF", "dodger_blue",
|
||||
"X c #9ACD32", "yellow_green",
|
||||
"X c #008B8B", "dark_cyan",
|
||||
"X c #808000", "olive",
|
||||
"X c #DEB887", "burly_wood",
|
||||
"X c #7B68EE", "medium_slate_blue",
|
||||
"X c #483D8B", "dark_slate_blue",
|
||||
"X c #98FB98", "pale_green",
|
||||
"X c #FF1493", "deep_pink",
|
||||
"X c #FF6347", "tomato",
|
||||
"X c #32CD32", "lime_green",
|
||||
"X c #DDA0DD", "plum",
|
||||
"X c #7FFF00", "chartreuse",
|
||||
"X c #800080", "purple",
|
||||
"X c #00CED1", "dark_turquoise",
|
||||
"X c #8FBC8F", "dark_sea_green",
|
||||
"X c #4682B4", "steel_blue",
|
||||
"X c #800000", "maroon",
|
||||
"X c #3CB371", "medium_sea_green",
|
||||
"X c #FF4500", "orange_red",
|
||||
"X c #BA55D3", "medium_orchid",
|
||||
"X c #2F4F4F", "dark_slate_gray",
|
||||
"X c #CD853F", "peru",
|
||||
"X c #228B22", "forest_green",
|
||||
"X c #48D1CC", "medium_turquoise",
|
||||
"X c #DC143C", "crimson",
|
||||
"X c #D3D3D3", "light_gray",
|
||||
"X c #ADFF2F", "green_yellow",
|
||||
"X c #7FFFD4", "aquamarine",
|
||||
"X c #BC8F8F", "rosy_brown",
|
||||
"X c #20B2AA", "light_sea_green",
|
||||
"X c #C71585", "medium_violet_red",
|
||||
"X c #F0E68C", "khaki",
|
||||
"X c #6495ED", "cornflower_blue",
|
||||
"X c #556B2F", "dark_olive_green",
|
||||
"X c #CD5C5C", "indian_red",
|
||||
"X c #2E8B57", "sea_green",
|
||||
"X c #F08080", "light_coral",
|
||||
"X c #8A2BE2", "blue_violet",
|
||||
"X c #AFEEEE", "pale_turquoise",
|
||||
"X c #4169E1", "royal_blue",
|
||||
"X c #0000CD", "medium_blue",
|
||||
"X c #B8860B", "dark_goldenrod",
|
||||
"X c #00BFFF", "deep_sky_blue",
|
||||
"X c #FFC0CB", "pink",
|
||||
"X c #4B0082", "indigo",
|
||||
"X c #A0522D", "sienna",
|
||||
"X c #FFD700", "gold",
|
||||
"X c #F4A460", "sandy_brown",
|
||||
"X c #DAA520", "goldenrod",
|
||||
"X c #DA70D6", "orchid",
|
||||
"X c #E6E6FA", "lavender",
|
||||
"X c #5F9EA0", "cadet_blue",
|
||||
"X c #D2691E", "chocolate",
|
||||
"X c #66CDAA", "medium_aquamarine",
|
||||
"X c #6B8E23", "olive_drab",
|
||||
"X c #A9A9A9", "dark_gray",
|
||||
"X c #BDB76B", "dark_khaki",
|
||||
"X c #696969", "dim_gray",
|
||||
"X c #B0C4DE", "light_steel_blue",
|
||||
"X c #191970", "midnight_blue",
|
||||
"X c #FFE4C4", "bisque",
|
||||
"X c #6A5ACD", "slate_blue",
|
||||
"X c #EE82EE", "violet",
|
||||
"X c #8B4513", "saddle_brown",
|
||||
"X c #FF7F50", "coral",
|
||||
"X c #008000", "mid_green",
|
||||
"X c #DB7093", "pale_violet_red",
|
||||
"X c #C0C0C0", "silver",
|
||||
"X c #E0FFFF", "light_cyan",
|
||||
"X c #9370DB", "medium_purple",
|
||||
"X c #FF8C00", "dark_orange",
|
||||
"X c #00FA9A", "medium_spring_green",
|
||||
"X c #E9967A", "dark_salmon",
|
||||
"X c #778899", "light_slate_gray",
|
||||
"X c #9932CC", "dark_orchid",
|
||||
"X c #EEE8AA", "pale_goldenrod",
|
||||
"X c #F8F8FF", "ghost_white",
|
||||
"X c #FFA07A", "light_salmon",
|
||||
"X c #ADD8E6", "light_blue",
|
||||
"X c #D8BFD8", "thistle",
|
||||
"X c #FFE4E1", "misty_rose",
|
||||
"X c #FFDEAD", "navajo_white",
|
||||
"X c #40E0D0", "turquoise",
|
||||
"X c #90EE90", "light_green",
|
||||
"X c #B22222", "fire_brick",
|
||||
"X c #008080", "teal",
|
||||
"X c #F0FFF0", "honeydew",
|
||||
"X c #FFFACD", "lemon_chiffon",
|
||||
"X c #FFF5EE", "seashell",
|
||||
"X c #F5F5DC", "beige",
|
||||
"X c #DCDCDC", "gainsboro",
|
||||
"X c #FA8072", "salmon",
|
||||
"X c #8B008B", "dark_magenta",
|
||||
"X c #FFB6C1", "light_pink",
|
||||
"X c #708090", "slate_gray",
|
||||
"X c #87CEFA", "light_sky_blue",
|
||||
"X c #FFEFD5", "papaya_whip",
|
||||
"X c #D2B48C", "tan",
|
||||
"X c #FFFFF0", "ivory",
|
||||
"X c #F0FFFF", "azure",
|
||||
"X c #F5DEB3", "wheat",
|
||||
"X c #00008B", "dark_blue",
|
||||
"X c #FFDAB9", "peach_puff",
|
||||
"X c #8B0000", "dark_red",
|
||||
"X c #FAF0E6", "linen",
|
||||
"X c #B0E0E6", "powder_blue",
|
||||
"X c #FFE4B5", "moccasin",
|
||||
"X c #F5F5F5", "white_smoke",
|
||||
"X c #FFF8DC", "cornsilk",
|
||||
"X c #FFFAFA", "snow",
|
||||
"X c #FFF0F5", "lavender_blush",
|
||||
"X c #FFEBCD", "blanched_almond",
|
||||
"X c #F0F8FF", "alice_blue",
|
||||
"X c #FAEBD7", "antique_white",
|
||||
"X c #FDF5E6", "old_lace",
|
||||
"X c #FAFAD2", "light_goldenrod_yellow",
|
||||
"X c #F5FFFA", "mint_cream",
|
||||
"X c #FFFAF0", "floral_white",
|
||||
"X c #7CFC00", "lawn_green"
|
||||
};
|
||||
|
||||
static long seaColors[N_SEACOLORS]={0};
|
||||
|
||||
static void getRGB(long i, long &r, long &g, long &b) {
|
||||
long code;
|
||||
char *k;
|
||||
|
||||
if (i >= 0x1000000 && i < 0x2000000) {
|
||||
code = i - 0x1000000;
|
||||
} else {
|
||||
if (i < 0 || i >= N_SEACOLORS) {
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
return;
|
||||
}
|
||||
if (seaColors[i] == 0) {
|
||||
k = strchr(coltab[i*2], '#');
|
||||
if (k) {
|
||||
seaColors[i] = strtol(k+1, NULL, 16);
|
||||
}
|
||||
}
|
||||
code = seaColors[i];
|
||||
}
|
||||
b = code % 256; code = code / 256;
|
||||
g = code % 256; code = code / 256;
|
||||
r = code % 256;
|
||||
}
|
||||
|
||||
QPen thisPen(long i, int w) {
|
||||
long r,g,b;
|
||||
|
||||
getRGB(i, r, g, b);
|
||||
if (w == 0) {
|
||||
w = (3 * r + 5 * g + b) / 460; /* make pen larger for bright colors, 0 <= w <= 4 */
|
||||
if (w < 2) {
|
||||
w = 2;
|
||||
}
|
||||
}
|
||||
return QPen(QColor(r,g,b), w, Qt::SolidLine, Qt::FlatCap, Qt::BevelJoin);
|
||||
};
|
||||
|
||||
static const char *miniPix[] = {
|
||||
"1 1 1 1",
|
||||
" c None",
|
||||
" "
|
||||
};
|
||||
|
||||
|
||||
// the following routine is for a color widget
|
||||
const QPixmap *thisPixmap(long i, int w) {
|
||||
char *penpix[3+11];
|
||||
long l, j, k;
|
||||
|
||||
if (i < 0) {
|
||||
return new QPixmap(miniPix);
|
||||
}
|
||||
if (i >= N_SEACOLORS) {
|
||||
return NULL;
|
||||
}
|
||||
l = thisPen(i, w).width();
|
||||
if (l > 11) l = 11;
|
||||
penpix[0] = "20 11 2 1";
|
||||
penpix[1] = coltab[i*2];
|
||||
penpix[2] = " c None";
|
||||
k = (11 - l) / 2;
|
||||
for (j = 0; j < k; j++) {
|
||||
penpix[j+3] = " ";
|
||||
}
|
||||
for (j = k; j < k + l; j++) {
|
||||
penpix[j+3] = "XXXXXXXXXXXXXXXXXXXX";
|
||||
}
|
||||
for (j = k + l; j < 11; j++) {
|
||||
penpix[j+3] = " ";
|
||||
}
|
||||
return new QPixmap((const char **)penpix);
|
||||
};
|
||||
|
||||
long Convert2ColorIndex(const QString &color) {
|
||||
QString s=color.stripWhiteSpace();
|
||||
long rgb;
|
||||
bool ok;
|
||||
long r,g,b,rr,gg,bb,d;
|
||||
long dist;
|
||||
long index;
|
||||
long i;
|
||||
const char *ccol;
|
||||
|
||||
if (s[0] == '#') { // hexadecimal color
|
||||
s.remove(0,1);
|
||||
rgb = s.toLong(&ok, 16);
|
||||
if (!ok) {
|
||||
return -2;
|
||||
}
|
||||
if (s.length() == 3) { // short form: find closest index
|
||||
bb = rgb % 16 * 17; rgb = rgb / 16;
|
||||
gg = rgb % 16 * 17; rgb = rgb / 16;
|
||||
rr = rgb % 16 * 17;
|
||||
dist = 9999999;
|
||||
index = -2;
|
||||
for (i = 0; i < N_SEACOLORS; i++) {
|
||||
getRGB(i, r, g, b);
|
||||
r -= rr;
|
||||
g -= gg;
|
||||
b -= bb;
|
||||
d = 5*r*r + 8*g*g + 5*b*b;
|
||||
if (d < dist) {
|
||||
dist = d;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
} else if (s.length() == 6) { // long form: keep rgb code
|
||||
index = 0x1000000 + rgb;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
index = s.toLong(&ok);
|
||||
if (ok) { // color index
|
||||
return index;
|
||||
}
|
||||
i = s.find("grey");
|
||||
if (i >= 0) {
|
||||
s.replace(i+2, 1, "a");
|
||||
}
|
||||
ccol = s.latin1();
|
||||
if (strcasecmp(ccol, "auto") == 0) {
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < N_SEACOLORS; i++) {
|
||||
if (strcasecmp(coltab[i*2+1], ccol) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (strcasecmp(ccol, "green") == 0) {
|
||||
return 2;
|
||||
}
|
||||
if (strcasecmp(ccol, "fuchsia") == 0) {
|
||||
return 4;
|
||||
}
|
||||
if (strcasecmp(ccol, "aqua") == 0) {
|
||||
return 6;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
bool Convert2ColorName(long i, QString &result) {
|
||||
if (i >= 0x1000000 && i < 0x2000000) {
|
||||
result.sprintf("#%6.6lX", i - 0x1000000);
|
||||
return true;
|
||||
}
|
||||
if (i < 0 || i >= N_SEACOLORS) {
|
||||
result = "auto";
|
||||
return false;
|
||||
} else {
|
||||
result = coltab[i*2+1];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
QString toRichText(QString &txt, bool *finished) {
|
||||
QString result("");
|
||||
QChar ch;
|
||||
int i, l;
|
||||
bool wasspace;
|
||||
|
||||
if (txt == "" || txt == " ") {
|
||||
return " ";
|
||||
}
|
||||
l = txt.length();
|
||||
wasspace = true;
|
||||
for (i = 0; i < l; i++) {
|
||||
ch = txt[i];
|
||||
if (ch == ' ') {
|
||||
if (wasspace) {
|
||||
result.append(" ");
|
||||
} else {
|
||||
result.append(' ');
|
||||
wasspace = true;
|
||||
}
|
||||
} else {
|
||||
wasspace = false;
|
||||
if (ch == '&') {
|
||||
result.append("&");
|
||||
} else if (ch == '<') {
|
||||
result.append("<");
|
||||
} else {
|
||||
result.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MyTextEdit::MyTextEdit(QWidget * parent, const char *name) : QTextEdit(parent, name)
|
||||
{
|
||||
QFont monospace("Courier");
|
||||
|
||||
setTextFormat(Qt::RichText);
|
||||
setWordWrap(QTextEdit::WidgetWidth);
|
||||
setWrapPolicy(QTextEdit::Anywhere);
|
||||
monospace.setStyleHint(QFont::TypeWriter);
|
||||
setFont(monospace);
|
||||
linebuffer = "";
|
||||
buffered = false;
|
||||
buffer = QStringList();
|
||||
}
|
||||
|
||||
void MyTextEdit::appendHtml(QString text) {
|
||||
linebuffer.append(text);
|
||||
}
|
||||
|
||||
void MyTextEdit::setBuffered(bool arg) {
|
||||
if (buffered) {
|
||||
hide();
|
||||
for (QStringList::Iterator it = buffer.begin(); it != buffer.end(); ++it ) {
|
||||
append(*it);
|
||||
}
|
||||
show();
|
||||
buffer.clear();
|
||||
}
|
||||
buffered = arg;
|
||||
}
|
||||
|
||||
void MyTextEdit::appendText(QString text) {
|
||||
QChar ch;
|
||||
int i, l;
|
||||
bool wasspace;
|
||||
|
||||
l = text.length();
|
||||
wasspace = true;
|
||||
for (i = 0; i < l; i++) {
|
||||
ch = text[i];
|
||||
if (ch == ' ') {
|
||||
if (wasspace) {
|
||||
linebuffer.append(" ");
|
||||
} else {
|
||||
linebuffer.append(' ');
|
||||
wasspace = true;
|
||||
}
|
||||
} else {
|
||||
wasspace = false;
|
||||
if (ch == '\n') {
|
||||
if (linebuffer == "" || linebuffer == " ") {
|
||||
linebuffer="<br>";
|
||||
}
|
||||
if (buffered) {
|
||||
buffer.append(linebuffer);
|
||||
} else {
|
||||
append(linebuffer);
|
||||
}
|
||||
linebuffer = "";
|
||||
} else if (ch == '&') {
|
||||
linebuffer.append("&");
|
||||
} else if (ch == '<') {
|
||||
linebuffer.append("<");
|
||||
} else {
|
||||
linebuffer.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
59
utils.h
Normal file
59
utils.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qlabel.h>
|
||||
#include <qstring.h>
|
||||
#include <qstringlist.h>
|
||||
#include <qtextedit.h>
|
||||
#include <qevent.h>
|
||||
#include <qpixmap.h>
|
||||
#include <qpen.h>
|
||||
|
||||
#define N_SEACOLORS 138
|
||||
|
||||
class FlatButton: public QLabel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FlatButton(const QString &label, QWidget *parent, const char *name=0);
|
||||
signals:
|
||||
void clicked();
|
||||
void mousePressed();
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
private:
|
||||
int x, y;
|
||||
};
|
||||
|
||||
void ShrinkButton(QPushButton *b);
|
||||
void SetEraseColor(QWidget *widget, QWidget *from, bool inclBgr = false);
|
||||
|
||||
double DoubleTime(void);
|
||||
|
||||
QPen thisPen(long i, int w = 0);
|
||||
|
||||
const QPixmap *thisPixmap(long i, int w = 0);
|
||||
|
||||
long Convert2ColorIndex(const QString &color);
|
||||
|
||||
bool Convert2ColorName(long i, QString &result);
|
||||
|
||||
// my own textedit, making paragraphs for newlines, but with single line spacing
|
||||
class MyTextEdit: public QTextEdit {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MyTextEdit(QWidget * parent, const char *name=0);
|
||||
void appendHtml(QString text);
|
||||
void appendText(QString text);
|
||||
void setBuffered(bool arg);
|
||||
private:
|
||||
bool buffered;
|
||||
QString linebuffer;
|
||||
QStringList buffer;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user