Files
seaclient/command.cpp

352 lines
8.4 KiB
C++

#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;
}