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