Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/superv.git] / src / GraphEditor / DataFlowEditor_OutNode.cxx
1 //  SUPERV GraphEditor : contains classes that permit edition of graphs
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : DataFlowEditor_OutNode.cxx
25 //  Module : SUPERV
26
27 using namespace std;
28 #include <sstream>
29 #include <iostream>
30 #include "DataFlowEditor_DataFlow.hxx"
31 #include "DataFlowEditor_OutNode.hxx"
32 #include "DataFlowBase_EndOfLoopNode.hxx"
33 #include "DataFlowBase_EndOfSwitchNode.hxx"
34
35 //map< string , GraphBase::Graph * > GraphEditor::OutNode::_MapOfGraphs;
36 map< string , int > _MapOfGraphNames;
37
38 string GraphInstanceName( const char * aGraphName ) {
39   // mkr : PAL8004 -->
40   // For Macro nodes : names of subgraphs must be unique and differ from the main dataflow
41   // name (i.e. the dataflow with MacroLevel = 0).
42   // It is neccessary for reqursive call of LoadDataFlows(...) method for MacroNodes execution.
43   int GraphInstanceNumber = _MapOfGraphNames[ aGraphName ] ;
44   string theGraphInstanceName = string( aGraphName ) ;
45   if ( GraphInstanceNumber ) {
46     theGraphInstanceName += "_" ;
47     ostringstream astr ;
48     astr << GraphInstanceNumber ;
49     theGraphInstanceName += astr.str() ;
50   }
51   if ( theGraphInstanceName != string( aGraphName ) )
52     _MapOfGraphNames[ theGraphInstanceName ] = GraphInstanceNumber ;
53   _MapOfGraphNames[ aGraphName ] = GraphInstanceNumber + 1 ;
54   // mkr : PAL8004 <--
55   return theGraphInstanceName ;
56 }
57
58
59 // Implementation de la classe GraphEditor::Graph
60
61 GraphEditor::OutNode::OutNode() {
62 //             Graph() {
63   cdebug_in << "GraphEditor::OutNode::OutNode()" << endl;
64
65   _Graph = NULL ;
66   _Imported = false ;
67   _Valid = false ;
68   _Executable = false ;
69
70   cdebug_out << "GraphEditor::OutNode::OutNode()" << endl;
71 }
72
73 GraphEditor::OutNode::OutNode( CORBA::ORB_ptr ORB ,
74                                SALOME_NamingService * ptrNamingService ,
75                                const char * DataFlowName ,
76                                const char * DebugFileName ,
77                                const SUPERV::KindOfNode aKindOfNode ) {
78 //             Graph( ORB , ptrNamingService , DataFlowName , DebugFileName ) {
79   _Graph = NULL ;
80   Set_prof_debug( ORB , DebugFileName ) ;
81   cdebug_in << "GraphEditor::OutNode::OutNode(" ;
82   if ( DataFlowName ) {
83     cdebug << DataFlowName ;
84   }
85   cdebug << ")" << endl;
86
87   if ( aKindOfNode == SUPERV::DataFlowGraph ) {
88     _StreamGraph = NULL ;
89     _Graph = new GraphBase::Graph( ORB , ptrNamingService , DataFlowName , aKindOfNode ,
90                                    _prof_debug , _fdebug ) ; 
91 //    MapGraph( _Graph , _Graph->Name() ) ;
92   }
93   else if ( aKindOfNode == SUPERV::DataStreamGraph ) {
94     _StreamGraph = new GraphBase::StreamGraph( ORB , ptrNamingService , DataFlowName , aKindOfNode ,
95                                                _prof_debug , _fdebug ) ;
96     _Graph = _StreamGraph ;
97 //    MapGraph( _Graph , _Graph->Name() ) ;
98   }
99   _Orb = CORBA::ORB::_duplicate( ORB ) ;
100   _Imported = false ;
101   _Valid = false ;
102   _Executable = false ;
103
104   cdebug_out << "GraphEditor::OutNode::OutNode" << endl;
105 }
106
107 GraphEditor::OutNode::OutNode(
108                      CORBA::ORB_ptr ORB ,
109                      SALOME_NamingService * ptrNamingService ,
110                      const SALOME_ModuleCatalog::Service& DataFlowService ,
111                      const char * DataFlowComponentName ,
112                      const char * DataFlowInterfaceName ,
113                      const char * DataFlowName ,
114                      const SUPERV::KindOfNode DataFlowkind ,
115                      const SUPERV::SDate DataFlowFirstCreation ,
116                      const SUPERV::SDate DataFlowLastModification ,
117                      const char * DataFlowEditorRelease ,
118                      const char * DataFlowAuthor ,
119                      const char * DataFlowComputer ,
120                      const char * DataFlowComment ,
121                      const char * DebugFileName ) {
122   _Graph = NULL ;
123   Set_prof_debug( ORB , DebugFileName ) ;
124
125   if ( DataFlowkind == SUPERV::DataFlowGraph ) {
126     _StreamGraph = NULL ;
127     _Graph = new GraphBase::Graph( ORB , ptrNamingService , DataFlowService , DataFlowComponentName ,
128                                    DataFlowInterfaceName , DataFlowName , DataFlowkind ,
129                                    DataFlowFirstCreation , DataFlowLastModification  ,
130                                    DataFlowEditorRelease , DataFlowAuthor ,
131                                    DataFlowComputer , DataFlowComment ,
132                                    _prof_debug , _fdebug ) ;
133 //    MapGraph( _Graph , _Graph->Name() ) ;
134   }
135   else if ( DataFlowkind == SUPERV::DataStreamGraph ) {
136     _StreamGraph = new GraphBase::StreamGraph( ORB , ptrNamingService , DataFlowService , DataFlowComponentName ,
137                                                DataFlowInterfaceName , DataFlowName , DataFlowkind ,
138                                                DataFlowFirstCreation , DataFlowLastModification  ,
139                                                DataFlowEditorRelease , DataFlowAuthor ,
140                                                DataFlowComputer , DataFlowComment ,
141                                                _prof_debug , _fdebug ) ;
142     _Graph = _StreamGraph ;
143 //    MapGraph( _Graph , _Graph->Name() ) ;
144   }
145   _Orb = CORBA::ORB::_duplicate( ORB ) ;
146   _Imported = false ;
147   _Valid = false ;
148   _Executable = false ;
149
150 } ;
151
152 GraphEditor::OutNode::~OutNode() {
153 //  EraseGraph( Graph->Name() ) ;
154 //  delete _DataFlowNode ;
155 //  delete _DataFlowDatas ;
156 //  delete _GT ;
157 }
158
159 bool GraphEditor::OutNode::Name( const char * aName ) {
160   bool RetVal = false ;
161 //  if ( !GraphName( aName ) ) {
162 //    char * aGraphName = Graph()->Name() ;
163     RetVal = Graph()->Name( aName ) ;
164 //    if ( RetVal ) {
165 //      EraseGraph( aGraphName ) ;
166 //      MapGraph( Graph() , aName ) ;
167 //    }
168 //  }
169   return RetVal ;
170 }
171
172 void GraphEditor::OutNode::Set_prof_debug( CORBA::ORB_ptr ORB ,
173                                            const char * DebugFileName ) {
174   _Graph_prof_debug = 0 ;
175   _prof_debug = 0 ;
176   if ( DebugFileName ) {
177     _fdebug = new ofstream( DebugFileName );
178     SetDebug( ORB , &_Graph_prof_debug , _fdebug ) ;
179     MESSAGE( endl << "Trace redirected to file " << DebugFileName << endl)
180   }
181 }
182
183 bool GraphEditor::OutNode::LoadDataFlow( const GraphBase::SGraph * aDataFlow ) {
184   bool RetVal = false ;
185   cdebug_in << "GraphEditor::OutNode::LoadDataFlow() " << (*aDataFlow).Info.theName.c_str()
186             << " GraphNodesSize " << Graph()->GraphNodesSize() << endl;
187   if ( !_Imported ) {
188     RetVal = LoadInfo( (*aDataFlow).Info ) ;
189     _Imported = true ;
190   }
191   else if ( Graph()->IsDataStreamNode() || (*aDataFlow).Info.theKind == SUPERV::DataFlowGraph ) {
192     RetVal = true ;
193   }
194   cdebug << "GraphEditor::OutNode::LoadDataFlow() _Imported " << _Imported << " RetVal " << RetVal << endl;
195
196   map< string , int > aMapOfNodes ;
197   if ( RetVal ) {
198     cdebug << "GraphEditor::OutNode::LoadDataFlow() LoadNodes GraphNodesSize " << Graph()->GraphNodesSize() << endl;
199     RetVal = LoadNodes( aMapOfNodes , (*aDataFlow).Nodes ) ;
200   }
201   if ( RetVal ) {
202     cdebug << "GraphEditor::OutNode::LoadDataFlow() LoadLinks GraphNodesSize " << Graph()->GraphNodesSize() << endl;
203     RetVal = LoadLinks( aMapOfNodes , (*aDataFlow).Links ) ;
204   }
205   if ( RetVal ) {
206     Valid() ;
207     cdebug << "GraphEditor::OutNode::LoadDataFlow() LoadDatas GraphNodesSize " << Graph()->GraphNodesSize() << endl;
208     RetVal = LoadDatas( aMapOfNodes , (*aDataFlow).Datas ) ;
209   }
210   cdebug_out << "GraphEditor::OutNode::LoadDataFlow done GraphNodesSize " << Graph()->GraphNodesSize()
211              << " _Valid " << _Valid << " _Executable " << _Executable << " RetVal " << RetVal << endl;
212   return RetVal ;
213 }
214
215 bool GraphEditor::OutNode::LoadXml( const char* myFileName , GraphBase::ListOfSGraphs & aListOfDataFlows ) {
216   bool RetVal = false ;
217 //  GraphBase::ListOfSGraphs aListOfDataFlows ;
218   if ( myFileName == NULL ) {
219     cdebug << "GraphEditor::OutNode::LoadXml() No file" << endl;
220     _Imported = true ;
221     char * aDataFlowName = Graph()->Name() ;
222 //  Name( Graph()->Name() ) ;
223     Name( GraphInstanceName( Graph()->Name() ).c_str() ) ;
224 //    MapGraph( Graph() , Graph()->Name() ) ;
225     cdebug << "GraphEditor::OutNode::LoadXml() " << aDataFlowName << " --> " << Graph()->Name() << endl;
226     RetVal = true ;
227   }
228   else {
229     cdebug_in << "GraphEditor::OutNode::LoadXml() " << myFileName << endl;
230     RetVal = Graph()->LoadXml( _Orb , myFileName , aListOfDataFlows ) ;
231 //    RetVal = LoadDataFlows( &aListOfDataFlows ) ;
232     cdebug_out << "GraphEditor::OutNode::LoadXml " << RetVal << " " << aListOfDataFlows.size()
233                << " Graphs" << endl;
234   }
235   return RetVal ;
236
237
238 #if 0
239 bool GraphEditor::OutNode::LoadXml( const char* myFileName ) {
240   bool RetVal = false ;
241   GraphBase::ListOfSGraphs aListOfDataFlows ;
242   if ( myFileName == NULL ) {
243     cdebug << "GraphEditor::OutNode::LoadXml() No file" << endl;
244     _Imported = true ;
245     RetVal = true ;
246   }
247   else if ( Graph()->LoadXml( _Orb , myFileName , aListOfDataFlows ) ) {
248     cdebug_in << "GraphEditor::OutNode::LoadXml() " << myFileName << endl;
249     RetVal = LoadDataFlows( &aListOfDataFlows ) ;
250     cdebug_out << "GraphEditor::OutNode::LoadXml " << RetVal << endl;
251   }
252   return RetVal ;
253 }
254 #endif
255
256 bool GraphEditor::OutNode::LoadInfo(const GraphBase::SNode &aDataFlowInfo ) {
257   bool RetVal = false ;
258   cdebug_in << "GraphEditor::OutNode::LoadInfo " << aDataFlowInfo.theName.c_str()
259             << endl ;
260 //  MESSAGE( "GraphEditor::OutNode::LoadInfo" );
261 //  ComponentName( aDataFlowInfo.theComponentName.c_str() ) ;
262 //  InterfaceName( aDataFlowInfo.theInterfaceName.c_str() ) ;
263   if ( Graph()->IsDataStreamNode() || aDataFlowInfo.theKind == SUPERV::DataFlowGraph ) {
264     char * aDataFlowName = Graph()->Name() ;
265 //    Graph()->Name( aDataFlowInfo.theName.c_str() ) ;
266     Graph()->Name( GraphInstanceName( aDataFlowInfo.theName.c_str() ).c_str() ) ;
267 //    MapGraph( Graph() , Graph()->Name() ) ;
268     cdebug << "GraphEditor::OutNode::LoadInfo " << aDataFlowName << " --> " << Graph()->Name()
269            << " aDataFlowInfo.Kind " << aDataFlowInfo.theKind << " Kind() " << Graph()->Kind() << endl ;
270     if ( Graph()->IsDataStreamNode() ) {
271       Graph()->Kind( SUPERV::DataStreamGraph ) ;
272       StreamGraph()->SetStreamParams( aDataFlowInfo.theTimeout , aDataFlowInfo.theDataStreamTrace , aDataFlowInfo.theDeltaTime ) ;
273     }
274     else {
275       Graph()->Kind( SUPERV::DataFlowGraph ) ;
276     }
277     Graph()->SetService( aDataFlowInfo.theService ) ;
278     Graph()->FirstCreation( aDataFlowInfo.theFirstCreation ) ;
279     Graph()->LastModification( aDataFlowInfo.theLastModification ) ;
280     Graph()->EditorRelease( aDataFlowInfo.theEditorRelease.c_str() ) ;
281     Graph()->Author( aDataFlowInfo.theAuthor.c_str()  ) ;
282 //    Graph()->Computer( aDataFlowInfo.theContainer.c_str() ) ;
283     Graph()->Comment( aDataFlowInfo.theComment.c_str() ) ;
284 // Not in OutNode/DataFlow but in InNode/DataFlow_in_an_other_DataFlow
285 //    Graph()->Coordinates( aDataFlowInfo.theX , aDataFlowInfo.theY ) ;
286     RetVal = true ;
287   }
288   else {
289     Graph()->Kind( aDataFlowInfo.theKind ) ;
290     cdebug << "GraphEditor::OutNode::LoadInfo aDataFlowInfo.Kind " << aDataFlowInfo.theKind
291            << " != IsDataStreamNode() " << Graph()->IsDataStreamNode() << endl ;
292   }
293   cdebug_out << "GraphEditor::OutNode::LoadInfo " << RetVal << endl ;
294   return RetVal ;
295 }
296
297 bool GraphEditor::OutNode::LoadNodes(map< string , int > & aMapOfNodes ,
298                                      const GraphBase::ListOfSNodes &aListOfNodes ) {
299   GraphEditor::InNode * anInNode ;
300   cdebug_in << "GraphEditor::OutNode::LoadNodes " << endl ;
301   int i ;
302   for ( i = 0 ; i < (int ) aListOfNodes.size() ; i++ ) {
303     GraphBase::SNode aNode = aListOfNodes[ i ] ;
304     const char * aNodeName = aNode.theName.c_str() ;
305 //    cout << "GraphEditor::OutNode::LoadNodes " << aNodeName << " "
306 //         << aNode.theService.ServiceinParameter.length() << " InParameters "
307 //         << aNode.theService.ServiceoutParameter.length() << " OutParameters "
308 //         << aNode.theListOfInDataStreams.size() << " InDataStreams "
309 //         << aNode.theListOfOutDataStreams.size() << " OutDataStreams "
310 //         << " _prof_debug " << _prof_debug << endl ;
311     cdebug << "GraphEditor::OutNode::LoadNodes " << aNodeName << " "
312            << aNode.theService.ServiceinParameter.length() << " InParameters "
313            << aNode.theService.ServiceoutParameter.length() << " OutParameters "
314            << aNode.theListOfInDataStreams.size() << " InDataStreams "
315            << aNode.theListOfOutDataStreams.size() << " OutDataStreams "
316            << endl ;
317     if ( aNode.theListOfFuncName.size() == 0 ) {
318       aNode.theListOfFuncName.resize( 1 ) ;
319       aNode.theListOfFuncName[ 0 ] = "" ;
320       aNode.theListOfPythonFunctions.resize( 1 ) ;
321       aNode.theListOfPythonFunctions[ 0 ] = new SUPERV::ListOfStrings() ;
322     }
323     if ( Graph()->GetGraphNode( aNode.theName.c_str() ) ) {
324       aNodeName = NULLSTRING ;
325     }
326
327     aNode.theService.ServiceinDataStreamParameter.length( aNode.theListOfInDataStreams.size() ) ;
328     aNode.theService.ServiceoutDataStreamParameter.length( aNode.theListOfOutDataStreams.size() ) ;
329     unsigned int j ;
330     for ( j = 0 ; j < aNode.theListOfInDataStreams.size() ; j++ ) {
331       aNode.theService.ServiceinDataStreamParameter[ j ].Parametername = aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parametername ,
332       aNode.theService.ServiceinDataStreamParameter[ j ].Parametertype = aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parametertype ,
333       aNode.theService.ServiceinDataStreamParameter[ j ].Parameterdependency = aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parameterdependency ;
334     }
335     for ( j = 0 ; j < aNode.theListOfOutDataStreams.size() ; j++ ) {
336       aNode.theService.ServiceoutDataStreamParameter[ j ].Parametername = aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parametername ,
337       aNode.theService.ServiceoutDataStreamParameter[ j ].Parametertype = aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parametertype ,
338       aNode.theService.ServiceoutDataStreamParameter[ j ].Parameterdependency = aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parameterdependency ;
339     }
340
341     anInNode = AddNode( aNode.theService ,
342                         aNode.theListOfFuncName ,
343                         aNode.theListOfPythonFunctions ,
344                         aNode.theComponentName.c_str() ,
345                         aNode.theInterfaceName.c_str() , aNodeName ,
346                         aNode.theKind ,
347                         aNode.theFirstCreation , aNode.theLastModification ,
348                         aNode.theEditorRelease.c_str() ,
349                         aNode.theAuthor.c_str() , aNode.theContainer.c_str() ,
350                         aNode.theComment.c_str() ,
351                         aNode.theCoords.theX , aNode.theCoords.theY ) ;
352
353     // insert container into < ComponentName, Container > map for corresponding component
354     Graph()->InsertToMapOfComponentNameContainer( aNode.theComponentName.c_str(), aNode.theContainer.c_str() ) ; // mkr : PAL13947
355
356     string * aNodetheName = new string( aNode.theName ) ;
357     aMapOfNodes[ *aNodetheName ] = Graph()->GetGraphNodeIndex( anInNode->Name() ) ;
358     if ( anInNode->IsOneOfInLineNodes() || anInNode->IsMacroNode() ) {
359       anInNode->GraphEditor::InNode::InLineNode()->DefPortsOfNode(
360                 _Orb , aNode.theService , anInNode->NamePtr() ,
361                 anInNode->Kind() ,
362                 _prof_debug , _fdebug ) ;
363       GraphBase::InLineNode * aINode = anInNode->InLineNode() ;
364       GraphBase::LoopNode * aLNode = NULL ;
365       if ( aINode->IsLoopNode() ) {
366         aLNode = anInNode->LoopNode() ;
367         aLNode->SetPythonFunction( aNode.theListOfFuncName[ 0 ].c_str() ,
368                                    *aNode.theListOfPythonFunctions[ 0 ] ) ;
369         aLNode->SetMorePythonFunction( aNode.theListOfFuncName[ 1 ].c_str() ,
370                                        *aNode.theListOfPythonFunctions[ 1 ] ) ;
371         aLNode->SetNextPythonFunction( aNode.theListOfFuncName[ 2 ].c_str() ,
372                                        *aNode.theListOfPythonFunctions[ 2 ] ) ;
373       }
374       else if ( aINode->IsMacroNode() || aINode->IsInLineNode() || aINode->IsGOTONode() ||
375                 aINode->IsSwitchNode() || aINode->IsEndSwitchNode() ) {
376         aINode->SetPythonFunction( aNode.theListOfFuncName[ 0 ].c_str() ,
377                                    *aNode.theListOfPythonFunctions[ 0 ] ) ;
378       }
379     }
380
381     for ( j = 0 ; j < aNode.theListOfInDataStreams.size() ; j++ ) {
382       GraphBase::InPort * anInPort ;
383       if ( anInNode->IsOneOfInLineNodes() ) {
384         anInPort = anInNode->ComputingNode()->AddInDataStreamPort( aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parametername ,
385                                                                    aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parametertype ,
386                                                                    aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parameterdependency ,
387                                                                    SUPERV::DataStreamParameter ) ;
388       }
389       else {
390         anInPort = anInNode->ComputingNode()->GetChangeInPort( aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parametername ) ;
391       }
392       ((GraphBase::InDataStreamPort * ) anInPort)->SetParams( aNode.theListOfInDataStreams[ j ].theKindOfSchema ,
393                                                               aNode.theListOfInDataStreams[ j ].theKindOfInterpolation ,
394                                                               aNode.theListOfInDataStreams[ j ].theKindOfExtrapolation ) ;
395     }
396     for ( j = 0 ; j < aNode.theListOfOutDataStreams.size() ; j++ ) {
397       GraphBase::OutPort * anOutPort ;
398       if ( anInNode->IsOneOfInLineNodes() ) {
399         anOutPort = anInNode->ComputingNode()->AddOutDataStreamPort( aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parametername ,
400                                                                      aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parametertype ,
401                                                                      aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parameterdependency ,
402                                                                      SUPERV::DataStreamParameter ) ;
403       }
404       else {
405         anOutPort = anInNode->ComputingNode()->GetChangeOutPort( aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parametername ) ;
406       }
407       ((GraphBase::OutDataStreamPort * ) anOutPort)->NumberOfValues( aNode.theListOfOutDataStreams[ j ].theNumberOfValues ) ;
408     }
409     delete aNodetheName ;
410     if ( !anInNode ) {
411       return false ;
412     }
413   }
414
415   // setting coupled pairs of nodes: Loop-EndLoop, Switch-EndSwitch, InLine-GOTO, MacroNode-Graph
416   for ( i = 0 ; i < (int ) aListOfNodes.size() ; i++ ) {
417     GraphBase::SNode aNode = aListOfNodes[ i ] ;
418     cdebug << "GraphEditor::OutNode::LoadNodes " << aNode.theName.c_str() << " Coupled to "
419            << aNode.theCoupledNode.c_str() << endl ;
420     anInNode = (GraphEditor::InNode * ) Graph()->GetChangeGraphNode( aMapOfNodes[ aNode.theName.c_str() ] )->GetInNode() ;
421
422     if ( anInNode->IsOneOfGOTONodes() && strlen( aNode.theCoupledNode.c_str() ) ) {
423       GraphBase::GOTONode * aGOTONode;
424       aGOTONode = (GraphBase::GOTONode * ) anInNode->ComputingNode() ;
425
426       // asv : 25.10.04 : if aNode is a MacroNode, then its coupled node (another Graph) is NOT in aMapOfNodes 
427       //                  and we must couple MacroNode only with name to its subgraph
428       if ( aGOTONode->IsMacroNode() ) {
429         cdebug << "GraphEditor::OutNode::LoadNodes MacroNode " << aNode.theName.c_str()
430                << " is Coupled ONLY WITH NAME to its subgraph " << aNode.theCoupledNode.c_str() << endl;
431         aGOTONode->CoupledNodeName( aNode.theCoupledNode.c_str() ) ;
432       }
433       else { // coupling Loop-EndLoop, Switch-EndSwitch, InLine-GOTO
434         // asv : fix for 6822 : using map because if aNode's name is the same as some existing node's name
435         // aMap will give the correct index any way (aMap has already a different name for aNode, SNode still has old name)
436         int aCoupledNodeIndex = aMapOfNodes[ aNode.theCoupledNode.c_str() ] ;
437         cdebug << "GraphEditor::OutNode::LoadNodes " << aNode.theCoupledNode.c_str()
438                << " index " << aCoupledNodeIndex << endl ;
439         GraphBase::GOTONode * aCoupledNode ;
440         aCoupledNode = (GraphBase::GOTONode * ) Graph()->GetChangeGraphNode( aCoupledNodeIndex ) ;
441         cdebug << "GraphEditor::OutNode::LoadNodes " << aNode.theName.c_str()
442                << " is now Coupled to " << aNode.theCoupledNode.c_str() << endl ;
443         aGOTONode->CoupledNode( aCoupledNode ) ;
444       }
445     }
446   }
447   cdebug_out << "GraphEditor::OutNode::LoadNodes" << endl ;
448   return true ;
449 }
450
451 bool GraphEditor::OutNode::LoadLinks(map< string , int > & aMapOfNodes ,
452                                      const GraphBase::ListOfSLinks &aListOfLinks ) {
453   bool RetVal = true ;
454   bool RetAddLink ;
455   cdebug_in << "GraphEditor::OutNode::LoadLinks" << endl ;
456 //  MESSAGE( "GraphEditor::OutNode::LoadLinks" );
457   int i , j ;
458   for ( i = 0 ; i < (int ) aListOfLinks.size() ; i++ ) {
459     GraphBase::SLink aLink = aListOfLinks[ i ] ;
460     string * aLinkFromNodeName = new string( aLink.FromNodeName.c_str() ) ;
461     string * aLinkToNodeName = new string( aLink.ToNodeName.c_str() ) ;
462     cdebug << "LoadLinks " << aLinkFromNodeName->c_str() << "( "
463            << aLink.FromServiceParameterName.c_str() << " ) --> "
464            << aLinkToNodeName->c_str() << "( "
465            << aLink.ToServiceParameterName.c_str() << " )" << endl ;
466     if ( Graph()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] ) &&
467          Graph()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] ) ) {
468 //JR 08.02.2005 : Rule of CEA : a bad graph may be stored in a xml
469       RetAddLink = AddLink( Graph()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
470                             aLink.FromServiceParameterName.c_str() ,
471                             Graph()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
472                             aLink.ToServiceParameterName.c_str() ) ;
473     }
474     else {
475       RetVal = false ;
476     }
477     if ( RetVal && RetAddLink ) {
478       for ( j = 0 ; j < (int ) aLink.aListOfCoords.size() ; j++ ) {
479         RetVal = AddLinkCoord( Graph()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
480                                         aLink.FromServiceParameterName.c_str() ,
481                                         Graph()->GetGraphNode( aMapOfNodes[ aLink.ToNodeName.c_str() ] )->Name() ,
482                                         aLink.ToServiceParameterName.c_str() ,
483                                        j + 1 ,
484                                        aLink.aListOfCoords[j].theX ,
485                                        aLink.aListOfCoords[j].theY ) ;
486         if ( !RetVal )
487           break ;
488       }
489     }
490     delete aLinkFromNodeName ;
491     delete aLinkToNodeName ;
492   }
493   cdebug_out << "GraphEditor::OutNode::LoadLinks " << RetVal << endl ;
494   return RetVal ;
495 }
496
497 bool GraphEditor::OutNode::LoadDatas(map< string , int > & aMapOfNodes ,
498                                      const GraphBase::ListOfSLinks &aListOfDatas ) {
499   bool RetVal = true ;
500   bool RetAddLink ;
501   cdebug_in << "GraphEditor::OutNode::LoadDatas" << endl ;
502 //  MESSAGE( "GraphEditor::OutNode::LoadDatas" );
503   int i ;
504   for ( i = 0 ; i < (int ) aListOfDatas.size() ; i++ ) {
505     GraphBase::SLink aLink = aListOfDatas[ i ] ;
506     cdebug << "OutNode::LoadDatas " << i << aLink.FromNodeName.c_str() << "(" << aLink.FromServiceParameterName
507            << ") --> " << aLink.ToNodeName.c_str() << "(" << aLink.ToServiceParameterName << ") CORBA::tk_xxx "
508            << aLink.aLinkValue.type()->kind() << endl ;
509     string * aLinkFromNodeName = new string( aLink.FromNodeName.c_str() ) ;
510     string * aLinkToNodeName = new string( aLink.ToNodeName.c_str() ) ;
511 //      cout << "LoadDatas " << aLink.FromNodeName.c_str() << " "
512 //           << aMapOfNodes[ aLinkFromNodeName->c_str() ] << endl ;
513 //      cout << "          " << aLink.ToNodeName.c_str() << " "
514 //           << aMapOfNodes[ aLinkToNodeName->c_str() ] << endl ;
515     RetAddLink = Graph()->AddInputData( Graph()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
516                                         aLink.ToServiceParameterName.c_str() ,
517                                         aLink.aLinkValue ) ;
518     delete aLinkFromNodeName ;
519     delete aLinkToNodeName ;
520     if ( !RetVal )
521       break ;
522   }
523   cdebug_out << "GraphEditor::OutNode::LoadDatas " << RetVal << endl ;
524   return RetVal ;
525 }
526
527 bool GraphEditor::OutNode::SaveXml(const char* filename) {
528   bool test;
529   cdebug_in << "GraphEditor::OutNode::SaveXml(" << filename << ")" << endl;
530   ofstream f(filename);
531   IsValid() ;
532   QDomDocument DomGraph ;
533   QDomElement Domsupergraph ;
534   cdebug << "OutNode::SaveXML("<< filename << ") ---> OutNode::SaveXML( ostream & f , QDomDocument & , true "
535          << " , QDomElement & ) " << Graph()->Name() << endl ;
536   test = SaveXML( f , DomGraph , true , Domsupergraph );
537   QString xml = DomGraph.toString() ;
538   f << xml << endl ;
539
540   cdebug << "OutNode::SaveXML("<< filename << ") done" << endl ;
541 //  if ( test ) {
542 //    QString xml = Graph.toString() ;
543 //    cout << "GraphEditor::OutNode::SaveXML " << xml << endl ;
544 //    f << xml << endl ;
545 //  }
546   cdebug_out << "GraphEditor::OutNode::SaveXml " << test << endl;
547   return test;
548 }
549
550
551 bool GraphEditor::OutNode::SavePy( const char* filename ) {
552   bool test;
553   cdebug_in << "GraphEditor::OutNode::SavePy(" << filename << ")" << endl;
554   ofstream f( filename ) ;
555   IsValid() ;
556   test = SavePY( f , true );
557   f << endl << Graph()->Name() << " = Def" << Graph()->Name() << "()" << endl ;
558   cdebug_out << "GraphEditor::OutNode::SavePy " << test << endl;
559   return test;
560 }
561
562 GraphBase::ListOfSGraphs * GraphEditor::OutNode::GetDataFlows( GraphBase::ListOfSGraphs * aListOfDataFlows ) {
563 //  GraphBase::ListOfSGraphs * aListOfDataFlows = new GraphBase::ListOfSGraphs;
564   int index = aListOfDataFlows->size() ;
565   aListOfDataFlows->resize( index + 1 ) ;
566   if ( Graph()->IsDataFlowNode() ) {
567     (*aListOfDataFlows)[ index ].Info = *Graph()->GetInfo() ;
568     (*aListOfDataFlows)[ index ].Nodes = *Graph()->GetNodes() ;
569     (*aListOfDataFlows)[ index ].Links = *Graph()->GetLinks( true ) ;
570     (*aListOfDataFlows)[ index ].Datas = *Graph()->GetDatas() ;
571   }
572   else {
573     (*aListOfDataFlows)[ index ].Info = *StreamGraph()->GetInfo() ;
574     (*aListOfDataFlows)[ index ].Nodes = *StreamGraph()->GetNodes() ;
575     (*aListOfDataFlows)[ index ].Links = *StreamGraph()->GetLinks( true ) ;
576     (*aListOfDataFlows)[ index ].Datas = *StreamGraph()->GetDatas() ;
577   }
578   int i ;
579   for ( i = 0 ; i < (int ) (*aListOfDataFlows)[ index ].Nodes.size() ; i++ ) {
580     const GraphBase::ComputingNode * aNode = Graph()->GetGraphNode( (*aListOfDataFlows)[ index ].Nodes[i].theName.c_str() ) ;
581     if ( aNode->IsMacroNode() ) {
582 //      string aCoupledNodeName = (*aListOfDataFlows)[ index ].Nodes[i].theCoupledNode ;
583       GraphBase::Graph * aGraph = (GraphBase::Graph * ) ((GraphBase::GOTONode * ) aNode )->CoupledNode() ;
584 //      GraphBase::Graph * aGraph = MapGraph( aCoupledNodeName.c_str() ) ;
585       aGraph->GraphEditor()->GraphEditor::OutNode::GetDataFlows( aListOfDataFlows ) ;
586     }
587   }
588   return aListOfDataFlows ;
589 }
590
591 void GraphEditor::OutNode::DateModification() {
592   time_t T = time(NULL);
593   struct tm * Tm = localtime(&T);
594   SUPERV::SDate aLastModificationDate ;
595
596   aLastModificationDate.Second = Tm->tm_sec;
597   aLastModificationDate.Minute = Tm->tm_min;
598   aLastModificationDate.Hour   = Tm->tm_hour;
599   aLastModificationDate.Day    = Tm->tm_mday;
600   aLastModificationDate.Month  = Tm->tm_mon + 1;
601   aLastModificationDate.Year   = Tm->tm_year + 1900;
602   Graph()->LastModification( aLastModificationDate ) ;
603 }
604
605 void GraphEditor::OutNode::Coordinates( const char* NodeName ,
606                                         const int X ,
607                                         const int Y ) {
608   ((GraphEditor::InNode * ) Graph()->GetChangeGraphNode( NodeName ))->Coordinates( X , Y ) ;
609 }
610
611 const int GraphEditor::OutNode::XCoordinate( const char* NodeName ) {
612   return ((GraphEditor::InNode * ) Graph()->GetChangeGraphNode( NodeName ))->XCoordinate() ;
613 }
614
615 const int GraphEditor::OutNode::YCoordinate( const char* NodeName ) {
616   return ((GraphEditor::InNode * ) Graph()->GetChangeGraphNode( NodeName ))->YCoordinate() ;
617 }
618
619 GraphEditor::InNode * GraphEditor::OutNode::AddNode(
620                       const SALOME_ModuleCatalog::Service& NodeService ,
621                       GraphBase::ListOfFuncName aFuncName ,
622                       GraphBase::ListOfPythonFunctions aPythonFunction ,
623                       const char * NodeComponentName ,
624                       const char * NodeInterfaceName ,
625                       const char * theNodeName ,
626                       const SUPERV::KindOfNode NodeKindOfNode ,
627                       const SUPERV::SDate NodeFirstCreation ,
628                       const SUPERV::SDate NodeLastModification  ,
629                       const char * NodeEditorRelease ,
630                       const char * NodeAuthor ,
631                       const char * NodeComputer ,
632                       const char * NodeComment ,
633                       const int NodeX ,
634                       const int NodeY ) {
635   cdebug_in << "GraphEditor::OutNode::AddNode( " ;
636   if ( NodeComponentName != NULLSTRING && strlen( NodeComponentName ) ) {
637     cdebug << "Component('" << NodeComponentName << "') , Node('" ;
638   }
639   else {
640     cdebug << "NodeComponentName[NULL] )" << endl;
641   }
642   if ( theNodeName == NULL ) {
643     theNodeName = NULLSTRING ;
644   }
645   if ( theNodeName != NULLSTRING && strlen( theNodeName ) ) {
646     cdebug << theNodeName << "' )" ;
647   }
648   else {
649     cdebug << "NodeName[NULLSTRING]' )" ;
650   }
651   cdebug << " " << NodeKindOfNode << endl ;
652   char * RetVal = NULLSTRING ;
653   GraphEditor::InNode *Nd = NULL ;
654   char * aNodeName = NULLSTRING ;
655   bool   GeneratedName = false ;
656 //PAL9048 JR Debug : a node may not have the same name as the graph
657   bool GraphNodeSameName = false ;
658   if ( theNodeName && !strcmp( Graph()->Name() , theNodeName ) ) {
659     GraphNodeSameName = true ;
660   }
661   if ( NodeKindOfNode == SUPERV::InLineNode ||
662        NodeKindOfNode == SUPERV::LoopNode ||
663        NodeKindOfNode == SUPERV::EndLoopNode ||
664        NodeKindOfNode == SUPERV::SwitchNode ||
665        NodeKindOfNode == SUPERV::EndSwitchNode ||
666        NodeKindOfNode == SUPERV::GOTONode ) {
667     if ( theNodeName == NULLSTRING || strlen( theNodeName ) == 0 ) {
668       if ( NodeKindOfNode == SUPERV::InLineNode ) {
669         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "InLine" ) ;
670       }
671       else if ( NodeKindOfNode == SUPERV::LoopNode ) {
672         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "Loop" ) ;
673       }
674       else if ( NodeKindOfNode == SUPERV::EndLoopNode ) {
675         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "EndLoop" ) ;
676       }
677       else if ( NodeKindOfNode == SUPERV::SwitchNode ) {
678         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "Switch" ) ;
679       }
680       else if ( NodeKindOfNode == SUPERV::EndSwitchNode ) {
681         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "EndSwitch" ) ;
682       }
683       else if ( NodeKindOfNode == SUPERV::GOTONode ) {
684         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "GOTO" ) ;
685       }
686     }
687     else {
688       ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = CORBA::string_dup( theNodeName ) ;
689     }
690     theNodeName = NULLSTRING ;
691   }
692 //PAL9048 JR Debug : a node may not have the same name as the graph
693 //  if ( theNodeName == NULLSTRING || strlen( theNodeName ) == 0 || Graph()->GetGraphNode( theNodeName ) ) {
694   if ( theNodeName == NULLSTRING || strlen( theNodeName ) == 0 ||
695        Graph()->GetGraphNode( theNodeName ) || GraphNodeSameName ) {
696     cdebug << "OutNode::AddNode : '" << theNodeName << "' GraphNodeSameName "
697            << GraphNodeSameName << endl;
698     aNodeName = new char[ strlen( NodeService.ServiceName )+1 ] ;
699     strcpy( aNodeName , NodeService.ServiceName ) ;
700 //    if ( Graph()->GetGraphNode( NodeService.ServiceName ) ) {
701     if ( Graph()->GetGraphNode( NodeService.ServiceName ) || GraphNodeSameName ) {
702       GeneratedName = true ;
703       while ( Graph()->GetGraphNode( aNodeName ) || GraphNodeSameName ) {
704         cdebug << "OutNode::AddNode : '" << aNodeName << "' exists or GraphNodeSameName "
705                << GraphNodeSameName << endl;
706         if ( aNodeName ) {
707           delete [] aNodeName ;
708         }
709 //JR 09.08.2005 Debug : folowing line does not run with OMNIORB4
710 //        char * aServiceName = (CORBA::String_member ) NodeService.ServiceName ;
711         int num = Graph()->GetNewServiceInstanceNumber( (CORBA::String_member ) NodeService.ServiceName ) ;
712         ostringstream astr ;
713         astr << num << ends ;
714 //        const char * n_instance = astr.str().c_str() ;
715         int lname = strlen( NodeService.ServiceName ) + 1 +
716                     strlen( astr.str().c_str() ) + 1 ;
717         aNodeName = new char[lname] ;
718         strcpy( aNodeName , NodeService.ServiceName ) ;
719         strcat( aNodeName , "_" ) ;
720         strcat( aNodeName , astr.str().c_str() ) ;
721         GraphNodeSameName = !strcmp( Graph()->Name() , aNodeName ) ;
722       }
723     }
724   }
725   else {
726     if ( Graph()->GetGraphNode( theNodeName ) == NULL ) {
727       aNodeName = new char[ strlen( theNodeName )+1 ] ;
728       strcpy( aNodeName , theNodeName ) ;
729     }
730     else {
731       aNodeName = NULLSTRING ;
732     }
733   }
734   if ( aNodeName != NULLSTRING ) {
735     Nd = new GraphEditor::InNode( _Orb , Graph()->NamingService() ,
736                                   aFuncName , aPythonFunction , NodeService ,
737                                   NodeComponentName , NodeInterfaceName ,
738                                   aNodeName , NodeKindOfNode ,
739                                   NodeFirstCreation , NodeLastModification ,
740                                   NodeEditorRelease , NodeAuthor ,
741                                   NodeComputer , NodeComment , GeneratedName ,
742                                   NodeX , NodeY ,
743                                   _prof_debug , _fdebug ) ;
744     
745     // asv: 28.09.04 fix for 6621
746     //if ( Nd->IsMacroNode() )
747     //  MapGraph( Nd->GraphMacroNode(), aNodeName );
748
749     if ( Graph()->IsDataStreamNode() && ( Nd->IsComputingNode() || Nd->IsFactoryNode() ) ) {
750       unsigned int i ;
751       for ( i = 0 ; i < NodeService.ServiceinDataStreamParameter.length() ; i++ ) {
752         GraphBase::InDataStreamPort * aDataStreamPort ;
753         aDataStreamPort = Nd->ComputingNode()->AddInDataStreamPort(
754 //JR 17.02.2005 Memory Leak                                         my_strdup( NodeService.ServiceinDataStreamParameter[i].Parametername ) ,
755                                          NodeService.ServiceinDataStreamParameter[i].Parametername ,
756                                          NodeService.ServiceinDataStreamParameter[i].Parametertype ,
757                                          NodeService.ServiceinDataStreamParameter[i].Parameterdependency ,
758                                          SUPERV::DataStreamParameter ) ;
759       }
760       for ( i = 0 ; i < NodeService.ServiceoutDataStreamParameter.length() ; i++ ) {
761         GraphBase::OutDataStreamPort * aDataStreamPort ;
762         aDataStreamPort = Nd->ComputingNode()->AddOutDataStreamPort(
763 //JR 17.02.2005 Memory Leak                                         my_strdup( NodeService.ServiceoutDataStreamParameter[i].Parametername ) ,
764                                          NodeService.ServiceoutDataStreamParameter[i].Parametername ,
765                                          NodeService.ServiceoutDataStreamParameter[i].Parametertype ,
766                                          NodeService.ServiceoutDataStreamParameter[i].Parameterdependency ,
767                                          SUPERV::DataStreamParameter ) ;
768       }
769     }
770
771     if ( Graph()->AddNode( Nd->ComputingNode() ) ) {
772       DateModification() ;
773       RetVal = Nd->Name() ;
774     }
775     else {
776       cdebug << "NodeName already exists." << endl ;
777     }
778   }
779   else {
780     cdebug << "ERROR NodeName is NULL or already exists." << endl ;
781   }
782 //  delete [] aNodeName ;
783   _Valid = false ;
784   if ( Nd == NULL ) {
785     cdebug_out << "GraphEditor::OutNode::AddNode : NULL" << endl;
786   }
787   else {
788     cdebug_out << "GraphEditor::OutNode::AddNode : " << Nd << " " << Nd->Name() << endl;
789   }
790   return Nd ;
791 }
792
793 bool GraphEditor::OutNode::AddLinkCoord( const char* FromNodeName ,
794                                          const char* FromServiceParameterName ,
795                                          const char* ToNodeName ,
796                                          const char* ToServiceParameterName ,
797                                          const int nXY ,
798                                          const int* X ,
799                                          const int* Y ) {
800   GraphBase::InPort * anInPort = Graph()->GetChangeInPort( ToNodeName ,
801                                                            ToServiceParameterName ) ;
802 //  cdebug << "GraphEditor::OutNode::AddLinkCoord " << ToNodeName << "( " << ToServiceParameterName
803 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
804   if ( anInPort ) {
805     if ( anInPort->IsEndSwitch() ) {
806 //      cdebug << "GraphEditor::OutNode::AddLinkCoord " << FromNodeName << "( " << FromServiceParameterName
807 //             << " )" << endl ;
808       return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->AddCoord( nXY , X , Y ) ;
809     }
810     else {
811       return anInPort->AddCoord( nXY , X , Y ) ;
812     }
813   }
814   return false ;
815 }
816
817 bool GraphEditor::OutNode::AddLinkCoord( const char* FromNodeName ,
818                                          const char* FromServiceParameterName ,
819                                          const char* ToNodeName ,
820                                          const char* ToServiceParameterName ,
821                                          const int index ,
822                                          const int X ,
823                                          const int Y ) {
824   GraphBase::InPort * anInPort = Graph()->GetChangeInPort( ToNodeName ,
825                                                            ToServiceParameterName ) ;
826 //  cdebug << "GraphEditor::OutNode::AddLinkCoord " << ToNodeName << "( " << ToServiceParameterName
827 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
828   if ( anInPort ) {
829     if ( anInPort->IsEndSwitch() ) {
830 //      cdebug << "GraphEditor::OutNode::AddLinkCoord " << FromNodeName << "( " << FromServiceParameterName
831 //             << " )" << endl ;
832       return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->AddCoord( index , X , Y ) ;
833     }
834     else {
835       return anInPort->AddCoord( index , X , Y ) ;
836     }
837   }
838   return false ;
839 }
840
841 bool GraphEditor::OutNode::ChangeLinkCoord( const char* FromNodeName ,
842                                             const char* FromServiceParameterName ,
843                                             const char* ToNodeName ,
844                                             const char* ToServiceParameterName ,
845                                             const int index ,
846                                             const int X ,
847                                             const int Y ) {
848   GraphBase::InPort * anInPort = Graph()->GetChangeInPort( ToNodeName ,
849                                                            ToServiceParameterName ) ;
850 //  cdebug << "GraphEditor::OutNode::ChangeLinkCoord " << ToNodeName << "( " << ToServiceParameterName
851 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
852   if ( anInPort ) {
853     if ( anInPort->IsEndSwitch() ) {
854 //      cdebug << "GraphEditor::OutNode::ChangeLinkCoord " << FromNodeName << "( " << FromServiceParameterName
855 //             << " )" << endl ;
856       return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->ChangeCoord( index , X , Y ) ;
857     }
858     else {
859       return anInPort->ChangeCoord( index , X , Y ) ;
860     }
861   }
862   return false ;
863 }
864
865 bool GraphEditor::OutNode::RemoveLinkCoord( const char* FromNodeName ,
866                                             const char* FromServiceParameterName ,
867                                             const char* ToNodeName ,
868                                             const char* ToServiceParameterName ,
869                                             const int index ) {
870   GraphBase::InPort * anInPort = Graph()->GetChangeInPort( ToNodeName ,
871                                                            ToServiceParameterName ) ;
872 //  cdebug << "GraphEditor::OutNode::RemoveLinkCoord " << ToNodeName << "( " << ToServiceParameterName
873 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
874   if ( anInPort ) {
875     if ( anInPort->IsEndSwitch() ) {
876 //      cdebug << "GraphEditor::OutNode::RemoveLinkCoord " << FromNodeName << "( " << FromServiceParameterName
877 //             << " )" << endl ;
878       return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->RemoveCoord( index ) ;
879     }
880     else {
881       return anInPort->RemoveCoord( index ) ;
882     }
883   }
884   return false ;
885 }
886
887 int GraphEditor::OutNode::GetLinkCoordSize( const char* FromNodeName ,
888                                             const char* FromServiceParameterName ,
889                                             const char* ToNodeName ,
890                                             const char* ToServiceParameterName ) {
891   const GraphBase::InPort * anInPort = Graph()->GetInPort( ToNodeName , ToServiceParameterName ) ;
892 //  cdebug << "GraphEditor::OutNode::GetLinkCoordSize " << ToNodeName << "( " << ToServiceParameterName
893 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
894   if ( anInPort ) {
895     if ( anInPort->IsEndSwitch() ) {
896 //      cdebug << "GraphEditor::OutNode::GetLinkCoordSize " << FromNodeName << "( " << FromServiceParameterName
897 //             << " )" << endl ;
898       return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord() ;
899     }
900     else {
901       return anInPort->GetCoord() ;
902     }
903   }
904   return 0 ;
905 }
906
907 bool GraphEditor::OutNode::GetLinkCoord( const char* FromNodeName ,
908                                          const char* FromServiceParameterName ,
909                                          const char* ToNodeName ,
910                                          const char* ToServiceParameterName ,
911                                          int *X , int *Y ) {
912   const GraphBase::InPort * anInPort = Graph()->GetInPort( ToNodeName , ToServiceParameterName ) ;
913 //  cdebug << "GraphEditor::OutNode::GetLinkCoord " << ToNodeName << "( " << ToServiceParameterName
914 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
915   if ( anInPort ) {
916     if ( anInPort->IsEndSwitch() ) {
917 //      cdebug << "GraphEditor::OutNode::GetLinkCoord " << FromNodeName << "( " << FromServiceParameterName
918 //             << " )" << endl ;
919       return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord( X , Y ) ;
920     }
921     else {
922       return anInPort->GetCoord( X , Y ) ;
923     }
924   }
925   return false ;
926 }
927
928 bool GraphEditor::OutNode::GetLinkCoord( const char* FromNodeName ,
929                                          const char* FromServiceParameterName ,
930                                          const char* ToNodeName ,
931                                          const char* ToServiceParameterName ,
932                                          const int index , CORBA::Long &X , CORBA::Long &Y ) {
933   GraphBase::InPort * anInPort = Graph()->GetChangeInPort( ToNodeName ,
934                                                            ToServiceParameterName ) ;
935 //  cdebug << "GraphEditor::OutNode::GetLinkCoord " << ToNodeName << "( " << ToServiceParameterName
936 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
937   if ( anInPort ) {
938     if ( anInPort->IsEndSwitch() ) {
939 //      cdebug << "GraphEditor::OutNode::GetLinkCoord " << FromNodeName << "( " << FromServiceParameterName
940 //             << " )" << endl ;
941       return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord( index , X , Y ) ;
942     }
943     else {
944       return anInPort->GetCoord( index , X , Y ) ;
945     }
946   }
947   return false ;
948 }
949
950 bool GraphEditor::OutNode::UnValid() {
951   bool RetVal = _Valid ;
952   _Valid = false ;
953   if ( Graph()->GraphMacroLevel() != 0 ) {
954     cdebug << "GraphEditor::OutNode::UnValid() GraphMacroLevel " << Graph()->GraphMacroLevel() << endl ;
955     RetVal = Valid() ;
956   }
957   return RetVal ;
958 }
959
960 //JR Optional parameter kLoopSwitch (default = true) :
961 //In some cases we do not need to check the validity of loops and switchs
962 //JR 07.07.2005 PAL9342 : that code is now in Executable() method instead of Valid() method
963 //bool GraphEditor::OutNode::Valid(bool kLoopSwitch ) {
964 bool GraphEditor::OutNode::Valid() {
965   bool RetVal = true ;
966   cdebug_in << "GraphEditor::OutNode::Valid" << endl;
967 //  if ( _Valid )
968 //    return true ;
969
970   _Executable = false ;
971
972   if ( !Graph()->CreateService() ) {
973     cdebug << "GraphEditor::OutNode::Valid ERROR _Valid " << _Valid << endl;
974     RetVal = false ;
975   }
976   
977   if ( Graph()->GraphMacroLevel() != 0 ) {
978     cdebug << "CoupledNode " << Graph()->CoupledNode() << endl ;
979     cdebug << "GraphEditor " << Graph()->CoupledNode()->GraphEditor() << endl ;
980     cdebug << "Graph " << Graph()->CoupledNode()->GraphEditor()->Graph() << endl ;
981     cdebug << "Name " << Graph()->CoupledNode()->GraphEditor()->Graph()->Name() << endl ;
982     cdebug << "Valid --> UpdateMacroPorts of " << Graph()->CoupledNodeName() << " of "
983            << Graph()->CoupledNode()->GraphEditor()->Graph()->Name() << endl ;
984     cdebug << Graph()->CoupledNode() << endl ;
985     Graph()->CoupledNode()->UpdateMacroPorts( Graph() ) ;
986     cdebug << Graph()->CoupledNode()->Name() << " Valid --> UnValid of graph "
987            << Graph()->CoupledNode()->GraphEditor()->Graph()->Name()
988            << " GraphMacroLevel " << Graph()->CoupledNode()->GraphEditor()->Graph()->GraphMacroLevel()  << endl ;
989     Graph()->CoupledNode()->GraphEditor()->UnValid() ;
990   }
991
992   Graph()->InLineServices() ;
993
994 //JR 07.07.2005 PAL9342 : that code is now in Executable() method instead of Valid() method
995 #if 0
996   int SubStreamGraphsNumber = 0 ;
997   if ( !Graph()->Sort( SubStreamGraphsNumber ) ) {
998     cdebug_out << "This DataFlow is not valid." << endl ;
999     RetVal = false ;
1000   }
1001   if ( Graph()->IsDataStreamNode() ) {
1002     StreamGraph()->SubStreamGraphsNumber( SubStreamGraphsNumber ) ;
1003   }
1004
1005 //JR Debug 24.08.2005 : InLineServices is needed for Export ==> it is executed above
1006 //  Graph()->InLineServices() ;
1007
1008   if ( kLoopSwitch ) {
1009     if ( !Graph()->ValidLoops() ) {
1010       cdebug_out << "This DataFlow have not valid Loops." << endl ;
1011       RetVal = false ;
1012     }
1013     if ( !Graph()->ValidSwitchs() ) {
1014       cdebug_out << "This DataFlow have not valid Switchs." << endl ;
1015       RetVal = false ;
1016     }
1017   }
1018   
1019   Graph()->ComputingNodes() ;
1020 #endif
1021
1022   if ( !Graph()->ValidGOTO() ) { // mkr : PAL12575
1023     cdebug << "Editor::OutNode::Valid This DataFlow have not valid GOTO(ValidGOTO)." << endl ;
1024     RetVal = false ;
1025   }
1026
1027   if ( RetVal ) {
1028     _Valid = true ;
1029   }
1030
1031   cdebug_out << "GraphEditor::OutNode::Valid " << _Valid << " RetVal " << RetVal << endl;
1032   return RetVal ;
1033 }
1034
1035 bool GraphEditor::OutNode::Executable() {
1036   cdebug_in << "GraphEditor::OutNode::Executable" << endl;
1037   bool RetVal = true ;
1038   bool NewLink ;
1039 // LinkLoopNodes manage input values of LoopNodes and EndLoopNodes
1040   if ( Graph()->LinkLoopNodes( NewLink ) ) {
1041     if ( NewLink ) {
1042       _Valid = false ;
1043       RetVal = false ;
1044     }
1045   }
1046   else {
1047     cdebug << "Editor::OutNode::Executable This DataFlow is not executable(LinkLoopNodes)." << endl ;
1048     _Executable = false ;
1049     RetVal = false ;
1050   }
1051   if ( !IsValid() ) {
1052     Valid() ;
1053   }
1054   if ( !IsValid() ) {
1055     RetVal = false ;
1056   }
1057
1058 //JR 07.07.2005 PAL9342 : that code is now in Executable() method instead of Valid() method
1059   bool IsValid = true;
1060   int SubStreamGraphsNumber = 0 ;
1061   if ( !Graph()->Sort( SubStreamGraphsNumber ) ) {
1062     cdebug << "Editor::OutNode::Executable This DataFlow is not valid(Sort)." << endl ;
1063     RetVal = false ;
1064     //mkr : 28.09.2005 : if dataflow is not valid => it is not executable
1065     IsValid = false ;
1066   }
1067   if ( Graph()->IsDataStreamNode() )
1068     StreamGraph()->SubStreamGraphsNumber( SubStreamGraphsNumber ) ;
1069
1070   Graph()->InLineServices() ;
1071   
1072 //  if ( kLoopSwitch ) {
1073     if ( !Graph()->ValidLoops() ) {
1074       cdebug << "Editor::OutNode::Executable This DataFlow have not valid Loops(ValidLoops)." << endl ;
1075       RetVal = false ;
1076       //mkr : 28.09.2005 : if dataflow is not valid => it is not executable
1077       IsValid = false ;
1078     }
1079     if ( !Graph()->ValidSwitchs() ) {
1080       cdebug << "Editor::OutNode::Executable This DataFlow have not valid Switchs(ValidSwitchs)." << endl ;
1081       RetVal = false ;
1082       //mkr : 28.09.2005 : if dataflow is not valid => it is not executable
1083       IsValid = false ;
1084     }
1085 //  }
1086   
1087   Graph()->ComputingNodes() ;
1088
1089   if ( Graph()->DataServerNodes() )
1090     _Executable = true ;
1091   else {
1092     cdebug << "Editor::OutNode::Executable This DataFlow is not executable(DataServerNodes)." << endl ;
1093     _Executable = false ;
1094     RetVal = false ;
1095   }
1096
1097   if ( _Executable && Graph()->IsDataStreamNode() ) {
1098     StreamGraph()->CreateStreamTopology( "/tmp/" ) ;
1099   }
1100
1101   // asv : 13.12.04 : introducing check for compatibility of linked ports' types.
1102   if ( !IsLinksCompatible() ) {
1103     _Executable = false;
1104     RetVal = false ;
1105   }    
1106
1107   //mkr : 28.09.2005 : if dataflow is not valid => it is not executable
1108   if ( !IsValid ) _Executable = false ;
1109
1110   cdebug_out << "GraphEditor::OutNode::Executable _Executable " << _Executable << " RetVal " << RetVal
1111              << endl;
1112   return RetVal ;
1113 }
1114
1115 //JR 30.03.2005const CORBA::Any *GraphEditor::OutNode::GetInData(
1116 const CORBA::Any GraphEditor::OutNode::GetInData(
1117                               const char * ToNodeName ,
1118                               const char * ToParameterName ) {
1119 //  cdebug_in << "GraphEditor::OutNode::GetInData " << ToNodeName
1120 //            << " " << ToParameterName << endl ;
1121 //JR 30.03.2005  const CORBA::Any * retdata = Graph()->PortInData( ToNodeName , ToParameterName ) ;
1122   const CORBA::Any retdata = Graph()->PortInData( ToNodeName , ToParameterName ) ;
1123 //  cdebug_out << "GraphEditor::OutNode::GetInData" << endl ;
1124   return retdata ;
1125 }
1126
1127 //JR 30.03.2005const CORBA::Any *GraphEditor::OutNode::GetOutData(
1128 const CORBA::Any GraphEditor::OutNode::GetOutData(
1129                               const char * FromNodeName ,
1130                               const char * FromParameterName ) {
1131 //  cdebug_in << "GraphEditor::OutNode::GetOutData " << FromNodeName
1132 //            << " " << FromParameterName << endl ;
1133 //JR 30.03.2005  const CORBA::Any * retdata = Graph()->PortOutData( FromNodeName , FromParameterName ) ;
1134   const CORBA::Any retdata = Graph()->PortOutData( FromNodeName , FromParameterName ) ;
1135 //  cdebug_out << "GraphEditor::OutNode::GetOutData" << endl ;
1136   return retdata ;
1137 }
1138
1139 //bool GraphEditor::OutNode::LinkSaveXML( ostream &f , char *Tabs ,
1140 bool GraphEditor::OutNode::LinkSaveXML( QDomDocument & Graph , QDomElement & link ,
1141                                         GraphBase::SLink aLink ,
1142                                         bool wdata ) const {
1143   cdebug_in << "GraphEditor::OutNode::LinkSaveXML " << aLink.FromNodeName
1144             << "(" << aLink.FromServiceParameterName << ") --> "
1145             << aLink.ToNodeName << "(" << aLink.ToServiceParameterName << ")" << endl ;
1146   QDomElement fromnodename = Graph.createElement( "fromnode-name" ) ;
1147   QDomText aField ;
1148   if ( strlen( aLink.FromNodeName.c_str() ) ) {
1149 //    f << Tabs << "<fromnode-name>" << aLink.FromNodeName.c_str()
1150 //      << "</fromnode-name>" << endl ;
1151     aField = Graph.createTextNode( aLink.FromNodeName.c_str() ) ;
1152   }
1153   else {
1154 //    f << Tabs << "<fromnode-name>?</fromnode-name>" << endl ;
1155     aField = Graph.createTextNode( "?" ) ;
1156   }
1157   link.appendChild( fromnodename ) ;
1158   fromnodename.appendChild( aField ) ;
1159
1160 //  f << Tabs << "<fromserviceparameter-name>"
1161 //    << aLink.FromServiceParameterName.c_str() << "</fromserviceparameter-name>"
1162 //    << endl ;
1163   QDomElement fromserviceparametername = Graph.createElement( "fromserviceparameter-name" ) ;
1164   aField = Graph.createTextNode( aLink.FromServiceParameterName.c_str() ) ;
1165   link.appendChild( fromserviceparametername ) ;
1166   fromserviceparametername.appendChild( aField ) ;
1167
1168   QDomElement tonodename = Graph.createElement( "tonode-name" ) ;
1169   if ( strlen( aLink.ToNodeName.c_str() ) ) {
1170 //    f << Tabs << "<tonode-name>" << aLink.ToNodeName.c_str()
1171 //      << "</tonode-name>" << endl ;
1172     aField = Graph.createTextNode( aLink.ToNodeName.c_str() ) ;
1173   }
1174   else {
1175 //    f << Tabs << "<tonode-name>?</tonode-name>" << endl ;
1176     aField = Graph.createTextNode( "?" ) ;
1177   }
1178   link.appendChild( tonodename ) ;
1179   tonodename.appendChild( aField ) ;
1180
1181 //  f << Tabs << "<toserviceparameter-name>"
1182 //    << aLink.ToServiceParameterName.c_str() << "</toserviceparameter-name>"
1183 //    << endl ;
1184   QDomElement toserviceparametername = Graph.createElement( "toserviceparameter-name" ) ;
1185   aField = Graph.createTextNode( aLink.ToServiceParameterName.c_str() ) ;
1186   link.appendChild( toserviceparametername ) ;
1187   toserviceparametername.appendChild( aField ) ;
1188
1189   if ( wdata ) {
1190 //    f << Tabs << "<data-value>" << endl ;
1191     QDomElement datavalue = Graph.createElement( "data-value" ) ;
1192     link.appendChild( datavalue ) ;
1193 //    f << Tabs << "    <value-type>" << aLink.aLinkValue.type()->kind()
1194 //      << "</value-type>" << endl ;
1195     QDomElement valuetype = Graph.createElement( "value-type" ) ;
1196     QString aKind ;
1197     aKind = aKind.setNum( aLink.aLinkValue.type()->kind() ) ;
1198     aField = Graph.createTextNode( aKind ) ;
1199     datavalue.appendChild( valuetype ) ;
1200     valuetype.appendChild( aField ) ;
1201     switch (aLink.aLinkValue.type()->kind()) {
1202       case CORBA::tk_string: {
1203         const char* retstr ;
1204         aLink.aLinkValue >>= retstr;
1205 //        f << Tabs << "        <value>" << retstr << "</value>" << endl ;
1206         QDomElement value = Graph.createElement( "value" ) ;
1207 //PAL9133 Debug JR : accept void strings
1208         QDomCDATASection aCDATA ;
1209         int i ;
1210         for ( i = 0 ; i < (int ) strlen( retstr ) ; i++ ) {
1211           if ( retstr[ i ] != ' ' ) {
1212             break ;
1213           }
1214         }
1215         if ( i == (int ) strlen( retstr ) ) {
1216           aCDATA = Graph.createCDATASection( "?" ) ;
1217         }
1218         else {
1219           aCDATA = Graph.createCDATASection( retstr ) ;
1220         }
1221 //        aField = Graph.createTextNode( retstr ) ;
1222         datavalue.appendChild( value ) ;
1223 //        datavalue.appendChild( value ) ;
1224         value.appendChild( aCDATA ) ;
1225 //        MESSAGE( "ToString( string ) " << retstr );
1226         break ;
1227       }
1228       case CORBA::tk_double: {
1229         CORBA::Double d;
1230         aLink.aLinkValue >>= d;
1231 //        f << Tabs << "        <value>" << d << "</value>" << endl ;
1232         QDomElement value = Graph.createElement( "value" ) ;
1233         QString aKind ;
1234         aKind = aKind.setNum( d ) ;
1235         aField = Graph.createTextNode( aKind ) ;
1236         datavalue.appendChild( value ) ;
1237         value.appendChild( aField ) ;
1238 //        MESSAGE( "ToString( double ) " << d );
1239         break ;
1240       }
1241       case CORBA::tk_long: {
1242         CORBA::Long l;
1243         aLink.aLinkValue >>= l;
1244 //        f << Tabs << "        <value>" << l << "</value>" << endl ;
1245         QDomElement value = Graph.createElement( "value" ) ;
1246         QString aKind ;
1247         aKind = aKind.setNum( l ) ;
1248         aField = Graph.createTextNode( aKind ) ;
1249         datavalue.appendChild( value ) ;
1250         value.appendChild( aField ) ;
1251 //        MESSAGE( "ToString( CORBA::Long ) " << l );
1252         break ;
1253       }
1254       case CORBA::tk_objref: {
1255         char* retstr ;
1256         CORBA::Object_ptr obj ;
1257 #if OMNIORB_VERSION >= 4
1258         aLink.aLinkValue >>= (CORBA::Any::to_object)obj;
1259 #else
1260         aLink.aLinkValue >>= obj;
1261 #endif 
1262         retstr = _Orb->object_to_string(obj );
1263 //        f << Tabs << "        <value>" << retstr << "</value>" << endl ;
1264         QDomElement value = Graph.createElement( "value" ) ;
1265         aField = Graph.createTextNode( retstr ) ;
1266         datavalue.appendChild( value ) ;
1267         value.appendChild( aField ) ;
1268 //        MESSAGE( "ToString( object ) " << retstr );
1269         break ;
1270       }
1271       default: {
1272 //        f << Tabs << "        <value>?</value>" << endl ;
1273         QDomElement value = Graph.createElement( "value" ) ;
1274         aField = Graph.createTextNode( "?" ) ;
1275         datavalue.appendChild( value ) ;
1276         value.appendChild( aField ) ;
1277 //        MESSAGE( "Unknown CORBA::Any Type" );
1278         break ;
1279       }
1280     }
1281 //    f << Tabs << "</data-value>" << endl ;
1282   }
1283 //  f << Tabs << "<coord-list>" << endl ;
1284   QDomElement coordlist = Graph.createElement( "coord-list" ) ;
1285   link.appendChild( coordlist ) ;
1286   
1287   int i ;
1288   for ( i = 0 ; i < (int ) aLink.aListOfCoords.size() ; i++ ) {
1289 //    f << Tabs << "    <coord>" << endl ;
1290     QDomElement coord = Graph.createElement( "coord" ) ;
1291     coordlist.appendChild( coord ) ;
1292 //    f << Tabs << "            <x>" << aLink.aListOfCoords[ i ].theX << "</x>" << endl ;
1293     QDomElement x = Graph.createElement( "x" ) ;
1294     QString ax ;
1295     ax = ax.setNum( aLink.aListOfCoords[ i ].theX ) ;
1296     aField = Graph.createTextNode( ax ) ;
1297     coord.appendChild( x ) ;
1298     x.appendChild( aField ) ;    
1299 //    f << Tabs << "            <y>" << aLink.aListOfCoords[ i ].theY << "</y>" << endl ;
1300     QDomElement y = Graph.createElement( "y" ) ;
1301     QString ay ;
1302     ay = ay.setNum( aLink.aListOfCoords[ i ].theY ) ;
1303     aField = Graph.createTextNode( ay ) ;
1304     coord.appendChild( y ) ;
1305     y.appendChild( aField ) ;    
1306 //    f << Tabs << "    </coord>" << endl ;
1307   }
1308 //  f << Tabs << "</coord-list>" << endl ;
1309   cdebug_out << "GraphEditor::OutNode::LinkSaveXML " << aLink.FromNodeName
1310              << "(" << aLink.FromServiceParameterName << ") --> "
1311              << aLink.ToNodeName << "(" << aLink.ToServiceParameterName << ")"
1312              << endl ;
1313   return true ;
1314 }
1315
1316 bool GraphEditor::OutNode::LinkSavePY( ostream &f , const char * aGraphName ,
1317                                        GraphBase::SLink aLink ,
1318                                        bool fromparam , bool toparam ,
1319                                        bool wdata ) const {
1320   if ( !wdata ) {
1321 //    if ( intervar ) {
1322 //      f << "O" << aLink.FromNodeName.c_str() << aLink.FromServiceParameterName.c_str()
1323 //        << " = "
1324 //        << aLink.FromNodeName.c_str() << ".GetOutPort( '"
1325 //        << aLink.FromServiceParameterName.c_str()
1326 //        << "' )" << endl ;
1327 //    }
1328     f << "    " << "L" << aLink.FromNodeName.c_str() << aLink.FromServiceParameterName.c_str()
1329       << aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str() ;
1330     if ( ((GraphBase::Graph *) Graph())->GetChangeGraphNode( aLink.FromNodeName.c_str() )->GetChangeOutPort( aLink.FromServiceParameterName.c_str() )->IsDataStream() ) {
1331       f << " = " << aGraphName << ".StreamLink( " ;
1332     }
1333     else {
1334       f << " = " << aGraphName << ".Link( " ;
1335     }
1336 //    if ( !fromparam ) {
1337       f << "O" ;
1338 //    }
1339     f << aLink.FromNodeName.c_str() << aLink.FromServiceParameterName.c_str() << " , " ;
1340 //    if ( !toparam ) {
1341       f << "I" ;
1342 //    }
1343     f << aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str() << " )" << endl ;
1344   }
1345   else {
1346     f << "    " << "I"<< aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str()
1347 //      << " = " << aLink.ToNodeName.c_str() << ".Input( '"
1348 //      << aLink.ToServiceParameterName.c_str() << "' , " ;
1349       << ".Input( " ;
1350     switch (aLink.aLinkValue.type()->kind()) {
1351       case CORBA::tk_string: {
1352         const char* retstr ;
1353         aLink.aLinkValue >>= retstr;
1354         f << "'" << retstr << "'" ;
1355         break ;
1356       }
1357       case CORBA::tk_double: {
1358         CORBA::Double d;
1359         aLink.aLinkValue >>= d;
1360         f << d ;
1361         break ;
1362       }
1363       case CORBA::tk_long: {
1364         CORBA::Long l;
1365         aLink.aLinkValue >>= l;
1366         f << l ;
1367         break ;
1368       }
1369       case CORBA::tk_objref: {
1370         char* retstr ;
1371         CORBA::Object_ptr obj ;
1372 #if OMNIORB_VERSION >= 4
1373         aLink.aLinkValue >>= (CORBA::Any::to_object)obj;
1374 #else
1375         aLink.aLinkValue >>= obj;
1376 #endif 
1377         retstr = _Orb->object_to_string(obj );
1378         f << "'" << retstr << "'" ;
1379         break ;
1380       }
1381       default: {
1382         f << "?" ;
1383 //        MESSAGE( "Unknown CORBA::Any Type" );
1384         break ;
1385       }
1386     }
1387     f << " )" << endl ;
1388   }
1389   int i ;
1390   for ( i = 0 ; i < (int ) aLink.aListOfCoords.size() ; i++ ) {
1391     f << "    " << "L" << aLink.FromNodeName.c_str() << aLink.FromServiceParameterName.c_str()
1392       << aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str() << ".AddCoord( " << i+1 << " , "
1393       << aLink.aListOfCoords[ i ].theX << " , "
1394       << aLink.aListOfCoords[ i ].theY << " )" << endl ;
1395   }
1396   return true ;
1397 }
1398
1399 //bool GraphEditor::OutNode::SaveXML(ostream & f ) {
1400 bool GraphEditor::OutNode::SaveXML( ostream & f , QDomDocument & GraphQDom ,
1401                                     bool aSuperGraph , QDomElement & supergraph ) {
1402   cdebug_in << "OutNode::SaveXML( ostream & f , QDomDocument & , " << aSuperGraph << " , QDomElement & ) "
1403             << Graph()->Name() << endl ;
1404   int i ;
1405
1406   QDomElement dataflow ;
1407   if ( aSuperGraph ) {
1408     QString SuperGraph("SuperGraph") ;
1409     GraphQDom = QDomDocument(SuperGraph) ;
1410
1411     supergraph = GraphQDom.createElement( "supergraph" ) ;
1412     GraphQDom.appendChild( supergraph ) ;
1413
1414     dataflow = GraphQDom.createElement( "dataflow" ) ;
1415     supergraph.appendChild( dataflow ) ;
1416   }
1417   else {
1418 //    QString Dataflow("Dataflow") ;
1419 //    GraphQDom = QDomDocument(Dataflow) ;
1420
1421     dataflow = GraphQDom.createElement( "dataflow" ) ;
1422     supergraph.appendChild( dataflow ) ;
1423   }
1424
1425   QDomElement info = GraphQDom.createElement( "info-list" ) ;
1426   dataflow.appendChild( info ) ;
1427
1428   Graph()->SaveXML( GraphQDom , info , 0 , 0 ) ;
1429
1430   QDomElement nodelist = GraphQDom.createElement( "node-list" ) ;
1431   dataflow.appendChild( nodelist ) ;
1432   for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
1433 //      f << "          <node>" << endl ;
1434       if ( Graph()->GraphNodes( i )->IsComputingNode() ) {
1435 //        ((GraphBase::ComputingNode *)GraphNodes( i ))->SaveXML( f ,
1436 //                    "                 " ,
1437         ((GraphBase::ComputingNode *) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
1438                     Graph()->GraphNodes( i )->XCoordinate() ,
1439                     Graph()->GraphNodes( i )->YCoordinate() ) ;
1440       }
1441       else if ( Graph()->GraphNodes( i )->IsFactoryNode() ) {
1442 //        ((GraphBase::FactoryNode * ) GraphNodes( i ))->SaveXML( f ,
1443 //                    "                 " ,
1444         ((GraphBase::FactoryNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
1445                     Graph()->GraphNodes( i )->XCoordinate() ,
1446                     Graph()->GraphNodes( i )->YCoordinate() ) ;
1447       }
1448       else if ( Graph()->GraphNodes( i )->IsInLineNode()  ) {
1449 //        ((GraphBase::InLineNode * ) GraphNodes( i ))->SaveXML( f ,
1450 //                    "                 " ,
1451         ((GraphBase::InLineNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
1452                     Graph()->GraphNodes( i )->XCoordinate() ,
1453                     Graph()->GraphNodes( i )->YCoordinate() ) ;
1454       }
1455       else if ( Graph()->GraphNodes( i )->IsMacroNode() ) {
1456 //        ((GraphBase::InLineNode * ) GraphNodes( i ))->SaveXML( f ,
1457 //                    "                 " ,
1458         ((GraphBase::GOTONode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
1459                     Graph()->GraphNodes( i )->XCoordinate() ,
1460                     Graph()->GraphNodes( i )->YCoordinate() ) ;
1461       }
1462       else if ( Graph()->GraphNodes( i )->IsGOTONode() ) {
1463 //        ((GraphBase::GOTONode * ) GraphNodes( i ))->SaveXML( f ,
1464 //                    "                 " ,
1465         ((GraphBase::GOTONode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
1466                     Graph()->GraphNodes( i )->XCoordinate() ,
1467                     Graph()->GraphNodes( i )->YCoordinate() ) ;
1468       }
1469       else if ( Graph()->GraphNodes( i )->IsLoopNode() ) {
1470 //        ((GraphBase::LoopNode * ) GraphNodes( i ))->SaveXML( f ,
1471 //                    "                 " ,
1472         ((GraphBase::LoopNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
1473                     Graph()->GraphNodes( i )->XCoordinate() ,
1474                     Graph()->GraphNodes( i )->YCoordinate() ) ;
1475       }
1476       else if ( Graph()->GraphNodes( i )->IsEndLoopNode() ) {
1477 //        ((GraphBase::EndOfLoopNode * ) GraphNodes( i ))->SaveXML( f ,
1478 //                    "                 " ,
1479         ((GraphBase::EndOfLoopNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
1480                     Graph()->GraphNodes( i )->XCoordinate() ,
1481                     Graph()->GraphNodes( i )->YCoordinate() ) ;
1482       }
1483       else if ( Graph()->GraphNodes( i )->IsSwitchNode() ) {
1484 //        ((GraphBase::SwitchNode * ) GraphNodes( i ))->SaveXML( f ,
1485 //                    "                 " ,
1486         ((GraphBase::SwitchNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
1487                     Graph()->GraphNodes( i )->XCoordinate() ,
1488                     Graph()->GraphNodes( i )->YCoordinate() ) ;
1489       }
1490       else if ( Graph()->GraphNodes( i )->IsEndSwitchNode() ) {
1491 //        ((GraphBase::EndOfSwitchNode * ) GraphNodes( i ))->SaveXML( f ,
1492 //                    "                 " ,
1493         ((GraphBase::EndOfSwitchNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
1494                     Graph()->GraphNodes( i )->XCoordinate() ,
1495                     Graph()->GraphNodes( i )->YCoordinate() ) ;
1496       }
1497 //      f << "          </node>" << endl ;
1498 //    }
1499   }
1500 //  f << "      </node-list>" << endl << endl ;
1501
1502 //  f << "      <link-list>" << endl ;
1503   QDomElement linklist = GraphQDom.createElement( "link-list" ) ;
1504   dataflow.appendChild( linklist ) ;
1505   const GraphBase::ListOfSLinks * Links = Graph()->GetLinks( true ) ;
1506   for ( i = 0 ; i < (int ) Links->size() ; i++ ) {
1507 //    f << "            <link>" << endl ;
1508     QDomElement link = GraphQDom.createElement( "link" ) ;
1509     linklist.appendChild( link ) ;
1510 //    LinkSaveXML( f , "                        " , (*Links)[ i ] , false ) ;
1511     LinkSaveXML( GraphQDom , link , (*Links)[ i ] , false ) ;
1512 //    f << "            </link>" << endl ;
1513   }
1514 //  f << "      </link-list>" << endl << endl ;
1515
1516 //  f << "      <data-list>" << endl ;
1517   QDomElement datalist = GraphQDom.createElement( "data-list" ) ;
1518   dataflow.appendChild( datalist ) ;
1519   if ( Graph()->GraphMacroLevel() == 0 ) {
1520     const GraphBase::ListOfSLinks * Datas = Graph()->GetDatas() ;
1521     for ( i = 0 ; i < (int ) Datas->size() ; i++ ) {
1522 //    f << "            <data>" << endl ;
1523       QDomElement data = GraphQDom.createElement( "data" ) ;
1524       datalist.appendChild( data ) ;
1525 //    LinkSaveXML( f , "                        " , (*Datas)[ i ] , true ) ;
1526       LinkSaveXML( GraphQDom , data , (*Datas)[ i ] , true ) ;
1527 //    f << "            </data>" << endl ;
1528     }
1529   }
1530
1531   for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
1532     if ( Graph()->GraphNodes( i )->IsMacroNode() ) {
1533       GraphBase::GOTONode * aMacroNode = (GraphBase::GOTONode * ) Graph()->GraphNodes( i ) ;
1534       GraphBase::Graph * aMacroGraph = (GraphBase::Graph * ) aMacroNode->CoupledNode() ;
1535       cdebug << "OutNode::SaveXML ---> OutNode::SaveXML( ostream & f , QDomDocument & , false "
1536              << " , QDomElement & ) MacroGraph " << aMacroGraph->Name() << endl ;
1537       if ( !aMacroGraph->GraphEditor()->SaveXML( f , GraphQDom , false , supergraph ) ) {
1538         return false ;
1539       cdebug << "OutNode::SaveXML MacroGraph "<< aMacroGraph->Name() << " done" << endl ;
1540       }
1541     }
1542   }
1543
1544   cdebug_out << "OutNode::SaveXML( ostream & f , QDomDocument & , " << aSuperGraph << " , QDomElement & ) "
1545              << Graph()->Name() << endl ;
1546
1547   return true ;
1548 }
1549
1550 bool GraphEditor::OutNode::SavePY( ostream & f , bool importSuperV ) {
1551   int i ;
1552   int j ;
1553   const GraphBase::ListOfSLinks * Links ;
1554   if ( importSuperV ) {
1555     f << endl << "# Generated python file of Graph " << Graph()->Name() << endl << endl ;
1556
1557     f << "from SuperV import *" << endl << endl ;
1558   }
1559
1560   f << "# Graph creation of " << Graph()->Name() << endl ;
1561   f << "def Def" << Graph()->Name() << "() :" << endl ;
1562   Graph()->SavePY( f , Graph()->Name() , 0 , 0 ) ;
1563
1564   f << "    " << endl << "    " << "# Creation of Factory Nodes" << endl ;
1565   for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
1566     if ( Graph()->GraphNodes( i )->IsFactoryNode() ) {
1567       f << "    " << endl ;
1568       ((GraphBase::FactoryNode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
1569                                                                       Graph()->GraphNodes( i )->XCoordinate() ,
1570                                                                       Graph()->GraphNodes( i )->YCoordinate() ) ;
1571     }
1572   }
1573
1574   bool first = true ;
1575   for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
1576     if ( Graph()->GraphNodes( i )->IsComputingNode() ) {
1577       if ( first ) {
1578         f << "    " << endl << "    " << "# Creation of Computing Nodes" << endl ;
1579         first = false ;
1580       }
1581       else {
1582         f << "    " << endl ;
1583       }
1584       ((GraphBase::ComputingNode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
1585                                                                         Graph()->GraphNodes( i )->XCoordinate() ,
1586                                                                         Graph()->GraphNodes( i )->YCoordinate() ) ;
1587     }
1588   }
1589
1590   first = true ;
1591   for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
1592     if ( Graph()->GraphNodes( i )->IsInLineNode() ) {
1593       if ( first ) {
1594         f << "    " << endl << "    " << "# Creation of InLine Nodes" << endl ;
1595         first = false ;
1596       }
1597       else {
1598         f << "    " << endl ;
1599       }
1600       ((GraphBase::InLineNode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
1601                                                                      Graph()->GraphNodes( i )->XCoordinate() ,
1602                                                                      Graph()->GraphNodes( i )->YCoordinate() ) ;
1603     }
1604   }
1605
1606   first = true ;
1607   for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
1608     if ( Graph()->GraphNodes( i )->IsLoopNode() ) {
1609       if ( first ) {
1610         f << "    " << endl << "    " << "# Creation of Loop Nodes" << endl ;
1611         first = false ;
1612       }
1613       else {
1614         f << "    " << endl ;
1615       }
1616       ((GraphBase::LoopNode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
1617                                                                    Graph()->GraphNodes( i )->XCoordinate() ,
1618                                                                    Graph()->GraphNodes( i )->YCoordinate() ) ;
1619     }
1620   }
1621
1622   first = true ;
1623   for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
1624     if ( Graph()->GraphNodes( i )->IsSwitchNode() ) {
1625       if ( first ) {
1626         f << "    " << endl << "    " << "# Creation of Switch Nodes" << endl ;
1627         first = false ;
1628       }
1629       else {
1630         f << "    " << endl ;
1631       }
1632       ((GraphBase::SwitchNode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
1633                                                                      Graph()->GraphNodes( i )->XCoordinate() ,
1634                                                                      Graph()->GraphNodes( i )->YCoordinate() ) ;
1635     }
1636   }
1637
1638   first = true ;
1639   for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
1640     if ( Graph()->GraphNodes( i )->IsGOTONode() ) {
1641       if ( first ) {
1642         f << "    " << endl << "    " << "# Creation of GOTO Nodes" << endl ;
1643         first = false ;
1644       }
1645       else {
1646         f << "    " << endl ;
1647       }
1648       ((GraphBase::GOTONode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
1649                                                                    Graph()->GraphNodes( i )->XCoordinate() ,
1650                                                                    Graph()->GraphNodes( i )->YCoordinate() ) ;
1651     }
1652   }
1653
1654   first = true ;
1655   for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
1656     if ( Graph()->GraphNodes( i )->IsMacroNode() ) {
1657       if ( first ) {
1658         f << "    " << endl << "    " << "# Creation of Macro Nodes" << endl ;
1659         first = false ;
1660       }
1661       else {
1662         f << "    " << endl ;
1663       }
1664       ((GraphBase::GOTONode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
1665                                                                    Graph()->GraphNodes( i )->XCoordinate() ,
1666                                                                    Graph()->GraphNodes( i )->YCoordinate() ) ;
1667     }
1668   }
1669
1670   Links = Graph()->GetLinks() ;
1671 //  bool intervar ;
1672 //  map< string , int > aMapOfOutPorts ;
1673   first = true ;
1674   for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
1675     for ( j = 0 ; j < (int ) Links->size() ; j++ ) {
1676       if ( !strcmp( Graph()->GraphNodes( i )->Name() , (*Links)[ j ].FromNodeName.c_str() ) ) {
1677         if ( first ) {
1678           f << "    " << endl
1679             << "    " << "# Creation of Links"
1680             << endl ;
1681           first = false ;
1682         }
1683         else {
1684           f << "    " << endl ;
1685         }
1686 //        char * NodePort = new char [ strlen( (*Links)[ j ].FromNodeName.c_str() ) +
1687 //                                     strlen( (*Links)[ j ].FromServiceParameterName.c_str() ) + 1 ] ;
1688 //        strcpy( NodePort , (*Links)[ j ].FromNodeName.c_str() ) ;
1689 //        strcat( NodePort , (*Links)[ j ].FromServiceParameterName.c_str() ) ;
1690 //        if ( aMapOfOutPorts[ NodePort ] == 0 ) {
1691 //          aMapOfOutPorts[ NodePort ] = j + 1 ;
1692 //          intervar = true ;
1693 //        }
1694 //        else {
1695 //          intervar = false ;
1696 //        }
1697         bool fromparam = false ;
1698         if ( Graph()->GraphNodes( i )->GetOutPort( (*Links)[ j ].FromServiceParameterName.c_str() )->IsParam() ) {
1699           fromparam = true ;
1700         }
1701         bool toparam = false ;
1702         if ( Graph()->GetChangeGraphNode( (*Links)[ j ].ToNodeName.c_str() )->GetInPort( (*Links)[ j ].ToServiceParameterName.c_str() )->IsParam() ) {
1703           toparam = true ;
1704         }
1705         LinkSavePY( f , Graph()->Name() , (*Links)[ j ] , fromparam , toparam , false ) ;
1706 //        delete [] NodePort ;
1707       }
1708     }
1709   }
1710
1711   if ( Graph()->GraphMacroLevel() == 0 ) {
1712     const GraphBase::ListOfSLinks * Datas = Graph()->GetDatas() ;
1713     first = true ;
1714     for ( i = 0 ; i < (int ) Datas->size() ; i++ ) {
1715       if ( first ) {
1716         f << "    " << endl << "    " << "# Input datas" << endl ;
1717         first = false ;
1718       }
1719       bool fromparam = true ;
1720       bool toparam = true ;
1721       LinkSavePY( f , Graph()->Name() , (*Datas)[ i ] , fromparam , toparam , true ) ;
1722     }
1723   }
1724
1725   first = true ;
1726   const SALOME_ModuleCatalog::ListOfServicesParameter ListOfInParam = Graph()->ServiceInParameter() ;
1727   for ( i = 0 ; i < (int ) ListOfInParam.length() ; i++ ) {
1728     string _aParam = CORBA::string_dup(ListOfInParam[ i ].Parametername) ;
1729     const char * aParam = _aParam.c_str() ;
1730     char * aNodeName ;
1731     char * aPortName ;
1732     int j ;
1733     for ( j = 0 ; j < (int ) strlen( aParam ) ; j++ ) {
1734 //      if ( aParam[ j ] == '\\' ) {
1735       if ( aParam[ j ] == '_' && aParam[ j+1 ] == '_' ) {
1736         aNodeName = new char[ j+1 ] ;
1737         strncpy( aNodeName , aParam , j ) ;
1738         aNodeName[ j ] = '\0' ;
1739         aPortName = new char[ strlen( aParam ) - j-1 ] ;
1740         strncpy( aPortName , &aParam[ j+2 ] , strlen( aParam ) - j-1 ) ;
1741         break ;
1742       }
1743     }
1744     const GraphBase::InPort * anInPort = Graph()->GetChangeGraphNode( aNodeName )->GetInPort( aPortName ) ;
1745     if ( !anInPort->IsDataConnected() ) {
1746       if ( first ) {
1747         f << "    " << endl << "    " << "# Input Ports of the graph" << endl ;
1748         first = false ;
1749       }
1750       f << "    " << "#I" << aNodeName << aPortName << " = " << aNodeName << ".GetInPort( '"
1751         << aPortName << "' )" << endl ;
1752     }
1753     delete [] aNodeName ;
1754     delete [] aPortName ;
1755   }
1756
1757   f << "    " << endl << "    # Output Ports of the graph" << endl ;
1758   const SALOME_ModuleCatalog::ListOfServicesParameter ListOfOutParam = Graph()->ServiceOutParameter() ;
1759   for ( i = 0 ; i < (int ) ListOfOutParam.length() ; i++ ) {
1760     string _aParam = CORBA::string_dup(ListOfOutParam[ i ].Parametername) ;
1761     const char * aParam = _aParam.c_str() ;
1762     char * aNodeName ;
1763     char * aPortName ;
1764     int j ;
1765     for ( j = 0 ; j < (int ) strlen( aParam ) ; j++ ) {
1766 //      if ( aParam[ j ] == '\\' ) {
1767       if ( aParam[ j ] == '_' && aParam[ j+1 ] == '_' ) {
1768         aNodeName = new char[ j+1 ] ;
1769         strncpy( aNodeName , aParam , j ) ;
1770         aNodeName[ j ] = '\0' ;
1771         aPortName = new char[ strlen( aParam ) - j-1 ] ;
1772         strncpy( aPortName , &aParam[ j+2 ] , strlen( aParam ) - j-1 ) ;
1773         break ;
1774       }
1775     }
1776     f << "    " << "#O" << aNodeName << aPortName << " = " << aNodeName << ".GetOutPort( '"
1777       << aPortName << "' )" << endl ;
1778     delete [] aNodeName ;
1779     delete [] aPortName ;
1780   }
1781
1782   f << "    " << "return " << Graph()->Name() << endl << endl ;
1783
1784 // RECURSIVE CREATION OF GRAPHS OF MACRONODES
1785   for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
1786     if ( Graph()->GraphNodes( i )->IsMacroNode() ) {
1787       GraphBase::GOTONode * aMacroNode = (GraphBase::GOTONode * ) Graph()->GraphNodes( i ) ;
1788       GraphBase::Graph * aMacroGraph = (GraphBase::Graph * ) aMacroNode->CoupledNode() ;
1789       cdebug << "OutNode::SavePY ---> OutNode::SavePY( ostream & f ) MacroGraph " << aMacroGraph->Name() << endl ;
1790       GraphEditor::DataFlow * aDataFlow = aMacroGraph->GraphEditor() ;
1791       cdebug << "SavePY of the Graph " << aDataFlow->Graph() << " of the MacroNode "
1792              << aMacroGraph->Name() << endl ;
1793       if ( !aDataFlow->SavePY( f , false ) ) {
1794         return false ;
1795       }
1796     }
1797   }
1798
1799 //  f << Graph()->Name() << " = " << Graph()->Name() << "()" << endl ;
1800
1801   return true ;
1802 }
1803
1804 /** Iterate through ALL links (OutPort-InPort pairs) and check if their types are 
1805  *  compatible - call GraphEditor::DataFlow::IsCompatible(type1, type2).
1806  *  Returns true if all are compatible.
1807  */
1808 bool GraphEditor::OutNode::IsLinksCompatible() {
1809   cdebug_in << "Editor::OutNode::IsLinksCompatible()" << endl ;
1810   bool RetVal = true;
1811   bool b ;
1812   const GraphBase::ListOfSLinks * Links = Graph()->GetLinks( true ) ;
1813   cdebug_in << "Editor::OutNode::IsLinksCompatible() " << Links->size() << " Links" << endl ;
1814 //  for ( int i = 0 ; i < (int ) Links->size() && b ; i++ ) {
1815   for ( int i = 0 ; i < (int ) Links->size() ; i++ ) {
1816     GraphBase::SLink aLink = (*Links)[i];
1817     GraphBase::ComputingNode* anOutNode = Graph()->GetChangeGraphNode( aLink.FromNodeName.c_str() );
1818     GraphBase::ComputingNode* anInNode = Graph()->GetChangeGraphNode( aLink.ToNodeName.c_str() );
1819     const GraphBase::OutPort* anOutPort = anOutNode->GetOutPort( aLink.FromServiceParameterName.c_str() );
1820     const GraphBase::InPort* anInPort = anInNode->GetInPort( aLink.ToServiceParameterName.c_str() );    
1821     b = IsCompatible( anOutPort->PortType(), anInPort->PortType() );
1822     cdebug << "GraphEditor::OutNode::IsLinksCompatible:  " << aLink.FromNodeName << "( "
1823            << aLink.FromServiceParameterName << " " << anOutPort->PortType()
1824            << " )  -->  " << aLink.ToNodeName <<"( " << aLink.ToServiceParameterName << " "
1825            << anInPort->PortType() << " ) = " << (b ? "OK" : "Not compatible (ERROR)") << endl;
1826     if ( !b ) {
1827       RetVal = false ;
1828       MESSAGE( "Graph structure ERROR: type of port \"" << aLink.FromServiceParameterName
1829                << "\" of node \"" << aLink.FromNodeName
1830                << "\" is not compatible with type of linked port \""
1831                << aLink.ToServiceParameterName << "\" of node \"" << aLink.ToNodeName<<"\"" ) ; 
1832       ostringstream aTypeOutPortstr ;
1833       aTypeOutPortstr << anOutPort->PortType() ;
1834       ostringstream aTypeInPortstr ;
1835       aTypeInPortstr << anInPort->PortType() ;
1836       string anErrorMessage = string( "PortTypes of " ) + string( aLink.FromNodeName ) +
1837                               string( "( " ) + aLink.FromServiceParameterName +
1838                               string( " ) " ) + aTypeOutPortstr.str() + string( " and " ) +
1839                               string( aLink.ToNodeName ) + string( "( " ) +
1840                               string( aLink.ToServiceParameterName ) + 
1841                               string( " ) " ) + aTypeInPortstr.str() +
1842                               string( " are not compatibles.\n" ) ;
1843       Graph()->SetMessages( anErrorMessage ) ;
1844     }
1845   }
1846   cdebug_out << "Editor::OutNode::IsLinksCompatible() RetVal " << RetVal << endl ;
1847   return RetVal ;
1848 }
1849
1850 static const char* gSimpleTypes[] = 
1851   {"boolean", "char", "short", "int", "long", "float", "double"};
1852 bool isSimpleType( string type ) {
1853   for ( int i = 0; i < 7; i++ )
1854     if ( type == gSimpleTypes[i] )
1855       return true;
1856   return false;
1857 }
1858
1859 /**Returns true if an out-port of type "OutPortType" can be bound with in-port of type "InPortType". 
1860  * Types: {"string", "boolean", "char", "short", "int", "long", "float", "double", "objref"};
1861  * Currently considered compatible ALL types except for objref - they must match exactly
1862  */
1863 bool GraphEditor::OutNode::IsCompatible( const char* OutPortType, const char* InPortType ) const {
1864   bool ret = true;
1865   string t1 = OutPortType;
1866   string t2 = InPortType;
1867   // if ANY is a string - the link is OK
1868   if ( t1 == "string" || t2 == "string" )
1869     ret = true;
1870
1871   // the next check prohibits linkage of "objref" to any simple type (int, char, etc.)
1872   // it is still possible to link "objref" to some UNKNOWN type (probably objref, too,
1873   // which interface name came from Cataloge
1874   else if ( ( t1 == "objref" && isSimpleType( t2 ) ) ||  
1875             ( t2 == "objref" && isSimpleType( t1 ) ) )
1876     ret = false; 
1877   return ret;
1878 }
1879
1880 ostream & operator<< (ostream & f,const GraphEditor::OutNode & G) {
1881   f << (GraphBase::ComputingNode ) *(G.Graph()) ;
1882   f << endl ;
1883
1884   f << "  Nodes : " << (G.Graph())->GraphNodesSize() << " node" 
1885     << ((G.Graph())->GraphNodesSize() > 1 ? "s" : "") << endl;
1886   
1887   int i ;
1888   for ( i = 0 ; i < (G.Graph())->GraphNodesSize() ; i++ ) {
1889     f
1890 //      << hex << (void *) G.Graph().GraphNodes( i ) << dec << " "
1891       << (G.Graph())->GraphNodes( i ) << endl;
1892   }
1893
1894   f << "  Links : " << endl ;
1895   for ( i = 0 ; i < (G.Graph())->GraphNodesSize() ; i++ ) {
1896     (G.Graph())->GraphNodes( i )->ListLinks( f ) ;
1897   }
1898
1899   f << "  Datas : " << endl ;
1900   (G.Graph())->ListDatas( f ) ;
1901
1902   f << "DataFlow " << (G.Graph())->Name() << " is " ;
1903   if ( G.IsNotValid() )
1904     f << "not " ;
1905   f << "valid and is " ;
1906   if ( G.IsNotExecutable() )
1907     f << "not " ;
1908   f << "executable." << endl ;
1909
1910   f << endl ;
1911   
1912   return f;
1913 }
1914
1915 ostream & operator<< (ostream &fOut,const SUPERV::SDate &D)
1916 {
1917 //  cdebug_in << "operator<< GraphEditor::Date" << endl;
1918
1919   fOut  << D.Day << "/" 
1920         << D.Month << "/" 
1921         << D.Year << " - " 
1922         << D.Hour << ":" 
1923         << D.Minute <<  ":"  
1924         << D.Second;
1925
1926 //  cdebug_out << "operator<< GraphEditor::Date" << endl;
1927   return fOut;
1928 }
1929
1930 /*
1931 GraphBase::Graph * GraphEditor::OutNode::MapGraph( const char * aGraphName ) {
1932   GraphBase::Graph * aGraph = _MapOfGraphs[ aGraphName ] ;
1933   return aGraph ;
1934 }
1935
1936 bool GraphEditor::OutNode::MapGraph( GraphBase::Graph * aGraph , const char * aGraphName ) {
1937   if ( MapGraph( aGraphName ) ) {
1938     return false ;
1939   }
1940   _MapOfGraphs[ aGraphName ] = aGraph ;
1941   return true ;
1942 }
1943
1944 void GraphEditor::OutNode::EraseGraph( const char * aGraphName ) {
1945   _MapOfGraphs.erase( aGraphName ) ;
1946 }
1947
1948 bool GraphEditor::OutNode::GraphName( const char * aGraphName ) {
1949   return  _MapOfGraphNames[ aGraphName ] ;
1950 }
1951 */
1952
1953