From 660bf6b3ea7a4048ac9f208c4ab69c8c70838be2 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 14 Oct 2015 14:47:29 +0200 Subject: [PATCH 1/6] ScriptEditor: single quotes support and spelling fix --- interface/src/ScriptHighlighting.cpp | 18 +++++++++--------- interface/src/ScriptHighlighting.h | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/interface/src/ScriptHighlighting.cpp b/interface/src/ScriptHighlighting.cpp index 125ab1e967..1d31f2823b 100644 --- a/interface/src/ScriptHighlighting.cpp +++ b/interface/src/ScriptHighlighting.cpp @@ -16,7 +16,7 @@ ScriptHighlighting::ScriptHighlighting(QTextDocument* parent) : QSyntaxHighlighter(parent) { _keywordRegex = QRegExp("\\b(break|case|catch|continue|debugger|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|this|throw|try|typeof|var|void|while|with)\\b"); - _qoutedTextRegex = QRegExp("\"[^\"]*(\"){0,1}"); + _quotedTextRegex = QRegExp("(\"[^\"]*(\"){0,1}|\'[^\']*(\'){0,1})"); _multiLineCommentBegin = QRegExp("/\\*"); _multiLineCommentEnd = QRegExp("\\*/"); _numberRegex = QRegExp("[0-9]+(\\.[0-9]+){0,1}"); @@ -29,7 +29,7 @@ void ScriptHighlighting::highlightBlock(const QString& text) { this->highlightKeywords(text); this->formatNumbers(text); this->formatTrueFalse(text); - this->formatQoutedText(text); + this->formatQuotedText(text); this->formatComments(text); } @@ -61,14 +61,14 @@ void ScriptHighlighting::formatComments(const QString& text) { int index = _singleLineComment.indexIn(text); while (index >= 0) { int length = _singleLineComment.matchedLength(); - int quoted_index = _qoutedTextRegex.indexIn(text); + int quoted_index = _quotedTextRegex.indexIn(text); bool valid = true; while (quoted_index >= 0 && valid) { - int quoted_length = _qoutedTextRegex.matchedLength(); + int quoted_length = _quotedTextRegex.matchedLength(); if (quoted_index <= index && index <= (quoted_index + quoted_length)) { valid = false; } - quoted_index = _qoutedTextRegex.indexIn(text, quoted_index + quoted_length); + quoted_index = _quotedTextRegex.indexIn(text, quoted_index + quoted_length); } if (valid) { @@ -78,12 +78,12 @@ void ScriptHighlighting::formatComments(const QString& text) { } } -void ScriptHighlighting::formatQoutedText(const QString& text){ - int index = _qoutedTextRegex.indexIn(text); +void ScriptHighlighting::formatQuotedText(const QString& text){ + int index = _quotedTextRegex.indexIn(text); while (index >= 0) { - int length = _qoutedTextRegex.matchedLength(); + int length = _quotedTextRegex.matchedLength(); setFormat(index, length, Qt::red); - index = _qoutedTextRegex.indexIn(text, index + length); + index = _quotedTextRegex.indexIn(text, index + length); } } diff --git a/interface/src/ScriptHighlighting.h b/interface/src/ScriptHighlighting.h index 232d594308..2eb40796e3 100644 --- a/interface/src/ScriptHighlighting.h +++ b/interface/src/ScriptHighlighting.h @@ -29,14 +29,14 @@ protected: void highlightBlock(const QString& text); void highlightKeywords(const QString& text); void formatComments(const QString& text); - void formatQoutedText(const QString& text); + void formatQuotedText(const QString& text); void formatNumbers(const QString& text); void formatTrueFalse(const QString& text); private: QRegExp _alphacharRegex; QRegExp _keywordRegex; - QRegExp _qoutedTextRegex; + QRegExp _quotedTextRegex; QRegExp _multiLineCommentBegin; QRegExp _multiLineCommentEnd; QRegExp _numberRegex; From 880d34d483c323dcaca522bf5d0ec7640a9c6310 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 14 Oct 2015 20:35:15 +0200 Subject: [PATCH 2/6] JSConsole improvements - ability to set Script Engine - clear function for clearing the output - only show evaluation output for executeCommand, print() and error output is still being printed --- interface/src/ui/JSConsole.cpp | 63 +++++++++++++++++++++++++--------- interface/src/ui/JSConsole.h | 6 +++- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/interface/src/ui/JSConsole.cpp b/interface/src/ui/JSConsole.cpp index 6e5b22399d..6a8b1116a7 100644 --- a/interface/src/ui/JSConsole.cpp +++ b/interface/src/ui/JSConsole.cpp @@ -35,7 +35,8 @@ JSConsole::JSConsole(QWidget* parent, ScriptEngine* scriptEngine) : _ui(new Ui::Console), _currentCommandInHistory(NO_CURRENT_HISTORY_COMMAND), _commandHistory(), - _scriptEngine(scriptEngine) { + _ownScriptEngine(scriptEngine == NULL), + _scriptEngine(NULL) { _ui->setupUi(this); _ui->promptTextEdit->setLineWrapMode(QTextEdit::NoWrap); @@ -51,23 +52,40 @@ JSConsole::JSConsole(QWidget* parent, ScriptEngine* scriptEngine) : connect(_ui->scrollArea->verticalScrollBar(), SIGNAL(rangeChanged(int, int)), this, SLOT(scrollToBottom())); connect(_ui->promptTextEdit, SIGNAL(textChanged()), this, SLOT(resizeTextInput())); - - if (_scriptEngine == NULL) { - _scriptEngine = qApp->loadScript(QString(), false); - } - - connect(_scriptEngine, SIGNAL(evaluationFinished(QScriptValue, bool)), - this, SLOT(handleEvalutationFinished(QScriptValue, bool))); - connect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(handlePrint(const QString&))); - connect(_scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(handleError(const QString&))); + setScriptEngine(scriptEngine); resizeTextInput(); } JSConsole::~JSConsole() { + disconnect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(handlePrint(const QString&))); + disconnect(_scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(handleError(const QString&))); + if (_ownScriptEngine) { + _scriptEngine->deleteLater(); + } delete _ui; } +void JSConsole::setScriptEngine(ScriptEngine* scriptEngine) { + if (_scriptEngine == scriptEngine && scriptEngine != NULL) { + return; + } + if (_scriptEngine != NULL) { + disconnect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(handlePrint(const QString&))); + disconnect(_scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(handleError(const QString&))); + if (_ownScriptEngine) { + _scriptEngine->deleteLater(); + } + } + + // if scriptEngine is NULL then create one and keep track of it using _ownScriptEngine + _ownScriptEngine = scriptEngine == NULL; + _scriptEngine = _ownScriptEngine ? qApp->loadScript(QString(), false) : scriptEngine; + + connect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(handlePrint(const QString&))); + connect(_scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(handleError(const QString&))); +} + void JSConsole::executeCommand(const QString& command) { _commandHistory.prepend(command); if (_commandHistory.length() > MAX_HISTORY_SIZE) { @@ -78,12 +96,10 @@ void JSConsole::executeCommand(const QString& command) { appendMessage(">", "" + command.toHtmlEscaped() + ""); - QMetaObject::invokeMethod(_scriptEngine, "evaluate", Q_ARG(const QString&, command)); + QScriptValue result; + QMetaObject::invokeMethod(_scriptEngine, "evaluate", Qt::ConnectionType::BlockingQueuedConnection, + Q_RETURN_ARG(QScriptValue, result), Q_ARG(const QString&, command)); - resetCurrentCommandHistory(); -} - -void JSConsole::handleEvalutationFinished(QScriptValue result, bool isException) { _ui->promptTextEdit->setDisabled(false); // Make sure focus is still on this window - some commands are blocking and can take awhile to execute. @@ -91,10 +107,13 @@ void JSConsole::handleEvalutationFinished(QScriptValue result, bool isException) _ui->promptTextEdit->setFocus(); } - QString gutter = (isException || result.isError()) ? GUTTER_ERROR : GUTTER_PREVIOUS_COMMAND; - QString resultColor = (isException || result.isError()) ? RESULT_ERROR_STYLE : RESULT_SUCCESS_STYLE; + bool error = (_scriptEngine->hasUncaughtException() || result.isError()); + QString gutter = error ? GUTTER_ERROR : GUTTER_PREVIOUS_COMMAND; + QString resultColor = error ? RESULT_ERROR_STYLE : RESULT_SUCCESS_STYLE; QString resultStr = "" + result.toString().toHtmlEscaped() + ""; appendMessage(gutter, resultStr); + + resetCurrentCommandHistory(); } void JSConsole::handleError(const QString& message) { @@ -233,3 +252,13 @@ void JSConsole::appendMessage(const QString& gutter, const QString& message) { _ui->logArea->updateGeometry(); scrollToBottom(); } + +void JSConsole::clear() { + QLayoutItem* item; + while ((item = _ui->logArea->layout()->takeAt(0)) != NULL) { + delete item->widget(); + delete item; + } + _ui->logArea->updateGeometry(); + scrollToBottom(); +} diff --git a/interface/src/ui/JSConsole.h b/interface/src/ui/JSConsole.h index 98afdf7bf8..dd104723d0 100644 --- a/interface/src/ui/JSConsole.h +++ b/interface/src/ui/JSConsole.h @@ -31,6 +31,9 @@ public: JSConsole(QWidget* parent, ScriptEngine* scriptEngine = NULL); ~JSConsole(); + void setScriptEngine(ScriptEngine* scriptEngine = NULL); + void clear(); + public slots: void executeCommand(const QString& command); @@ -47,7 +50,6 @@ protected: protected slots: void scrollToBottom(); void resizeTextInput(); - void handleEvalutationFinished(QScriptValue result, bool isException); void handlePrint(const QString& message); void handleError(const QString& message); @@ -60,6 +62,8 @@ private: Ui::Console* _ui; int _currentCommandInHistory; QList _commandHistory; + // Keeps track if the script engine is created inside the JSConsole + bool _ownScriptEngine; QString _rootCommand; ScriptEngine* _scriptEngine; }; From 96b6067d88be891ee5a35806447bb2730960612e Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 14 Oct 2015 20:37:47 +0200 Subject: [PATCH 3/6] ScriptEditor Improvements: - Script restart works proper again - Fixed on and off icon switch - Replaced regular script output box with fully functional JSConsole! --- interface/src/ui/ScriptEditorWidget.cpp | 33 ++++++++-------------- interface/src/ui/ScriptEditorWidget.h | 4 +-- interface/src/ui/ScriptEditorWindow.cpp | 12 +++----- interface/ui/scriptEditorWidget.ui | 37 ------------------------- 4 files changed, 18 insertions(+), 68 deletions(-) diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index 76327804b6..0ae13f9c24 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -52,10 +52,16 @@ ScriptEditorWidget::ScriptEditorWidget() : // We create a new ScriptHighligting QObject and provide it with a parent so this is NOT a memory leak. new ScriptHighlighting(_scriptEditorWidgetUI->scriptEdit->document()); QTimer::singleShot(0, _scriptEditorWidgetUI->scriptEdit, SLOT(setFocus())); + + _console = new JSConsole(this); + _console->setFixedHeight(CONSOLE_HEIGHT); + _scriptEditorWidgetUI->verticalLayout->addWidget(_console); + connect(_scriptEditorWidgetUI->clearButton, &QPushButton::clicked, _console, &JSConsole::clear); } ScriptEditorWidget::~ScriptEditorWidget() { delete _scriptEditorWidgetUI; + delete _console; } void ScriptEditorWidget::onScriptModified() { @@ -68,6 +74,7 @@ void ScriptEditorWidget::onScriptModified() { void ScriptEditorWidget::onScriptFinished(const QString& scriptPath) { _scriptEngine = NULL; + _console->setScriptEngine(NULL); if (_isRestarting) { _isRestarting = false; setRunning(true); @@ -89,8 +96,6 @@ bool ScriptEditorWidget::setRunning(bool run) { if (_scriptEngine != NULL) { disconnect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); - disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); - disconnect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); disconnect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified); disconnect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished); } @@ -100,15 +105,15 @@ bool ScriptEditorWidget::setRunning(bool run) { // Reload script so that an out of date copy is not retrieved from the cache _scriptEngine = qApp->loadScript(scriptURLString, true, true, false, true); connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); - connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); - connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); connect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified); connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished); } else { connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished); - qApp->stopScript(_currentScript); + const QString& scriptURLString = QUrl(_currentScript).toString(); + qApp->stopScript(scriptURLString); _scriptEngine = NULL; } + _console->setScriptEngine(_scriptEngine); return true; } @@ -147,8 +152,6 @@ void ScriptEditorWidget::loadFile(const QString& scriptPath) { if (_scriptEngine != NULL) { disconnect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); - disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); - disconnect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); disconnect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified); disconnect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished); } @@ -168,16 +171,14 @@ void ScriptEditorWidget::loadFile(const QString& scriptPath) { static_cast(this->parent()->parent()->parent())->terminateCurrentTab(); } } - const QString& scriptURLString = QUrl(_currentScript).toString(); _scriptEngine = qApp->getScriptEngine(scriptURLString); if (_scriptEngine != NULL) { connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); - connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); - connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); connect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified); connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished); } + _console->setScriptEngine(_scriptEngine); } bool ScriptEditorWidget::save() { @@ -210,19 +211,11 @@ bool ScriptEditorWidget::questionSave() { QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Interface"), tr("The script has been modified.\nDo you want to save your changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); - return button == QMessageBox::Save ? save() : (button == QMessageBox::Cancel ? false : true); + return button == QMessageBox::Save ? save() : (button == QMessageBox::Discard); } return true; } -void ScriptEditorWidget::onScriptError(const QString& message) { - _scriptEditorWidgetUI->debugText->appendPlainText("ERROR: " + message); -} - -void ScriptEditorWidget::onScriptPrint(const QString& message) { - _scriptEditorWidgetUI->debugText->appendPlainText("> " + message); -} - void ScriptEditorWidget::onWindowActivated() { if (!_isReloading) { _isReloading = true; @@ -241,10 +234,8 @@ void ScriptEditorWidget::onWindowActivated() { setRunning(false); // Script is restarted once current script instance finishes. } - } } - _isReloading = false; } } diff --git a/interface/src/ui/ScriptEditorWidget.h b/interface/src/ui/ScriptEditorWidget.h index 8dd847ee6d..f53fd7b718 100644 --- a/interface/src/ui/ScriptEditorWidget.h +++ b/interface/src/ui/ScriptEditorWidget.h @@ -14,6 +14,7 @@ #include +#include "JSConsole.h" #include "ScriptEngine.h" namespace Ui { @@ -47,12 +48,11 @@ public slots: void onWindowActivated(); private slots: - void onScriptError(const QString& message); - void onScriptPrint(const QString& message); void onScriptModified(); void onScriptFinished(const QString& scriptName); private: + JSConsole* _console; Ui::ScriptEditorWidget* _scriptEditorWidgetUI; ScriptEngine* _scriptEngine; QString _currentScript; diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp index b5c8500083..3c6d0f73d5 100644 --- a/interface/src/ui/ScriptEditorWindow.cpp +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -28,7 +28,6 @@ #include #include "Application.h" -#include "JSConsole.h" #include "PathUtils.h" ScriptEditorWindow::ScriptEditorWindow(QWidget* parent) : @@ -59,10 +58,6 @@ ScriptEditorWindow::ScriptEditorWindow(QWidget* parent) : _ScriptEditorWindowUI->newButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + "icons/new-script.svg"))); _ScriptEditorWindowUI->saveButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + "icons/save-script.svg"))); _ScriptEditorWindowUI->toggleRunButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + "icons/start-script.svg"))); - - QWidget* console = new JSConsole(this); - console->setFixedHeight(CONSOLE_HEIGHT); - this->layout()->addWidget(console); } ScriptEditorWindow::~ScriptEditorWindow() { @@ -77,10 +72,11 @@ void ScriptEditorWindow::setRunningState(bool run) { } void ScriptEditorWindow::updateButtons() { + bool isRunning = _ScriptEditorWindowUI->tabWidget->currentIndex() != -1 && + static_cast(_ScriptEditorWindowUI->tabWidget->currentWidget())->isRunning(); _ScriptEditorWindowUI->toggleRunButton->setEnabled(_ScriptEditorWindowUI->tabWidget->currentIndex() != -1); - _ScriptEditorWindowUI->toggleRunButton->setIcon(_ScriptEditorWindowUI->tabWidget->currentIndex() != -1 && - static_cast(_ScriptEditorWindowUI->tabWidget->currentWidget())->isRunning() ? - QIcon("../resources/icons/stop-script.svg") : QIcon("../resources/icons/start-script.svg")); + _ScriptEditorWindowUI->toggleRunButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + ((isRunning ? + "icons/stop-script.svg" : "icons/start-script.svg"))))); } void ScriptEditorWindow::loadScriptMenu(const QString& scriptName) { diff --git a/interface/ui/scriptEditorWidget.ui b/interface/ui/scriptEditorWidget.ui index 8aeeff363f..e2e538a595 100644 --- a/interface/ui/scriptEditorWidget.ui +++ b/interface/ui/scriptEditorWidget.ui @@ -128,25 +128,6 @@ - - - - - 0 - 0 - - - - font: 15px "Courier"; - - - true - - - - - - @@ -158,22 +139,4 @@ - - - clearButton - clicked() - debugText - clear() - - - 663 - 447 - - - 350 - 501 - - - - From c585647f10dfd7eb00973456120336053c583204 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 14 Oct 2015 21:00:50 +0200 Subject: [PATCH 4/6] ScriptEditor Improvements: - fixed run icon --- interface/resources/icons/start-script.svg | 32 +++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/interface/resources/icons/start-script.svg b/interface/resources/icons/start-script.svg index 1401853fe4..dc37144f7a 100644 --- a/interface/resources/icons/start-script.svg +++ b/interface/resources/icons/start-script.svg @@ -14,7 +14,7 @@ height="45" id="svg3827" version="1.1" - inkscape:version="0.48.1 r9760" + inkscape:version="0.48.3.1 r9886" sodipodi:docname="start-script.svg"> @@ -439,16 +439,16 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="5.6" - inkscape:cx="76.804753" - inkscape:cy="13.198134" + inkscape:zoom="22.4" + inkscape:cx="44.04179" + inkscape:cy="22.346221" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" - inkscape:window-width="1920" - inkscape:window-height="1028" + inkscape:window-width="1680" + inkscape:window-height="997" inkscape:window-x="-8" - inkscape:window-y="-8" + inkscape:window-y="21" inkscape:window-maximized="1" /> @@ -536,5 +536,23 @@ height="44.57473" x="84.498352" y="1050.0748" /> + + + + From 9d2ae661e16ea7797be7911f32d45015be8a8af9 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 14 Oct 2015 21:10:52 +0200 Subject: [PATCH 5/6] removed some XML from start-script button which possible caused an error before --- interface/resources/icons/start-script.svg | 8 -------- 1 file changed, 8 deletions(-) diff --git a/interface/resources/icons/start-script.svg b/interface/resources/icons/start-script.svg index dc37144f7a..994eb61efe 100644 --- a/interface/resources/icons/start-script.svg +++ b/interface/resources/icons/start-script.svg @@ -540,14 +540,6 @@ id="run-arrow" transform="translate(-46.607143,-3.5714285)" inkscape:label="#run-arrow"> - Date: Wed, 14 Oct 2015 22:21:51 +0200 Subject: [PATCH 6/6] JSConsole: executeCommand works async now --- interface/src/ui/JSConsole.cpp | 18 ++++++++++++++++-- interface/src/ui/JSConsole.h | 8 ++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/JSConsole.cpp b/interface/src/ui/JSConsole.cpp index 6a8b1116a7..b50f84d538 100644 --- a/interface/src/ui/JSConsole.cpp +++ b/interface/src/ui/JSConsole.cpp @@ -9,9 +9,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include #include #include +#include #include @@ -55,6 +57,8 @@ JSConsole::JSConsole(QWidget* parent, ScriptEngine* scriptEngine) : setScriptEngine(scriptEngine); resizeTextInput(); + + connect(&_executeWatcher, SIGNAL(finished()), this, SLOT(commandFinished())); } JSConsole::~JSConsole() { @@ -96,9 +100,19 @@ void JSConsole::executeCommand(const QString& command) { appendMessage(">", "" + command.toHtmlEscaped() + ""); + QFuture future = QtConcurrent::run(this, &JSConsole::executeCommandInWatcher, command); + _executeWatcher.setFuture(future); +} + +QScriptValue JSConsole::executeCommandInWatcher(const QString& command) { QScriptValue result; QMetaObject::invokeMethod(_scriptEngine, "evaluate", Qt::ConnectionType::BlockingQueuedConnection, Q_RETURN_ARG(QScriptValue, result), Q_ARG(const QString&, command)); + return result; +} + +void JSConsole::commandFinished() { + QScriptValue result = _executeWatcher.result(); _ui->promptTextEdit->setDisabled(false); @@ -106,11 +120,11 @@ void JSConsole::executeCommand(const QString& command) { if (window()->isActiveWindow()) { _ui->promptTextEdit->setFocus(); } - + bool error = (_scriptEngine->hasUncaughtException() || result.isError()); QString gutter = error ? GUTTER_ERROR : GUTTER_PREVIOUS_COMMAND; QString resultColor = error ? RESULT_ERROR_STYLE : RESULT_SUCCESS_STYLE; - QString resultStr = "" + result.toString().toHtmlEscaped() + ""; + QString resultStr = "" + result.toString().toHtmlEscaped() + ""; appendMessage(gutter, resultStr); resetCurrentCommandHistory(); diff --git a/interface/src/ui/JSConsole.h b/interface/src/ui/JSConsole.h index dd104723d0..cb58beab35 100644 --- a/interface/src/ui/JSConsole.h +++ b/interface/src/ui/JSConsole.h @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -37,10 +38,6 @@ public: public slots: void executeCommand(const QString& command); -signals: - void commandExecuting(const QString& command); - void commandFinished(const QString& result); - protected: void setAndSelectCommand(const QString& command); virtual bool eventFilter(QObject* sender, QEvent* event); @@ -52,13 +49,16 @@ protected slots: void resizeTextInput(); void handlePrint(const QString& message); void handleError(const QString& message); + void commandFinished(); private: void appendMessage(const QString& gutter, const QString& message); void setToNextCommandInHistory(); void setToPreviousCommandInHistory(); void resetCurrentCommandHistory(); + QScriptValue executeCommandInWatcher(const QString& command); + QFutureWatcher _executeWatcher; Ui::Console* _ui; int _currentCommandInHistory; QList _commandHistory;