From c454c790fa87bf86553e545b9e183f84f1e3d995 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 29 Jun 2014 21:31:28 -0700 Subject: [PATCH] Check script file for external changes when editor regains focus Prompt user whether to reload. --- interface/src/ui/ScriptEditorWidget.cpp | 39 ++++++++++++++++++++++--- interface/src/ui/ScriptEditorWidget.h | 6 ++++ interface/src/ui/ScriptEditorWindow.cpp | 11 +++++++ interface/src/ui/ScriptEditorWindow.h | 4 +++ 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index 4d73ab26bd..3829cb6a2e 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -29,8 +29,11 @@ ScriptEditorWidget::ScriptEditorWidget() : _scriptEditorWidgetUI(new Ui::ScriptEditorWidget), _scriptEngine(NULL), - _isRestarting(false) + _isRestarting(false), + _isReloading(false) { + setAttribute(Qt::WA_DeleteOnClose); + _scriptEditorWidgetUI->setupUi(this); connect(_scriptEditorWidgetUI->scriptEdit->document(), &QTextDocument::modificationChanged, this, @@ -52,7 +55,7 @@ ScriptEditorWidget::~ScriptEditorWidget() { } void ScriptEditorWidget::onScriptModified() { - if(_scriptEditorWidgetUI->onTheFlyCheckBox->isChecked() && isModified() && isRunning()) { + if(_scriptEditorWidgetUI->onTheFlyCheckBox->isChecked() && isModified() && isRunning() && !_isReloading) { _isRestarting = true; setRunning(false); // Script is restarted once current script instance finishes. @@ -76,7 +79,7 @@ bool ScriptEditorWidget::isRunning() { } bool ScriptEditorWidget::setRunning(bool run) { - if (run && !save()) { + if (run && isModified() && !save()) { return false; } @@ -114,13 +117,14 @@ bool ScriptEditorWidget::saveFile(const QString &scriptPath) { QTextStream out(&file); out << _scriptEditorWidgetUI->scriptEdit->toPlainText(); + file.close(); setScriptFile(scriptPath); return true; } void ScriptEditorWidget::loadFile(const QString& scriptPath) { - QUrl url(scriptPath); + QUrl url(scriptPath); // if the scheme length is one or lower, maybe they typed in a file, let's try const int WINDOWS_DRIVE_LETTER_SIZE = 1; @@ -133,6 +137,7 @@ void ScriptEditorWidget::loadFile(const QString& scriptPath) { } QTextStream in(&file); _scriptEditorWidgetUI->scriptEdit->setPlainText(in.readAll()); + file.close(); setScriptFile(scriptPath); if (_scriptEngine != NULL) { @@ -184,6 +189,7 @@ bool ScriptEditorWidget::saveAs() { void ScriptEditorWidget::setScriptFile(const QString& scriptPath) { _currentScript = scriptPath; + _currentScriptModified = QFileInfo(_currentScript).lastModified(); _scriptEditorWidgetUI->scriptEdit->document()->setModified(false); setWindowModified(false); @@ -207,3 +213,28 @@ void ScriptEditorWidget::onScriptError(const QString& message) { void ScriptEditorWidget::onScriptPrint(const QString& message) { _scriptEditorWidgetUI->debugText->appendPlainText("> " + message); } + +void ScriptEditorWidget::onWindowActivated() { + if (!_isReloading) { + _isReloading = true; + + if (QFileInfo(_currentScript).lastModified() > _currentScriptModified) { + if (QMessageBox::warning(this, _currentScript, + tr("This file has been modified outside of the Interface editor.") + "\n\n" + +(isModified() + ? tr("Do you want to reload it and lose the changes you've made in the Interface editor?") + : tr("Do you want to reload it?")), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + loadFile(_currentScript); + if (_scriptEditorWidgetUI->onTheFlyCheckBox->isChecked() && isRunning()) { + _isRestarting = true; + 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 d7fa615024..8dd847ee6d 100644 --- a/interface/src/ui/ScriptEditorWidget.h +++ b/interface/src/ui/ScriptEditorWidget.h @@ -13,6 +13,7 @@ #define hifi_ScriptEditorWidget_h #include + #include "ScriptEngine.h" namespace Ui { @@ -42,6 +43,9 @@ signals: void scriptnameChanged(); void scriptModified(); +public slots: + void onWindowActivated(); + private slots: void onScriptError(const QString& message); void onScriptPrint(const QString& message); @@ -52,7 +56,9 @@ private: Ui::ScriptEditorWidget* _scriptEditorWidgetUI; ScriptEngine* _scriptEngine; QString _currentScript; + QDateTime _currentScriptModified; bool _isRestarting; + bool _isReloading; }; #endif // hifi_ScriptEditorWidget_h diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp index 3f63f0741b..7c8f5c79cb 100644 --- a/interface/src/ui/ScriptEditorWindow.cpp +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -36,6 +36,8 @@ ScriptEditorWindow::ScriptEditorWindow() : _loadMenu(new QMenu), _saveMenu(new QMenu) { + setAttribute(Qt::WA_DeleteOnClose); + _ScriptEditorWindowUI->setupUi(this); this->setWindowFlags(Qt::Tool); show(); @@ -140,6 +142,7 @@ ScriptEditorWidget* ScriptEditorWindow::addScriptEditorWidget(QString title) { connect(newScriptEditorWidget, &ScriptEditorWidget::scriptnameChanged, this, &ScriptEditorWindow::updateScriptNameOrStatus); connect(newScriptEditorWidget, &ScriptEditorWidget::scriptModified, this, &ScriptEditorWindow::updateScriptNameOrStatus); connect(newScriptEditorWidget, &ScriptEditorWidget::runningStateChanged, this, &ScriptEditorWindow::updateButtons); + connect(this, &ScriptEditorWindow::windowActivated, newScriptEditorWidget, &ScriptEditorWidget::onWindowActivated); _ScriptEditorWindowUI->tabWidget->addTab(newScriptEditorWidget, title); _ScriptEditorWindowUI->tabWidget->setCurrentWidget(newScriptEditorWidget); newScriptEditorWidget->setUpdatesEnabled(true); @@ -216,3 +219,11 @@ void ScriptEditorWindow::terminateCurrentTab() { this->raise(); } } + +bool ScriptEditorWindow::event(QEvent* event) { + if (event->type() == QEvent::WindowActivate) { + emit windowActivated(); + } + return QWidget::event(event); +} + diff --git a/interface/src/ui/ScriptEditorWindow.h b/interface/src/ui/ScriptEditorWindow.h index 360e902cc2..271a3d685b 100644 --- a/interface/src/ui/ScriptEditorWindow.h +++ b/interface/src/ui/ScriptEditorWindow.h @@ -27,8 +27,12 @@ public: void terminateCurrentTab(); +signals: + void windowActivated(); + protected: void closeEvent(QCloseEvent* event); + virtual bool event(QEvent* event); private: Ui::ScriptEditorWindow* _ScriptEditorWindowUI;