365 lines
11 KiB
C++
365 lines
11 KiB
C++
#include "scriptingwindow.h"
|
|
#include "ui_scriptingwindow.h"
|
|
|
|
#include <QFile>
|
|
#include <QFileDialog>
|
|
#include <QSettings>
|
|
|
|
#include "connections/canconmanager.h"
|
|
#include "helpwindow.h"
|
|
|
|
ScriptingWindow::ScriptingWindow(const QVector<CANFrame> *frames, QWidget *parent) :
|
|
QDialog(parent),
|
|
ui(new Ui::ScriptingWindow)
|
|
{
|
|
ui->setupUi(this);
|
|
|
|
editor = new JSEdit();
|
|
editor->setFrameShape(JSEdit::NoFrame);
|
|
editor->setWordWrapMode(QTextOption::NoWrap);
|
|
editor->setTabStopWidth(4);
|
|
editor->setEnabled(false);
|
|
editor->setFont(QFont("Monospace", 12));
|
|
editor->show();
|
|
ui->verticalLayout->insertWidget(2,editor, 10);
|
|
|
|
readSettings();
|
|
|
|
modelFrames = frames;
|
|
|
|
connect(ui->btnLoadScript, &QAbstractButton::pressed, this, &ScriptingWindow::loadNewScript);
|
|
connect(ui->btnNewScript, &QAbstractButton::pressed, this, &ScriptingWindow::createNewScript);
|
|
connect(ui->btnRecompile, &QAbstractButton::pressed, this, &ScriptingWindow::recompileScript);
|
|
connect(ui->btnRemoveScript, &QAbstractButton::pressed, this, &ScriptingWindow::deleteCurrentScript);
|
|
connect(ui->btnRevertScript, &QAbstractButton::pressed, this, &ScriptingWindow::revertScript);
|
|
connect(ui->btnSaveScript, &QAbstractButton::pressed, this, &ScriptingWindow::saveScript);
|
|
connect(ui->btnClearLog, &QAbstractButton::pressed, this, &ScriptingWindow::clickedLogClear);
|
|
connect(ui->listLoadedScripts, &QListWidget::currentRowChanged, this, &ScriptingWindow::changeCurrentScript);
|
|
connect(ui->tableVariables, SIGNAL(cellChanged(int,int)), this, SLOT(updatedValue(int, int)));
|
|
|
|
connect(CANConManager::getInstance(), &CANConManager::framesReceived, this, &ScriptingWindow::newFrames);
|
|
|
|
connect(&valuesTimer, SIGNAL(timeout()), this, SLOT(valuesTimerElapsed()));
|
|
|
|
currentScript = NULL;
|
|
|
|
elapsedTime.start();
|
|
valuesTimer.start(1000);
|
|
|
|
ui->tableVariables->insertColumn(0);
|
|
ui->tableVariables->insertColumn(1);
|
|
}
|
|
|
|
ScriptingWindow::~ScriptingWindow()
|
|
{
|
|
delete editor;
|
|
delete ui;
|
|
}
|
|
|
|
|
|
void ScriptingWindow::newFrames(const CANConnection* pConn, const QVector<CANFrame>& pFrames)
|
|
{
|
|
/*FIXME: name of the probe and bus should be checked */
|
|
Q_UNUSED(pConn);
|
|
Q_UNUSED(pFrames);
|
|
|
|
/*for (int j = 0; j < scripts.length(); j++)
|
|
{
|
|
foreach(const CANFrame& frame, pFrames)
|
|
{
|
|
//scripts[j]->gotFrame(frame);
|
|
}
|
|
}*/
|
|
}
|
|
|
|
void ScriptingWindow::updatedValue(int row, int col)
|
|
{
|
|
QTableWidgetItem *nameItem = ui->tableVariables->item(row, 0);
|
|
QTableWidgetItem *valItem = ui->tableVariables->item(row, 1);
|
|
|
|
if (!valItem) return;
|
|
if (col == 0) return;
|
|
if (!valItem->isSelected()) return; // don't record updates not from a user edited cell
|
|
|
|
if (nameItem && valItem)
|
|
{
|
|
QString name = nameItem->text();
|
|
QString val = valItem->text();
|
|
emit updatedParameter(name, val);
|
|
}
|
|
}
|
|
|
|
void ScriptingWindow::showEvent(QShowEvent* event)
|
|
{
|
|
QDialog::showEvent(event);
|
|
installEventFilter(this);
|
|
}
|
|
|
|
void ScriptingWindow::closeEvent(QCloseEvent *event)
|
|
{
|
|
Q_UNUSED(event);
|
|
removeEventFilter(this);
|
|
writeSettings();
|
|
}
|
|
|
|
bool ScriptingWindow::eventFilter(QObject *obj, QEvent *event)
|
|
{
|
|
if (event->type() == QEvent::KeyRelease) {
|
|
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
|
switch (keyEvent->key())
|
|
{
|
|
case Qt::Key_F1:
|
|
HelpWindow::getRef()->showHelp("scriptingwindow.html");
|
|
break;
|
|
}
|
|
return true;
|
|
} else {
|
|
// standard event processing
|
|
return QObject::eventFilter(obj, event);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void ScriptingWindow::readSettings()
|
|
{
|
|
QSettings settings;
|
|
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
|
{
|
|
resize(settings.value("ScriptingWindow/WindowSize", QSize(860, 650)).toSize());
|
|
move(settings.value("ScriptingWindow/WindowPos", QPoint(100, 100)).toPoint());
|
|
}
|
|
}
|
|
|
|
void ScriptingWindow::writeSettings()
|
|
{
|
|
QSettings settings;
|
|
|
|
if (settings.value("Main/SaveRestorePositions", false).toBool())
|
|
{
|
|
settings.setValue("ScriptingWindow/WindowSize", size());
|
|
settings.setValue("ScriptingWindow/WindowPos", pos());
|
|
}
|
|
}
|
|
|
|
void ScriptingWindow::changeCurrentScript()
|
|
{
|
|
ui->tableVariables->clear();
|
|
for (int i = 0; i < ui->tableVariables->rowCount(); i++) ui->tableVariables->removeRow(0);
|
|
QStringList labels;
|
|
labels.append("Parameter");
|
|
labels.append("Value");
|
|
ui->tableVariables->setHorizontalHeaderLabels(labels);
|
|
|
|
int sel = ui->listLoadedScripts->currentRow();
|
|
if (sel < 0) return;
|
|
|
|
if (currentScript) {
|
|
currentScript->scriptText = editor->toPlainText();
|
|
disconnect(this, SIGNAL(updateValueTable(QTableWidget*)), currentScript, SLOT(updateValuesTable(QTableWidget*)));
|
|
disconnect(this, SIGNAL(updatedParameter(QString,QString)), currentScript, SLOT(updateParameter(QString,QString)));
|
|
}
|
|
|
|
ScriptContainer *container = scripts.at(sel);
|
|
currentScript = container;
|
|
editor->setPlainText(container->scriptText);
|
|
editor->setEnabled(true);
|
|
connect(this, SIGNAL(updateValueTable(QTableWidget*)), currentScript, SLOT(updateValuesTable(QTableWidget*)));
|
|
connect(this, SIGNAL(updatedParameter(QString,QString)), currentScript, SLOT(updateParameter(QString,QString)));
|
|
}
|
|
|
|
void ScriptingWindow::valuesTimerElapsed()
|
|
{
|
|
if (currentScript)
|
|
{
|
|
emit updateValueTable(ui->tableVariables);
|
|
}
|
|
}
|
|
|
|
void ScriptingWindow::loadNewScript()
|
|
{
|
|
QString filename;
|
|
QFileDialog dialog;
|
|
ScriptContainer *container;
|
|
|
|
QStringList filters;
|
|
filters.append(QString(tr("Javascript File (*.js)")));
|
|
|
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
|
dialog.setNameFilters(filters);
|
|
dialog.setViewMode(QFileDialog::Detail);
|
|
|
|
if (dialog.exec() == QDialog::Accepted)
|
|
{
|
|
filename = dialog.selectedFiles()[0];
|
|
|
|
if (dialog.selectedNameFilter() == filters[0])
|
|
{
|
|
QFile scriptFile(filename);
|
|
|
|
if (scriptFile.open(QIODevice::ReadOnly))
|
|
{
|
|
QString contents = scriptFile.readAll();
|
|
scriptFile.close();
|
|
QStringList fileList = filename.split('/');
|
|
QString justFileName = fileList[fileList.length() - 1];
|
|
ui->listLoadedScripts->addItem(justFileName);
|
|
|
|
container = new ScriptContainer();
|
|
container->fileName = justFileName;
|
|
container->filePath = filename;
|
|
container->scriptText = contents;
|
|
container->setScriptWindow(this);
|
|
container->compileScript();
|
|
scripts.append(container);
|
|
|
|
ui->listLoadedScripts->setCurrentRow(ui->listLoadedScripts->count() - 1);
|
|
changeCurrentScript();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScriptingWindow::createNewScript()
|
|
{
|
|
ScriptContainer *container;
|
|
|
|
container = new ScriptContainer();
|
|
|
|
container->fileName = "UNNAMED_" + QString::number((qrand() % 10000)) + ".js";
|
|
container->filePath = QString();
|
|
container->scriptText = QString();
|
|
container->setScriptWindow(this);
|
|
scripts.append(container);
|
|
ui->listLoadedScripts->addItem(container->fileName);
|
|
|
|
ui->listLoadedScripts->setCurrentRow(ui->listLoadedScripts->count() - 1);
|
|
changeCurrentScript();
|
|
}
|
|
|
|
void ScriptingWindow::deleteCurrentScript()
|
|
{
|
|
ScriptContainer* thisScript;
|
|
|
|
int sel = ui->listLoadedScripts->currentRow();
|
|
if (sel < 0) return;
|
|
|
|
QMessageBox msgBox;
|
|
msgBox.setText("Really remove script?");
|
|
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
|
msgBox.setDefaultButton(QMessageBox::No);
|
|
int ret = msgBox.exec();
|
|
switch (ret)
|
|
{
|
|
case QMessageBox::Yes:
|
|
ui->listLoadedScripts->takeItem(sel);
|
|
thisScript = scripts.at(sel);
|
|
scripts.removeAt(sel);
|
|
delete thisScript; //causes a seg fault. Seems to be due to currently running javascript code. No idea how to stop code from running
|
|
thisScript = NULL;
|
|
currentScript = NULL;
|
|
|
|
if (ui->listLoadedScripts->count() > 0)
|
|
{
|
|
ui->listLoadedScripts->setCurrentRow(0);
|
|
changeCurrentScript();
|
|
}
|
|
else
|
|
{
|
|
editor->setPlainText("");
|
|
editor->setEnabled(false);
|
|
}
|
|
break;
|
|
case QMessageBox::No:
|
|
break;
|
|
default:
|
|
// should never be reached
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ScriptingWindow::refreshSourceWindow()
|
|
{
|
|
editor->setPlainText(currentScript->scriptText);
|
|
}
|
|
|
|
void ScriptingWindow::saveScript()
|
|
{
|
|
QString filename;
|
|
QFileDialog dialog(this);
|
|
|
|
QStringList filters;
|
|
filters.append(QString(tr("Javascript File (*.js)")));
|
|
|
|
dialog.setFileMode(QFileDialog::AnyFile);
|
|
dialog.setNameFilters(filters);
|
|
dialog.setViewMode(QFileDialog::Detail);
|
|
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
|
|
|
if (dialog.exec() == QDialog::Accepted)
|
|
{
|
|
filename = dialog.selectedFiles()[0];
|
|
if (!filename.contains('.')) filename += ".js";
|
|
if (dialog.selectedNameFilter() == filters[0])
|
|
{
|
|
QFile *outFile = new QFile(filename);
|
|
|
|
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
|
|
{
|
|
delete outFile;
|
|
return;
|
|
}
|
|
outFile->write(editor->toPlainText().toUtf8());
|
|
outFile->close();
|
|
delete outFile;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScriptingWindow::revertScript()
|
|
{
|
|
QMessageBox msgBox;
|
|
msgBox.setText("Are you sure you'd like to revert?");
|
|
msgBox.setInformativeText("Really do it?");
|
|
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
|
msgBox.setDefaultButton(QMessageBox::Cancel);
|
|
int ret = msgBox.exec();
|
|
switch (ret)
|
|
{
|
|
case QMessageBox::Yes:
|
|
//just grab the last stored copy of the script (last compiled version) and replace current text with that text
|
|
editor->setPlainText(currentScript->scriptText);
|
|
break;
|
|
case QMessageBox::No:
|
|
break;
|
|
default:
|
|
// should never be reached
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ScriptingWindow::recompileScript()
|
|
{
|
|
currentScript->scriptText = editor->toPlainText();
|
|
currentScript->compileScript();
|
|
}
|
|
|
|
void ScriptingWindow::clickedLogClear()
|
|
{
|
|
ui->listLog->clear();
|
|
elapsedTime.start();
|
|
}
|
|
|
|
void ScriptingWindow::log(QString text)
|
|
{
|
|
ScriptContainer *cont = qobject_cast<ScriptContainer*>(sender());
|
|
if (cont != NULL)
|
|
ui->listLog->addItem(QString::number(elapsedTime.elapsed()) + "(" + cont->fileName + "): " + text);
|
|
else
|
|
ui->listLog->addItem(QString::number(elapsedTime.elapsed()) + ": " + text);
|
|
|
|
if (ui->cbAutoScroll->isChecked())
|
|
{
|
|
ui->listLog->scrollToBottom();
|
|
}
|
|
}
|