Check script file for external changes when editor regains focus

Prompt user whether to reload.
This commit is contained in:
David Rowe 2014-06-29 21:31:28 -07:00
parent 3df43dc653
commit c454c790fa
4 changed files with 56 additions and 4 deletions

View file

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

View file

@ -13,6 +13,7 @@
#define hifi_ScriptEditorWidget_h
#include <QDockWidget>
#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

View file

@ -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);
}

View file

@ -27,8 +27,12 @@ public:
void terminateCurrentTab();
signals:
void windowActivated();
protected:
void closeEvent(QCloseEvent* event);
virtual bool event(QEvent* event);
private:
Ui::ScriptEditorWindow* _ScriptEditorWindowUI;