Salome HOME
Copyright update 2021
[modules/yacs.git] / src / ydfx_gui / ResourceWidget.cxx
1 // Copyright (C) 2017-2021  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 "ResourceWidget.hxx"
21
22 ResourceWidget::ResourceWidget(AbstractResourceModel* model, QWidget* parent)
23 : QScrollArea(parent),
24   _model(model),
25   _clusterBox(0),
26   _localdirEdit(0)
27 {
28   QWidget* mainWidget = new QWidget();
29   QVBoxLayout *mainLayout = new QVBoxLayout();
30   mainWidget->setLayout(mainLayout);
31   QGroupBox *resourcesBox = new QGroupBox();
32   resourcesBox->setTitle(tr("Launching parameters"));
33   mainLayout->addWidget(resourcesBox);
34   QGridLayout *resourcesLayout = new QGridLayout();
35   resourcesBox->setLayout(resourcesLayout);
36   
37   QCheckBox *parallelizeStatusCheckBox = new QCheckBox(tr("Parallelize status"));
38   parallelizeStatusCheckBox->setChecked(_model->getParallelizeStatus());
39   connect(parallelizeStatusCheckBox, SIGNAL(toggled(bool)),
40           this, SLOT(updateParallelizeStatus(bool)));
41   resourcesLayout->addWidget(parallelizeStatusCheckBox, 0, 0);
42   
43   QLabel * resourcesLabel = new QLabel(tr("Computing resource:"));
44   resourcesLayout->addWidget(resourcesLabel, 1, 0);
45   
46   QComboBox* resourcesComboBox = new QComboBox;
47   std::vector<std::string> resources = _model->getFittingMachines();
48   std::vector<std::string>::const_iterator it;
49   for(it=resources.begin(); it!=resources.end(); it++)
50     resourcesComboBox->addItem(QString(it->c_str()));
51   resourcesLayout->addWidget(resourcesComboBox, 1, 1);
52   
53   _clusterBox = createClusterWidgets();
54   mainLayout->addWidget(_clusterBox);
55
56   resourcesComboBox->setCurrentIndex(
57                 resourcesComboBox->findText(model->getWantedMachine().c_str()));
58
59   connect(resourcesComboBox, SIGNAL(currentIndexChanged( const QString &)),
60           this, SLOT(updateWantedMachine( const QString &)));
61
62   _clusterBox->setVisible(!model->isMachineInteractive(
63                                                     model->getWantedMachine()));
64   mainLayout->addStretch();
65   setWidget(mainWidget);
66   setWidgetResizable (true);
67 }
68
69 ResourceWidget::~ResourceWidget()
70 {
71 }
72
73 QWidget * ResourceWidget::createClusterWidgets()
74 {
75   // Infos for clusters
76   QGroupBox *clusterBox = new QGroupBox();
77   QGridLayout *groupLayout = new QGridLayout;
78   clusterBox->setLayout(groupLayout);
79   clusterBox->setTitle(tr("Specific parameters for clusters"));
80   QHBoxLayout *hLayout;
81   int pos = 0;
82
83   QLabel *nbprocLabel = new QLabel();
84   QSpinBox *nbprocEdit = new QSpinBox();
85   nbprocLabel->setText(tr("Number of processes"));
86   nbprocEdit->setRange(1, 10000);
87   groupLayout->addWidget(nbprocLabel, pos, 0);
88   groupLayout->addWidget(nbprocEdit, pos++, 1);
89   connect(nbprocEdit, SIGNAL(valueChanged(int)), this, SLOT(updateNbprocs(int)));
90   nbprocEdit->setValue(_model->getNbprocs());
91
92   QLabel *remotedirLabel = new QLabel();
93   _remotedirEdit = new QLineEdit();
94   remotedirLabel->setText(tr("Remote working directory"));
95   groupLayout->addWidget(remotedirLabel, pos, 0);
96   groupLayout->addWidget(_remotedirEdit, pos++, 1);
97   connect(_remotedirEdit, SIGNAL(textEdited(const QString &)),
98           this, SLOT(updateRemoteDir(const QString &)));
99   _remotedirEdit->setText(_model->getRemoteDir().c_str());
100
101   QLabel *localdirLabel = new QLabel();
102   _localdirEdit = new QLineEdit();
103   QPushButton* localdirButton = new QPushButton("...");
104   
105   localdirLabel->setText(tr("Local result directory"));
106   groupLayout->addWidget(localdirLabel, pos, 0);
107   groupLayout->addWidget(_localdirEdit, pos, 1);
108   groupLayout->addWidget(localdirButton, pos++, 2);
109   connect(_localdirEdit, SIGNAL(textEdited(const QString &)),
110           this, SLOT(updateLocalDir(const QString &)));
111   connect(localdirButton,SIGNAL(clicked()),this, SLOT(onChoseLocaldir()));
112   _localdirEdit->setText(_model->getLocalDir().c_str());
113   
114   QLabel *wckeyLabel = new QLabel();
115   QLineEdit *wckeyEdit = new QLineEdit();
116   wckeyLabel->setText(tr("Working Characterization Key"));
117   groupLayout->addWidget(wckeyLabel, pos, 0);
118   groupLayout->addWidget(wckeyEdit, pos++, 1);
119   connect(wckeyEdit, SIGNAL(textEdited(const QString &)),
120           this, SLOT(updateWckey(const QString &)));
121   wckeyEdit->setText(_model->getWckey().c_str());
122   
123   hLayout = new QHBoxLayout();
124   QLabel *timeLabel = new QLabel();
125   QLabel *hoursLabel = new QLabel();
126   QLabel *minutesLabel = new QLabel();
127   QSpinBox *hoursEdit = new QSpinBox();
128   QSpinBox *minutesEdit = new QSpinBox();
129   hoursEdit->setRange(0, 99);
130   minutesEdit->setRange(0,59);
131   timeLabel->setText(tr("Time limit (0:0 for default values):"));
132   hoursLabel->setText(tr("hours"));
133   minutesLabel->setText(tr("minutes"));
134   hLayout->addWidget(hoursEdit);
135   hLayout->addWidget(hoursLabel);
136   hLayout->addWidget(minutesEdit);
137   hLayout->addWidget(minutesLabel);
138   groupLayout->addWidget(timeLabel, pos, 0);
139   groupLayout->addLayout(hLayout, pos++, 1);
140   
141   hoursEdit->setValue(_model->getMaxDurationHours());
142   minutesEdit->setValue(_model->getMaxDurationMinutes());
143   connect(hoursEdit, SIGNAL(valueChanged(int)),
144           this, SLOT(updateMaxHours(int)));
145   connect(minutesEdit, SIGNAL(valueChanged(int)),
146           this, SLOT(updateMaxMinutes(int)));
147   
148   QGroupBox * inputFilesBox = new QGroupBox;
149   inputFilesBox->setTitle(tr("Input files"));
150   QHBoxLayout *inputFilesLayout = new QHBoxLayout;
151   inputFilesBox->setLayout(inputFilesLayout);
152   _inputFilesList = new QListWidget;
153   _inputFilesList->setSelectionMode(QAbstractItemView::MultiSelection);
154   std::list<std::string>::const_iterator it;
155   for(it=_model->getInFiles().begin(); it!= _model->getInFiles().end(); it++)
156   {
157     _inputFilesList->addItem(it->c_str());
158   }
159   QVBoxLayout *inputButtonsLayout = new QVBoxLayout;
160   QPushButton *addInputFilesButton = new QPushButton(tr("+"));
161   _removeInputFilesButton = new QPushButton(tr("-"));
162   inputButtonsLayout->addWidget(addInputFilesButton);
163   inputButtonsLayout->addWidget(_removeInputFilesButton);
164   inputFilesLayout->addWidget(_inputFilesList);
165   inputFilesLayout->addLayout(inputButtonsLayout);
166   groupLayout->addWidget(inputFilesBox, pos++, 0, 1, -1);
167   _removeInputFilesButton->setEnabled(false);
168   connect(_inputFilesList, SIGNAL(itemSelectionChanged()),
169           this, SLOT(inputSelectionChanged()));
170   connect(addInputFilesButton, SIGNAL(clicked()),
171           this, SLOT(addInputFiles()));
172   connect(_removeInputFilesButton, SIGNAL(clicked()),
173           this, SLOT(removeInputFiles()));
174   return clusterBox;
175 }
176
177 void ResourceWidget::updateParallelizeStatus(bool v)
178 {
179   _model->setParallelizeStatus(v);
180 }
181
182 void ResourceWidget::updateWantedMachine( const QString& v)
183 {
184   _model->setWantedMachine(v.toStdString());
185   bool isRemote = !_model->isMachineInteractive(v.toStdString());
186   _clusterBox->setVisible(isRemote);
187   if(isRemote)
188   {
189     std::string defaultValue = _model->getDefaultRemoteDir(v.toStdString());
190     _remotedirEdit->setText(defaultValue.c_str());
191     _model->setRemoteDir(defaultValue);
192   }
193 }
194
195 void ResourceWidget::updateNbprocs(int v)
196 {
197   _model->setNbprocs(v);
198 }
199
200 void ResourceWidget::updateRemoteDir(const QString &v)
201 {
202   _model->setRemoteDir(v.toStdString());
203 }
204
205 void ResourceWidget::updateLocalDir(const QString &v)
206 {
207   _model->setLocalDir(v.toStdString());
208 }
209
210 void ResourceWidget::updateWckey(const QString &v)
211 {
212   _model->setWckey(v.toStdString());
213 }
214
215 void ResourceWidget::updateMaxHours(int v)
216 {
217   _model->setMaxDurationHours(v);
218 }
219
220 void ResourceWidget::updateMaxMinutes(int v)
221 {
222   _model->setMaxDurationMinutes(v);
223 }
224
225 void ResourceWidget::onChoseLocaldir()
226 {
227   QString dir;
228   dir = QFileDialog::getExistingDirectory(this,
229                                           tr("Choose local result directory"),
230                                           "",
231                                           QFileDialog::ShowDirsOnly
232                                           | QFileDialog::DontResolveSymlinks);
233
234   if (dir != "")
235   {
236     _model->setLocalDir(dir.toStdString());
237     _localdirEdit->setText(dir);
238   }
239 }
240
241 void ResourceWidget::inputSelectionChanged()
242 {
243   bool canRemove = (_inputFilesList->selectedItems().size() > 0);
244   _removeInputFilesButton->setEnabled(canRemove);
245 }
246
247 void ResourceWidget::addInputFiles()
248 {
249   // We need to be able to select both files and folders.
250   // Standard QFileDialog cannot do it.
251   QFileDialog w(this, tr("Select input files"),
252               "", tr("All files and folders(*)")) ;
253   w.setOption(QFileDialog::DontUseNativeDialog,true);
254   QListView *l = w.findChild<QListView*>("listView");
255   if (l)
256   {
257     l->setSelectionMode(QAbstractItemView::MultiSelection);
258   }
259   QTreeView *t = w.findChild<QTreeView*>();
260   if (t)
261   {
262     t->setSelectionMode(QAbstractItemView::MultiSelection);
263   }
264   if(w.exec())
265   {
266     QStringList fileNames = w.selectedFiles();
267     for (int i = 0; i < fileNames.size(); ++i) 
268     {
269       QString fileName = fileNames.at(i);
270       if (_inputFilesList->findItems(fileName,Qt::MatchFixedString).size() == 0)
271       {
272         _model->getInFiles().push_back(fileName.toStdString());
273         _inputFilesList->addItem(fileName);
274       }
275     }
276   }
277 }
278
279 void ResourceWidget::removeInputFiles()
280 {
281   QList<QListWidgetItem *> list = _inputFilesList->selectedItems();
282   for (int i = 0; i < list.size(); ++i)
283   {
284     int row = _inputFilesList->row( list.at(i) );
285     QListWidgetItem * item = _inputFilesList->takeItem(row);
286     std::string itemName = item->text().toStdString();
287     _model->getInFiles().remove(itemName);
288     delete item;
289   }
290 }