SpikeStream Application Library  0.2
SpikeStreamMainWindow.cpp
Go to the documentation of this file.
00001 //SpikeStream includes
00002 #include "AnalysisLoaderWidget.h"
00003 #include "SpikeStreamMainWindow.h"
00004 #include "GlobalVariables.h"
00005 #include "ConfigLoader.h"
00006 #include "Globals.h"
00007 #include "SpikeStreamException.h"
00008 #include "NetworksWidget.h"
00009 #include "ArchiveWidget.h"
00010 #include "NeuronGroupWidget.h"
00011 #include "ConnectionWidget.h"
00012 #include "NetworkViewer.h"
00013 #include "NetworkViewerProperties.h"
00014 #include "SimulationLoaderWidget.h"
00015 #include "Util.h"
00016 using namespace spikestream;
00017 
00018 //Qt includes
00019 #include <qsplitter.h>
00020 #include <qsplashscreen.h>
00021 #include <qpixmap.h>
00022 #include <qmenubar.h>
00023 #include <qmessagebox.h>
00024 #include <qapplication.h>
00025 #include <qfile.h>
00026 #include <QCloseEvent>
00027 #include <QDebug>
00028 #include <QScrollArea>
00029 
00030 //Other includes
00031 #include <string>
00032 using namespace std;
00033 
00034 
00036 SpikeStreamMainWindow::SpikeStreamMainWindow() : QMainWindow(){
00037         setWindowTitle("SpikeStream");
00038 
00039         try{
00040                 //Get the working directory and store in global scope
00041                 QString rootDir = Util::getRootDirectory();
00042                 Globals::setSpikeStreamRoot(rootDir);
00043 
00044                 //Set up splash screen to give feedback whilst application is loading
00045                 QSplashScreen *splashScreen = 0;
00046                 QPixmap splashPixmap(Globals::getSpikeStreamRoot() + "/images/spikestream_splash.png" );
00047                 splashScreen = new QSplashScreen( splashPixmap );
00048                 splashScreen->show();
00049 
00050                 //Set up application and GUI
00051                 initializeApplication();
00052 
00053                 //Get rid of splash screen if it is showing
00054                 if(splashScreen){
00055                         splashScreen->finish( this );
00056                         delete splashScreen;
00057                 }
00058         }
00059         catch(SpikeStreamException& ex){
00060                 qCritical()<<ex.getMessage();
00061                 exit(1);
00062         }
00063         catch(...){
00064                 qCritical()<<"An unknown exception occurred setting up application.";
00065                 exit(1);
00066         }
00067 }
00068 
00069 
00071 SpikeStreamMainWindow::~SpikeStreamMainWindow(){
00072         //Clean up globals - everything stored in globals is cleaned up by globals
00073         Globals::cleanUp();
00074 
00075         delete databaseManager;
00076 }
00077 
00078 
00079 /*----------------------------------------------------------*/
00080 /*-----                PROTECTED METHODS               -----*/
00081 /*----------------------------------------------------------*/
00082 
00084 void SpikeStreamMainWindow::closeEvent (QCloseEvent* event){
00085         if(databaseManager->isRunning()){
00086                 qWarning()<<"Database manager is still running, it is recommended that you wait for it to complete";
00087                 event->ignore();
00088                 return;
00089         }
00090 
00091         //Nothing will be running or unsaved if no network is loaded
00092         if(!Globals::networkLoaded()) {
00093                 event->accept();
00094                 return;
00095         }
00096 
00097         //Check for simulation loaded
00098         if(Globals::isSimulationLoaded()){
00099                 qWarning()<<"SpikeStream should not be quit with a simulation loaded.\nUnload the simulation and try again.";
00100                 event->ignore();
00101                 return;
00102         }
00103 
00104         //Check for analysis running
00105         if(Globals::isAnalysisRunning()){
00106                 int response = QMessageBox::warning(this, "Quit SpikeStream?", "Analysis is running.\nAre you sure that you want to quit SpikeStream?", QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
00107                 if(response != QMessageBox::Ok){
00108                         event->ignore();
00109                         return;
00110                 }
00111         }
00112 
00113         //Check for network save
00114         if(!Globals::getNetwork()->isSaved()){
00115                 int response = QMessageBox::warning(this, "Quit SpikeStream?", "Network has not been saved.\nAre you sure that you want to quit SpikeStream?", QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
00116                 if(response != QMessageBox::Ok){
00117                         event->ignore();
00118                         return;
00119                 }
00120         }
00121 
00122         //Clean up Globals
00123         Globals::cleanUp();
00124 
00125         //Accept event if checks have been passed.
00126         event->accept();
00127 }
00128 
00129 
00130 /*----------------------------------------------------------*/
00131 /*-----                PRIVATE SLOTS                   -----*/
00132 /*----------------------------------------------------------*/
00133 
00135 void SpikeStreamMainWindow::about(){
00136         QMessageBox::about( this, "About", "SpikeStream Version 0.2\nCreated by David Gamez: www.davidgamez.eu.\nOther contributors: Andreas Fidjeland.");
00137 }
00138 
00139 
00141 void SpikeStreamMainWindow::databaseManagerFinished(){
00142         //Check for errors
00143         if(databaseManager->isError())
00144                 qCritical()<<databaseManager->getErrorMessage();
00145 
00146         if(databaseManager->getTaskID() == DatabaseManager::CLEAR_DATABASES_TASK){
00147                 //Inform other classes about the change
00148                 Globals::setNetwork(NULL);
00149                 Globals::getEventRouter()->reloadSlot();
00150                 progressDialog->hide();
00151                 delete progressDialog;
00152         }
00153 }
00154 
00155 
00157 void SpikeStreamMainWindow::showAnalysisWidget(){
00158         tabWidget->setCurrentIndex(5);
00159 }
00160 
00161 
00163 void SpikeStreamMainWindow::showArchiveWidget(){
00164         tabWidget->setCurrentIndex(4);
00165 }
00166 
00167 
00169 void SpikeStreamMainWindow::showEditorWidget(){
00170         tabWidget->setCurrentIndex(1);
00171 }
00172 
00173 
00175 void SpikeStreamMainWindow::showNetworkWidget(){
00176         tabWidget->setCurrentIndex(0);
00177 }
00178 
00179 
00181 void SpikeStreamMainWindow::showSimulationWidget(){
00182         tabWidget->setCurrentIndex(3);
00183 }
00184 
00185 
00187 void SpikeStreamMainWindow::showViewerWidget(){
00188         tabWidget->setCurrentIndex(2);
00189 }
00190 
00191 
00195 void SpikeStreamMainWindow::clearDatabases(){
00196         //Confirm that user wants to take this action.
00197         QMessageBox msgBox;
00198         msgBox.setText("Clearing Database");
00199         msgBox.setInformativeText("Are you sure that you want to clear the database completely?\nAll data will be lost and this step cannot be undone.");
00200         msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
00201         msgBox.setDefaultButton(QMessageBox::Cancel);
00202         int ret = msgBox.exec();
00203         if(ret != QMessageBox::Ok)
00204                 return;
00205 
00206         //Instruct database manager to delete all networks
00207         progressDialog = new QProgressDialog("Clearing databases, please wait", "", 0, 0, this, Qt::CustomizeWindowHint);
00208         progressDialog->setWindowModality(Qt::WindowModal);
00209         progressDialog->setCancelButton(0);//Cannot implement cancel sensibly
00210         databaseManager->startClearDatabases();
00211         progressDialog->show();
00212 }
00213 
00214 
00217 void SpikeStreamMainWindow::loadDatabases(){
00218         qWarning()<<"Load database method not implemented";
00219 }
00220 
00221 
00225 void SpikeStreamMainWindow::saveDatabases(){
00226         qWarning()<<"Save databases method not implementd";
00227 }
00228 
00229 
00230 /*----------------------------------------------------------*/
00231 /*-----                PRIVATE METHODS                 -----*/
00232 /*----------------------------------------------------------*/
00233 
00235 void SpikeStreamMainWindow::initializeApplication(){
00236         //Set up config
00237         ConfigLoader* configLoader = new ConfigLoader();
00238 
00239         //Set up the data access objects wrapping the network database
00240         DBInfo netDBInfo(
00241                         configLoader->getParameter("spikeStreamNetworkHost"),
00242                         configLoader->getParameter("spikeStreamNetworkUser"),
00243                         configLoader->getParameter("spikeStreamNetworkPassword"),
00244                         "SpikeStreamNetwork"
00245         );
00246 
00247         //Create network data access object
00248         NetworkDao* networkDao = new NetworkDao(netDBInfo);
00249         Globals::setNetworkDao(networkDao);
00250 
00251         //Set up the data access objects wrapping the archive database.
00252         DBInfo archiveDBInfo(
00253                         configLoader->getParameter("spikeStreamArchiveHost"),
00254                         configLoader->getParameter("spikeStreamArchiveUser"),
00255                         configLoader->getParameter("spikeStreamArchivePassword"),
00256                         "SpikeStreamArchive"
00257         );
00258 
00259         //Create archive data access object
00260         ArchiveDao* archiveDao = new ArchiveDao(archiveDBInfo);
00261         Globals::setArchiveDao(archiveDao);
00262 
00263         //Set up the data access object wrapping the analysis database.
00264         DBInfo analysisDBInfo(
00265                         configLoader->getParameter("spikeStreamAnalysisHost"),
00266                         configLoader->getParameter("spikeStreamAnalysisUser"),
00267                         configLoader->getParameter("spikeStreamAnalysisPassword"),
00268                         "SpikeStreamAnalysis"
00269         );
00270 
00271         //Create analysis data access object
00272         AnalysisDao* analysisDao = new AnalysisDao(analysisDBInfo);
00273         Globals::setAnalysisDao(analysisDao);
00274 
00275         //Create Database manager
00276         databaseManager = new DatabaseManager(Globals::getNetworkDao()->getDBInfo(), Globals::getArchiveDao()->getDBInfo(), Globals::getAnalysisDao()->getDBInfo());
00277         connect(databaseManager, SIGNAL(finished()), this, SLOT(databaseManagerFinished()), Qt::UniqueConnection);
00278         progressDialog = NULL;
00279 
00280         //Get the default location for saving and loading databases
00281         Globals::setWorkingDirectory(configLoader->getParameter("default_file_location"));
00282 
00283         //Load display settings from configuration file
00284         Globals::getNetworkDisplay()->loadDisplaySettings(configLoader);
00285 
00286         //Actions
00287         //Add OpenGL actions
00288         QAction* moveUpAction = new QAction(this);
00289         moveUpAction->setShortcut(QKeySequence(Qt::Key_Up));
00290         connect(moveUpAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(moveUpSlot()));
00291         this->addAction(moveUpAction);
00292 
00293         QAction* moveDownAction = new QAction(this);
00294         moveDownAction->setShortcut(QKeySequence(Qt::Key_Down));
00295         connect(moveDownAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(moveDownSlot()));
00296         this->addAction(moveDownAction);
00297 
00298         QAction* moveLeftAction = new QAction(this);
00299         moveLeftAction->setShortcut(QKeySequence(Qt::Key_Left));
00300         connect(moveLeftAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(moveLeftSlot()));
00301         this->addAction(moveLeftAction);
00302 
00303         QAction* moveRightAction = new QAction(this);
00304         moveRightAction->setShortcut(QKeySequence(Qt::Key_Right));
00305         connect(moveRightAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(moveRightSlot()));
00306         this->addAction(moveRightAction);
00307 
00308         QAction* moveForwardAction = new QAction(this);
00309         moveForwardAction->setShortcut(QKeySequence(Qt::Key_PageUp));
00310         connect(moveForwardAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(moveForwardSlot()));
00311         this->addAction(moveForwardAction);
00312 
00313         QAction* moveBackwardAction = new QAction(this);
00314         moveBackwardAction->setShortcut(QKeySequence(Qt::Key_PageDown));
00315         connect(moveBackwardAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(moveBackwardSlot()));
00316         this->addAction(moveBackwardAction);
00317 
00318         QAction* resetViewAction = new QAction(this);
00319         resetViewAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R));
00320         connect(resetViewAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(resetViewSlot()));
00321         this->addAction(resetViewAction);
00322 
00323         QAction* rotateUpAction = new QAction(this);
00324         rotateUpAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Up));
00325         connect(rotateUpAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(rotateUpSlot()));
00326         this->addAction(rotateUpAction);
00327 
00328         QAction* rotateDownAction = new QAction(this);
00329         rotateDownAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down));
00330         connect(rotateDownAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(rotateDownSlot()));
00331         this->addAction(rotateDownAction);
00332 
00333         QAction* rotateLeftAction = new QAction(this);
00334         rotateLeftAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Left));
00335         connect(rotateLeftAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(rotateLeftSlot()));
00336         this->addAction(rotateLeftAction);
00337 
00338         QAction* rotateRightAction = new QAction(this);
00339         rotateRightAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Right));
00340         connect(rotateRightAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(rotateRightSlot()));
00341         this->addAction(rotateRightAction);
00342 
00343         //Simulation actions
00344         QAction* startStopSimulationAction = new QAction(this);
00345         startStopSimulationAction->setShortcut(QKeySequence(Qt::Key_Space));
00346         connect(startStopSimulationAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(startStopSimulationSlot()));
00347         this->addAction(startStopSimulationAction);
00348 
00349         QAction* stepSimulationAction = new QAction(this);
00350         stepSimulationAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Space));
00351         connect(stepSimulationAction, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(stepSimulationSlot()));
00352         this->addAction(stepSimulationAction);
00353 
00354         //Show/hide all connection groups
00355         QAction* showAllNoneConnectionsActions = new QAction(this);
00356         showAllNoneConnectionsActions->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_W));
00357         connect(showAllNoneConnectionsActions, SIGNAL(triggered()), Globals::getEventRouter(), SLOT(showAllOrNoneConnectionsSlot()));
00358         this->addAction(showAllNoneConnectionsActions);
00359 
00360         //Set up menus.
00361         //Add file menu.
00362         QMenu * fileMenu = new QMenu("File", this);
00363         menuBar()->addMenu(fileMenu);
00364         fileMenu->addAction("Clear databases", this, SLOT(clearDatabases()));
00365         fileMenu->addSeparator();
00366         fileMenu->addAction("Quit", qApp, SLOT(closeAllWindows()), Qt::CTRL+Qt::Key_Q);
00367 
00368         //Add refresh menu for when changes have been made in the database independently of the application
00369         QMenu *viewMenu = new QMenu("View", this);
00370         menuBar()->addMenu(viewMenu);
00371 
00372         //Reload everything is broadcast to all classes connected to the event router
00373         viewMenu->addAction("Reload everything", Globals::getEventRouter(), SLOT(reloadSlot()), Qt::CTRL + Qt::Key_F5);
00374 
00375         //Add help menu
00376         QMenu *helpMenu = new QMenu("Help", this);
00377         menuBar()->addMenu(helpMenu);
00378         helpMenu->addAction("About", this , SLOT(about()), Qt::Key_F12);
00379 
00380         //Set up panes
00381         //Set up main splitter, which will divide graphical view from editor/viewer/simulator windows
00382         QSplitter *mainSplitterWidget = new QSplitter(this);
00383         tabWidget = new QTabWidget(mainSplitterWidget);
00384 
00385         //Add networks tab
00386         QScrollArea* networksScrollArea = new QScrollArea();
00387         NetworksWidget* networksWidget = new NetworksWidget(networksScrollArea);
00388         networksScrollArea->setWidget(networksWidget);
00389         tabWidget->addTab(networksScrollArea, "Networks");
00390 
00391         //Set up editor window
00392         QSplitter *layerSplitterWidget = new QSplitter(tabWidget);
00393         NeuronGroupWidget* neuronGrpWidget = new NeuronGroupWidget();
00394         ConnectionWidget* conWidget = new ConnectionWidget();
00395         layerSplitterWidget->addWidget(neuronGrpWidget);
00396         layerSplitterWidget->addWidget(conWidget);
00397         layerSplitterWidget->setOrientation(Qt::Vertical);
00398         tabWidget->addTab(layerSplitterWidget, "Editor");
00399 
00400         //Create network viewer for right half of screen
00401         NetworkViewer* networkViewer = new NetworkViewer(mainSplitterWidget);
00402 
00403         //Set up viewer tab
00404         QScrollArea* networkViewPropsScrollArea = new QScrollArea(tabWidget);
00405         NetworkViewerProperties* networkViewerProperties = new NetworkViewerProperties(networkViewPropsScrollArea);
00406         networkViewPropsScrollArea->setWidget(networkViewerProperties);
00407         tabWidget->addTab(networkViewPropsScrollArea, "Viewer");
00408 
00409         //Set up simulation tab
00410         QScrollArea* simulationScrollArea = new QScrollArea(tabWidget);
00411         SimulationLoaderWidget* simulationWidget = new SimulationLoaderWidget();
00412         simulationScrollArea->setWidget(simulationWidget);
00413         tabWidget->addTab(simulationScrollArea, "Simulation");
00414 
00415         //Set up archive tab
00416         QScrollArea* archiveScrollArea = new QScrollArea(tabWidget);
00417         ArchiveWidget* archiveWidget = new ArchiveWidget();
00418         archiveScrollArea->setWidget(archiveWidget);
00419         tabWidget->addTab(archiveScrollArea, "Archives");
00420 
00421         //Set up analysis tab
00422         QScrollArea* analysisScrollArea = new QScrollArea(tabWidget);
00423         AnalysisLoaderWidget* analysisLoaderWidget = new AnalysisLoaderWidget();
00424         analysisScrollArea->setWidget(analysisLoaderWidget);
00425         tabWidget->addTab(analysisScrollArea, "Analysis");
00426 
00427         //Add all  the key combinations that will be required.
00428         QAction* showNetworkWidgetAction = new QAction(this);
00429         showNetworkWidgetAction->setShortcut(QKeySequence(Qt::Key_F1));
00430         connect(showNetworkWidgetAction, SIGNAL(triggered()), this, SLOT(showNetworkWidget()));
00431         this->addAction(showNetworkWidgetAction);
00432 
00433         QAction* showEditorWidgetAction = new QAction(this);
00434         showEditorWidgetAction->setShortcut(QKeySequence(Qt::Key_F2));
00435         connect(showEditorWidgetAction, SIGNAL(triggered()), this, SLOT(showEditorWidget()));
00436         this->addAction(showEditorWidgetAction);
00437 
00438         QAction* showViewerWidgetAction = new QAction(this);
00439         showViewerWidgetAction->setShortcut(QKeySequence(Qt::Key_F3));
00440         connect(showViewerWidgetAction, SIGNAL(triggered()), this, SLOT(showViewerWidget()));
00441         this->addAction(showViewerWidgetAction);
00442 
00443         QAction* showSimulationWidgetAction = new QAction(this);
00444         showSimulationWidgetAction->setShortcut(QKeySequence(Qt::Key_F4));
00445         connect(showSimulationWidgetAction, SIGNAL(triggered()), this, SLOT(showSimulationWidget()));
00446         this->addAction(showSimulationWidgetAction);
00447 
00448         QAction* showArchiveWidgetAction = new QAction(this);
00449         showArchiveWidgetAction->setShortcut(QKeySequence(Qt::Key_F5));
00450         connect(showArchiveWidgetAction, SIGNAL(triggered()), this, SLOT(showArchiveWidget()));
00451         this->addAction(showArchiveWidgetAction);
00452 
00453         QAction* showAnalysisWidgetAction = new QAction(this);
00454         showAnalysisWidgetAction->setShortcut(QKeySequence(Qt::Key_F6));
00455         connect(showAnalysisWidgetAction, SIGNAL(triggered()), this, SLOT(showAnalysisWidget()));
00456         this->addAction(showAnalysisWidgetAction);
00457 
00458         //Finish off
00459         QPixmap iconPixmap(Globals::getSpikeStreamRoot() + "/images/spikestream_icon_64.png" );
00460         setWindowIcon(iconPixmap);
00461         setCentralWidget( mainSplitterWidget );
00462         if( Util::getBool(configLoader->getParameter("maximize_gui") ))
00463                 setWindowState(Qt::WindowMaximized);
00464 
00465         networkViewer->reset();
00466 
00467         //Delete config loader
00468         delete configLoader;
00469 }
00470 
00471 
 All Classes Files Functions Variables Typedefs Friends Defines