Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

LoadArchiveDialog.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   SpikeStream Application                                               *
00003  *   Copyright (C) 2007 by David Gamez                                     *
00004  *   david@davidgamez.eu                                                   *
00005  *   Version 0.1                                                           *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************/
00022 
00023 //SpikeStream includes
00024 #include "LoadArchiveDialog.h"
00025 #include "NameDialog.h"
00026 #include "Debug.h"
00027 #include "Utilities.h"
00028 #include "ArchiveWidget.h"
00029 #include "SimulationWidget.h"
00030 
00031 //Qt includes
00032 #include <qlayout.h>
00033 #include <qaccel.h>
00034 #include <qpushbutton.h>
00035 #include <qmessagebox.h>
00036 
00037 //Other includes
00038 #include <mysql++.h>
00039 #include <iostream>
00040 using namespace std;
00041 using namespace mysqlpp;
00042 
00043 
00044 /*! Constructor. */
00045 LoadArchiveDialog::LoadArchiveDialog(QWidget *parent, DBInterface *archDBInter) : QDialog(parent){
00046         //Store reference to archive database
00047         archiveDBInterface = archDBInter;
00048 
00049         //Set caption
00050     setCaption( "Load Archive" );
00051 
00052         //Create box to organise vertical layout of dialog
00053         QVBoxLayout *mainVerticalBox = new QVBoxLayout(this, 5, 10, "Main vertical Box");
00054         
00055         //Set up table
00056         archiveList = new QListBox(this);
00057         archiveList->setMinimumSize(350, 400);
00058         archiveList->setBaseSize(350, 400);
00059 
00060         loadArchiveInformation();
00061 
00062         mainVerticalBox->addWidget(archiveList);
00063 
00064         //Set up buttons to rename and delete archives
00065         QHBoxLayout *renameDeletebuttonBox = new QHBoxLayout();
00066         QPushButton *renamePushButton = new QPushButton("Rename", this, "renameButton");
00067         connect (renamePushButton, SIGNAL(clicked()), this, SLOT(renameButtonPressed()));
00068         renameDeletebuttonBox->addWidget(renamePushButton);
00069 
00070         QPushButton *deletePushButton = new QPushButton("Delete", this, "deleteButton");
00071         connect (deletePushButton, SIGNAL(clicked()), this, SLOT(deleteButtonPressed()));
00072         renameDeletebuttonBox->addWidget(deletePushButton);
00073 
00074         QPushButton *deleteAllPushButton = new QPushButton("Delete all", this, "deleteAllButton");
00075         if(SimulationManager::isInitialised())
00076                 deleteAllPushButton->setEnabled(false);
00077         else
00078                 connect (deleteAllPushButton, SIGNAL(clicked()), this, SLOT(deleteAllButtonPressed()));
00079         renameDeletebuttonBox->addWidget(deleteAllPushButton);
00080         mainVerticalBox->addLayout(renameDeletebuttonBox);
00081 
00082         //Set up ok and cancel buttons
00083         QHBoxLayout *okCanButtonBox = new QHBoxLayout();
00084         QPushButton *okPushButton = new QPushButton("Ok", this, "okButton");
00085         QPushButton *cancelPushButton = new QPushButton("Cancel", this, "cancelButton");        
00086         okCanButtonBox->addWidget(okPushButton);
00087         okCanButtonBox->addWidget(cancelPushButton);
00088         mainVerticalBox->addLayout(okCanButtonBox);
00089         
00090         connect (okPushButton, SIGNAL(clicked()), this, SLOT(okButtonPressed()));
00091         connect (cancelPushButton, SIGNAL(clicked()), this, SLOT(reject()));
00092         
00093         //Set up accelerator for return button
00094         QAccel *returnAccel = new QAccel( this );
00095     returnAccel->connectItem( returnAccel->insertItem( Key_Enter ), this, SLOT(okButtonPressed()));
00096 }
00097 
00098 
00099 /*! Destructor. */
00100 LoadArchiveDialog::~ LoadArchiveDialog(){
00101         #ifdef MEMORY_DEBUG
00102                 cout<<"DESTROYING LOAD ARCHIVE DIALOG"<<endl;
00103         #endif//MEMORY_DEBUG
00104 }
00105 
00106 
00107 //-----------------------------------------------------------------------
00108 //--------------------------- PUBLIC METHODS ----------------------------
00109 //-----------------------------------------------------------------------
00110 
00111 /*! Returns the start time of the selected archive. */
00112 QString LoadArchiveDialog::getArchiveString(){
00113         return archiveList->currentText();
00114 }
00115 
00116 
00117 //-----------------------------------------------------------------------
00118 //---------------------------- SLOTS ------------------------------------
00119 //-----------------------------------------------------------------------
00120 
00121 /*! Deletes all the archives. */
00122 void LoadArchiveDialog::deleteAllButtonPressed(){
00123         if(SimulationManager::isInitialised()){
00124                 cerr<<"LoadArchiveDialog: THIS SHOULD NOT BE CALLED WHEN SIMULATION IS INITIALISED"<<endl;
00125                 return;//This button should be disabled when simulation is initialised
00126         }
00127 
00128         //Confirm that user wants to delete archives
00129         int warningConfirmation = QMessageBox::warning (this, "Delete Archive?", "Are you sure that you want to delete *all* the archives?", QMessageBox::Ok,  QMessageBox::Cancel, QMessageBox::NoButton);
00130         
00131         //User wants to delete archive
00132         if(warningConfirmation == QMessageBox::Ok){//1 is returned for cancel and closing message box
00133 
00134                 /* Inform other classes that we are deleting archives. 
00135                         ArchiveWidget should be connected to this signal. */
00136                 emit deleteArchiveStarted();
00137 
00138                 try{
00139                         //Delete the archive's network model
00140                         Query query = archiveDBInterface->getQuery();
00141                         query.reset();
00142                         query<<"DELETE FROM NetworkModels";
00143                         query.execute();
00144 
00145                         //Delete the archive's network data
00146                         query.reset();
00147                         query<<"DELETE FROM NetworkData";
00148                         query.execute();
00149                 }
00150                 catch (const BadQuery& er) {// Handle any query errors
00151                         cerr<<"LoadArchiveDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00152                         QString errorString = "Bad query when deleting all archives: \"";
00153                         errorString += er.what();
00154                         errorString += "\"";
00155                         QMessageBox::critical( 0, "Archive Error", errorString);
00156                 }
00157                 catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00158                         cerr<<"LoadArchiveDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00159                         QString errorString = "Exception thrown when deleting all archives: \"";
00160                         errorString += er.what();
00161                         errorString += "\"";
00162                         QMessageBox::critical( 0, "Archive Error", errorString);
00163                 }
00164                 
00165                 //Reload list of archives in case something went wrong with deletion
00166                 loadArchiveInformation();
00167 
00168                 //Inform other classes that we have finished deleting archives
00169                 emit deleteArchiveFinished();
00170         }
00171 }
00172 
00173 
00174 /*! Deletes a single archive. */
00175 void LoadArchiveDialog::deleteButtonPressed(){
00176         //Extract information about archive
00177         QString archiveText = archiveList->currentText();
00178         if(archiveText == ""){
00179                 QMessageBox::critical(this, "Delete Archive", "No archive selected");
00180                 return;
00181         }
00182         QString archiveStartTime = archiveText.section( "[ ", 1, 1 ); //string should equal "date ]"
00183         archiveStartTime = archiveStartTime.section( " ]", 0, 0); // string should equal "date"
00184 
00185         //First check that archive is not being accessed by simulation manager
00186         if(getUnixTime(archiveStartTime) == SimulationWidget::getSimulationStartTime()){
00187                 QString messageText = "Archive \"" + archiveText + "\" is still be accessed\nby the simulation and cannot be deleted.";
00188                 QMessageBox::critical (this, "Delete Archive", messageText, QMessageBox::Ok,  QMessageBox::NoButton, QMessageBox::NoButton);
00189                 return;
00190         }
00191 
00192         //Confirm that user wants to delete archive
00193         QString messageText = "Are you sure that you want to delete \"" + archiveText;
00194         int warningConfirmation = QMessageBox::warning (this, "Delete Archive?", messageText, QMessageBox::Ok,  QMessageBox::Cancel, QMessageBox::NoButton);
00195         
00196         //User wants to delete archive
00197         if(warningConfirmation == QMessageBox::Ok){//1 is returned for cancel and closing message box
00198 
00199                 /* Deleting an archive affects the query if there is an archive already loaded
00200                         So have to delete and then re-initialise the query */
00201                 emit deleteArchiveStarted();
00202 
00203                 try{
00204                         //Delete the archive's network model
00205                         Query query = archiveDBInterface->getQuery();
00206                         query.reset();
00207                         query<<mysqlpp::escape<<"DELETE FROM NetworkModels WHERE StartTime = UNIX_TIMESTAMP("<<"\""<<archiveStartTime<<"\")";
00208                         query.execute();
00209 
00210                         //Delete the archive's network data
00211                         query.reset();
00212                         query<<"DELETE FROM NetworkData WHERE SimulationStartTime = UNIX_TIMESTAMP("<<"\""<<archiveStartTime<<"\")";
00213                         query.execute();
00214                 }
00215                 catch (const BadQuery& er) {// Handle any query errors
00216                         cerr<<"LoadArchiveDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00217                         QString errorString = "Bad query when deleting archive: \"";
00218                         errorString += er.what();
00219                         errorString += "\"";
00220                         QMessageBox::critical( 0, "Archive Error", errorString);
00221                 }
00222                 catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00223                         cerr<<"LoadArchiveDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00224                         QString errorString = "Exception thrown when deleting archive: \"";
00225                         errorString += er.what();
00226                         errorString += "\"";
00227                         QMessageBox::critical( 0, "Archive Error", errorString);
00228                 }
00229                 
00230                 //Reload list of archives
00231                 loadArchiveInformation();
00232 
00233                 emit deleteArchiveFinished();
00234         }
00235 }
00236 
00237 
00238 /*! Hides the dialog. */
00239 void LoadArchiveDialog::okButtonPressed(){
00240         accept();
00241 }
00242 
00243 
00244 /*! Renames an archive. */
00245 void LoadArchiveDialog::renameButtonPressed(){
00246         //Extract information about archive
00247         QString archiveText = archiveList->currentText();
00248         if(archiveText == ""){
00249                 QMessageBox::critical(this, "Rename Archive", "No archive selected");
00250                 return;
00251         }
00252         QString archiveName = archiveText.section(" [", 0, 0);
00253         QString archiveStartTime = archiveText.section( "[ ", 1, 1 ); //string should equal "date ]"
00254         archiveStartTime = archiveStartTime.section( " ]", 0, 0); // string should equal "date"
00255 
00256         //First check that archive is not being accessed by simulation manager
00257         if(getUnixTime(archiveStartTime) == SimulationWidget::getSimulationStartTime()){
00258                 QString messageText = "Archive \"" + archiveText + "\" is still be accessed\nby the simulation and cannot be renamed.";
00259                 QMessageBox::critical (this, "Delete Archive", messageText, QMessageBox::Ok,  QMessageBox::NoButton, QMessageBox::NoButton);
00260                 return;
00261         }
00262 
00263         //Show dialog with current name
00264         NameDialog *nameDialog = new NameDialog(archiveName, this);
00265         if (nameDialog->exec() == QDialog::Accepted ) {//Ok button has been pressed
00266                 QString newName = nameDialog->getName();
00267 
00268                 //Change name in the database if user wants it changed
00269                 //NOTE THIS USES UNIX_TIMESTAMP, WHICH MAY BE LOSSY AROUND CERTAIN DATES
00270                 if(newName != archiveName){
00271                         try{
00272                                 Query query = archiveDBInterface->getQuery();
00273                                 query.reset();
00274                                 query<<"UPDATE NetworkModels SET Name = \""<<newName<<"\" WHERE StartTime = UNIX_TIMESTAMP(\'"<<archiveStartTime<<"\')";
00275                                 query.execute();
00276                         }
00277                         catch (const BadQuery& er) {// Handle any query errors
00278                                 cerr<<"LoadArchiveDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00279                                 QString errorString = "Bad query when renaming archive: \"";
00280                                 errorString += er.what();
00281                                 errorString += "\"";
00282                                 QMessageBox::critical( 0, "Archive Error", errorString);
00283                         }
00284                         catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00285                                 cerr<<"LoadArchiveDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00286                                 QString errorString = "Exception thrown when renaming archive: \"";
00287                                 errorString += er.what();
00288                                 errorString += "\"";
00289                                 QMessageBox::critical( 0, "Archive Error", errorString);
00290                         }
00291 
00292                         //Reload list of archives
00293                         loadArchiveInformation();
00294 
00295                         /* Let any classes that might be using the archive that its name has changed. */
00296                         emit archiveNameChanged(archiveStartTime, newName);
00297                 }
00298         }
00299 
00300         //Clean up
00301         delete nameDialog;
00302 }
00303 
00304 
00305 //--------------------------------------------------------------------------------
00306 //----------------------------- PRIVATE METHODS ----------------------------------
00307 //--------------------------------------------------------------------------------
00308 
00309 /*! Returns the current UNIX time in seconds. */
00310 unsigned int LoadArchiveDialog::getUnixTime(QString &timeString){
00311         QDateTime dateTime = QDateTime::fromString(timeString, Qt::ISODate);
00312         return dateTime.toTime_t();
00313 }
00314 
00315 
00316 /*! Loads up the details about the archives into the archiveTable. */
00317 void LoadArchiveDialog::loadArchiveInformation(){
00318         //Empty archive list
00319         archiveList->clear();
00320 
00321         /* Load up information about archives. */
00322         try{
00323                 Query query = archiveDBInterface->getQuery();
00324                 query.reset();
00325                 query<<"SELECT StartTime, FROM_UNIXTIME(StartTime), Name FROM NetworkModels ORDER BY StartTime";
00326                 Result modelResult = query.store();
00327                 Result::iterator resIter;
00328                 for (resIter = modelResult.begin(); resIter != modelResult.end(); ++resIter) {
00329                         Row row(*resIter);
00330         
00331                         /* Filter out any network models that do not have data
00332                                 Most likely these are here because the simulation is running
00333                                 and they will be deleted when the simulation is destroyed if
00334                                 no data is added. Also end up with network models that were
00335                                 not deleted because of a crash */
00336                         query.reset();
00337                         query<<"SELECT COUNT(*) FROM NetworkData WHERE SimulationStartTime = "<<row["StartTime"];
00338                         Result dataResult= query.store();
00339                         Row dataRow(*dataResult.begin());//Should only be one row
00340                         unsigned int numberOfRows = Utilities::getUInt((std::string)dataRow["COUNT(*)"]);
00341                         if(numberOfRows > 0){
00342                                 //Add new row to the table
00343                                 int currentRow = archiveList->count();
00344                                 QString insertionText((std::string)row["Name"]);
00345                                 insertionText += "   [ ";
00346                                 insertionText += (std::string)row["FROM_UNIXTIME(StartTime)"];
00347                                 insertionText += " ]";
00348                                 archiveList->insertItem(insertionText, currentRow);
00349                         }
00350                 }
00351         }
00352         catch (const BadQuery& er) {// Handle any query errors
00353                 cerr<<"LoadArchiveDialog: MYSQL QUERY EXCEPTION \""<<er.what()<<"\""<<endl;
00354                 QString errorString = "Bad query when loading archive information: \"";
00355                 errorString += er.what();
00356                 errorString += "\"";
00357                 QMessageBox::critical( 0, "Archive Error", errorString);
00358                 return;
00359         }
00360         catch (const Exception& er) {// Catch-all for any other MySQL++ exceptions
00361                 cerr<<"LoadArchiveDialog: MYSQL EXCEPTION \""<<er.what()<<"\""<<endl;
00362                 QString errorString = "Exception thrown loading archive information: \"";
00363                 errorString += er.what();
00364                 errorString += "\"";
00365                 QMessageBox::critical( 0, "Archive Error", errorString);
00366                 return;
00367         }
00368         catch(std::exception& er){// Catch-all for std exceptions
00369                 cerr<<"LoadArchiveDialog: STD EXCEPTION \""<<er.what()<<"\""<<endl;
00370                 QString errorString = "Exception thrown loading archive information: \"";
00371                 errorString += er.what();
00372                 errorString += "\"";
00373                 QMessageBox::critical( 0, "Archive Error", errorString);
00374                 return;
00375         }
00376 
00377         //Select the most recent item
00378         archiveList->setSelected(archiveList->count() -1, true);
00379 }
00380 
00381 

Generated on Mon Sep 3 22:29:04 2007 for SpikeStream Application by  doxygen 1.4.4