1 // Copyright (C) 2006-2024 CEA, EDF
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "RuntimeSALOME.hxx"
24 #include "ListJobs_GUI.hxx"
25 #include "GenericGui.hxx"
26 #include "QtGuiContext.hxx"
27 #include "YACSGuiLoader.hxx"
29 #include "YacsTrace.hxx"
30 #include "LoadState.hxx"
34 #include <QMessageBox>
35 #include <QPushButton>
36 #include <QTableWidget>
40 using namespace YACS::HMI;
41 using namespace YACS::ENGINE;
43 BatchJobsListDialog::BatchJobsListDialog(QString title,GenericGui* genericGui): QWidget(),_genericGui(genericGui),_proc(NULL) {
45 setWindowTitle(title);
47 // Connection to Salome Launcher
51 QBoxLayout* box = new QBoxLayout(QBoxLayout::TopToBottom, this);
54 _table = new QTableWidget(this);
55 _table->setColumnCount(4);
60 box->addWidget(_table);
63 QWidget* buttons = build_buttons();
64 box->addWidget(buttons);
67 _ok->setEnabled(false);
70 // Set timer to refresh table
71 _timer1 = new QTimer(this);
72 connect(_timer1, SIGNAL(timeout()), this, SLOT(build_table()));
73 _timer1->start(30000);
77 BatchJobsListDialog::~BatchJobsListDialog(){
80 void BatchJobsListDialog::getSalomeLauncher(){
81 YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
82 CORBA::ORB_ptr orb = runTime->getOrb();
83 SALOME_NamingService_Wrapper NS;
84 CORBA::Object_var obj = NS.Resolve("/SalomeLauncher");
85 _salome_launcher = Engines::SalomeLauncher::_narrow(obj);
86 if (CORBA::is_nil(_salome_launcher))
87 throw YACS::Exception("Salome Launcher not reachable!!");
90 // Display list of current batch jobs and allow selection only on running jobs
91 void BatchJobsListDialog::build_table() {
97 Engines::JobsList* joblist = _salome_launcher->getJobsList();
99 int nblines = joblist->length();
100 _table->setRowCount(nblines);
103 titres << "Job Name" << "State" << "Resource" << "Launcher Id";
104 _table->setHorizontalHeaderLabels(titres);
106 for(int i=0;i<nblines;i++){
107 Engines::JobDescription descr = (*joblist)[i];
108 string jobType = CORBA::string_dup(descr.job_parameters.job_type);
109 // We display only jobs of type yacs_file
110 if(jobType.find("yacs_file")!=string::npos){
111 long jobId = descr.job_id;
114 string jobName = CORBA::string_dup(descr.job_parameters.job_name);
115 string jobState = _salome_launcher->getJobState(jobId);
116 string jobMachine = CORBA::string_dup(descr.job_parameters.resource_required.name);
117 QTableWidgetItem* item0 = new QTableWidgetItem(jobName.c_str() , type_job);
118 QTableWidgetItem* item1 = new QTableWidgetItem(jobState.c_str() , type_state);
119 QTableWidgetItem* item2 = new QTableWidgetItem(jobMachine.c_str() , type_res );
120 QTableWidgetItem* item3 = new QTableWidgetItem(sstId.str().c_str(), type_id );
121 _table->setItem(irow, 0, item0);
122 _table->setItem(irow, 1, item1);
123 _table->setItem(irow, 2, item2);
124 _table->setItem(irow, 3, item3);
125 if(jobState != "RUNNING"){
126 item0->setFlags(Qt::NoItemFlags);
127 item1->setFlags(Qt::NoItemFlags);
128 item2->setFlags(Qt::NoItemFlags);
129 item3->setFlags(Qt::NoItemFlags);
131 else if(jobId == _id){
132 item0->setSelected(true);
133 item1->setSelected(true);
134 item2->setSelected(true);
135 item3->setSelected(true);
141 connect(_table, SIGNAL( itemClicked(QTableWidgetItem*) ), this, SLOT( userCell(QTableWidgetItem*) ));
145 // Build buttons in a layout
146 // -------------------------
148 QWidget* BatchJobsListDialog::build_buttons() {
149 _ok = new QPushButton("OK" , this);
150 QPushButton* cancel = new QPushButton("Cancel", this);
152 connect(_ok , SIGNAL(clicked()), this, SLOT(userOK ()));
153 connect(cancel, SIGNAL(clicked()), this, SLOT(userCancel()));
155 QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, this);
157 layout->addWidget(_ok);
158 layout->addWidget(cancel);
160 QWidget* buttons = new QWidget(this);
161 buttons->setLayout(layout);
166 // Click on a cell button
167 // ----------------------
169 void BatchJobsListDialog::userCell(QTableWidgetItem* cell) {
170 if ( cell->flags() ) {
171 int line = cell->row();
172 string sid = _table->item(line,3)->text().toStdString();
173 _id = atoi(sid.c_str());
174 _ok->setEnabled(true);
176 QTableWidget* table = cell->tableWidget();
177 for (int c=0; c<4; c++) {
178 QTableWidgetItem* it = table->item(line, c);
179 it->setSelected(true);
184 // Click on OK button
185 // ------------------
187 void BatchJobsListDialog::userOK() {
190 Engines::JobParameters* jobParam = _salome_launcher->getJobParameters(_id);
191 _jobFile = CORBA::string_dup(jobParam->job_file);
192 _dumpStateFile = QString("/tmp/%1/dumpState_%2.xml").arg(getenv("USER")).arg(QFileInfo(_jobFile).baseName());
194 // stop first timer and hide window
198 // replace objref by string in YACS schema job file to avoid trying to reach remote objects
201 // display yacs graph
202 YACSGuiLoader *loader = _genericGui->getLoader();
203 _proc = loader->load(_filteredJobFile.toLatin1());
205 QMessageBox msgBox(QMessageBox::Critical, "Import Batch Schema, native YACS XML format",
206 "The xml graph has not the native YACS XML format or is not readable." );
210 YACS::ENGINE::Logger* logger= _proc->getLogger("parser");
211 if(!logger->isEmpty()) {
212 DEBTRACE(logger->getStr());
214 _genericGui->createContext(_proc, _filteredJobFile, _filteredJobFile, false);
217 // start second timer to get remote graph state xml file
218 _timer2 = new QTimer(this);
219 connect(_timer2, SIGNAL(timeout()), this, SLOT(get_dump_file()));
220 _timer2->start(30000);
224 // Click on CANCEL button
225 // ----------------------
227 void BatchJobsListDialog::userCancel() {
232 // get remote graph state xml file
234 void BatchJobsListDialog::get_dump_file()
236 int execState = YACS::NOTYETINITIALIZED;
237 // get batch job state
238 string jobState = _salome_launcher->getJobState(_id);
239 // get dump state remote file
240 bool ret = _salome_launcher->getJobDumpState(_id, QFileInfo(_dumpStateFile).absolutePath().toLatin1().constData());
242 // replace objref by string in dump state file
243 filterDumpStateFile();
244 // parse dump state file and load proc
245 YACS::ENGINE::loadState(_proc,_filteredDumpStateFile.toStdString());
246 // display remote graph states
247 GuiExecutor *executor = QtGuiContext::getQtCurrent()->getGuiExecutor();
248 execState = executor->updateSchema(jobState);
250 // stop timer if job is not running
251 if((execState!=YACS::RUNNING)&&(execState!=YACS::NOTYETINITIALIZED))
255 // filtering of _jobFile to replace objref by string
256 void BatchJobsListDialog::filterJobFile()
258 _filteredJobFile = QString("/tmp/%1/%2.xml").arg(getenv("USER")).arg(QFileInfo(_jobFile).baseName());
259 // reading input file
260 ifstream infile(_jobFile.toStdString().c_str());
262 string errmsg = "File " + _jobFile.toStdString() + " doesn't exist!!";
263 throw YACS::Exception(errmsg);
266 vector<string> objref;
267 while( !infile.eof() ){
268 getline(infile,buffer);
269 // look for objref and memorize them in vector
270 if( (buffer.find("objref") != string::npos) && (buffer.find("IDL") != string::npos) ){
271 size_t pos1 = buffer.find("\"");
272 size_t pos2 = buffer.find("\"",pos1+1);
273 objref.push_back(buffer.substr(pos1+1,pos2-pos1-1));
277 // reread the input file
278 infile.open(_jobFile.toStdString().c_str());
279 // open the output file
280 ofstream outfile(_filteredJobFile.toStdString().c_str());
282 string errmsg = "Impossible to create the file " + _filteredJobFile.toStdString() + "!!";
283 throw YACS::Exception(errmsg);
285 while( !infile.eof() ){
286 getline(infile,buffer);
287 // replace objref by string
288 if( ((buffer.find("objref") == string::npos) || (buffer.find("IDL") == string::npos)) && (buffer.find("/objref") == string::npos) ){
290 for(int i=0;i<objref.size();i++){
291 size_t pos = buffer.find(objref[i]);
292 if(pos != string::npos)
293 tmp = buffer.substr(0,pos) + "string" + buffer.substr(pos+objref[i].size());
295 outfile << tmp << endl;
300 // filtering of _dumpStateFile to replace objref by string
301 void BatchJobsListDialog::filterDumpStateFile()
304 _filteredDumpStateFile = QString("/tmp/%1/filtered_%2.xml").arg(getenv("USER")).arg(QFileInfo(_dumpStateFile).baseName());
305 ifstream infile(_dumpStateFile.toStdString().c_str());
307 string errmsg = "File " + _dumpStateFile.toStdString() + " doesn't exist!!";
308 throw YACS::Exception(errmsg);
310 ofstream outfile(_filteredDumpStateFile.toStdString().c_str());
312 string errmsg = "Impossible to create the file " + _filteredDumpStateFile.toStdString() + "!!";
313 throw YACS::Exception(errmsg);
315 // replace objref by string in dump state file
316 while( !infile.eof() ){
317 getline(infile,buffer);
318 size_t pos = buffer.find("objref");
319 while(pos != string::npos){
320 buffer.replace(pos,6,"string");
321 pos = buffer.find("objref");
323 outfile << buffer << endl;