overte/interface/src/ui/ScriptEditorWindow.cpp

233 lines
9.7 KiB
C++

//
// ScriptEditorWindow.cpp
// interface/src/ui
//
// Created by Thijs Wenker on 4/14/14.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ui_scriptEditorWindow.h"
#include "ScriptEditorWindow.h"
#include "ScriptEditorWidget.h"
#include <QGridLayout>
#include <QFrame>
#include <QLayoutItem>
#include <QMainWindow>
#include <QMessageBox>
#include <QPalette>
#include <QScrollBar>
#include <QShortcut>
#include <QSizePolicy>
#include <QTimer>
#include <QWidget>
#include "Application.h"
#include "FlowLayout.h"
#include "JSConsole.h"
const int CONSOLE_HEIGHT = 150;
ScriptEditorWindow::ScriptEditorWindow() :
_ScriptEditorWindowUI(new Ui::ScriptEditorWindow),
_loadMenu(new QMenu),
_saveMenu(new QMenu)
{
setAttribute(Qt::WA_DeleteOnClose);
_ScriptEditorWindowUI->setupUi(this);
this->setWindowFlags(Qt::Tool);
show();
addScriptEditorWidget("New script");
connect(_loadMenu, &QMenu::aboutToShow, this, &ScriptEditorWindow::loadMenuAboutToShow);
_ScriptEditorWindowUI->loadButton->setMenu(_loadMenu);
_saveMenu->addAction("Save as..", this, SLOT(saveScriptAsClicked()), Qt::CTRL | Qt::SHIFT | Qt::Key_S);
_ScriptEditorWindowUI->saveButton->setMenu(_saveMenu);
connect(new QShortcut(QKeySequence("Ctrl+N"), this), &QShortcut::activated, this, &ScriptEditorWindow::newScriptClicked);
connect(new QShortcut(QKeySequence("Ctrl+S"), this), &QShortcut::activated, this,&ScriptEditorWindow::saveScriptClicked);
connect(new QShortcut(QKeySequence("Ctrl+O"), this), &QShortcut::activated, this, &ScriptEditorWindow::loadScriptClicked);
connect(new QShortcut(QKeySequence("F5"), this), &QShortcut::activated, this, &ScriptEditorWindow::toggleRunScriptClicked);
QWidget* console = new JSConsole(this);
console->setFixedHeight(CONSOLE_HEIGHT);
this->layout()->addWidget(console);
}
ScriptEditorWindow::~ScriptEditorWindow() {
delete _ScriptEditorWindowUI;
}
void ScriptEditorWindow::setRunningState(bool run) {
if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) {
static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->currentWidget())->setRunning(run);
}
this->updateButtons();
}
void ScriptEditorWindow::updateButtons() {
_ScriptEditorWindowUI->toggleRunButton->setEnabled(_ScriptEditorWindowUI->tabWidget->currentIndex() != -1);
_ScriptEditorWindowUI->toggleRunButton->setIcon(_ScriptEditorWindowUI->tabWidget->currentIndex() != -1 &&
static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->currentWidget())->isRunning() ?
QIcon("../resources/icons/stop-script.svg") : QIcon("../resources/icons/start-script.svg"));
}
void ScriptEditorWindow::loadScriptMenu(const QString& scriptName) {
addScriptEditorWidget("loading...")->loadFile(scriptName);
updateButtons();
}
void ScriptEditorWindow::loadScriptClicked() {
QString scriptName = QFileDialog::getOpenFileName(this, tr("Interface"),
Application::getInstance()->getPreviousScriptLocation(),
tr("JavaScript Files (*.js)"));
if (!scriptName.isEmpty()) {
Application::getInstance()->setPreviousScriptLocation(scriptName);
addScriptEditorWidget("loading...")->loadFile(scriptName);
updateButtons();
}
}
void ScriptEditorWindow::loadMenuAboutToShow() {
_loadMenu->clear();
QStringList runningScripts = Application::getInstance()->getRunningScripts();
if (runningScripts.count() > 0) {
QSignalMapper* signalMapper = new QSignalMapper(this);
foreach (const QString& runningScript, runningScripts) {
QAction* runningScriptAction = new QAction(runningScript, _loadMenu);
connect(runningScriptAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
signalMapper->setMapping(runningScriptAction, runningScript);
_loadMenu->addAction(runningScriptAction);
}
connect(signalMapper, SIGNAL(mapped(const QString &)), this, SLOT(loadScriptMenu(const QString&)));
} else {
QAction* naAction = new QAction("(no running scripts)", _loadMenu);
naAction->setDisabled(true);
_loadMenu->addAction(naAction);
}
}
void ScriptEditorWindow::newScriptClicked() {
addScriptEditorWidget(QString("New script"));
}
void ScriptEditorWindow::toggleRunScriptClicked() {
this->setRunningState(!(_ScriptEditorWindowUI->tabWidget->currentIndex() !=-1
&& static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->currentWidget())->isRunning()));
}
void ScriptEditorWindow::saveScriptClicked() {
if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) {
ScriptEditorWidget* currentScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget
->currentWidget());
currentScriptWidget->save();
}
}
void ScriptEditorWindow::saveScriptAsClicked() {
if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) {
ScriptEditorWidget* currentScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget
->currentWidget());
currentScriptWidget->saveAs();
}
}
ScriptEditorWidget* ScriptEditorWindow::addScriptEditorWidget(QString title) {
ScriptEditorWidget* newScriptEditorWidget = new ScriptEditorWidget();
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);
newScriptEditorWidget->adjustSize();
return newScriptEditorWidget;
}
void ScriptEditorWindow::tabSwitched(int tabIndex) {
this->updateButtons();
if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) {
ScriptEditorWidget* currentScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget
->currentWidget());
QString modifiedStar = (currentScriptWidget->isModified() ? "*" : "");
if (currentScriptWidget->getScriptName().length() > 0) {
this->setWindowTitle("Script Editor [" + currentScriptWidget->getScriptName() + modifiedStar + "]");
} else {
this->setWindowTitle("Script Editor [New script" + modifiedStar + "]");
}
} else {
this->setWindowTitle("Script Editor");
}
}
void ScriptEditorWindow::tabCloseRequested(int tabIndex) {
ScriptEditorWidget* closingScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget
->widget(tabIndex));
if(closingScriptWidget->questionSave()) {
_ScriptEditorWindowUI->tabWidget->removeTab(tabIndex);
}
}
void ScriptEditorWindow::closeEvent(QCloseEvent *event) {
bool unsaved_docs_warning = false;
for (int i = 0; i < _ScriptEditorWindowUI->tabWidget->count(); i++){
if(static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->widget(i))->isModified()){
unsaved_docs_warning = true;
break;
}
}
if (!unsaved_docs_warning || QMessageBox::warning(this, tr("Interface"),
tr("There are some unsaved scripts, are you sure you want to close the editor? Changes will be lost!"),
QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel) == QMessageBox::Discard) {
event->accept();
} else {
event->ignore();
}
}
void ScriptEditorWindow::updateScriptNameOrStatus() {
ScriptEditorWidget* source = static_cast<ScriptEditorWidget*>(QObject::sender());
QString modifiedStar = (source->isModified()? "*" : "");
if (source->getScriptName().length() > 0) {
for (int i = 0; i < _ScriptEditorWindowUI->tabWidget->count(); i++){
if (_ScriptEditorWindowUI->tabWidget->widget(i) == source) {
_ScriptEditorWindowUI->tabWidget->setTabText(i, modifiedStar + QFileInfo(source->getScriptName()).fileName());
_ScriptEditorWindowUI->tabWidget->setTabToolTip(i, source->getScriptName());
}
}
}
if (_ScriptEditorWindowUI->tabWidget->currentWidget() == source) {
if (source->getScriptName().length() > 0) {
this->setWindowTitle("Script Editor [" + source->getScriptName() + modifiedStar + "]");
} else {
this->setWindowTitle("Script Editor [New script" + modifiedStar + "]");
}
}
}
void ScriptEditorWindow::terminateCurrentTab() {
if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) {
_ScriptEditorWindowUI->tabWidget->removeTab(_ScriptEditorWindowUI->tabWidget->currentIndex());
this->raise();
}
}
bool ScriptEditorWindow::autoReloadScripts() {
return _ScriptEditorWindowUI->autoReloadCheckBox->isChecked();
}
bool ScriptEditorWindow::event(QEvent* event) {
if (event->type() == QEvent::WindowActivate) {
emit windowActivated();
}
return QWidget::event(event);
}