From d09d23ab61397979c9c39fcd93829ea078fe1d80 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Wed, 3 Aug 2016 14:18:48 +0200 Subject: [PATCH] GUI of YDFX is in for uncertainties and parametric users. --- CMakeLists.txt | 4 +- SalomeYACSConfig.cmake.in | 2 + src/CMakeLists.txt | 2 +- src/ydfx_gui/CMakeLists.txt | 112 +++ src/ydfx_gui/YDFXGUIHostParametrizer.cxx | 404 ++++++++++ src/ydfx_gui/YDFXGUIHostParametrizer.hxx | 105 +++ src/ydfx_gui/YDFXGUIMain.cxx | 109 +++ src/ydfx_gui/YDFXGUIMain.hxx | 83 ++ src/ydfx_gui/YDFXGUIParametrizer.cxx | 45 ++ src/ydfx_gui/YDFXGUIParametrizer.hxx | 42 + src/ydfx_gui/YDFXGUIPortsSelector.cxx | 980 +++++++++++++++++++++++ src/ydfx_gui/YDFXGUIPortsSelector.hxx | 327 ++++++++ src/ydfx_gui/YDFXGUIPortsValidator.cxx | 96 +++ src/ydfx_gui/YDFXGUIPortsValidator.hxx | 38 + src/ydfx_gui/YDFXGUIPushButtons.cxx | 471 +++++++++++ src/ydfx_gui/YDFXGUIPushButtons.hxx | 177 ++++ src/ydfx_gui/YDFXGUIPyThreadSaver.cxx | 40 + src/ydfx_gui/YDFXGUIPyThreadSaver.hxx | 40 + src/ydfx_gui/YDFXGUISeqInit.cxx | 628 +++++++++++++++ src/ydfx_gui/YDFXGUISeqInit.hxx | 187 +++++ src/ydfx_gui/YDFXGUIWrap.cxx | 175 ++++ src/ydfx_gui/YDFXGUIWrap.hxx | 69 ++ src/ydfx_gui/ydfxgui.cxx | 36 + src/ydfx_gui/ydfxwidgetsExport.hxx | 38 + 24 files changed, 4207 insertions(+), 3 deletions(-) create mode 100644 src/ydfx_gui/CMakeLists.txt create mode 100644 src/ydfx_gui/YDFXGUIHostParametrizer.cxx create mode 100644 src/ydfx_gui/YDFXGUIHostParametrizer.hxx create mode 100644 src/ydfx_gui/YDFXGUIMain.cxx create mode 100644 src/ydfx_gui/YDFXGUIMain.hxx create mode 100644 src/ydfx_gui/YDFXGUIParametrizer.cxx create mode 100644 src/ydfx_gui/YDFXGUIParametrizer.hxx create mode 100644 src/ydfx_gui/YDFXGUIPortsSelector.cxx create mode 100644 src/ydfx_gui/YDFXGUIPortsSelector.hxx create mode 100644 src/ydfx_gui/YDFXGUIPortsValidator.cxx create mode 100644 src/ydfx_gui/YDFXGUIPortsValidator.hxx create mode 100644 src/ydfx_gui/YDFXGUIPushButtons.cxx create mode 100644 src/ydfx_gui/YDFXGUIPushButtons.hxx create mode 100644 src/ydfx_gui/YDFXGUIPyThreadSaver.cxx create mode 100644 src/ydfx_gui/YDFXGUIPyThreadSaver.hxx create mode 100644 src/ydfx_gui/YDFXGUISeqInit.cxx create mode 100644 src/ydfx_gui/YDFXGUISeqInit.hxx create mode 100644 src/ydfx_gui/YDFXGUIWrap.cxx create mode 100644 src/ydfx_gui/YDFXGUIWrap.hxx create mode 100644 src/ydfx_gui/ydfxgui.cxx create mode 100644 src/ydfx_gui/ydfxwidgetsExport.hxx diff --git a/CMakeLists.txt b/CMakeLists.txt index d71452e91..5286d7130 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -286,7 +286,7 @@ SET(_${PROJECT_NAME}_exposed_targets IF(SALOME_YACS_USE_KERNEL) LIST(APPEND _${PROJECT_NAME}_exposed_targets - SalomeIDLYACS YACSRuntimeSALOME YACSloader + SalomeIDLYACS YACSRuntimeSALOME YACSloader YACSevalYFX ) ENDIF(SALOME_YACS_USE_KERNEL) @@ -303,7 +303,7 @@ ENDIF(SALOME_BUILD_TESTS) IF(SALOME_BUILD_GUI) LIST(APPEND _${PROJECT_NAME}_exposed_targets - HMI GenericGui YACS SalomeWrap + HMI ydfxwidgets GenericGui YACS SalomeWrap ) ENDIF(SALOME_BUILD_GUI) diff --git a/SalomeYACSConfig.cmake.in b/SalomeYACSConfig.cmake.in index f56227697..b615d5e24 100644 --- a/SalomeYACSConfig.cmake.in +++ b/SalomeYACSConfig.cmake.in @@ -149,6 +149,7 @@ SET(YACS_YACSloader YACSloader) SET(YACS_YACSBases YACSBases) SET(YACS_YACSlibEngine YACSlibEngine) SET(YACS_YACSRuntimeSALOME YACSRuntimeSALOME) +SET(YACS_YACSevalYFX YACSevalYFX) SET(YACS_YACSDLTest YACSDLTest) SET(YACS_SalomeIDLYACS SalomeIDLYACS) #TODO: @@ -156,6 +157,7 @@ SET(YACS_SalomeIDLYACS SalomeIDLYACS) #SET(YACS_PluginSimplex PluginSimplex) #SET(YACS_PluginOptEvTest1 PluginOptEvTest1) SET(YACS_HMI HMI) +SET(YACS_ydfxwidgets ydfxwidgets) SET(YACS_GenericGui GenericGui) SET(YACS_YACS YACS) SET(YACS_SalomeWrap SalomeWrap) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7db379670..064805212 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -46,7 +46,7 @@ ENDIF(SALOME_YACS_USE_SWIG) # GUI ## IF(SALOME_BUILD_GUI) - SET(SUBDIRS_GUI pyqt hmi salomewrap genericgui salomegui) + SET(SUBDIRS_GUI ydfx_gui pyqt hmi salomewrap genericgui salomegui) IF(SALOME_YACS_USE_SWIG) LIST(APPEND SUBDIRS_GUI salomegui_swig) ENDIF() diff --git a/src/ydfx_gui/CMakeLists.txt b/src/ydfx_gui/CMakeLists.txt new file mode 100644 index 000000000..f8378fb22 --- /dev/null +++ b/src/ydfx_gui/CMakeLists.txt @@ -0,0 +1,112 @@ +# Copyright (C) 2012-2016 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +INCLUDE(UseQtExt) + +# additional include directories +INCLUDE_DIRECTORIES( + ${PYTHON_INCLUDE_DIR} + ${QT_INCLUDES} + ${KERNEL_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/src/bases + ${PROJECT_SOURCE_DIR}/src/engine + ${PROJECT_SOURCE_DIR}/src/runtime + ${PROJECT_SOURCE_DIR}/src/yacsloader + ${PROJECT_SOURCE_DIR}/src/evalyfx + ) + +# additional preprocessor / compiler flags +ADD_DEFINITIONS( + ${QT_DEFINITIONS} + ${PYTHON_DEFINITIONS}) + +IF(SALOME_YACS_USE_KERNEL) + INCLUDE_DIRECTORIES(${KERNEL_INCLUDE_DIRS}) + ADD_DEFINITIONS(${KERNEL_DEFINITIONS}) + SET(SALOME_LIBS + ${KERNEL_SalomeLifeCycleCORBA} + ${KERNEL_SalomeIDLKernel} + ${KERNEL_SalomeNS} + ${KERNEL_SalomeContainer} + ${KERNEL_SALOMEBasics} + ${KERNEL_SalomeResourcesManager} + ${KERNEL_OpUtil} + ${KERNEL_SALOMELocalTrace} + ${KERNEL_Registry} + ${KERNEL_SalomeNotification} + ${KERNEL_ResourcesManager} + ${KERNEL_SalomeHDFPersist} + ${KERNEL_SalomeGenericObj} + ) +ENDIF(SALOME_YACS_USE_KERNEL) + + +SET(ydfxwidgets_LIBRARIES + YACSevalYFX + ${QT_LIBRARIES} + ${PYTHON_LIBRARIES} + ) + +SET(_moc_HEADERS + YDFXGUIPortsSelector.hxx + YDFXGUIPushButtons.hxx + YDFXGUIMain.hxx + YDFXGUIWrap.hxx + YDFXGUISeqInit.hxx + YDFXGUIParametrizer.hxx + YDFXGUIHostParametrizer.hxx + ) + +# sources / moc wrappings +QT_WRAP_MOC(_moc_SOURCES ${_moc_HEADERS}) + +SET(ydfxwidgets_HEADERS + ydfxwidgetsExport.hxx + YDFXGUIHostParametrizer.hxx + YDFXGUIMain.hxx + YDFXGUIParametrizer.hxx + YDFXGUIPortsSelector.hxx + YDFXGUIPortsValidator.hxx + YDFXGUIPushButtons.hxx + YDFXGUIPyThreadSaver.hxx + YDFXGUISeqInit.hxx + YDFXGUIWrap.hxx + ) + +SET(ydfxwidgets_SOURCES + YDFXGUIHostParametrizer.cxx + YDFXGUIMain.cxx + YDFXGUIParametrizer.cxx + YDFXGUIPortsSelector.cxx + YDFXGUIPortsValidator.cxx + YDFXGUIPushButtons.cxx + YDFXGUIPyThreadSaver.cxx + YDFXGUISeqInit.cxx + YDFXGUIWrap.cxx + ${_moc_SOURCES} + ) + +ADD_LIBRARY(ydfxwidgets ${ydfxwidgets_SOURCES}) +TARGET_LINK_LIBRARIES(ydfxwidgets ${ydfxwidgets_LIBRARIES}) +ADD_EXECUTABLE(ydfxgui ydfxgui.cxx) +TARGET_LINK_LIBRARIES(ydfxgui ydfxwidgets) + +INSTALL(TARGETS ydfxwidgets EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) +INSTALL(TARGETS ydfxgui DESTINATION ${SALOME_INSTALL_BINS}) +INSTALL(FILES ${ydfxwidgets_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) diff --git a/src/ydfx_gui/YDFXGUIHostParametrizer.cxx b/src/ydfx_gui/YDFXGUIHostParametrizer.cxx new file mode 100644 index 000000000..e83c6d946 --- /dev/null +++ b/src/ydfx_gui/YDFXGUIHostParametrizer.cxx @@ -0,0 +1,404 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#include "YDFXGUIHostParametrizer.hxx" + +#include "YDFXGUIWrap.hxx" + +#include "YACSEvalResource.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +const char YDFXGUIHostParametrizer::MACHINE[]="machine/machine"; + +const char YDFXGUIBatchInfo::NBPROCS[]="machine/nbprocs"; + +const char YDFXGUIBatchInfo::REMOTEDIR[]="machine/remotedir"; + +const char YDFXGUIBatchInfo::LOCALDIR[]="machine/localdir"; + +const char YDFXGUIBatchInfo::WCKEY[]="machine/wckey"; + +const char YDFXGUIBatchInfo::MAXDUR[]="machine/maxdur"; + +YDFXGUIHostParametrizer::YDFXGUIHostParametrizer(QWidget *parent, YACSEvalYFXWrap *efx):QWidget(parent),_hostSelector(0),_clusterAdvInfo(0),_buttonBox(0),_efx(efx),_wasInteractive(true) +{ + _efx->lockPortsForEvaluation(); + YACSEvalListOfResources *res(_efx->giveResources()); + std::vector machines(res->getAllFittingMachines()); + ///////////// + QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Maximum); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(sizePolicy().hasHeightForWidth()); + QVBoxLayout *verticalLayout_3(new QVBoxLayout(this)); + QHBoxLayout *horizontalLayout_2(new QHBoxLayout); + QLabel *label(new QLabel(this)); + QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Maximum); + sizePolicy2.setHorizontalStretch(0); + sizePolicy2.setVerticalStretch(0); + sizePolicy2.setHeightForWidth(label->sizePolicy().hasHeightForWidth()); + label->setText("Select machine"); + horizontalLayout_2->addWidget(label); + _hostSelector=new QComboBox(this); + int i(0); + foreach(std::string mach,machines) + _hostSelector->insertItem(i++,mach.c_str()); + connect(_hostSelector,SIGNAL(currentIndexChanged(const QString &)),this,SLOT(changeMachine(const QString &))); + sizePolicy2.setHeightForWidth(_hostSelector->sizePolicy().hasHeightForWidth()); + horizontalLayout_2->addWidget(_hostSelector); + verticalLayout_3->addLayout(horizontalLayout_2,1); + // + _clusterAdvInfo=new YDFXGUIBatchInfo(this,_efx); + verticalLayout_3->addWidget(_clusterAdvInfo,1); + connect(_clusterAdvInfo,SIGNAL(statusOfEntryChanged(bool)),this,SLOT(clusterAdvParamStatusChanged(bool))); + // + QHBoxLayout *horizontalLayout_3(new QHBoxLayout); + _buttonBox=new QDialogButtonBox(this); + _buttonBox->setOrientation(Qt::Horizontal); + _buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + horizontalLayout_3->addWidget(_buttonBox,0); + verticalLayout_3->addLayout(horizontalLayout_3,0); + // + _hostSelector->setCurrentIndex(0); + { + YACSEvalListOfResources *res(_efx->giveResources()); + _wasInteractive=res->isMachineInteractive(machines[0]); + } + this->changeMachine(QString(machines[0].c_str())); +} + +void YDFXGUIHostParametrizer::loadFromSettings(const QSettings& settings) +{ + if(!settings.contains(MACHINE)) + return ; + QVariant v(settings.value(MACHINE)); + QString vs(v.toString()); + if(vs.isEmpty()) + return ; + int id(_hostSelector->findText(vs)); + if(id==-1) + return ; + _hostSelector->setCurrentIndex(id); + YACSEvalListOfResources *res(_efx->giveResources()); + if(!res->isMachineInteractive(vs.toStdString())) + _clusterAdvInfo->loadFromSettings(settings); +} + +void YDFXGUIHostParametrizer::learnSettings(QSettings& settings) const +{ + settings.setValue(MACHINE,_hostSelector->currentText()); + YACSEvalListOfResources *res(_efx->giveResources()); + std::string selectedRes(_hostSelector->currentText().toStdString()); + if(!res->isMachineInteractive(selectedRes))//res->isInteractive() does not work here if efx has no Resource (no containers !) + _clusterAdvInfo->learnSettings(settings); +} + +void YDFXGUIHostParametrizer::applyToEFX() +{ + YACSEvalListOfResources *res(_efx->giveResources()); + std::string selectedRes(_hostSelector->currentText().toStdString()); + res->setWantedMachine(selectedRes); + if(!res->isMachineInteractive(selectedRes))//res->isInteractive() does not work here if efx has no Resource (no containers !) + { + YACSEvalParamsForCluster& ps(res->getAddParamsForCluster()); + _clusterAdvInfo->applyToParams(ps); + } + emit readyForRunSignal(true); +} + +QString YDFXGUIHostParametrizer::getNameOfHost() +{ + return _hostSelector->currentText(); +} + +void YDFXGUIHostParametrizer::changeMachine(const QString& newMachineSelected) +{ + YACSEvalListOfResources *res(_efx->giveResources()); + bool isInterac(res->isMachineInteractive(newMachineSelected.toStdString())); + _clusterAdvInfo->setVisible(!isInterac); + QPushButton *ok(_buttonBox->button(QDialogButtonBox::Ok)); + ok->setDisabled(!isInterac && !_clusterAdvInfo->isOK()); + if(_wasInteractive!=isInterac) + { + emit interactivityChanged(isInterac); + _wasInteractive=isInterac; + } +} + +void YDFXGUIHostParametrizer::clusterAdvParamStatusChanged(bool newStatus) +{ + QPushButton *ok(_buttonBox->button(QDialogButtonBox::Ok)); + ok->setDisabled(!newStatus); +} + +QValidator::State YDFXGUIDurationValidator::validate(QString &input, int &) const +{ + QString input2(input.simplified()); + input2.replace(' ',QString()); + QStringList sp(input2.split(QChar(':'))); + if(sp.size()>3) + return QValidator::Invalid; + QRegExp rx("\\d{1,2}"); + if(sp.size()==1) + { + if(input2.isEmpty()) + return QValidator::Intermediate; + if(!rx.exactMatch(input2)) + return QValidator::Invalid; + return QValidator::Intermediate; + } + if(sp.size()==2 && sp[1].isEmpty()) + { + if(sp[0].isEmpty()) + return QValidator::Invalid; + return QValidator::Intermediate; + } + if(sp.size()==2) + sp.insert(0,QString("00")); + if(sp[2].isEmpty()) + return QValidator::Intermediate; + int hms(0); + foreach(QString elt,sp) + { + if(!rx.exactMatch(elt)) + return QValidator::Invalid; + bool isOK(false); + uint val(elt.toUInt(&isOK)); + if(!isOK) + return QValidator::Invalid; + if(hms>1) + if(val>=60) + return QValidator::Invalid; + hms++; + } + return QValidator::Acceptable; +} + +YDFXGUIBatchInfo::YDFXGUIBatchInfo(QWidget *parent, YACSEvalYFXWrap *efx):QWidget(parent),_efx(efx),_nbProcs(0),_remoteDir(0),_localDir(0),_WCKey(0),_maxDuration(0),_wasOK(false) +{ + QVBoxLayout *verticalLayout(new QVBoxLayout(this)); + QGroupBox *gb(new QGroupBox(this)); + gb->setTitle("Specific info for cluster"); + verticalLayout->addWidget(gb); + QVBoxLayout *verticalLayout_1(new QVBoxLayout(gb)); + QFrame *frame(new QFrame(gb)); + verticalLayout_1->addWidget(frame); + frame->setFrameStyle(QFrame::Panel | QFrame::Sunken); + frame->setFrameShadow(QFrame::Raised); + QVBoxLayout *verticalLayout_2(new QVBoxLayout(frame)); + QSpacerItem *verticalSpacer(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding)); + verticalLayout_2->addItem(verticalSpacer); + QHBoxLayout *horizontalLayout_3(0); + // + horizontalLayout_3=new QHBoxLayout; + QLabel *label_5(new QLabel(frame)); + label_5->setText("Number of processes"); + horizontalLayout_3->addWidget(label_5); + _nbProcs=new QLineEdit(frame); + QValidator *nbProcVal(new QIntValidator(1,10000,_nbProcs)); + _nbProcs->setValidator(nbProcVal); + horizontalLayout_3->addWidget(_nbProcs); + verticalLayout_2->addLayout(horizontalLayout_3); + verticalSpacer=new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + verticalLayout_2->addItem(verticalSpacer); + connect(_nbProcs,SIGNAL(textChanged(const QString&)),this,SLOT(somethingChanged())); + // + horizontalLayout_3=new QHBoxLayout; + QLabel *label_2(new QLabel(frame)); + label_2->setText("Remote dir"); + horizontalLayout_3->addWidget(label_2); + _remoteDir=new QLineEdit(frame); + horizontalLayout_3->addWidget(_remoteDir); + verticalLayout_2->addLayout(horizontalLayout_3); + connect(_remoteDir,SIGNAL(textChanged(const QString&)),this,SLOT(somethingChanged())); + // + verticalSpacer=new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + verticalLayout_2->addItem(verticalSpacer); + // + horizontalLayout_3=new QHBoxLayout; + QLabel *label_3(new QLabel(frame)); + label_3->setText("Local dir"); + horizontalLayout_3->addWidget(label_3); + _localDir=new QLineEdit(frame); + horizontalLayout_3->addWidget(_localDir); + connect(_localDir,SIGNAL(textChanged(const QString&)),this,SLOT(somethingChanged())); + verticalLayout_2->addLayout(horizontalLayout_3); + verticalSpacer=new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + verticalLayout_2->addItem(verticalSpacer); + // + horizontalLayout_3=new QHBoxLayout; + QLabel *label_4(new QLabel(frame)); + label_4->setText("Working Caracterization Key"); + horizontalLayout_3->addWidget(label_4); + _WCKey=new QLineEdit(frame); + connect(_WCKey,SIGNAL(textChanged(const QString&)),this,SLOT(somethingChanged())); + horizontalLayout_3->addWidget(_WCKey); + verticalLayout_2->addLayout(horizontalLayout_3); + verticalSpacer=new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + verticalLayout_2->addItem(verticalSpacer); + // + horizontalLayout_3=new QHBoxLayout; + QLabel *label_6(new QLabel(frame)); + label_6->setText("Max duration"); + horizontalLayout_3->addWidget(label_6); + _maxDuration=new QLineEdit(frame); + QValidator *maxDurVal(new YDFXGUIDurationValidator(_maxDuration)); + _maxDuration->setText("05:00"); + _maxDuration->setValidator(maxDurVal); + connect(_maxDuration,SIGNAL(textChanged(const QString&)),this,SLOT(somethingChanged())); + horizontalLayout_3->addWidget(_maxDuration); + verticalLayout_2->addLayout(horizontalLayout_3); + verticalSpacer=new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + verticalLayout_2->addItem(verticalSpacer); +} + +void YDFXGUIBatchInfo::showEvent(QShowEvent *event) +{ + YDFXGUIHostParametrizer *parentc(qobject_cast(parent())); + if(parentc) + { + QPushButton *ok(parentc->getDialogButtonBox()->button(QDialogButtonBox::Ok)); + ok->setEnabled(isOK()); + } + QWidget::showEvent(event); +} + +bool YDFXGUIBatchInfo::isOK() const +{ + bool ret1(!_nbProcs->text().isEmpty() && !_remoteDir->text().isEmpty() && !_localDir->text().isEmpty() && !_WCKey->text().isEmpty()); + const QValidator *val(_maxDuration->validator()); + int dummy; + QString st(_maxDuration->text()); + QValidator::State sta(val->validate(st,dummy)); + return ret1 && sta==QValidator::Acceptable; +} + +void YDFXGUIBatchInfo::loadFromSettings(const QSettings& settings) +{ + static const int NB=5; + const char *tab1[NB]={NBPROCS,REMOTEDIR,LOCALDIR,WCKEY,MAXDUR}; + QLineEdit *tab2[NB]={_nbProcs,_remoteDir,_localDir,_WCKey,_maxDuration}; + QString tab3[NB]; + YACSEvalParamsForCluster* cp(0); + YACSEvalListOfResources *lr(_efx->giveResources()); + if(lr) + { + std::vector machines(lr->getAllChosenMachines()); + if(machines.size()==1) + { + if(machines[0]==getNameOfHost().toStdString()) + cp=&lr->getAddParamsForCluster(); + } + } + if(cp) + { + tab3[0]=QString("%1").arg(cp->getNbProcs()); + tab3[1]=cp->getRemoteWorkingDir().c_str(); + tab3[2]=cp->getLocalWorkingDir().c_str(); + tab3[3]=cp->getWCKey().c_str(); + tab3[4]=cp->getMaxDuration().c_str(); + } + for(int i=0;isetText(tab3[i]); + continue; + } + // + if(!settings.contains(entry)) + continue ; + QVariant v(settings.value(entry)); + QString vs(v.toString()); + if(vs.isEmpty()) + return ; + le->setText(vs); + } + bool newOK(isOK()); + _wasOK=newOK; + emit statusOfEntryChanged(newOK); +} + +void YDFXGUIBatchInfo::learnSettings(QSettings& settings) const +{ + settings.setValue(NBPROCS,_nbProcs->text()); + settings.setValue(REMOTEDIR,_remoteDir->text()); + settings.setValue(LOCALDIR,_localDir->text()); + settings.setValue(WCKEY,_WCKey->text()); + settings.setValue(MAXDUR,_maxDuration->text()); +} + +void YDFXGUIBatchInfo::applyToParams(YACSEvalParamsForCluster& ps) const +{ + QString nbProcs(_nbProcs->text()); + ps.setNbProcs(nbProcs.toUInt()); + ps.setRemoteWorkingDir(_remoteDir->text().toStdString()); + ps.setLocalWorkingDir(_localDir->text().toStdString()); + ps.setWCKey(_WCKey->text().toStdString()); + ps.setMaxDuration(NormalizeDuration(_maxDuration->text()).toStdString()); +} + +QString YDFXGUIBatchInfo::getNameOfHost() +{ + YDFXGUIHostParametrizer *parentc(qobject_cast(parent())); + if(parentc) + return parentc->getNameOfHost(); + else + return QString(); +} + +void YDFXGUIBatchInfo::somethingChanged() +{ + emit statusOfEntryChanged(isOK()); +} + +QString YDFXGUIBatchInfo::NormalizeDuration(const QString& txt) +{ + QString input2(txt.simplified()); + input2.replace(' ',QString()); + QStringList sp(txt.split(QChar(':'))); + QStringList ret; + foreach(QString elt,sp) + { + bool isOK(false); + uint val(elt.toUInt(&isOK)); + if(!isOK) + { + ret << "00"; + continue; + } + ret << QString("%1").arg(val,2,10,QChar('0')); + } + return ret.join(QChar(':')); +} + diff --git a/src/ydfx_gui/YDFXGUIHostParametrizer.hxx b/src/ydfx_gui/YDFXGUIHostParametrizer.hxx new file mode 100644 index 000000000..da290f023 --- /dev/null +++ b/src/ydfx_gui/YDFXGUIHostParametrizer.hxx @@ -0,0 +1,105 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#ifndef __YDFXGUIHOSTPARAMETRIZER_HXX__ +#define __YDFXGUIHOSTPARAMETRIZER_HXX__ + +#include "ydfxwidgetsExport.hxx" + +#include +#include + +class QComboBox; +class QLineEdit; +class QSettings; +class QDialogButtonBox; + +class YACSEvalYFXWrap; +class YDFXGUIBatchInfo; + +class YDFXGUIHostParametrizer : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIHostParametrizer(QWidget *parent, YACSEvalYFXWrap *efx); + YDFXWIDGETS_EXPORT QDialogButtonBox *getDialogButtonBox() { return _buttonBox; } + YDFXWIDGETS_EXPORT void loadFromSettings(const QSettings& settings); + YDFXWIDGETS_EXPORT void learnSettings(QSettings& settings) const; + YDFXWIDGETS_EXPORT void applyToEFX(); + YDFXWIDGETS_EXPORT QString getNameOfHost(); +public slots: + YDFXWIDGETS_EXPORT void changeMachine(const QString& newMachineSelected); + YDFXWIDGETS_EXPORT void clusterAdvParamStatusChanged(bool newStatus); +signals: + void readyForRunSignal(bool); + void interactivityChanged(bool); +public: + YDFXWIDGETS_EXPORT static const char MACHINE[]; +private: + QComboBox *_hostSelector; + YDFXGUIBatchInfo *_clusterAdvInfo; + QDialogButtonBox *_buttonBox; + YACSEvalYFXWrap *_efx; + bool _wasInteractive; +}; + +class YDFXGUIDurationValidator : public QValidator +{ +public: + YDFXWIDGETS_EXPORT YDFXGUIDurationValidator(QObject *parent):QValidator(parent) { } + YDFXWIDGETS_EXPORT QValidator::State validate(QString & input, int & pos) const; +}; + +class YACSEvalParamsForCluster; + +class YDFXGUIBatchInfo : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIBatchInfo(QWidget *parent, YACSEvalYFXWrap *efx); + YDFXWIDGETS_EXPORT void showEvent(QShowEvent *event); + YDFXWIDGETS_EXPORT bool isOK() const; + YDFXWIDGETS_EXPORT void loadFromSettings(const QSettings& settings); + YDFXWIDGETS_EXPORT void learnSettings(QSettings& settings) const; + YDFXWIDGETS_EXPORT void applyToParams(YACSEvalParamsForCluster& ps) const; + YDFXWIDGETS_EXPORT QString getNameOfHost(); +public slots: + YDFXWIDGETS_EXPORT void somethingChanged(); +public: + YDFXWIDGETS_EXPORT static const char NBPROCS[]; + YDFXWIDGETS_EXPORT static const char REMOTEDIR[]; + YDFXWIDGETS_EXPORT static const char LOCALDIR[]; + YDFXWIDGETS_EXPORT static const char WCKEY[]; + YDFXWIDGETS_EXPORT static const char MAXDUR[]; +signals: + void statusOfEntryChanged(bool newStatus); +private: + static QString NormalizeDuration(const QString& txt); +private: + YACSEvalYFXWrap *_efx; + QLineEdit *_nbProcs; + QLineEdit *_remoteDir; + QLineEdit *_localDir; + QLineEdit *_WCKey; + QLineEdit *_maxDuration; + bool _wasOK; +}; + +#endif diff --git a/src/ydfx_gui/YDFXGUIMain.cxx b/src/ydfx_gui/YDFXGUIMain.cxx new file mode 100644 index 000000000..f423dc254 --- /dev/null +++ b/src/ydfx_gui/YDFXGUIMain.cxx @@ -0,0 +1,109 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#include "YDFXGUIMain.hxx" +#include "YDFXGUIPortsSelector.hxx" +#include "YDFXGUIHostParametrizer.hxx" +#include "YDFXGUISeqInit.hxx" +#include "YDFXGUIPushButtons.hxx" + +#include "YACSEvalYFX.hxx" + +#include + +///////////// + +YDFXGUIMainEFXWidget::YDFXGUIMainEFXWidget(YACSEvalSession *session, YACSEvalYFXWrap *efx, QWidget *parent):QWidget(parent),_efx(efx),_ports(new YDFXGUIAllPorts(efx,this)),_run(0) +{ + QVBoxLayout *mainLayout(new QVBoxLayout(this)); + mainLayout->addWidget(_ports,1); + QHBoxLayout *buttonLayout(new QHBoxLayout); + QSpacerItem *si(new QSpacerItem(40,20,QSizePolicy::Expanding,QSizePolicy::Minimum)); + buttonLayout->addItem(si); + _seqInit=new YDFXGUISeqInitButton(this,_efx,_ports); + buttonLayout->addWidget(_seqInit); + _run=new YDFXGUIRunButton(this,session,_efx); + _run->setEnabled(false); + connect(_seqInit,SIGNAL(sequenceWellDefined(bool)),_ports,SLOT(somethingChangedInPorts(bool))); + connect(_ports,SIGNAL(sequencesCanBeDefinedSignal(bool)),_seqInit,SLOT(setEnabled(bool))); + connect(_ports,SIGNAL(canBeExecutedSignal(bool)),_run,SLOT(setEnabled(bool))); + // + buttonLayout->addWidget(_run); + mainLayout->addLayout(buttonLayout); +} + +YDFXGUIMainEFXWidget::~YDFXGUIMainEFXWidget() +{ + delete _efx; +} + +AddTabWidget::AddTabWidget(QWidget *parent):QWidget(parent) +{ + QVBoxLayout *mainLayout(new QVBoxLayout); + QPushButton *pb(new QPushButton("Add from XML file",this)); + mainLayout->addWidget(pb); + connect(pb,SIGNAL(clicked(bool)),this,SIGNAL(addNewTab())); + this->setLayout(mainLayout); +} + +///////////// + +TabEFXViews::TabEFXViews(QWidget *parent, YACSEvalSession *session):QTabWidget(parent),_addWidget(new AddTabWidget(this)),_session(session) +{ + this->addTab(_addWidget,"+"); + connect(_addWidget,SIGNAL(addNewTab()),this,SLOT(newTabFromXMLRequested())); + this->setTabsClosable(true); + connect(this,SIGNAL(tabCloseRequested(int)),this,SLOT(closeTabPlease(int))); +} + +void TabEFXViews::newTabFromXMLRequested() +{ + QFileDialog fd(this); + fd.setNameFilter("YACS XML files (*.xml)"); + if(fd.exec()) + { + QStringList fileNames(fd.selectedFiles()); + if(fileNames.size()!=1) + return ; + QString fileName(fileNames[0]); + QFileInfo fn(fileName); + YACSEvalYFXWrap *efx(new YACSEvalYFXWrap(YACSEvalYFX::BuildFromFile(fileName.toStdString()))); + YDFXGUIMainEFXWidget *newTab(new YDFXGUIMainEFXWidget(_session,efx,this)); + int index(this->insertTab(count()-1,newTab,fn.baseName())); + this->setCurrentIndex(index); + } +} + +void TabEFXViews::closeTabPlease(int tabId) +{ + if(tabId==count()-1) + return ; + QWidget *tab(this->widget(tabId)); + delete tab; +} + +///////////// + +YDFXGUI::YDFXGUI(YACSEvalSession *session):_tabWidget(new TabEFXViews(this,session)) +{ + QVBoxLayout *mainLayout(new QVBoxLayout); + mainLayout->addWidget(_tabWidget); + this->setLayout(mainLayout); +} diff --git a/src/ydfx_gui/YDFXGUIMain.hxx b/src/ydfx_gui/YDFXGUIMain.hxx new file mode 100644 index 000000000..80509ce29 --- /dev/null +++ b/src/ydfx_gui/YDFXGUIMain.hxx @@ -0,0 +1,83 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#ifndef __YDFXGUIMAIN_HXX__ +#define __YDFXGUIMAIN_HXX__ + +#include "ydfxwidgetsExport.hxx" + +#include +#include +#include +#include +#include + +#include "Python.h" + +class YACSEvalSession; +class YACSEvalYFXWrap; +class YDFXGUIAllPorts; +class YDFXGUIRunButton; + +class YDFXGUIMainEFXWidget : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIMainEFXWidget(YACSEvalSession *session, YACSEvalYFXWrap *efx, QWidget *parent); + YDFXWIDGETS_EXPORT ~YDFXGUIMainEFXWidget(); +private: + YACSEvalSession *_session; + YACSEvalYFXWrap *_efx;//owned + YDFXGUIAllPorts *_ports; + QPushButton *_seqInit; + YDFXGUIRunButton *_run; +}; + +class AddTabWidget : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT AddTabWidget(QWidget *parent); +signals: + void addNewTab(); +}; + +class TabEFXViews : public QTabWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT TabEFXViews(QWidget *parent, YACSEvalSession *session); +public slots: + YDFXWIDGETS_EXPORT void newTabFromXMLRequested(); + YDFXWIDGETS_EXPORT void closeTabPlease(int tabId); +private: + AddTabWidget *_addWidget; + YACSEvalSession *_session; +}; + +class YDFXGUI : public QWidget +{ +public: + YDFXWIDGETS_EXPORT YDFXGUI(YACSEvalSession *session); +private: + TabEFXViews *_tabWidget; +}; + +#endif diff --git a/src/ydfx_gui/YDFXGUIParametrizer.cxx b/src/ydfx_gui/YDFXGUIParametrizer.cxx new file mode 100644 index 000000000..9b541b8bf --- /dev/null +++ b/src/ydfx_gui/YDFXGUIParametrizer.cxx @@ -0,0 +1,45 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#include "YDFXGUIParametrizer.hxx" + +#include "Exception.hxx" + +YDFXGUIParametrizer::YDFXGUIParametrizer(QWidget *parent):QWidget(parent),_yfx(0) +{ +} + +YDFXGUIParametrizer::YDFXGUIParametrizer(QWidget *parent, YACSEvalYFX *yfx):QWidget(parent),_yfx(yfx) +{ + if(!_yfx) + throw YACS::Exception("YDFXGUIParametrizer cstr: input yfx is NULL !"); +} + +bool YDFXGUIParametrizer::isReadyForEvaluation() const +{ + return true; +} + +YACSEvalYFX *YDFXGUIParametrizer::getPreparedYFXInstance() const +{ + if(!isReadyForEvaluation()) + throw YACS::Exception("YDFXGUIParametrizer::getPreparedYFXInstance : this is NULL !"); + return _yfx; +} diff --git a/src/ydfx_gui/YDFXGUIParametrizer.hxx b/src/ydfx_gui/YDFXGUIParametrizer.hxx new file mode 100644 index 000000000..a1d0ee168 --- /dev/null +++ b/src/ydfx_gui/YDFXGUIParametrizer.hxx @@ -0,0 +1,42 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#ifndef __YDFXGUIPARAMETRIZER_HXX__ +#define __YDFXGUIPARAMETRIZER_HXX__ + +#include "ydfxwidgetsExport.hxx" + +#include + +class YACSEvalYFX; + +class YDFXGUIParametrizer : public QWidget +{ +Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIParametrizer(QWidget *parent); + YDFXWIDGETS_EXPORT YDFXGUIParametrizer(QWidget *parent, YACSEvalYFX *yfx); + YDFXWIDGETS_EXPORT bool isReadyForEvaluation() const; + YDFXWIDGETS_EXPORT YACSEvalYFX *getPreparedYFXInstance() const; +private: + YACSEvalYFX *_yfx; +}; + +#endif diff --git a/src/ydfx_gui/YDFXGUIPortsSelector.cxx b/src/ydfx_gui/YDFXGUIPortsSelector.cxx new file mode 100644 index 000000000..8ccb05423 --- /dev/null +++ b/src/ydfx_gui/YDFXGUIPortsSelector.cxx @@ -0,0 +1,980 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#include "YDFXGUIPortsSelector.hxx" +#include "YDFXGUIPortsValidator.hxx" + +#include "YACSEvalPort.hxx" +#include "YACSEvalSeqAny.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +const int MyWidgetPainter::SZ_OF_PEN_RECT=2; +const int MyWidgetPainter::PADLOCK_X=130; +const int MyWidgetPainter::PADLOCK_Y=206; +const int MyWidgetPainter::DICE_X=225; +const int MyWidgetPainter::DICE_Y=225; +const int HoverLabel::PT_SZ_ON_HOVER=8; +const int OutputLabel::PEN_SZ_CIRCLED=5; + +void MyWidgetPainter::drawPadlock(QWidget *wid) const +{ + static const int STRT_BASEY=86,H_CHORD=18; + const float RATIO(float(PADLOCK_Y)/float(PADLOCK_X)); + QPainter painter(wid); + int width(wid->width()),height(wid->height()); + if(float(height)>RATIO*float(width)) + painter.setViewport(0,int(height-RATIO*float(width))/2,width,width*RATIO); + else + painter.setViewport((float(width)-height/RATIO)/2,0,height/RATIO,height);//width-height/RATIO + painter.setRenderHint(QPainter::Antialiasing,true); + painter.setWindow(0,-STRT_BASEY,PADLOCK_X,PADLOCK_Y); + painter.setPen(QPen(Qt::black,SZ_OF_PEN_RECT,Qt::SolidLine,Qt::SquareCap)); + + float radius=PADLOCK_X*PADLOCK_X/(8*H_CHORD)+H_CHORD/2; + float startAngle=acos(PADLOCK_X/(2.*radius))/M_PI*180*16; + float spanAngle=2*asin(PADLOCK_X/(2*radius))/M_PI*180*16; + + // + QColor darkYellow(194,170,99),brightYellow(255,250,219),zeYellow(255,212,80); + QBrush brush(painter.brush()); + QLinearGradient grad(0,0,PADLOCK_X,0); + grad.setColorAt(0.,darkYellow); + grad.setColorAt(0.8,brightYellow); + grad.setColorAt(1.,zeYellow); + painter.setBrush(grad); + //painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);// SourceOver by default + painter.drawRect(QRect(SZ_OF_PEN_RECT,SZ_OF_PEN_RECT,PADLOCK_X-2*SZ_OF_PEN_RECT,PADLOCK_Y-STRT_BASEY-2*SZ_OF_PEN_RECT)); + // + painter.setBrush(brush); + painter.drawRect(QRect(0+SZ_OF_PEN_RECT/2,0+SZ_OF_PEN_RECT/2,PADLOCK_X-SZ_OF_PEN_RECT,PADLOCK_Y-STRT_BASEY-SZ_OF_PEN_RECT)); + QTransform t,t2; + t.translate(0,-(STRT_BASEY+H_CHORD)) ; t.rotate(180) ; t.translate(-PADLOCK_X,-STRT_BASEY-2*H_CHORD); + painter.setWorldTransform(t); + painter.drawChord(QRect(-(radius-PADLOCK_X/2),0,2*radius,2*radius),180*16-startAngle,-spanAngle); + painter.setWorldTransform(t2); + // + painter.drawLine(6,0,6,-24); painter.drawLine(25,0,25,-24); + //painter.drawLine(103,0,103,-24); painter.drawLine(122,0,122,-24); + const int r1(39),r2(58);//78==103-25 116==122-6 + const int center[2]={64,-24}; + float p1x=cos((180.-_angle)/180.*M_PI)*r1+center[0]; + float p1y=-sin((180.-_angle)/180.*M_PI)*r1+center[1]; + float p2x=cos((180.-_angle)/180.*M_PI)*r2+center[0]; + float p2y=-sin((180.-_angle)/180.*M_PI)*r2+center[1]; + painter.drawArc(QRect(25,-63,2*r1,2*r1),180*16,-_angle*16); + painter.drawArc(QRect(6,-82,2*r2,2*r2),180*16,-_angle*16); + painter.drawLine(p1x,p1y,p2x,p2y); +} + +void MyWidgetPainter::drawDice(QWidget *wid) const +{ + QPainter painter(wid); + int width(wid->width()),height(wid->height()); + if(height>width) + painter.setViewport(0,(height-width)/2,width,width); + else + painter.setViewport((width-height)/2,0,height,height); + painter.setRenderHint(QPainter::Antialiasing,true); + painter.setWindow(0,0,DICE_X,DICE_Y); + const QPoint face0[4]={QPoint(22,35),QPoint(113,110),QPoint(90,224),QPoint(0,148)}; + const QPoint face1[4]={QPoint(113,110),QPoint(224,73),QPoint(196,185),QPoint(90,224)}; + const QPoint face2[4]={QPoint(22,35),QPoint(113,110),QPoint(224,73),QPoint(126,0)}; + QLinearGradient grad(0,0,PADLOCK_X,0); + QColor red0(154,18,20),red1(87,11,13),red2(205,25,24); + painter.setBrush(QBrush(red0)); painter.drawPolygon(face0,4); + painter.setBrush(QBrush(red1)); painter.drawPolygon(face1,4); + painter.setBrush(QBrush(red2)); painter.drawPolygon(face2,4); + //32x16 rot=12*16 + QColor grey(209,209,209); + painter.setBrush(grey); + // + const int NB_POINTS=14; + const float refs[NB_POINTS*2]={50,29,76,48,104,70,112,10,140,29,168,50, + 33,57,53,114,72,171,21,127,87,103, + 109,192,148,145,186,102 + }; + const int angles[NB_POINTS]={12,12,12,12,12,12,72,72,72,72,72,-47,-47,-47}; + for(int i=0;iwidth()),height0(getWidget()->height()); + QRect refRect(0,0,width0,height0); + QPainter painter(getWidget()); + //const QRect& refRect(event->rect());//getWidget()->frameGeometry() + QRect refRect2(refRect);//event->rect()); + painter.setPen(QPen(Qt::red,SZ_OF_PEN_RECT,Qt::SolidLine,Qt::RoundCap)); + refRect2.translate(SZ_OF_PEN_RECT,SZ_OF_PEN_RECT); + refRect2.setWidth(refRect2.width()-2*SZ_OF_PEN_RECT);; + refRect2.setHeight(refRect2.height()-2*SZ_OF_PEN_RECT); + painter.drawRect(refRect2); + painter.setPen(QPen(Qt::black,10,Qt::SolidLine,Qt::RoundCap)); + QRect rect(painter.boundingRect(refRect,Qt::AlignTop,text));//Qt::AlignCenter + const QFont& ft(getWidget()->font()); + QFontMetrics fm(ft); + painter.drawText(QPoint(refRect.x()+SZ_OF_PEN_RECT+refRect2.width()/2-rect.width()/2, + refRect.y()+refRect.height()/2+rect.height()/2-fm.descent()),text); +} + +template +void MyWidgetPainterNoFocus::prepareFontAndBrush(FontBrushSetGet *fbsg) +{ + QFont ft(fbsg->font()); + ft.setBold(true); + fbsg->setFont(ft); +} + +void MyWidgetPainterNoFocus::paintEvent(QPaintEvent *event) +{ + prepareFontAndBrush(getWidget()); + if(!getWidget()->isRandom()) + { + if(getWidget()->text().isEmpty()) + drawPadlock(getWidget()); + else + paintDataCommonPart(event,getWidget()->text()); + } + else + drawDice(getWidget()); +} + +QSize MyWidgetPainterNoFocus::sizeHint() const +{ + if(!getWidget()->isRandom()) + { + if(getWidget()->text().isEmpty()) + return QSize(PADLOCK_X/6,PADLOCK_Y/6); + else + { + QPixmap px(1000,1000); + QPainter painter(&px); + painter.setPen(QPen(Qt::black,5,Qt::SolidLine,Qt::RoundCap)); + prepareFontAndBrush(&painter); + QRect rect(painter.boundingRect(QRect(),Qt::AlignTop,getWidget()->text())); + return QSize(rect.width()+2*SZ_OF_PEN_RECT,rect.height()+2*SZ_OF_PEN_RECT); + } + } + else + return QSize(DICE_X/5,DICE_Y/5); +} + +void MyWidgetPainterNoFocus::appendLetter(const QString& letter) +{ +} + +void MyWidgetPainterNoFocus::supprLetter() +{ +} + +template +void MyWidgetPainterFocus::prepareFontAndBrush(FontBrushSetGet *fbsg) +{ + QFont ft(fbsg->font()); + ft.setBold(false); + fbsg->setFont(ft); +} + +void MyWidgetPainterFocus::paintEvent(QPaintEvent *event) +{ + prepareFontAndBrush(getWidget()); + paintDataCommonPart(event,_textEntered); +} + +QSize MyWidgetPainterFocus::sizeHint() const +{ + QPixmap px(1000,1000); + QPainter painter(&px); + painter.setPen(QPen(Qt::black,5,Qt::SolidLine,Qt::RoundCap)); + prepareFontAndBrush(&painter); + QRect rect(painter.boundingRect(QRect(),Qt::AlignTop,_textEntered)); + return QSize(rect.width(),rect.height()); +} + +void MyWidgetPainterFocus::appendLetter(const QString& letter) +{ + _textEntered+=letter; + getWidget()->updateGeometry(); + getWidget()->update(); +} + +void MyWidgetPainterFocus::supprLetter() +{ + _textEntered.chop(1); + getWidget()->updateGeometry(); + getWidget()->update(); +} + +///////////// + +YDFXGUIInputPortValueEditor::YDFXGUIInputPortValueEditor(YACSEvalInputPort *inp):_inp(inp),_zePainter(new MyWidgetPainterNoFocus(this)),_valid(0) +{ + _valid=BuildValidatorFromPort(this,_inp); + QString txt(text()); + setText(txt); + setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);//Fixed + setFocusPolicy(Qt::ClickFocus); +} + +YDFXGUIInputPortValueEditor::~YDFXGUIInputPortValueEditor() +{ + delete _zePainter; +} + +QString YDFXGUIInputPortValueEditor::text() const +{ + QString txt; + if(_inp->hasDefaultValueDefined()) + { + YACSEvalAny *val(_inp->getDefaultValueDefined()); + txt=BuidStringFromAny(val); + delete val; + } + return txt; +} + +void YDFXGUIInputPortValueEditor::setText(const QString& text) +{ + bool wasKO(!_inp->hasDefaultValueDefined()); + YACSEvalAny *val(BuildAnyFromString(text,_inp)); + _inp->setDefaultValue(val); + QString text2(BuidStringFromAny(val)); + delete val; + QString toolTipText(QString("Default = %1").arg(text2)); + if(text.isNull()) + toolTipText="No default set !"; + setToolTip(toolTipText); + if(text.isEmpty()) + { + connect(this,SIGNAL(changeLook()),this,SLOT(applyModificationOfLook())); + } + else + { + if(wasKO) + { + emit statusChanged(); + disconnect(this,SIGNAL(changeLook()),this,SLOT(applyModificationOfLook())); + } + } +} + +void YDFXGUIInputPortValueEditor::paintEvent(QPaintEvent *event) +{ + _zePainter->paintEvent(event); +} + +void YDFXGUIInputPortValueEditor::mousePressEvent(QMouseEvent *event) +{ + delete _zePainter; + _zePainter=new MyWidgetPainterFocus(this); + updateGeometry(); + update(); +} + +void YDFXGUIInputPortValueEditor::mouseReleaseEvent(QMouseEvent *event) +{ + QClipboard *cb(QApplication::clipboard()); + if(event->button()==Qt::MidButton && cb->supportsSelection()) + { + QString text(cb->text(QClipboard::Selection)); + int pos; + if(_valid->validate(text,pos)==QValidator::Acceptable) + { + delete _zePainter; + _zePainter=new MyWidgetPainterNoFocus(this); + setText(text); + update(); + } + } +} + +void YDFXGUIInputPortValueEditor::keyPressEvent(QKeyEvent *event) +{ + int ekey(event->key()); + if(ekey==Qt::Key_Return || ekey==Qt::Key_Enter) + { + clearFocus(); + return ; + } + if(ekey==Qt::Key_Escape) + { + delete _zePainter; + _zePainter=new MyWidgetPainterNoFocus(this); + clearFocus(); + return ; + } + if(ekey==Qt::Key_Backspace) + { + _zePainter->supprLetter(); + return ; + } + if((ekey>=Qt::Key_Exclam && ekey<=Qt::Key_Z)) + { + QString st(event->text()); + _zePainter->appendLetter(st); + } +} + +void YDFXGUIInputPortValueEditor::focusOutEvent(QFocusEvent * event) +{ + MyWidgetPainterFocus *zePainter(dynamic_cast(_zePainter)); + if(zePainter) + { + int pos; + QString zeSt(zePainter->getText()); + delete _zePainter; + _zePainter=new MyWidgetPainterNoFocus(this); + if(_valid->validate(zeSt,pos)==QValidator::Acceptable) + setText(zeSt); + } + updateGeometry(); + update(); +} + +QSize YDFXGUIInputPortValueEditor::sizeHint() const +{ + return _zePainter->sizeHint(); +} + +QSize YDFXGUIInputPortValueEditor::minimumSizeHint() const +{ + return _zePainter->sizeHint(); +} + +bool YDFXGUIInputPortValueEditor::isOK() const +{ + return IsOK(_inp); +} + +bool YDFXGUIInputPortValueEditor::IsOK(YACSEvalInputPort *inp) +{ + return inp->isRandomVar() || inp->hasDefaultValueDefined(); +} + +bool YDFXGUIInputPortValueEditor::isRandom() const +{ + return _inp->isRandomVar(); +} + +bool YDFXGUIInputPortValueEditor::toggleRandom() +{ + bool oldOK(isOK()); + bool oldStatus(_inp->isRandomVar()); + _inp->declareRandomnessStatus(!oldStatus); + emit statusChanged(); // always emit because this even if newOK and oldOK are the same the upon status can changed ! + updateGeometry(); + update(); + return _inp->isRandomVar(); +} + +void YDFXGUIInputPortValueEditor::applyModificationOfLook() +{ + _zePainter->changeAngle(); + if(!isOK()) + this->update(); +} + +////////////////// + +HoverLabel::HoverLabel(QWidget *parent):QLabel(parent),_isin(false),_isPressed(false) +{ + //setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); + setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); +} + +void HoverLabel::mousePressEvent(QMouseEvent *event) +{ + if(event->button()==Qt::LeftButton) + { + _isPressed=true; + pressOccured(); + updateGeometry(); + update(); + } +} + +void HoverLabel::mouseReleaseEvent(QMouseEvent *event) +{ + if(event->button()==Qt::LeftButton) + { + _isPressed=false; + updateGeometry(); + update(); + } +} + +void HoverLabel::enterEvent(QEvent *event) +{ + _isin=true; + updateGeometry(); + update(); +} + +void HoverLabel::leaveEvent(QEvent *event) +{ + _isin=false; + updateGeometry(); + update(); +} + +void HoverLabel::paintEvent(QPaintEvent *event) +{ + if(!_isin) + return paintIfNotOn(event); + // + QPainter painter(this); + QFont ft(painter.font()); + AssignFontOnHover(ft); + painter.setFont(ft); + QFontMetrics fm(ft); + QPalette pal(QApplication::palette("QPushButton")); + QRect refRect(rect()); + std::vector sts(textForEmulatedPushButton()); + QRect rect3(painter.boundingRect(refRect,Qt::AlignTop,sts[0].str())); + int deltaY((refRect.height()-sts.size()*rect3.height())/(sts.size()+1)); + QBrush b0(pal.color(_isPressed?QPalette::Dark:QPalette::Button)); + painter.setBrush(b0); + painter.setPen(QPen(pal.color(QPalette::Highlight),1,Qt::SolidLine,Qt::SquareCap)); + painter.drawRoundedRect(QRect(0,0,refRect.width()-1,refRect.height()-1),3,3); + painter.setBrush(QBrush()); + painter.setPen(QPen(pal.color(QPalette::Shadow),1,Qt::SolidLine,Qt::SquareCap)); + painter.drawRoundedRect(QRect(1,1,refRect.width()-3,refRect.height()-3),3,3); + painter.setPen(QPen(pal.color(QPalette::Dark),1,Qt::SolidLine,Qt::SquareCap)); + painter.drawRoundedRect(QRect(2,2,refRect.width()-5,refRect.height()-5),5,5); + painter.setPen(QPen(pal.color(QPalette::Midlight),1,Qt::SolidLine,Qt::SquareCap)); + painter.drawRoundedRect(QRect(3,3,refRect.width()-7,refRect.height()-7),3,3); + painter.setPen(QPen(pal.color(QPalette::Light),1,Qt::SolidLine,Qt::SquareCap)); + painter.drawRoundedRect(QRect(4,4,refRect.width()-9,refRect.height()-9),3,3); + //QPalette::Button QPalette::ButtonText + painter.setPen(QPen(pal.color(QPalette::ButtonText),2,Qt::SolidLine,Qt::SquareCap)); + int posY(deltaY); + foreach(ColoredString st,sts) + { + QRect rect2(painter.boundingRect(refRect,Qt::AlignTop,st.str())); + QPen pen(painter.pen()); + QPen pen2(pen); + pen2.setColor(st.color()); + painter.setPen(pen2); + painter.drawText(QPoint((refRect.width()-rect2.width())/2,posY+rect2.height()-fm.descent()),st.str()); + painter.setPen(pen); + posY+=deltaY+rect2.height(); + } +} + +QSize HoverLabel::sizeHint() const +{ + if(!_isin) + return sizeHintNotHovered(); + else + { + QFont ft(font()); + AssignFontOnHover(ft); + QFontMetrics fm(ft); + std::vector sts(textForEmulatedPushButton()); + int h(0),w(0); + foreach(ColoredString st,sts) + { + QSize elt(fm.boundingRect(st.str()).size()); + h+=elt.height(); + w=std::max(w,elt.width()); + } + QSize ret; + ret.setHeight(h); ret.setWidth(w);//3*PT_SZ_ON_HOVER + return ret; + } +} + +void HoverLabel::AssignFontOnHover(QFont& ft) +{ + ft.setBold(true); + ft.setItalic(true); + ft.setPointSize(PT_SZ_ON_HOVER); +} + +////////////////// + +InputLabel::InputLabel(YACSEvalInputPort *inp, QWidget *parent):HoverLabel(parent),_inp(inp) +{ + AssignTextAndTooltip(this,_inp); +} + +QSize InputLabel::sizeHintNotHovered() const +{ + return QLabel::sizeHint(); +} + +void InputLabel::paintIfNotOn(QPaintEvent *event) +{ + QLabel::paintEvent(event); +} + +void InputLabel::pressOccured() +{ + emit randomnessStatusChanged(); +} + +std::vector InputLabel::textForEmulatedPushButton() const +{ + std::vector ret; + if(!_inp->isRandomVar()) + ret.push_back(QString(" Parametrize %1 ").arg(text())); + else + ret.push_back(QString(" Unparametrize %1 ").arg(text())); + return ret; +} + +void InputLabel::AssignTextAndTooltip(QLabel *wid, YACSEvalInputPort *port) +{ + QString txt(port->getName().c_str()); + wid->setText(txt); + wid->setToolTip(QString("%1 (%2)").arg(txt).arg(QString(port->getTypeOfData().c_str()))); +} + +////////////////// + +InputLabelNonToggle::InputLabelNonToggle(YDFXGUIInputPortValueEditor *wid, QWidget *parent):QLabel(parent),_wid(wid) +{ + setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + InputLabel::AssignTextAndTooltip(this,_wid->getPort()); +} + +////////////////// + +OutputLabel::OutputLabel(YACSEvalOutputPort *outp, QWidget *parent):HoverLabel(parent),_outp(outp) +{ + QString txt(_outp->getName().c_str()); + setText(txt); + setToolTip(txt); +} + +bool OutputLabel::isQOfInt() const +{ + return _outp->isQOfInterest(); +} + +QSize OutputLabel::sizeHintNotHovered() const +{ + if(!isQOfInt()) + return QLabel::sizeHint(); + const QFont& ft(font()); + QFontMetrics fm(ft); + QString txt(text()); + QPointF pts[7]; + ComputePointsToCircle(txt,rect(),font(),pts); + QPainterPath path; + path.moveTo(pts[0]); + path.cubicTo(pts[1],pts[2],pts[3]); + path.cubicTo(pts[4],pts[5],pts[6]); + QSize ret(path.boundingRect().toRect().size()); + int& rh(ret.rheight()),&rw(ret.rwidth()); + rh+=2*PEN_SZ_CIRCLED; rw+=2*PEN_SZ_CIRCLED; + return ret; +} + +void OutputLabel::paintIfNotOn(QPaintEvent *event) +{ + QLabel::paintEvent(event); + if(!isQOfInt()) + return ; + QString txt(text()); + // + const QFont& ft(font()); + QFontMetrics fm(ft); + QPainter painter(this); + // + QPointF pts[7]; + ComputePointsToCircle(txt,rect(),font(),pts); + // + QPainterPath path; + path.moveTo(pts[0]); + path.cubicTo(pts[1],pts[2],pts[3]); + path.cubicTo(pts[4],pts[5],pts[6]); + QPen pen(painter.pen()); + pen.setColor(Qt::green); pen.setWidth(PEN_SZ_CIRCLED); + painter.strokePath(path,pen); +} + +void OutputLabel::pressOccured() +{ + bool oldStatus(_outp->isQOfInterest()); + _outp->setQOfInterestStatus(!oldStatus); + emit clicked(); +} + +std::vector OutputLabel::textForEmulatedPushButton() const +{ + std::vector ret; + if(!isQOfInt()) + { + ret.push_back(QString("Make")); + ColoredString elt(QString("%1").arg(_outp->getName().c_str())); + elt.setColor(Qt::red); + ret.push_back(elt); + } + else + { + ret.push_back(QString("No more")); + ColoredString elt(QString("%1").arg(_outp->getName().c_str())); + elt.setColor(Qt::red); + ret.push_back(elt); + ret.push_back(QString("as")); + } + ret.push_back(QString("quantity")); + ret.push_back(QString("of")); + ret.push_back(QString("interest")); + return ret; +} + +QSize OutputLabel::minimumSizeHint() const +{ + return sizeHint(); +} + +void OutputLabel::ComputePointsToCircle(const QString& txt, const QRect& refRect, const QFont& font, QPointF pts[8]) +{ + QFontMetrics fm(font); + QSize rect2(fm.boundingRect(txt).size()); + QPointF refPt(refRect.width()/2,refRect.height()/2+fm.descent()); + for(int i=0;i<7;i++) + pts[i]=refPt; + qreal& p0x(pts[0].rx()),&p0y(pts[0].ry()),&p1x(pts[1].rx()),&p1y(pts[1].ry()),&p2x(pts[2].rx()),&p2y(pts[2].ry()),&p3x(pts[3].rx()),&p3y(pts[3].ry()); + p0x+=rect2.width()/2.; p0y-=rect2.height(); + p1x+=rect2.width(); p1y-=1.2*rect2.height()/2.; + p2x+=rect2.width(); p2y+=1.2*rect2.height(); + p3y+=1.2*rect2.height(); + qreal &p4x(pts[4].rx()),&p4y(pts[4].ry()),&p5x(pts[5].rx()),&p5y(pts[5].ry()),&p6x(pts[6].rx()),&p6y(pts[6].ry()); + p4x-=1.1*rect2.width(); p4y+=1.2*rect2.height(); + p5x-=rect2.width(); p5y-=1.3*rect2.height()/2.; + p6x+=rect2.width()/2.; p6y-=1.4*rect2.height(); +} + +///////////// + +void YDFXGUIOKCls::initOK() +{ + _isOK=isOK(); +} + +////////////////// + +void YDFXGUIGatherPorts::somebodyChangedStatus() +{ + bool newStatus(isOK()); + if(newStatus!=wasOK()) + { + updateGeometry(); + update(); + setWasOKStatus(newStatus); + } + emit theGlobalStatusChanged(newStatus);// emit signal always because of input ports and sequences definitions. +} + +////////////////// + +YDFXGUIInputPortsSelector::YDFXGUIInputPortsSelector(YACSEvalYFXWrap *efx, QWidget *parent):YDFXGUIGatherPorts(parent),_timerId(-1) +{ + _inps=efx->getFreeInputPorts(); + fillWidget(); + initOK(); +} + +bool YDFXGUIInputPortsSelector::isOK() const +{ + const QObjectList &children(this->children()); + int nbOfRandom(0); + foreach(QObject *child,children) + { + YDFXGUIInputPortValueEditor *childc(qobject_cast(child)); + if(childc) + { + if(!childc->isOK()) + return false; + if(childc->isRandom()) + nbOfRandom++; + } + } + return nbOfRandom>=1; +} + +bool YDFXGUIInputPortsSelector::areSeqWellDefined() const +{ + const QObjectList &children(this->children()); + int nbOfRandom(0),refSz(std::numeric_limits::max()); + foreach(QObject *child,children) + { + YDFXGUIInputPortValueEditor *childc(qobject_cast(child)); + if(!childc) + continue; + if(!childc->isOK()) + return false; + if(!childc->isRandom()) + continue; + YACSEvalInputPort *port(childc->getPort()); + YACSEvalSeqAny *seq(port->getSequenceOfValuesToEval()); + if(!seq) + return false; + if(nbOfRandom==0) + refSz=seq->size(); + if(refSz!=seq->size()) + return false; + nbOfRandom++; + } + return nbOfRandom>=1; +} + +void YDFXGUIInputPortsSelector::fillWidget() +{ + QVBoxLayout *mainLayout(new QVBoxLayout); + for(std::vector< YACSEvalInputPort * >::const_iterator it=_inps.begin();it!=_inps.end();it++) + { + QHBoxLayout *lineLayout(new QHBoxLayout); + YDFXGUIInputPortValueEditor *elt1(new YDFXGUIInputPortValueEditor(*it)); + QLabel *elt0(0); + if((*it)->getTypeOfData()==YACSEvalAnyDouble::TYPE_REPR) + { + InputLabel *elt0c(new InputLabel(*it,this)); + elt0=elt0c; + connect(elt0c,SIGNAL(randomnessStatusChanged()),elt1,SLOT(toggleRandom())); + } + else + elt0=new InputLabelNonToggle(elt1,this); + lineLayout->addWidget(elt0); + connect(elt1,SIGNAL(statusChanged()),this,SLOT(somebodyChangedStatus())); + lineLayout->addWidget(elt1); + mainLayout->addLayout(lineLayout); + } + this->setLayout(mainLayout); +} + +YDFXGUIInputPortsSelector::~YDFXGUIInputPortsSelector() +{ + if(_timerId!=-1) + killTimer(_timerId); +} + +void YDFXGUIInputPortsSelector::showEvent(QShowEvent *e) +{ + _timerId=startTimer(100); +} + +void YDFXGUIInputPortsSelector::timerEvent(QTimerEvent *e) +{ + if(e->timerId()==_timerId) + { + const QObjectList &children(this->children()); + foreach(QObject *child,children) + { + YDFXGUIInputPortValueEditor *childc(qobject_cast(child)); + if(childc) + { + emit childc->changeLook(); + } + } + } +} + +void YDFXGUIInputPortsSelector::DrawWarningSign(QPainter& painter, int width0, int height0) +{ + const int SZP(12); + static const int WARN_Y=176,WARN_X=200; + const float RATIO(float(WARN_X)/float(WARN_Y)); + //QPen(QColor(255,203,189) + if(float(width0)>RATIO*float(height0)) + painter.setViewport(int(width0-RATIO*float(height0))/2,0,height0*RATIO,height0); + else + painter.setViewport(0,(float(height0)-width0/RATIO)/2,width0,width0/RATIO);//width-height/RATIO + painter.setRenderHint(QPainter::Antialiasing,true); + painter.setWindow(0,0,WARN_X,WARN_Y); + // + painter.setPen(QPen(QColor(255,203,189),SZP,Qt::SolidLine,Qt::RoundCap)); + painter.drawLine(QPoint(100,13),QPoint(11,164)); + painter.drawLine(QPoint(11,164),QPoint(185,164)); + painter.drawLine(QPoint(185,164),QPoint(100,13)); + QColor lightBlack(200,200,200); + painter.setBrush(QBrush(lightBlack)); + painter.setPen(QPen(lightBlack,2,Qt::SolidLine,Qt::RoundCap)); + painter.drawEllipse(87,47,24,24); + painter.drawEllipse(93,105,12,12); + painter.drawEllipse(90,129,18,18); + const QPoint points[4]={QPoint(87,59),QPoint(93,111),QPoint(105,111),QPoint(111,59)}; + painter.drawPolygon(points,4); +} + +void YDFXGUIInputPortsSelector::paintEvent(QPaintEvent *e) +{ + QPainter painter(this); + const int SZP(12); + int width0(width()),height0(height()); + // + QRect refRect(0,0,width0,height0); + painter.eraseRect(refRect); + if(!isOK()) + DrawWarningSign(painter,width0,height0); +} + +///////////// + +YDFXGUIOutputPortsSelector::YDFXGUIOutputPortsSelector(YACSEvalYFXWrap *efx, QWidget *parent):YDFXGUIGatherPorts(parent) +{ + _outps=efx->getFreeOutputPorts(); + fillWidget(); + initOK(); +} + +void YDFXGUIOutputPortsSelector::fillWidget() +{ + QVBoxLayout *mainLayout(new QVBoxLayout); + for(std::vector< YACSEvalOutputPort * >::const_iterator it=_outps.begin();it!=_outps.end();it++) + { + if((*it)->getTypeOfData()==YACSEvalAnyDouble::TYPE_REPR) + { + OutputLabel *elt1(new OutputLabel(*it,this)); + mainLayout->addWidget(elt1); + connect(elt1,SIGNAL(clicked()),this,SLOT(somebodyChangedStatus())); + } + } + this->setLayout(mainLayout); +} + +void YDFXGUIOutputPortsSelector::paintEvent(QPaintEvent *e) +{ + if(isOK()) + { + QWidget::paintEvent(e); + return ; + } + QPainter painter(this); + YDFXGUIInputPortsSelector::DrawWarningSign(painter,width(),height()); +} + +bool YDFXGUIOutputPortsSelector::isOK() const +{ + int nbOfOutputsQOI(0); + foreach(QObject *child,children()) + { + OutputLabel *childc(qobject_cast(child)); + if(!childc) + continue; + if(childc->isQOfInt()) + nbOfOutputsQOI++; + } + return nbOfOutputsQOI>=1; +} + +///////////// + +QScrollArea *YDFXGUIAbstractPorts::setupWidgets(const QString& title, QWidget *zeWidget) +{ + QHBoxLayout *mainLayout(new QHBoxLayout(this)); + QGroupBox *gb(new QGroupBox(title,this)); + QVBoxLayout *vbox(new QVBoxLayout); + QVBoxLayout *vbox2(new QVBoxLayout); + QFrame *frame(new QFrame(this)); + frame->setFrameStyle(QFrame::Panel | QFrame::Sunken); + vbox->addWidget(frame); + gb->setLayout(vbox); + QScrollArea *sa(new QScrollArea(this)); + sa->setWidgetResizable(true); + sa->setWidget(zeWidget); + vbox2->addWidget(sa); + frame->setLayout(vbox2); + mainLayout->addWidget(gb); + this->setLayout(mainLayout); + return sa; +} + +///////////// + +YDFXGUIInputPorts::YDFXGUIInputPorts(YACSEvalYFXWrap *efx, QWidget *parent):YDFXGUIAbstractPorts(efx,parent),_inputsSelector(new YDFXGUIInputPortsSelector(efx,this)) +{ + QScrollArea *sa(setupWidgets("Inputs",_inputsSelector)); + connect(efx,SIGNAL(lockSignal(bool)),_inputsSelector,SLOT(setDisabled(bool))); + sa->setMinimumWidth(320); + sa->setMinimumHeight(360); +} + +///////////// + +YDFXGUIOutputPorts::YDFXGUIOutputPorts(YACSEvalYFXWrap *efx, QWidget *parent):YDFXGUIAbstractPorts(efx,parent),_outputsSelector(new YDFXGUIOutputPortsSelector(efx,this)) +{ + QScrollArea *sa(setupWidgets("Outputs",_outputsSelector)); + connect(efx,SIGNAL(lockSignal(bool)),_outputsSelector,SLOT(setDisabled(bool))); + sa->setMinimumWidth(100); +} +///////////// + +YDFXGUIAllPorts::YDFXGUIAllPorts(YACSEvalYFXWrap *efx, QWidget *parent):QWidget(parent),_in(new YDFXGUIInputPorts(efx,this)),_out(new YDFXGUIOutputPorts(efx,this)) +{ + QVBoxLayout *mainLayout(new QVBoxLayout(this)); + QSplitter *sp(new QSplitter(Qt::Horizontal,this)); + sp->addWidget(_in); sp->setStretchFactor(0,3); + sp->addWidget(_out); sp->setStretchFactor(1,1); + mainLayout->addWidget(sp); + connect(_in->getPortsManager(),SIGNAL(theGlobalStatusChanged(bool)),this,SLOT(somethingChangedInPorts(bool))); + connect(_out->getPortsManager(),SIGNAL(theGlobalStatusChanged(bool)),this,SLOT(somethingChangedInPorts(bool))); +} + +bool YDFXGUIAllPorts::isOK() const +{ + return _in->getPortsManager()->isOK() && _out->getPortsManager()->isOK(); +} + +void YDFXGUIAllPorts::somethingChangedInPorts(bool status) +{ + bool step1(_in->isOK() && _out->isOK()); + if(!step1) + { + emit sequencesCanBeDefinedSignal(false); + emit canBeExecutedSignal(false); + return ; + } + emit sequencesCanBeDefinedSignal(true); + emit canBeExecutedSignal(_in->areSeqWellDefined()); +} diff --git a/src/ydfx_gui/YDFXGUIPortsSelector.hxx b/src/ydfx_gui/YDFXGUIPortsSelector.hxx new file mode 100644 index 000000000..bb0692b3d --- /dev/null +++ b/src/ydfx_gui/YDFXGUIPortsSelector.hxx @@ -0,0 +1,327 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#ifndef __YDFXGUIPORTSSELECTOR_HXX__ +#define __YDFXGUIPORTSSELECTOR_HXX__ + +#include "ydfxwidgetsExport.hxx" + +#include "YDFXGUIWrap.hxx" + +#include +#include +#include +#include +#include +#include +#include + +#include + +class QValidator; + +class YDFXGUIInputPortValueEditor; + +class ColoredString +{ +public: + ColoredString(const QString& str):_str(str) { } + void setColor(const QColor& col) { _col=col; } + const QString& str() const { return _str; } + const QColor& color() const { return _col; } +private: + QString _str; + QColor _col; +}; + +class MyWidgetPainter +{ +public: + virtual ~MyWidgetPainter() { } + virtual void paintEvent(QPaintEvent *event) = 0; + virtual QSize sizeHint() const = 0; + virtual void appendLetter(const QString& letter) = 0; + virtual void supprLetter() = 0; + virtual bool isNotSelected() const = 0; +public: + void changeAngle(); +protected: + MyWidgetPainter(YDFXGUIInputPortValueEditor *wid):_wid(wid),_angle(120) { } + YDFXGUIInputPortValueEditor *getWidget() const { return _wid; } +protected: + void paintDataCommonPart(QPaintEvent *event, const QString& text); + void drawPadlock(QWidget *wid) const; + void drawDice(QWidget *wid) const; +private: + YDFXGUIInputPortValueEditor *_wid; + int _angle; +public: + static const int SZ_OF_PEN_RECT; + static const int PADLOCK_X; + static const int PADLOCK_Y; + static const int DICE_X; + static const int DICE_Y; +}; + +class MyWidgetPainterNoFocus : public MyWidgetPainter +{ +public: + MyWidgetPainterNoFocus(YDFXGUIInputPortValueEditor *wid):MyWidgetPainter(wid) { } +private: + template + static void prepareFontAndBrush(FontBrushSetGet *fbsg); +private: + virtual ~MyWidgetPainterNoFocus() { } + void paintEvent(QPaintEvent *event); + QSize sizeHint() const; + void appendLetter(const QString& letter); + void supprLetter(); + bool isNotSelected() const { return true; } +}; + +class MyWidgetPainterFocus : public MyWidgetPainter +{ +public: + MyWidgetPainterFocus(YDFXGUIInputPortValueEditor *wid):MyWidgetPainter(wid) { } + QString getText() const { return _textEntered; } +private: + template + static void prepareFontAndBrush(FontBrushSetGet *fbsg); +private: + virtual ~MyWidgetPainterFocus() { } + void paintEvent(QPaintEvent *event); + QSize sizeHint() const; + void appendLetter(const QString& letter); + void supprLetter(); + bool isNotSelected() const { return false; } +private: + QString _textEntered; +}; + +class YDFXGUIInputPortValueEditor : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText) +public: + YDFXWIDGETS_EXPORT YDFXGUIInputPortValueEditor(YACSEvalInputPort *inp); + YDFXWIDGETS_EXPORT ~YDFXGUIInputPortValueEditor(); + YDFXWIDGETS_EXPORT QString text() const; + YDFXWIDGETS_EXPORT void setText(const QString& text); + YDFXWIDGETS_EXPORT void paintEvent(QPaintEvent *event); + YDFXWIDGETS_EXPORT void mousePressEvent(QMouseEvent *event); + YDFXWIDGETS_EXPORT void mouseReleaseEvent(QMouseEvent *event); + YDFXWIDGETS_EXPORT void keyPressEvent(QKeyEvent *event); + YDFXWIDGETS_EXPORT void focusOutEvent(QFocusEvent * event); + YDFXWIDGETS_EXPORT QSize sizeHint() const; + YDFXWIDGETS_EXPORT QSize minimumSizeHint() const; +public: + YDFXWIDGETS_EXPORT bool isOK() const; + YDFXWIDGETS_EXPORT bool isRandom() const; + YDFXWIDGETS_EXPORT YACSEvalInputPort *getPort() const { return _inp; } + YDFXWIDGETS_EXPORT static bool IsOK(YACSEvalInputPort *inp); +public slots: + YDFXWIDGETS_EXPORT void applyModificationOfLook(); + YDFXWIDGETS_EXPORT bool toggleRandom(); +signals: + void changeLook(); + void statusChanged(); +private: + YACSEvalInputPort *_inp; + MyWidgetPainter *_zePainter; + QValidator *_valid; +}; + +class HoverLabel : public QLabel +{ +public: + YDFXWIDGETS_EXPORT HoverLabel(QWidget *parent); + YDFXWIDGETS_EXPORT void mousePressEvent(QMouseEvent *event); + YDFXWIDGETS_EXPORT void mouseReleaseEvent(QMouseEvent *event); + YDFXWIDGETS_EXPORT void enterEvent(QEvent *event); + YDFXWIDGETS_EXPORT void leaveEvent(QEvent *event); + YDFXWIDGETS_EXPORT void paintEvent(QPaintEvent *event); + YDFXWIDGETS_EXPORT QSize sizeHint() const; +private: + virtual QSize sizeHintNotHovered() const = 0; + virtual void paintIfNotOn(QPaintEvent *event) = 0; + virtual void pressOccured() = 0; + virtual std::vector textForEmulatedPushButton() const = 0; + static void AssignFontOnHover(QFont& ft); +private: + bool _isin; + bool _isPressed; + static const int PT_SZ_ON_HOVER; +}; + +class InputLabel : public HoverLabel +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT InputLabel(YACSEvalInputPort *inp, QWidget *parent); +private: + QSize sizeHintNotHovered() const; + void paintIfNotOn(QPaintEvent *event); + void pressOccured(); + std::vector textForEmulatedPushButton() const; +public: + YDFXWIDGETS_EXPORT static void AssignTextAndTooltip(QLabel *wid, YACSEvalInputPort *port); +signals: + YDFXWIDGETS_EXPORT void randomnessStatusChanged(); +private: + YACSEvalInputPort *_inp; +}; + +class InputLabelNonToggle : public QLabel +{ +public: + YDFXWIDGETS_EXPORT InputLabelNonToggle(YDFXGUIInputPortValueEditor *wid, QWidget *parent); +private: + YDFXGUIInputPortValueEditor *_wid; +}; + +class OutputLabel : public HoverLabel +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT OutputLabel(YACSEvalOutputPort *outp, QWidget *parent); + YDFXWIDGETS_EXPORT bool isQOfInt() const; +private: + QSize sizeHintNotHovered() const; + void paintIfNotOn(QPaintEvent *event); + void pressOccured(); + std::vector textForEmulatedPushButton() const; + QSize minimumSizeHint() const; + static void ComputePointsToCircle(const QString& txt, const QRect& refRect, const QFont& font, QPointF pts[7]); +signals: + void clicked(); +private: + static const int PEN_SZ_CIRCLED; +private: + YACSEvalOutputPort *_outp; +}; + +class YDFXGUIOKCls +{ +public: + YDFXWIDGETS_EXPORT YDFXGUIOKCls():_isOK(false) { } + YDFXWIDGETS_EXPORT bool wasOK() const { return _isOK; } + YDFXWIDGETS_EXPORT bool setWasOKStatus(bool newStatus) { _isOK=newStatus; } + YDFXWIDGETS_EXPORT virtual bool isOK() const = 0; +protected: + void initOK(); +private: + bool _isOK; +}; + +class YDFXGUIGatherPorts : public QWidget, public YDFXGUIOKCls +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIGatherPorts(QWidget *parent):QWidget(parent) { } +public slots: + YDFXWIDGETS_EXPORT void somebodyChangedStatus(); +signals: + void theGlobalStatusChanged(bool newStatus); +}; + +class YDFXGUIInputPortsSelector : public YDFXGUIGatherPorts +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIInputPortsSelector(YACSEvalYFXWrap *efx, QWidget *parent=0); + YDFXWIDGETS_EXPORT ~YDFXGUIInputPortsSelector(); + YDFXWIDGETS_EXPORT const std::vector< YACSEvalInputPort * >& getInputs() const { return _inps; } + YDFXWIDGETS_EXPORT bool isOK() const; + YDFXWIDGETS_EXPORT bool areSeqWellDefined() const; + YDFXWIDGETS_EXPORT static void DrawWarningSign(QPainter& painter, int width0, int height0); +private: + void fillWidget(); + void showEvent(QShowEvent *e); + void timerEvent(QTimerEvent *e); + void paintEvent(QPaintEvent *e); +private: + std::vector< YACSEvalInputPort * > _inps; + int _timerId; +}; + +class YDFXGUIOutputPortsSelector : public YDFXGUIGatherPorts +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIOutputPortsSelector(YACSEvalYFXWrap *efx, QWidget *parent=0); + YDFXWIDGETS_EXPORT const std::vector< YACSEvalOutputPort * >& getOutputs() const { return _outps; } + YDFXWIDGETS_EXPORT bool isOK() const; +private: + void fillWidget(); + void paintEvent(QPaintEvent *e); +private: + std::vector< YACSEvalOutputPort * > _outps; +}; + +class YDFXGUIAbstractPorts : public QWidget +{ +protected: + YDFXGUIAbstractPorts(YACSEvalYFXWrap *efx, QWidget *parent):QWidget(parent) { } + QScrollArea *setupWidgets(const QString& title, QWidget *zeWidget); + virtual YDFXGUIGatherPorts *getPortsManager() = 0; + virtual const YDFXGUIGatherPorts *getPortsManager() const = 0; +}; + +class YDFXGUIInputPorts : public YDFXGUIAbstractPorts +{ +public: + YDFXWIDGETS_EXPORT YDFXGUIInputPorts(YACSEvalYFXWrap *efx, QWidget *parent); + YDFXWIDGETS_EXPORT bool isOK() const { return _inputsSelector->isOK(); } + YDFXWIDGETS_EXPORT bool areSeqWellDefined() const { return _inputsSelector->areSeqWellDefined(); } + YDFXWIDGETS_EXPORT YDFXGUIInputPortsSelector *getInputsSelector() const { return _inputsSelector; } + YDFXWIDGETS_EXPORT YDFXGUIGatherPorts *getPortsManager() { return _inputsSelector; } + YDFXWIDGETS_EXPORT const YDFXGUIGatherPorts *getPortsManager() const { return _inputsSelector; } +private: + YDFXGUIInputPortsSelector *_inputsSelector; +}; + +class YDFXGUIOutputPorts : public YDFXGUIAbstractPorts +{ +public: + YDFXWIDGETS_EXPORT YDFXGUIOutputPorts(YACSEvalYFXWrap *efx, QWidget *parent); + YDFXWIDGETS_EXPORT bool isOK() const { return _outputsSelector->isOK(); } + YDFXWIDGETS_EXPORT YDFXGUIGatherPorts *getPortsManager() { return _outputsSelector; } + YDFXWIDGETS_EXPORT const YDFXGUIGatherPorts *getPortsManager() const { return _outputsSelector; } +private: + YDFXGUIOutputPortsSelector *_outputsSelector; +}; + +class YDFXGUIAllPorts : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIAllPorts(YACSEvalYFXWrap *efx, QWidget *parent); + YDFXWIDGETS_EXPORT bool isOK() const; +private: + YDFXGUIInputPorts *_in; + YDFXGUIOutputPorts *_out; +public slots: + YDFXWIDGETS_EXPORT void somethingChangedInPorts(bool status); +signals: + void sequencesCanBeDefinedSignal(bool status); + void canBeExecutedSignal(bool status); +}; + +#endif diff --git a/src/ydfx_gui/YDFXGUIPortsValidator.cxx b/src/ydfx_gui/YDFXGUIPortsValidator.cxx new file mode 100644 index 000000000..71355b19b --- /dev/null +++ b/src/ydfx_gui/YDFXGUIPortsValidator.cxx @@ -0,0 +1,96 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#include "YDFXGUIPortsValidator.hxx" + +#include +#include + +#include "YACSEvalPort.hxx" +#include "YACSEvalSeqAny.hxx" + +QValidator *BuildValidatorFromPort(QObject *parent, YACSEvalPort *port) +{ + if(!port) + return 0; + std::string tod(port->getTypeOfData()); + if(tod==YACSEvalAnyDouble::TYPE_REPR) + return new QDoubleValidator(parent); + if(tod==YACSEvalAnyInt::TYPE_REPR) + return new QIntValidator(parent); + return 0; +} + +YACSEvalAny *BuildAnyFromString(const QString& text, YACSEvalPort *port) +{ + if(!port) + return 0; + std::string tod(port->getTypeOfData()); + if(tod==YACSEvalAnyDouble::TYPE_REPR) + { + bool isok; + double val(text.toDouble(&isok)); + if(!isok) + return 0; + return new YACSEvalAnyDouble(val); + } + if(tod==YACSEvalAnyInt::TYPE_REPR) + { + bool isok; + int val(text.toInt(&isok)); + if(!isok) + return 0; + return new YACSEvalAnyInt(val); + } + return 0; +} + +QString BuidStringFromAny(YACSEvalAny *val) +{ + if(!val) + return QString(); + if(val->getTypeOfData()==YACSEvalAnyDouble::TYPE_REPR) + { + YACSEvalAnyDouble *valc(static_cast(val)); + return QString::number(valc->toDouble(),'g',16); + } + if(val->getTypeOfData()==YACSEvalAnyInt::TYPE_REPR) + { + YACSEvalAnyInt *valc(static_cast(val)); + return QString::number(valc->toInt()); + } + return QString(); +} + +YACSEvalSeqAny *BuildEmptySeqFromPort(YACSEvalPort *port) +{ + std::string tod(port->getTypeOfData()); + if(tod==YACSEvalAnyDouble::TYPE_REPR) + { + std::vector v; + return new YACSEvalSeqAnyDouble(v); + } + if(tod==YACSEvalAnyInt::TYPE_REPR) + { + std::vector v; + return new YACSEvalSeqAnyInt(v); + } + return 0; +} diff --git a/src/ydfx_gui/YDFXGUIPortsValidator.hxx b/src/ydfx_gui/YDFXGUIPortsValidator.hxx new file mode 100644 index 000000000..6bc7b5efa --- /dev/null +++ b/src/ydfx_gui/YDFXGUIPortsValidator.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#ifndef __YDFXGUIPORTSVALIDATOR_HXX__ +#define __YDFXGUIPORTSVALIDATOR_HXX__ + +class QValidator; +class QString; +class QObject; + +class YACSEvalPort; +class YACSEvalAny; +class YACSEvalSeqAny; +class YACSEvalInputPort; + +QValidator *BuildValidatorFromPort(QObject *parent, YACSEvalPort *port); +YACSEvalAny *BuildAnyFromString(const QString& text, YACSEvalPort *port); +QString BuidStringFromAny(YACSEvalAny *val); +YACSEvalSeqAny *BuildEmptySeqFromPort(YACSEvalPort *port); + +#endif diff --git a/src/ydfx_gui/YDFXGUIPushButtons.cxx b/src/ydfx_gui/YDFXGUIPushButtons.cxx new file mode 100644 index 000000000..550f21790 --- /dev/null +++ b/src/ydfx_gui/YDFXGUIPushButtons.cxx @@ -0,0 +1,471 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#include "YDFXGUIPushButtons.hxx" + +#include "YDFXGUIWrap.hxx" +#include "YDFXGUISeqInit.hxx" +#include "YDFXGUIPyThreadSaver.hxx" +#include "YDFXGUIHostParametrizer.hxx" + +#include "YACSEvalSession.hxx" +#include "YACSEvalObserver.hxx" +#include "YACSEvalResource.hxx" +#include "YACSEvalExecParams.hxx" + +#include "Exception.hxx" + +#include +#include +#include +#include +#include + +///////////// + +YDFXGUIPushButton1::YDFXGUIPushButton1(QWidget *parent, YACSEvalYFXWrap *efx, YDFXGUIAllPorts *ports):QPushButton(parent),_efx(efx),_ports(ports) +{ + setEnabled(false); +} + +///////////// + +YDFXGUIResourcePushButton::YDFXGUIResourcePushButton(QWidget *parent, YACSEvalYFXWrap *efx, YDFXGUIAllPorts *ports):YDFXGUIPushButton1(parent,efx,ports) +{ + setText("Assign Resources"); + connect(this,SIGNAL(clicked(bool)),this,SLOT(resourceAssignmentRequested())); + connect(efx,SIGNAL(runSignal(bool)),this,SLOT(setHidden(bool))); +} + +void YDFXGUIResourcePushButton::resourceAssignmentRequested() +{ + QDialog dial(this); + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(dial.sizePolicy().hasHeightForWidth()); + dial.setSizePolicy(sizePolicy); + QVBoxLayout *vbox(new QVBoxLayout(&dial)); + YDFXGUIHostParametrizer *param(new YDFXGUIHostParametrizer(&dial,_efx)); + QObject::connect(param->getDialogButtonBox(),SIGNAL(accepted()),&dial,SLOT(accept())); + QObject::connect(param->getDialogButtonBox(),SIGNAL(rejected()),&dial,SLOT(reject())); + vbox->addWidget(param); + param->loadFromSettings(_settings); + if(dial.exec()) + { + param->applyToEFX(); + param->learnSettings(_settings); + } +} + +///////////// + +YDFXGUISeqInitButton::YDFXGUISeqInitButton(QWidget *parent, YACSEvalYFXWrap *efx, YDFXGUIAllPorts *ports):YDFXGUIPushButton1(parent,efx,ports) +{ + setText("Init sequences"); + connect(this,SIGNAL(clicked(bool)),this,SLOT(sequenceInitRequested())); + connect(efx,SIGNAL(runSignal(bool)),this,SLOT(setHidden(bool))); +} + +void YDFXGUISeqInitButton::sequenceInitRequested() +{ + QDialog dial(this); + YDFXGUISeqInit *zeWidget(new YDFXGUISeqInit(&dial,_efx)); + zeWidget->loadState(_state); + QVBoxLayout *mainLayout(new QVBoxLayout(&dial)); + mainLayout->addWidget(zeWidget); + QObject::connect(zeWidget,SIGNAL(assignButtonClicked()),&dial,SLOT(accept())); + if(dial.exec()) + { + _state=zeWidget->saveState(); + emit sequenceWellDefined(true); + } +} + +///////////// + +YDFXGUIRunInfo::YDFXGUIRunInfo(QObject *parent, int nbOfItems):QObject(parent),_computationInProgress(false),_items(nbOfItems,0) +{ +} + +void YDFXGUIRunInfo::startComputation() +{ + _mut.lock(); + std::fill(_items.begin(),_items.end(),0); + _computationInProgress=true; + _mut.unlock(); + emit somethingChanged(); +} + +void YDFXGUIRunInfo::endComputation() +{ + _mut.lock(); + _computationInProgress=false; + _mut.unlock(); + emit somethingChanged(); +} + +void YDFXGUIRunInfo::sampleOK(int pos) +{ + _mut.lock(); + _items[pos]=1; + _mut.unlock(); + emit somethingChanged(); +} + +void YDFXGUIRunInfo::sampleKO(int pos) +{ + _mut.lock(); + _items[pos]=2; + _mut.unlock(); + emit somethingChanged(); +} + +std::vector YDFXGUIRunInfo::getItems() const +{ + std::vector ret; + _mut.lock(); + ret=_items; + _mut.unlock(); + return ret; +} + +int YDFXGUIRunInfo::getNbOfItems() const +{ + _mut.lock(); + int ret(_items.size()); + _mut.unlock(); + return ret; +} + +int YDFXGUIRunInfo::setNbOfItems(int nbOfItems) +{ + _items.resize(nbOfItems); + std::fill(_items.begin(),_items.end(),0); +} + +bool YDFXGUIRunInfo::getComputationStatus() const +{ + _mut.lock(); + bool ret(_computationInProgress); + _mut.unlock(); + return ret; +} + +///////////// + +class MyObserver : public YACSEvalObserver +{ +public: + MyObserver(YDFXGUIRunInfo *info):_info(info) { } + void startComputation(YACSEvalYFX *sender) + { + //std::cerr << " Start ! " << _info->getNbOfItems() << std::endl; + } + void notifySampleOK(YACSEvalYFX *sender, int sampleId) + { + _info->sampleOK(sampleId); + //std::cerr << "sample OK = " << sampleId << std::endl; + } + void notifySampleKO(YACSEvalYFX *sender, int sampleId) + { + _info->sampleKO(sampleId); + //std::cerr << "sample KO = " << sampleId << std::endl; + } +private: + YDFXGUIRunInfo *_info; +}; + +///////////// + +YDFXGUIRunThread::YDFXGUIRunThread(QObject *parent, YACSEvalYFXWrap *efx, YACSEvalSession *session, YDFXGUIRunInfo *info):QThread(parent),_efx(efx),_session(session),_info(info),_ret0(false),_ret1(-1) +{ + _session->setForcedPyThreadSavedStatus(true); +} + +void YDFXGUIRunThread::run() +{ + YDFXGUIPyThreadSaver::SaveContext(this); + _efx->getParams()->setStopASAPAfterErrorStatus(false); + MyObserver *obs(new MyObserver(_info)); + _efx->registerObserver(obs); + obs->decrRef(); + _ret0=_efx->run(_session,_ret1); +} + +YDFXGUIRunThread::~YDFXGUIRunThread() +{ +} + +bool YDFXGUIRunThread::getReturns(int& ret1) const +{ + ret1=_ret1; + return _ret0; +} + +///////////// + +YDFXGUIRunningButton::YDFXGUIRunningButton(QWidget *parent):QPushButton(parent) +{ + setText("Run !"); + int dummy; + YACSEvalYFXWrap *efx(getEFX()); + setEnabled(ComputeStateRes(efx,dummy) && ComputeStateSeq(efx)); + connect(this,SIGNAL(clicked()),this,SLOT(runWizardSlot())); +} + +YACSEvalYFXWrap *YDFXGUIRunningButton::getEFX() +{ + YDFXGUIRunButton *parentc(qobject_cast(parent())); + if(!parentc) + return 0; + return parentc->getEFX(); +} + +YDFXGUIRunInfo *YDFXGUIRunningButton::getInfo() +{ + YDFXGUIRunButton *parentc(qobject_cast(parent())); + if(!parentc) + return 0; + return parentc->getInfo(); +} + +YACSEvalSession *YDFXGUIRunningButton::getSess() +{ + YDFXGUIRunButton *parentc(qobject_cast(parent())); + if(!parentc) + return 0; + return parentc->getSess(); +} + +YDFXGUIRunThread *YDFXGUIRunningButton::getThread() +{ + YDFXGUIRunButton *parentc(qobject_cast(parent())); + if(!parentc) + return 0; + return parentc->getThread(); +} + +///////////// + +YDFXGUIMachineDialog::YDFXGUIMachineDialog(QWidget *parent):QDialog(parent) +{ +} + +void YDFXGUIMachineDialog::interactivityStatusChanged(bool) +{ + QSize sz1(_wid->minimumSizeHint()),sz2(_wid->sizeHint()); + QMargins marg(layout()->contentsMargins()); + int delta(marg.top()+marg.bottom()); + setMinimumHeight(sz1.height()+delta); + setMaximumHeight(sz2.height()+delta); +} + +///////////// + +void YDFXGUIRunningButton::runWizardSlot() +{ + YDFXGUIMachineDialog dial(this); + QGridLayout *mainLayout(new QGridLayout(&dial)); + YDFXGUIHostParametrizer *zeWidget(new YDFXGUIHostParametrizer(&dial,getEFX())); + dial.setWidget(zeWidget); + dial.interactivityStatusChanged(true); + connect(zeWidget,SIGNAL(interactivityChanged(bool)),&dial,SLOT(interactivityStatusChanged(bool))); + mainLayout->addWidget(zeWidget); + connect(zeWidget->getDialogButtonBox(),SIGNAL(accepted()),&dial,SLOT(accept())); + connect(zeWidget->getDialogButtonBox(),SIGNAL(rejected()),&dial,SLOT(reject())); + if(dial.exec()) + { + getEFX()->lockPortsForEvaluation(); + zeWidget->applyToEFX(); + getInfo()->setNbOfItems(getEFX()->getNbOfItems()); + runEvaluation(); + } +} + +void YDFXGUIRunningButton::runEvaluation() +{ + if(!getSess()->isLaunched()) + getSess()->launch(); + if(!PyEval_ThreadsInitialized()) + PyEval_InitThreads(); + connect(getThread(),SIGNAL(finished()),this,SLOT(evaluationFinished())); + setEnabled(false); + getThread()->start(); +} + +void YDFXGUIRunningButton::evaluationFinished() +{ + YACSEvalYFXWrap *efx(getEFX()); + int dummy; + setEnabled(ComputeStateRes(efx,dummy) && ComputeStateSeq(efx)); +} + +bool YDFXGUIRunningButton::ComputeStateRes(YACSEvalYFXWrap *efx, int& nbOfSamples) +{ + return efx->computeSequencesStatus(nbOfSamples); +} + +bool YDFXGUIRunningButton::ComputeStateSeq(YACSEvalYFXWrap *efx) +{ + bool isOKForDef(true); + try + { + efx->giveResources()->checkOKForRun(); + } + catch(YACS::Exception& e) + { + isOKForDef=false; + } + return isOKForDef; +} + +///////////////////// + +YDFXGUIRunningPB::YDFXGUIRunningPB(QWidget *parent, YDFXGUIRunInfo *info):QWidget(parent),_info(info) +{ +} + +void YDFXGUIRunningPB::paintEvent(QPaintEvent *event) +{ + const int SZ_OF_PEN_RECT=2; + QPainter painter(this); + QRect refRect(rect()); + QRect refRect2(refRect);//event->rect()); + painter.setPen(QPen(Qt::black,SZ_OF_PEN_RECT,Qt::SolidLine));//,Qt::RoundCap)); + refRect2.translate(SZ_OF_PEN_RECT,SZ_OF_PEN_RECT); + refRect2.setWidth(refRect2.width()-2*SZ_OF_PEN_RECT);; + refRect2.setHeight(refRect2.height()-2*SZ_OF_PEN_RECT); + painter.drawRect(refRect2); + // + std::vector items(_info->getItems()); + int nbOfItems(items.size()); + // + float xFact(float(refRect.width()-3.5*SZ_OF_PEN_RECT)/float(nbOfItems)); + // + QPalette pal(QApplication::palette("QPushButton")); + QColor color(pal.color(QPalette::Window)),color2; + painter.setPen(QPen(color,0)); + for(int ii=0;iigetNbOfItems()); + width=std::max(width,50); + width=std::min(width,150); + return QSize(width,15); +} + +QSize YDFXGUIRunningPB::minimumSizeHint() const +{ + int width(3*_info->getNbOfItems()); + width=std::max(width,50); + width=std::min(width,120); + return sizeHint(); +} + +///////////// + +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)) +{ + QVBoxLayout *mainLayout(new QVBoxLayout(this)); + mainLayout->addWidget(_pb); + mainLayout->addWidget(_push); + _pb->hide(); + _push->setEnabled(false); + // + connect(getThread(),SIGNAL(started()),_info,SLOT(startComputation())); + connect(getThread(),SIGNAL(finished()),_info,SLOT(endComputation())); + // + connect(_info,SIGNAL(somethingChanged()),this,SLOT(update())); + connect(_info,SIGNAL(somethingChanged()),_pb,SLOT(update())); +} + +QSize YDFXGUIRunButton::sizeHint() const +{ + QSize sz,sz2(QWidget::sizeHint()); + if(_info->getComputationStatus()) + sz=_pb->sizeHint(); + else + sz=_push->sizeHint(); + sz.rwidth()+=sz2.rwidth(); + sz.rheight()+=sz2.rheight(); + return sz; +} + +QSize YDFXGUIRunButton::minimumSizeHint() const +{ + QSize sz,sz2(QWidget::minimumSizeHint()); + if(_info->getComputationStatus()) + sz=_pb->minimumSizeHint(); + else + sz=_push->minimumSizeHint(); + sz.rwidth()+=sz2.rwidth(); + sz.rheight()+=sz2.rheight(); + return sz; +} + +void YDFXGUIRunButton::update() +{ + bool stat(_info->getComputationStatus()); + _pb->setVisible(stat); + _push->setHidden(stat); + QWidget::update(); +} + +void YDFXGUIRunButton::setEnabled(bool status) +{ + _push->setEnabled(status); + QWidget::setEnabled(status); +} + +void YDFXGUIRunButton::setDisabled(bool status) +{ + _push->setDisabled(status); + QWidget::setEnabled(status); +} diff --git a/src/ydfx_gui/YDFXGUIPushButtons.hxx b/src/ydfx_gui/YDFXGUIPushButtons.hxx new file mode 100644 index 000000000..68e4f79cd --- /dev/null +++ b/src/ydfx_gui/YDFXGUIPushButtons.hxx @@ -0,0 +1,177 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#ifndef __YDFXGUIPUSHBUTTONS_HXX__ +#define __YDFXGUIPUSHBUTTONS_HXX__ + +#include "ydfxwidgetsExport.hxx" + +#include +#include +#include +#include +#include + +class YACSEvalSession; +class YACSEvalYFXWrap; +class YDFXGUIAllPorts; + +class YDFXGUIPushButton1 : public QPushButton +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIPushButton1(QWidget *parent, YACSEvalYFXWrap *efx, YDFXGUIAllPorts *ports); +protected: + YACSEvalYFXWrap *_efx; + YDFXGUIAllPorts *_ports; +}; + +class YDFXGUIResourcePushButton : public YDFXGUIPushButton1 +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIResourcePushButton(QWidget *parent, YACSEvalYFXWrap *efx, YDFXGUIAllPorts *ports); +public slots: + void resourceAssignmentRequested(); +private: + QSettings _settings; +}; + +class YDFXGUISeqInitButton : public YDFXGUIPushButton1 +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUISeqInitButton(QWidget *parent, YACSEvalYFXWrap *efx, YDFXGUIAllPorts *ports); +public slots: + void sequenceInitRequested(); +signals: + void sequenceWellDefined(bool); +private: + QMap _state; +}; + +class YDFXGUIMachineDialog : public QDialog +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIMachineDialog(QWidget *wid); + YDFXWIDGETS_EXPORT void setWidget(QWidget *wid) { _wid=wid; } +public slots: + void interactivityStatusChanged(bool newStatus); +private: + QWidget *_wid; +}; + +class YDFXGUIRunInfo : public QObject +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIRunInfo(QObject *parent, int nbOfItems); + YDFXWIDGETS_EXPORT std::vector getItems() const; + YDFXWIDGETS_EXPORT int getNbOfItems() const; + YDFXWIDGETS_EXPORT int setNbOfItems(int nbOfItems); + YDFXWIDGETS_EXPORT bool getComputationStatus() const; +public slots: + YDFXWIDGETS_EXPORT void startComputation(); + YDFXWIDGETS_EXPORT void endComputation(); + YDFXWIDGETS_EXPORT void sampleOK(int); + YDFXWIDGETS_EXPORT void sampleKO(int); +signals: + void somethingChanged(); +private: + bool _computationInProgress; + std::vector _items; + mutable QMutex _mut; +}; + +class YDFXGUIRunThread : public QThread +{ +public: + YDFXWIDGETS_EXPORT YDFXGUIRunThread(QObject *parent, YACSEvalYFXWrap *efx, YACSEvalSession *session, YDFXGUIRunInfo *info); + YDFXWIDGETS_EXPORT ~YDFXGUIRunThread(); + YDFXWIDGETS_EXPORT bool getReturns(int& ret1) const; + YDFXWIDGETS_EXPORT YACSEvalYFXWrap *getEFX() const { return _efx; } + YDFXWIDGETS_EXPORT YACSEvalSession *getSess() const { return _session; } +public: + YDFXWIDGETS_EXPORT void run(); +private: + YACSEvalYFXWrap *_efx; + YACSEvalSession *_session; + YDFXGUIRunInfo *_info; + bool _ret0; + int _ret1; +}; + +class YDFXGUIRunningButton : public QPushButton +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIRunningButton(QWidget *parent); + YDFXWIDGETS_EXPORT YACSEvalYFXWrap *getEFX(); + YDFXWIDGETS_EXPORT YDFXGUIRunInfo *getInfo(); + YDFXWIDGETS_EXPORT YACSEvalSession *getSess(); + YDFXWIDGETS_EXPORT YDFXGUIRunThread *getThread(); +public slots: + YDFXWIDGETS_EXPORT void runWizardSlot(); + YDFXWIDGETS_EXPORT void evaluationFinished(); +private: + void runEvaluation(); +private: + static bool ComputeStateRes(YACSEvalYFXWrap *efx, int& nbOfSamples); + static bool ComputeStateSeq(YACSEvalYFXWrap *efx); +}; + +class YDFXGUIRunningPB : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIRunningPB(QWidget *parent, YDFXGUIRunInfo *info); + YDFXWIDGETS_EXPORT void startComputation(); + YDFXWIDGETS_EXPORT void paintEvent(QPaintEvent *event); + YDFXWIDGETS_EXPORT QSize sizeHint() const; + YDFXWIDGETS_EXPORT QSize minimumSizeHint() const; +private: + YDFXGUIRunInfo *_info; +}; + +class YDFXGUIRunButton : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIRunButton(QWidget *parent, YACSEvalSession *session, YACSEvalYFXWrap *efx); + YDFXWIDGETS_EXPORT QSize sizeHint() const; + YDFXWIDGETS_EXPORT QSize minimumSizeHint() const; + YDFXWIDGETS_EXPORT YACSEvalYFXWrap *getEFX() { return _th->getEFX(); } + YDFXWIDGETS_EXPORT YDFXGUIRunInfo *getInfo() { return _info; } + YDFXWIDGETS_EXPORT YACSEvalSession *getSess() { return _th->getSess(); } + YDFXWIDGETS_EXPORT YDFXGUIRunThread *getThread() { return _th; } + YDFXWIDGETS_EXPORT YDFXGUIRunningButton *getPush() { return _push; } +public slots: + YDFXWIDGETS_EXPORT void update(); + YDFXWIDGETS_EXPORT void setEnabled(bool); + YDFXWIDGETS_EXPORT void setDisabled(bool); +private: + YDFXGUIRunInfo *_info; + YDFXGUIRunThread *_th; + YDFXGUIRunningButton *_push; + YDFXGUIRunningPB *_pb; +}; + +#endif diff --git a/src/ydfx_gui/YDFXGUIPyThreadSaver.cxx b/src/ydfx_gui/YDFXGUIPyThreadSaver.cxx new file mode 100644 index 000000000..3bd728be5 --- /dev/null +++ b/src/ydfx_gui/YDFXGUIPyThreadSaver.cxx @@ -0,0 +1,40 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#include "YDFXGUIPyThreadSaver.hxx" + +PyThreadState *YDFXGUIPyThreadSaver::_save=0; + +QThread *YDFXGUIPyThreadSaver::_cppThread=0; + +void YDFXGUIPyThreadSaver::SetDefault(QThread *th) +{ + _cppThread=th; +} + +void YDFXGUIPyThreadSaver::SaveContext(QThread *th) +{ + if(_cppThread==th) + return ; + if(_save) + PyEval_RestoreThread(_save); + _save=PyEval_SaveThread(); + _cppThread=th; +} diff --git a/src/ydfx_gui/YDFXGUIPyThreadSaver.hxx b/src/ydfx_gui/YDFXGUIPyThreadSaver.hxx new file mode 100644 index 000000000..d10ee7c67 --- /dev/null +++ b/src/ydfx_gui/YDFXGUIPyThreadSaver.hxx @@ -0,0 +1,40 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#ifndef __YDFXGUIPYTHREADSAVER_HXX__ +#define __YDFXGUIPYTHREADSAVER_HXX__ + +#include "ydfxwidgetsExport.hxx" + +#include "Python.h" + +class QThread; + +class YDFXGUIPyThreadSaver +{ +public: + YDFXWIDGETS_EXPORT static void SetDefault(QThread *th); + YDFXWIDGETS_EXPORT static void SaveContext(QThread *th); +private: + static PyThreadState *_save; + static QThread *_cppThread; +}; + +#endif diff --git a/src/ydfx_gui/YDFXGUISeqInit.cxx b/src/ydfx_gui/YDFXGUISeqInit.cxx new file mode 100644 index 000000000..500ec1ad3 --- /dev/null +++ b/src/ydfx_gui/YDFXGUISeqInit.cxx @@ -0,0 +1,628 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#include "YDFXGUISeqInit.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Python.h" + +#include "AutoGIL.hxx" + +#include "YDFXGUIWrap.hxx" +#include "YDFXGUIPyThreadSaver.hxx" + +#include "YACSEvalPort.hxx" +#include "YACSEvalSeqAny.hxx" + +#include +#include + +const char YDFXGUIStatus::OK_STR[]="OK !"; + +class AutoPyRef +{ +public: + AutoPyRef(PyObject *pyobj=0):_pyobj(pyobj) { } + ~AutoPyRef() { release(); } + AutoPyRef(const AutoPyRef& other):_pyobj(other._pyobj) { if(_pyobj) Py_XINCREF(_pyobj); } + AutoPyRef& operator=(const AutoPyRef& other) { if(_pyobj==other._pyobj) return *this; release(); _pyobj=other._pyobj; Py_XINCREF(_pyobj); return *this; } + operator PyObject *() { return _pyobj; } + void set(PyObject *pyobj) { if(pyobj==_pyobj) return ; release(); _pyobj=pyobj; } + PyObject *get() { return _pyobj; } + bool isNull() const { return _pyobj==0; } + PyObject *retn() { if(_pyobj) Py_XINCREF(_pyobj); return _pyobj; } +private: + void release() { if(_pyobj) Py_XDECREF(_pyobj); _pyobj=0; } +private: + PyObject *_pyobj; +}; + +//////////////////////////// + +void YDFXGUIDoubleVectHolder::applyOnInput(YACSEvalInputPort *inp) const +{ + YACSEvalSeqAny *val(new YACSEvalSeqAnyDouble(_vect)); + inp->setSequenceOfValuesToEval(val); + delete val; +} + +//////////////////////////// + +YDFXGUISeqSetterP::YDFXGUISeqSetterP(QWidget *parent):QPushButton(parent),_isIn(false) +{ + setText("Open..."); + connect(this,SIGNAL(clicked()),this,SLOT(selectAFile())); +} + +void YDFXGUISeqSetterP::loadState(const QString& state) +{ + _fileName=state; + setToolTip(_fileName); +} + +QString YDFXGUISeqSetterP::saveState() const +{ + return _fileName; +} + +bool YDFXGUISeqSetterP::executeScript(int& sz) +{ + QObject *zeBoss(parent()->parent()); + YDFXGUISeqLine *zeBossc(qobject_cast(zeBoss)); + if(!zeBossc) + return false; + // + if(_fileName.isEmpty()) + { + emit problemDetected(QString("For \"%1\" : no file defined !").arg(zeBossc->getName())); + return false; + } + QFile file(_fileName); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return false; + int i=0; + _vect.clear(); + while(!file.atEnd()) + { + QByteArray line(file.readLine()); + QString line2(line.data()); + bool isOK(false); + double v(line2.toDouble(&isOK)); + if(!isOK) + { + emit problemDetected(QString("For \"%1\" : At line %2 it is not a float !").arg(zeBossc->getName()).arg(i)); + return false; + } + _vect.push_back(v); + i++; + } + sz=_vect.size(); + return true; +} + +void YDFXGUISeqSetterP::enterEvent(QEvent *event) +{ + _isIn=true; + update(); +} + +void YDFXGUISeqSetterP::leaveEvent(QEvent *event) +{ + _isIn=false; + update(); +} + +void YDFXGUISeqSetterP::paintEvent(QPaintEvent *event) +{ + if(_isIn || _fileName.isEmpty()) + { + QPushButton::paintEvent(event); + return ; + } + QFileInfo fi(_fileName); + QString txt(fi.fileName()); + QRect refRect(rect()); + QFont ft(font()); + QFontMetrics fm(ft); + QSize refRect2(fm.boundingRect(txt).size()); + // + QPainter painter(this); + painter.drawText(QPoint((refRect.width()-refRect2.width())/2, + refRect.height()/2+refRect2.height()/2-fm.descent()),txt); +} + +void YDFXGUISeqSetterP::selectAFile() +{ + QFileDialog fd(this,QString("Select a file containing list of floats.")); + fd.setFileMode(QFileDialog::ExistingFile); + if(fd.exec()) + { + QStringList files(fd.selectedFiles()); + if(files.size()>=1) + { + _fileName=files[0]; + } + setToolTip(_fileName); + update(); + } +} + +//////////////////////////// + +void YDFXGUISeqSetterT::loadState(const QString& state) +{ + setText(state); +} + +QString YDFXGUISeqSetterT::saveState() const +{ + return toPlainText(); +} + +bool YDFXGUISeqSetterT::executeScript(int& sz) +{ + QObject *zeBoss(parent()->parent()); + YDFXGUISeqLine *zeBossc(qobject_cast(zeBoss)); + if(!zeBossc) + return false; + // + std::string name(zeBossc->getName().toStdString()); + // + static const char TMP_FILENAME[]="/tmp/TMP"; + std::string txt(toPlainText().toStdString()); + YDFXGUIPyThreadSaver::SaveContext(QApplication::instance()->thread()); + { + YACS::ENGINE::AutoGIL gal; + AutoPyRef code(Py_CompileString(txt.c_str(),TMP_FILENAME, Py_file_input)); + if(code.get() == NULL) + { + emit problemDetected(QString("For \"%1\" : python code is invalid !").arg(zeBossc->getName())); + return false; + } + AutoPyRef context(PyDict_New()); + PyDict_SetItemString( context, "__builtins__", PyEval_GetBuiltins() ); + AutoPyRef res(PyEval_EvalCode((PyCodeObject *)code.get(), context, context)); + PyObject *item(PyDict_GetItemString(context,name.c_str())); + // + if(!item) + { + emit problemDetected(QString("For \"%1\" : Py var %1 is not defined !").arg(zeBossc->getName())); + return false; + } + if(!PyList_Check(item)) + { + emit problemDetected(QString("For \"%1\" : Py var %1 must be a list !").arg(zeBossc->getName())); + return false; + } + sz=PyList_Size(item); + _vect.clear() ; _vect.resize(sz); + for(int i=0;igetName()).arg(i)); + return false; + } + _vect[i]=PyFloat_AS_DOUBLE(val); + } + } + return true; +} + +//////////////////////////// + +YDFXGUICombo::YDFXGUICombo(QWidget *parent):QComboBox(parent),_isIn(false) +{ + setFocusPolicy(Qt::TabFocus); +} + +QString YDFXGUICombo::getName() +{ + QString ret; + YDFXGUISeqLine *parentc(qobject_cast(parent())); + if(parentc) + ret=parentc->getName(); + return ret; +} + +void YDFXGUICombo::enterEvent(QEvent *event) +{ + _isIn=true; + update(); +} + +void YDFXGUICombo::leaveEvent(QEvent *event) +{ + _isIn=false; + update(); +} + +void YDFXGUICombo::paintEvent(QPaintEvent *event) +{ + if(_isIn) + { + QComboBox::paintEvent(event); + return ; + } + QRect refRect(rect()); + QFont ft(font()); + ft.setBold(true); + QFontMetrics fm(ft); + QSize refRect2(fm.boundingRect(getName()).size()); + QPainter painter(this); + painter.setFont(ft); + QPen pen(painter.pen()); + pen.setColor(Qt::red); + painter.setPen(pen); + painter.drawText(QPoint((refRect.width()-refRect2.width())/2,refRect.height()/2+refRect2.height()/2-fm.descent()),getName()); +} + +//////////////////////////// + +YDFXGUISeqSetter::YDFXGUISeqSetter(QWidget *parent, const QString& name):QWidget(parent),_textEdit(0),_push(0),_curType(0) +{ + QVBoxLayout *verticalLayout(new QVBoxLayout(this)); + _textEdit=new YDFXGUISeqSetterT(this); verticalLayout->addWidget(_textEdit); + _push=new YDFXGUISeqSetterP(this); verticalLayout->addWidget(_push); + _textEdit->setText(QString("import math\n%1=[math.sqrt(float(elt)+0.) for elt in xrange(4)]").arg(name)); + _textEdit->hide(); + _push->hide(); +} + +int YDFXGUISeqSetter::loadState(const QString& state) +{ + if(state.isEmpty() || state.size()<3) + return 0; + QString sw(state.mid(0,3)); + if(sw=="@0@") + { + _push->loadState(state.mid(3)); + return 0; + } + if(sw=="@1@") + { + + _textEdit->loadState(state.mid(3)); + return 1; + } + return 0; +} + +QString YDFXGUISeqSetter::saveState() const +{ + YDFXGUISeqLine *parentc(qobject_cast(parent())); + if(!parentc) + return QString(); + int pos(parentc->getPositionOfCombo()); + if(pos==0) + { + QString ret("@0@"); + ret+=_push->saveState(); + return ret; + } + if(pos==1) + { + QString ret("@1@"); + ret+=_textEdit->saveState(); + return ret; + } + return QString(); +} + +QSize YDFXGUISeqSetter::sizeHint() const +{ + QSize sz,sz2(QWidget::sizeHint()); + if(_curType==0) + sz=_push->sizeHint(); + else + sz=_textEdit->sizeHint(); + sz.rwidth()+=sz2.rwidth(); + sz.rheight()+=sz2.rheight(); + return sz; +} + +QSize YDFXGUISeqSetter::minimumSizeHint() const +{ + QSize sz,sz2(QWidget::minimumSizeHint()); + if(_curType==0) + sz=_push->minimumSizeHint(); + else + sz=_textEdit->minimumSizeHint(); + sz.rwidth()+=sz2.rwidth(); + sz.rheight()+=sz2.rheight(); + return sz; +} + +bool YDFXGUISeqSetter::checkOK(int& sz) +{ + if(_curType==0) + return _push->executeScript(sz); + else + return _textEdit->executeScript(sz); +} + +void YDFXGUISeqSetter::applyOnInput(YACSEvalInputPort *inp) +{ + if(_curType==0) + _push->applyOnInput(inp); + else + _textEdit->applyOnInput(inp); +} + +void YDFXGUISeqSetter::typeOfAssignmentChanged(int newType) +{ + _curType=newType; + if(newType==0) + { + _textEdit->hide(); + _push->show(); + disconnect(_textEdit,SIGNAL(problemDetected(const QString&)),this,SIGNAL(problemDetected(const QString&))); + connect(_push,SIGNAL(problemDetected(const QString&)),this,SIGNAL(problemDetected(const QString&))); + } + else + { + _textEdit->show(); + _push->hide(); + disconnect(_push,SIGNAL(problemDetected(const QString&)),this,SIGNAL(problemDetected(const QString&))); + connect(_textEdit,SIGNAL(problemDetected(const QString&)),this,SIGNAL(problemDetected(const QString&))); + } +} + +//////////////////////////// + +YDFXGUISeqLine::YDFXGUISeqLine(QWidget *parent, YACSEvalInputPort *inp):_combo(0),_setter(0),_inp(inp) +{ + QHBoxLayout *horizontalLayout(new QHBoxLayout(this)); + _combo=new YDFXGUICombo(this); + _combo->insertItem(0,QString("%1 from file").arg(getName())); + _combo->insertItem(1,QString("%1 from PyScript").arg(getName())); + horizontalLayout->addWidget(_combo); + _setter=new YDFXGUISeqSetter(this,getName()); + connect(_combo,SIGNAL(currentIndexChanged(int)),this,SLOT(typeOfAssignmentChanged(int))); + horizontalLayout->addWidget(_setter); + _combo->setCurrentIndex(0); + emit _combo->currentIndexChanged(0);//to be sure to sync widgets +} + +void YDFXGUISeqLine::loadState(const QMap& state) +{ + QString name(getName()); + QMap::const_iterator it(state.find(name)); + if(it==state.end()) + return ; + int pos(_setter->loadState(it.value())); + _combo->setCurrentIndex(pos); +} + +void YDFXGUISeqLine::saveState(QMap& state) const +{ + state[getName()]=_setter->saveState(); +} + +QString YDFXGUISeqLine::getName() const +{ + return QString(_inp->getName().c_str()); +} + +int YDFXGUISeqLine::getPositionOfCombo() const +{ + return _combo->currentIndex(); +} + +bool YDFXGUISeqLine::checkOK(int& sz) +{ + return _setter->checkOK(sz); +} + +void YDFXGUISeqLine::connectToStatus(YDFXGUIStatus *status) +{ + connect(_setter,SIGNAL(problemDetected(const QString&)),status,SLOT(displayInfo(const QString&))); +} + +void YDFXGUISeqLine::applyOnInput() +{ + _setter->applyOnInput(_inp); +} + +void YDFXGUISeqLine::typeOfAssignmentChanged(int newType) +{ + _setter->typeOfAssignmentChanged(newType); + _setter->updateGeometry(); + _setter->update(); +} + +//////////////////////////// + +YDFXGUIStatus::YDFXGUIStatus(QWidget *parent):QWidget(parent) +{ +} + +void YDFXGUIStatus::paintEvent(QPaintEvent *event) +{ + QRect refRect(rect()); + QFont ft(font()); + QFontMetrics fm(ft); + QSize refRect2(fm.boundingRect(_text).size()); + // + QPainter painter(this); + QPen pen(painter.pen()); + pen.setColor(_text==OK_STR?Qt::green:Qt::red); + painter.setPen(pen); + painter.drawText(QPoint((refRect.width()-refRect2.width())/2, + refRect.height()/2+refRect2.height()/2-fm.descent()),_text); +} + +QSize YDFXGUIStatus::sizeHint() const +{ + QFont ft(font()); + QFontMetrics fm(ft); + QSize ret(fm.boundingRect(_text).size()); + return ret; +} + +QSize YDFXGUIStatus::minimumSizeHint() const +{ + return sizeHint(); +} + +void YDFXGUIStatus::declareOK(bool isOK) +{ + if(!isOK) + return ; + _text=OK_STR; + updateGeometry(); + update(); +} + +void YDFXGUIStatus::displayInfo(const QString& txt) +{ + _text=txt; + updateGeometry(); + update(); +} + +//////////////////////////// + +YDFXGUISeqInitEff::YDFXGUISeqInitEff(QWidget *parent, YACSEvalYFXWrap *efx):QWidget(parent) +{ + QVBoxLayout *verticalLayout(new QVBoxLayout(this)); + std::vector< YACSEvalInputPort * > inputs(efx->getFreeInputPorts()); + foreach(YACSEvalInputPort *input,inputs) + { + if(!input->isRandomVar()) + continue; + YDFXGUISeqLine *line(new YDFXGUISeqLine(this,input)); + verticalLayout->addWidget(line); + _lines.push_back(line); + } +} + +void YDFXGUISeqInitEff::loadState(const QMap& state) +{ + foreach(YDFXGUISeqLine *line,_lines) + line->loadState(state); +} + +QMap YDFXGUISeqInitEff::saveState() const +{ + QMap ret; + foreach(YDFXGUISeqLine *line,_lines) + line->saveState(ret); + return ret; +} + +void YDFXGUISeqInitEff::connectToStatus(YDFXGUIStatus *status) +{ + foreach(YDFXGUISeqLine *line,_lines) + { + line->connectToStatus(status); + } +} + +void YDFXGUISeqInitEff::assignButtonClicked() +{ + int sz; + bool verdict(checkConsistency(sz)); + emit configurationIsOK(verdict); +} + +void YDFXGUISeqInitEff::applyOnEFX() +{ + foreach(YDFXGUISeqLine *line,_lines) + line->applyOnInput(); +} + +bool YDFXGUISeqInitEff::checkConsistency(int& sz) +{ + int refSz(std::numeric_limits::max()); + foreach(YDFXGUISeqLine *line,_lines) + { + int locSz; + if(!line->checkOK(locSz)) + return false; + if(refSz==std::numeric_limits::max()) + refSz=locSz; + if(locSz!=refSz) + { + emit line->setter()->problemDetected(QString("Var %1 does not have the same number of elts than others !").arg(line->getName())); + return false; + } + } + sz=refSz; + return true; +} + +//////////////////////////// + +YDFXGUISeqInit::YDFXGUISeqInit(QWidget *parent, YACSEvalYFXWrap *efx):QWidget(parent),_zeWidget(0) +{ + QVBoxLayout *verticalLayout(new QVBoxLayout(this)); + QFrame *frame(new QFrame(this)); + frame->setFrameStyle(QFrame::Panel | QFrame::Sunken); + verticalLayout->addWidget(frame); + QHBoxLayout *horizontalLayout2(new QHBoxLayout(frame)); + QScrollArea *sa(new QScrollArea(frame)); + horizontalLayout2->addWidget(sa); + _zeWidget=new YDFXGUISeqInitEff(sa,efx); + sa->setWidgetResizable(true); + sa->setWidget(_zeWidget); + // + QHBoxLayout *horizontalLayout(new QHBoxLayout); + QSpacerItem *si(new QSpacerItem(40,20,QSizePolicy::Expanding,QSizePolicy::Minimum)); + YDFXGUIStatus *statusInfo(new YDFXGUIStatus(this)); + _zeWidget->connectToStatus(statusInfo); + connect(_zeWidget,SIGNAL(configurationIsOK(bool)),statusInfo,SLOT(declareOK(bool))); + QPushButton *button(new QPushButton(this)); + button->setText("Check"); + QPushButton *button2(new QPushButton(this)); + button2->setText("Assign !"); + connect(_zeWidget,SIGNAL(configurationIsOK(bool)),button2,SLOT(setEnabled(bool))); + connect(button2,SIGNAL(clicked(bool)),_zeWidget,SLOT(applyOnEFX())); + connect(button2,SIGNAL(clicked(bool)),this,SIGNAL(assignButtonClicked())); + horizontalLayout->addWidget(statusInfo); + horizontalLayout->addItem(si); + horizontalLayout->addWidget(button); + horizontalLayout->addWidget(button2); + connect(button,SIGNAL(pressed()),_zeWidget,SLOT(assignButtonClicked())); + button2->setEnabled(false); + // + verticalLayout->addLayout(horizontalLayout); +} + +void YDFXGUISeqInit::loadState(const QMap& state) +{ + _zeWidget->loadState(state); +} + +QMap YDFXGUISeqInit::saveState() const +{ + return _zeWidget->saveState(); +} diff --git a/src/ydfx_gui/YDFXGUISeqInit.hxx b/src/ydfx_gui/YDFXGUISeqInit.hxx new file mode 100644 index 000000000..24acc35ff --- /dev/null +++ b/src/ydfx_gui/YDFXGUISeqInit.hxx @@ -0,0 +1,187 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#ifndef __YDFXGUISEQINIT_HXX__ +#define __YDFXGUISEQINIT_HXX__ + +#include "ydfxwidgetsExport.hxx" + +#include +#include +#include +#include + +#include + +class QTextEdit; +class QComboBox; +class QPushButton; + +class YACSEvalYFXWrap; +class YACSEvalInputPort; + +class YDFXGUIDoubleVectHolder +{ +public: + YDFXWIDGETS_EXPORT YDFXGUIDoubleVectHolder() { } + YDFXWIDGETS_EXPORT virtual bool executeScript(int& sz) = 0; + YDFXWIDGETS_EXPORT void applyOnInput(YACSEvalInputPort *inp) const; +protected: + std::vector _vect; +}; + +class YDFXGUISeqSetterP : public QPushButton, public YDFXGUIDoubleVectHolder +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUISeqSetterP(QWidget *parent=0); + YDFXWIDGETS_EXPORT void loadState(const QString& state); + YDFXWIDGETS_EXPORT QString saveState() const; + YDFXWIDGETS_EXPORT bool executeScript(int& sz); + YDFXWIDGETS_EXPORT void enterEvent(QEvent *event); + YDFXWIDGETS_EXPORT void leaveEvent(QEvent *event); + YDFXWIDGETS_EXPORT void paintEvent(QPaintEvent *event); +public slots: + YDFXWIDGETS_EXPORT void selectAFile(); +signals: + void problemDetected(const QString& msg); +private: + bool _isIn; + QString _fileName; +}; + +class YDFXGUISeqSetterT : public QTextEdit, public YDFXGUIDoubleVectHolder +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUISeqSetterT(QWidget *parent=0):QTextEdit(parent) { } + YDFXWIDGETS_EXPORT void loadState(const QString& state); + YDFXWIDGETS_EXPORT QString saveState() const; + YDFXWIDGETS_EXPORT bool executeScript(int& sz); +signals: + void problemDetected(const QString& msg); +}; + +class YDFXGUICombo : public QComboBox +{ +public: + YDFXWIDGETS_EXPORT YDFXGUICombo(QWidget *parent); + YDFXWIDGETS_EXPORT QString getName(); + YDFXWIDGETS_EXPORT void enterEvent(QEvent *event); + YDFXWIDGETS_EXPORT void leaveEvent(QEvent *event); + YDFXWIDGETS_EXPORT void paintEvent(QPaintEvent *event); +private: + bool _isIn; +}; + +class YDFXGUISeqSetter : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUISeqSetter(QWidget *parent, const QString& name); + YDFXWIDGETS_EXPORT int loadState(const QString& state); + YDFXWIDGETS_EXPORT QString saveState() const; + YDFXWIDGETS_EXPORT QSize sizeHint() const; + YDFXWIDGETS_EXPORT QSize minimumSizeHint() const; + YDFXWIDGETS_EXPORT bool checkOK(int& sz); + YDFXWIDGETS_EXPORT void applyOnInput(YACSEvalInputPort *inp); +public: + YDFXWIDGETS_EXPORT void typeOfAssignmentChanged(int newType); +signals: + void problemDetected(const QString& msg); +private: + YDFXGUISeqSetterT *_textEdit; + YDFXGUISeqSetterP *_push; + int _curType; +}; + +class YDFXGUIStatus; + +class YDFXGUISeqLine : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUISeqLine(QWidget *parent, YACSEvalInputPort *inp); + YDFXWIDGETS_EXPORT void loadState(const QMap& state); + YDFXWIDGETS_EXPORT void saveState(QMap& state) const; + YDFXWIDGETS_EXPORT QString getName() const; + YDFXWIDGETS_EXPORT int getPositionOfCombo() const; + YDFXWIDGETS_EXPORT bool checkOK(int& sz); + YDFXWIDGETS_EXPORT void connectToStatus(YDFXGUIStatus *status); + YDFXWIDGETS_EXPORT YDFXGUISeqSetter *setter() { return _setter; } + YDFXWIDGETS_EXPORT void applyOnInput(); +public slots: + void typeOfAssignmentChanged(int newType); +private: + YDFXGUICombo *_combo; + YDFXGUISeqSetter *_setter; + YACSEvalInputPort *_inp; +}; + +class YDFXGUIStatus : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUIStatus(QWidget *parent); + YDFXWIDGETS_EXPORT void paintEvent(QPaintEvent *event); + YDFXWIDGETS_EXPORT QSize sizeHint() const; + YDFXWIDGETS_EXPORT QSize minimumSizeHint() const; +public slots: + YDFXWIDGETS_EXPORT void declareOK(bool); + YDFXWIDGETS_EXPORT void displayInfo(const QString& txt); +public: + static const char OK_STR[]; +private: + QString _text; +}; + +class YDFXGUISeqInitEff : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUISeqInitEff(QWidget *parent, YACSEvalYFXWrap *efx); + YDFXWIDGETS_EXPORT void loadState(const QMap& state); + YDFXWIDGETS_EXPORT QMap saveState() const; + YDFXWIDGETS_EXPORT void connectToStatus(YDFXGUIStatus *status); +public slots: + YDFXWIDGETS_EXPORT void assignButtonClicked(); + YDFXWIDGETS_EXPORT void applyOnEFX(); +signals: + void configurationIsOK(bool); +private: + bool checkConsistency(int& sz); +private: + std::vector _lines; +}; + +class YDFXGUISeqInit : public QWidget +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YDFXGUISeqInit(QWidget *parent, YACSEvalYFXWrap *efx); + YDFXWIDGETS_EXPORT void loadState(const QMap& state); + YDFXWIDGETS_EXPORT QMap saveState() const; +signals: + void assignButtonClicked(); +private: + YDFXGUISeqInitEff *_zeWidget; +}; + +#endif diff --git a/src/ydfx_gui/YDFXGUIWrap.cxx b/src/ydfx_gui/YDFXGUIWrap.cxx new file mode 100644 index 000000000..6c85bf55a --- /dev/null +++ b/src/ydfx_gui/YDFXGUIWrap.cxx @@ -0,0 +1,175 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#include "YDFXGUIWrap.hxx" + +#include "YACSEvalYFX.hxx" +#include "YACSEvalPort.hxx" +#include "YACSEvalSeqAny.hxx" + +#include + +std::vector< YACSEvalInputPort * > YACSEvalYFXWrap::getFreeInputPorts() const +{ + return _efx->getFreeInputPorts(); +} + +std::vector< YACSEvalOutputPort * > YACSEvalYFXWrap::getFreeOutputPorts() const +{ + return _efx->getFreeOutputPorts(); +} + +YACSEvalExecParams *YACSEvalYFXWrap::getParams() const +{ + return _efx->getParams(); +} + +bool YACSEvalYFXWrap::isLocked() const +{ + return _efx->isLocked(); +} + +YACSEvalListOfResources *YACSEvalYFXWrap::giveResources() +{ + return _efx->giveResources(); +} + +class AutoRunningDeclarator +{ +public: + AutoRunningDeclarator(YACSEvalYFXWrap *wrap):_wrap(wrap) { _wrap->setRunningStatus(true); } + ~AutoRunningDeclarator() { _wrap->setRunningStatus(false); } +private: + YACSEvalYFXWrap *_wrap; +}; + +bool YACSEvalYFXWrap::run(YACSEvalSession *session, int& nbOfBranches) +{ + AutoRunningDeclarator ard(this); + return _efx->run(session,nbOfBranches); +} + +void YACSEvalYFXWrap::registerObserver(YACSEvalObserver *observer) +{ + _efx->registerObserver(observer); +} + +void YACSEvalYFXWrap::unlockAll() +{ + _efx->unlockAll(); + emit lockSignal(false); +} + +void YACSEvalYFXWrap::lockPortsForEvaluation() +{ + bool lockedOrNot(isLocked()); + std::vector< YACSEvalInputPort * > inps(getFreeInputPorts()),inps2; + foreach(YACSEvalInputPort *inp,inps) + { + if(inp->isRandomVar()) + inps2.push_back(inp); + } + std::vector< YACSEvalOutputPort * > outps(getFreeOutputPorts()),outps2; + foreach(YACSEvalOutputPort *outp,outps) + { + if(outp->isQOfInterest()) + outps2.push_back(outp); + } + if(lockedOrNot) + _efx->unlockAll(); + _efx->lockPortsForEvaluation(inps2,outps2); + _efx->giveResources();//do not remove this line to generate resource info + if(!lockedOrNot) + emit lockSignal(true); +} + +int YACSEvalYFXWrap::getNbOfItems() const +{ + std::vector< YACSEvalInputPort * > inps(getFreeInputPorts()); + int nbOfRandom(0),refSz(std::numeric_limits::max()); + foreach(YACSEvalInputPort *inp,inps) + { + if(!inp->isRandomVar()) + continue; + YACSEvalSeqAny *seq(inp->getSequenceOfValuesToEval()); + if(!seq) + return 0; + if(nbOfRandom==0) + refSz=seq->size(); + if(refSz!=seq->size()) + return 0; + nbOfRandom++; + } + if(nbOfRandom==0) + return 0; + return refSz; +} + +void lockPortsForEvaluation(const std::vector< YACSEvalInputPort * >& inputsOfInterest, const std::vector< YACSEvalOutputPort * >& outputsOfInterest); + +YACSEvalYFXWrap::~YACSEvalYFXWrap() +{ + delete _efx; +} + +void YACSEvalYFXWrap::setRunningStatus(bool status) +{ + if(_isRunning!=status) + emit runSignal(status); + _isRunning=status; +} + +void YACSEvalYFXWrap::updateSequencesStatus() +{ + int nbOfVals; + bool newStatus(computeSequencesStatus(nbOfVals)); + if(_isSeqOfValsSet!=newStatus) + { + _isSeqOfValsSet=newStatus; + emit sequencesAreSetSignal(_isSeqOfValsSet); + } +} + +bool YACSEvalYFXWrap::computeSequencesStatus(int& nbOfVals) +{ + std::vector< YACSEvalInputPort * > inputs(_efx->getFreeInputPorts()); + std::size_t sz(0),nbOfRandomVars(0); + foreach(YACSEvalInputPort *input,inputs) + { + if(!input->isRandomVar()) + continue; + nbOfRandomVars++; + if(!input->hasSequenceOfValuesToEval()) + return false; + YACSEvalSeqAny *seq(input->getSequenceOfValuesToEval()); + sz=seq->size(); + } + if(nbOfRandomVars==0 || sz==0) + return false; + foreach(YACSEvalInputPort *input,inputs) + { + if(!input->isRandomVar()) + continue; + if(sz!=input->getSequenceOfValuesToEval()->size()) + return false; + } + nbOfVals=sz; + return true; +} diff --git a/src/ydfx_gui/YDFXGUIWrap.hxx b/src/ydfx_gui/YDFXGUIWrap.hxx new file mode 100644 index 000000000..736bd0fc3 --- /dev/null +++ b/src/ydfx_gui/YDFXGUIWrap.hxx @@ -0,0 +1,69 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#ifndef __YDFXGUIWRAP_HXX__ +#define __YDFXGUIWRAP_HXX__ + +#include "ydfxwidgetsExport.hxx" + +#include + +class YACSEvalYFX; +class YACSEvalSession; +class YACSEvalObserver; +class YACSEvalInputPort; +class YACSEvalExecParams; +class YACSEvalOutputPort; +class YACSEvalListOfResources; + +class YACSEvalYFXWrap : public QObject +{ + Q_OBJECT +public: + YDFXWIDGETS_EXPORT YACSEvalYFXWrap(YACSEvalYFX *efx):_efx(efx),_isSeqOfValsSet(false),_isRunning(false) { } + YDFXWIDGETS_EXPORT YACSEvalYFXWrap(const YACSEvalYFXWrap& other):_efx(other._efx) { } + YDFXWIDGETS_EXPORT std::vector< YACSEvalInputPort * > getFreeInputPorts() const; + YDFXWIDGETS_EXPORT std::vector< YACSEvalOutputPort * > getFreeOutputPorts() const; + YDFXWIDGETS_EXPORT YACSEvalExecParams *getParams() const; + YDFXWIDGETS_EXPORT bool isLocked() const; + YDFXWIDGETS_EXPORT void unlockAll(); + YDFXWIDGETS_EXPORT YACSEvalListOfResources *giveResources(); + YDFXWIDGETS_EXPORT bool run(YACSEvalSession *session, int& nbOfBranches); + YDFXWIDGETS_EXPORT void registerObserver(YACSEvalObserver *observer); + YDFXWIDGETS_EXPORT ~YACSEvalYFXWrap(); +public:// modified API + YDFXWIDGETS_EXPORT void lockPortsForEvaluation(); + YDFXWIDGETS_EXPORT int getNbOfItems() const; +public: + YDFXWIDGETS_EXPORT void setRunningStatus(bool status); + YDFXWIDGETS_EXPORT bool isRunning() const { return _isRunning; } + YDFXWIDGETS_EXPORT void updateSequencesStatus(); + YDFXWIDGETS_EXPORT bool computeSequencesStatus(int& nbOfVals); +signals: + void lockSignal(bool); + void sequencesAreSetSignal(bool); + void runSignal(bool); +private: + YACSEvalYFX *_efx; + bool _isSeqOfValsSet; + bool _isRunning; +}; + +#endif diff --git a/src/ydfx_gui/ydfxgui.cxx b/src/ydfx_gui/ydfxgui.cxx new file mode 100644 index 000000000..65c9241de --- /dev/null +++ b/src/ydfx_gui/ydfxgui.cxx @@ -0,0 +1,36 @@ +// Copyright (C) 2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (EDF R&D) + +#include "YACSEvalSession.hxx" + +#include "YDFXGUIMain.hxx" + +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc,argv); + // + YACSEvalSession session; + session.launch(); + YDFXGUI mygui(&session); + mygui.show(); + return app.exec(); +} diff --git a/src/ydfx_gui/ydfxwidgetsExport.hxx b/src/ydfx_gui/ydfxwidgetsExport.hxx new file mode 100644 index 000000000..0f63286cf --- /dev/null +++ b/src/ydfx_gui/ydfxwidgetsExport.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2006-2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _YDFXWIDGETSEXPORT_HXX_ +#define _YDFXWIDGETSEXPORT_HXX_ + +#ifdef WIN32 +# if defined ydfxwidgets_EXPORTS +# define YDFXWIDGETS_EXPORT __declspec( dllexport ) +# else +# define YDFXWIDGETS_EXPORT __declspec( dllimport ) +# endif +#else +# define YDFXWIDGETS_EXPORT +#endif + +#ifdef WIN32 +#pragma warning(disable:4251) // Warning DLL Interface ... +#pragma warning(disable:4290) // Warning Exception ... +#endif + +#endif -- 2.30.2