1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "YACSPrs_ForEachLoopNode.h"
21 #include "YACSPrs_Def.h"
23 #include "SUIT_ResourceMgr.h"
27 #include <ForEachLoop.hxx>
29 using namespace YACS::ENGINE;
34 YACSPrs_ForEachLoopNode::YACSPrs_ForEachLoopNode( SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACS::HMI::SubjectNode* theSNode ):
35 YACSPrs_LoopNode(theMgr, theCanvas, theSNode, false)
37 //updatePorts(); // will be called in moveBy(...) function
38 moveBy(3*TITLE_HEIGHT/2+NODEBOUNDARY_MARGIN, 3*TITLE_HEIGHT/2+NODEBOUNDARY_MARGIN);
44 YACSPrs_ForEachLoopNode::~YACSPrs_ForEachLoopNode()
48 int YACSPrs_ForEachLoopNode::rtti() const
50 return 0;//YACSPrs_Canvas::Rtti_ForEachLoopNode;
53 void YACSPrs_ForEachLoopNode::updatePorts(bool theForce)
55 bool aDisp = isVisible();
58 bool withCreate = theForce;
63 myPortHeight = 2*PORT_MARGIN;
67 myPortList.setAutoDelete(true);
70 QPtrList<YACSPrs_LabelPort> aDeletePortList;
71 for (YACSPrs_Port* aPort = myPortList.first(); aPort; aPort = myPortList.next())
73 if( YACSPrs_LabelPort* aLabelPort = dynamic_cast<YACSPrs_LabelPort*>( aPort ) )
75 aDeletePortList.append( aLabelPort );
80 for (YACSPrs_Port* aPort = aDeletePortList.first(); aPort; aPort = aDeletePortList.next())
81 myPortList.remove( aPort );
84 // ForEachLoop has 2 input ports and 2 output ports.
85 // Input ports : 1) 'nbBranches' port, its type is 'int', its value is a number of iterations;
86 // 2) 'SmplsCollection' port, its type is 'sequence' of elelmnts of the given type,
87 // it is a list of values of the given type.
88 // Output ports : 1) 'SmplPrt' port, its type is the given type, its value is a value of the
89 // list item, which is processed at the current moment.
90 // 2) 'Body' label port, this 'label' port connects with help of label link to
91 // 'Master' hook of the node, which is set as an internal node of the loop.
93 if ( myPortList.isEmpty() ) withCreate = true;
97 QRect r = getBodyRect();
98 int aPRectWidth = (int)(r.width()/2) - 2*PORT_MARGIN;
99 if ( aPRectWidth < PORT_WIDTH ) aPRectWidth = PORT_WIDTH;
101 int ix = r.x() + PORT_MARGIN + 1;
102 int iy = r.y() + PORT_MARGIN;// + 1;
103 int ox = ix + aPRectWidth + 2*PORT_MARGIN;
104 int oy = r.y() + PORT_MARGIN;// + 1;
107 { // create (and update)
108 ForEachLoop* aFELoop = dynamic_cast<ForEachLoop*>( getEngine() );
110 { // create 2 input and 1 output ports
111 bool isBranchesPortCreated = false;
112 bool isSeqOfSamplesPortCreated = false;
113 bool isSamplePortCreated = false;
114 InputPort* aBranchesPort = aFELoop->edGetNbOfBranchesPort();
115 InputPort* aSeqOfSamplesPort = aFELoop->edGetSeqOfSamplesPort();
116 OutputPort* aSamplePort = aFELoop->edGetSamplePort();
118 for (YACSPrs_Port* aPort = myPortList.first(); aPort; aPort = myPortList.next())
120 if( !aPort->getName().compare( QString( aBranchesPort->getName() ) ) )
121 isBranchesPortCreated = true;
122 else if( !aPort->getName().compare( QString( aSeqOfSamplesPort->getName() ) ) )
123 isSeqOfSamplesPortCreated = true;
124 else if( !aPort->getName().compare( QString( aSamplePort->getName() ) ) )
125 isSamplePortCreated = true;
128 if( !isBranchesPortCreated )
131 YACSPrs_InOutPort* anIn1Port = new YACSPrs_InOutPort(myMgr,canvas(),aBranchesPort,this);
132 anIn1Port->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT));
133 anIn1Port->setColor(nodeSubColor());
134 anIn1Port->setStoreColor(nodeSubColor());
135 myPortList.append(anIn1Port);
137 if( !isSeqOfSamplesPortCreated )
140 YACSPrs_InOutPort* anIn2Port = new YACSPrs_InOutPort(myMgr,canvas(),aSeqOfSamplesPort,this);
141 anIn2Port->setPortRect(QRect(ix, iy+PORT_HEIGHT+PORT_SPACE, aPRectWidth, PORT_HEIGHT));
142 anIn2Port->setColor(nodeSubColor());
143 anIn2Port->setStoreColor(nodeSubColor());
144 myPortList.append(anIn2Port);
147 myPortHeight += 2*PORT_HEIGHT;
148 myPortHeight += PORT_SPACE;
150 if( !isSamplePortCreated )
153 YACSPrs_InOutPort* anOutPort = new YACSPrs_InOutPort(myMgr,canvas(),aSamplePort,this);
154 anOutPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT));
155 anOutPort->setColor(nodeSubColor());
156 anOutPort->setStoreColor(nodeSubColor());
157 myPortList.append(anOutPort);
160 // get a set of internal loop nodes (in fact ForEachLoop has 2 internal nodes: _node and _initNode,
161 // but only _node was initialized in engine, in all examples _initNode is null)
162 std::list<Node*> aNodes = aFELoop->edGetDirectDescendants();
163 std::list<Node*>::iterator aNodesIter = aNodes.begin();
164 for (; aNodesIter != aNodes.end(); aNodesIter++)
165 { // output label port
166 YACSPrs_LabelPort* anOutPort = new YACSPrs_LabelPort(myMgr,canvas(),*aNodesIter,this);
167 anOutPort->setPortRect(QRect(ox, oy+PORT_HEIGHT+PORT_SPACE, aPRectWidth, PORT_HEIGHT));
168 anOutPort->setColor(nodeSubColor().dark(140));
169 anOutPort->setStoreColor(nodeSubColor().dark(140));
170 myPortList.append(anOutPort);
177 for (aPort = myPortList.first(); aPort; aPort = myPortList.next())
179 YACSPrs_InOutPort* anIOPort = dynamic_cast<YACSPrs_InOutPort*>( aPort );
182 if ( !anIOPort->isGate() )
184 if ( anIOPort->isInput() )
185 { // input data (i.e. not Gate) ports
186 anIOPort->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea);
187 iy += PORT_HEIGHT+PORT_SPACE;
190 { // output data (i.e. not Gate) ports
191 anIOPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea);
192 oy += PORT_HEIGHT+PORT_SPACE;
197 { // not YACSPrs_InOutPort => it is YACSPrs_LabelPort (output!) => we not need to dynamic cast
198 aPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea);
199 oy += PORT_HEIGHT+PORT_SPACE;
205 // can update gates only after body height will be defined
206 bool createGates = withCreate;
207 for (YACSPrs_Port* aPort = myPortList.first(); aPort; aPort = myPortList.next())
209 if( YACSPrs_InOutPort* anIOPort = dynamic_cast<YACSPrs_InOutPort*>( aPort ) )
211 if ( anIOPort->isGate() )
212 { // gate ports are already created - we should only update them
218 updateGates(createGates);
220 if (theForce && myPointMaster)
222 QPoint aPnt = getConnectionMasterPoint();
223 myPointMaster->setCoords(aPnt.x(), aPnt.y());
229 //! Increments time iteration.
231 * Note : use not null argument of this function only for update original body node of ForEachLoop node.
233 * \param theEngine : the engine of clone node from which we have to update presentation of this node.
235 void YACSPrs_ForEachLoopNode::nextTimeIteration(YACS::ENGINE::Node* theEngine)
237 bool nullifyOnToActivate = false;
238 if ( !theEngine ) theEngine = getEngine();
239 else nullifyOnToActivate = true;
243 ( theEngine->getState() == YACS::READY /*|| theEngine->getEffectiveState() == YACS::READY*/
245 ( nullifyOnToActivate && ( theEngine->getState() == YACS::TOACTIVATE || theEngine->getEffectiveState() == YACS::TOACTIVATE) ) ) )
246 setTimeIteration( 0. );
247 else if ( theEngine &&
248 theEngine->getState() != YACS::READY /*&& theEngine->getEffectiveState() != YACS::READY*/ &&
250 if ( ForEachLoop* aLoop = dynamic_cast<ForEachLoop*>( theEngine ) )
251 setTimeIteration( aLoop->getExecCurrentId()-1. >= 0 ? aLoop->getExecCurrentId()-1. : 0. );
255 //! Returns the progress bar percentage.
257 * Note : use not null argument of this function only for update original body node of ForEachLoop node.
259 * \param theEngine : the engine of clone node from which we have to update presentation of this node.
261 int YACSPrs_ForEachLoopNode::getPercentage(YACS::ENGINE::Node* theEngine) const
263 if ( !theEngine ) theEngine = getEngine();
265 if ( !theEngine ) return 0;
267 if ( theEngine->getState() == YACS::READY || /*theEngine->getEffectiveState() == YACS::READY ||*/
268 theEngine->getState() == YACS::TOLOAD || theEngine->getEffectiveState() == YACS::TOLOAD )
270 if ( theEngine->getState() == YACS::DONE )
272 if ( ForEachLoop* aLoop = dynamic_cast<ForEachLoop*>( theEngine ) ) {
273 SeqAnyInputPort* aCollection = dynamic_cast<SeqAnyInputPort*>( aLoop->edGetSeqOfSamplesPort() );
274 if ( aCollection && !aCollection->isEmpty() )
275 return (int)( 100. / aCollection->getNumberOfElements() * getTimeIteration() );