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