352 lines
8.4 KiB
C++
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;
|
|
}
|