00001 #include "ButtonProcessAdministrator.h"
00002 #include <iostream>
00003 #include <QMessageBox>
00004 #include <QMenu>
00005 #include <QRegExp>
00006
00007 ButtonProcessAdministrator::ButtonProcessAdministrator(QString name, QString command, QStringList arguments, QObject *parent):
00008 QObject(parent),
00009 current_process_state_(NotRunning),
00010 name_(name),
00011 process_(new QProcess()),
00012 command_(command),
00013 arguments_(arguments)
00014 {
00015 process_->setProcessChannelMode(QProcess::SeparateChannels);
00016 connectProcess();
00017 }
00018
00019 ButtonProcessAdministrator::ButtonProcessAdministrator(QObject *parent):
00020 QObject(parent),
00021 current_process_state_(NotRunning),
00022 process_(new QProcess())
00023 {
00024 process_->setProcessChannelMode(QProcess::SeparateChannels);
00025 connectProcess();
00026 }
00027
00028 ButtonProcessAdministrator::ButtonProcessAdministrator(const ButtonProcessAdministrator ©):
00029 QObject(),
00030 name_(copy.getName()),
00031 process_(new QProcess())
00032 {
00033 buttons_ = copy.buttons_;
00034 process_->setProcessChannelMode(QProcess::SeparateChannels);
00035 this -> setCommand(copy.getCommand(), copy.getArguments());
00036 connectProcess();
00037 }
00038
00039 ButtonProcessAdministrator::~ButtonProcessAdministrator()
00040 {
00041 if(process_->state() == QProcess::Running){
00042 stopProcess();
00043 }
00044 delete process_;
00045 }
00046
00047 QString ButtonProcessAdministrator::getName() const
00048 {
00049 return name_;
00050 }
00051
00052 QString ButtonProcessAdministrator::getCommand() const
00053 {
00054 return command_;
00055 }
00056
00057 QStringList ButtonProcessAdministrator::getArguments() const
00058 {
00059 return arguments_;
00060 }
00061
00062 void ButtonProcessAdministrator::addButton(QAbstractButton* button)
00063 {
00064 buttons_.push_back(button);
00065 setButtonTextStart();
00066 connect(button,SIGNAL(clicked()),this,SLOT(handleClick()));
00067 }
00068
00069 void ButtonProcessAdministrator::addButton(QPushButton *button)
00070 {
00071 buttons_.push_back(button);
00072 setButtonTextStart();
00073 connect(button,SIGNAL(clicked()),this,SLOT(handleClick()));
00074 }
00075
00076 void ButtonProcessAdministrator::addButton(RosProcessButton *button)
00077 {
00078 buttons_.push_back(button);
00079 setButtonTextStart();
00080 connect(button, SIGNAL(clicked()), this, SLOT(handleClick()));
00081 connect(button, SIGNAL(killPushed()), this->process_, SLOT(kill()));
00082 connect(button, SIGNAL(startInTerminalPushed()), this, SLOT(startInExternalTerminal()));
00083 }
00084
00085 QProcess::ProcessState ButtonProcessAdministrator::getState() const
00086 {
00087 return this -> process_->state();
00088 }
00089
00090 QString ButtonProcessAdministrator::getCombinedString() const
00091 {
00092 return combined_string_;
00093 }
00094
00095 QString ButtonProcessAdministrator::getStderrString() const
00096 {
00097 return stderr_string_;
00098 }
00099
00100 QString ButtonProcessAdministrator::getStdcoutString() const
00101 {
00102 return stdcout_string_;
00103 }
00104
00105 void ButtonProcessAdministrator::stopProcess()
00106 {
00107 process_->terminate();
00108 current_process_state_ = ShuttingDown;
00109 setButtonTextShuttingDown();
00110 }
00111
00112 void ButtonProcessAdministrator::startProcess()
00113 {
00114 this -> combined_string_.append("--------------------------------------------------------------------------------------------\n");
00115 process_->start(command_, arguments_);
00116 current_process_state_ = Starting;
00117 }
00118
00119 void ButtonProcessAdministrator::setName(QString name)
00120 {
00121 this -> name_ = name;
00122 }
00123
00124 void ButtonProcessAdministrator::setCommand(QString command, QStringList arguments)
00125 {
00126 this->command_ = command;
00127 this->arguments_ = arguments;
00128 }
00129
00130
00131 void ButtonProcessAdministrator::setButtonText(QString text)
00132 {
00133 for(int i = 0; i < buttons_.size(); ++i)
00134 {
00135 buttons_[i]->setText(text);
00136 }
00137 }
00138
00139 void ButtonProcessAdministrator::connectProcess()
00140 {
00141 connect(this -> process_, SIGNAL(readyReadStandardOutput()), this, SLOT(readStdoutProcess()));
00142 connect(this -> process_, SIGNAL(readyReadStandardError()), this, SLOT(readStderrProcess()));
00143 connect(this -> process_, SIGNAL(error(QProcess::ProcessError)), this, SLOT(handleProcessError(QProcess::ProcessError)));
00144 connect(this -> process_, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(handleProcessStateChange(QProcess::ProcessState)) );
00145 }
00146
00147
00148 void ButtonProcessAdministrator::handleClick()
00149 {
00150 if(current_process_state_ == NotRunning)
00151 {
00152 startProcess();
00153 }
00154 else if(current_process_state_ == Running)
00155 {
00156 stopProcess();
00157 }
00158 else if(current_process_state_ == Starting ||
00159 current_process_state_ == ShuttingDown)
00160 {
00161
00162 }
00163 }
00164
00165 void ButtonProcessAdministrator::handleProcessError(QProcess::ProcessError error)
00166 {
00167 switch(error)
00168 {
00169 case QProcess::FailedToStart:
00170 QMessageBox::information(0,"FailedToStart",this->name_ + " FailedToStart");
00171 break;
00172 case QProcess::Crashed:
00173 QMessageBox::information(0,"Crashed", this->name_ + " crashed");
00174 break;
00175 case QProcess::Timedout:
00176 QMessageBox::information(0,"FailedToStart",this->name_ + " FailedToStart");
00177 break;
00178 case QProcess::WriteError:
00179 QMessageBox::information(0,"Timedout",this->name_ + " Timedout");
00180 break;
00181 case QProcess::ReadError:
00182 QMessageBox::information(0,"ReadError",this->name_ + " ReadError");
00183 break;
00184 case QProcess::UnknownError:
00185 QMessageBox::information(0,"UnknownError",this->name_ + " UnknownError");
00186 break;
00187 default:
00188 QMessageBox::information(0,"default",this->name_ + " default");
00189 break;
00190 }
00191 }
00192
00193 void ButtonProcessAdministrator::startInExternalTerminal()
00194 {
00195 QString processCommand = command_ + " " + arguments_.join(" ");
00196
00197 QString terminalCommand = "gnome-terminal -e \"bash -c '" + processCommand + "; bash'\"";
00198
00199 this->process_->start(terminalCommand);
00200 }
00201
00202 void ButtonProcessAdministrator::handleProcessStateChange(QProcess::ProcessState state)
00203 {
00204 switch(state)
00205 {
00206 case QProcess::Starting:
00207 setButtonTextStarting();
00208 current_process_state_ = Starting;
00209 break;
00210 case QProcess::NotRunning:
00211 setButtonTextStart();
00212 current_process_state_ = NotRunning;
00213 break;
00214 case QProcess::Running:
00215 setButtonTextStop();
00216 current_process_state_ = Running;
00217 break;
00218 }
00219 }
00220
00221 void ButtonProcessAdministrator::readStdoutProcess()
00222 {
00223 QString coutString(this -> process_->readAllStandardOutput());
00224
00225
00226 coutString.remove(QRegExp ("\e\\[[0-9]{0,3}m"));
00227 coutString.remove(QRegExp ("\e\\][0-9];"));
00228
00229 coutString.remove(QRegExp ("\a"));
00230
00231 this -> stdcout_string_.append(coutString);
00232 this -> combined_string_.append(coutString);
00233
00234 emit stdcoutStringChanged(this -> stdcout_string_);
00235 emit stdcoutStringChanged();
00236 emit combinedStringChanged(this -> combined_string_);
00237 emit combinedStringChanged();
00238 }
00239
00240 void ButtonProcessAdministrator::readStderrProcess()
00241 {
00242 QString errString(this -> process_->readAllStandardError());
00243
00244
00245 errString.remove(QRegExp ("\e\\[[0-9]{0,3}m"));
00246 errString.remove(QRegExp ("\e\\][0-9];"));
00247 errString.remove(QRegExp ("\a"));
00248
00249 this -> stderr_string_.append(errString);
00250 this -> combined_string_.append(errString);
00251
00252 emit stderrStringChanged(this -> stderr_string_);
00253 emit stderrStringChanged();
00254 emit combinedStringChanged(this -> combined_string_);
00255 emit combinedStringChanged();
00256 }
00257
00258 void ButtonProcessAdministrator::setButtonTextStart()
00259 {
00260 setButtonText(QString("Start ").append(this->name_));
00261 }
00262
00263 void ButtonProcessAdministrator::setButtonTextStop()
00264 {
00265 setButtonText(QString("Stop ").append(this->name_));
00266 }
00267
00268 void ButtonProcessAdministrator::setButtonTextStarting()
00269 {
00270 setButtonText(QString("Starting ").append(this->name_));
00271 }
00272
00273 void ButtonProcessAdministrator::setButtonTextShuttingDown()
00274 {
00275 setButtonText(QString("Stopping ").append(this->name_));
00276 }