]> SALOME platform Git repositories - modules/yacs.git/blob - src/hmi/guiObservers.cxx
Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / hmi / guiObservers.cxx
1 //  Copyright (C) 2006-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include <Python.h>
20 #include "guiObservers.hxx"
21 #include "commandsProc.hxx"
22 #include "Node.hxx"
23 #include "ComposedNode.hxx"
24 #include "Bloc.hxx"
25 #include "Proc.hxx"
26 #include "ElementaryNode.hxx"
27 #include "InlineNode.hxx"
28 #include "ServiceNode.hxx"
29 #include "PythonNode.hxx"
30 #include "CORBANode.hxx"
31 #include "CppNode.hxx"
32 #include "XMLNode.hxx"
33 #include "SalomePythonNode.hxx"
34 #include "DataNode.hxx"
35 #include "PresetNode.hxx"
36 #include "OutNode.hxx"
37 #include "StudyNodes.hxx"
38 #include "ForLoop.hxx"
39 #include "ForEachLoop.hxx"
40 #include "WhileLoop.hxx"
41 #include "Switch.hxx"
42 #include "OptimizerLoop.hxx"
43 #include "InputPort.hxx"
44 #include "OutputPort.hxx"
45 #include "InputDataStreamPort.hxx"
46 #include "OutputDataStreamPort.hxx"
47 #include "SalomeContainer.hxx"
48 #include "SalomeComponent.hxx"
49 #include "ComponentDefinition.hxx"
50 #include "TypeCode.hxx"
51
52 #include "guiContext.hxx"
53
54 #include <string>
55 #include <sstream>
56 #include <vector>
57
58 //#define _DEVDEBUG_
59 #include "YacsTrace.hxx"
60
61 using namespace std;
62
63 using namespace YACS;
64 using namespace YACS::HMI;
65 using namespace YACS::ENGINE;
66
67 std::map<int, std::string> GuiObserver::_eventNameMap;
68
69 // ----------------------------------------------------------------------------
70
71 void Subject::erase(Subject* sub)
72 {
73   sub->clean();
74   delete sub;
75 }
76
77 // ----------------------------------------------------------------------------
78
79 Subject::Subject(Subject *parent) : _parent(parent)
80 {
81   _destructible = true;
82 }
83
84 /*!
85  *  Destructor must only be called by Subject::erase to clean
86  *  completely the context (detach observers), before the delete
87  *  process itself. Some actions involving dynamic_cast can't be done
88  *  in destructor.
89  */
90 Subject::~Subject()
91 {
92   DEBTRACE("Subject::~Subject " << this << " "<< getName());
93 }
94
95 /*!
96  * Clean process prior to delete is redefined in derived classes: a local clean
97  * treatment relative to the derived class, then a call to the parent class clean
98  * method.
99  */
100 void Subject::clean()
101 {
102   localClean();
103 }
104
105 /*!
106  *  the local clean method of base class of subjects take care of Observers.
107  *  Remaining Observers in the list are detached, if an observer has no more
108  *  Subject to observe, it can be deleted.
109  */
110 void Subject::localClean()
111 {
112   DEBTRACE("Subject::localClean ");
113   set<GuiObserver*>::iterator it;
114   while (int nbObs = _setObs.size())
115     {
116       DEBTRACE("--- " << this << " nbObs " << nbObs);
117       set<GuiObserver*> copySet = _setObs;
118       for (it = copySet.begin(); it != copySet.end(); ++it)
119         {
120           GuiObserver* anObs = (*it);
121           detach(anObs);
122           int nbsub = anObs->getNbSubjects();
123           DEBTRACE("nbSubjects=" << nbsub << " obs=" << anObs);
124           if (nbsub <= 0 && anObs->isDestructible())
125             {
126               delete anObs ;
127               break; // --- each delete may induce remove of other observers
128             }
129         }
130     }
131   _setObs.clear();
132 }
133
134 void Subject::attach(GuiObserver *obs)
135 {
136   DEBTRACE("Subject::attach " << obs);
137   _setObs.insert(obs);
138   obs->incrementSubjects(this);
139 }
140
141 void Subject::detach(GuiObserver *obs)
142 {
143   DEBTRACE("Subject::detach " << obs);
144   obs->decrementSubjects(this);
145   _setObs.erase(obs);
146 }
147
148 std::string Subject::getName()
149 {
150   return "generic";
151 }
152
153 bool Subject::setName(std::string name)
154 {
155   return false;
156 }
157
158 void Subject::select(bool isSelected)
159 {
160   DEBTRACE("Subject::select " << isSelected << " " << this);
161   set<GuiObserver*> copySet = _setObs;
162   for (set<GuiObserver *>::iterator it = copySet.begin(); it != copySet.end(); ++it)
163     {
164       GuiObserver* currOb = *it;
165       currOb->select(isSelected);
166     }
167 }
168
169 void Subject::update(GuiEvent event,int type, Subject* son)
170 {
171   //DEBTRACE("Subject::update " << type << "," << GuiObserver::eventName(event) << "," << son);
172   set<GuiObserver*> copySet = _setObs;
173   for (set<GuiObserver *>::iterator it = copySet.begin(); it != copySet.end(); ++it)
174     {
175       //DEBTRACE("Subject::update " << *it);
176       (*it)->update(event, type, son);
177     }
178 }
179
180 Subject* Subject::getParent()
181 {
182   return _parent;
183 }
184
185 bool Subject::destroy(Subject *son)
186 {
187   string toDestroy = son->getName();
188   DEBTRACE("Subject::destroy " << toDestroy);
189   Proc *proc = GuiContext::getCurrent()->getProc();
190   string position = "";
191
192   if (dynamic_cast<SubjectProc*>(son))
193     position = proc->getName();
194   else
195     {
196       if (SubjectNode *subNode = dynamic_cast<SubjectNode*>(son))
197         {
198           if (subNode->getNode()->getFather() )
199             position = proc->getChildName(subNode->getNode());
200         }
201       else if (dynamic_cast<SubjectDataPort*>(son))
202         {
203           SubjectNode *subNodep = dynamic_cast<SubjectNode*>(son->getParent());
204           if (dynamic_cast<SubjectProc*>(subNodep))
205             position = proc->getName();
206           else
207             position = proc->getChildName(subNodep->getNode());
208         }
209       else if (dynamic_cast<SubjectLink*>(son))
210         {
211           SubjectNode *subNodep = dynamic_cast<SubjectNode*>(son->getParent());
212           if (dynamic_cast<SubjectProc*>(subNodep))
213             position = proc->getName();
214           else
215             position = proc->getChildName(subNodep->getNode());
216         }
217     }
218   if (son->isDestructible())
219     {
220       CommandDestroy* command = new CommandDestroy(position, son);
221       if (command->execute())
222         {
223           DEBTRACE("Destruction done: " << toDestroy);
224           update(REMOVE, 0, 0);
225           return true;
226         }
227       else delete command;
228     }
229   return false;
230 }
231
232 void Subject::loadChildren()
233 {
234 }
235
236 void Subject::loadLinks()
237 {
238 }
239
240 void Subject::addSubjectReference(Subject *ref)
241 {
242   DEBTRACE("Subject::addSubjectReference " << getName() << " " << ref->getName());
243   SubjectReference *son = new SubjectReference(ref, this);
244   update(ADDREF, 0, son);
245 }
246
247 // ----------------------------------------------------------------------------
248
249 GuiObserver::GuiObserver()
250   : _destructible(true)
251 {
252   //DEBTRACE("GuiObserver::GuiObserver " << this);
253   _subjectSet.clear();
254 }
255
256 GuiObserver::~GuiObserver()
257 {
258   DEBTRACE("GuiObserver::~GuiObserver " << this);
259   set<Subject*> subsetcpy = _subjectSet;
260   set<Subject*>::iterator it= subsetcpy.begin();
261   for (; it != subsetcpy.end(); ++it)
262     (*it)->detach(this);
263 }
264
265 void GuiObserver::select(bool isSelected)
266 {
267   DEBTRACE("GuiObserver::select() " << isSelected);
268 }
269
270 void GuiObserver::update(GuiEvent event, int type,  Subject* son)
271 {
272   //DEBTRACE("GuiObserver::update, event not handled " << eventName(event) << " " << type );
273 }
274
275 /*!
276  * only called by subject when attach to subject.
277  * @see Subject::attach
278  */
279 void GuiObserver::incrementSubjects(Subject *subject)
280 {
281   if (_subjectSet.count(subject))
282     DEBTRACE("subject " << subject << " is already a subject of observer " << this << "---------------------------");
283   _subjectSet.insert(subject);
284   //DEBTRACE(this << " " << _subjectSet.size());
285 }
286
287 /*!
288  * only called by subject when detach from subject.
289  * @see Subject::detach
290  */
291 void GuiObserver::decrementSubjects(Subject *subject)
292 {
293   if (_subjectSet.count(subject))
294     _subjectSet.erase(subject);
295   else
296     DEBTRACE("subject " << subject << " is not a subject of observer " << this << "---------------------------");
297   //DEBTRACE(this << " " << _subjectSet.size());
298 }
299
300 /*! 
301  * Gets the number of subjects observed.
302  * used by subject. When the subject is erased (Subject::erase),
303  * remaining observers are detached from subjects. If an observer has no
304  * more subject, it can be deleted.
305  * @see Subject::erase Subject::localClean
306  */
307 int GuiObserver::getNbSubjects()
308 {
309   return _subjectSet.size();
310 }
311
312 void GuiObserver::setEventMap()
313 {
314   _eventNameMap.clear();
315   _eventNameMap[ADD]            = "ADD";
316   _eventNameMap[REMOVE]         = "REMOVE";
317   _eventNameMap[CUT]            = "CUT";
318   _eventNameMap[PASTE]          = "PASTE";
319   _eventNameMap[ORDER]          = "ORDER";
320   _eventNameMap[EDIT]           = "EDIT";
321   _eventNameMap[UPDATE]         = "UPDATE";
322   _eventNameMap[UPDATEPROGRESS] = "UPDATEPROGRESS";
323   _eventNameMap[SYNCHRO]        = "SYNCHRO";
324   _eventNameMap[UP]             = "UP";
325   _eventNameMap[DOWN]           = "DOWN";
326   _eventNameMap[RENAME]         = "RENAME";
327   _eventNameMap[NEWROOT]        = "NEWROOT";
328   _eventNameMap[ENDLOAD]        = "ENDLOAD";
329   _eventNameMap[ADDLINK]        = "ADDLINK";
330   _eventNameMap[ADDCONTROLLINK] = "ADDCONTROLLINK";
331   _eventNameMap[ADDREF]         = "ADDREF";
332   _eventNameMap[ADDCHILDREF]    = "ADDCHILDREF";
333   _eventNameMap[REMOVECHILDREF] = "REMOVECHILDREF";
334   _eventNameMap[ASSOCIATE]      = "ASSOCIATE";
335   _eventNameMap[SETVALUE]       = "SETVALUE";
336   _eventNameMap[SETCASE]        = "SETCASE";
337   _eventNameMap[SETSELECT]      = "SETSELECT";
338   _eventNameMap[GEOMETRY]       = "GEOMETRY";
339 }
340
341 std::string GuiObserver::eventName(GuiEvent event)
342 {
343   if (_eventNameMap.count(event))
344     return _eventNameMap[event];
345   else return "Unknown Event";
346 }
347
348 // ----------------------------------------------------------------------------
349
350 SubjectReference::SubjectReference(Subject* ref, Subject *parent)
351   : Subject(parent), _reference(ref)
352 {
353 }
354
355 SubjectReference::~SubjectReference()
356 {
357 }
358
359 void SubjectReference::clean()
360 {
361   localClean();
362   Subject::clean();
363 }
364
365 void SubjectReference::localClean()
366 {
367   DEBTRACE("SubjectReference::localClean ");
368 }
369
370 std::string SubjectReference::getName()
371 {
372   std::stringstream name;
373   name << "ref-->" << _reference->getName();
374   return name.str();
375 }
376
377 Subject* SubjectReference::getReference() const
378 {
379   return _reference;
380 }
381
382 void SubjectReference::reparent(Subject *parent)
383 {
384   _parent = parent;
385 }
386
387 // ----------------------------------------------------------------------------
388
389 SubjectNode::SubjectNode(YACS::ENGINE::Node *node, Subject *parent)
390   : Subject(parent), _node(node)
391 {
392   _listSubjectInputPort.clear();
393   _listSubjectOutputPort.clear();
394   _listSubjectIDSPort.clear();
395   _listSubjectODSPort.clear();
396   _listSubjectLink.clear();
397   _listSubjectControlLink.clear();
398   _execState = YACS::UNDEFINED;
399   Dispatcher* d=Dispatcher::getDispatcher();
400   d->addObserver(this,node,"status");
401 }
402
403 /*!
404  * all destruction is done in generic class SubjectNode
405  */
406 SubjectNode::~SubjectNode()
407 {
408   DEBTRACE("SubjectNode::~SubjectNode " << getName());
409   Dispatcher::getDispatcher()->removeObserver(this,_node,"status");
410
411   ComposedNode* father = _node->getFather();
412   GuiContext::getCurrent()->_mapOfSubjectNode.erase(_node);
413   if (father)
414     try
415       {
416         Bloc *bloc = dynamic_cast<Bloc*>(father);
417         if (bloc) bloc->edRemoveChild(_node);
418         else
419           {
420             Loop *loop = dynamic_cast<Loop*>(father);
421             if (loop) loop->edRemoveChild(_node);
422             else
423               {
424                 ForEachLoop *feloop = dynamic_cast<ForEachLoop*>(father);
425                 if (feloop && getName() != ForEachLoop::NAME_OF_SPLITTERNODE) {
426                   DEBTRACE("SubjectNode::localClean: remove for each loop body");
427                   feloop->edRemoveChild(_node);
428                 }
429                 else
430                   {
431                     Switch *aSwitch = dynamic_cast<Switch*>(father);
432                     if (aSwitch) aSwitch->edRemoveChild(_node);
433                   }
434               }
435           }
436       }
437     catch (YACS::Exception &e)
438       {
439         DEBTRACE("------------------------------------------------------------------------------");
440         DEBTRACE("SubjectNode::localClean: father->edRemoveChild: YACS exception " << e.what());
441         DEBTRACE("------------------------------------------------------------------------------");
442       }
443 }
444
445 void SubjectNode::clean()
446 {
447   localClean();
448   Subject::clean();
449 }
450
451 void SubjectNode::localClean()
452 {
453   DEBTRACE("SubjectNode::localClean ");
454   removeExternalLinks();
455   {
456     list<SubjectLink*>::iterator its;
457     list<SubjectLink*> cpll = _listSubjectLink;
458     for (its = cpll.begin(); its != cpll.end(); ++its)
459       erase(*its);
460   }
461   {
462     list<SubjectControlLink*>::iterator its;
463     list<SubjectControlLink*> cplcl = _listSubjectControlLink;
464     for (its = cplcl.begin(); its != cplcl.end(); ++its)
465       erase(*its);
466   }
467   {
468     list<SubjectInputPort*>::iterator iti;
469     list<SubjectInputPort*> cpli = _listSubjectInputPort;
470     for(iti = cpli.begin(); iti != cpli.end(); ++iti)
471       erase(*iti);
472   }
473   {
474     list<SubjectOutputPort*>::iterator ito;
475     list<SubjectOutputPort*> cplo = _listSubjectOutputPort;
476     for(ito = cplo.begin(); ito != cplo.end(); ++ito)
477       erase(*ito);
478   }
479   {
480     list<SubjectInputDataStreamPort*>::iterator itid;
481     list<SubjectInputDataStreamPort*> cplid = _listSubjectIDSPort;
482     for(itid = cplid.begin(); itid != cplid.end(); ++itid)
483       erase(*itid);
484   }
485   {
486     list<SubjectOutputDataStreamPort*>::iterator itod;
487     list<SubjectOutputDataStreamPort*> cplod = _listSubjectODSPort;
488     for(itod = cplod.begin(); itod != cplod.end(); ++itod)
489       erase(*itod);
490   }
491   if (_parent)
492     {
493       if( SubjectBloc* sb = dynamic_cast<SubjectBloc*>(_parent) )
494         sb->removeNode(this);
495       else if( SubjectForLoop* sfl = dynamic_cast<SubjectForLoop*>(_parent) )
496         sfl->completeChildrenSubjectList( 0 );
497       else if( SubjectWhileLoop* swl = dynamic_cast<SubjectWhileLoop*>(_parent) )
498         swl->completeChildrenSubjectList( 0 );
499       else if( SubjectForEachLoop* sfel = dynamic_cast<SubjectForEachLoop*>(_parent) )
500         sfel->completeChildrenSubjectList( 0 );
501       else if( SubjectSwitch* ss = dynamic_cast<SubjectSwitch*>(_parent) )
502         ss->removeNode(this);
503     }
504 }
505
506 bool SubjectNode::reparent(Subject* parent)
507 {
508   DEBTRACE("SubjectNode::reparent");
509   Subject *sop = getParent(); // --- old parent subject
510   SubjectComposedNode *snp = dynamic_cast<SubjectComposedNode*>(parent); // --- new parent subject
511   if (!snp)
512     {
513       GuiContext::getCurrent()->_lastErrorMessage = "new parent must be a composed node";
514       DEBTRACE(GuiContext::getCurrent()->_lastErrorMessage);
515       return false;
516     }
517   ComposedNode *cnp = dynamic_cast<ComposedNode*>(snp->getNode());
518   assert(cnp);
519   Proc *proc = GuiContext::getCurrent()->getProc();
520
521   string position = "";
522   if (proc != dynamic_cast<Proc*>(_node))
523     position = proc->getChildName(_node);
524   else
525     position = _node->getName();
526
527   string newParent = "";
528   if (proc != dynamic_cast<Proc*>(cnp))
529     newParent = proc->getChildName(cnp);
530   else
531     newParent = cnp->getName();
532
533   CommandReparentNode *command = new CommandReparentNode(position, newParent);
534   if (command->execute())
535     {
536       GuiContext::getCurrent()->getInvoc()->add(command);
537       sop->update(CUT, ProcInvoc::getTypeOfNode(_node), this);
538       snp->update(PASTE, ProcInvoc::getTypeOfNode(_node), this);
539       recursiveUpdate(RENAME, 0, this);
540       _parent = snp;
541       return true;
542     }
543   else delete command;
544   DEBTRACE(GuiContext::getCurrent()->_lastErrorMessage);
545   return false;
546 }
547
548 void SubjectNode::recursiveUpdate(GuiEvent event, int type, Subject* son)
549 {
550   update(event, type, son);
551 }
552
553 bool SubjectNode::copy(Subject* parent)
554 {
555   DEBTRACE("SubjectNode::copy");
556   Subject *sop = getParent(); // --- old parent subject
557   SubjectComposedNode *snp = dynamic_cast<SubjectComposedNode*>(parent); // --- new parent subject
558   if (!snp)
559     {
560       GuiContext::getCurrent()->_lastErrorMessage = "new parent must be a composed node";
561       DEBTRACE(GuiContext::getCurrent()->_lastErrorMessage);
562       return false;
563     }
564   ComposedNode *cnp = dynamic_cast<ComposedNode*>(snp->getNode());
565   assert(cnp);
566   Proc *proc = GuiContext::getCurrent()->getProc();
567
568   string position = "";
569   if (proc != dynamic_cast<Proc*>(_node))
570     position = proc->getChildName(_node);
571   else
572     position = _node->getName();
573
574   string newParent = "";
575   if (proc != dynamic_cast<Proc*>(cnp))
576     newParent = proc->getChildName(cnp);
577   else
578     newParent = cnp->getName();
579
580   CommandCopyNode *command = new CommandCopyNode(position, newParent);
581   if (command->execute())
582     {
583       GuiContext::getCurrent()->getInvoc()->add(command);
584       Node *clone = command->getNode();
585       DEBTRACE(snp->getName());
586       DEBTRACE(clone->getName());
587       SubjectNode *son = snp->addSubjectNode(clone);
588       son->loadChildren();
589       son->loadLinks();
590       return true;
591     }
592   else delete command;
593   DEBTRACE(GuiContext::getCurrent()->_lastErrorMessage);
594   return false;
595
596 }
597
598 std::string SubjectNode::getName()
599 {
600   return _node->getName();
601 }
602
603 YACS::ENGINE::Node* SubjectNode::getNode()
604 {
605   return _node;
606 }
607
608 bool SubjectNode::setName(std::string name)
609 {
610   DEBTRACE("SubjectNode::setName " << name);
611   Proc *proc = GuiContext::getCurrent()->getProc();
612   string position = "";
613   if (proc != dynamic_cast<Proc*>(_node))
614     position = proc->getChildName(_node);
615   else
616     position = _node->getName();
617   CommandRenameNode* command = new CommandRenameNode(position, name);
618   if (command->execute())
619     {
620       GuiContext::getCurrent()->getInvoc()->add(command);
621       recursiveUpdate(RENAME, 0, this);
622       return true;
623     }
624   else delete command;
625   return false;
626 }
627
628 void SubjectNode::notifyObserver(Node* object,const std::string& event)
629 {
630   DEBTRACE("SubjectNode::notifyObserver " << object->getName() << " " << event);
631   TypeOfElem ntyp = ProcInvoc::getTypeOfNode(object);
632   update(UPDATE, ntyp , 0 );
633 }
634
635 SubjectInputPort* SubjectNode::addSubjectInputPort(YACS::ENGINE::InputPort *port,
636                                                    std::string name)
637 {
638   string theName = name;
639   if (name.empty()) theName =port->getName();
640   DEBTRACE("SubjectNode::addSubjectInputPort "<< theName);
641   SubjectInputPort *son = new SubjectInputPort(port, this);
642   GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
643   _listSubjectInputPort.push_back(son);
644   if (!name.empty()) son->setName(name);
645   update(ADD, INPUTPORT ,son);
646   YACS::ENGINE::TypeCode *typcod = port->edGetType();
647   GuiContext::getCurrent()->getSubjectProc()->addSubjectDataType(typcod, typcod->name());
648   return son;
649 }
650
651 void SubjectNode::update( GuiEvent event, int type, Subject* son )
652 {
653   Subject::update( event, type, son );
654   
655   // remove subject data type if necessary
656   YACS::HMI::SubjectDataPort* aSPort = dynamic_cast< YACS::HMI::SubjectDataPort* >( son );
657 //   if ( aSPort && event == REMOVE )
658 //   {
659 //     YACS::ENGINE::DataPort* aEPort = aSPort->getPort();
660 //     if ( aEPort )
661 //     {
662 //       YACS::ENGINE::TypeCode* aTypeCode = aEPort->edGetType();
663 //       if ( aTypeCode )
664 //         GuiContext::getCurrent()->getSubjectProc()->removeSubjectDataType( aTypeCode );
665 //     }
666 //   }
667 }
668
669 void SubjectNode::setExecState(int execState)
670 {
671   _execState = execState;
672   update(YACS::HMI::UPDATEPROGRESS, _execState, this);
673 }
674
675 SubjectOutputPort* SubjectNode::addSubjectOutputPort(YACS::ENGINE::OutputPort *port,
676                                                      std::string name)
677 {
678   string theName = name;
679   if (name.empty()) theName =port->getName();
680   DEBTRACE("SubjectNode::addSubjectOutputPort "<< theName);
681   SubjectOutputPort *son = new SubjectOutputPort(port, this);
682   GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
683   _listSubjectOutputPort.push_back(son);
684   if (!name.empty()) son->setName(name);
685   update(ADD, OUTPUTPORT ,son);
686   YACS::ENGINE::TypeCode *typcod = port->edGetType();
687   GuiContext::getCurrent()->getSubjectProc()->addSubjectDataType(typcod, typcod->name());
688   return son;
689 }
690
691 SubjectInputDataStreamPort* SubjectNode::addSubjectIDSPort(YACS::ENGINE::InputDataStreamPort *port,
692                                                            std::string name)
693 {
694   string theName = name;
695   if (name.empty()) theName =port->getName();
696   DEBTRACE("SubjectNode::addSubjectIDSPort "<< theName);
697   SubjectInputDataStreamPort *son = new SubjectInputDataStreamPort(port, this);
698   GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
699   _listSubjectIDSPort.push_back(son);
700   if (!name.empty()) son->setName(name);
701   update(ADD, INPUTDATASTREAMPORT ,son);
702   YACS::ENGINE::TypeCode *typcod = port->edGetType();
703   GuiContext::getCurrent()->getSubjectProc()->addSubjectDataType(typcod, typcod->name());
704   return son;
705 }
706
707
708 SubjectOutputDataStreamPort* SubjectNode::addSubjectODSPort(YACS::ENGINE::OutputDataStreamPort *port,
709                                                             std::string name)
710 {
711   string theName = name;
712   if (name.empty()) theName =port->getName();
713   DEBTRACE("SubjectNode::addSubjectODSPort "<< theName);
714   SubjectOutputDataStreamPort *son = new SubjectOutputDataStreamPort(port, this);
715   GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
716   _listSubjectODSPort.push_back(son);
717   if (!name.empty()) son->setName(name);
718   update(ADD, OUTPUTDATASTREAMPORT ,son);
719   YACS::ENGINE::TypeCode *typcod = port->edGetType();
720   GuiContext::getCurrent()->getSubjectProc()->addSubjectDataType(typcod, typcod->name());
721   return son;
722 }
723
724 bool SubjectNode::tryCreateLink(SubjectNode *subOutNode, SubjectNode *subInNode)
725 {
726   DEBTRACE("SubjectNode::tryCreateLink " << subOutNode->getName() << " " << subInNode->getName());
727   Proc *proc = GuiContext::getCurrent()->getProc();
728   Node *outNode = subOutNode->getNode();
729   string outNodePos = proc->getChildName(outNode);
730   Node *inNode = subInNode->getNode();
731   string inNodePos = proc->getChildName(inNode);
732   CommandAddControlLink *command = new CommandAddControlLink(outNodePos, inNodePos);
733   if (command->execute())
734     {
735       GuiContext::getCurrent()->getInvoc()->add(command);
736       ComposedNode *cla = ComposedNode::getLowestCommonAncestor(outNode->getFather(),
737                                                                 inNode->getFather());
738       SubjectComposedNode *scla = dynamic_cast<SubjectComposedNode*>(subOutNode->getParent());
739       ComposedNode *ancestor = outNode->getFather();
740       while (ancestor && ancestor != cla)
741         {
742           ancestor = ancestor->getFather();
743           scla = dynamic_cast<SubjectComposedNode*>(scla->getParent());
744           assert(scla);
745         }
746       DEBTRACE(scla->getName());
747       scla->addSubjectControlLink(subOutNode,subInNode);
748       return true;
749     }
750   else
751     {
752       delete command;
753       return false;
754     }
755 }
756
757 void SubjectNode::removeExternalLinks()
758 {
759   DEBTRACE("SubjectNode::removeExternalLinks " << getName());
760   std::vector< std::pair<OutPort *, InPort *> > listLeaving  = getNode()->getSetOfLinksLeavingCurrentScope();
761   std::vector< std::pair<InPort *, OutPort *> > listIncoming = getNode()->getSetOfLinksComingInCurrentScope();
762   std::vector< std::pair<OutPort *, InPort *> > globalList = listLeaving;
763   std::vector< std::pair<InPort *, OutPort *> >::iterator it1;
764   for (it1 = listIncoming.begin(); it1 != listIncoming.end(); ++it1)
765     {
766       std::pair<OutPort *, InPort *> outin = std::pair<OutPort *, InPort *>((*it1).second, (*it1).first);
767       globalList.push_back(outin);
768     }
769   std::vector< std::pair<OutPort *, InPort *> >::iterator it2;
770   for (it2 = globalList.begin(); it2 != globalList.end(); ++it2)
771     {
772       SubjectLink* subject = 0;
773       if (GuiContext::getCurrent()->_mapOfSubjectLink.count(*it2))
774         {
775           subject = GuiContext::getCurrent()->_mapOfSubjectLink[*it2];
776           assert(subject);
777           DEBTRACE("link to remove " << subject->getName());
778           erase(subject);
779           GuiContext::getCurrent()->_mapOfSubjectLink.erase(*it2);
780         }
781       else
782         {
783           DEBTRACE("------------------------------------------------------------------------------");
784           DEBTRACE("SubjectNode::removeExternalLinks(): an external link not in map...");
785           DEBTRACE("------------------------------------------------------------------------------");
786         }
787     } 
788 }
789
790 void SubjectNode::removeExternalControlLinks()
791 {
792   DEBTRACE("SubjectNode::removeExternalControlLinks " << getName());
793   list<SubjectControlLink*> cplcl = getSubjectControlLinks();
794   list<SubjectControlLink*>::iterator its;
795   Node* node = getNode();
796   for (its = cplcl.begin(); its != cplcl.end(); ++its)
797     {
798       bool inside = true;
799       Node *nout = (*its)->getSubjectOutNode()->getNode();
800       Node *nin = (*its)->getSubjectInNode()->getNode();
801       inside = inside && (node == nout);
802       inside = inside && (node == nin);
803       if (!inside)
804         Subject::erase(*its);
805     }
806 }
807
808 // ----------------------------------------------------------------------------
809
810 SubjectComposedNode::SubjectComposedNode(YACS::ENGINE::ComposedNode *composedNode,
811                                          Subject *parent)
812   : SubjectNode(composedNode, parent), _composedNode(composedNode)
813 {
814 }
815
816 /*!
817  * all generic destruction is done in generic class SubjectNode
818  */
819 SubjectComposedNode::~SubjectComposedNode()
820 {
821   DEBTRACE("SubjectComposedNode::~SubjectComposedNode " << getName());
822 }
823
824 void SubjectComposedNode::clean()
825 {
826   localClean();
827   SubjectNode::clean();
828 }
829
830 void SubjectComposedNode::localClean()
831 {
832   DEBTRACE("SubjectComposedNode::localClean ");
833 }
834
835 SubjectNode* SubjectComposedNode::addNode(YACS::ENGINE::Catalog *catalog,
836                                           std::string compo,
837                                           std::string type,
838                                           std::string name)
839 {
840   DEBTRACE("SubjectComposedNode::addNode("<<catalog<<","<<compo<<","<<type<<","<<name<<")");
841   SubjectNode* body = 0;
842   return body;
843 }
844
845 SubjectNode *SubjectComposedNode::createNode(YACS::ENGINE::Catalog *catalog,
846                                              std::string compo,
847                                              std::string type,
848                                              std::string name,
849                                              int swCase)
850 {
851   Proc *proc = GuiContext::getCurrent()->getProc();
852   string position = "";
853   if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
854   CommandAddNodeFromCatalog *command = new CommandAddNodeFromCatalog(catalog,
855                                                                      compo,
856                                                                      type,
857                                                                      position,
858                                                                      name,
859                                                                      swCase);
860   if (command->execute())
861     {
862       GuiContext::getCurrent()->getInvoc()->add(command);
863       Node * node = command->getNode();
864       SubjectNode *son = addSubjectNode(node,"",catalog,compo,type);
865       son->loadChildren();
866       son->loadLinks();
867       return son;
868     }
869   else delete command;
870   return 0;
871 }
872
873 SubjectNode *SubjectComposedNode::addSubjectNode(YACS::ENGINE::Node * node,
874                                                  std::string name,
875                                                  YACS::ENGINE::Catalog *catalog,
876                                                  std::string compo,
877                                                  std::string type)
878 {
879   string theName = name;
880   if (name.empty()) theName =node->getName();
881   DEBTRACE("SubjectComposedNode::addSubjectNode "<< theName);
882   TypeOfElem ntyp = ProcInvoc::getTypeOfNode(node);
883   DEBTRACE("TypeOfNode: " << ntyp);
884   SubjectNode *son = 0;
885   switch(ntyp)
886     {
887     case BLOC:
888       son = new SubjectBloc(dynamic_cast<YACS::ENGINE::Bloc*>(node), this);
889       break;
890     case PYTHONNODE:
891       son = new SubjectPythonNode(dynamic_cast<YACS::ENGINE::PythonNode*>(node), this);
892       break;
893     case PYFUNCNODE:
894       son = new SubjectPyFuncNode(dynamic_cast<YACS::ENGINE::PyFuncNode*>(node), this);
895       break;
896     case CORBANODE:
897       son = new SubjectCORBANode(dynamic_cast<YACS::ENGINE::CORBANode*>(node), this);
898       break;
899     case CPPNODE:
900       son = new SubjectCppNode(dynamic_cast<YACS::ENGINE::CppNode*>(node), this);
901       break;
902     case SALOMENODE:
903       son = new SubjectSalomeNode(dynamic_cast<YACS::ENGINE::SalomeNode*>(node), this);
904       break;
905     case SALOMEPYTHONNODE:
906       son = new SubjectSalomePythonNode(dynamic_cast<YACS::ENGINE::SalomePythonNode*>(node), this);
907       break;
908     case XMLNODE:
909       son = new SubjectXmlNode(dynamic_cast<YACS::ENGINE::XmlNode*>(node), this);
910       break;
911     case SPLITTERNODE:
912       son = new SubjectSplitterNode(dynamic_cast<YACS::ENGINE::SplitterNode*>(node), this);
913       break;
914     case PRESETNODE:
915       son = new SubjectPresetNode(dynamic_cast<YACS::ENGINE::PresetNode*>(node), this);
916       break;
917     case OUTNODE:
918       son = new SubjectOutNode(dynamic_cast<YACS::ENGINE::OutNode*>(node), this);
919       break;
920     case STUDYINNODE:
921       son = new SubjectStudyInNode(dynamic_cast<YACS::ENGINE::StudyInNode*>(node), this);
922       break;
923     case STUDYOUTNODE:
924       son = new SubjectStudyOutNode(dynamic_cast<YACS::ENGINE::StudyOutNode*>(node), this);
925       break;
926     case FORLOOP:
927       son = new SubjectForLoop(dynamic_cast<YACS::ENGINE::ForLoop*>(node), this);
928       break;
929     case WHILELOOP:
930       son = new SubjectWhileLoop(dynamic_cast<YACS::ENGINE::WhileLoop*>(node), this);
931       break;
932     case SWITCH:
933       son = new SubjectSwitch(dynamic_cast<YACS::ENGINE::Switch*>(node), this);
934       break;
935     case FOREACHLOOP:
936       son = new SubjectForEachLoop(dynamic_cast<YACS::ENGINE::ForEachLoop*>(node), this);
937       break;
938     case OPTIMIZERLOOP:
939       son = new SubjectOptimizerLoop(dynamic_cast<YACS::ENGINE::OptimizerLoop*>(node), this);
940       break;
941     default:
942       throw YACS::Exception("Not implemented");
943       //assert(0);
944     }
945   assert(son);
946   GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(node)] = son;
947   GuiContext::getCurrent()->_mapOfExecSubjectNode[node->getNumId()] = son;
948   if (!name.empty()) son->setName(name);
949   completeChildrenSubjectList(son);
950   update(ADD, ntyp ,son);
951   if (SubjectServiceNode *service = dynamic_cast<SubjectServiceNode*>(son))
952     if (catalog && !compo.empty() && !type.empty()) // --- clone from catalog: set component
953       service->setComponentFromCatalog(catalog,compo,type);
954     else
955       service->setComponent();
956   return son;
957 }
958
959 void SubjectComposedNode::completeChildrenSubjectList(SubjectNode *son)
960 {
961 }
962
963 void SubjectComposedNode::loadChildren()
964 {
965   list<Node *> setOfNode= _composedNode->edGetDirectDescendants();
966   if (ForEachLoop *feloop = dynamic_cast<ForEachLoop*>(_composedNode))
967     {
968       Node *node2Insert=feloop->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE);
969       if(find(setOfNode.begin(),setOfNode.end(),node2Insert)==setOfNode.end())
970         setOfNode.push_back(node2Insert);
971     }
972   for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
973     {
974       try
975         {
976           SubjectNode * son = addSubjectNode(*iter);
977           son->loadChildren();
978         }
979       catch(YACS::Exception& ex)
980         {
981           std::cerr << "Unknown type of node" << std::endl;
982         }
983     }
984   list<InputPort*>  listInputPorts  = _composedNode->getLocalInputPorts();
985   list<OutputPort*> listOutputPorts = _composedNode->getLocalOutputPorts();
986   list<InputDataStreamPort*>  listIDSPorts = _composedNode->getSetOfInputDataStreamPort();
987   list<OutputDataStreamPort*> listODSPorts = _composedNode->getSetOfOutputDataStreamPort();
988   list<InputPort*>::const_iterator iti;
989   for (iti = listInputPorts.begin(); iti != listInputPorts.end(); ++iti)
990     addSubjectInputPort(*iti);
991   list<OutputPort*>::const_iterator ito;
992   for (ito = listOutputPorts.begin(); ito != listOutputPorts.end(); ++ito)
993     addSubjectOutputPort(*ito);
994 }
995
996 SubjectLink* SubjectComposedNode::addSubjectLink(SubjectNode *sno,
997                                                  SubjectDataPort *spo,
998                                                  SubjectNode *sni,
999                                                  SubjectDataPort *spi)
1000 {
1001   DEBTRACE("SubjectComposedNode::addSubjectLink");
1002   SubjectLink *son = new SubjectLink(sno, spo, sni, spi, this);
1003   OutPort *outp = sno->getNode()->getOutPort(spo->getName());
1004   InPort *inp = sni->getNode()->getInPort(spi->getName());
1005   pair<OutPort*,InPort*> keyLink(outp,inp);
1006   GuiContext::getCurrent()->_mapOfSubjectLink[keyLink] = son;
1007   _listSubjectLink.push_back(son);
1008   spo->addSubjectLink(son);
1009   spi->addSubjectLink(son);
1010   update(ADDLINK, DATALINK, son);
1011   DEBTRACE("addSubjectLink: " << getName() << " " << son->getName());
1012   return son;
1013 }
1014
1015 void SubjectComposedNode::removeLink(SubjectLink* link)
1016 {
1017   DEBTRACE("removeSubjectLink: " << link->getName());
1018
1019   OutPort *outp = dynamic_cast<OutPort*>(link->getSubjectOutPort()->getPort());
1020   InPort  *inp  = dynamic_cast<InPort*>(link->getSubjectInPort()->getPort());
1021   pair<OutPort*,InPort*> keyLink(outp,inp);
1022   if (GuiContext::getCurrent()->_mapOfSubjectLink.count(keyLink))
1023     {
1024       DEBTRACE(outp->getName() << " " << inp->getName());
1025       GuiContext::getCurrent()->_mapOfSubjectLink.erase(keyLink);
1026     }
1027
1028   link->getSubjectOutPort()->removeSubjectLink(link);
1029   link->getSubjectInPort()->removeSubjectLink(link);
1030   _listSubjectLink.remove(link);
1031 }
1032
1033 SubjectControlLink* SubjectComposedNode::addSubjectControlLink(SubjectNode *sno,
1034                                                         SubjectNode *sni)
1035 {
1036   SubjectControlLink *son = new SubjectControlLink(sno, sni, this);
1037   Node *outn = sno->getNode();
1038   Node *inn = sni->getNode();
1039   pair<Node*,Node*> keyLink(outn,inn);
1040
1041   GuiContext::getCurrent()->_mapOfSubjectControlLink[keyLink] = son;
1042   _listSubjectControlLink.push_back(son);
1043   sno->addSubjectControlLink(son);
1044   sni->addSubjectControlLink(son);
1045   update(ADDCONTROLLINK, CONTROLLINK, son);
1046   DEBTRACE("addSubjectControlLink: " << getName() << " " << son->getName());
1047   return son;
1048 }
1049
1050 void SubjectComposedNode::removeControlLink(SubjectControlLink* link)
1051 {
1052   DEBTRACE("removeSubjectControlLink: " << getName());
1053
1054   Node *outn = link->getSubjectOutNode()->getNode();
1055   Node *inn = link->getSubjectInNode()->getNode();
1056   pair<Node*,Node*> keyLink(outn,inn);
1057   if (GuiContext::getCurrent()->_mapOfSubjectControlLink.count(keyLink))
1058     {
1059       DEBTRACE(outn->getName() << " " << inn->getName());
1060       GuiContext::getCurrent()->_mapOfSubjectControlLink.erase(keyLink);
1061     }
1062
1063   link->getSubjectOutNode()->removeSubjectControlLink(link);
1064   link->getSubjectInNode()->removeSubjectControlLink(link);
1065   _listSubjectControlLink.remove(link);
1066 }
1067
1068 void SubjectComposedNode::removeExternalControlLinks()
1069 {
1070   DEBTRACE("SubjectComposedNode::removeExternalControlLinks " << getName());
1071   list<SubjectControlLink*> cplcl = getSubjectControlLinks();
1072   list<SubjectControlLink*>::iterator its;
1073   ComposedNode *cnode = dynamic_cast<ComposedNode*>(getNode());
1074   for (its = cplcl.begin(); its != cplcl.end(); ++its)
1075     {
1076       bool inside = true;
1077       Node *nout = (*its)->getSubjectOutNode()->getNode();
1078       Node *nin = (*its)->getSubjectInNode()->getNode();
1079       inside = inside && cnode->isInMyDescendance(nout); // --- 0 if nout is outside
1080       inside = inside && cnode->isInMyDescendance(nin);  // --- 0 if nin is outside
1081       if (!inside)
1082         Subject::erase(*its);
1083     }
1084 }   
1085
1086 /*!
1087  * loadLinks is used when an existing scheme has been loaded in memory, to create gui representation.
1088  * Gui representation of links is done after node representation (loadChildren).
1089  * Proc is explored recursively to find the composedNodes and create the corresponding links
1090  * representation, from bottom to top.
1091  * For each composedNode, data links representation are created first and stored in a map to avoid
1092  * double representation. Then control links representation are created.
1093  */
1094 void SubjectComposedNode::loadLinks()
1095 {
1096   list<Node *> setOfNode= _composedNode->edGetDirectDescendants();
1097   for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1098     {
1099       ComposedNode *cnSon = dynamic_cast<ComposedNode*>(*iter);
1100       if (cnSon)
1101         {
1102           SubjectNode *subSon = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(*iter)];
1103           assert(subSon);
1104           SubjectComposedNode *subCnSon = dynamic_cast<SubjectComposedNode*>(subSon);
1105           assert (subCnSon);
1106           subCnSon->loadLinks();
1107         }
1108     }
1109
1110   std::vector<std::pair<OutPort*,InPort*> > setOfLinks = _composedNode->getSetOfInternalLinks();
1111   std::vector<std::pair<OutPort*,InPort*> >::iterator itp;
1112   for (itp = setOfLinks.begin(); itp != setOfLinks.end(); ++itp)
1113     if (!GuiContext::getCurrent()->_mapOfSubjectLink.count(*itp))
1114       {
1115         OutPort *outp = (*itp).first;
1116         InPort *inp = (*itp).second;
1117         Node *outn = outp->getNode();
1118         Node *inn = inp->getNode();
1119         DEBTRACE(outn->getName()<<"."<<outp->getName()<<"->"<<inn->getName()<<"."<<inp->getName());
1120         SubjectNode *sno = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(outn)];
1121         SubjectNode *sni = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(inn)];
1122         SubjectDataPort *spo = GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(outp)];
1123         SubjectDataPort *spi = GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(inp)];
1124         addSubjectLink(sno,spo,sni,spi);
1125       }
1126
1127   std::list<Node*> setOfNodes = _composedNode->edGetDirectDescendants();
1128   std::list<Node*>::const_iterator itn;
1129   for(itn = setOfNodes.begin(); itn != setOfNodes.end(); ++itn)
1130     {
1131       SubjectNode* sno = GuiContext::getCurrent()->_mapOfSubjectNode[*itn];
1132       OutGate* outgate = (*itn)->getOutGate();
1133       std::set<InGate*> setIngate = outgate->edSetInGate();
1134       std::set<InGate*>::const_iterator itg;
1135       for(itg = setIngate.begin(); itg != setIngate.end(); ++itg)
1136         {
1137           Node* inNode = (*itg)->getNode();
1138           SubjectNode* sni = GuiContext::getCurrent()->_mapOfSubjectNode[inNode];
1139           if(sno && sni)
1140             addSubjectControlLink(sno,sni);
1141         }
1142     }
1143 }
1144
1145 //! Retrieves the lowest common ancestor of 2 nodes
1146 /*!
1147  * 
1148  * \note Retrieves the lowest common ancestor of 'node1' AND 'node2'. 
1149  *       If  'node1' or 'node2' are both or indiscriminately instances of ComposedNode and that
1150  *       'node1' is in descendance of 'node2' (resp. 'node2' in descendance of 'node1')
1151  *       'node2' is returned (resp. 'node1').
1152  * \exception Exception : if 'node1' and 'node2' do not share the same genealogy.
1153  * \return The lowest common ancestor if it exists.
1154  *
1155  */
1156 SubjectComposedNode* SubjectComposedNode::getLowestCommonAncestor(SubjectNode* snode1, SubjectNode* snode2)
1157 {
1158   Node* node1 = snode1->getNode();
1159   Node* node2 = snode2->getNode();
1160
1161   ComposedNode *node = ComposedNode::getLowestCommonAncestor(node1->getFather(), node2->getFather());
1162   SubjectComposedNode* snode = dynamic_cast<SubjectComposedNode*>( GuiContext::getCurrent()->_mapOfSubjectNode[node] );
1163   return snode;
1164 }
1165
1166 /*! used in derived classes using a counter, a selector, or a condition:
1167  *  ForLoop, ForEachLoop, Switch, WhileLoop.
1168  */
1169 bool SubjectComposedNode::hasValue()
1170 {
1171   return false;
1172 }
1173
1174 /*! used in derived classes using a counter, a selector, or a condition:
1175  *  ForLoop, ForEachLoop, Switch, WhileLoop.
1176  */
1177 std::string SubjectComposedNode::getValue()
1178 {
1179   return "";
1180 }
1181
1182
1183 // ----------------------------------------------------------------------------
1184
1185 SubjectBloc::SubjectBloc(YACS::ENGINE::Bloc *bloc, Subject *parent)
1186   : SubjectComposedNode(bloc, parent), _bloc(bloc)
1187 {
1188   _children.clear();
1189 }
1190
1191 /*!
1192  * all generic destruction is done in generic class SubjectNode
1193  */
1194 SubjectBloc::~SubjectBloc()
1195 {
1196   DEBTRACE("SubjectBloc::~SubjectBloc " << getName());
1197 }
1198
1199 void SubjectBloc::clean()
1200 {
1201   localClean();
1202   SubjectComposedNode::clean();
1203 }
1204
1205 void SubjectBloc::localClean()
1206 {
1207   DEBTRACE("SubjectBloc::localClean ");
1208   set<SubjectNode*>::iterator it;
1209   set<SubjectNode*> copyChildren = _children;
1210   for (it = copyChildren.begin(); it !=copyChildren.end(); ++it)
1211     erase(*it);
1212 }
1213
1214 SubjectNode* SubjectBloc::addNode(YACS::ENGINE::Catalog *catalog,
1215                                   std::string compo,
1216                                   std::string type,
1217                                   std::string name)
1218 {
1219   DEBTRACE("SubjectBloc::addNode( " << catalog << ", " << compo << ", " << type << ", " << name << " )");
1220   SubjectNode* child = createNode(catalog, compo, type, name);
1221   return child;
1222 }
1223
1224 void SubjectBloc::completeChildrenSubjectList(SubjectNode *son)
1225 {
1226   _children.insert(son);
1227 }
1228
1229 void SubjectBloc::removeNode(SubjectNode* child)
1230 {
1231   _children.erase(child);
1232 }
1233
1234 SubjectNode* SubjectBloc::getChild(YACS::ENGINE::Node* node) const
1235 {
1236   SubjectNode* aChild = 0;
1237
1238   if (node)
1239   {
1240     set<SubjectNode*>::iterator it = _children.begin();
1241     for ( ; it != _children.end(); it++ )
1242       if ( (*it)->getNode() == node )
1243       {
1244         aChild = (*it);
1245         break;
1246       }
1247   }
1248
1249   return aChild;
1250 }
1251
1252 void SubjectBloc::recursiveUpdate(GuiEvent event, int type, Subject* son)
1253 {
1254   update(event, type, son);
1255   set<SubjectNode*>::iterator it = _children.begin();
1256   for (; it != _children.end(); ++it)
1257     (*it)->recursiveUpdate(event, type, son);
1258 }
1259
1260
1261 // ----------------------------------------------------------------------------
1262
1263 SubjectProc::SubjectProc(YACS::ENGINE::Proc *proc, Subject *parent)
1264   : SubjectBloc(proc, parent), _proc(proc)
1265 {
1266 }
1267
1268 SubjectProc::~SubjectProc()
1269 {
1270   DEBTRACE("SubjectProc::~SubjectProc " << getName());
1271 }
1272
1273 void SubjectProc::clean()
1274 {
1275   localClean();
1276   SubjectBloc::clean();
1277 }
1278
1279 void SubjectProc::localClean()
1280 {
1281   DEBTRACE("SubjectProc::localClean ");
1282 }
1283
1284 void SubjectProc::loadProc()
1285 {
1286   DEBTRACE("SubjectProc::loadProc "  << getName());
1287   loadContainers();
1288   loadComponents();
1289   loadChildren();
1290   loadLinks();
1291 }
1292
1293 /*!
1294  * loadComponents is used when an existing scheme has been loaded in memory,
1295  * to create subjects for components stored in the schema file, but are not
1296  * associated with any service nodes. Note, that if such component is associated
1297  * to any container, the subject for this container is also created, if it is not
1298  * exist yet.
1299  */
1300 void SubjectProc::loadComponents()
1301 {
1302   Proc* aProc = GuiContext::getCurrent()->getProc();
1303   for (map<pair<string,int>, ComponentInstance*>::const_iterator itComp = aProc->componentInstanceMap.begin();
1304        itComp != aProc->componentInstanceMap.end(); ++itComp)
1305     if ( GuiContext::getCurrent()->_mapOfSubjectComponent.find((*itComp).second)
1306          ==
1307          GuiContext::getCurrent()->_mapOfSubjectComponent.end() )
1308     { // engine object for component already exists => add only a subject for it
1309       addSubjectComponent((*itComp).second);
1310     }
1311 }
1312
1313 /*!
1314  * loadContainers is used when an existing scheme has been loaded in memory,
1315  * to create subjects for containers stored in the schema file, but are not
1316  * associated with components.
1317  */
1318 void SubjectProc::loadContainers()
1319 {
1320   Proc* aProc = GuiContext::getCurrent()->getProc();
1321   for (map<string, Container*>::const_iterator itCont = aProc->containerMap.begin();
1322        itCont != aProc->containerMap.end(); ++itCont)
1323     if ( GuiContext::getCurrent()->_mapOfSubjectContainer.find((*itCont).second)
1324          ==
1325          GuiContext::getCurrent()->_mapOfSubjectContainer.end() )
1326       // engine object for container already exists => add only a subject for it
1327       addSubjectContainer((*itCont).second, (*itCont).second->getName());
1328 }
1329
1330 SubjectComponent* SubjectProc::addComponent(std::string name)
1331 {
1332   DEBTRACE("SubjectProc::addComponent " << name);
1333   CommandAddComponentInstance *command = new CommandAddComponentInstance(name);
1334   if (command->execute())
1335     {
1336       GuiContext::getCurrent()->getInvoc()->add(command);
1337       ComponentInstance *compo = command->getComponentInstance();
1338       SubjectComponent *son = addSubjectComponent(compo);
1339       return son;
1340     }
1341   else delete command;
1342   return 0;
1343 }
1344
1345 SubjectContainer* SubjectProc::addContainer(std::string name, std::string ref)
1346 {
1347   DEBTRACE("SubjectProc::addContainer " << name << " " << ref);
1348   if (! GuiContext::getCurrent()->getProc()->containerMap.count(name))
1349     {
1350       CommandAddContainer *command = new CommandAddContainer(name,ref);
1351       if (command->execute())
1352         {
1353           GuiContext::getCurrent()->getInvoc()->add(command);
1354           Container *cont = command->getContainer();
1355           SubjectContainer *son = addSubjectContainer(cont, name);
1356           GuiContext::getCurrent()->getProc()->containerMap[name] = cont;
1357           return son;
1358         }
1359       else
1360           delete command;
1361     }
1362   else GuiContext::getCurrent()->_lastErrorMessage = "There is already a container with that name";
1363   return 0;
1364 }
1365
1366 SubjectDataType* SubjectProc::addDataType(YACS::ENGINE::Catalog* catalog, std::string typeName)
1367 {
1368   DEBTRACE("SubjectProc::addDataType " << typeName);
1369   CommandAddDataTypeFromCatalog *command = new CommandAddDataTypeFromCatalog(catalog, typeName);
1370   if (command->execute())
1371     {
1372       DEBTRACE("new datatype " << typeName);
1373       GuiContext::getCurrent()->getInvoc()->add(command);
1374       SubjectDataType *son = addSubjectDataType(command->getTypeCode(), typeName);
1375       return son;
1376     }
1377   else delete command;
1378   return 0;
1379 }
1380
1381 SubjectComponent* SubjectProc::addSubjectComponent(YACS::ENGINE::ComponentInstance* compo)
1382 {
1383   DEBTRACE("SubjectProc::addSubjectComponent " << compo->getInstanceName());
1384   SubjectComponent *son = new SubjectComponent(compo, this);
1385   GuiContext::getCurrent()->_mapOfSubjectComponent[compo] = son;
1386   update(ADD, COMPONENT, son);
1387   //son->setContainer();
1388   return son;
1389 }
1390
1391 SubjectContainer* SubjectProc::addSubjectContainer(YACS::ENGINE::Container* cont,
1392                                                    std::string name)
1393 {
1394   DEBTRACE("SubjectProc::addSubjectContainer " << name);
1395   SubjectContainer *son = new SubjectContainer(cont, this);
1396   GuiContext::getCurrent()->_mapOfSubjectContainer[cont] = son;
1397   update(ADD, CONTAINER, son);
1398   return son;
1399 }
1400
1401 SubjectDataType* SubjectProc::addSubjectDataType(YACS::ENGINE::TypeCode *type, std::string alias)
1402 {
1403   string typeName = type->name();
1404   DEBTRACE("SubjectProc::addSubjectDataType " << typeName);
1405   Proc* proc = GuiContext::getCurrent()->getProc();
1406   SubjectDataType* son = 0;
1407   if (! proc->typeMap.count(typeName))
1408     proc->typeMap[ typeName ] = type->clone();
1409   else 
1410     proc->typeMap[ typeName ]->incrRef();
1411   if (! GuiContext::getCurrent()->_mapOfSubjectDataType.count(typeName))
1412     {
1413       son = new SubjectDataType(type, this, alias);
1414       GuiContext::getCurrent()->_mapOfSubjectDataType[typeName] = son;
1415       update(ADD, DATATYPE, son);
1416     }
1417   else
1418     GuiContext::getCurrent()->_lastErrorMessage = "Typecode " + typeName + " already had added in proc";
1419   return son;
1420 }
1421
1422 void SubjectProc::removeSubjectDataType( YACS::ENGINE::TypeCode* theType )
1423 {
1424   if ( !theType )
1425     return;
1426
1427   YACS::HMI::GuiContext* aContext = GuiContext::getCurrent();
1428   if ( !aContext )
1429     return;
1430
1431   YACS::ENGINE::Proc* aProc = aContext->getProc();
1432   if ( !aProc )
1433     return;
1434
1435   string typeName = theType->name();
1436   if ( !aProc->typeMap.count( typeName ) )
1437     return;
1438   
1439   YACS::ENGINE::TypeCode* aTypeCode = aProc->typeMap[ typeName ];
1440   if ( !aTypeCode )
1441     return;
1442
1443   if ( !aContext->_mapOfSubjectDataType.count( typeName ) )
1444     return;
1445
1446   YACS::HMI::SubjectDataType* aSDataType = aContext->_mapOfSubjectDataType[ typeName ];
1447   if ( !aSDataType )
1448     return;
1449
1450   unsigned int aRefCnt = aTypeCode->getRefCnt();
1451   if ( aRefCnt == 1 )
1452   {
1453 //     update( REMOVE, DATATYPE, aSDataType );
1454     aContext->_mapOfSubjectDataType.erase( typeName );
1455     aProc->typeMap.erase( typeName );
1456   }
1457
1458   aTypeCode->decrRef();
1459 }
1460
1461 // ----------------------------------------------------------------------------
1462
1463 SubjectElementaryNode::SubjectElementaryNode(YACS::ENGINE::ElementaryNode *elementaryNode,
1464                                              Subject *parent)
1465   : SubjectNode(elementaryNode, parent), _elementaryNode(elementaryNode)
1466 {
1467 }
1468
1469 /*!
1470  * all generic destruction is done in generic class SubjectNode
1471  */
1472 SubjectElementaryNode::~SubjectElementaryNode()
1473 {
1474   DEBTRACE("SubjectElementaryNode::~SubjectElementaryNode " << getName());
1475 }
1476
1477 void SubjectElementaryNode::clean()
1478 {
1479   localClean();
1480   SubjectNode::clean();
1481 }
1482
1483 void SubjectElementaryNode::localClean()
1484 {
1485   DEBTRACE("SubjectElementaryNode::localClean ");
1486 }
1487
1488 void SubjectElementaryNode::recursiveUpdate(GuiEvent event, int type, Subject* son)
1489 {
1490   update(event, type, son);
1491 }
1492
1493 SubjectDataPort* SubjectElementaryNode::addInputPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
1494 {
1495   DEBTRACE("SubjectElementaryNode::addInputPort( " << catalog << ", " << type << ", " << name << " )");
1496   Proc *proc = GuiContext::getCurrent()->getProc();
1497   string position = "";
1498   if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1499   else assert(0);
1500   CommandAddInputPortFromCatalog *command = new CommandAddInputPortFromCatalog(catalog,
1501                                                                                type,
1502                                                                                position,
1503                                                                                name);
1504   if (command->execute())
1505     {
1506       GuiContext::getCurrent()->getInvoc()->add(command);
1507       InputPort * port = command->getInputPort();
1508       SubjectInputPort *son = addSubjectInputPort(port, name);
1509       return son;
1510     }
1511   else delete command;
1512   return 0;
1513 }
1514
1515 SubjectDataPort* SubjectElementaryNode::addOutputPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
1516 {
1517   DEBTRACE("SubjectElementaryNode::addOutputPort( " << catalog << ", " << type << ", " << name << " )");
1518   Proc *proc = GuiContext::getCurrent()->getProc();
1519   string position = "";
1520   if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1521   else assert(0);
1522   CommandAddOutputPortFromCatalog *command = new CommandAddOutputPortFromCatalog(catalog,
1523                                                                                  type,
1524                                                                                  position,
1525                                                                                  name);
1526   if (command->execute())
1527     {
1528       GuiContext::getCurrent()->getInvoc()->add(command);
1529       OutputPort * port = command->getOutputPort();
1530       SubjectOutputPort *son = addSubjectOutputPort(port, name);
1531       return son;
1532     }
1533   else delete command;
1534   return 0;
1535 }
1536
1537 SubjectDataPort* SubjectElementaryNode::addIDSPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
1538 {
1539   DEBTRACE("SubjectElementaryNode::addIDSPort( " << catalog << ", " << type << ", " << name << " )");
1540   Proc *proc = GuiContext::getCurrent()->getProc();
1541   string position = "";
1542   if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1543   else assert(0);
1544   CommandAddIDSPortFromCatalog *command = new CommandAddIDSPortFromCatalog(catalog,
1545                                                                            type,
1546                                                                            position,
1547                                                                            name);
1548   if (command->execute())
1549     {
1550       GuiContext::getCurrent()->getInvoc()->add(command);
1551       InputDataStreamPort * port = command->getIDSPort();
1552       SubjectInputDataStreamPort *son = addSubjectIDSPort(port, name);
1553       return son;
1554     }
1555   else delete command;
1556   return 0;
1557 }
1558
1559 SubjectDataPort* SubjectElementaryNode::addODSPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
1560 {
1561   DEBTRACE("SubjectElementaryNode::addODSPort( " << catalog << ", " << type << ", " << name << " )");
1562   Proc *proc = GuiContext::getCurrent()->getProc();
1563   string position = "";
1564   if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1565   else assert(0);
1566   CommandAddODSPortFromCatalog *command = new CommandAddODSPortFromCatalog(catalog,
1567                                                                            type,
1568                                                                            position,
1569                                                                            name);
1570   if (command->execute())
1571     {
1572       GuiContext::getCurrent()->getInvoc()->add(command);
1573       OutputDataStreamPort * port = command->getODSPort();
1574       SubjectOutputDataStreamPort *son = addSubjectODSPort(port, name);
1575       return son;
1576     }
1577   else delete command;
1578   return 0;
1579 }
1580
1581 bool SubjectElementaryNode::OrderDataPorts(SubjectDataPort* portToMove, int isUp)
1582 {
1583   DEBTRACE("SubjectElementaryNode::OrderDataPorts");
1584   Proc *proc = GuiContext::getCurrent()->getProc();
1585   string position = "";
1586   if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1587   else assert(0);
1588
1589   if (!portToMove) return false;
1590   string nameToMove = portToMove->getName();
1591
1592   Command *command = 0;
1593   bool isInput = dynamic_cast<SubjectInputPort*>(portToMove);
1594   if (isInput)
1595     command = new CommandOrderInputPorts(position, nameToMove, isUp);
1596   else
1597     command = new CommandOrderOutputPorts(position, nameToMove, isUp);
1598
1599   if (command->execute())
1600     {
1601       GuiContext::getCurrent()->getInvoc()->add(command);
1602       update(ORDER, isInput, portToMove);
1603       update(SYNCHRO, isInput, portToMove); // --- synchronise edition and scene
1604       return true;
1605     }
1606   return false;
1607 }
1608       
1609 void SubjectElementaryNode::removePort(SubjectDataPort* port)
1610 {
1611   DEBTRACE("SubjectElementaryNode::removePort " << port->getName());
1612   if (SubjectInputPort* inp = dynamic_cast<SubjectInputPort*>(port))
1613     {
1614       DEBTRACE("-");
1615       _listSubjectInputPort.remove(inp);
1616     }
1617   else if(SubjectOutputPort* outp = dynamic_cast<SubjectOutputPort*>(port))
1618     {
1619       DEBTRACE("--");
1620       _listSubjectOutputPort.remove(outp);
1621     }
1622   if (SubjectInputDataStreamPort* idsp = dynamic_cast<SubjectInputDataStreamPort*>(port))
1623     {
1624       DEBTRACE("---");
1625       _listSubjectIDSPort.remove(idsp);
1626     }
1627   else if(SubjectOutputDataStreamPort* odsp = dynamic_cast<SubjectOutputDataStreamPort*>(port))
1628     {
1629       DEBTRACE("----");
1630       _listSubjectODSPort.remove(odsp);
1631     }
1632 }
1633
1634 void SubjectElementaryNode::loadChildren()
1635 {
1636   list<InputPort*>  listInputPorts  = _elementaryNode->getLocalInputPorts();
1637   list<OutputPort*> listOutputPorts = _elementaryNode->getLocalOutputPorts();
1638   list<InputDataStreamPort*>  listIDSPorts = _elementaryNode->getSetOfInputDataStreamPort();
1639   list<OutputDataStreamPort*> listODSPorts = _elementaryNode->getSetOfOutputDataStreamPort();
1640   if (SplitterNode *splitterNode = dynamic_cast<SplitterNode*>(_elementaryNode))
1641     listInputPorts.push_back(splitterNode->getFather()->getInputPort("SmplsCollection"));
1642   list<InputPort*>::const_iterator iti;
1643   for (iti = listInputPorts.begin(); iti != listInputPorts.end(); ++iti)
1644     addSubjectInputPort(*iti);
1645   list<OutputPort*>::const_iterator ito;
1646   for (ito = listOutputPorts.begin(); ito != listOutputPorts.end(); ++ito)
1647     addSubjectOutputPort(*ito);
1648   list<InputDataStreamPort*>::const_iterator itids;
1649   for (itids = listIDSPorts.begin(); itids != listIDSPorts.end(); ++itids)
1650     addSubjectIDSPort(*itids);
1651   list<OutputDataStreamPort*>::const_iterator itods;
1652   for (itods = listODSPorts.begin(); itods != listODSPorts.end(); ++itods)
1653     addSubjectODSPort(*itods);
1654 }
1655
1656 // ----------------------------------------------------------------------------
1657
1658
1659 SubjectInlineNode::SubjectInlineNode(YACS::ENGINE::InlineNode *inlineNode, Subject *parent)
1660   : SubjectElementaryNode(inlineNode, parent), _inlineNode(inlineNode)
1661 {
1662 }
1663
1664 SubjectInlineNode::~SubjectInlineNode()
1665 {
1666   DEBTRACE("SubjectInlineNode::~SubjectInlineNode " << getName());
1667 }
1668
1669 bool SubjectInlineNode::setScript(std::string script)
1670 {
1671   Proc *proc = GuiContext::getCurrent()->getProc();
1672   CommandSetInlineNodeScript *command =
1673     new CommandSetInlineNodeScript(proc->getChildName(_node), script);
1674   if (command->execute())
1675     {
1676       GuiContext::getCurrent()->getInvoc()->add(command);
1677       return true;
1678     }
1679   else delete command;
1680   return false;
1681 }
1682
1683 std::string SubjectInlineNode::getScript()
1684 {
1685   return _inlineNode->getScript();
1686 }
1687
1688 void SubjectInlineNode::clean()
1689 {
1690   localClean();
1691   SubjectElementaryNode::clean();
1692 }
1693
1694 void SubjectInlineNode::localClean()
1695 {
1696   DEBTRACE("SubjectInlineNode::localClean ");
1697 }
1698
1699
1700 // ----------------------------------------------------------------------------
1701
1702 SubjectServiceNode::SubjectServiceNode(YACS::ENGINE::ServiceNode *serviceNode, Subject *parent)
1703   : SubjectElementaryNode(serviceNode, parent), _serviceNode(serviceNode)
1704 {
1705   _subjectReference = 0;
1706   _subRefComponent = 0;
1707 }
1708
1709 SubjectServiceNode::~SubjectServiceNode()
1710 {
1711   DEBTRACE("SubjectServiceNode::~SubjectServiceNode " << getName());
1712 }
1713
1714 void SubjectServiceNode::clean()
1715 {
1716   localClean();
1717   SubjectElementaryNode::clean();
1718 }
1719
1720 void SubjectServiceNode::localClean()
1721 {
1722   DEBTRACE("SubjectServiceNode::localClean ");
1723   if (_subjectReference)
1724     {
1725 //       update( REMOVE, REFERENCE, _subjectReference );
1726       erase(_subjectReference);
1727       _subjectReference = 0;
1728     }
1729   if (_subRefComponent)
1730     {
1731       erase(_subRefComponent);
1732       _subRefComponent = 0;
1733     }
1734 }
1735
1736
1737 /*!
1738  *  When cloning a service node from a catalog, create the component associated to the node,
1739  *  if not already existing, and create the corresponding subject.
1740  */
1741 void SubjectServiceNode::setComponentFromCatalog(YACS::ENGINE::Catalog *catalog,
1742                                                  std::string compo,
1743                                                  std::string service)
1744 {
1745   DEBTRACE("SubjectServiceNode::setComponentFromCatalog " << compo);
1746   if (catalog->_componentMap.count(compo))
1747     {
1748       YACS::ENGINE::ComponentDefinition* compodef = catalog->_componentMap[compo];
1749       if (compodef->_serviceMap.count(service))
1750         {
1751           Proc* proc = GuiContext::getCurrent()->getProc();
1752           ComponentInstance *instance = 0;
1753           instance = new SalomeComponent(compo);
1754           pair<string,int> key = pair<string,int>(compo, instance->getNumId());
1755           proc->componentInstanceMap[key] = instance;
1756           SubjectComponent* subCompo = GuiContext::getCurrent()->getSubjectProc()->addSubjectComponent(instance);
1757           assert(subCompo);
1758           addSubjectReference(subCompo);
1759           _serviceNode->setComponent(instance);
1760           if (_subRefComponent)
1761             subCompo->moveService(_subRefComponent);
1762           else
1763             _subRefComponent = subCompo->attachService(this);
1764         }
1765     }
1766 }
1767
1768 /*!
1769  *  When loading scheme from file, get the component associated to the node, if any,
1770  *  and create the corresponding subject.
1771  */
1772 void SubjectServiceNode::setComponent()
1773 {
1774   DEBTRACE("SubjectServiceNode::setComponent");
1775   ComponentInstance *instance = _serviceNode->getComponent();
1776   if (instance)
1777     {
1778       Proc* proc = GuiContext::getCurrent()->getProc();
1779       string compo = instance->getCompoName();
1780       SubjectComponent* subCompo = 0;
1781       if (! GuiContext::getCurrent()->_mapOfSubjectComponent.count(instance))
1782         {
1783           DEBTRACE("SubjectServiceNode::setComponent : create subject for compo = " << compo.c_str());
1784           pair<string,int> key = pair<string,int>(compo, instance->getNumId());
1785           proc->componentInstanceMap[key] = instance;
1786           subCompo =
1787             GuiContext::getCurrent()->getSubjectProc()->addSubjectComponent(instance);
1788         }
1789       else
1790         {
1791           DEBTRACE("SubjectServiceNode::setComponent : get already created subject for compo = " <<compo.c_str());
1792           subCompo = GuiContext::getCurrent()->_mapOfSubjectComponent[instance];
1793         }       
1794       assert(subCompo);
1795       addSubjectReference(subCompo);
1796       if (_subRefComponent)
1797         subCompo->moveService(_subRefComponent);
1798       else
1799         _subRefComponent = subCompo->attachService(this);
1800     }
1801 }
1802
1803 bool SubjectServiceNode::associateToComponent(SubjectComponent *subcomp)
1804 {
1805   DEBTRACE("SubjectServiceNode::associateToComponent " << getName() << " " << subcomp->getName());
1806   SubjectReference* oldSReference = _subjectReference;
1807   string aName = GuiContext::getCurrent()->getProc()->getChildName(_serviceNode);
1808   CommandAssociateServiceToComponent *command =
1809     new CommandAssociateServiceToComponent(aName, subcomp->getKey());
1810   if (command->execute())
1811     {
1812       GuiContext::getCurrent()->getInvoc()->add(command);
1813       addSubjectReference(subcomp);
1814       if (_subRefComponent)
1815         subcomp->moveService(_subRefComponent);
1816       else
1817         _subRefComponent = subcomp->attachService(this);
1818       return true;
1819     }
1820   else delete command;
1821   return false;
1822 }
1823
1824 void SubjectServiceNode::removeSubjectReference(Subject *ref)
1825 {
1826   DEBTRACE("Subject::removeSubjectReference " << getName() << " " << ref->getName());
1827 //   update( REMOVE, REFERENCE, ref );
1828   erase( ref );
1829 }
1830
1831 void SubjectServiceNode::addSubjectReference(Subject *ref)
1832 {
1833   DEBTRACE("Subject::addSubjectReference " << getName() << " " << ref->getName());
1834   SubjectReference *son = new SubjectReference(ref, this);
1835   _subjectReference = son;
1836   update(ADDREF, 0, son);
1837 }
1838
1839 SubjectReference* SubjectServiceNode::getSubjectReference()
1840 {
1841   return _subjectReference;
1842 }
1843
1844 // ----------------------------------------------------------------------------
1845
1846 SubjectPythonNode::SubjectPythonNode(YACS::ENGINE::PythonNode *pythonNode, Subject *parent)
1847   : SubjectInlineNode(pythonNode, parent), _pythonNode(pythonNode)
1848 {
1849 }
1850
1851 SubjectPythonNode::~SubjectPythonNode()
1852 {
1853   DEBTRACE("SubjectPythonNode::~SubjectPythonNode " << getName());
1854 }
1855
1856 void SubjectPythonNode::clean()
1857 {
1858   localClean();
1859   SubjectInlineNode::clean();
1860 }
1861
1862 void SubjectPythonNode::localClean()
1863 {
1864   DEBTRACE("SubjectPythonNode::localClean ");
1865 }
1866
1867
1868 // ----------------------------------------------------------------------------
1869
1870 SubjectPyFuncNode::SubjectPyFuncNode(YACS::ENGINE::PyFuncNode *pyFuncNode, Subject *parent)
1871   : SubjectInlineNode(pyFuncNode, parent), _pyFuncNode(pyFuncNode)
1872 {
1873 }
1874
1875 SubjectPyFuncNode::~SubjectPyFuncNode()
1876 {
1877   DEBTRACE("SubjectPyFuncNode::~SubjectPyFuncNode " << getName());
1878 }
1879
1880 bool SubjectPyFuncNode::setFunctionName(std::string funcName)
1881 {
1882   Proc *proc = GuiContext::getCurrent()->getProc();
1883   CommandSetFuncNodeFunctionName *command =
1884     new CommandSetFuncNodeFunctionName(proc->getChildName(_node), funcName);
1885   if (command->execute())
1886     {
1887       GuiContext::getCurrent()->getInvoc()->add(command);
1888       return true;
1889     }
1890   else delete command;
1891   return false;
1892 }
1893
1894 void SubjectPyFuncNode::clean()
1895 {
1896   localClean();
1897   SubjectInlineNode::clean();
1898 }
1899
1900 void SubjectPyFuncNode::localClean()
1901 {
1902   DEBTRACE("SubjectPyFuncNode::localClean ");
1903 }
1904
1905
1906 // ----------------------------------------------------------------------------
1907
1908 SubjectCORBANode::SubjectCORBANode(YACS::ENGINE::CORBANode *corbaNode, Subject *parent)
1909   : SubjectServiceNode(corbaNode, parent), _corbaNode(corbaNode)
1910 {
1911 }
1912
1913 SubjectCORBANode::~SubjectCORBANode()
1914 {
1915   DEBTRACE("SubjectCORBANode::~SubjectCORBANode " << getName());
1916 }
1917
1918 void SubjectCORBANode::clean()
1919 {
1920   localClean();
1921   SubjectServiceNode::clean();
1922 }
1923
1924 void SubjectCORBANode::localClean()
1925 {
1926   DEBTRACE("SubjectCORBANode::localClean ");
1927 }
1928
1929
1930 // ----------------------------------------------------------------------------
1931
1932 SubjectCppNode::SubjectCppNode(YACS::ENGINE::CppNode *cppNode, Subject *parent)
1933   : SubjectServiceNode(cppNode, parent), _cppNode(cppNode)
1934 {
1935 }
1936
1937 SubjectCppNode::~SubjectCppNode()
1938 {
1939   DEBTRACE("SubjectCppNode::~SubjectCppNode " << getName());
1940 }
1941
1942 void SubjectCppNode::clean()
1943 {
1944   localClean();
1945   SubjectServiceNode::clean();
1946 }
1947
1948 void SubjectCppNode::localClean()
1949 {
1950   DEBTRACE("SubjectCppNode::localClean ");
1951 }
1952
1953
1954 // ----------------------------------------------------------------------------
1955
1956 SubjectSalomeNode::SubjectSalomeNode(YACS::ENGINE::SalomeNode *salomeNode, Subject *parent)
1957   : SubjectServiceNode(salomeNode, parent), _salomeNode(salomeNode)
1958 {
1959 }
1960
1961 SubjectSalomeNode::~SubjectSalomeNode()
1962 {
1963   DEBTRACE("SubjectSalomeNode::~SubjectSalomeNode " << getName());
1964 }
1965
1966 void SubjectSalomeNode::clean()
1967 {
1968   localClean();
1969   SubjectServiceNode::clean();
1970 }
1971
1972 void SubjectSalomeNode::localClean()
1973 {
1974   DEBTRACE("SubjectSalomeNode::localClean ");
1975 }
1976
1977
1978 // ----------------------------------------------------------------------------
1979
1980 SubjectSalomePythonNode::SubjectSalomePythonNode(YACS::ENGINE::SalomePythonNode *salomePythonNode,
1981                                                  Subject *parent)
1982   : SubjectServiceNode(salomePythonNode, parent), _salomePythonNode(salomePythonNode)
1983 {
1984 }
1985
1986 SubjectSalomePythonNode::~SubjectSalomePythonNode()
1987 {
1988   DEBTRACE("SubjectSalomePythonNode::~SubjectSalomePythonNode " << getName());
1989 }
1990
1991 void SubjectSalomePythonNode::clean()
1992 {
1993   localClean();
1994   SubjectServiceNode::clean();
1995 }
1996
1997 void SubjectSalomePythonNode::localClean()
1998 {
1999   DEBTRACE("SubjectSalomePythonNode::localClean ");
2000 }
2001
2002
2003 // ----------------------------------------------------------------------------
2004
2005 SubjectXmlNode::SubjectXmlNode(YACS::ENGINE::XmlNode *xmlNode, Subject *parent)
2006   : SubjectServiceNode(xmlNode, parent), _xmlNode(xmlNode)
2007 {
2008 }
2009
2010 SubjectXmlNode::~SubjectXmlNode()
2011 {
2012   DEBTRACE("SubjectXmlNode::~SubjectXmlNode " << getName());
2013 }
2014
2015 void SubjectXmlNode::clean()
2016 {
2017   localClean();
2018   SubjectServiceNode::clean();
2019 }
2020
2021 void SubjectXmlNode::localClean()
2022 {
2023   DEBTRACE("SubjectXmlNode::localClean ");
2024 }
2025
2026
2027 // ----------------------------------------------------------------------------
2028
2029 SubjectSplitterNode::SubjectSplitterNode(YACS::ENGINE::SplitterNode *splitterNode, Subject *parent)
2030   : SubjectElementaryNode(splitterNode, parent), _splitterNode(splitterNode)
2031 {
2032   _destructible = false;
2033 }
2034
2035 SubjectSplitterNode::~SubjectSplitterNode()
2036 {
2037   DEBTRACE("SubjectSplitterNode::~SubjectSplitterNode " << getName());
2038 }
2039
2040 void SubjectSplitterNode::clean()
2041 {
2042   localClean();
2043   SubjectElementaryNode::clean();
2044 }
2045
2046 void SubjectSplitterNode::localClean()
2047 {
2048   DEBTRACE("SubjectSplitterNode::localClean ");
2049 }
2050
2051
2052 std::string SubjectSplitterNode::getName()
2053 {
2054   return "splitter";
2055 }
2056
2057 // ----------------------------------------------------------------------------
2058
2059 SubjectDataNode::SubjectDataNode(YACS::ENGINE::DataNode *dataNode, Subject *parent)
2060   : SubjectElementaryNode(dataNode, parent), _dataNode(dataNode)
2061 {
2062   _destructible = true;
2063 }
2064
2065 SubjectDataNode::~SubjectDataNode()
2066 {
2067   DEBTRACE("SubjectDataNode::~SubjectDataNode " << getName());
2068 }
2069
2070 void SubjectDataNode::clean()
2071 {
2072   localClean();
2073   SubjectElementaryNode::clean();
2074 }
2075
2076 void SubjectDataNode::localClean()
2077 {
2078   DEBTRACE("SubjectDataNode::localClean ");
2079 }
2080
2081 // ----------------------------------------------------------------------------
2082
2083 SubjectPresetNode::SubjectPresetNode(YACS::ENGINE::PresetNode *presetNode, Subject *parent)
2084   : SubjectDataNode(presetNode, parent), _presetNode(presetNode)
2085 {
2086   _destructible = true;
2087 }
2088
2089 SubjectPresetNode::~SubjectPresetNode()
2090 {
2091   DEBTRACE("SubjectPresetNode::~SubjectPresetNode " << getName());
2092 }
2093
2094 void SubjectPresetNode::clean()
2095 {
2096   localClean();
2097   SubjectDataNode::clean();
2098 }
2099
2100 void SubjectPresetNode::localClean()
2101 {
2102   DEBTRACE("SubjectPresetNode::localClean ");
2103 }
2104
2105 // ----------------------------------------------------------------------------
2106
2107 SubjectOutNode::SubjectOutNode(YACS::ENGINE::OutNode *outNode, Subject *parent)
2108   : SubjectDataNode(outNode, parent), _outNode(outNode)
2109 {
2110   _destructible = true;
2111 }
2112
2113 SubjectOutNode::~SubjectOutNode()
2114 {
2115   DEBTRACE("SubjectOutNode::~SubjectOutNode " << getName());
2116 }
2117
2118 void SubjectOutNode::clean()
2119 {
2120   localClean();
2121   SubjectDataNode::clean();
2122 }
2123
2124 void SubjectOutNode::localClean()
2125 {
2126   DEBTRACE("SubjectOutNode::localClean ");
2127 }
2128
2129 // ----------------------------------------------------------------------------
2130
2131 SubjectStudyInNode::SubjectStudyInNode(YACS::ENGINE::StudyInNode *studyInNode, Subject *parent)
2132   : SubjectDataNode(studyInNode, parent), _studyInNode(studyInNode)
2133 {
2134   _destructible = true;
2135 }
2136
2137 SubjectStudyInNode::~SubjectStudyInNode()
2138 {
2139   DEBTRACE("SubjectStudyInNode::~SubjectStudyInNode " << getName());
2140 }
2141
2142 void SubjectStudyInNode::clean()
2143 {
2144   localClean();
2145   SubjectDataNode::clean();
2146 }
2147
2148 void SubjectStudyInNode::localClean()
2149 {
2150   DEBTRACE("SubjectStudyInNode::localClean ");
2151 }
2152
2153 // ----------------------------------------------------------------------------
2154
2155 SubjectStudyOutNode::SubjectStudyOutNode(YACS::ENGINE::StudyOutNode *studyOutNode, Subject *parent)
2156   : SubjectDataNode(studyOutNode, parent), _studyOutNode(studyOutNode)
2157 {
2158   _destructible = true;
2159 }
2160
2161 SubjectStudyOutNode::~SubjectStudyOutNode()
2162 {
2163   DEBTRACE("SubjectStudyOutNode::~SubjectStudyOutNode " << getName());
2164 }
2165
2166 void SubjectStudyOutNode::clean()
2167 {
2168   localClean();
2169   SubjectDataNode::clean();
2170 }
2171
2172 void SubjectStudyOutNode::localClean()
2173 {
2174   DEBTRACE("SubjectStudyOutNode::localClean ");
2175 }
2176
2177 // ----------------------------------------------------------------------------
2178
2179 SubjectForLoop::SubjectForLoop(YACS::ENGINE::ForLoop *forLoop, Subject *parent)
2180   : SubjectComposedNode(forLoop, parent), _forLoop(forLoop)
2181 {
2182   _body = 0;
2183 }
2184
2185 SubjectForLoop::~SubjectForLoop()
2186 {
2187   DEBTRACE("SubjectForLoop::~SubjectForLoop " << getName());
2188 }
2189
2190 void SubjectForLoop::clean()
2191 {
2192   localClean();
2193   SubjectComposedNode::clean();
2194 }
2195
2196 void SubjectForLoop::localClean()
2197 {
2198   DEBTRACE("SubjectForLoop::localClean ");
2199   if (_body)
2200     erase(_body);
2201 }
2202
2203 void SubjectForLoop::recursiveUpdate(GuiEvent event, int type, Subject* son)
2204 {
2205   update(event, type, son);
2206   if (_body)
2207     _body->recursiveUpdate(event, type, son);
2208 }
2209
2210 SubjectNode* SubjectForLoop::addNode(YACS::ENGINE::Catalog *catalog,
2211                                      std::string compo,
2212                                      std::string type,
2213                                      std::string name)
2214 {
2215   DEBTRACE("SubjectForLoop::addNode(catalog, compo, type, name)");
2216   SubjectNode* body = 0;
2217   if (_body) return body;
2218   body = createNode(catalog, compo, type, name);
2219   return body;
2220 }
2221
2222 void SubjectForLoop::completeChildrenSubjectList(SubjectNode *son)
2223 {
2224   _body = son;
2225 }
2226
2227 bool SubjectForLoop::setNbSteps(std::string nbSteps)
2228 {
2229   DEBTRACE("SubjectForLoop::setNbSteps " << nbSteps);
2230   Proc *proc = GuiContext::getCurrent()->getProc();
2231   CommandSetForLoopSteps *command =
2232     new CommandSetForLoopSteps(proc->getChildName(getNode()), nbSteps);
2233   if (command->execute())
2234     {
2235       GuiContext::getCurrent()->getInvoc()->add(command);
2236       update(SETVALUE, 0, this);
2237       return true;
2238     }
2239   else delete command;
2240   return false;
2241 }
2242 bool SubjectForLoop::hasValue()
2243 {
2244   return true;
2245 }
2246
2247 std::string SubjectForLoop::getValue()
2248 {
2249   return _forLoop->edGetNbOfTimesInputPort()->getAsString();
2250 }
2251
2252 // ----------------------------------------------------------------------------
2253
2254 SubjectWhileLoop::SubjectWhileLoop(YACS::ENGINE::WhileLoop *whileLoop, Subject *parent)
2255   : SubjectComposedNode(whileLoop, parent), _whileLoop(whileLoop)
2256 {
2257   _body = 0;
2258 }
2259
2260 SubjectWhileLoop::~SubjectWhileLoop()
2261 {
2262   DEBTRACE("SubjectWhileLoop::~SubjectWhileLoop " << getName());
2263 }
2264
2265 void SubjectWhileLoop::clean()
2266 {
2267   localClean();
2268   SubjectComposedNode::clean();
2269 }
2270
2271 void SubjectWhileLoop::localClean()
2272 {
2273   DEBTRACE("SubjectWhileLoop::localClean ");
2274   if (_body)
2275     erase(_body);
2276 }
2277
2278 void SubjectWhileLoop::recursiveUpdate(GuiEvent event, int type, Subject* son)
2279 {
2280   update(event, type, son);
2281   if (_body)
2282     _body->recursiveUpdate(event, type, son);
2283 }
2284
2285 SubjectNode* SubjectWhileLoop::addNode(YACS::ENGINE::Catalog *catalog,
2286                                        std::string compo,
2287                                        std::string type,
2288                                        std::string name)
2289 {
2290   DEBTRACE("SubjectWhileLoop::addNode(catalog, compo, type, name)");
2291   SubjectNode* body = 0;
2292   if (_body) return body;
2293   body = createNode(catalog, compo, type, name);
2294   return body;
2295 }
2296
2297 void SubjectWhileLoop::completeChildrenSubjectList(SubjectNode *son)
2298 {
2299   _body = son;
2300 }
2301
2302 bool SubjectWhileLoop::setCondition(std::string condition)
2303 {
2304   DEBTRACE("SubjectWhileLoop::setCondition " << condition);
2305   Proc *proc = GuiContext::getCurrent()->getProc();
2306   CommandSetWhileCondition *command =
2307     new CommandSetWhileCondition(proc->getChildName(getNode()), condition);
2308   if (command->execute())
2309     {
2310       GuiContext::getCurrent()->getInvoc()->add(command);
2311       update(SETVALUE, 0, this);
2312       return true;
2313     }
2314   else delete command;
2315   return false;
2316 }
2317
2318 bool SubjectWhileLoop::hasValue()
2319 {
2320   return true;
2321 }
2322
2323 std::string SubjectWhileLoop::getValue()
2324 {
2325   return _whileLoop->edGetConditionPort()->getAsString();
2326 }
2327
2328 // ----------------------------------------------------------------------------
2329
2330 SubjectSwitch::SubjectSwitch(YACS::ENGINE::Switch *aSwitch, Subject *parent)
2331   : SubjectComposedNode(aSwitch, parent), _switch(aSwitch)
2332 {
2333   _bodyMap.clear();
2334 }
2335
2336 SubjectSwitch::~SubjectSwitch()
2337 {
2338   DEBTRACE("SubjectSwitch::~SubjectSwitch " << getName());
2339 }
2340
2341 void SubjectSwitch::clean()
2342 {
2343   localClean();
2344   SubjectComposedNode::clean();
2345 }
2346
2347 void SubjectSwitch::localClean()
2348 {
2349   DEBTRACE("SubjectSwitch::localClean ");
2350   map<int, SubjectNode*>::iterator it;
2351   map<int, SubjectNode*> bodyMapCpy = _bodyMap;
2352   for (it = bodyMapCpy.begin(); it != bodyMapCpy.end(); ++it)
2353     erase((*it).second);
2354 }
2355
2356 void SubjectSwitch::recursiveUpdate(GuiEvent event, int type, Subject* son)
2357 {
2358   update(event, type, son);
2359   map<int, SubjectNode*>::iterator it = _bodyMap.begin();
2360   for (; it != _bodyMap.end(); ++it)
2361     (*it).second->recursiveUpdate(event, type, son);
2362 }
2363
2364 SubjectNode* SubjectSwitch::addNode(YACS::ENGINE::Catalog *catalog,
2365                                     std::string compo,
2366                                     std::string type,
2367                                     std::string name,
2368                                     int swCase,
2369                                     bool replace)
2370 {
2371   DEBTRACE("SubjectSwitch::addNode("<<catalog<<","<<compo<<","<<type<<","<<name<<","<<swCase<<","<<(int)replace<<")");
2372   SubjectNode* body = 0;
2373   if (!replace && _bodyMap.count(swCase)) return body;
2374   body = createNode(catalog, compo, type, name, swCase);
2375   return body;
2376 }
2377
2378 void SubjectSwitch::removeNode(SubjectNode* son)
2379 {
2380   DEBTRACE("SubjectSwitch::removeNode("<<son->getName()<<")");
2381   if (son)
2382   {
2383     int id;
2384     bool isFound = false;
2385     map<int, SubjectNode*>::const_iterator it;
2386     for (it = _bodyMap.begin(); it != _bodyMap.end(); ++it)
2387     {
2388       if ( (*it).second == son )
2389       {
2390         isFound = true;
2391         id = (*it).first;
2392         break;
2393       }
2394     }
2395     if (isFound)
2396     {
2397       DEBTRACE("id = "<<id);
2398       _bodyMap.erase(id);
2399     }
2400   }
2401 }
2402
2403 std::map<int, SubjectNode*> SubjectSwitch::getBodyMap()
2404 {
2405   return _bodyMap;
2406 }
2407
2408 void SubjectSwitch::completeChildrenSubjectList(SubjectNode *son)
2409 {
2410   _bodyMap[_switch->getRankOfNode(son->getNode())] = son;
2411 }
2412
2413 SubjectNode* SubjectSwitch::getChild(YACS::ENGINE::Node* node) const
2414 {
2415   SubjectNode* aChild = 0;
2416
2417   if (node)
2418   {
2419     map<int, SubjectNode*>::const_iterator it;
2420     for (it = _bodyMap.begin(); it != _bodyMap.end(); ++it)
2421       if ( (*it).second->getNode() == node )
2422       {
2423         aChild = (*it).second;
2424         break;
2425       }
2426   }
2427
2428   return aChild;
2429 }
2430
2431 bool SubjectSwitch::setSelect(std::string select)
2432 {
2433   DEBTRACE("SubjectSwitch::setSelect " << select);
2434   Proc *proc = GuiContext::getCurrent()->getProc();
2435   CommandSetSwitchSelect *command =
2436     new CommandSetSwitchSelect(proc->getChildName(getNode()), select);
2437   if (command->execute())
2438     {
2439       GuiContext::getCurrent()->getInvoc()->add(command);
2440       update(SETSELECT, 0, this);
2441       return true;
2442     }
2443   else delete command;
2444   return false;
2445 }
2446
2447 bool SubjectSwitch::setCase(std::string caseId, SubjectNode* snode)
2448 {
2449   DEBTRACE("SubjectSwitch::setCase " << caseId);
2450   Proc *proc = GuiContext::getCurrent()->getProc();
2451
2452   Switch* aSwitch = dynamic_cast<Switch*>(getNode());
2453   Node* node =snode->getNode();
2454   int previousRank = aSwitch->getRankOfNode(node);
2455   int newRank = atoi(caseId.c_str());
2456   if (previousRank == newRank) return true; // nothing to do.
2457
2458   CommandSetSwitchCase *command =
2459     new CommandSetSwitchCase(proc->getChildName(getNode()),
2460                              proc->getChildName(snode->getNode()),
2461                              caseId);
2462   if (command->execute())
2463     {
2464       GuiContext::getCurrent()->getInvoc()->add(command);
2465       update(SETCASE, newRank, snode);
2466       return true;
2467     }
2468   else delete command;
2469   return false;
2470 }
2471
2472 bool SubjectSwitch::hasValue()
2473 {
2474   return true;
2475 }
2476
2477 std::string SubjectSwitch::getValue()
2478 {
2479   return _switch->edGetConditionPort()->getAsString();
2480 }
2481
2482 // ----------------------------------------------------------------------------
2483
2484 SubjectForEachLoop::SubjectForEachLoop(YACS::ENGINE::ForEachLoop *forEachLoop, Subject *parent)
2485   : SubjectComposedNode(forEachLoop, parent), _forEachLoop(forEachLoop)
2486 {
2487   _body = 0;
2488   _splitter = 0;
2489 }
2490
2491 SubjectForEachLoop::~SubjectForEachLoop()
2492 {
2493   DEBTRACE("SubjectForEachLoop::~SubjectForEachLoop " << getName());
2494 }
2495
2496 void SubjectForEachLoop::clean()
2497 {
2498   Node* aSplitterEngine = 0;
2499   if (_splitter) aSplitterEngine = _splitter->getNode();
2500
2501   localClean();
2502   SubjectComposedNode::clean();
2503
2504   if (_forEachLoop && aSplitterEngine)
2505     {
2506       DEBTRACE("SubjectForEachLoop::clean: remove for each loop splitter");
2507       _forEachLoop->edRemoveChild(aSplitterEngine);
2508     }
2509 }
2510
2511 void SubjectForEachLoop::localClean()
2512 {
2513   DEBTRACE("SubjectForEachLoop::localClean ");
2514   if (_body)
2515     {
2516       DEBTRACE(_body->getName());
2517       erase(_body);
2518     }
2519   if (_splitter)
2520     {
2521       DEBTRACE(_splitter->getName());
2522       erase(_splitter);
2523     }
2524 }
2525
2526 void SubjectForEachLoop::recursiveUpdate(GuiEvent event, int type, Subject* son)
2527 {
2528   update(event, type, son);
2529   if (_body)
2530     _body->recursiveUpdate(event, type, son);
2531 }
2532
2533 SubjectNode* SubjectForEachLoop::addNode(YACS::ENGINE::Catalog *catalog,
2534                                          std::string compo,
2535                                          std::string type,
2536                                          std::string name)
2537 {
2538   DEBTRACE("SubjectForEachLoop::addNode(catalog, compo, type, name)");
2539   SubjectNode* body = 0;
2540   if (_body) return body;
2541   body = createNode(catalog, compo, type, name);
2542   return body;
2543 }
2544
2545 void SubjectForEachLoop::completeChildrenSubjectList(SubjectNode *son)
2546 {
2547   if ( !son )
2548   {
2549     _body = son;
2550     return;
2551   }
2552
2553   string name = son->getName();
2554   DEBTRACE("SubjectForEachLoop::completeChildrenSubjectList " << name);
2555   if (name == ForEachLoop::NAME_OF_SPLITTERNODE)
2556     _splitter = son;
2557   else
2558     _body = son;
2559 }
2560
2561 bool SubjectForEachLoop::setNbBranches(std::string nbBranches)
2562 {
2563   DEBTRACE("SubjectForEachLoop::setNbBranches " << nbBranches);
2564   Proc *proc = GuiContext::getCurrent()->getProc();
2565   CommandSetForEachBranch *command =
2566     new CommandSetForEachBranch(proc->getChildName(getNode()), nbBranches);
2567   if (command->execute())
2568     {
2569       GuiContext::getCurrent()->getInvoc()->add(command);
2570       update(SETVALUE, 0, this);
2571       return true;
2572     }
2573   else delete command;
2574   return false;
2575 }
2576
2577 bool SubjectForEachLoop::hasValue()
2578 {
2579   return true;
2580 }
2581
2582 std::string SubjectForEachLoop::getValue()
2583 {
2584   return _forEachLoop->getInputPort("nbBranches")->getAsString();
2585 }
2586
2587
2588 // ----------------------------------------------------------------------------
2589
2590 SubjectOptimizerLoop::SubjectOptimizerLoop(YACS::ENGINE::OptimizerLoop *optimizerLoop,
2591                                            Subject *parent)
2592   : SubjectComposedNode(optimizerLoop, parent), _optimizerLoop(optimizerLoop)
2593 {
2594   _body = 0;
2595 }
2596
2597 SubjectOptimizerLoop::~SubjectOptimizerLoop()
2598 {
2599   DEBTRACE("SubjectOptimizerLoop::~SubjectOptimizerLoop " << getName());
2600 }
2601
2602 void SubjectOptimizerLoop::clean()
2603 {
2604   localClean();
2605   SubjectComposedNode::clean();
2606 }
2607
2608 void SubjectOptimizerLoop::localClean()
2609 {
2610   DEBTRACE("SubjectOptimizerLoop::localClean ");
2611   if (_body)
2612     erase(_body);
2613 }
2614
2615 void SubjectOptimizerLoop::recursiveUpdate(GuiEvent event, int type, Subject* son)
2616 {
2617   update(event, type, son);
2618   if (_body)
2619     _body->recursiveUpdate(event, type, son);
2620 }
2621
2622 SubjectNode* SubjectOptimizerLoop::addNode(YACS::ENGINE::Catalog *catalog,
2623                                            std::string compo,
2624                                            std::string type,
2625                                            std::string name)
2626 {
2627   DEBTRACE("SubjectOptimizerLoop::addNode(catalog, compo, type, name)");
2628   SubjectNode* body = 0;
2629   if (_body) return body;
2630   body = createNode(catalog, compo, type, name);
2631   return body;
2632 }
2633
2634 void SubjectOptimizerLoop::completeChildrenSubjectList(SubjectNode *son)
2635 {
2636   _body = son;
2637 }
2638
2639 // ----------------------------------------------------------------------------
2640
2641 SubjectDataPort::SubjectDataPort(YACS::ENGINE::DataPort* port, Subject *parent)
2642   : Subject(parent), _dataPort(port)
2643 {
2644   _listSubjectLink.clear();
2645   _execValue = "";
2646 }
2647
2648 SubjectDataPort::~SubjectDataPort()
2649 {
2650   DEBTRACE("SubjectDataPort::~SubjectDataPort " << getName());
2651   if (isDestructible())
2652     {
2653       Node* node = _dataPort->getNode();
2654       assert(node);
2655       ElementaryNode * father = dynamic_cast<ElementaryNode*>(node);
2656       if (father)
2657         {
2658           DEBTRACE("father->edRemovePort(_dataPort)");
2659           try
2660             {
2661               father->edRemovePort(_dataPort);
2662             }
2663           catch (YACS::Exception &e)
2664             {
2665               DEBTRACE("------------------------------------------------------------------------------");
2666               DEBTRACE("SubjectDataPort::~SubjectDataPort: father->edRemovePort: YACS exception " << e.what());
2667               DEBTRACE("------------------------------------------------------------------------------");
2668             }
2669         }
2670     }
2671 }
2672
2673 void SubjectDataPort::clean()
2674 {
2675   localClean();
2676   Subject::clean();
2677 }
2678
2679 void SubjectDataPort::localClean()
2680 {
2681   DEBTRACE("SubjectDataPort::localClean ");
2682   list<SubjectLink*> lsl = getListOfSubjectLink();
2683   for (list<SubjectLink*>::iterator it = lsl.begin(); it != lsl.end(); ++it)
2684     erase(*it);
2685 }
2686
2687 std::string SubjectDataPort::getName()
2688 {
2689   return _dataPort->getName();
2690 }
2691
2692 bool SubjectDataPort::setName(std::string name)
2693 {
2694   DEBTRACE("SubjectDataPort::setName " << name);
2695   Proc *proc = GuiContext::getCurrent()->getProc();
2696   string position = "";
2697   Node *node = getPort()->getNode();
2698   if (proc != dynamic_cast<Proc*>(node))
2699     position = proc->getChildName(node);
2700   else
2701     position = node->getName();
2702
2703   Command *command = 0;
2704   bool isIn = dynamic_cast<InPort*>(_dataPort);
2705   if (isIn) 
2706     command = new CommandRenameInDataPort(position, _dataPort->getName(),name);
2707   else 
2708     command = new CommandRenameOutDataPort(position, _dataPort->getName(),name);
2709
2710   if (command->execute())
2711     {
2712       GuiContext::getCurrent()->getInvoc()->add(command);
2713       update(RENAME, 0, this);
2714       return true;
2715     }
2716   else delete command;
2717   return false;
2718 }
2719
2720 YACS::ENGINE::DataPort* SubjectDataPort::getPort()
2721 {
2722   return _dataPort;
2723 }
2724
2725 bool SubjectDataPort::tryCreateLink(SubjectDataPort *subOutport, SubjectDataPort *subInport,bool control)
2726 {
2727   DEBTRACE("SubjectDataPort::tryCreateLink");
2728
2729   InPort *inp = dynamic_cast<InPort*>(subInport->getPort());
2730   OutPort *outp = dynamic_cast<OutPort*>(subOutport->getPort());
2731   if (outp && outp->isAlreadyLinkedWith(inp))
2732     {
2733       DEBTRACE("isAlreadyLinkedWith");
2734       return false;
2735     }
2736
2737   Proc *proc = GuiContext::getCurrent()->getProc();
2738
2739   string outNodePos = "";
2740   SubjectNode *sno = dynamic_cast<SubjectNode*>(subOutport->getParent());
2741   assert(sno);
2742   Node *outNode = sno->getNode();
2743   outNodePos = proc->getChildName(outNode);
2744   string outportName = subOutport->getName();
2745
2746   string inNodePos = "";
2747   SubjectNode *sni = dynamic_cast<SubjectNode*>(subInport->getParent());
2748   assert(sni);
2749   Node *inNode = sni->getNode();
2750   inNodePos = proc->getChildName(inNode);
2751   string inportName = subInport->getName();
2752
2753   CommandAddLink *command = new CommandAddLink(outNodePos, outportName,
2754                                                inNodePos, inportName,control);
2755   if (command->execute())
2756     {
2757       GuiContext::getCurrent()->getInvoc()->add(command);
2758       
2759       ComposedNode *cla = ComposedNode::getLowestCommonAncestor(outNode->getFather(),
2760                                                                 inNode->getFather());
2761       SubjectComposedNode *scla = dynamic_cast<SubjectComposedNode*>(sno->getParent());
2762       ComposedNode *ancestor = outNode->getFather();
2763       while (ancestor && ancestor != cla)
2764         {
2765           ancestor = ancestor->getFather();
2766           scla = dynamic_cast<SubjectComposedNode*>(scla->getParent());
2767           assert(scla);
2768         }
2769       DEBTRACE(scla->getName());
2770       scla->addSubjectLink(sno, subOutport, sni, subInport);
2771       return true;
2772     }
2773   else
2774     {
2775       delete command;
2776       return false;
2777     }
2778 }
2779
2780 /*! Generic method do nothing.
2781  *  Implementation in SubjectInputPort and SubjectOutputPort.
2782  */
2783 bool SubjectDataPort::setValue(std::string value)
2784 {
2785   return false;
2786 }
2787
2788 void SubjectDataPort::setExecValue(std::string value)
2789 {
2790   _execValue = value;
2791 }
2792
2793 std::string SubjectDataPort::getExecValue()
2794 {
2795   return _execValue;
2796 }
2797
2798
2799 // ----------------------------------------------------------------------------
2800
2801 SubjectInputPort::SubjectInputPort(YACS::ENGINE::InputPort *port, Subject *parent)
2802   : SubjectDataPort(port, parent), _inputPort(port)
2803 {
2804   Node *node = _inputPort->getNode();
2805   if (ForLoop* forloop = dynamic_cast<ForLoop*>(node))
2806     {
2807       if (_inputPort->getName() == "nsteps") _destructible = false;
2808     }
2809   else if (WhileLoop* whileloop = dynamic_cast<WhileLoop*>(node))
2810     {
2811       if (_inputPort->getName() == "condition") _destructible = false;
2812     }
2813   else if (Switch* aSwitch = dynamic_cast<Switch*>(node))
2814     {
2815       if (_inputPort->getName() == "select") _destructible = false;
2816     }
2817   else if (ForEachLoop* foreach = dynamic_cast<ForEachLoop*>(node))
2818     {
2819       if (_inputPort->getName() == "nbBranches") _destructible = false;
2820     }
2821   else if (OptimizerLoop* optil = dynamic_cast<OptimizerLoop*>(node))
2822     {
2823       if (_inputPort->getName() == "nbBranches") _destructible = false;
2824     }
2825   else if (SplitterNode* split = dynamic_cast<SplitterNode*>(node))
2826     {
2827       if (_inputPort->getName() == "SmplsCollection") _destructible = false;
2828     }
2829
2830 }
2831
2832 SubjectInputPort::~SubjectInputPort()
2833 {
2834   DEBTRACE("SubjectInputPort::~SubjectInputPort " << getName());
2835 }
2836
2837 void SubjectInputPort::clean()
2838 {
2839   localClean();
2840   SubjectDataPort::clean();
2841 }
2842
2843 void SubjectInputPort::localClean()
2844 {
2845   DEBTRACE("SubjectInputPort::localClean ");
2846   if (_parent)
2847     {
2848       SubjectElementaryNode* elem = dynamic_cast<SubjectElementaryNode*>(_parent);
2849       if (elem) elem->removePort(this);
2850     }
2851 }
2852
2853 bool SubjectInputPort::setValue(std::string value)
2854 {
2855   DEBTRACE("SubjectInputPort::setValue " << value);
2856   Proc *proc = GuiContext::getCurrent()->getProc();
2857   CommandSetInPortValue *command =
2858     new CommandSetInPortValue(proc->getChildName(getPort()->getNode()), getName(), value);
2859   if (command->execute())
2860     {
2861       GuiContext::getCurrent()->getInvoc()->add(command);
2862       update(SETVALUE, 0, this);
2863       return true;
2864     }
2865   else delete command;
2866   return false;
2867 }
2868
2869 // ----------------------------------------------------------------------------
2870
2871 SubjectOutputPort::SubjectOutputPort(YACS::ENGINE::OutputPort *port, Subject *parent)
2872   : SubjectDataPort(port, parent), _outputPort(port)
2873 {
2874   Node *node = _outputPort->getNode();
2875   if (ForEachLoop* foreach = dynamic_cast<ForEachLoop*>(node))
2876     {
2877       if (_outputPort->getName() == "SmplPrt") _destructible = false;
2878     }
2879   else if (OptimizerLoop* optil = dynamic_cast<OptimizerLoop*>(node))
2880     {
2881       if (_outputPort->getName() == "SmplPrt") _destructible = false;
2882     }
2883 }
2884
2885 SubjectOutputPort::~SubjectOutputPort()
2886 {
2887   DEBTRACE("SubjectOutputPort::~SubjectOutputPort " << getName());
2888 }
2889
2890 void SubjectOutputPort::clean()
2891 {
2892   localClean();
2893   SubjectDataPort::clean();
2894 }
2895
2896 void SubjectOutputPort::localClean()
2897 {
2898   DEBTRACE("SubjectOutputPort::localClean ");
2899   if (_parent)
2900     {
2901       SubjectElementaryNode* elem = dynamic_cast<SubjectElementaryNode*>(_parent);
2902       if (elem) elem->removePort(this);
2903     }
2904 }
2905
2906 bool SubjectOutputPort::setValue(std::string value)
2907 {
2908   DEBTRACE("SubjectOutputPort::setValue " << value);
2909   Proc *proc = GuiContext::getCurrent()->getProc();
2910   CommandSetOutPortValue *command =
2911     new CommandSetOutPortValue(proc->getChildName(getPort()->getNode()), getName(), value);
2912   if (command->execute())
2913     {
2914       GuiContext::getCurrent()->getInvoc()->add(command);
2915       update(SETVALUE, 0, this);
2916       return true;
2917     }
2918   else delete command;
2919   return false;
2920 }
2921
2922 // ----------------------------------------------------------------------------
2923
2924 SubjectInputDataStreamPort::SubjectInputDataStreamPort(YACS::ENGINE::InputDataStreamPort *port,
2925                                                        Subject *parent)
2926   : SubjectDataPort(port, parent), _inputDataStreamPort(port)
2927 {
2928 }
2929
2930 SubjectInputDataStreamPort::~SubjectInputDataStreamPort()
2931 {
2932   DEBTRACE("SubjectInputDataStreamPort::~SubjectInputDataStreamPort " << getName());
2933 }
2934
2935 std::map<std::string, std::string> SubjectInputDataStreamPort::getProperties()
2936 {
2937   return _inputDataStreamPort->getPropertyMap();
2938 }
2939
2940 bool SubjectInputDataStreamPort::setProperties(std::map<std::string, std::string> properties)
2941 {
2942   Proc *proc = GuiContext::getCurrent()->getProc();
2943   CommandSetDSPortProperties *command =
2944     new CommandSetDSPortProperties(proc->getChildName(getPort()->getNode()), getName(), true, properties);
2945   if (command->execute())
2946     {
2947       GuiContext::getCurrent()->getInvoc()->add(command);
2948       return true;
2949     }
2950   else delete command;
2951   return false;
2952 }
2953
2954 void SubjectInputDataStreamPort::clean()
2955 {
2956   localClean();
2957   SubjectDataPort::clean();
2958 }
2959
2960 void SubjectInputDataStreamPort::localClean()
2961 {
2962   DEBTRACE("SubjectInputDataStreamPort::localClean ");
2963 }
2964
2965 // ----------------------------------------------------------------------------
2966
2967 SubjectOutputDataStreamPort::SubjectOutputDataStreamPort(YACS::ENGINE::OutputDataStreamPort *port,
2968                                                          Subject *parent)
2969   : SubjectDataPort(port, parent), _outputDataStreamPort(port)
2970 {
2971 }
2972
2973 SubjectOutputDataStreamPort::~SubjectOutputDataStreamPort()
2974 {
2975   DEBTRACE("SubjectOutputDataStreamPort::~SubjectOutputDataStreamPort " << getName());
2976 }
2977
2978 std::map<std::string, std::string> SubjectOutputDataStreamPort::getProperties()
2979 {
2980   return _outputDataStreamPort->getPropertyMap();
2981 }
2982
2983 bool SubjectOutputDataStreamPort::setProperties(std::map<std::string, std::string> properties)
2984 {
2985   Proc *proc = GuiContext::getCurrent()->getProc();
2986   CommandSetDSPortProperties *command =
2987     new CommandSetDSPortProperties(proc->getChildName(getPort()->getNode()), getName(), false, properties);
2988   if (command->execute())
2989     {
2990       GuiContext::getCurrent()->getInvoc()->add(command);
2991       return true;
2992     }
2993   else delete command;
2994   return false;
2995 }
2996
2997 void SubjectOutputDataStreamPort::clean()
2998 {
2999   localClean();
3000   SubjectDataPort::clean();
3001 }
3002
3003 void SubjectOutputDataStreamPort::localClean()
3004 {
3005   DEBTRACE("SubjectOutputDataStreamPort::localClean ");
3006 }
3007
3008 // ----------------------------------------------------------------------------
3009
3010 SubjectLink::SubjectLink(SubjectNode* subOutNode,
3011                          SubjectDataPort* outPort,
3012                          SubjectNode* subInNode,
3013                          SubjectDataPort* inPort,
3014                          Subject *parent)
3015   : Subject(parent),
3016     _subOutNode(subOutNode), _outPort(outPort), _subInNode(subInNode), _inPort(inPort)
3017 {
3018   _name = "";
3019   ComposedNode *cla = ComposedNode::getLowestCommonAncestor(_subOutNode->getNode()->getFather(),
3020                                                             _subInNode->getNode()->getFather());
3021   DEBTRACE(_subOutNode->getName() << "." << _outPort->getName());
3022   DEBTRACE(_subInNode->getName() << "." << _inPort->getName());
3023   DEBTRACE(cla->getName());
3024   _name += cla->getChildName(_subOutNode->getNode());
3025   _name += "." + _outPort->getName();
3026   _name += "->";
3027   _name += cla->getChildName(_subInNode->getNode());
3028   _name += "." + _inPort->getName();
3029   DEBTRACE("SubjectLink::SubjectLink " << _name);
3030 }
3031
3032 SubjectLink::~SubjectLink()
3033 {
3034   DEBTRACE("SubjectLink::~SubjectLink " << getName());
3035 }
3036
3037 void SubjectLink::clean()
3038 {
3039   localClean();
3040   Subject::clean();
3041 }
3042
3043 void SubjectLink::localClean()
3044 {
3045   DEBTRACE("SubjectLink::localClean ");
3046   if (_parent)
3047     {
3048       DEBTRACE("clean link: " << _parent->getName() << " " << getName());
3049       SubjectComposedNode* father = dynamic_cast<SubjectComposedNode*>(_parent);
3050       assert(father);
3051       father->removeLink(this); // --- clean subjects first
3052       _cla = dynamic_cast<ComposedNode*>(father->getNode());
3053       assert(_cla);
3054       _outp = dynamic_cast<OutPort*>(_outPort->getPort());
3055       assert(_outp);
3056       _inp = dynamic_cast<InPort*>(_inPort->getPort());
3057       assert(_inp);
3058       if (isDestructible())
3059         _cla->edRemoveLink(_outp, _inp);
3060     }
3061 }
3062
3063 std::string SubjectLink::getName()
3064 {
3065   return _name;
3066 }
3067 // ----------------------------------------------------------------------------
3068
3069 SubjectControlLink::SubjectControlLink(SubjectNode* subOutNode,
3070                                        SubjectNode* subInNode,
3071                                        Subject *parent)
3072   : Subject(parent),
3073     _subOutNode(subOutNode), _subInNode(subInNode)
3074 {
3075   _name = "";
3076   ComposedNode *cla = ComposedNode::getLowestCommonAncestor(_subOutNode->getNode()->getFather(),
3077                                                             _subInNode->getNode()->getFather());
3078   DEBTRACE(_subOutNode->getName());
3079   DEBTRACE(_subInNode->getName());
3080   DEBTRACE(cla->getName());
3081   _name += cla->getChildName(_subOutNode->getNode());
3082   _name += "-->>";
3083   _name += cla->getChildName(_subInNode->getNode());
3084   DEBTRACE("SubjectControlLink::SubjectControlLink " << _name);
3085 }
3086
3087 SubjectControlLink::~SubjectControlLink()
3088 {
3089   DEBTRACE("SubjectControlLink::~SubjectControlLink " << getName());
3090   if (isDestructible())
3091     {
3092       try
3093         {
3094
3095           _cla->edRemoveCFLink(_subOutNode->getNode(), _subInNode->getNode());
3096         }
3097       catch (YACS::Exception &e)
3098         {
3099           DEBTRACE("------------------------------------------------------------------------------");
3100           DEBTRACE("SubjectControlLink::~SubjectControlLink: edRemoveLink YACS exception " << e.what());
3101           DEBTRACE("------------------------------------------------------------------------------");
3102         }
3103     }
3104 }
3105
3106 void SubjectControlLink::clean()
3107 {
3108   localClean();
3109   Subject::clean();
3110 }
3111
3112 void SubjectControlLink::localClean()
3113 {
3114   DEBTRACE("SubjectControlLink::localClean ");
3115   if (_parent)
3116     {
3117       DEBTRACE("clean control link: " << _parent->getName() << " " << getName());
3118       SubjectComposedNode* father = dynamic_cast<SubjectComposedNode*>(_parent);
3119       assert(father);
3120       father->removeControlLink(this); // --- clean subjects first
3121       _cla = dynamic_cast<ComposedNode*>(father->getNode());
3122       assert(_cla);
3123     }
3124 }
3125
3126 std::string SubjectControlLink::getName()
3127 {
3128   return _name;
3129 }
3130
3131 // ----------------------------------------------------------------------------
3132
3133 SubjectComponent::SubjectComponent(YACS::ENGINE::ComponentInstance* component, Subject *parent)
3134   : Subject(parent), _compoInst(component)
3135 {
3136   _compoInst->incrRef();
3137   _subRefContainer = 0;
3138   _subServiceSet.clear();
3139 }
3140
3141 SubjectComponent::~SubjectComponent()
3142 {
3143   Proc* aProc = GuiContext::getCurrent()->getProc();
3144   if ( aProc )
3145   {
3146     pair<string,int> key = pair<string,int>(_compoInst->getCompoName(),_compoInst->getNumId());
3147     aProc->componentInstanceMap.erase(key);
3148     GuiContext::getCurrent()->_mapOfSubjectComponent.erase(_compoInst);
3149   }
3150   _compoInst->decrRef();
3151 }
3152
3153 void SubjectComponent::clean()
3154 {
3155   localClean();
3156   Subject::clean();
3157 }
3158
3159 void SubjectComponent::localClean()
3160 {
3161   DEBTRACE("SubjectComponent::localClean ");
3162   Proc* aProc = GuiContext::getCurrent()->getProc();
3163   if ( aProc )
3164   {
3165     std::map<Node*, SubjectNode*>::iterator it = GuiContext::getCurrent()->_mapOfSubjectNode.begin();
3166     std::list<SubjectNode*> services;
3167     for ( ; it!=GuiContext::getCurrent()->_mapOfSubjectNode.end(); it++ )
3168       {
3169         if(ServiceNode* service=dynamic_cast<ServiceNode*>((*it).first))
3170           {
3171             if ( service->getComponent() == _compoInst )
3172               {
3173                 services.push_back((*it).second);
3174               }
3175           }
3176       }
3177     while(!services.empty())
3178       {
3179         SubjectNode* son=services.front();
3180         services.pop_front();
3181         Subject* parent=son->getParent();
3182 //         parent->update(REMOVE,son->getType(),son);
3183         parent->erase(son);
3184         parent->update(REMOVE,0,0);
3185       }
3186   }
3187 }
3188
3189 std::string SubjectComponent::getName()
3190 {
3191   return _compoInst->getInstanceName();
3192 }
3193
3194 std::pair<std::string, int> SubjectComponent::getKey()
3195 {
3196   std::pair<std::string, int> key = std::pair<std::string, int>(_compoInst->getCompoName(), _compoInst->getNumId());
3197   return key;
3198 }
3199
3200 YACS::ENGINE::ComponentInstance* SubjectComponent::getComponent() const
3201 {
3202   return _compoInst;
3203 }
3204
3205 /*!
3206  *  When loading scheme from file, get the container associated to the component, if any,
3207  *  and create the corresponding subject.
3208  */
3209 void SubjectComponent::setContainer()
3210 {
3211   DEBTRACE("SubjectComponent::setContainer " << getName());
3212   Container* container = _compoInst->getContainer();
3213   if (container)
3214     {
3215       SubjectContainer *subContainer;
3216       if (GuiContext::getCurrent()->_mapOfSubjectContainer.count(container))
3217         subContainer = GuiContext::getCurrent()->_mapOfSubjectContainer[container];
3218       else
3219         subContainer = 
3220           GuiContext::getCurrent()->getSubjectProc()->addSubjectContainer(container, container->getName());
3221       addSubjectReference(subContainer);
3222       if (_subRefContainer)
3223         subContainer->moveComponent(_subRefContainer);
3224       else
3225         _subRefContainer = subContainer->attachComponent(this);
3226       notifyServicesChange(ASSOCIATE, CONTAINER, subContainer);
3227     }
3228 }
3229
3230 bool SubjectComponent::associateToContainer(SubjectContainer* subcont)
3231 {
3232   DEBTRACE("SubjectComponent::associateToContainer " << getName() << subcont->getName());
3233   CommandAssociateComponentToContainer *command =
3234     new CommandAssociateComponentToContainer(getKey(), subcont->getName());
3235   if (command->execute())
3236     {
3237       GuiContext::getCurrent()->getInvoc()->add(command);
3238
3239       addSubjectReference(subcont);
3240       if (_subRefContainer)
3241         subcont->moveComponent(_subRefContainer);
3242       else
3243         _subRefContainer = subcont->attachComponent(this);
3244       notifyServicesChange(ASSOCIATE, CONTAINER, subcont);
3245       return true;
3246     }
3247   else delete command;
3248   return false;
3249 }
3250
3251 SubjectReference* SubjectComponent::attachService(SubjectServiceNode* service)
3252 {
3253   _subServiceSet.insert(service);
3254   SubjectReference *son = new SubjectReference(service, this);
3255   update(ADDCHILDREF, SALOMENODE, son);
3256   return son;
3257 }
3258
3259 void SubjectComponent::detachService(SubjectReference* reference)
3260 {
3261   _subServiceSet.erase(dynamic_cast<SubjectServiceNode*>(reference->getReference()));
3262   update(REMOVECHILDREF, SALOMENODE, reference);
3263   erase(reference);
3264 }
3265
3266 void SubjectComponent::moveService(SubjectReference* reference)
3267 {
3268   SubjectComponent* oldcomp = dynamic_cast<SubjectComponent*>(reference->getParent());
3269   assert(oldcomp);
3270
3271   SubjectServiceNode* service = dynamic_cast<SubjectServiceNode*>(reference->getReference());
3272   oldcomp->removeSubServiceFromSet(service);
3273   _subServiceSet.insert(service);
3274
3275   oldcomp->update(CUT, SALOMENODE, reference);
3276   reference->reparent(this);
3277   update(PASTE, SALOMENODE, reference);
3278 }
3279
3280 void SubjectComponent::removeSubServiceFromSet(SubjectServiceNode *service)
3281 {
3282   _subServiceSet.erase(service);
3283 }
3284
3285 void SubjectComponent::notifyServicesChange(GuiEvent event, int type, Subject* son)
3286 {
3287   set<SubjectServiceNode*>::iterator it = _subServiceSet.begin();
3288   for(; it != _subServiceSet.end(); ++it)
3289     {
3290       (*it)->update(event, type, son);
3291     }
3292 }
3293
3294 // ----------------------------------------------------------------------------
3295
3296 SubjectContainer::SubjectContainer(YACS::ENGINE::Container* container, Subject *parent)
3297   : Subject(parent), _container(container)
3298 {
3299   _subComponentSet.clear();
3300 }
3301
3302 SubjectContainer::~SubjectContainer()
3303 {
3304   DEBTRACE("SubjectContainer::~SubjectContainer");
3305   Proc* aProc = GuiContext::getCurrent()->getProc();
3306   if ( aProc )
3307   {
3308     aProc->containerMap.erase(_container->getName());
3309
3310     map<ComponentInstance*,SubjectComponent*> mapOfSubjectComponentCpy
3311       = GuiContext::getCurrent()->_mapOfSubjectComponent;
3312     map<ComponentInstance*,SubjectComponent*>::iterator it = mapOfSubjectComponentCpy.begin();
3313     for ( ; it!=mapOfSubjectComponentCpy.end(); it++ )
3314       if ( (*it).first && (*it).first->getContainer() == _container )
3315       {
3316         (*it).first->setContainer(0);
3317         GuiContext::getCurrent()->getSubjectProc()->destroy((*it).second);
3318       }
3319
3320     GuiContext::getCurrent()->_mapOfSubjectContainer.erase(_container);
3321   }
3322 }
3323
3324 std::map<std::string, std::string> SubjectContainer::getProperties()
3325 {
3326   return _container->getProperties();
3327 }
3328
3329 bool SubjectContainer::setProperties(std::map<std::string, std::string> properties)
3330 {
3331   CommandSetContainerProperties *command = new CommandSetContainerProperties(getName(), properties);
3332   if (command->execute())
3333     {
3334       GuiContext::getCurrent()->getInvoc()->add(command);
3335       return true;
3336     }
3337   else delete command;
3338   return false;
3339 }
3340
3341 bool SubjectContainer::setName(std::string name)
3342 {
3343   DEBTRACE("SubjectContainer::setName " << name);
3344   CommandRenameContainer* command = new CommandRenameContainer(getName(), name);
3345   if (command->execute())
3346     {
3347       GuiContext::getCurrent()->getInvoc()->add(command);
3348       update(RENAME, 0, this);
3349       notifyComponentsChange(ASSOCIATE, CONTAINER, this);
3350       return true;
3351     }
3352   else delete command;
3353   return false;
3354 }
3355
3356 SubjectReference* SubjectContainer::attachComponent(SubjectComponent* component)
3357 {
3358   _subComponentSet.insert(component);
3359   SubjectReference *son = new SubjectReference(component, this);
3360   update(ADDCHILDREF, COMPONENT, son);
3361   return son;
3362 }
3363
3364 void SubjectContainer::detachComponent(SubjectReference* reference)
3365 {
3366   _subComponentSet.erase(dynamic_cast<SubjectComponent*>(reference->getReference()));
3367   update(REMOVECHILDREF, COMPONENT, reference);
3368   erase(reference);
3369 }
3370
3371 void SubjectContainer::moveComponent(SubjectReference* reference)
3372 {
3373   SubjectContainer* oldcont = dynamic_cast<SubjectContainer*>(reference->getParent());
3374   assert(oldcont);
3375   SubjectComponent* component = dynamic_cast<SubjectComponent*>(reference->getReference());
3376   _subComponentSet.insert(component);
3377   oldcont->removeSubComponentFromSet(component);
3378   oldcont->update(CUT, COMPONENT, reference);
3379   reference->reparent(this);
3380   update(PASTE, COMPONENT, reference);
3381 }
3382
3383 void SubjectContainer::removeSubComponentFromSet(SubjectComponent *component)
3384 {
3385   _subComponentSet.erase(component);
3386 }
3387
3388 void SubjectContainer::notifyComponentsChange(GuiEvent event, int type, Subject* son)
3389 {
3390   set<SubjectComponent*>::iterator it = _subComponentSet.begin();
3391   for(; it != _subComponentSet.end(); ++it)
3392     {
3393       (*it)->update(event, type, son);
3394       (*it)->notifyServicesChange(event, type, son);
3395     }
3396 }
3397
3398
3399 void SubjectContainer::clean()
3400 {
3401   localClean();
3402   Subject::clean();
3403 }
3404
3405 void SubjectContainer::localClean()
3406 {
3407   DEBTRACE("SubjectContainer::localClean ");
3408   Proc* aProc = GuiContext::getCurrent()->getProc();
3409   if ( aProc )
3410   {
3411     SubjectComponent* compo;
3412     map<ComponentInstance*,SubjectComponent*>::iterator it = GuiContext::getCurrent()->_mapOfSubjectComponent.begin();
3413     std::list<SubjectComponent*> compos;
3414     for ( ; it!=GuiContext::getCurrent()->_mapOfSubjectComponent.end(); it++ )
3415       if ( (*it).first && (*it).first->getContainer() == _container )
3416       {
3417         compo=(*it).second;
3418         (*it).first->setContainer(0);
3419         compos.push_back((*it).second);
3420       }
3421     while(!compos.empty())
3422       {
3423         compo=compos.front();
3424         compos.pop_front();
3425         GuiContext::getCurrent()->getSubjectProc()->update(REMOVE,compo->getType(),compo);
3426         GuiContext::getCurrent()->getSubjectProc()->erase(compo);
3427       }
3428   }
3429 }
3430
3431 std::string SubjectContainer::getName()
3432 {
3433   return _container->getName();
3434 }
3435
3436 YACS::ENGINE::Container* SubjectContainer::getContainer() const
3437 {
3438   return _container;
3439 }
3440
3441 // ----------------------------------------------------------------------------
3442
3443 SubjectDataType::SubjectDataType(YACS::ENGINE::TypeCode *typeCode, Subject *parent, std::string alias)
3444   : Subject(parent), _typeCode(typeCode), _alias(alias)
3445 {
3446 }
3447
3448 SubjectDataType::~SubjectDataType()
3449 {
3450 }
3451
3452 void SubjectDataType::clean()
3453 {
3454   localClean();
3455   Subject::clean();
3456 }
3457
3458 void SubjectDataType::localClean()
3459 {
3460   DEBTRACE("SubjectDataType::localClean ");
3461 }
3462
3463 std::string SubjectDataType::getName()
3464 {
3465   return _typeCode->name();
3466 }
3467
3468 std::string SubjectDataType::getAlias()
3469 {
3470   return _alias;
3471 }
3472
3473 YACS::ENGINE::TypeCode* SubjectDataType::getTypeCode()
3474 {
3475   return _typeCode;
3476 }
3477
3478 // ----------------------------------------------------------------------------