SpikeStream Application Library
0.2
|
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