/*
* 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 <qapplication.h>
#include <qmenubar.h>
#include <qmessagebox.h>
#include <qpixmap.h>
#include <qfiledialog.h>
#include <qclipboard.h>
#include <iostream>
#include <qfontdialog.h>
#include <qsettings.h>
#include "Interpreter.hpp"
#include "highlighter.hpp"
#include "Editor.hpp"
#include <QtGui>
#include <QDebug>
#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 <QtGui>
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");
}
syntax highlighted by Code2HTML, v. 0.9.1