]> SALOME platform Git repositories - modules/jobmanager.git/blob - src/genericgui/BL_CreateJobWizard.cxx
Salome HOME
Add possibility to keep default values for memory and time requirements
[modules/jobmanager.git] / src / genericgui / BL_CreateJobWizard.cxx
1 // Copyright (C) 2009-2014  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, or (at your option) any later version.
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 "BL_CreateJobWizard.hxx"
21 #include "BL_JobsManager_QT.hxx"
22 #ifndef WNT
23 #include <unistd.h>
24 #include <pwd.h>
25 #endif
26 #include <sys/types.h>
27 #include <stdlib.h>
28 #include <time.h>
29
30 #include <ui_ResourceRequirementsWizardPage.h>
31 #include <ui_FilesWizardPage.h>
32 #include <ui_AdvancedParametersWizardPage.h>
33
34 #ifdef WNT
35 #undef ERROR
36 #endif
37
38 using namespace std;
39 using namespace BL;
40
41 BL::CreateJobWizard::CreateJobWizard(BL::JobsManager_QT * jobs_manager, BL::SALOMEServices * salome_services)
42 {
43   DEBTRACE("Creating BL::CreateJobWizard");
44   BL_ASSERT(jobs_manager);
45   BL_ASSERT(salome_services);
46   _jobs_manager = jobs_manager;
47   _salome_services = salome_services;
48
49   job_name = "";
50   yacs_file = "";
51   command = "";
52   python_salome_file = "";
53   env_file = "";
54   batch_directory = "";
55
56   // For COORM
57   coorm_batch_directory = "";
58
59   maximum_duration = "";
60   mem_limit = 0;
61   mem_req_type = BL::Job::MEM_PER_NODE;
62   nb_proc = 1;
63
64   // Parameters for COORM
65   launcher_file = "";
66   launcher_args = "";
67
68   result_directory = "";
69
70   resource_choosed = "";
71   batch_queue = "";
72
73   start_job = false;
74   dump_yacs_state = -1;
75   ll_jobtype = "";
76
77   setOptions(QWizard::NoBackButtonOnStartPage);
78
79   // Common pages
80   _job_name_page = new BL::JobNamePage(this, _jobs_manager);
81   _batch_parameters_page = new BL::BatchParametersPage(this, salome_services);
82
83   setPage(Page_JobName, _job_name_page);
84   setPage(Page_BatchParameters, _batch_parameters_page);
85
86   // For COORM
87   setPage(Page_COORM_BatchParameters, new BL::COORM_BatchParametersPage(this, salome_services));
88
89   setPage(Page_Files, new BL::FilesPage(this, salome_services));
90   setPage(Page_Resource, new BL::ResourcePage(this, salome_services));
91   setPage(Page_Advanced, new BL::AdvancedParametersPage(this));
92   setPage(Page_Conclusion, new BL::ConclusionPage(this));
93
94   // Specific pages
95   setPage(Page_YACSSchema, new BL::YACSSchemaPage(this));
96   setPage(Page_Command_Main_Definitions, new BL::CommandMainPage(this));
97   setPage(Page_PythonSalome_Main_Definitions, new BL::PythonSalomeMainPage(this));
98
99   setWindowTitle("Create Job Wizard");
100   connect(this, SIGNAL(finished(int)), this, SLOT(end(int)));
101 }
102
103 BL::CreateJobWizard::~CreateJobWizard()
104 {
105   DEBTRACE("Destroying BL::CreateJobWizard");
106 }
107
108 void
109 BL::CreateJobWizard::clone(const std::string & name)
110 {
111   if (_jobs_manager->job_already_exist(name) == true)
112   {
113     BL::Job * job = _jobs_manager->getJob(name);
114
115     // We can only edit a job in CREATED, ERROR, FAILED and NOT_CREATED
116     if (job->getState() == BL::Job::CREATED ||
117         job->getState() == BL::Job::ERROR   ||
118         job->getState() == BL::Job::FAILED  ||
119         job->getState() == BL::Job::NOT_CREATED)
120     { 
121       setField("job_name", QString(name.c_str()));
122       _job_name_page->_check_name = false;
123     }
124
125     if (job->getType() == BL::Job::YACS_SCHEMA)
126     {
127       setField("yacs_file", QString(job->getJobFile().c_str()));
128       _job_name_page->_yacs_schema_button->click();
129       setField("env_yacs_file", QString(job->getEnvFile().c_str()));
130       if (job->getDumpYACSState() != -1)
131       {
132         QString value;
133         value.setNum(job->getDumpYACSState());
134         setField("dump_yacs_state", value);
135       }
136     }
137     else if (job->getType() == BL::Job::COMMAND)
138     {
139       setField("command", QString(job->getJobFile().c_str()));
140       _job_name_page->_command_button->click();
141       setField("env_command_file", QString(job->getEnvFile().c_str()));
142     }
143     else if (job->getType() == BL::Job::PYTHON_SALOME)
144     {
145       setField("PythonSalome", QString(job->getJobFile().c_str()));
146       _job_name_page->_python_salome_button->click();
147       setField("env_PythonSalome_file", QString(job->getEnvFile().c_str()));
148     }
149
150
151         // For COORM
152     BL::Job::BatchParam batch_params = job->getBatchParameters();
153         BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(job->getResource().c_str());
154         std::string batch = resource_descr.batch.c_str();
155         if (batch == "coorm")
156         {
157                 setField("coorm_batch_directory", QString(batch_params.batch_directory.c_str()));
158                 setField("launcher_file", QString(batch_params.launcher_file.c_str()));
159                 setField("launcher_args", QString(batch_params.launcher_args.c_str()));
160         }
161         else
162         {
163                 setField("batch_directory", QString(batch_params.batch_directory.c_str()));
164         }
165
166     QString proc_value;
167     proc_value.setNum(batch_params.nb_proc);
168     setField("proc_value", proc_value);
169
170     setField("exclusive", batch_params.exclusive);
171
172     if (batch_params.maximum_duration == "")
173     {
174       setField("default_time", true);
175       setField("duration_hour", 0);
176       setField("duration_min", 0);
177     }
178     else
179     {
180       setField("user_time", true);
181       std::size_t pos = batch_params.maximum_duration.find(":");
182       std::string hour_str = batch_params.maximum_duration.substr(0, pos);
183       int hour; 
184       std::istringstream iss_hour(hour_str);
185       iss_hour >> hour;
186       setField("duration_hour", hour);
187
188       std::string min_str = batch_params.maximum_duration.substr(pos + 1, batch_params.maximum_duration.npos);
189       int min; 
190       std::istringstream iss_min(min_str);
191       iss_min >> min;
192       setField("duration_min", min);
193     }
194
195     long long mem_mb = batch_params.mem_limit;
196     if (mem_mb < 1)
197     {
198       setField("default_mem", true);
199     }
200     else
201     {
202       setField("user_mem", true);
203       if (mem_mb % 1024 == 0)
204       {
205         setField("mem_value", mem_mb / 1024);
206         _batch_parameters_page->setMemUnit(BatchParametersPage::GB);
207       }
208       else
209       {
210         setField("mem_value", mem_mb);
211         _batch_parameters_page->setMemUnit(BatchParametersPage::MB);
212       }
213       _batch_parameters_page->setMemReqType(batch_params.mem_req_type);
214     }
215
216     BL::Job::FilesParam files_params = job->getFilesParameters();
217
218     std::list<std::string>::iterator it = files_params.input_files_list.begin();
219     for (; it != files_params.input_files_list.end(); it++)
220       _input_files_list->addItem(QString((*it).c_str()));
221     it = files_params.output_files_list.begin();
222     for (; it != files_params.output_files_list.end(); it++)
223       _output_files_list->addItem(QString((*it).c_str()));
224
225     setField("result_directory", QString(files_params.result_directory.c_str()));
226     setField("resource_choosed", QString(job->getResource().c_str()));
227     setField("batch_queue", QString(job->getBatchQueue().c_str()));
228     setField("ll_jobtype", QString(job->getLoadLevelerJobType().c_str()));
229     setField("wckey", QString(job->getWCKey().c_str()));
230   }
231 }
232
233 void
234 BL::CreateJobWizard::setFilesList(QListWidget * input_files_list, QListWidget * output_files_list)
235 {
236   _input_files_list = input_files_list;
237   _output_files_list = output_files_list;
238 }
239
240 void
241 BL::CreateJobWizard::end(int result)
242 {
243   DEBTRACE("End of BL::CreateJobWizard");
244   if (result)
245   {
246     // Job Name Panel
247     QString f_job_name = field("job_name").toString();
248     job_name = f_job_name.trimmed().toUtf8().constData();
249
250     // YACS Schema Panel
251     QString f_yacs_file = field("yacs_file").toString();
252     yacs_file = f_yacs_file.trimmed().toUtf8().constData();
253     dump_yacs_state = field("dump_yacs_state").toInt();
254
255     // Command Panel
256     QString f_command = field("command").toString();
257     command = f_command.trimmed().toUtf8().constData();
258
259     // Command Panel
260     QString f_python_salome_file = field("PythonSalome").toString();
261     python_salome_file = f_python_salome_file.trimmed().toUtf8().constData();
262
263     QString f_env_file;
264     if (yacs_file != "")
265       f_env_file = field("env_yacs_file").toString();
266     else if (command != "")
267       f_env_file = field("env_command_file").toString();
268     else if (python_salome_file != "")
269       f_env_file = field("env_PythonSalome_file").toString();
270     env_file = f_env_file.trimmed().toUtf8().constData();
271
272     // Batch Panel
273     QString f_batch_directory = field("batch_directory").toString();
274     batch_directory = f_batch_directory.trimmed().toUtf8().constData();
275
276     // For COORM
277     QString f_coorm_batch_directory = field("coorm_batch_directory").toString();
278     coorm_batch_directory = f_coorm_batch_directory.toUtf8().constData();
279
280         // For COORM
281     QString f_launcher_file = field("launcher_file").toString();
282     launcher_file = f_launcher_file.toUtf8().constData();
283     QString f_launcher_args = field("launcher_args").toString();
284     launcher_args = f_launcher_args.toUtf8().constData();
285
286     QString time_hour;
287     QString time_min;
288     if (field("default_time").toBool() ||
289         (field("duration_hour").toInt() == 0 && field("duration_min").toInt() == 0))
290     {
291       maximum_duration = "";
292     }
293     else
294     {
295       if (field("duration_hour").toInt() < 10)
296         time_hour = "0" + field("duration_hour").toString().trimmed();
297       else
298         time_hour = field("duration_hour").toString().trimmed();
299       if (field("duration_min").toInt() < 10)
300         time_min = "0" + field("duration_min").toString().trimmed();
301       else
302         time_min = field("duration_min").toString().trimmed();
303       maximum_duration = time_hour.toStdString() + ":" + time_min.toStdString();
304     }
305
306     if(field("default_mem").toBool())
307     {
308       mem_limit = -1;
309     }
310     else
311     {
312       unsigned long mem = field("mem_value").toULongLong();
313       BatchParametersPage::MemUnit mem_unit = _batch_parameters_page->getMemUnit();
314       switch (mem_unit)
315       {
316       case BatchParametersPage::MB:
317         mem_limit = mem;
318         break;
319       case BatchParametersPage::GB:
320         mem_limit = mem * 1024;
321         break;
322       default:
323         throw Exception("Invalid memory unit");
324       }
325       mem_req_type = _batch_parameters_page->getMemReqType();
326     }
327
328     nb_proc = field("proc_value").toInt();
329     exclusive = field("exclusive").toBool();
330
331     // Files Panel
332     QString f_result_directory = field("result_directory").toString();
333     result_directory = f_result_directory.trimmed().toUtf8().constData();
334     for (int i = 0; i < _input_files_list->count(); ++i)
335     {
336       QListWidgetItem * item = _input_files_list->item(i);
337       QString item_text = item->text();
338       input_files_list.push_back(item_text.trimmed().toUtf8().constData());
339     }
340     for (int i = 0; i < _output_files_list->count(); ++i)
341     {
342       QListWidgetItem * item = _output_files_list->item(i);
343       QString item_text = item->text();
344       output_files_list.push_back(item_text.trimmed().toUtf8().constData());
345     }
346
347     // Resource list
348     QString f_resource_choosed = field("resource_choosed").toString();
349     resource_choosed = f_resource_choosed.trimmed().toUtf8().constData();
350
351     // Batch Queue
352     QString f_batch_queue = field("batch_queue").toString();
353     batch_queue = f_batch_queue.trimmed().toUtf8().constData();
354
355     // LoadLeveler JobType
356     BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(resource_choosed);
357     std::string batch = resource_descr.batch.c_str();
358     if (batch == "ll")
359     {
360       QString f_ll_jobtype = field("ll_jobtype").toString();
361       ll_jobtype = f_ll_jobtype.trimmed().toStdString();
362     }
363     else
364     {
365       ll_jobtype = "";
366     }
367
368     // WC Key
369     QString f_wckey = field("wckey").toString();
370     wckey = f_wckey.trimmed().toUtf8().constData();
371
372     start_job = field("start_job").toBool();
373   }
374 }
375
376 // Job Name Page
377 BL::JobNamePage::JobNamePage(QWidget * parent, BL::JobsManager_QT * jobs_manager)
378 : QWizardPage(parent)
379 {
380   _jobs_manager = jobs_manager;
381   _check_name = true;
382   setTitle("Create a new job");
383
384   QLabel *label = new QLabel("Enter Job name, you cannot add two jobs with the same name");
385   label->setWordWrap(true);
386   QLabel * nameLabel = new QLabel("Job Name:");
387   QLineEdit * _nameLineEdit = new QLineEdit(this);
388   registerField("job_name", _nameLineEdit);
389
390   QLabel * label_type = new QLabel("Choose type of batch job:");
391   QGroupBox *groupBox = new QGroupBox("Type of job");
392   _yacs_schema_button = new QRadioButton(tr("YACS Schema"));
393   _yacs_schema_button->setChecked(true);
394   _command_button = new QRadioButton(tr("Command"));
395   _python_salome_button = new QRadioButton(tr("Python script in SALOME"));
396   QVBoxLayout *vbox = new QVBoxLayout;
397   vbox->addWidget(_yacs_schema_button);
398   vbox->addWidget(_command_button);
399   vbox->addWidget(_python_salome_button);
400   vbox->addStretch(1);
401   groupBox->setLayout(vbox);
402
403   QGroupBox * explanationBox = new QGroupBox("Explanation");
404   QVBoxLayout *explanationvbox = new QVBoxLayout;
405   _explanation = new QLabel();
406   _explanation->setWordWrap(true);
407   explanationvbox->addWidget(_explanation);
408   explanationvbox->addStretch(1);
409   explanationBox->setLayout(explanationvbox);
410
411   // Layouts
412   QVBoxLayout * main_layout = new QVBoxLayout;
413   main_layout->addWidget(label);
414   QGridLayout *layout = new QGridLayout;
415   layout->addWidget(nameLabel, 0, 0);
416   layout->addWidget(_nameLineEdit, 0, 1);
417   main_layout->insertLayout(-1, layout);
418   layout->addWidget(label_type, 2, 0);
419   layout->addWidget(groupBox, 3, 0, 1, -1);
420   layout->addWidget(explanationBox, 4, 0, 1, -1);
421   setLayout(main_layout);
422
423   connect(_yacs_schema_button, SIGNAL(clicked(bool)), this, SLOT(yacs_schema_button(bool)));
424   connect(_command_button, SIGNAL(clicked(bool)), this, SLOT(command_button(bool)));
425   connect(_python_salome_button, SIGNAL(clicked(bool)), this, SLOT(python_salome_button(bool)));
426
427   // Default button
428   yacs_schema_button(true);
429 }
430
431 BL::JobNamePage::~JobNamePage()
432 {}
433
434 void
435 BL::JobNamePage::yacs_schema_button(bool checked)
436 {
437   if (checked)
438   {
439     _explanation->setText("This job permits to launch a YACS schema into a SALOME application");
440     setField("exclusive", true);
441   }
442 }
443
444 void
445 BL::JobNamePage::command_button(bool checked)
446 {
447   if (checked)
448   {
449     _explanation->setText("This job permits to launch a script into a distributed resource. This script is not launched into a SALOME application");
450     setField("exclusive", false);
451   }
452 }
453
454 void
455 BL::JobNamePage::python_salome_button(bool checked)
456 {
457   if (checked)
458   {
459     _explanation->setText("This job permits to launch a python script into a SALOME application");
460     setField("exclusive", true);
461   }
462 }
463
464 bool
465 BL::JobNamePage::validatePage()
466 {
467   DEBTRACE("Calling validatePage of BL::JobNamePage");
468   bool return_value;
469   QString job_name = field("job_name").toString();
470
471   // Check if job name is empty
472   if (job_name == "")
473   {
474     QMessageBox::warning(NULL, "Job Name Error", "Job name entered is empty, enter a job name or cancel the wizard");
475     return_value = false;
476   }
477
478   // Check if job name already exists
479   else {
480     if (_jobs_manager->job_already_exist(job_name.toUtf8().constData()) == false || _check_name == false)
481     {
482       return_value = true;
483     }
484     else
485     {
486       QMessageBox::critical(NULL, "Job Name Error", "Job name entered is already used");
487       QString value("");
488       setField("job_name", value);
489       return_value = false;
490     }
491   }
492
493   return return_value;
494 }
495
496 int
497 BL::JobNamePage::nextId() const
498 {
499   if (_yacs_schema_button->isChecked())
500   {
501     return BL::CreateJobWizard::Page_YACSSchema;
502   } 
503   else if (_command_button->isChecked())
504   {
505     return BL::CreateJobWizard::Page_Command_Main_Definitions;
506   }
507   else
508   {
509     return BL::CreateJobWizard::Page_PythonSalome_Main_Definitions;
510   }
511 }
512
513 BL::YACSSchemaPage::YACSSchemaPage(QWidget * parent)
514 : QWizardPage(parent)
515 {
516   setTitle("Configure YACS Execution");
517
518   QLabel *label = new QLabel("In this step you have to configure your YACS execution");
519   label->setWordWrap(true);
520
521   QGroupBox * files_param_box = new QGroupBox("YACS job files");
522   QPushButton * yacs_file_button = new QPushButton(tr("Choose YACS Schema file"));
523   connect(yacs_file_button, SIGNAL(clicked()), this, SLOT(choose_file()));
524   _yacs_file_text = new QLineEdit(this);
525   _yacs_file_text->setText("");
526   registerField("yacs_file", _yacs_file_text);
527   _yacs_file_text->setReadOnly(true);
528   QPushButton * command_env_file_button = new QPushButton(tr("Choose an environnement file"));
529   connect(command_env_file_button, SIGNAL(clicked()), this, SLOT(choose_env_file()));
530   _line_env_file = new QLineEdit(this);
531   registerField("env_yacs_file", _line_env_file);
532   _line_env_file->setReadOnly(true);
533   QGridLayout * files_layout = new QGridLayout;
534   files_layout->addWidget(yacs_file_button, 0, 0);
535   files_layout->addWidget(_yacs_file_text, 0, 1);
536   files_layout->addWidget(command_env_file_button, 1, 0);
537   files_layout->addWidget(_line_env_file, 1, 1);
538   files_param_box->setLayout(files_layout);
539
540   QGroupBox * spec_param_box = new QGroupBox("YACS specific parameters");
541   QLabel * label_dump =  new QLabel("Dump YACS state each secs (0 disable this feature)");
542   QLabel * label_dump_warning = new QLabel("(WARNING: can only be used with SALOME >= 6.3.0)");
543   QSpinBox * spin_dump = new QSpinBox(this);
544   spin_dump->setMinimum(0);
545   spin_dump->setMaximum(1000000);
546   registerField("dump_yacs_state", spin_dump);
547   QGridLayout * specific_layout = new QGridLayout;
548   specific_layout->addWidget(label_dump, 0, 0);
549   specific_layout->addWidget(spin_dump, 0, 1);
550   specific_layout->addWidget(label_dump_warning, 1, 0);
551   spec_param_box->setLayout(specific_layout);
552
553   QVBoxLayout * main_layout = new QVBoxLayout;
554   main_layout->addWidget(label);
555   main_layout->addWidget(files_param_box);
556   main_layout->addWidget(spec_param_box);
557
558   setLayout(main_layout);
559 };
560
561 BL::YACSSchemaPage::~YACSSchemaPage()
562 {}
563
564 bool
565 BL::YACSSchemaPage::validatePage()
566 {
567   bool return_value;
568   QString yacs_file = field("yacs_file").toString();
569   if (yacs_file != "")
570   {
571     return_value = true;
572   }
573   else
574   {
575     QMessageBox::warning(NULL, "YACS File Error", "Please choose a YACS File");
576     return_value = false;
577   }
578   return return_value;
579 }
580
581 void
582 BL::YACSSchemaPage::choose_file()
583 {
584   QString yacs_file = QFileDialog::getOpenFileName(this,
585                                                    tr("Open YACS files"), "",
586                                                    tr("XML (*.xml);;All Files (*)"));
587   _yacs_file_text->setReadOnly(false);
588   _yacs_file_text->setText(yacs_file);
589   _yacs_file_text->setReadOnly(true);
590 }
591
592 void
593 BL::YACSSchemaPage::choose_env_file()
594 {
595   QString env_file = QFileDialog::getOpenFileName(this,
596                                                   tr("Open environnement file"), "",
597                                                   tr("sh (*.sh);;All Files (*)"));
598   _line_env_file->setReadOnly(false);
599   _line_env_file->setText(env_file);
600   _line_env_file->setReadOnly(true);
601 }
602
603
604 int 
605 BL::YACSSchemaPage::nextId() const
606 {
607   return BL::CreateJobWizard::Page_Resource;
608 }
609
610 BL::CommandMainPage::CommandMainPage(QWidget * parent)
611 : QWizardPage(parent)
612 {
613   setTitle("Define command job");
614   QLabel *label = new QLabel("Enter the command that will be executed into the resource");
615   label->setWordWrap(true);
616
617   // command
618   QPushButton * command_file_button = new QPushButton(tr("Choose a command file"));
619   connect(command_file_button, SIGNAL(clicked()), this, SLOT(choose_command_file()));
620   _line_command = new QLineEdit(this);
621   registerField("command", _line_command);
622   _line_command->setReadOnly(true);
623
624   QPushButton * command_env_file_button = new QPushButton(tr("Choose an environnement file"));
625   connect(command_env_file_button, SIGNAL(clicked()), this, SLOT(choose_env_file()));
626   _line_env_file = new QLineEdit(this);
627   registerField("env_command_file", _line_env_file);
628   _line_env_file->setReadOnly(true);
629
630   QGridLayout *layout = new QGridLayout;
631   layout->addWidget(command_file_button, 0, 0);
632   layout->addWidget(_line_command, 0, 1);
633   layout->addWidget(command_env_file_button, 1, 0);
634   layout->addWidget(_line_env_file, 1, 1);
635
636   QVBoxLayout * main_layout = new QVBoxLayout;
637   main_layout->addWidget(label);
638   main_layout->insertLayout(-1, layout);
639   setLayout(main_layout);
640 };
641
642 BL::CommandMainPage::~CommandMainPage()
643 {}
644
645 void
646 BL::CommandMainPage::choose_command_file()
647 {
648   QString command_file = QFileDialog::getOpenFileName(this,
649                                                       tr("Open command file"), "",
650                                                       tr("sh (*.sh);;All Files (*)"));
651   _line_command->setReadOnly(false);
652   _line_command->setText(command_file);
653   _line_command->setReadOnly(true);
654 }
655
656 void
657 BL::CommandMainPage::choose_env_file()
658 {
659   QString env_file = QFileDialog::getOpenFileName(this,
660                                                   tr("Open environnement file"), "",
661                                                   tr("sh (*.sh);;All Files (*)"));
662   _line_env_file->setReadOnly(false);
663   _line_env_file->setText(env_file);
664   _line_env_file->setReadOnly(true);
665 }
666
667 bool
668 BL::CommandMainPage::validatePage()
669 {
670   QString command = field("command").toString();
671   if (command == "")
672   {
673     QMessageBox::warning(NULL, "Command Error", "Please enter a command");
674     return false;
675   }
676
677   return true;
678 }
679
680 int 
681 BL::CommandMainPage::nextId() const
682 {
683   return BL::CreateJobWizard::Page_Resource;
684 }
685
686 BatchParametersPage::BatchParametersPage(QWidget * parent, SALOMEServices * salome_services)
687 : QWizardPage(parent),
688   ui(new Ui::ResourceRequirementsWizardPage),
689   _salome_services(salome_services),
690   resource_choosed()
691 {
692   ui->setupUi(this);
693
694   registerField("duration_hour", ui->spin_duration_hour);
695   registerField("duration_min", ui->spin_duration_min);
696   registerField("mem_value", ui->spin_memory);
697   registerField("proc_value", ui->spin_proc);
698   registerField("exclusive", ui->check_exclusive);
699   registerField("default_time", ui->rb_default_time);
700   registerField("user_time", ui->rb_user_time);
701   registerField("default_mem", ui->rb_default_mem);
702   registerField("user_mem", ui->rb_user_mem);
703
704   ui->combo_memory_unit->insertItem(ui->combo_memory_unit->count(), "MB", MB);
705   ui->combo_memory_unit->insertItem(ui->combo_memory_unit->count(), "GB", GB);
706   setMemUnit(GB);
707
708   ui->combo_memory_req_type->insertItem(ui->combo_memory_req_type->count(),
709                                         "per node", Job::MEM_PER_NODE);
710   ui->combo_memory_req_type->insertItem(ui->combo_memory_req_type->count(),
711                                         "per core", Job::MEM_PER_CPU);
712
713   connect(ui->spin_duration_hour, SIGNAL(valueChanged(int)), this, SLOT(timeChanged()));
714   connect(ui->spin_duration_min, SIGNAL(valueChanged(int)), this, SLOT(timeChanged()));
715   connect(ui->spin_memory, SIGNAL(valueChanged(int)), this, SLOT(memChanged()));
716   connect(ui->combo_memory_unit, SIGNAL(currentIndexChanged(int)), this, SLOT(memChanged()));
717   connect(ui->combo_memory_req_type, SIGNAL(currentIndexChanged(int)), this, SLOT(memChanged()));
718 };
719
720 BatchParametersPage::~BatchParametersPage()
721 {
722   delete ui;
723 }
724
725 void
726 BatchParametersPage::initializePage()
727 {
728   string f_resource_choosed = field("resource_choosed").toString().toUtf8().constData();
729   if (f_resource_choosed != resource_choosed)
730   {
731     resource_choosed = f_resource_choosed;
732     // If choosed resource has a SLURM batch manager, activate option "memory per cpu"
733     ResourceDescr resource_descr = _salome_services->getResourceDescr(resource_choosed);
734     if (resource_descr.batch == "slurm")
735     {
736       ui->combo_memory_req_type->setEnabled(true);
737     }
738     else
739     {
740       ui->combo_memory_req_type->setEnabled(false);
741       setMemReqType(Job::MEM_PER_NODE);
742     }
743   }
744 }
745
746 BatchParametersPage::MemUnit
747 BatchParametersPage::getMemUnit() const
748 {
749   int idx = ui->combo_memory_unit->currentIndex();
750   return (MemUnit)(ui->combo_memory_unit->itemData(idx).toInt());
751 }
752
753 void
754 BatchParametersPage::setMemUnit(MemUnit mem_unit)
755 {
756   ui->combo_memory_unit->setCurrentIndex(ui->combo_memory_unit->findData(mem_unit));
757 }
758
759 Job::MemReqType
760 BatchParametersPage::getMemReqType() const
761 {
762   int idx = ui->combo_memory_req_type->currentIndex();
763   return (Job::MemReqType)(ui->combo_memory_req_type->itemData(idx).toInt());
764 }
765
766 void
767 BatchParametersPage::setMemReqType(Job::MemReqType mem_req_type)
768 {
769   ui->combo_memory_req_type->setCurrentIndex(ui->combo_memory_req_type->findData(mem_req_type));
770 }
771
772 void
773 BatchParametersPage::timeChanged()
774 {
775   if (ui->spin_duration_hour->value() == 0 && ui->spin_duration_min->value() == 0)
776     ui->rb_default_time->setChecked(true);
777   else
778     ui->rb_user_time->setChecked(true);
779 }
780
781 void
782 BatchParametersPage::memChanged()
783 {
784   ui->rb_user_mem->setChecked(true);
785 }
786
787 void
788 BatchParametersPage::cleanupPage()
789 {
790 }
791
792 int 
793 BatchParametersPage::nextId() const
794 {
795   return CreateJobWizard::Page_Files;
796 }
797
798 BL::COORM_BatchParametersPage::COORM_BatchParametersPage(QWidget * parent, BL::SALOMEServices * salome_services)
799 : QWizardPage(parent)
800 {
801   setTitle("Enter COORM Parameters");
802   resource_choosed = "";
803
804   _salome_services = salome_services;
805
806   QLabel *label = new QLabel("In this step you define the parameters for COORM");
807   label->setWordWrap(true);
808   QVBoxLayout * main_layout = new QVBoxLayout;
809   main_layout->addWidget(label);
810
811   // coorm_batch_directory
812   QLabel * label_directory = new QLabel("Remote work directory: ");
813   QLineEdit * line_directory = new QLineEdit(this);
814   registerField("coorm_batch_directory", line_directory);
815
816   // launcher_file
817   QPushButton * launcher_file_button = new QPushButton(tr("Choose a launcher file"));
818   connect(launcher_file_button, SIGNAL(clicked()), this, SLOT(choose_launcher_file()));
819   _launcher_file_text = new QLineEdit(this);
820   _launcher_file_text->setText("");
821   registerField("launcher_file", _launcher_file_text);
822   _launcher_file_text->setReadOnly(true);
823
824   // launcher_args
825   QLabel * launcher_args_label = new QLabel("Launcher args:");
826   QLineEdit * launcher_args_text = new QLineEdit(this);
827   registerField("launcher_args", launcher_args_text);
828
829   QGridLayout * layout = new QGridLayout;
830   layout->addWidget(label_directory, 0, 0);
831   layout->addWidget(line_directory, 0, 1);
832   layout->addWidget(launcher_file_button, 1, 0);
833   layout->addWidget(_launcher_file_text, 1, 1);
834   layout->addWidget(launcher_args_label, 2, 0);
835   layout->addWidget(launcher_args_text, 2, 1);
836
837   main_layout->insertLayout(-1, layout);
838
839   setLayout(main_layout);
840 };
841
842 BL::COORM_BatchParametersPage::~COORM_BatchParametersPage()
843 {}
844
845 bool
846 BL::COORM_BatchParametersPage::validatePage()
847 {
848   QString coorm_batch_directory = field("coorm_batch_directory").toString();
849   if (coorm_batch_directory == "")
850   {
851     QMessageBox::warning(NULL, "Batch Directory Error", "Please enter a batch directory");
852     return false;
853   }
854
855   QString launcher_file = field("launcher_file").toString();
856   if (launcher_file == "")
857   {
858     QMessageBox::warning(NULL, "Launcher File Error", "Please enter a launcher file");
859     return false;
860   }
861
862   return true;
863 }
864
865 int
866 BL::COORM_BatchParametersPage::nextId() const
867 {
868   return BL::CreateJobWizard::Page_Files;
869 }
870
871 void
872 BL::COORM_BatchParametersPage::choose_launcher_file()
873 {
874   QString launcher_file = QFileDialog::getOpenFileName(this,
875                                                    tr("Open launcher files"), "",
876                                                    tr("Py (*.py);;All Files (*)"));
877   _launcher_file_text->setReadOnly(false);
878   _launcher_file_text->setText(launcher_file);
879   _launcher_file_text->setReadOnly(true);
880 }
881
882 void BL::COORM_BatchParametersPage::cleanupPage()
883 {}
884
885 void
886 BL::COORM_BatchParametersPage::initializePage()
887 {
888   QString f_resource_choosed = field("resource_choosed").toString();
889   if (f_resource_choosed != resource_choosed)
890   {
891     resource_choosed = f_resource_choosed;
892     // If choosed resource has a working_directory set
893     // Generates a default remote working directory
894     BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(resource_choosed.toUtf8().constData());
895     QString res_work_dir = resource_descr.working_directory.c_str();
896     if (res_work_dir != "")
897     {
898       time_t rawtime;
899       time(&rawtime);
900       std::string launch_date = ctime(&rawtime);
901       for (int i = 0; i < launch_date.size(); i++)
902         if (launch_date[i] == '/' ||
903             launch_date[i] == '-' ||
904             launch_date[i] == ':' ||
905             launch_date[i] == ' ')
906           launch_date[i] = '_';
907       launch_date.erase(--launch_date.end()); // Last caracter is a \n
908       QString date = launch_date.c_str();
909       setField("coorm_batch_directory", res_work_dir + "/" + date);
910     }
911   }
912 }
913
914 FilesPage::FilesPage(CreateJobWizard * parent, SALOMEServices * salome_services)
915 : QWizardPage(parent),
916   ui(new Ui::FilesWizardPage)
917 {
918   ui->setupUi(this);
919
920   resource_choosed = "";
921   _salome_services = salome_services;
922
923   connect(ui->add_input_files_button, SIGNAL(clicked()), this, SLOT(choose_input_files()));
924   connect(ui->remove_input_files_button, SIGNAL(clicked()), this, SLOT(remove_input_files()));
925   connect(ui->input_files_list, SIGNAL(itemSelectionChanged()), this, SLOT(input_itemSelectionChanged()));
926   connect(ui->add_output_files_button, SIGNAL(clicked()), this, SLOT(add_output_file()));
927   connect(ui->remove_output_files_button, SIGNAL(clicked()), this, SLOT(remove_output_files()));
928   connect(ui->output_files_list, SIGNAL(itemSelectionChanged()), this, SLOT(output_itemSelectionChanged()));
929   connect(ui->button_choose_result_dir, SIGNAL(clicked()), this, SLOT(choose_local_directory()));
930
931   registerField("batch_directory", ui->line_remote_working_dir);
932   registerField("result_directory", ui->line_result_dir);
933
934   // Default result directory is home directory (if we found it)
935   // First try -> HOME
936 #ifdef WNT
937   ui->line_result_dir->setText(getenv("HOME"));
938 #else
939   if (getenv("HOME"))
940     ui->line_result_dir->setText(getenv("HOME"));
941   else {
942     // Second try -> getpwuid
943     struct passwd * pass_struct = getpwuid(getuid());
944     if (pass_struct)
945       ui->line_result_dir->setText(pass_struct->pw_dir);
946   }
947 #endif
948
949   parent->setFilesList(ui->input_files_list, ui->output_files_list);
950
951   // Check for warning messages
952   ui->label_warning_icon->setPixmap(QIcon::fromTheme("dialog-error").pixmap(16, 16));
953   connect(ui->line_remote_working_dir, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
954   connect(ui->line_result_dir, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
955 };
956
957 FilesPage::~FilesPage()
958 {
959   delete ui;
960 }
961
962 void
963 FilesPage::initializePage()
964 {
965   QString f_resource_choosed = field("resource_choosed").toString();
966   if (f_resource_choosed != resource_choosed)
967   {
968     resource_choosed = f_resource_choosed;
969     // If choosed resource has a working_directory set
970     // Generates a default remote working directory
971     BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(resource_choosed.toUtf8().constData());
972     QString res_work_dir = resource_descr.working_directory.c_str();
973     if (res_work_dir != "")
974     {
975       time_t rawtime;
976       time(&rawtime);
977       std::string launch_date = ctime(&rawtime);
978       for (int i = 0; i < launch_date.size(); i++)
979         if (launch_date[i] == '/' ||
980             launch_date[i] == '-' ||
981             launch_date[i] == ':' ||
982             launch_date[i] == ' ')
983           launch_date[i] = '_';
984       launch_date.erase(--launch_date.end()); // Last caracter is a \n
985       QString date = launch_date.c_str();
986       setField("batch_directory", res_work_dir + "/" + date);
987     }
988   }
989 }
990
991 bool
992 FilesPage::isComplete() const
993 {
994   QString warn_msg;
995   if (field("batch_directory").toString().isEmpty())
996     warn_msg = "Remote working directory is mandatory.";
997   if (field("result_directory").toString().isEmpty() && ui->output_files_list->count() != 0)
998   {
999     if (!warn_msg.isEmpty()) warn_msg += "\n";
1000     warn_msg += "Result directory is mandatory if there are output files.";
1001   }
1002
1003   ui->label_warning_text->setText(warn_msg);
1004   if (warn_msg.isEmpty())
1005   {
1006     ui->label_warning_icon->hide();
1007     return true;
1008   }
1009   else
1010   {
1011     ui->label_warning_icon->show();
1012     return false;
1013   }
1014 }
1015
1016 void
1017 FilesPage::choose_input_files()
1018 {
1019   QStringList files = QFileDialog::getOpenFileNames(this,
1020                                                     tr("Add input files"), "",
1021                                                     tr("All Files (*)"));
1022   for (int i = 0; i < files.size(); ++i) 
1023   {
1024     if (ui->input_files_list->findItems(files.at(i), Qt::MatchFixedString).size() == 0)
1025       ui->input_files_list->addItem(files.at(i));
1026   }
1027 }
1028
1029 void
1030 FilesPage::choose_local_directory()
1031 {
1032   QString dir = QFileDialog::getExistingDirectory(this, tr("Choose local result directory"),
1033                                                  "",
1034                                                  QFileDialog::ShowDirsOnly
1035                                                  | QFileDialog::DontResolveSymlinks);
1036
1037   if (dir != "")
1038     ui->line_result_dir->setText(dir);
1039 }
1040
1041 void 
1042 FilesPage::remove_input_files()
1043 {
1044   QList<QListWidgetItem *> list = ui->input_files_list->selectedItems();
1045   for (int i = 0; i < list.size(); ++i)
1046   {
1047     int row = ui->input_files_list->row( list.at(i) );
1048     delete ui->input_files_list->takeItem(row);
1049   }
1050 }
1051
1052 void 
1053 FilesPage::input_itemSelectionChanged()
1054 {
1055   if (ui->input_files_list->selectedItems().size() > 0)
1056     ui->remove_input_files_button->setEnabled(true);
1057   else
1058     ui->remove_input_files_button->setEnabled(false);
1059 }
1060
1061 void
1062 FilesPage::add_output_file()
1063 {
1064   QListWidgetItem * new_item = new QListWidgetItem("TO EDIT!");
1065   new_item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
1066   ui->output_files_list->addItem(new_item);
1067   emit completeChanged();
1068 }
1069
1070 void 
1071 FilesPage::remove_output_files()
1072 {
1073   QList<QListWidgetItem *> list = ui->output_files_list->selectedItems();
1074   for (int i = 0; i < list.size(); ++i)
1075   {
1076     int row = ui->output_files_list->row( list.at(i) );
1077     delete ui->output_files_list->takeItem(row);
1078   }
1079   emit completeChanged();
1080 }
1081
1082 void 
1083 FilesPage::output_itemSelectionChanged()
1084 {
1085   if (ui->output_files_list->selectedItems().size() > 0)
1086     ui->remove_output_files_button->setEnabled(true);
1087   else
1088     ui->remove_output_files_button->setEnabled(false);
1089 }
1090
1091 int 
1092 FilesPage::nextId() const
1093 {
1094   return BL::CreateJobWizard::Page_Advanced;
1095 }
1096
1097 BL::ConclusionPage::ConclusionPage(QWidget * parent)
1098 : QWizardPage(parent)
1099 {
1100   setTitle("Job definition is finished");
1101   QCheckBox * check_box =  new QCheckBox("Start job after creation");
1102   registerField("start_job", check_box);
1103   QVBoxLayout * main_layout = new QVBoxLayout;
1104   main_layout->addWidget(check_box);
1105   setLayout(main_layout);
1106 };
1107
1108 BL::ConclusionPage::~ConclusionPage()
1109 {}
1110
1111 bool
1112 BL::ConclusionPage::validatePage()
1113 {
1114   return true;
1115 }
1116
1117 int 
1118 BL::ConclusionPage::nextId() const
1119 {
1120   return -1;
1121 }
1122
1123 BL::ResourcePage::ResourcePage(BL::CreateJobWizard * parent, BL::SALOMEServices * salome_services)
1124 : QWizardPage(parent)
1125 {
1126   _salome_services = salome_services;
1127   setTitle("Select a Resource");
1128
1129   QLabel * main_label = new QLabel("In this step you select the resource of your job");
1130   main_label->setWordWrap(true);
1131
1132   // input_Resource
1133   QGroupBox * resource_group_box = new QGroupBox("Resource List");
1134   _resource_list = new JM::ResourceCatalog(this, _salome_services, true);
1135   connect(_resource_list->getQListWidget(), SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(itemSelected(QListWidgetItem*)));
1136
1137   QVBoxLayout * resource_list_layout = new QVBoxLayout();
1138   resource_list_layout->addWidget(_resource_list);
1139   resource_group_box->setLayout(resource_list_layout);
1140
1141   QLabel * resource_label = new QLabel("Resource selected: ");
1142   _resource_choosed = new QLineEdit();
1143   _resource_choosed->setText("");
1144   _resource_choosed->setReadOnly(true);
1145   registerField("resource_choosed", _resource_choosed);
1146
1147   QLabel * bqLabel = new QLabel("Batch Queue (could be optional):");
1148   QLineEdit * _bqLineEdit = new QLineEdit(this);
1149   registerField("batch_queue", _bqLineEdit);
1150
1151   _ll_label = new QLabel("LoadLeveler JobType:", this);
1152   _ll_value = new QLineEdit(this);
1153   registerField("ll_jobtype", _ll_value);
1154   _ll_label->hide();
1155   _ll_value->hide();
1156
1157   _main_layout = new QGridLayout;
1158   _main_layout->addWidget(resource_group_box, 0, 0, 1, -1);
1159   _main_layout->addWidget(resource_label, 1, 0);
1160   _main_layout->addWidget(_resource_choosed, 1, 1);
1161   _main_layout->addWidget(bqLabel, 2, 0);
1162   _main_layout->addWidget(_bqLineEdit, 2, 1);
1163   setLayout(_main_layout);
1164
1165 };
1166
1167 BL::ResourcePage::~ResourcePage()
1168 {}
1169
1170 void
1171 BL::ResourcePage::initializePage()
1172 {
1173   if (field("ll_jobtype").toString() != "")
1174   {
1175     _main_layout->addWidget(_ll_label, 3, 0);
1176     _main_layout->addWidget(_ll_value, 3, 1);
1177     _ll_label->show();
1178     _ll_value->show();
1179   }
1180
1181   // Initialize resource_choosed with first resource in resource list
1182   if (field("resource_choosed").toString() == "")
1183   {
1184     std::list<std::string> resource_list = _salome_services->getResourceList(true);
1185     std::list<std::string>::iterator it = resource_list.begin();
1186     if (it != resource_list.end())
1187     {
1188       QString first_resource((*it).c_str());
1189       setField("resource_choosed", first_resource);
1190     }
1191   }
1192 }
1193
1194 bool
1195 BL::ResourcePage::validatePage()
1196 {
1197   QString resource_choosed = field("resource_choosed").toString();
1198   if (resource_choosed == "")
1199   {
1200     QMessageBox::warning(NULL, "Resource Error", "Please choose a resource");
1201     return false;
1202   }
1203
1204   BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(resource_choosed.toUtf8().constData());
1205   std::string batch = resource_descr.batch.c_str();
1206   if (batch == "ll")
1207   {
1208     QString ll_jobtype = field("ll_jobtype").toString();
1209     if (ll_jobtype == "")
1210     {
1211       QMessageBox::warning(NULL, "LoadLeveler Error", "Please define a LoadLeveler JobType");
1212       return false;
1213     }
1214   }
1215   return true;
1216 }
1217
1218 void 
1219 BL::ResourcePage::itemSelected(QListWidgetItem * item)
1220 {
1221   _resource_choosed->setReadOnly(false);
1222   _resource_choosed->setText(item->text());
1223   _resource_choosed->setReadOnly(true);
1224
1225   //Specific parameters for LoadLeveler
1226   BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(item->text().toUtf8().constData());
1227   std::string batch = resource_descr.batch.c_str();
1228   if (batch == "ll")
1229   {
1230     _main_layout->addWidget(_ll_label, 3, 0);
1231     _main_layout->addWidget(_ll_value, 3, 1);
1232     _ll_label->show();
1233     _ll_value->show();
1234   }
1235   else
1236   {
1237     _main_layout->removeWidget(_ll_value);
1238     _main_layout->removeWidget(_ll_label);
1239     _ll_label->hide();
1240     _ll_value->hide();
1241   }
1242 }
1243
1244 int 
1245 BL::ResourcePage::nextId() const
1246 {
1247   BL::ResourceDescr resource_descr = _salome_services->getResourceDescr(_resource_choosed->text().toUtf8().constData());
1248   std::string batch = resource_descr.batch.c_str();
1249   if (batch == "coorm")
1250   {
1251           return BL::CreateJobWizard::Page_COORM_BatchParameters;
1252   }
1253   else
1254   {
1255           return BL::CreateJobWizard::Page_BatchParameters;
1256   }
1257 }
1258
1259 BL::PythonSalomeMainPage::PythonSalomeMainPage(QWidget * parent)
1260 : QWizardPage(parent)
1261 {
1262   setTitle("Define a Python script in SALOME job");
1263   QLabel *label = new QLabel("Enter the Python script that will be executed into the resource");
1264   label->setWordWrap(true);
1265
1266   // PythonSalome
1267   QPushButton * PythonSalome_file_button = new QPushButton(tr("Choose a Python file"));
1268   connect(PythonSalome_file_button, SIGNAL(clicked()), this, SLOT(choose_PythonSalome_file()));
1269   _line_PythonSalome = new QLineEdit(this);
1270   registerField("PythonSalome", _line_PythonSalome);
1271   _line_PythonSalome->setReadOnly(true);
1272
1273   QPushButton * PythonSalome_env_file_button = new QPushButton(tr("Choose an environnement file"));
1274   connect(PythonSalome_env_file_button, SIGNAL(clicked()), this, SLOT(choose_env_file()));
1275   _line_env_file = new QLineEdit(this);
1276   registerField("env_PythonSalome_file", _line_env_file);
1277   _line_env_file->setReadOnly(true);
1278
1279   QGridLayout *layout = new QGridLayout;
1280   layout->addWidget(PythonSalome_file_button, 0, 0);
1281   layout->addWidget(_line_PythonSalome, 0, 1);
1282   layout->addWidget(PythonSalome_env_file_button, 1, 0);
1283   layout->addWidget(_line_env_file, 1, 1);
1284
1285   QVBoxLayout * main_layout = new QVBoxLayout;
1286   main_layout->addWidget(label);
1287   main_layout->insertLayout(-1, layout);
1288   setLayout(main_layout);
1289 };
1290
1291 BL::PythonSalomeMainPage::~PythonSalomeMainPage()
1292 {}
1293
1294 void
1295 BL::PythonSalomeMainPage::choose_PythonSalome_file()
1296 {
1297   QString PythonSalome_file = QFileDialog::getOpenFileName(this,
1298                                                       tr("Open Python script file"), "",
1299                                                       tr("py (*.py);;All Files (*)"));
1300   _line_PythonSalome->setReadOnly(false);
1301   _line_PythonSalome->setText(PythonSalome_file);
1302   _line_PythonSalome->setReadOnly(true);
1303 }
1304
1305 void
1306 BL::PythonSalomeMainPage::choose_env_file()
1307 {
1308   QString env_file = QFileDialog::getOpenFileName(this,
1309                                                       tr("Open environnement file"), "",
1310                                                       tr("sh (*.sh);;All Files (*)"));
1311   _line_env_file->setReadOnly(false);
1312   _line_env_file->setText(env_file);
1313   _line_env_file->setReadOnly(true);
1314 }
1315
1316 bool
1317 BL::PythonSalomeMainPage::validatePage()
1318 {
1319   QString PythonSalome = field("PythonSalome").toString();
1320   if (PythonSalome == "")
1321   {
1322     QMessageBox::warning(NULL, "Python script in SALOME Error", "Please enter a Python script");
1323     return false;
1324   }
1325
1326   return true;
1327 }
1328
1329 int 
1330 BL::PythonSalomeMainPage::nextId() const
1331 {
1332   return BL::CreateJobWizard::Page_Resource;
1333 }
1334
1335
1336
1337 AdvancedParametersPage::AdvancedParametersPage(CreateJobWizard * parent)
1338 : QWizardPage(parent),
1339   ui(new Ui::AdvancedParametersWizardPage)
1340 {
1341   ui->setupUi(this);
1342   registerField("wckey", ui->line_wckey);
1343 };
1344
1345 AdvancedParametersPage::~AdvancedParametersPage()
1346 {
1347   delete ui;
1348 }
1349
1350 int
1351 AdvancedParametersPage::nextId() const
1352 {
1353   return BL::CreateJobWizard::Page_Conclusion;
1354 }