Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/yacs.git] / src / genericgui / ListJobs_GUI.cxx
1 // Copyright (C) 2006-2012  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include <iostream>
21 #include <fstream>
22
23 #include "ListJobs_GUI.hxx"
24 #include "RuntimeSALOME.hxx"
25 #include "GenericGui.hxx"
26 #include "QtGuiContext.hxx"
27 #include "YACSGuiLoader.hxx"
28 #include "Logger.hxx"
29 #include "YacsTrace.hxx"
30 #include "LoadState.hxx"
31
32 using namespace std;
33 using namespace YACS::HMI;
34 using namespace YACS::ENGINE;
35
36 BatchJobsListDialog::BatchJobsListDialog(QString title,GenericGui* genericGui): QWidget(),_genericGui(genericGui),_proc(NULL) {
37
38   setWindowTitle(title);
39
40   // Connection to Salome Launcher
41   getSalomeLauncher();
42
43   // Add a layout
44   QBoxLayout* box = new QBoxLayout(QBoxLayout::TopToBottom, this);
45   setLayout(box);
46
47   _table = new QTableWidget(this);
48   _table->setColumnCount(4);
49
50   build_table();
51
52   // Add table
53   box->addWidget(_table);
54
55   // Add buttons
56   QWidget* buttons = build_buttons();
57   box->addWidget(buttons);
58
59   // No line selected
60   _ok->setEnabled(false);
61   _id = -1;
62
63   // Set timer to refresh table
64   _timer1 = new QTimer(this);
65   connect(_timer1, SIGNAL(timeout()), this, SLOT(build_table()));
66   _timer1->start(30000);
67
68 }
69
70 BatchJobsListDialog::~BatchJobsListDialog(){
71 }
72
73 void BatchJobsListDialog::getSalomeLauncher(){
74   YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
75   CORBA::ORB_ptr orb = runTime->getOrb();
76   SALOME_NamingService* NS = new SALOME_NamingService(orb);
77   CORBA::Object_var obj = NS->Resolve("/SalomeLauncher");
78   _salome_launcher = Engines::SalomeLauncher::_narrow(obj);
79   if (CORBA::is_nil(_salome_launcher))
80     throw YACS::Exception("Salome Launcher not reachable!!");
81 }
82
83 // Display list of current batch jobs and allow selection only on running jobs
84 void BatchJobsListDialog::build_table() {
85
86   int irow = 0;
87
88   _table->clear();
89
90   Engines::JobsList* joblist = _salome_launcher->getJobsList();
91
92   int nblines = joblist->length();
93   _table->setRowCount(nblines);
94
95   QStringList titres;
96   titres << "Job Name" << "State" << "Resource" << "Launcher Id";
97   _table->setHorizontalHeaderLabels(titres);
98
99   for(int i=0;i<nblines;i++){
100     Engines::JobDescription descr = (*joblist)[i];
101     string jobType = CORBA::string_dup(descr.job_parameters.job_type);
102     // We display only jobs of type yacs_file
103     if(jobType.find("yacs_file")!=string::npos){
104       long jobId = descr.job_id;
105       ostringstream sstId;
106       sstId << jobId;
107       string jobName = CORBA::string_dup(descr.job_parameters.job_name);
108       string jobState = _salome_launcher->getJobState(jobId);
109       string jobMachine = CORBA::string_dup(descr.job_parameters.resource_required.name);
110       QTableWidgetItem* item0 = new QTableWidgetItem(jobName.c_str()    , type_job);
111       QTableWidgetItem* item1 = new QTableWidgetItem(jobState.c_str()   , type_state);
112       QTableWidgetItem* item2 = new QTableWidgetItem(jobMachine.c_str() , type_res  );
113       QTableWidgetItem* item3 = new QTableWidgetItem(sstId.str().c_str(), type_id   );
114       _table->setItem(irow, 0, item0);
115       _table->setItem(irow, 1, item1);
116       _table->setItem(irow, 2, item2);
117       _table->setItem(irow, 3, item3);
118       if(jobState != "RUNNING"){
119         item0->setFlags(Qt::NoItemFlags);
120         item1->setFlags(Qt::NoItemFlags);
121         item2->setFlags(Qt::NoItemFlags);
122         item3->setFlags(Qt::NoItemFlags);
123       }
124       else if(jobId == _id){
125         item0->setSelected(true);
126         item1->setSelected(true);
127         item2->setSelected(true);
128         item3->setSelected(true);
129       }
130       irow++;
131     }
132   }
133     
134   connect(_table, SIGNAL( itemClicked(QTableWidgetItem*) ), this, SLOT( userCell(QTableWidgetItem*) ));
135
136 }
137
138 // Build buttons in a layout
139 // -------------------------
140
141 QWidget* BatchJobsListDialog::build_buttons() {
142   _ok     = new QPushButton("OK"    , this);
143   QPushButton* cancel = new QPushButton("Cancel", this);
144
145   connect(_ok    , SIGNAL(clicked()), this, SLOT(userOK    ()));
146   connect(cancel, SIGNAL(clicked()), this, SLOT(userCancel()));
147
148   QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, this);
149
150   layout->addWidget(_ok);
151   layout->addWidget(cancel);
152
153   QWidget* buttons = new QWidget(this);
154   buttons->setLayout(layout);
155
156   return(buttons);
157 }
158
159 // Click on a cell button
160 // ----------------------
161
162 void BatchJobsListDialog::userCell(QTableWidgetItem* cell) {
163   if ( cell->flags() ) {
164     int line = cell->row();
165     string sid = _table->item(line,3)->text().toStdString();
166     _id = atoi(sid.c_str());
167     _ok->setEnabled(true);
168
169     QTableWidget* table = cell->tableWidget();
170     for (int c=0; c<4; c++) {
171       QTableWidgetItem* it = table->item(line, c);
172       it->setSelected(true);
173     };
174   };
175 }
176
177 // Click on OK button
178 // ------------------
179
180 void BatchJobsListDialog::userOK() {
181
182   // get job file name
183   Engines::JobParameters* jobParam = _salome_launcher->getJobParameters(_id);
184   _jobFile = CORBA::string_dup(jobParam->job_file);
185   _dumpStateFile = QString("/tmp/%1/dumpState_%2.xml").arg(getenv("USER")).arg(QFileInfo(_jobFile).baseName());
186
187   // stop first timer and hide window
188   _timer1->stop();
189   hide();
190
191   // replace objref by string in YACS schema job file to avoid trying to reach remote objects
192   filterJobFile();
193
194   // display yacs graph
195   YACSGuiLoader *loader = _genericGui->getLoader();
196   _proc = loader->load(_filteredJobFile.toLatin1());
197   if (!_proc) {
198     QMessageBox msgBox(QMessageBox::Critical, "Import Batch Schema, native YACS XML format",
199                        "The xml graph has not the native YACS XML format or is not readable." );
200     msgBox.exec();
201   } 
202   else {
203     YACS::ENGINE::Logger* logger= _proc->getLogger("parser");
204     if(!logger->isEmpty()) {
205       DEBTRACE(logger->getStr());
206     };
207     _genericGui->createContext(_proc, _filteredJobFile, _filteredJobFile, false);
208   };
209
210   // start second timer to get remote graph state xml file
211   _timer2 = new QTimer(this);
212   connect(_timer2, SIGNAL(timeout()), this, SLOT(get_dump_file()));
213   _timer2->start(30000);
214   get_dump_file();
215 }
216
217 // Click on CANCEL button
218 // ----------------------
219
220 void BatchJobsListDialog::userCancel() {
221   _timer1->stop();
222   hide();
223 }
224
225 // get remote graph state xml file
226
227 void BatchJobsListDialog::get_dump_file()
228 {
229   int execState = YACS::NOTYETINITIALIZED;
230   // get batch job state
231   string jobState = _salome_launcher->getJobState(_id);
232   // get dump state remote file
233   bool ret = _salome_launcher->getJobDumpState(_id, QFileInfo(_dumpStateFile).absolutePath().toLatin1().constData());
234   if(ret){
235     // replace objref by string in dump state file
236     filterDumpStateFile();
237     // parse dump state file and load proc
238     YACS::ENGINE::loadState(_proc,_filteredDumpStateFile.toStdString());
239     // display remote graph states
240     GuiExecutor *executor = QtGuiContext::getQtCurrent()->getGuiExecutor();
241     execState = executor->updateSchema(jobState);
242   }
243   // stop timer if job is not running
244   if((execState!=YACS::RUNNING)&&(execState!=YACS::NOTYETINITIALIZED))
245     _timer2->stop();
246 }
247
248 // filtering of _jobFile to replace objref by string
249 void BatchJobsListDialog::filterJobFile()
250 {
251   _filteredJobFile = QString("/tmp/%1/%2.xml").arg(getenv("USER")).arg(QFileInfo(_jobFile).baseName());
252   // reading input file
253   ifstream infile(_jobFile.toStdString().c_str());
254   if(!infile){
255     string errmsg = "File " + _jobFile.toStdString() + " doesn't exist!!";
256     throw YACS::Exception(errmsg);
257   }
258   string buffer;
259   vector<string> objref;
260   while( !infile.eof() ){
261     getline(infile,buffer);
262     // look for objref and memorize them in vector
263     if( (buffer.find("objref") != string::npos) && (buffer.find("IDL") != string::npos) ){
264       size_t pos1 = buffer.find("\"");
265       size_t pos2 = buffer.find("\"",pos1+1);
266       objref.push_back(buffer.substr(pos1+1,pos2-pos1-1));
267     }
268   }
269   infile.close();
270   // reread the input file
271   infile.open(_jobFile.toStdString().c_str());
272   // open the output file
273   ofstream outfile(_filteredJobFile.toStdString().c_str());
274   if(!outfile){
275     string errmsg = "Impossible to create the file " + _filteredJobFile.toStdString() + "!!";
276     throw YACS::Exception(errmsg);
277   }
278   while( !infile.eof() ){
279     getline(infile,buffer);
280     // replace objref by string
281     if( ((buffer.find("objref") == string::npos) || (buffer.find("IDL") == string::npos)) && (buffer.find("/objref") == string::npos) ){
282       string tmp = buffer;
283       for(int i=0;i<objref.size();i++){
284         size_t pos = buffer.find(objref[i]);
285         if(pos != string::npos)
286           tmp = buffer.substr(0,pos) + "string" + buffer.substr(pos+objref[i].size());
287       }
288       outfile << tmp << endl;
289     }
290   }
291 }
292
293 // filtering of _dumpStateFile to replace objref by string
294 void BatchJobsListDialog::filterDumpStateFile()
295 {
296   string buffer;
297   _filteredDumpStateFile = QString("/tmp/%1/filtered_%2.xml").arg(getenv("USER")).arg(QFileInfo(_dumpStateFile).baseName());
298   ifstream infile(_dumpStateFile.toStdString().c_str());
299   if(!infile){
300     string errmsg = "File " + _dumpStateFile.toStdString() + " doesn't exist!!";
301     throw YACS::Exception(errmsg);
302   }
303   ofstream outfile(_filteredDumpStateFile.toStdString().c_str());
304   if(!outfile){
305     string errmsg = "Impossible to create the file " + _filteredDumpStateFile.toStdString() + "!!";
306     throw YACS::Exception(errmsg);
307   }
308   // replace objref by string in dump state file
309   while( !infile.eof() ){
310     getline(infile,buffer);
311     size_t pos = buffer.find("objref");
312     while(pos != string::npos){
313       buffer.replace(pos,6,"string");
314       pos = buffer.find("objref");
315     }
316     outfile << buffer << endl;
317   }
318 }
319