/* * Copyright (c) 2002-2006 Samit Basu * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "application.hpp" #include #include #include #include #include #include #include #include #include #include "Interpreter.hpp" #include "highlighter.hpp" #include "Editor.hpp" #include #include #include "PathTool.hpp" #include "ToolDock.hpp" const int about_linecount = 21; const char *about_strings[] = {"Julie Maya & Neil - My Fan Club", "Bruno De Man - New icon, general suggestions, support and FreeMat advocate", "Thomas Beutlich - MAT file support", "M. Vogel - Matlab compatibility scripts", "Brian Yanoff - Compatibility scripts", "Jeff Fessler - Support and test code, help with class support", "Al Danial - Help with sparse matrix support", "MT19937 - Takuji Nishimura and Makoto Matsumoto's random number generator", "RANLIB - Random number generator library", "ATLAS - Optimized BLAS", "LAPACK - Linear algebra", "UMFPACK - Sparse linear equation solver", "ARPACK - Sparse eigenvalue problems", "FFTW - Fast Fourier Transforms", "ffcall - Foreign Function interface", "Qt4 - Cross platform GUI and API", "libtecla - Inspiration for console interface code", "wxbasic - Inspiration for interpreter layout", "kde/konsole - Inspiration for QTTerm (GUI Console)", "tubeplot - Written by Anders Sandberg", "nsis - Installer on Win32"}; #define MAKEASCII(x) x.toAscii().constData() #include ApplicationWindow::~ApplicationWindow() { } void ApplicationWindow::createActions() { filetoolAct = new QAction("&File Browser",this); connect(filetoolAct,SIGNAL(triggered()),this,SLOT(filetool())); historyAct = new QAction("Show &History Tool",this); connect(historyAct,SIGNAL(triggered()),this,SLOT(history())); cleanHistoryAct = new QAction("&Clear History Tool",this); connect(cleanHistoryAct,SIGNAL(triggered()),this,SLOT(cleanhistory())); editorAct = new QAction("&Editor",this); connect(editorAct,SIGNAL(triggered()),this,SLOT(editor())); pathAct = new QAction("&Path Tool",this); connect(pathAct,SIGNAL(triggered()),this,SLOT(path())); saveAct = new QAction(QIcon(":/images/save.png"),"&Save Transcript",this); saveAct->setShortcut(Qt::Key_S | Qt::CTRL); connect(saveAct,SIGNAL(triggered()),this,SLOT(save())); clearAct = new QAction("&Clear Console",this); connect(clearAct,SIGNAL(triggered()),this,SLOT(clearconsole())); quitAct = new QAction(QIcon(":/images/quit.png"),"&Quit",this); connect(quitAct,SIGNAL(triggered()),this,SLOT(close())); copyAct = new QAction(QIcon(":/images/copy.png"),"&Copy",this); copyAct->setShortcut(Qt::Key_C | Qt::CTRL); connect(copyAct,SIGNAL(triggered()),this,SLOT(copy())); pasteAct = new QAction(QIcon(":/images/paste.png"),"&Paste",this); pasteAct->setShortcut(Qt::Key_V | Qt::CTRL); connect(pasteAct,SIGNAL(triggered()),this,SLOT(paste())); fontAct = new QAction("&Font",this); connect(fontAct,SIGNAL(triggered()),this,SLOT(font())); scrollbackAct = new QAction("&Scrollback Size",this); connect(scrollbackAct,SIGNAL(triggered()),this,SLOT(scrollback())); aboutAct = new QAction("&About",this); connect(aboutAct,SIGNAL(triggered()),this,SLOT(about())); manualAct = new QAction("Online &Manual",this); manualAct->setShortcut(Qt::Key_H | Qt::CTRL); connect(manualAct,SIGNAL(triggered()),this,SLOT(manual())); aboutQt = new QAction("About &Qt",this); connect(aboutQt,SIGNAL(triggered()),qApp,SLOT(aboutQt())); pauseAct = new QAction(QIcon(":/images/player_pause.png"),"&Pause",this); continueAct = new QAction(QIcon(":/images/player_play.png"),"&Continue",this); stopAct = new QAction(QIcon(":/images/player_stop.png"),"&Stop",this); dbStepAct = new QAction(QIcon(":/images/dbgnext.png"),"&Step Over",this); dbTraceAct = new QAction(QIcon(":/images/dbgstep.png"),"&Step Into",this); checkUpdates = new QAction("Check for Updated Software",this); } void ApplicationWindow::createMenus() { fileMenu = menuBar()->addMenu("&File"); fileMenu->addAction(saveAct); fileMenu->addAction(clearAct); fileMenu->addAction(quitAct); editMenu = menuBar()->addMenu("&Edit"); editMenu->addAction(copyAct); editMenu->addAction(pasteAct); QMenu* configMenu = editMenu->addMenu("&Preferences"); configMenu->addAction(fontAct); configMenu->addAction(scrollbackAct); debugMenu = menuBar()->addMenu("&Debug"); debugMenu->addAction(pauseAct); debugMenu->addAction(continueAct); debugMenu->addAction(stopAct); debugMenu->addAction(dbStepAct); debugMenu->addAction(dbTraceAct); toolsMenu = menuBar()->addMenu("&Tools"); toolsMenu->addAction(editorAct); toolsMenu->addAction(pathAct); toolsMenu->addAction(filetoolAct); historyMenu = toolsMenu->addMenu("&History"); historyMenu->addAction(historyAct); historyMenu->addAction(cleanHistoryAct); helpMenu = menuBar()->addMenu("&Help"); helpMenu->addAction(aboutAct); helpMenu->addAction(manualAct); helpMenu->addAction(aboutQt); helpMenu->addAction(checkUpdates); } bool ApplicationWindow::event(QEvent* e) { if (e->type() == QEvent::WindowActivate) { if (m_term) m_term->setFocus(Qt::MouseFocusReason); } return QMainWindow::event(e); } void ApplicationWindow::createToolBars() { editToolBar = addToolBar("Edit"); editToolBar->addAction(copyAct); editToolBar->addAction(pasteAct); editToolBar->setObjectName("edittoolbar"); debugToolBar = addToolBar("Debug"); debugToolBar->addAction(pauseAct); debugToolBar->addAction(continueAct); debugToolBar->addAction(stopAct); debugToolBar->addAction(dbStepAct); debugToolBar->addAction(dbTraceAct); debugToolBar->setObjectName("debugtoolbar"); } void ApplicationWindow::createStatusBar() { statusBar()->showMessage("Ready"); } ApplicationWindow::ApplicationWindow() : QMainWindow() { setWindowIcon(QPixmap(":/images/freemat_small_mod_64.png")); setWindowTitle(QString(Interpreter::getVersionString().c_str()) + " Command Window"); createActions(); createMenus(); createToolBars(); createStatusBar(); initializeTools(); createToolBox(); setObjectName("appwindow"); } void ApplicationWindow::createToolBox() { m_tool = new ToolDock(this); addDockWidget(Qt::RightDockWidgetArea, m_tool); } void ApplicationWindow::initializeTools() { } void ApplicationWindow::closeEvent(QCloseEvent* ce) { writeSettings(); delete m_tool; ce->accept(); exit(0); } void ApplicationWindow::readSettings() { QSettings settings("FreeMat", "FreeMat"); QPoint pos = settings.value("mainwindow/pos", QPoint(200, 200)).toPoint(); QSize size = settings.value("mainwindow/size", QSize(600, 400)).toSize(); if ((pos.x() < 0) || (pos.y() < 0)) pos = QPoint(200,200); resize(size); move(pos); QByteArray state = settings.value("mainwindow/state").toByteArray(); restoreState(state); } void ApplicationWindow::writeSettings() { QSettings settings("FreeMat", "FreeMat"); settings.setValue("mainwindow/state",saveState()); settings.setValue("mainwindow/pos", pos()); settings.setValue("mainwindow/size", size()); settings.sync(); } void ApplicationWindow::tclose() { close(); } void ApplicationWindow::SetGUITerminal(QTTerm* term) { m_term = term; setCentralWidget(term); term->show(); } void ApplicationWindow::clearconsole() { m_keys->ClearDisplayCommand(); } void ApplicationWindow::SetKeyManager(KeyManager *keys) { m_keys = keys; connect(keys,SIGNAL(SendCommand(QString)), m_tool->getHistoryWidget(),SLOT(addCommand(QString))); connect(m_tool->getHistoryWidget(),SIGNAL(clearHistory()), keys,SLOT(ClearHistory())); connect(m_tool->getHistoryWidget(),SIGNAL(sendCommand(QString)), keys,SLOT(QueueCommand(QString))); connect(m_tool->getFileTool(),SIGNAL(sendCommand(QString)), keys,SLOT(QueueMultiString(QString))); connect(keys,SIGNAL(UpdateCWD()), m_tool->getFileTool(),SLOT(updateCWD())); connect(keys,SIGNAL(UpdateVariables()), m_tool->getVariablesTool(),SLOT(refresh())); connect(pauseAct,SIGNAL(triggered()),m_keys,SIGNAL(RegisterInterrupt())); connect(continueAct,SIGNAL(triggered()),m_keys,SLOT(ContinueAction())); connect(stopAct,SIGNAL(triggered()),m_keys,SLOT(StopAction())); connect(dbStepAct,SIGNAL(triggered()),m_keys,SLOT(DbStepAction())); connect(dbTraceAct,SIGNAL(triggered()),m_keys,SLOT(DbTraceAction())); connect(checkUpdates,SIGNAL(triggered()),this,SLOT(checkForUpdates())); } void ApplicationWindow::save() { QString fn = QFileDialog::getSaveFileName(); if (!fn.isEmpty()) { FILE *fp; fp = fopen(MAKEASCII(fn),"w"); if (!fp) { char buffer[1000]; sprintf(buffer,"Unable to save transcript to file %s!", MAKEASCII(fn)); QMessageBox::information(this,"Error",buffer, QMessageBox::Ok); return; } fprintf(fp,"%s",m_term->getAllText().toStdString().c_str()); fclose(fp); } } void ApplicationWindow::copy() { QString copytextbuf = m_term->getSelectionText(); QClipboard *cb = QApplication::clipboard(); cb->setText(copytextbuf, QClipboard::Clipboard); } void ApplicationWindow::paste() { QClipboard *cb = QApplication::clipboard(); QString text; if (cb->supportsSelection()) text = cb->text(QClipboard::Selection); if (text.isNull()) text = cb->text(QClipboard::Clipboard); text.replace("\r\n","\n"); text.replace("\r","\n"); if (!text.isNull()) { m_keys->QueueMultiString(text); m_term->clearSelection(); } } void ApplicationWindow::scrollback() { int scroll_limit = m_term->getScrollbackLimit(); bool ok; int new_limit = QInputDialog::getInteger(this, "Change Scrollback of Command Window", "Lines:",scroll_limit,100,10000, 1,&ok); if (ok) { QSettings settings("FreeMat","FreeMat"); settings.setValue("console/scrollback",new_limit); m_term->setScrollbackLimit(new_limit); } } void ApplicationWindow::font() { QFont old_font = m_term->getFont(); bool ok; QFont new_font = QFontDialog::getFont(&ok, old_font, this); if (ok) { QSettings settings("FreeMat","FreeMat"); settings.setValue("terminal/font",new_font.toString()); m_term->setFont(new_font); } } void ApplicationWindow::manual() { emit startHelp(); } void ApplicationWindow::editor() { emit startEditor(); } void ApplicationWindow::path() { emit startPathTool(); } void ApplicationWindow::filetool() { m_tool->show(); m_tool->getFileTool()->show(); } void ApplicationWindow::history() { m_tool->show(); m_tool->getHistoryWidget()->show(); } void ApplicationWindow::cleanhistory() { m_tool->getHistoryWidget()->clear(); } void ApplicationWindow::about() { QString text; text += "FreeMat Version "; text += VERSION; text += "\n\n"; text += "Licensed under the GNU Public License Ver 2\n"; text += "Web: http://freemat.sf.net\n"; text += "Email: freemat@googlegroup.com\n"; QMessageBox::about(this,"About FreeMat",text); } void ApplicationWindow::init() { m_tool->getVariablesTool()->setContext(m_keys->GetCompletionContext()); // Check for the latest version? QSettings settings("FreeMat","FreeMat"); QDate lastCheck = settings.value("lastcheckdate").toDate(); if (QDate::currentDate().daysTo(lastCheck) > 7) { checkForUpdates(); } QString font = settings.value("terminal/font").toString(); if (!font.isNull()) { QFont new_font; new_font.fromString(font); m_term->setFont(new_font); } } void ApplicationWindow::checkForUpdates() { m_http = new QHttp(this); connect(m_http, SIGNAL(requestFinished(int, bool)), this, SLOT(httpRequestFinished(int, bool))); QUrl url("http://freemat.sourceforge.net/version.txt"); m_buffer.open(QBuffer::ReadWrite); m_http->setHost(url.host(), url.port() != -1 ? url.port() : 80); httpGetId = m_http->get(url.path(), &m_buffer); QSettings settings("FreeMat","FreeMat"); settings.setValue("lastcheckdate",QDate::currentDate()); } void ApplicationWindow::httpRequestFinished(int requestId, bool error) { char buffer[1000]; if (error) statusBar()->showMessage("Unable to check for updates..."); if (requestId != httpGetId) return; const char *qp = m_buffer.data(); if (atof(VERSION) < atof(m_buffer.data())) { sprintf(buffer,"A newer version of FreeMat appears to available. \n Please update by downloading version %s at http://freemat.sourceforge.net.",qp); QMessageBox::information(this,"Update Available", buffer,QMessageBox::Ok); } else statusBar()->showMessage("You are running the latest version of FreeMat"); }