1 // Copyright (C) 2016 CEA/DEN, EDF R&D
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
19 // Author : Anthony Geay (EDF R&D)
21 #include "YDFXGUIPyThreadSaver.hxx"
22 #include "YDFXGUIPushButtons.hxx"
24 #include "YDFXGUIWrap.hxx"
25 #include "YDFXGUISeqInit.hxx"
26 #include "YDFXGUIHostParametrizer.hxx"
28 #include "YACSEvalSession.hxx"
29 #include "YACSEvalObserver.hxx"
30 #include "YACSEvalResource.hxx"
31 #include "YACSEvalExecParams.hxx"
33 #include "Exception.hxx"
36 #include <QVBoxLayout>
37 #include <QApplication>
38 #include <QStackedLayout>
39 #include <QDialogButtonBox>
43 YDFXGUIPushButton1::YDFXGUIPushButton1(QWidget *parent, YACSEvalYFXWrap *efx, YDFXGUIAllPorts *ports):QPushButton(parent),_efx(efx),_ports(ports)
50 YDFXGUIResourcePushButton::YDFXGUIResourcePushButton(QWidget *parent, YACSEvalYFXWrap *efx, YDFXGUIAllPorts *ports):YDFXGUIPushButton1(parent,efx,ports)
52 setText("Assign Resources");
53 connect(this,SIGNAL(clicked(bool)),this,SLOT(resourceAssignmentRequested()));
54 connect(efx,SIGNAL(runSignal(bool)),this,SLOT(setHidden(bool)));
57 void YDFXGUIResourcePushButton::resourceAssignmentRequested()
60 QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
61 sizePolicy.setHorizontalStretch(0);
62 sizePolicy.setVerticalStretch(0);
63 sizePolicy.setHeightForWidth(dial.sizePolicy().hasHeightForWidth());
64 dial.setSizePolicy(sizePolicy);
65 QVBoxLayout *vbox(new QVBoxLayout(&dial));
66 YDFXGUIHostParametrizer *param(new YDFXGUIHostParametrizer(&dial,_efx));
67 QObject::connect(param->getDialogButtonBox(),SIGNAL(accepted()),&dial,SLOT(accept()));
68 QObject::connect(param->getDialogButtonBox(),SIGNAL(rejected()),&dial,SLOT(reject()));
69 vbox->addWidget(param);
70 param->loadFromSettings(_settings);
74 param->learnSettings(_settings);
80 YDFXGUISeqInitButton::YDFXGUISeqInitButton(QWidget *parent, YACSEvalYFXWrap *efx, YDFXGUIAllPorts *ports):YDFXGUIPushButton1(parent,efx,ports)
82 setText("Init sequences");
83 connect(this,SIGNAL(clicked(bool)),this,SLOT(sequenceInitRequested()));
84 connect(efx,SIGNAL(runSignal(bool)),this,SLOT(setHidden(bool)));
87 void YDFXGUISeqInitButton::sequenceInitRequested()
90 YDFXGUISeqInit *zeWidget(new YDFXGUISeqInit(&dial,_efx));
91 zeWidget->loadState(_state);
92 QVBoxLayout *mainLayout(new QVBoxLayout(&dial));
93 mainLayout->addWidget(zeWidget);
94 QObject::connect(zeWidget,SIGNAL(assignButtonClicked()),&dial,SLOT(accept()));
97 _state=zeWidget->saveState();
98 Q_EMIT sequenceWellDefined(true);
104 YDFXGUIRunInfo::YDFXGUIRunInfo(QObject *parent, int nbOfItems):QObject(parent),_computationInProgress(false),_items(nbOfItems,0)
108 void YDFXGUIRunInfo::startComputation()
111 std::fill(_items.begin(),_items.end(),0);
112 _computationInProgress=true;
114 Q_EMIT somethingChanged();
117 void YDFXGUIRunInfo::endComputation()
120 _computationInProgress=false;
122 Q_EMIT somethingChanged();
125 void YDFXGUIRunInfo::sampleOK(int pos)
130 Q_EMIT somethingChanged();
133 void YDFXGUIRunInfo::sampleKO(int pos)
138 Q_EMIT somethingChanged();
141 std::vector<char> YDFXGUIRunInfo::getItems() const
143 std::vector<char> ret;
150 int YDFXGUIRunInfo::getNbOfItems() const
153 int ret(_items.size());
158 void YDFXGUIRunInfo::setNbOfItems(int nbOfItems)
160 _items.resize(nbOfItems);
161 std::fill(_items.begin(),_items.end(),0);
164 bool YDFXGUIRunInfo::getComputationStatus() const
167 bool ret(_computationInProgress);
174 class MyObserver : public YACSEvalObserver
177 MyObserver(YDFXGUIRunInfo *info):_info(info) { }
178 void startComputation(YACSEvalYFX *sender)
180 //std::cerr << " Start ! " << _info->getNbOfItems() << std::endl;
182 void notifySampleOK(YACSEvalYFX *sender, int sampleId)
184 _info->sampleOK(sampleId);
185 //std::cerr << "sample OK = " << sampleId << std::endl;
187 void notifySampleKO(YACSEvalYFX *sender, int sampleId)
189 _info->sampleKO(sampleId);
190 //std::cerr << "sample KO = " << sampleId << std::endl;
193 YDFXGUIRunInfo *_info;
198 YDFXGUIRunThread::YDFXGUIRunThread(QObject *parent, YACSEvalYFXWrap *efx, YACSEvalSession *session, YDFXGUIRunInfo *info):QThread(parent),_efx(efx),_session(session),_info(info),_ret0(false),_ret1(-1)
200 _session->setForcedPyThreadSavedStatus(true);
203 void YDFXGUIRunThread::run()
205 YDFXGUIPyThreadSaver::SaveContext(this);
206 _efx->getParams()->setStopASAPAfterErrorStatus(false);
207 MyObserver *obs(new MyObserver(_info));
208 _efx->registerObserver(obs);
210 _ret0=_efx->run(_session,_ret1);
213 YDFXGUIRunThread::~YDFXGUIRunThread()
217 bool YDFXGUIRunThread::getReturns(int& ret1) const
225 YDFXGUIRunningButton::YDFXGUIRunningButton(QWidget *parent):QPushButton(parent)
229 YACSEvalYFXWrap *efx(getEFX());
230 setEnabled(ComputeStateRes(efx,dummy) && ComputeStateSeq(efx));
231 connect(this,SIGNAL(clicked()),this,SLOT(runWizardSlot()));
234 YACSEvalYFXWrap *YDFXGUIRunningButton::getEFX()
236 YDFXGUIRunButton *parentc(qobject_cast<YDFXGUIRunButton *>(parent()));
239 return parentc->getEFX();
242 YDFXGUIRunInfo *YDFXGUIRunningButton::getInfo()
244 YDFXGUIRunButton *parentc(qobject_cast<YDFXGUIRunButton *>(parent()));
247 return parentc->getInfo();
250 YACSEvalSession *YDFXGUIRunningButton::getSess()
252 YDFXGUIRunButton *parentc(qobject_cast<YDFXGUIRunButton *>(parent()));
255 return parentc->getSess();
258 YDFXGUIRunThread *YDFXGUIRunningButton::getThread()
260 YDFXGUIRunButton *parentc(qobject_cast<YDFXGUIRunButton *>(parent()));
263 return parentc->getThread();
268 YDFXGUIMachineDialog::YDFXGUIMachineDialog(QWidget *parent):QDialog(parent)
272 void YDFXGUIMachineDialog::interactivityStatusChanged(bool)
274 QSize sz1(_wid->minimumSizeHint()),sz2(_wid->sizeHint());
275 QMargins marg(layout()->contentsMargins());
276 int delta(marg.top()+marg.bottom());
277 setMinimumHeight(sz1.height()+delta);
278 setMaximumHeight(sz2.height()+delta);
283 void YDFXGUIRunningButton::runWizardSlot()
285 YDFXGUIMachineDialog dial(this);
286 QGridLayout *mainLayout(new QGridLayout(&dial));
287 YDFXGUIHostParametrizer *zeWidget(new YDFXGUIHostParametrizer(&dial,getEFX()));
288 dial.setWidget(zeWidget);
289 dial.interactivityStatusChanged(true);
290 connect(zeWidget,SIGNAL(interactivityChanged(bool)),&dial,SLOT(interactivityStatusChanged(bool)));
291 mainLayout->addWidget(zeWidget);
292 connect(zeWidget->getDialogButtonBox(),SIGNAL(accepted()),&dial,SLOT(accept()));
293 connect(zeWidget->getDialogButtonBox(),SIGNAL(rejected()),&dial,SLOT(reject()));
296 getEFX()->lockPortsForEvaluation();
297 zeWidget->applyToEFX();
298 getInfo()->setNbOfItems(getEFX()->getNbOfItems());
303 void YDFXGUIRunningButton::runEvaluation()
305 if(!getSess()->isLaunched())
307 if(!PyEval_ThreadsInitialized())
308 PyEval_InitThreads();
309 connect(getThread(),SIGNAL(finished()),this,SLOT(evaluationFinished()));
311 getThread()->start();
314 void YDFXGUIRunningButton::evaluationFinished()
316 YACSEvalYFXWrap *efx(getEFX());
318 setEnabled(ComputeStateRes(efx,dummy) && ComputeStateSeq(efx));
321 bool YDFXGUIRunningButton::ComputeStateRes(YACSEvalYFXWrap *efx, int& nbOfSamples)
323 return efx->computeSequencesStatus(nbOfSamples);
326 bool YDFXGUIRunningButton::ComputeStateSeq(YACSEvalYFXWrap *efx)
328 bool isOKForDef(true);
331 efx->giveResources()->checkOKForRun();
333 catch(YACS::Exception& e)
340 /////////////////////
342 YDFXGUIRunningPB::YDFXGUIRunningPB(QWidget *parent, YDFXGUIRunInfo *info):QWidget(parent),_info(info)
346 void YDFXGUIRunningPB::paintEvent(QPaintEvent *event)
348 const int SZ_OF_PEN_RECT=2;
349 QPainter painter(this);
350 QRect refRect(rect());
351 QRect refRect2(refRect);//event->rect());
352 painter.setPen(QPen(Qt::black,SZ_OF_PEN_RECT,Qt::SolidLine));//,Qt::RoundCap));
353 refRect2.translate(SZ_OF_PEN_RECT,SZ_OF_PEN_RECT);
354 refRect2.setWidth(refRect2.width()-2*SZ_OF_PEN_RECT);;
355 refRect2.setHeight(refRect2.height()-2*SZ_OF_PEN_RECT);
356 painter.drawRect(refRect2);
358 std::vector<char> items(_info->getItems());
359 int nbOfItems(items.size());
361 float xFact(float(refRect.width()-3.5*SZ_OF_PEN_RECT)/float(nbOfItems));
363 QPalette pal(QApplication::palette("QPushButton"));
364 QColor color(pal.color(QPalette::Window)),color2;
365 painter.setPen(QPen(color,0));
366 for(int ii=0;ii<nbOfItems;)
368 for(;ii<nbOfItems && items[ii]==0;ii++);
371 int ref(items[ii]),start(ii);
372 for(;ii<nbOfItems && items[ii]==ref;ii++);
378 QBrush brush(color2);
379 painter.setBrush(brush);
380 painter.setPen(QPen(color2,0));
381 float xs(float(start)*xFact+1.5f*SZ_OF_PEN_RECT);
382 float xe(float(endd)*xFact+1.5f*SZ_OF_PEN_RECT);
383 painter.drawRect(QRectF(xs,1.5f*SZ_OF_PEN_RECT,xe-xs,refRect.height()-3.5f*SZ_OF_PEN_RECT));
385 int nbOfEltsDone(nbOfItems-std::count(items.begin(),items.end(),0));
386 QString txt(QString("%1/%2 (%3%)").arg(nbOfEltsDone).arg(nbOfItems).arg(float(nbOfEltsDone)/float(nbOfItems)*100.f,0,'f',0));
390 QSize refRect3(fm.boundingRect(txt).size());
392 painter.setPen(QPen(Qt::black));
393 painter.drawText(QPoint((refRect.width()-refRect3.width())/2,refRect.height()/2+refRect3.height()/2-fm.descent()),txt);
396 QSize YDFXGUIRunningPB::sizeHint() const
398 int width(3*_info->getNbOfItems());
399 width=std::max(width,50);
400 width=std::min(width,150);
401 return QSize(width,15);
404 QSize YDFXGUIRunningPB::minimumSizeHint() const
406 int width(3*_info->getNbOfItems());
407 width=std::max(width,50);
408 width=std::min(width,120);
414 YDFXGUIRunButton::YDFXGUIRunButton(QWidget *parent, YACSEvalSession *session, YACSEvalYFXWrap *efx):QWidget(parent),_info(new YDFXGUIRunInfo(this,0)),_th(new YDFXGUIRunThread(this,efx,session,_info)),_push(new YDFXGUIRunningButton(this)),_pb(new YDFXGUIRunningPB(this,_info))
416 QVBoxLayout *mainLayout(new QVBoxLayout(this));
417 mainLayout->addWidget(_pb);
418 mainLayout->addWidget(_push);
420 _push->setEnabled(false);
422 connect(getThread(),SIGNAL(started()),_info,SLOT(startComputation()));
423 connect(getThread(),SIGNAL(finished()),_info,SLOT(endComputation()));
425 connect(_info,SIGNAL(somethingChanged()),this,SLOT(update()));
426 connect(_info,SIGNAL(somethingChanged()),_pb,SLOT(update()));
429 QSize YDFXGUIRunButton::sizeHint() const
431 QSize sz,sz2(QWidget::sizeHint());
432 if(_info->getComputationStatus())
435 sz=_push->sizeHint();
436 sz.rwidth()+=sz2.rwidth();
437 sz.rheight()+=sz2.rheight();
441 QSize YDFXGUIRunButton::minimumSizeHint() const
443 QSize sz,sz2(QWidget::minimumSizeHint());
444 if(_info->getComputationStatus())
445 sz=_pb->minimumSizeHint();
447 sz=_push->minimumSizeHint();
448 sz.rwidth()+=sz2.rwidth();
449 sz.rheight()+=sz2.rheight();
453 void YDFXGUIRunButton::update()
455 bool stat(_info->getComputationStatus());
456 _pb->setVisible(stat);
457 _push->setHidden(stat);
461 void YDFXGUIRunButton::setEnabled(bool status)
463 _push->setEnabled(status);
464 QWidget::setEnabled(status);
467 void YDFXGUIRunButton::setDisabled(bool status)
469 _push->setDisabled(status);
470 QWidget::setEnabled(status);