STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC)
SET(${PROJECT_NAME_UC}_MAJOR_VERSION 8)
-SET(${PROJECT_NAME_UC}_MINOR_VERSION 3)
+SET(${PROJECT_NAME_UC}_MINOR_VERSION 4)
SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
SET(${PROJECT_NAME_UC}_VERSION
${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
int Executor::_maxThreads(1000);
size_t Executor::_threadStackSize(262144); // Default thread stack size is 256 kB == 2**18 because threads launched by YACS are lightweight
-Executor::Executor():_nbOfConcurrentThreads(0), _semForMaxThreads(_maxThreads),_keepGoingOnFail(false),_DPLScopeSensitive(false)
+Executor::Executor():_mainSched(NULL),_isWaitingEventsFromRunningTasks(false),_nbOfConcurrentThreads(0), _semForMaxThreads(_maxThreads),_keepGoingOnFail(false),_DPLScopeSensitive(false)
{
_root=0;
_toContinue = true;
_executorState = YACS::NOTYETINITIALIZED;
_execMode = YACS::CONTINUE;
_semThreadCnt = _maxThreads;
+ _numberOfRunningTasks = 0;
+ _numberOfEndedTasks = 0;
DEBTRACE("Executor initialized with max threads = " << _maxThreads);
}
DEBTRACE("---");
}
+/*!
+ * This method can be called at any time simultaneously during a RunB call.
+ * This method will wait until the executor is locked in a consistent state of a running graph.
+ *
+ * This method is expected to be called in association with resume method.
+ * The returned parameter is expected to be transfered to resume method.
+ */
+bool Executor::suspendASAP()
+{
+ // no AutoLocker here. It's not a bug.
+ _mutexForSchedulerUpdate.lock();
+ if(!_toContinue && _executorState==YACS::FINISHED)
+ {// execution is finished
+ _mutexForSchedulerUpdate.unLock();
+ return false;// the executor is no more running
+ }
+ //general case. Leave method with locker in locked status
+ return true;
+}
+
+/*!
+ * This method is expected to be called in association with suspendASAP method.
+ * Expected to be called just after suspendASAP with output of resume as input parameter
+ */
+void Executor::resume(bool suspended)
+{
+ if(suspended)
+ _mutexForSchedulerUpdate.unLock();
+}
+
//! stops the execution as soon as possible
void Executor::stopExecution()
#endif
public:
Executor();
- ~Executor();
+ virtual ~Executor();
void RunA(Scheduler *graph,int debug=0, bool fromScratch=true);
void RunW(Scheduler *graph,int debug=0, bool fromScratch=true) { RunB(graph, debug, fromScratch); }
void RunB(Scheduler *graph,int debug=0, bool fromScratch=true);
void setStopOnError(bool dumpRequested=false, std::string xmlFile="");
void unsetStopOnError();
void waitPause();
+ bool suspendASAP();
+ void resume(bool suspended);
static int _maxThreads;
static size_t _threadStackSize;
YACS::BASES::Mutex& getTheMutexForSchedulerUpdate() { return _mutexForSchedulerUpdate; }
const char YACSEvalYFXGraphGen::GATHER_NODE_NAME[]="__gather__";
+const char YACSEvalYFXGraphGen::HIDDEN_INDEX_VAR[]="___idx___";
+
class MyAutoThreadSaver
{
public:
oss << "NODE = " << nnc->getChildName(*it1) << std::endl;
oss << "STATUS = " << nsm[st0] << std::endl;
oss << "BRANCH ID = " << j << std::endl;
- std::list<YACS::ENGINE::InputPort *> inps((*it1)->getSetOfInputPort());
- for(std::list<YACS::ENGINE::InputPort *>::const_iterator it2=inps.begin();it2!=inps.end();it2++)
- {
- std::string d((*it2)->getHumanRepr());
- if(d.size()>10000)
- d=d.substr(0,MAX_LGTH_OF_INP_DUMP);
- oss << "INPUT \"" << (*it2)->getName() << "\" = " << d << std::endl;
- }
oss << "DETAILS = " << std::endl;
oss << (*it1)->getErrorDetails();
}
_generatedGraph=0; _FEInGeneratedGraph=0;
}
-bool YACSEvalYFXGraphGen::isLocked() const
-{
- return _generatedGraph!=0;
-}
-
-int YACSEvalYFXGraphGen::assignNbOfBranches()
-{
- if(!_generatedGraph)
- throw YACS::Exception("YACSEvalYFXGraphGen::assignNbOfBranches : the generated graph has not been created !");
- std::list<YACS::ENGINE::Node *> nodes(_generatedGraph->getChildren());
- YACS::ENGINE::ForEachLoop *zeMainNode(0);
- for(std::list<YACS::ENGINE::Node *>::const_iterator it=nodes.begin();it!=nodes.end();it++)
- {
- YACS::ENGINE::ForEachLoop *isZeMainNode(dynamic_cast<YACS::ENGINE::ForEachLoop *>(*it));
- if(isZeMainNode)
- {
- if(!zeMainNode)
- zeMainNode=isZeMainNode;
- else
- throw YACS::Exception("YACSEvalYFXGraphGen::assignNbOfBranches : internal error 1 !");
- }
- }
- if(!zeMainNode)
- throw YACS::Exception("YACSEvalYFXGraphGen::assignNbOfBranches : internal error 2 !");
- unsigned int nbProcsDeclared(getBoss()->getResourcesInternal()->getNumberOfProcsDeclared());
- nbProcsDeclared=std::max(nbProcsDeclared,4u);
- int nbOfBranch=1;
- if(getBoss()->getParallelizeStatus())
- {
- nbOfBranch=(nbProcsDeclared/getBoss()->getResourcesInternal()->getMaxLevelOfParallelism());
- nbOfBranch=std::max(nbOfBranch,1);
- }
- YACS::ENGINE::InputPort *zeInputToSet(zeMainNode->edGetNbOfBranchesPort());
- YACS::ENGINE::AnyInputPort *zeInputToSetC(dynamic_cast<YACS::ENGINE::AnyInputPort *>(zeInputToSet));
- if(!zeInputToSetC)
- throw YACS::Exception("YACSEvalYFXGraphGen::assignNbOfBranches : internal error 3 !");
- YACS::ENGINE::Any *a(YACS::ENGINE::AtomAny::New(nbOfBranch));
- zeInputToSetC->put(a);
- zeInputToSetC->exSaveInit();
- a->decrRef();
- return nbOfBranch;
-}
-
-void YACSEvalYFXGraphGenInteractive::generateGraph()
+void YACSEvalYFXGraphGen::generateGraphCommon(CustomPatcher& patcher)
{
if(_generatedGraph)
{ delete _generatedGraph; _generatedGraph=0; _FEInGeneratedGraph=0; }
YACS::ENGINE::TypeCode *pyobjTC(_generatedGraph->createInterfaceTc("python:obj:1.0","pyobj",std::list<YACS::ENGINE::TypeCodeObjref *>()));
std::ostringstream oss; oss << "Loop_" << getBoss()->getRunNode()->getName();
_generatedGraph->createType(YACSEvalAnyDouble::TYPE_REPR,"double");
- _generatedGraph->createType(YACSEvalAnyInt::TYPE_REPR,"int");
+ YACS::ENGINE::TypeCode *tcInt(_generatedGraph->createType(YACSEvalAnyInt::TYPE_REPR,"int"));
//
YACS::ENGINE::InlineNode *n0(r->createScriptNode(YACS::ENGINE::PythonNode::KIND,"__initializer__"));
_generatedGraph->edAddChild(n0);
(*it).setUndergroundPortToBeSet(inpc);
}
}
- std::ostringstream n0Script; n0Script << "sender=zip(" << var0.str() << ")\n";
+ std::ostringstream n0Script; n0Script << "sender=[tuple([__p9Sq]+list(__p9Sw)) for __p9Sq,__p9Sw in enumerate(zip(" << var0.str() << "))]\n";
n0->setScript(n0Script.str());
//
YACS::ENGINE::ForEachLoop *n1(r->createForEachLoop(oss.str(),pyobjTC));
n10->edAddCFLink(n100,n101);
n1->edAddDFLink(n1->edGetSamplePort(),dispatchIn);
std::ostringstream var1;
+ YACS::ENGINE::OutputPort *n100_output(n100->edAddOutputPort(HIDDEN_INDEX_VAR,tcInt));
+ var1 << HIDDEN_INDEX_VAR << ",";
for(std::vector< YACSEvalInputPort >::const_iterator it=inputs.begin();it!=inputs.end();it++)
{
if((*it).isRandomVar())
std::ostringstream n100Script; n100Script << var1.str() << "=i0\n";
n100->setScript(n100Script.str());
const std::vector<YACSEvalOutputPort *>& outputsOfInt(getBoss()->getOutputsOfInterest());
+ {
+ std::list<YACS::ENGINE::ElementaryNode *> n101_constit(n101->getRecursiveConstituents());
+ for(std::list<YACS::ENGINE::ElementaryNode *>::const_iterator it=n101_constit.begin();it!=n101_constit.end();it++)
+ {
+ YACS::ENGINE::InlineNode *eltc(dynamic_cast<YACS::ENGINE::InlineNode *>(*it));
+ if(eltc)
+ {
+ YACS::ENGINE::InputPort *n101_input(eltc->edAddInputPort(HIDDEN_INDEX_VAR,tcInt));
+ _generatedGraph->edAddDFLink(n100_output,n101_input);
+ }
+ }
+ }
for(std::vector< YACSEvalOutputPort * >::const_iterator it=outputsOfInt.begin();it!=outputsOfInt.end();it++)
{
+ patcher.addOutputVar((*it)->getName());
YACS::ENGINE::TypeCode *tc(YACSEvalYFXPattern::CreateSeqTypeCodeFrom(_generatedGraph,(*it)->getTypeOfData()));
YACS::ENGINE::InputPort *myIn(n2->edAddInputPort((*it)->getName(),tc));
std::string tmpPortName(runNode->getOutPortName((*it)->getUndergroundPtr()));
YACS::ENGINE::OutputPort *myOut(n101->getOutputPort(tmpPortName));
_generatedGraph->edAddDFLink(myOut,myIn);
}
+ patcher.assignOutput(n2);
_generatedGraph->updateContainersAndComponents();
}
+bool YACSEvalYFXGraphGen::isLocked() const
+{
+ return _generatedGraph!=0;
+}
+
+int YACSEvalYFXGraphGen::assignNbOfBranches()
+{
+ if(!_generatedGraph)
+ throw YACS::Exception("YACSEvalYFXGraphGen::assignNbOfBranches : the generated graph has not been created !");
+ std::list<YACS::ENGINE::Node *> nodes(_generatedGraph->getChildren());
+ YACS::ENGINE::ForEachLoop *zeMainNode(0);
+ for(std::list<YACS::ENGINE::Node *>::const_iterator it=nodes.begin();it!=nodes.end();it++)
+ {
+ YACS::ENGINE::ForEachLoop *isZeMainNode(dynamic_cast<YACS::ENGINE::ForEachLoop *>(*it));
+ if(isZeMainNode)
+ {
+ if(!zeMainNode)
+ zeMainNode=isZeMainNode;
+ else
+ throw YACS::Exception("YACSEvalYFXGraphGen::assignNbOfBranches : internal error 1 !");
+ }
+ }
+ if(!zeMainNode)
+ throw YACS::Exception("YACSEvalYFXGraphGen::assignNbOfBranches : internal error 2 !");
+ unsigned int nbProcsDeclared(getBoss()->getResourcesInternal()->getNumberOfProcsDeclared());
+ nbProcsDeclared=std::max(nbProcsDeclared,4u);
+ int nbOfBranch=1;
+ if(getBoss()->getParallelizeStatus())
+ {
+ nbOfBranch=(nbProcsDeclared/getBoss()->getResourcesInternal()->getMaxLevelOfParallelism());
+ nbOfBranch=std::max(nbOfBranch,1);
+ }
+ YACS::ENGINE::InputPort *zeInputToSet(zeMainNode->edGetNbOfBranchesPort());
+ YACS::ENGINE::AnyInputPort *zeInputToSetC(dynamic_cast<YACS::ENGINE::AnyInputPort *>(zeInputToSet));
+ if(!zeInputToSetC)
+ throw YACS::Exception("YACSEvalYFXGraphGen::assignNbOfBranches : internal error 3 !");
+ YACS::ENGINE::Any *a(YACS::ENGINE::AtomAny::New(nbOfBranch));
+ zeInputToSetC->put(a);
+ zeInputToSetC->exSaveInit();
+ a->decrRef();
+ return nbOfBranch;
+}
+
+void YACSEvalYFXGraphGenInteractive::generateGraph()
+{
+ class LocalPatcher : public YACSEvalYFXGraphGen::CustomPatcher
+ {
+ public:
+ void addOutputVar(const std::string& name) { }
+ void assignOutput(YACS::ENGINE::InlineNode *node) { }
+ };
+ LocalPatcher lp;
+ this->generateGraphCommon(lp);
+}
+
bool YACSEvalYFXGraphGenInteractive::go(const YACSEvalExecParams& params, YACSEvalSession *session) const
{
YACS::ENGINE::Executor exe;
void YACSEvalYFXGraphGenCluster::generateGraph()
{
YACS::ENGINE::AutoGIL agil;
- if(_generatedGraph)
- { delete _generatedGraph; _generatedGraph=0; _FEInGeneratedGraph=0; }
//
const char EFXGenFileName[]="EFXGenFileName";
const char EFXGenContent[]="import getpass,datetime,os\nn=datetime.datetime.now()\nreturn os.path.join(os.path.sep,\"tmp\",\"EvalYFX_%s_%s_%s.xml\"%(getpass.getuser(),n.strftime(\"%d%m%y\"),n.strftime(\"%H%M%S\")))";
val=YACS::ENGINE::evalFuncPyWithNoParams(func);
_jobName=PyString_AsString(val);
//
- static const char LISTPYOBJ_STR[]="list[pyobj]";
- if(getBoss()->getOutputsOfInterest().empty())
- return ;
- YACS::ENGINE::RuntimeSALOME::setRuntime();
- YACS::ENGINE::RuntimeSALOME *r(YACS::ENGINE::getSALOMERuntime());
- _generatedGraph=r->createProc(DFT_PROC_NAME);
- YACS::ENGINE::TypeCode *pyobjTC(_generatedGraph->createInterfaceTc("python:obj:1.0","pyobj",std::list<YACS::ENGINE::TypeCodeObjref *>()));
- std::ostringstream oss; oss << "Loop_" << getBoss()->getRunNode()->getName();
- _generatedGraph->createType(YACSEvalAnyDouble::TYPE_REPR,"double");
- _generatedGraph->createType(YACSEvalAnyInt::TYPE_REPR,"int");
- //
- YACS::ENGINE::InlineNode *n0(r->createScriptNode(YACS::ENGINE::PythonNode::KIND,"__initializer__"));
- _generatedGraph->edAddChild(n0);
- YACS::ENGINE::TypeCode *listPyobjTC(_generatedGraph->createSequenceTc(LISTPYOBJ_STR,LISTPYOBJ_STR,pyobjTC));
- YACS::ENGINE::OutputPort *sender(n0->edAddOutputPort("sender",listPyobjTC));
- std::ostringstream var0;
- const std::vector< YACSEvalInputPort >& inputs(getBoss()->getInputs());
- for(std::vector< YACSEvalInputPort >::const_iterator it=inputs.begin();it!=inputs.end();it++)
- {
- if((*it).isRandomVar())
- {
- var0 << (*it).getName() << ",";
- YACS::ENGINE::TypeCode *tc(YACSEvalYFXPattern::CreateSeqTypeCodeFrom(_generatedGraph,(*it).getTypeOfData()));
- YACS::ENGINE::InputPort *inp(n0->edAddInputPort((*it).getName(),tc));
- YACS::ENGINE::InputPyPort *inpc(dynamic_cast<YACS::ENGINE::InputPyPort *>(inp));
- if(!inpc)
- throw YACS::Exception("YACSEvalYFXRunOnlyPattern::generateGraph : internal error 1 !");
- (*it).setUndergroundPortToBeSet(inpc);
- }
+ class ClusterPatcher : public YACSEvalYFXGraphGen::CustomPatcher
+ {
+ public:
+ ClusterPatcher(const std::string& jobName):_jobName(jobName) { n2Script << "zeRes=["; }
+ void addOutputVar(const std::string& name) { n2Script<< name << ", "; }
+ void assignOutput(YACS::ENGINE::InlineNode *node) {
+ n2Script << "]\nwith open(\"" << _jobName << "\",\"w\") as f:" << std::endl;
+ n2Script << " f.write(str(zeRes))" << std::endl;
+ node->setScript(n2Script.str());
}
- std::ostringstream n0Script; n0Script << "sender=zip(" << var0.str() << ")\n";
- n0->setScript(n0Script.str());
+ private:
+ std::ostringstream n2Script;
+ std::string _jobName;
+ };
+ ClusterPatcher cp(_jobName);
//
- YACS::ENGINE::ForEachLoop *n1(r->createForEachLoop(oss.str(),pyobjTC));
- _FEInGeneratedGraph=n1;
- _generatedGraph->edAddChild(n1);
- _generatedGraph->edAddCFLink(n0,n1);
- _generatedGraph->edAddDFLink(sender,n1->edGetSeqOfSamplesPort());
- YACS::ENGINE::InlineNode *n2(r->createScriptNode(YACS::ENGINE::PythonNode::KIND,GATHER_NODE_NAME));
- _generatedGraph->edAddChild(n2);
- _generatedGraph->edAddCFLink(n1,n2);
- //
- YACS::ENGINE::Bloc *n10(r->createBloc(FIRST_FE_SUBNODE_NAME));
- n1->edAddChild(n10);
- YACS::ENGINE::InlineNode *n100(r->createScriptNode(YACS::ENGINE::PythonNode::KIND,"__dispatch__"));
- YACS::ENGINE::ComposedNode *runNode(getBoss()->getRunNode());
- YACS::ENGINE::Node *n101(runNode->cloneWithoutCompAndContDeepCpy(0,true));
- n10->edAddChild(n100);
- n10->edAddChild(n101);
- YACS::ENGINE::InputPort *dispatchIn(n100->edAddInputPort("i0",pyobjTC));
- n10->edAddCFLink(n100,n101);
- n1->edAddDFLink(n1->edGetSamplePort(),dispatchIn);
- std::ostringstream var1;
- for(std::vector< YACSEvalInputPort >::const_iterator it=inputs.begin();it!=inputs.end();it++)
- {
- if((*it).isRandomVar())
- {
- var1 << (*it).getName() << ",";
- YACS::ENGINE::OutputPort *myOut(n100->edAddOutputPort((*it).getName(),_generatedGraph->getTypeCode((*it).getTypeOfData())));
- std::string tmpPortName(runNode->getInPortName((*it).getUndergroundPtr()));
- YACS::ENGINE::InputPort *myIn(n101->getInputPort(tmpPortName));
- n10->edAddDFLink(myOut,myIn);
- }
- }
- std::ostringstream n100Script; n100Script << var1.str() << "=i0\n";
- n100->setScript(n100Script.str());
- const std::vector<YACSEvalOutputPort *>& outputsOfInt(getBoss()->getOutputsOfInterest());
- std::ostringstream n2Script; n2Script << "zeRes=[";
- for(std::vector< YACSEvalOutputPort * >::const_iterator it=outputsOfInt.begin();it!=outputsOfInt.end();it++)
- {
- YACS::ENGINE::TypeCode *tc(YACSEvalYFXPattern::CreateSeqTypeCodeFrom(_generatedGraph,(*it)->getTypeOfData()));
- YACS::ENGINE::InputPort *myIn(n2->edAddInputPort((*it)->getName(),tc));
- n2Script << (*it)->getName() << ", ";
- std::string tmpPortName(runNode->getOutPortName((*it)->getUndergroundPtr()));
- YACS::ENGINE::OutputPort *myOut(n101->getOutputPort(tmpPortName));
- _generatedGraph->edAddDFLink(myOut,myIn);
- }
- n2Script << "]\nf=file(\"" << _jobName << "\",\"w\") ; f.write(str(zeRes)) ; del f";
- n2->setScript(n2Script.str());
- _generatedGraph->updateContainersAndComponents();
+ this->generateGraphCommon(cp);
}
bool YACSEvalYFXGraphGenCluster::go(const YACSEvalExecParams& params, YACSEvalSession *session) const
class TypeCode;
class ForEachLoop;
class ComposedNode;
+ class InlineNode;
class InputPyPort;
class SequenceAny;
}
class YACSEvalYFXGraphGen
{
+public:
+ class CustomPatcher
+ {
+ public:
+ virtual ~CustomPatcher() { }
+ virtual void addOutputVar(const std::string& name) = 0;
+ virtual void assignOutput(YACS::ENGINE::InlineNode *node) = 0;
+ };
protected:
YACSEvalYFXGraphGen(YACSEvalYFXRunOnlyPattern *boss);
YACSEvalYFXRunOnlyPattern *getBoss() const { return _boss; }
void resetGeneratedGraph();
YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const { return _generatedGraph; }
YACS::ENGINE::ForEachLoop *getUndergroundForEach() const { return _FEInGeneratedGraph; }
+protected:
+ void generateGraphCommon(CustomPatcher& patcher);
private:
YACSEvalYFXRunOnlyPattern *_boss;
protected:
static const char DFT_PROC_NAME[];
static const char FIRST_FE_SUBNODE_NAME[];
static const char GATHER_NODE_NAME[];
+ static const char HIDDEN_INDEX_VAR[];
};
class YACSEvalYFXGraphGenInteractive : public YACSEvalYFXGraphGen
class YACSEvalYFXGraphGenCluster : public YACSEvalYFXGraphGen
{
public:
- YACSEvalYFXGraphGenCluster(YACSEvalYFXRunOnlyPattern *boss):YACSEvalYFXGraphGen(boss) { }
+ YACSEvalYFXGraphGenCluster(YACSEvalYFXRunOnlyPattern *boss):YACSEvalYFXGraphGen(boss),_jobid(0) { }
void generateGraph();
bool go(const YACSEvalExecParams& params, YACSEvalSession *session) const;
std::vector<YACSEvalSeqAny *> getResults() const;
CatalogResources="""<?xml version="1.0"?>
<resources>
<machine name="localhost" hostname="dsp0698184" type="single_machine" appliPath="" batchQueue="" userCommands="" protocol="ssh" iprotocol="ssh" workingDirectory="" canLaunchBatchJobs="false" canRunContainers="true" batch="none" mpi="no mpi" userName="" OS="" memInMB="0" CPUFreqMHz="0" nbOfNodes="1" nbOfProcPerNode="4"/>
- <machine name="athos" hostname="athos" type="cluster" appliPath="/home/H87074/ATHOS_V771/appli_V7_7_1" batchQueue="" userCommands="" protocol="ssh" iprotocol="ssh" workingDirectory="" canLaunchBatchJobs="true" canRunContainers="false" batch="slurm" mpi="no mpi" userName="" OS="" memInMB="0" CPUFreqMHz="0" nbOfNodes="250" nbOfProcPerNode="28"/>
+ <machine name="athos" hostname="athos" type="cluster" appliPath="/home/H87074/ATHOS_V830/appli_V8_3_0" batchQueue="" userCommands="" protocol="ssh" iprotocol="ssh" workingDirectory="" canLaunchBatchJobs="true" canRunContainers="false" batch="slurm" mpi="no mpi" userName="" OS="" memInMB="0" CPUFreqMHz="0" nbOfNodes="250" nbOfProcPerNode="28"/>
</resources>"""
def buildScheme(fname):
p.edAddChild(n0)
q=n0.edAddInputPort("q",td)
ep=n0.edAddOutputPort("ep",td)
- n0.setScript("ep=1./(4.-q)") # <- force division by 0
+ #n0.setScript("ep=1./(4.-q)") # <- force division by 0
+ n0.setScript("ep=2.*float(___idx___)")
n0.setExecutionMode("remote")
n0.setContainer(cont)
p0.saveSchema(fname)
# For salome test
IF(NOT WIN32)
- ADD_TEST(TestPy2yacs TestPy2yacs)
- SET_TESTS_PROPERTIES(TestPy2yacs PROPERTIES
- ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR}:${CMAKE_CURRENT_SOURCE_DIR}/..:$ENV{PYTHONPATH}"
- )
+ # This test needs a running salome session
+ # TODO: Run the test in a salome session
+ #ADD_TEST(TestPy2yacs TestPy2yacs)
+ #SET_TESTS_PROPERTIES(TestPy2yacs PROPERTIES
+ # ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR}:${CMAKE_CURRENT_SOURCE_DIR}/..:$ENV{PYTHONPATH}"
+ # )
SET(LOCAL_TEST_DIR ${SALOME_YACS_INSTALL_TEST}/py2yacs)
SET(LOCAL_TEST_FILES
IF(NOT WIN32)
SET(TEST_NAME ${COMPONENT_NAME}_Py2YacsTest)
- # No need of a salome session for this test
+ # Need a salome session for this test
ADD_TEST(${TEST_NAME} python ${SALOME_TEST_DRIVER} ${TIMEOUT} ./TestPy2yacs)
- #ADD_TEST(${TEST_NAME} TestPy2yacs)
SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES
LABELS "${COMPONENT_NAME}"
)
#include "InlineNode.hxx"
#include "AutoGIL.hxx"
#include "InputPort.hxx"
+#include "Container.hxx"
Py2yacsException::Py2yacsException(const std::string& what)
: std::exception(),
node->edAddOutputPort(*it, tc_double);
node->setExecutionMode(YACS::ENGINE::InlineNode::REMOTE_STR);
- node->setContainer(schema->containerMap["DefaultContainer"]);
+ YACS::ENGINE::Container* cont=schema->createContainer("Py2YacsContainer");
+ node->setContainer(cont);
+ cont->decrRef();
return schema;
+}
+
+std::string Py2yacs::getAllErrors()const
+{
+ std::stringstream buffer;
+ buffer.clear();
+ if(! _global_errors.empty())
+ {
+ buffer << "Global errors:" << std::endl;
+ std::list<std::string>::const_iterator it;
+ for(it=_global_errors.begin(); it!=_global_errors.end(); it++)
+ {
+ buffer << *it << std::endl;
+ }
+ buffer << "-----------------------------------------" << std::endl;
+ }
+
+ std::list<FunctionProperties>::const_iterator it_fp;
+ for(it_fp=_functions.begin();it_fp!=_functions.end();it_fp++)
+ {
+ if(! it_fp->_errors.empty())
+ {
+ buffer << "Function " << it_fp->_name << " has errors:" << std::endl;
+ std::list<std::string>::const_iterator it;
+ buffer << "Errors :" ;
+ for(it=it_fp->_errors.begin();it!=it_fp->_errors.end();it++)
+ buffer << *it << std::endl;
+ buffer << "-----------------------------------------" << std::endl;
+ }
+ }
+ return buffer.str();
+}
+
+std::string Py2yacs::getFunctionErrors(const std::string& functionName)const
+{
+ std::stringstream buffer;
+ buffer.clear();
+ if(! _global_errors.empty())
+ {
+ buffer << "Global errors:" << std::endl;
+ std::list<std::string>::const_iterator it;
+ for(it=_global_errors.begin(); it!=_global_errors.end(); it++)
+ {
+ buffer << *it << std::endl;
+ }
+ buffer << "-----------------------------------------" << std::endl;
+ }
+
+ bool nameFound = false;
+ std::list<FunctionProperties>::const_iterator it_fp;
+ for(it_fp=_functions.begin(); it_fp!=_functions.end() && !nameFound; it_fp++)
+ {
+ if(it_fp->_name == functionName)
+ {
+ nameFound = true;
+ if(! it_fp->_errors.empty())
+ {
+ buffer << "Function " << it_fp->_name << " has errors:" << std::endl;
+ std::list<std::string>::const_iterator it;
+ buffer << "Errors :" ;
+ for(it=it_fp->_errors.begin();it!=it_fp->_errors.end();it++)
+ buffer << *it << std::endl;
+ buffer << "-----------------------------------------" << std::endl;
+ }
+ }
+ }
+
+ if(!nameFound)
+ {
+ buffer << "Function " << functionName << " not found." << std::endl;
+ }
+ return buffer.str();
}
\ No newline at end of file
*/
YACS::ENGINE::Proc* createProc(const std::string& python_function)const;
+ /*!
+ * Syntax errors when parsing python and py2yacs global errors.
+ * \return a list of errors.
+ */
const std::list<std::string>& getGlobalErrors() const;
+
const std::list<FunctionProperties>& getFunctionProperties()const;
+ /*!
+ * Get a string containing global errors and errors specific to py2yacs for
+ * every function in python script.
+ * An empty string means there is no error.
+ */
+ std::string getAllErrors()const;
+
+ /*!
+ * Same as getAllErrors but only for one function.
+ * py2yacs errors for other functions are ignored.
+ * If the function name is not found, you get an error message in the
+ * returned string.
+ */
+ std::string getFunctionErrors(const std::string& functionName)const;
+
private:
std::string _python_parser_module;
std::string _python_parser_function;
SET(_moc_HEADERS
Py2YacsDialog.hxx
Py2YacsModel.hxx
+ Py2YacsDialog_raw.hxx
)
# sources / moc wrappings
Py2YacsModel.hxx
Py2YacsDialog.hxx
config_py2yacsgui.hxx
+ Py2YacsDialog_raw.hxx
)
SET(py2yacsgui_SOURCES
Py2YacsDialog.cxx
Py2YacsModel.cxx
+ Py2YacsDialog_raw.cxx
${_moc_SOURCES}
)
ADD_EXECUTABLE(py2yacsgui py2yacsgui.cxx)
TARGET_LINK_LIBRARIES(py2yacsgui py2yacsguilib)
+ADD_EXECUTABLE(py2yacsgui_rich py2yacsgui_rich.cxx)
+TARGET_LINK_LIBRARIES(py2yacsgui_rich py2yacsguilib)
+
INSTALL(TARGETS py2yacsguilib EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS})
INSTALL(TARGETS py2yacsgui DESTINATION ${SALOME_INSTALL_BINS})
+INSTALL(TARGETS py2yacsgui_rich DESTINATION ${SALOME_INSTALL_BINS})
INSTALL(FILES ${py2yacsgui_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS})
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#include <QtWidgets>
-#include <QSettings>
-#ifdef HAS_PYEDITOR
-#include <PyEditor_Editor.h>
-#endif
#include "Py2YacsDialog.hxx"
+#include <PyEditor_Window.h>
+#include <PyEditor_Widget.h>
+#include <py2yacs.hxx>
Py2YacsDialog::Py2YacsDialog( QWidget* parent)
-: QDialog(parent)
+: QDialog(parent),
+ _yacsFile(),
+ _pyEditorWindow(0),
+ _errorMessages(0),
+ _okButton(0)
{
- QHBoxLayout *fileLayout = new QHBoxLayout;
- QPushButton *loadButton = new QPushButton(tr("&Load"));
- _saveButton = new QPushButton(tr("&Save"));
- QPushButton *saveAsButton = new QPushButton(tr("Save &as ..."));
- fileLayout->addWidget(loadButton);
- fileLayout->addWidget(_saveButton);
- fileLayout->addWidget(saveAsButton);
-
-#ifdef HAS_PYEDITOR
- _pyEditor = new PyEditor_Editor(this);
-#else
- _pyEditor = new QTextEdit(this);
-#endif
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ _pyEditorWindow = new PyEditor_Window;
- QPushButton * applyButton = new QPushButton(tr("A&pply"));
- QTextEdit *errorMessages = new QTextEdit(this);
- errorMessages->setReadOnly(true);
+ _errorMessages = new QTextEdit(this);
+ _errorMessages->setReadOnly(true);
+ _errorMessages->hide();
+ QSplitter * splitterW = new QSplitter(Qt::Vertical);
+ splitterW->addWidget(_pyEditorWindow);
+ splitterW->addWidget(_errorMessages);
+ mainLayout->addWidget(splitterW);
- QHBoxLayout *exportLayout = new QHBoxLayout;
- _functionChosen = new QComboBox(this);
- _exportButton = new QPushButton(tr("E&xport to YACS schema..."));
- exportLayout->addWidget(new QLabel(tr("Function to run:")));
- exportLayout->addWidget(_functionChosen);
-
QHBoxLayout *validationLayout = new QHBoxLayout;
- _okButton = new QPushButton(tr("Save YACS schema and &quit"));
+ _okButton = new QPushButton(tr("py -> &YACS"));
QPushButton * cancelButton = new QPushButton(tr("&Cancel"));
validationLayout->addWidget(_okButton);
validationLayout->addWidget(cancelButton);
-
- QGroupBox *editWidget = new QGroupBox(tr("Python script:"));
- QVBoxLayout *editLayout = new QVBoxLayout;
- editLayout->addLayout(fileLayout);
- editLayout->addWidget(_pyEditor);
- editLayout->addWidget(applyButton);
- editLayout->addLayout(exportLayout);
- editWidget->setLayout(editLayout);
-
- QGroupBox *messageWidget = new QGroupBox(tr("Messages:"));
- QVBoxLayout *messageLayout = new QVBoxLayout;
- messageLayout->addWidget(errorMessages);
- messageWidget->setLayout(messageLayout);
-
- QSplitter * splitterW = new QSplitter(Qt::Vertical);
- splitterW->addWidget(editWidget);
- splitterW->addWidget(messageWidget);
-
- QVBoxLayout *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(splitterW);
mainLayout->addLayout(validationLayout);
+
setLayout(mainLayout);
setWindowTitle(tr("Python to YACS schema editor"));
-
- invalidModel();
- _saveButton->setEnabled(false);
- connect(_pyEditor, SIGNAL(textChanged()), this, SLOT(invalidModel()));
- connect(applyButton,SIGNAL(clicked()),this, SLOT(onApply()));
-
- connect(&_model, SIGNAL(scriptChanged(const QString&)),
- _pyEditor, SLOT(setText(const QString&)));
- connect(&_model, SIGNAL(errorChanged(const QString&)),
- errorMessages, SLOT(setText(const QString&)));
- connect(&_model, SIGNAL(functionsChanged(std::list<std::string>)),
- this, SLOT(onFunctionNamesChange(std::list<std::string>)));
- connect(_functionChosen,SIGNAL(currentIndexChanged(const QString &)),
- &_model, SLOT(setFunctionName(const QString&)));
- connect(loadButton,SIGNAL(clicked()),this, SLOT(onLoad()));
- connect(_saveButton,SIGNAL(clicked()),this, SLOT(onSave()));
- connect(saveAsButton,SIGNAL(clicked()),this, SLOT(onSaveAs()));
- connect(_exportButton,SIGNAL(clicked()),this, SLOT(onExport()));
+
connect(cancelButton,SIGNAL(clicked()),this, SLOT(reject()));
connect(_okButton,SIGNAL(clicked()),this, SLOT(onExport()));
-}
-void Py2YacsDialog::onFunctionNamesChange(std::list<std::string> validFunctionNames)
-{
- int new_index = 0;
- int count = 0;
- QString lastChoice = _functionChosen->currentText();
- _functionChosen->clear();
- std::list<std::string>::const_iterator it;
- for(it=validFunctionNames.begin(); it!=validFunctionNames.end(); it++)
- {
- _functionChosen->addItem(it->c_str());
- if(lastChoice == it->c_str())
- new_index = count;
- count++;
- }
- _functionChosen->setCurrentIndex(new_index);
+ // PyEditor_Window has a button "exit".
+ // Trigger "cancel" when the editor is closed.
+ _pyEditorWindow->setAttribute(Qt::WA_DeleteOnClose);
+ connect(_pyEditorWindow,SIGNAL(destroyed()),this, SLOT(reject()));
}
-void Py2YacsDialog::onLoad()
+void Py2YacsDialog::onExport()
{
- QSettings settings;
- QString currentDir = settings.value("currentDir").toString();
- if (currentDir.isEmpty())
- currentDir = QDir::homePath();
- QString fileName = QFileDialog::getOpenFileName(this, tr("Python script to import..."),
- currentDir,
- tr("Python script (*.py);;"));
-
- if (!fileName.isEmpty())
+ PyEditor_Widget* pyEdit = dynamic_cast<PyEditor_Widget*>
+ (_pyEditorWindow->centralWidget());
+ if(!pyEdit)
{
- QFile file(fileName);
- settings.setValue("currentDir", QFileInfo(fileName).absolutePath());
-
- _model.loadFile(fileName.toStdString());
- _saveButton->setEnabled(_model.savePossible());
- checkModel();
+ reject();
+ return;
}
-}
-void Py2YacsDialog::onExport()
-{
- QSettings settings;
- QString currentDir = settings.value("currentDir").toString();
- if (currentDir.isEmpty())
- currentDir = QDir::homePath();
- QString fileName = QFileDialog::getSaveFileName(this,
+ Py2yacs converter;
+ std::string text = pyEdit->text().toStdString();
+ try
+ {
+ converter.load(text);
+ // _exec -> default name for OPENTURNS functions
+ std::string errors = converter.getFunctionErrors("_exec");
+ if(errors.empty())
+ {
+ QSettings settings;
+ QString currentDir = settings.value("currentDir").toString();
+ if (currentDir.isEmpty())
+ currentDir = QDir::homePath();
+ QString fileName = QFileDialog::getSaveFileName(this,
tr("Save to YACS schema..."),
currentDir,
QString("%1 (*.xml)" ).arg( tr("xml files")));
- if (!fileName.isEmpty())
- {
- if (!fileName.endsWith(".xml"))
- fileName += ".xml";
- QFile file(fileName);
- settings.setValue("currentDir", QFileInfo(fileName).absolutePath());
-
- if(_model.exportToXml(fileName.toStdString()))
+ if (!fileName.isEmpty())
+ {
+ if (!fileName.endsWith(".xml"))
+ fileName += ".xml";
+ QFile file(fileName);
+ settings.setValue("currentDir", QFileInfo(fileName).absolutePath());
+ converter.save(fileName.toStdString(), "_exec");
+ _yacsFile = fileName;
+ accept();
+ }
+ }
+ else
{
- _yacsFile = fileName;
- accept();
+ _errorMessages->show();
+ _errorMessages->setText(errors.c_str());
}
}
-}
-
-void Py2YacsDialog::onApply()
-{
- _model.setScript(_pyEditor->toPlainText().toStdString());
- checkModel();
-}
-
-void Py2YacsDialog::invalidModel()
-{
- _okButton->setEnabled(false);
- _exportButton->setEnabled(false);
- _functionChosen->setEnabled(false);
-}
-
-void Py2YacsDialog::checkModel()
-{
- bool modelState = _model.schemaAvailable();
- _okButton->setEnabled(modelState);
- _exportButton->setEnabled(modelState);
- _functionChosen->setEnabled(modelState);
-}
-
-void Py2YacsDialog::onSave()
-{
- _model.setScript(_pyEditor->toPlainText().toStdString());
- _model.save();
- checkModel();
-}
-
-void Py2YacsDialog::onSaveAs()
-{
- QSettings settings;
- QString currentDir = settings.value("currentDir").toString();
- if (currentDir.isEmpty())
- currentDir = QDir::homePath();
- QString fileName = QFileDialog::getSaveFileName(this,
- tr("Save to python file..."),
- currentDir,
- QString("%1 (*.py)" ).arg( tr("python files")));
- if (!fileName.isEmpty())
+ catch(Py2yacsException& e)
{
- if (!fileName.endsWith(".py"))
- fileName += ".py";
- QFile file(fileName);
- settings.setValue("currentDir", QFileInfo(fileName).absolutePath());
-
- _model.setScript(_pyEditor->toPlainText().toStdString());
- _model.saveAs(fileName.toStdString());
- _saveButton->setEnabled(_model.savePossible());
- checkModel();
+ const char * error = e.what();
+ _errorMessages->show();
+ _errorMessages->setText(QString(error));
+ return;
}
}
-YACS::ENGINE::Proc* Py2YacsDialog::getYacsSchema()
-{
- return _model.getProc();
-}
-
QString Py2YacsDialog::getYacsFile()
{
return _yacsFile;
#define PY2YACSDIALOG_HXX
#include "config_py2yacsgui.hxx"
-#include "Py2YacsModel.hxx"
-#include <QDialog>
-
-#ifdef HAS_PYEDITOR
- class PyEditor_Editor;
-#else
- class QTextEdit;
-#endif
- class QComboBox;
- class QPushButton;
+#include <QtWidgets>
+class PyEditor_Window;
class PY2YACSGUILIB_EXPORT Py2YacsDialog : public QDialog
{
Q_OBJECT
public:
Py2YacsDialog( QWidget* parent=0);
- YACS::ENGINE::Proc* getYacsSchema();
QString getYacsFile();
-
+
public slots:
- virtual void onFunctionNamesChange(std::list<std::string> validFunctionNames);
- virtual void onLoad();
virtual void onExport();
- virtual void checkModel();
- virtual void invalidModel();
- virtual void onApply();
- virtual void onSave();
- virtual void onSaveAs();
+
private:
- Py2YacsModel _model;
QString _yacsFile;
-#ifdef HAS_PYEDITOR
- PyEditor_Editor *_pyEditor;
-#else
- QTextEdit *_pyEditor;
-#endif
- QComboBox *_functionChosen;
- QPushButton *_saveButton;
- QPushButton *_exportButton;
+ PyEditor_Window *_pyEditorWindow;
+ QTextEdit * _errorMessages;
QPushButton *_okButton;
};
--- /dev/null
+// Copyright (C) 2016-2017 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 <QtWidgets>
+#include <QSettings>
+#ifdef HAS_PYEDITOR
+#include <PyEditor_Editor.h>
+#endif
+
+#include "Py2YacsDialog_raw.hxx"
+
+Py2YacsDialog_raw::Py2YacsDialog_raw( QWidget* parent)
+: QDialog(parent)
+{
+ QHBoxLayout *fileLayout = new QHBoxLayout;
+ QPushButton *loadButton = new QPushButton(tr("&Load"));
+ _saveButton = new QPushButton(tr("&Save"));
+ QPushButton *saveAsButton = new QPushButton(tr("Save &as ..."));
+ fileLayout->addWidget(loadButton);
+ fileLayout->addWidget(_saveButton);
+ fileLayout->addWidget(saveAsButton);
+
+#ifdef HAS_PYEDITOR
+ _pyEditor = new PyEditor_Editor(this);
+#else
+ _pyEditor = new QTextEdit(this);
+#endif
+
+ QPushButton * applyButton = new QPushButton(tr("A&pply"));
+ QTextEdit *errorMessages = new QTextEdit(this);
+ errorMessages->setReadOnly(true);
+
+ QHBoxLayout *exportLayout = new QHBoxLayout;
+ _functionChosen = new QComboBox(this);
+ _exportButton = new QPushButton(tr("E&xport to YACS schema..."));
+ exportLayout->addWidget(new QLabel(tr("Function to run:")));
+ exportLayout->addWidget(_functionChosen);
+
+ QHBoxLayout *validationLayout = new QHBoxLayout;
+ _okButton = new QPushButton(tr("Save YACS schema and &quit"));
+ QPushButton * cancelButton = new QPushButton(tr("&Cancel"));
+ validationLayout->addWidget(_okButton);
+ validationLayout->addWidget(cancelButton);
+
+ QGroupBox *editWidget = new QGroupBox(tr("Python script:"));
+ QVBoxLayout *editLayout = new QVBoxLayout;
+ editLayout->addLayout(fileLayout);
+ editLayout->addWidget(_pyEditor);
+ editLayout->addWidget(applyButton);
+ editLayout->addLayout(exportLayout);
+ editWidget->setLayout(editLayout);
+
+ QGroupBox *messageWidget = new QGroupBox(tr("Messages:"));
+ QVBoxLayout *messageLayout = new QVBoxLayout;
+ messageLayout->addWidget(errorMessages);
+ messageWidget->setLayout(messageLayout);
+
+ QSplitter * splitterW = new QSplitter(Qt::Vertical);
+ splitterW->addWidget(editWidget);
+ splitterW->addWidget(messageWidget);
+
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(splitterW);
+ mainLayout->addLayout(validationLayout);
+ setLayout(mainLayout);
+ setWindowTitle(tr("Python to YACS schema editor"));
+
+ invalidModel();
+ _saveButton->setEnabled(false);
+ connect(_pyEditor, SIGNAL(textChanged()), this, SLOT(invalidModel()));
+ connect(applyButton,SIGNAL(clicked()),this, SLOT(onApply()));
+
+ connect(&_model, SIGNAL(scriptChanged(const QString&)),
+ _pyEditor, SLOT(setText(const QString&)));
+ connect(&_model, SIGNAL(errorChanged(const QString&)),
+ errorMessages, SLOT(setText(const QString&)));
+ connect(&_model, SIGNAL(functionsChanged(std::list<std::string>)),
+ this, SLOT(onFunctionNamesChange(std::list<std::string>)));
+ connect(_functionChosen,SIGNAL(currentIndexChanged(const QString &)),
+ &_model, SLOT(setFunctionName(const QString&)));
+ connect(loadButton,SIGNAL(clicked()),this, SLOT(onLoad()));
+ connect(_saveButton,SIGNAL(clicked()),this, SLOT(onSave()));
+ connect(saveAsButton,SIGNAL(clicked()),this, SLOT(onSaveAs()));
+ connect(_exportButton,SIGNAL(clicked()),this, SLOT(onExport()));
+ connect(cancelButton,SIGNAL(clicked()),this, SLOT(reject()));
+ connect(_okButton,SIGNAL(clicked()),this, SLOT(onExport()));
+}
+
+void Py2YacsDialog_raw::onFunctionNamesChange(std::list<std::string> validFunctionNames)
+{
+ int new_index = 0;
+ int count = 0;
+ QString lastChoice = _functionChosen->currentText();
+ _functionChosen->clear();
+ std::list<std::string>::const_iterator it;
+ for(it=validFunctionNames.begin(); it!=validFunctionNames.end(); it++)
+ {
+ _functionChosen->addItem(it->c_str());
+ if(lastChoice == it->c_str())
+ new_index = count;
+ count++;
+ }
+ _functionChosen->setCurrentIndex(new_index);
+}
+
+void Py2YacsDialog_raw::onLoad()
+{
+ QSettings settings;
+ QString currentDir = settings.value("currentDir").toString();
+ if (currentDir.isEmpty())
+ currentDir = QDir::homePath();
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Python script to import..."),
+ currentDir,
+ tr("Python script (*.py);;"));
+
+ if (!fileName.isEmpty())
+ {
+ QFile file(fileName);
+ settings.setValue("currentDir", QFileInfo(fileName).absolutePath());
+
+ _model.loadFile(fileName.toStdString());
+ _saveButton->setEnabled(_model.savePossible());
+ checkModel();
+ }
+}
+
+void Py2YacsDialog_raw::onExport()
+{
+ QSettings settings;
+ QString currentDir = settings.value("currentDir").toString();
+ if (currentDir.isEmpty())
+ currentDir = QDir::homePath();
+ QString fileName = QFileDialog::getSaveFileName(this,
+ tr("Save to YACS schema..."),
+ currentDir,
+ QString("%1 (*.xml)" ).arg( tr("xml files")));
+ if (!fileName.isEmpty())
+ {
+ if (!fileName.endsWith(".xml"))
+ fileName += ".xml";
+ QFile file(fileName);
+ settings.setValue("currentDir", QFileInfo(fileName).absolutePath());
+ if(_model.exportToXml(fileName.toStdString()))
+ {
+ _yacsFile = fileName;
+ accept();
+ }
+ }
+}
+
+void Py2YacsDialog_raw::onApply()
+{
+ _model.setScript(_pyEditor->toPlainText().toStdString());
+ checkModel();
+}
+
+void Py2YacsDialog_raw::invalidModel()
+{
+ _okButton->setEnabled(false);
+ _exportButton->setEnabled(false);
+ _functionChosen->setEnabled(false);
+}
+
+void Py2YacsDialog_raw::checkModel()
+{
+ bool modelState = _model.schemaAvailable();
+ _okButton->setEnabled(modelState);
+ _exportButton->setEnabled(modelState);
+ _functionChosen->setEnabled(modelState);
+}
+
+void Py2YacsDialog_raw::onSave()
+{
+ _model.setScript(_pyEditor->toPlainText().toStdString());
+ _model.save();
+ checkModel();
+}
+
+void Py2YacsDialog_raw::onSaveAs()
+{
+ QSettings settings;
+ QString currentDir = settings.value("currentDir").toString();
+ if (currentDir.isEmpty())
+ currentDir = QDir::homePath();
+ QString fileName = QFileDialog::getSaveFileName(this,
+ tr("Save to python file..."),
+ currentDir,
+ QString("%1 (*.py)" ).arg( tr("python files")));
+ if (!fileName.isEmpty())
+ {
+ if (!fileName.endsWith(".py"))
+ fileName += ".py";
+ QFile file(fileName);
+ settings.setValue("currentDir", QFileInfo(fileName).absolutePath());
+ _model.setScript(_pyEditor->toPlainText().toStdString());
+ _model.saveAs(fileName.toStdString());
+ _saveButton->setEnabled(_model.savePossible());
+ checkModel();
+ }
+}
+
+YACS::ENGINE::Proc* Py2YacsDialog_raw::getYacsSchema()
+{
+ return _model.getProc();
+}
+
+QString Py2YacsDialog_raw::getYacsFile()
+{
+ return _yacsFile;
+}
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2016-2017 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 PY2YACSDIALOG_RAW_HXX
+#define PY2YACSDIALOG_RAW_HXX
+
+#include "config_py2yacsgui.hxx"
+#include "Py2YacsModel.hxx"
+#include <QDialog>
+
+#ifdef HAS_PYEDITOR
+ class PyEditor_Editor;
+#else
+ class QTextEdit;
+#endif
+ class QComboBox;
+ class QPushButton;
+
+class PY2YACSGUILIB_EXPORT Py2YacsDialog_raw : public QDialog
+{
+ Q_OBJECT
+ public:
+ Py2YacsDialog_raw( QWidget* parent=0);
+ YACS::ENGINE::Proc* getYacsSchema();
+ QString getYacsFile();
+ public slots:
+ virtual void onFunctionNamesChange(std::list<std::string> validFunctionNames);
+ virtual void onLoad();
+ virtual void onExport();
+ virtual void checkModel();
+ virtual void invalidModel();
+ virtual void onApply();
+ virtual void onSave();
+ virtual void onSaveAs();
+ private:
+ Py2YacsModel _model;
+ QString _yacsFile;
+#ifdef HAS_PYEDITOR
+ PyEditor_Editor *_pyEditor;
+#else
+ QTextEdit *_pyEditor;
+#endif
+ QComboBox *_functionChosen;
+ QPushButton *_saveButton;
+ QPushButton *_exportButton;
+ QPushButton *_okButton;
+};
+
+#endif // PY2YACSDIALOG_RAW_HXX
void Py2YacsModel::setScript(const std::string& texte)
{
- std::stringstream buffer;
_script = texte;
emit scriptChanged(_script.c_str());
_functionName = "";
try
{
_data.load(_script);
-
- // get the errors
- buffer.clear();
- const std::list<std::string>& globalErrors = _data.getGlobalErrors();
- if(! globalErrors.empty())
- {
- buffer << "Global errors:" << std::endl;
- std::list<std::string>::const_iterator it;
- for(it=globalErrors.begin(); it!=globalErrors.end(); it++)
- {
- buffer << *it << std::endl;
- }
- buffer << "-----------------------------------------" << std::endl;
- }
-
- std::list<FunctionProperties>::const_iterator it_fp;
- const std::list<FunctionProperties>& functions = _data.getFunctionProperties();
- for(it_fp=functions.begin();it_fp!=functions.end();it_fp++)
- {
- if(! it_fp->_errors.empty())
- {
- buffer << "Function " << it_fp->_name << " has errors:" << std::endl;
- std::list<std::string>::const_iterator it;
- buffer << "Errors :" ;
- for(it=it_fp->_errors.begin();it!=it_fp->_errors.end();it++)
- buffer << *it << std::endl;
- buffer << "-----------------------------------------" << std::endl;
- }
- }
- _lastError = buffer.str();
+ _lastError = _data.getAllErrors();
}
catch(Py2yacsException& e)
{
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#include "Py2YacsDialog.hxx"
+#include "Py2YacsDialog_raw.hxx"
#include <QApplication>
#include "RuntimeSALOME.hxx"
#include "Proc.hxx"
{
QApplication app(argc,argv);
YACS::ENGINE::RuntimeSALOME::setRuntime();
- Py2YacsDialog mygui;
+ Py2YacsDialog_raw mygui;
if(mygui.exec())
{
std::cout << "Accepted" << std::endl;
--- /dev/null
+// Copyright (C) 2016-2017 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 "Py2YacsDialog.hxx"
+#include <QApplication>
+#include "RuntimeSALOME.hxx"
+#include "Proc.hxx"
+#include <PyEditor_StdSettings.h>
+#include <iostream>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc,argv);
+ app.setOrganizationName( "salome" );
+ app.setOrganizationDomain( "www.salome-platform.org" );
+ app.setApplicationName( "py2yacs" );
+
+ YACS::ENGINE::RuntimeSALOME::setRuntime();
+ Py2YacsDialog mygui;
+ if(mygui.exec())
+ {
+ std::cout << "Accepted:" << mygui.getYacsFile().toStdString() << std::endl;
+ }
+ else
+ {
+ std::cout << "Not accepted" << std::endl;
+ }
+ return 0;
+}