/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set et sw=2 ts=2: */ /*************************************************************************** * mainwindow.cc * * Sat Aug 4 13:37:18 CEST 2012 * Copyright 2012 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of Kaiman. * * Kaiman is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Kaiman is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Kaiman; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "mainwindow.h" #include "outputwindow.h" #include #include #include #include #include #include #include #include #include #include #include #include MainWindow::MainWindow(QString p) { // Watch file on disk? //connect(&watcher, SIGNAL(fileChanged(const QString &)), // this, SLOT(reset())); //watcher.addPath(program); splitter = new QSplitter(); setCentralWidget(splitter); editor = new CodeEditor(); splitter->addWidget(editor); connect(editor, SIGNAL(textChanged()), this, SLOT(programChanged())); highlighter = new Highlighter(editor->document()); out = new OutputWindow(); splitter->addWidget(out); l = new LUAScript(*out); connect(l, SIGNAL(lineChanged(int)), editor, SLOT(runningLine(int))); connect(l, SIGNAL(errorLine(QString, int, QString)), editor, SLOT(errorLine(QString, int, QString))); // Setup menu QMenu* fileMenu = menuBar()->addMenu(tr("&File")); { QAction* act = new QAction(tr("&New File"), this); fileMenu->addAction(act); connect(act, SIGNAL(triggered()), this, SLOT(newFile())); } { QAction* act = new QAction(tr("&Load File..."), this); fileMenu->addAction(act); connect(act, SIGNAL(triggered()), this, SLOT(loadFile())); } { act_save = new QAction(tr("&Save File"), this); fileMenu->addAction(act_save); connect(act_save, SIGNAL(triggered()), this, SLOT(saveFile())); } { QAction* act = new QAction(tr("Save File As..."), this); fileMenu->addAction(act); connect(act, SIGNAL(triggered()), this, SLOT(saveFileAs())); } { QAction* act = new QAction(tr("&Quit"), this); fileMenu->addAction(act); connect(act, SIGNAL(triggered()), this, SLOT(close())); } // Setup toolbar QToolBar *toolbar = new QToolBar(); toolbar->setObjectName("Execution"); addToolBar(Qt::TopToolBarArea, toolbar); { QAction *act = toolbar->addAction("Start"); connect(act, SIGNAL(triggered()), this, SLOT(start())); } { QAction *act = toolbar->addAction("Stop"); connect(act, SIGNAL(triggered()), this, SLOT(stop())); } { QAction *act = toolbar->addAction("Reset"); connect(act, SIGNAL(triggered()), this, SLOT(reset())); } { QAction *act = toolbar->addAction("Image"); connect(act, SIGNAL(triggered()), this, SLOT(image())); } loadSettings(); statusBar()->showMessage(tr("Ready")); updateWindowTitle(); setWindowEnabled(false); reset(); if(!p.isEmpty()) { loadFile(p); } } void MainWindow::closeEvent(QCloseEvent* event) { if(!checkDirty()) { event->ignore(); return; } saveSettings(); event->accept(); } void MainWindow::loadSettings() { QByteArray state; QByteArray geometry; QSettings settings; settings.beginGroup("MainWindow"); state = settings.value("state").toByteArray(); geometry = settings.value("geometry").toByteArray(); splitter->restoreState(settings.value("splitter").toByteArray()); settings.endGroup(); settings.beginGroup("Canvas"); out->setScale(settings.value("scale", 2.0).toDouble()); settings.endGroup(); restoreGeometry(geometry); restoreState(state); } void MainWindow::saveSettings() { QSettings settings; settings.beginGroup("MainWindow"); settings.setValue("state", saveState()); settings.setValue("geometry", saveGeometry()); settings.setValue("splitter", splitter->saveState()); settings.endGroup(); settings.beginGroup("Canvas"); settings.setValue("scale", out->getScale()); settings.endGroup(); } bool MainWindow::checkDirty() { if(dirty) { int ret = QMessageBox::question(this, tr("Save before closing project?"), tr("The file has changed. Do you want to save " "before closing?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); switch(ret) { case QMessageBox::Yes: saveFile(); if(dirty) { // Project still dirty - it was not saved (user pressed cancel?) return false; } break; case QMessageBox::No: // Proceed to quit break; case QMessageBox::Cancel: return false; default: break; } } return true; // not dirty or user chose not to save } void MainWindow::setWindowEnabled(bool enabled) { editor->setEnabled(enabled); } void MainWindow::updateWindowTitle() { QString window_title_string; if(program != "") { window_title_string += " (" + QFileInfo(program).fileName() + ")"; } act_save->setEnabled(!program.isEmpty()); if(dirty) { window_title_string += "*"; } setWindowTitle("Kaiman - " + window_title_string); } void MainWindow::newFile() { if(!checkDirty()) { return; } reset(); setWindowEnabled(true); } void MainWindow::loadFile() { if(!checkDirty()) { return; } QString filename = QFileDialog::getOpenFileName(this, tr("Load Kaiman File"), "", tr("Kaiman Files (*.lua)")); if(filename == "") { // User clicked cancel return; } loadFile(filename); } void MainWindow::loadFile(QString filename) { QFile file(filename); if(!file.open(QIODevice::ReadOnly)) { return; } editor->setPlainText(file.readAll()); file.close(); l->setScriptFile(filename); program = filename; dirty = false; updateWindowTitle(); statusBar()->showMessage(tr("Loaded")); setWindowEnabled(true); } void MainWindow::saveFile() { QString filename = program; if(filename == "") { saveFileAs(); return; } QFile file(program); if(!file.open(QIODevice::WriteOnly)) { return; } QString code = editor->toPlainText(); file.write(code.toLocal8Bit()); file.close(); dirty = false; updateWindowTitle(); statusBar()->showMessage(tr("Saved")); } void MainWindow::saveFileAs() { QString filename = QFileDialog::getSaveFileName(this, tr("Save Kaiman File"), "", tr("Kaiman Files (*.lua)")); if(filename == "") { // User clicked cancel return; } if(filename.right(4) != ".lua") { filename += ".lua"; } program = filename; saveFile(); } void MainWindow::start() { reset(); saveFile(); l->start(); } void MainWindow::stop() { out->stopScript(); l->stopScript(); } void MainWindow::reset() { stop(); out->reset(); } void MainWindow::image() { QString filename = QFileDialog::getSaveFileName(this, tr("Save Kaiman File"), "", tr("Image Files (*.png)")); if(filename == "") { // User clicked cancel return; } if(filename.right(4) != ".png") { filename += ".png"; } auto image = out->acquire(true); image.save(filename); } void MainWindow::programChanged() { dirty = true; updateWindowTitle(); }