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

ScriptRunner.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 "ScriptRunner.h"
00025 #include "Debug.h"
00026 
00027 //Qt includes
00028 #include <qlayout.h>
00029 
00030 //Other includes
00031 #include <iostream>
00032 using namespace std;
00033 
00034 
00035 /*! Constructor. */
00036 ScriptRunner::ScriptRunner(QWidget* parent, QString scriptName, QString mainWorkDir) : QDialog(parent, "NeurParamDlg"){
00037         workingDirectory += mainWorkDir + "/scripts/";
00038 
00039         //Set up QProcess for running the script
00040         process = new QProcess();
00041 
00042         /* Set the working directory to the scripts directory so that scripts 
00043                 can easily invoke other scripts. */
00044         process->setWorkingDirectory(QDir(workingDirectory));
00045 
00046         //Connect process to slots
00047         connect( process, SIGNAL(readyReadStdout()), this, SLOT(readFromStdout()) );
00048         connect( process, SIGNAL(readyReadStderr()), this, SLOT(readFromStderr()) );
00049         connect( process, SIGNAL(processExited()), this, SLOT(processExited()) );
00050 
00051         //Create box to organise vertical layout of dialog
00052         QVBoxLayout *mainVerticalBox = new QVBoxLayout(this, 5, 10, "Main vertical Box");
00053 
00054         //Add a text area to hold the output from the script
00055         scriptMessages = new QTextEdit(this);
00056         mainVerticalBox->addWidget(scriptMessages);
00057 
00058         //Set up ok and cancel buttons
00059         QHBoxLayout *buttonBox = new QHBoxLayout();
00060         okButton = new QPushButton("Ok", this, "okButton");
00061         QPushButton *stopButton = new QPushButton("Stop", this, "stopButton");  
00062         buttonBox->addWidget(okButton);
00063         buttonBox->addWidget(stopButton);
00064         mainVerticalBox->addLayout(buttonBox);
00065         
00066         connect (okButton, SIGNAL(clicked()), this, SLOT(okButtonPressed()));
00067         connect (stopButton, SIGNAL(clicked()), this, SLOT(stopButtonPressed()));
00068 
00069         //Set dialog size
00070         this->resize(600, 300);
00071 
00072         //Run the script
00073         runScript(scriptName);
00074 }
00075 
00076 
00077 /*! Destructor. */
00078 ScriptRunner::~ ScriptRunner(){
00079         #ifdef MEMORY_DEBUG
00080                 cout<<"DESTROYING SCRIPT RUNNER"<<endl;
00081         #endif//MEMORY_DEBUG
00082 
00083         delete process;
00084 }
00085 
00086 
00087 //---------------------------------------------------------------------------
00088 //-------------------------- PUBLIC METHODS ---------------------------------
00089 //---------------------------------------------------------------------------
00090 
00091 /*! Returns true if there has been an error running the script. */
00092 bool ScriptRunner::processError(){
00093         return procErr;
00094 }
00095 
00096 
00097 /*! Returns true if process is running. */
00098 bool ScriptRunner::processRunning(){
00099         return process->isRunning();
00100 }
00101 
00102 
00103 //---------------------------------------------------------------------------
00104 //------------------------------- SLOTS -------------------------------------
00105 //---------------------------------------------------------------------------
00106 
00107 /*! Slot for when ok button is pressed. */
00108 void ScriptRunner::okButtonPressed(){
00109         accept();
00110 }
00111 
00112 
00113 /*! Slot called when process exits. */
00114 void ScriptRunner::processExited(){
00115         #ifdef RUN_SCRIPT_DEBUG
00116                 cout<<"Process finished"<<endl;
00117         #endif//RUN_SCRIPT_DEBUG
00118         scriptMessages->insertParagraph("--------------- Script finished ---------------", -1);
00119         okButton->setEnabled(true);
00120 }
00121 
00122 
00123 /*! Prints out error from process. */
00124 void ScriptRunner::readFromStderr(){
00125         while(process->canReadLineStderr()){
00126                 QString processString = process->readLineStderr();
00127                 cerr<<processString<<endl;
00128                 scriptMessages->insertParagraph(processString, -1);
00129         }
00130 }
00131 
00132 
00133 /*! Slot called when there is something to read from standard out. */
00134 void ScriptRunner::readFromStdout(){
00135         while(process->canReadLineStdout()){
00136                 QString processString = process->readLineStdout();
00137                 #ifdef RUN_SCRIPT_DEBUG
00138                         cout<<processString<<endl;
00139                 #endif//RUN_SCRIPT_DEBUG
00140                 scriptMessages->insertParagraph(processString, -1);
00141         }
00142 }
00143 
00144 
00145 /*! Slot for when stop button is pressed. */
00146 void ScriptRunner::stopButtonPressed(){
00147         stopScript();
00148         okButton->setEnabled(true);
00149 }
00150 
00151 
00152 //---------------------------------------------------------------------------
00153 //-------------------------- PRIVATE METHODS --------------------------------
00154 //---------------------------------------------------------------------------
00155 
00156 /*! Overloaded run script method. */
00157 void ScriptRunner::runScript(const char* scriptName){
00158         runScript(QString(scriptName));
00159 }
00160 
00161 
00162 /*! Runs the named script. */
00163 void ScriptRunner::runScript(QString scriptName){
00164         //Initialise error
00165         procErr = false;
00166 
00167         //Set the caption
00168         setCaption(scriptName);
00169 
00170         //Check script file exists
00171         if(!QFile::exists(workingDirectory + scriptName)){
00172         //      errorString += ;
00173                 scriptMessages->insertParagraph("Script file does not exist", -1);
00174                 procErr = true;
00175                 return;
00176         }
00177 
00178         //Set up the process
00179         process->clearArguments();      
00180         process->addArgument(workingDirectory + scriptName);
00181 
00182         //Start the process
00183         if ( process->start() ) {
00184                 scriptMessages->insertParagraph("---------------- Script started ----------------", -1);
00185                 okButton->setEnabled(false);
00186         }
00187         else{
00188                 scriptMessages->insertParagraph("Script will not start.", -1);
00189                 procErr = true;
00190         }
00191 }
00192 
00193 
00194 /*! Runs a script with a given set of parameters. */
00195 void ScriptRunner::runScript(QString scriptName, QStringList scriptParameters){
00196         //Initialise error
00197         procErr = false;
00198 
00199         //Set the caption
00200         setCaption(scriptName);
00201 
00202         //Check script file exists
00203         if(!QFile::exists(workingDirectory + scriptName)){
00204                 scriptMessages->insertParagraph("Script file does not exist", -1);
00205                 procErr = true;
00206                 return;
00207         }
00208 
00209         //Set up the process
00210         process->clearArguments();      
00211         process->addArgument(workingDirectory + scriptName);
00212         for(unsigned int i=0; i<scriptParameters.size(); ++i)
00213                 process->addArgument(scriptParameters[i]);
00214 
00215         //Start the process
00216         if ( process->start() ) {
00217                 scriptMessages->insertParagraph("---------------- Script started ----------------", -1);
00218                 okButton->setEnabled(false);
00219         }
00220         else{
00221                 scriptMessages->insertParagraph("Script will not start.", -1);
00222                 procErr = true;
00223         }
00224 }
00225 
00226 
00227 /*! Politely ask process to quit and kill it if it does not respond. */
00228 bool ScriptRunner::stopScript(){
00229         //First politely ask process to quit
00230         process->tryTerminate();
00231 
00232         int timeoutCount = 0;
00233         while (timeoutCount < 100){
00234                 if(!process->isRunning())
00235                         return true;
00236                 else{
00237                         usleep(10000);//Sleep for 10 ms
00238                 }
00239                 ++timeoutCount;
00240         }
00241         //Try to kill process
00242         process->kill();
00243 
00244         //Wait to see if it has stopped
00245         timeoutCount = 0;
00246         while (timeoutCount < 10){
00247                 if(!process->isRunning())
00248                         return true;
00249                 else{
00250                         usleep(10000);//Sleep for 10 ms
00251                 }
00252                 ++timeoutCount;
00253         }
00254         return false;
00255 }
00256 
00257 
00258 

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