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