view gui/src/MainWindow.cpp @ 13504:13e3d60aff2d

Replaced Quint with OctaveGUI.
author Jacob Dawid <jacob.dawid@googlemail.com>
date Sun, 17 Jul 2011 20:27:03 +0200
parents 86d6c3b90ad7
children c70511cf64ee
line wrap: on
line source

/* OctaveGUI - A graphical user interface for Octave
 * Copyright (C) 2011 Jacob Dawid
 * jacob.dawid@googlemail.com
 *
 * This program 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 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QSettings>
#include <QDesktopServices>
#include <QFileDialog>
#include "MainWindow.h"
#include "FileEditorMdiSubWindow.h"
#include "ImageViewerMdiSubWindow.h"
#include "SettingsDialog.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
      m_isRunning(true) {
    QDesktopServices desktopServices;
    m_settingsFile = desktopServices.storageLocation(QDesktopServices::HomeLocation) + "/.quint/settings.ini";
    construct();
    establishOctaveLink();
}

MainWindow::~MainWindow() {
}

void MainWindow::handleOpenFileRequest(QString fileName) {
    reportStatusMessage(tr("Opening file."));
    QPixmap pixmap;
    if(pixmap.load(fileName)) {
//        ImageViewerMdiSubWindow *subWindow = new ImageViewerMdiSubWindow(pixmap, this);
//        subWindow->setAttribute(Qt::WA_DeleteOnClose);
//        m_centralMdiArea->addSubWindow(subWindow);
//        subWindow->setWindowTitle(fileName);
    } else {
        FileEditorMdiSubWindow *subWindow = new FileEditorMdiSubWindow(m_centralMdiArea);
        subWindow->setAttribute(Qt::WA_DeleteOnClose);
// addSubWindow uncommented to avoid "QMdiArea::addSubWindow: window is already added"
//        m_centralMdiArea->addSubWindow(subWindow);
        subWindow->loadFile(fileName);
    }
}

void MainWindow::reportStatusMessage(QString statusMessage) {
    m_statusBar->showMessage(statusMessage, 1000);
}

void MainWindow::openWebPage(QString url) {
    m_documentationWidget->load(QUrl(url));
}

void MainWindow::handleSaveWorkspaceRequest() {
    QDesktopServices desktopServices;
    QString selectedFile = QFileDialog::getSaveFileName(this, tr("Save Workspace"),
        desktopServices.storageLocation(QDesktopServices::HomeLocation) + "/.quint/workspace");
    m_octaveTerminal->sendText(QString("save \'%1\'\n").arg(selectedFile));
    m_octaveTerminal->setFocus();
}

void MainWindow::handleLoadWorkspaceRequest() {
    QDesktopServices desktopServices;
    QString selectedFile = QFileDialog::getOpenFileName(this, tr("Load Workspace"),
        desktopServices.storageLocation(QDesktopServices::HomeLocation) + "/.quint/workspace");
    m_octaveTerminal->sendText(QString("load \'%1\'\n").arg(selectedFile));
    m_octaveTerminal->setFocus();
}

void MainWindow::handleClearWorkspaceRequest() {
    m_octaveTerminal->sendText("clear\n");
    m_octaveTerminal->setFocus();
}

void MainWindow::handleCommandDoubleClicked(QString command) {
    m_octaveTerminal->sendText(command);
    m_octaveTerminal->setFocus();
}

void MainWindow::alignMdiWindows() {
    m_centralMdiArea->tileSubWindows();
}

void MainWindow::openBugTrackerPage() {
    QDesktopServices::openUrl(QUrl("http://savannah.gnu.org/bugs/?group=octave"));
}

void MainWindow::processSettingsDialogRequest() {
    SettingsDialog settingsDialog(this, m_settingsFile);
    settingsDialog.exec();
}

void MainWindow::closeEvent(QCloseEvent *closeEvent) {
    m_isRunning = false;
    reportStatusMessage(tr("Saving data and shutting down."));
    writeSettings();

    m_octaveCallbackThread->terminate();
    m_octaveCallbackThread->wait();

    m_octaveMainThread->terminate();
    QMainWindow::closeEvent(closeEvent);
}

void MainWindow::readSettings() {
    QSettings settings(m_settingsFile, QSettings::IniFormat);
    restoreGeometry(settings.value("MainWindow/geometry").toByteArray());
    restoreState(settings.value("MainWindow/windowState").toByteArray());
}

void MainWindow::writeSettings() {
    QSettings settings(m_settingsFile, QSettings::IniFormat);
    settings.setValue("MainWindow/geometry", saveGeometry());
    settings.setValue("MainWindow/windowState", saveState());
}

void MainWindow::construct() {

    if(QFile::exists("../media/logo.png"))
        setWindowIcon(QIcon("../media/logo.png"));
    else
        setWindowIcon(QIcon("/usr/share/octave/quint/media/logo.png"));

    // Initialize MDI area.
    m_centralMdiArea = new QMdiArea(this);
    m_centralMdiArea->setObjectName("CentralMdiArea");
    m_centralMdiArea->setViewMode(QMdiArea::TabbedView);

    // Setup dockable widgets and the status bar.
    m_variablesDockWidget = new VariablesDockWidget(this);
    m_historyDockWidget = new HistoryDockWidget(this);
    m_filesDockWidget = new FilesDockWidget(this);
    m_statusBar = new QStatusBar(this);

    // Setup essential MDI Windows.
    m_octaveTerminal = new OctaveTerminal(this);
    m_documentationWidget = new BrowserWidget(this);
    m_ircWidget = new IRCWidget(this, m_settingsFile);

    m_documentationWidgetSubWindow = m_centralMdiArea->addSubWindow(m_documentationWidget,
        Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint);
    m_documentationWidgetSubWindow->setObjectName("DocumentationWidgetSubWindow");
    m_documentationWidgetSubWindow->setWindowTitle(tr("Documentation"));
    m_documentationWidgetSubWindow->setWindowIcon(QIcon("../media/help_index.png"));

    m_octaveTerminalSubWindow = m_centralMdiArea->addSubWindow(m_octaveTerminal,
        Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint);
    m_octaveTerminalSubWindow->setObjectName("OctaveTerminalSubWindow");
    m_octaveTerminalSubWindow->setWindowTitle(tr("Terminal"));
    m_octaveTerminalSubWindow->setWindowIcon(QIcon("../media/terminal.png"));

    m_ircWidgetSubWindow = m_centralMdiArea->addSubWindow(m_ircWidget,
        Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint);
    m_ircWidgetSubWindow->setObjectName("ChatWidgetSubWindow");
    m_ircWidgetSubWindow->setWindowTitle(tr("Chat"));
    m_ircWidgetSubWindow->setWindowIcon(QIcon("../media/chat.png"));

    QMenu *controlMenu = menuBar()->addMenu(tr("Octave"));
    QAction *settingsAction = controlMenu->addAction(tr("Settings"));
    controlMenu->addSeparator();
    QAction *exitAction = controlMenu->addAction(tr("Exit"));

    QMenu *interfaceMenu = menuBar()->addMenu(tr("Interface"));
    QAction *alignWindowsAction = interfaceMenu->addAction(tr("Align Windows"));

    QMenu *communityMenu = menuBar()->addMenu(tr("Community"));
    QAction *reportBugAction = communityMenu->addAction(tr("Report Bug"));

    connect(settingsAction, SIGNAL(triggered()), this, SLOT(processSettingsDialogRequest()));
    connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
    connect(alignWindowsAction, SIGNAL(triggered()), this, SLOT(alignMdiWindows()));
    connect(reportBugAction, SIGNAL(triggered()), this, SLOT(openBugTrackerPage()));

    setWindowTitle("Octave");
    setCentralWidget(m_centralMdiArea);
    addDockWidget(Qt::LeftDockWidgetArea, m_variablesDockWidget);
    addDockWidget(Qt::LeftDockWidgetArea, m_historyDockWidget);
    addDockWidget(Qt::RightDockWidgetArea, m_filesDockWidget);
    setStatusBar(m_statusBar);

    readSettings();

    connect(m_filesDockWidget, SIGNAL(openFile(QString)), this, SLOT(handleOpenFileRequest(QString)));
    connect(m_historyDockWidget, SIGNAL(information(QString)), this, SLOT(reportStatusMessage(QString)));
    connect(m_historyDockWidget, SIGNAL(commandDoubleClicked(QString)), this, SLOT(handleCommandDoubleClicked(QString)));
    connect(m_variablesDockWidget, SIGNAL(saveWorkspace()), this, SLOT(handleSaveWorkspaceRequest()));
    connect(m_variablesDockWidget, SIGNAL(loadWorkspace()), this, SLOT(handleLoadWorkspaceRequest()));
    connect(m_variablesDockWidget, SIGNAL(clearWorkspace()), this, SLOT(handleClearWorkspaceRequest()));

    openWebPage("http://www.gnu.org/software/octave/doc/interpreter/");
}

void MainWindow::establishOctaveLink() {
    m_octaveMainThread = new OctaveMainThread(this);
    m_octaveMainThread->start();

    m_octaveCallbackThread = new OctaveCallbackThread(this, this);
    m_octaveCallbackThread->start();

    command_editor::add_event_hook(OctaveLink::readlineEventHook);

    int fdm, fds;
    if(openpty(&fdm, &fds, 0, 0, 0) < 0) {
        assert(0);
    }
    dup2 (fds, 0);
    dup2 (fds, 1);
    dup2 (fds, 2);
    m_octaveTerminal->openTeletype(fdm);
    reportStatusMessage(tr("Established link to Octave."));
}