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