Salome HOME
sources v1.2
[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 "DataFlowEditor_OutNode.hxx"
29 #include "DataFlowBase_EndOfLoopNode.hxx"
30 #include "DataFlowBase_EndOfSwitchNode.hxx"
31
32 // Implementation de la classe GraphEditor::Graph
33
34 GraphEditor::OutNode::OutNode() :
35              Graph() {
36   cdebug_in << "GraphEditor::OutNode::OutNode()" << endl;
37
38   _Imported = false ;
39   _Valid = false ;
40   _Executable = false ;
41
42   cdebug_out << "GraphEditor::OutNode::OutNode()" << endl;
43 }
44
45 GraphEditor::OutNode::OutNode( CORBA::ORB_ptr ORB ,
46                                SALOME_NamingService* ptrNamingService ,
47                                const char *DataFlowName ,
48                                const char * DebugFileName ) :
49              Graph( ORB , ptrNamingService , DataFlowName , DebugFileName ) {
50   cdebug_in << "GraphEditor::OutNode::OutNode(" ;
51   if ( DataFlowName ) {
52     cdebug << DataFlowName ;
53   }
54   cdebug << ")" << endl;
55
56   _Orb = CORBA::ORB::_duplicate( ORB ) ;
57   _Imported = false ;
58   _Valid = false ;
59   _Executable = false ;
60
61   cdebug_out << "GraphEditor::OutNode::OutNode" << endl;
62 }
63
64 GraphEditor::OutNode::OutNode(
65                      CORBA::ORB_ptr ORB ,
66                      SALOME_NamingService* ptrNamingService ,
67                      const SALOME_ModuleCatalog::Service& DataFlowService ,
68                      const char *DataFlowComponentName ,
69                      const char *DataFlowInterfaceName ,
70                      const char *DataFlowName ,
71                      const SUPERV::KindOfNode DataFlowkind ,
72                      const SUPERV::SDate DataFlowFirstCreation ,
73                      const SUPERV::SDate DataFlowLastModification ,
74                      const char * DataFlowEditorRelease ,
75                      const char * DataFlowAuthor ,
76                      const char * DataFlowComputer ,
77                      const char * DataFlowComment ,
78                      const char * DebugFileName ) :
79              Graph( ORB , ptrNamingService , DataFlowService , DataFlowComponentName ,
80                     DataFlowInterfaceName , DataFlowName , DataFlowkind ,
81                     DataFlowFirstCreation , DataFlowLastModification  ,
82                     DataFlowEditorRelease , DataFlowAuthor ,
83                     DataFlowComputer , DataFlowComment , DebugFileName ) {
84
85   _Orb = CORBA::ORB::_duplicate( ORB ) ;
86   _Imported = false ;
87   _Valid = false ;
88   _Executable = false ;
89
90 } ;
91
92 GraphEditor::OutNode::~OutNode() {
93 //  delete _DataFlowNode ;
94 //  delete _DataFlowDatas ;
95 //  delete _GT ;
96 }
97
98 bool GraphEditor::OutNode::LoadDataFlow(
99                          const GraphBase::SGraph *aDataFlow ) {
100   bool RetVal = false ;
101   cdebug_in << "GraphEditor::OutNode::LoadDataFlow() " << aDataFlow->Info.theName.c_str()
102             << endl;
103 //  if ( GraphBase::Service::ServiceName() == NULL ||
104 //       !strlen( GraphBase::Service::ServiceName() ) || !aConstructor ) {
105   if ( !_Imported ) {
106     RetVal = LoadInfo( aDataFlow->Info ) ;
107     _Imported = true ;
108   }
109   else
110     RetVal = true ;
111
112     map< string , int > aMapOfNodes ;
113     if ( RetVal )
114       RetVal = LoadNodes( aMapOfNodes , aDataFlow->Nodes ) ;
115     if ( RetVal )
116       RetVal = LoadLinks( aMapOfNodes , aDataFlow->Links ) ;
117     if ( RetVal ) {
118       Valid() ;
119       RetVal = LoadDatas( aMapOfNodes , aDataFlow->Datas ) ;
120     }
121 //  }
122 //  else {
123 //    cdebug << "GraphEditor::OutNode::LoadDataFlow Error. ServiceName : "
124 //            << (void *) GraphBase::Service::ServiceName() << " '" 
125 //           << GraphBase::Service::ServiceName() << "'" << endl ;
126 //  }
127   cdebug_out << "GraphEditor::OutNode::LoadDataFlow" << endl;
128   return RetVal ;
129 }
130
131 bool GraphEditor::OutNode::LoadXml( const char* myFileName ) {
132   bool RetVal = false ;
133   GraphBase::SGraph aDataFlow ;
134   cdebug_in << "GraphEditor::OutNode::LoadXml() " << endl;
135   if ( myFileName == NULL ) {
136     _Imported = true ;
137     RetVal = true ;
138   }
139   else if ( GraphBase::Graph::LoadXml( _Orb , myFileName , aDataFlow ) ) {
140     RetVal = LoadDataFlow( &aDataFlow ) ;
141 //    if ( RetVal )
142 //      RetVal = Name( aDataFlow.Info.theName.c_str() ) ;
143   }
144   cdebug_out << "GraphEditor::OutNode::LoadXml" << endl;
145   return RetVal ;
146
147
148 bool GraphEditor::OutNode::LoadInfo(const GraphBase::SNode &aDataFlowInfo ) {
149   cdebug_in << "GraphEditor::OutNode::LoadInfo " << aDataFlowInfo.theName.c_str()
150             << endl ;
151 //  MESSAGE( "GraphEditor::OutNode::LoadDataFlow" );
152 //  ComponentName( aDataFlowInfo.theComponentName.c_str() ) ;
153 //  InterfaceName( aDataFlowInfo.theInterfaceName.c_str() ) ;
154   Name( aDataFlowInfo.theName.c_str() ) ;
155   Kind( aDataFlowInfo.theKind ) ;
156   Service( aDataFlowInfo.theService ) ;
157   FirstCreation( aDataFlowInfo.theFirstCreation ) ;
158   LastModification( aDataFlowInfo.theLastModification ) ;
159   EditorRelease( aDataFlowInfo.theEditorRelease.c_str() ) ;
160   Author( aDataFlowInfo.theAuthor.c_str()  ) ;
161 //  Computer( aDataFlowInfo.theContainer.c_str() ) ;
162   Comment( aDataFlowInfo.theComment.c_str() ) ;
163 // Not in OutNode/DataFlow but in InNode/DataFlow_in_an_other_DataFlow
164 //  Coordinates( aDataFlowInfo.theX , aDataFlowInfo.theY ) ;
165   cdebug_out << "GraphEditor::OutNode::LoadInfo" << endl ;
166   return true ;
167 }
168
169 bool GraphEditor::OutNode::LoadNodes(map< string , int > & aMapOfNodes ,
170                                      const GraphBase::ListOfNodes &aListOfNodes ) {
171   GraphEditor::InNode * anInNode ;
172   cdebug_in << "GraphEditor::OutNode::LoadNodes" << endl ;
173   int i ;
174   for ( i = 0 ; i < aListOfNodes.size() ; i++ ) {
175     GraphBase::SNode aNode = aListOfNodes[ i ] ;
176 //    if ( aConstructor ) {
177 //      anInNode = AddNode( aNode.theService , aNode.theComponentName.c_str() ,
178 //                        aNode.theInterfaceName.c_str() ,
179 //                        aNode.theName.c_str() ,
180 //                        aNode.theKind ,
181 //                        aNode.theFirstCreation , aNode.theLastModification ,
182 //                        aNode.theEditorRelease.c_str() ,
183 //                        aNode.theAuthor.c_str() , aNode.theContainer.c_str() ,
184 //                        aNode.theComment.c_str() ,
185 //                        aNode.theCoords.theX , aNode.theCoords.theY ) ;
186 //    }
187 //    else {
188       const char * aNodeName = aNode.theName.c_str() ;
189       if ( aNode.theListOfFuncName.size() == 0 ) {
190         aNode.theListOfFuncName.resize( 1 ) ;
191         aNode.theListOfFuncName[ 0 ] = "" ;
192         aNode.theListOfPythonFunctions.resize( 1 ) ;
193         aNode.theListOfPythonFunctions[ 0 ] = new SUPERV::ListOfStrings() ;
194       }
195       if ( GetGraphNode( aNode.theName.c_str() ) )
196         aNodeName = NULL ;
197       anInNode = AddNode( aNode.theService ,
198                           aNode.theListOfFuncName ,
199                           aNode.theListOfPythonFunctions ,
200                           aNode.theComponentName.c_str() ,
201                           aNode.theInterfaceName.c_str() , aNodeName ,
202                           aNode.theKind ,
203                           aNode.theFirstCreation , aNode.theLastModification ,
204                           aNode.theEditorRelease.c_str() ,
205                           aNode.theAuthor.c_str() , aNode.theContainer.c_str() ,
206                           aNode.theComment.c_str() ,
207                           aNode.theCoords.theX , aNode.theCoords.theY ) ;
208       string * aNodetheName = new string( aNode.theName ) ;
209       aMapOfNodes[ *aNodetheName ] = GetGraphNodeIndex( anInNode->Name() ) ;
210       if ( anInNode->IsOneOfInLineNodes() ) {
211         anInNode->GraphEditor::InNode::InLineNode()->DefPortsOfNode(
212                   _Orb , aNode.theService , anInNode->NamePtr() ,
213                   anInNode->Kind() ,
214 //                  false , // DataFlowOrComputing
215 //                  anInNode->IsLoopNode() || anInNode->IsEndLoopNode() , // WithInLoop
216 //                  anInNode->IsInLineNode() || anInNode->IsLoopNode() || anInNode->IsSwitchNode() || anInNode->IsEndSwitchNode() , // WithInGate
217 //                  anInNode->IsInLineNode() || anInNode->IsSwitchNode() || anInNode->IsGOTONode() , // WithOutGate
218                   Graph_prof_debug() , Graph_fdebug() ) ;
219         GraphBase::InLineNode * aINode = anInNode->InLineNode() ;
220         GraphBase::LoopNode * aLNode = NULL ;
221         if ( aINode->IsLoopNode() ) {
222           aLNode = anInNode->LoopNode() ;
223           aLNode->SetPythonFunction( aNode.theListOfFuncName[ 0 ].c_str() ,
224                                      *aNode.theListOfPythonFunctions[ 0 ] ) ;
225           aLNode->SetMorePythonFunction( aNode.theListOfFuncName[ 1 ].c_str() ,
226                                          *aNode.theListOfPythonFunctions[ 1 ] ) ;
227           aLNode->SetNextPythonFunction( aNode.theListOfFuncName[ 2 ].c_str() ,
228                                          *aNode.theListOfPythonFunctions[ 2 ] ) ;
229         }
230         else if ( aINode->IsInLineNode() || aINode->IsGOTONode() ||
231                   aINode->IsSwitchNode() || aINode->IsEndSwitchNode() ) {
232           aINode->SetPythonFunction( aNode.theListOfFuncName[ 0 ].c_str() ,
233                                      *aNode.theListOfPythonFunctions[ 0 ] ) ;
234         }
235       }
236 #if 0
237       if ( aNode.theListOfParameters.size() ) {
238         int j ;
239         for ( j = 0 ; j < aNode.theListOfParameters.size() ; j++ ) {
240           if ( IsInLineNode() ) {
241             GraphBase::InPort * InputPort = anInNode->AddInPort(
242                  aNode.theListOfParameters[ j ].theInParameter.Parametername ,
243                  aNode.theListOfParameters[ j ].theInParameter.Parametertype ) ;
244             GraphBase::OutPort * OutputPort = anInNode->AddOutPort(
245                  aNode.theListOfParameters[ j ].theOutParameter.Parametername ,
246                  aNode.theListOfParameters[ j ].theOutParameter.Parametertype ) ;
247             anInNode->InOutPort( InputPort , OutputPort ) ;
248           }
249         }
250       }
251 #endif
252 //      cout << "LoadNodes " << aNodetheName << " "
253 //           << GetGraphNodeIndex( anInNode->Name() ) << endl ;
254       delete aNodetheName ;
255 //    }
256     if ( !anInNode )
257       return false ;
258   }
259   for ( i = 0 ; i < aListOfNodes.size() ; i++ ) {
260     GraphBase::SNode aNode = aListOfNodes[ i ] ;
261     cdebug << "GraphEditor::OutNode::LoadNodes " << aNode.theName.c_str() << " Coupled to "
262            << aNode.theCoupledNode.c_str() << endl ;
263     anInNode = (GraphEditor::InNode * ) GetChangeGraphNode( aNode.theName.c_str() )->GetInNode() ;
264     if ( anInNode->IsOneOfGOTONodes() && strlen( aNode.theCoupledNode.c_str() ) ) {
265       GraphBase::GOTONode * aCoupledNode ;
266       aCoupledNode = (GraphBase::GOTONode * ) GetGraphNode( aNode.theName.c_str() ) ;
267       aCoupledNode->CoupledNode( (GraphBase::GOTONode * ) GetChangeGraphNode( aNode.theCoupledNode.c_str() ) ) ; 
268     }
269   }
270   cdebug_out << "GraphEditor::OutNode::LoadNodes" << endl ;
271   return true ;
272 }
273
274 bool GraphEditor::OutNode::LoadLinks(map< string , int > & aMapOfNodes ,
275                                      const GraphBase::ListOfLinks &aListOfLinks ) {
276   bool RetVal = true ;
277   cdebug_in << "GraphEditor::OutNode::LoadLinks" << endl ;
278 //  MESSAGE( "GraphEditor::OutNode::LoadLinks" );
279   int i , j ;
280   for ( i = 0 ; i < aListOfLinks.size() ; i++ ) {
281     GraphBase::SLink aLink = aListOfLinks[ i ] ;
282     string * aLinkFromNodeName = new string( aLink.FromNodeName.c_str() ) ;
283     string * aLinkToNodeName = new string( aLink.ToNodeName.c_str() ) ;
284     cdebug << "LoadLinks " << aLinkFromNodeName->c_str() << "( "
285            << aLink.FromServiceParameterName.c_str() << " ) --> "
286            << aLinkToNodeName->c_str() << "( "
287            << aLink.FromServiceParameterName.c_str() << " )" << endl ;
288     RetVal = AddLink( GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
289                       aLink.FromServiceParameterName.c_str() ,
290                       GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
291                       aLink.ToServiceParameterName.c_str() ,
292                       *((GraphBase::ComputingNode *) GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] ))->GetOutPort( aLink.FromServiceParameterName.c_str() )->Value() ) ;
293 //                      aLink.aLinkValue ) ;
294     if ( !RetVal )
295       break ;
296     else {
297       for ( j = 0 ; j < aLink.aListOfCoords.size() ; j++ ) {
298         RetVal = AddLinkCoord( GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
299                                aLink.FromServiceParameterName.c_str() ,
300                                GetGraphNode( aMapOfNodes[ aLink.ToNodeName.c_str() ] )->Name() ,
301                                aLink.ToServiceParameterName.c_str() ,
302                                j + 1 ,
303                                aLink.aListOfCoords[j].theX ,
304                                aLink.aListOfCoords[j].theY ) ;
305         if ( !RetVal )
306           break ;
307       }
308     }
309     delete aLinkFromNodeName ;
310     delete aLinkToNodeName ;
311   }
312   cdebug_out << "GraphEditor::OutNode::LoadLinks" << endl ;
313   return RetVal ;
314 }
315
316 bool GraphEditor::OutNode::LoadDatas(map< string , int > & aMapOfNodes ,
317                                      const GraphBase::ListOfLinks &aListOfDatas ) {
318   bool RetVal = true ;
319   cdebug_in << "GraphEditor::OutNode::LoadDatas" << endl ;
320 //  MESSAGE( "GraphEditor::OutNode::LoadDatas" );
321   int i ;
322   for ( i = 0 ; i < aListOfDatas.size() ; i++ ) {
323     GraphBase::SLink aLink = aListOfDatas[ i ] ;
324     if ( !strcmp( aLink.FromNodeName.c_str() , Name() ) ) {
325       cdebug << "GraphEditor::OutNode::LoadDatas Warning "
326              << aLink.FromNodeName.c_str()
327              << " and " << aLink.ToNodeName.c_str() << " differents from " << Name()
328              << endl ;
329     }
330     string * aLinkFromNodeName = new string( aLink.FromNodeName.c_str() ) ;
331     string * aLinkToNodeName = new string( aLink.ToNodeName.c_str() ) ;
332 //      cout << "LoadDatas " << aLink.FromNodeName.c_str() << " "
333 //           << aMapOfNodes[ aLinkFromNodeName->c_str() ] << endl ;
334 //      cout << "          " << aLink.ToNodeName.c_str() << " "
335 //           << aMapOfNodes[ aLinkToNodeName->c_str() ] << endl ;
336     RetVal = GraphBase::Graph::AddInputData( GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
337                                              aLink.ToServiceParameterName.c_str() ,
338                                              aLink.aLinkValue ) ;
339     delete aLinkFromNodeName ;
340     delete aLinkToNodeName ;
341     if ( !RetVal )
342       break ;
343   }
344   cdebug_out << "GraphEditor::OutNode::LoadDatas" << endl ;
345   return RetVal ;
346 }
347
348 bool GraphEditor::OutNode::SaveXml(const char* filename) {
349   bool test;
350   cdebug_in << "GraphEditor::OutNode::SaveXml(" << filename << ")" << endl;
351   ofstream f(filename);
352   IsValid() ;
353 //  test = SaveXML( f );
354   QDomDocument Graph ;
355   test = SaveXML( Graph );
356   if ( test ) {
357     QString xml = Graph.toString() ;
358 //    cout << "GraphEditor::OutNode::SaveXML " << xml << endl ;
359     f << xml << endl ;
360   }
361   cdebug_out << "GraphEditor::OutNode::SaveXml" << endl;
362   return test;
363 }
364
365
366 bool GraphEditor::OutNode::SavePy( const char* filename ) {
367   bool test;
368   cdebug_in << "GraphEditor::OutNode::SavePy(" << filename << ")" << endl;
369   ofstream f( filename ) ;
370   IsValid() ;
371   test = SavePY( f );
372   cdebug_out << "GraphEditor::OutNode::SavePy" << endl;
373   return test;
374 }
375
376 GraphBase::SGraph * GraphEditor::OutNode::GetDataFlow() {
377   GraphBase::SGraph * aDataFlow = new GraphBase::SGraph;
378   aDataFlow->Info = *GetInfo() ;
379   aDataFlow->Nodes = *GetNodes() ;
380   aDataFlow->Links = *GetLinks() ;
381   aDataFlow->Datas = *GetDatas() ;
382   return aDataFlow ;
383 }
384
385 void GraphEditor::OutNode::DateModification() {
386   time_t T = time(NULL);
387   struct tm * Tm = localtime(&T);
388   SUPERV::SDate aLastModificationDate ;
389
390   aLastModificationDate.Second = Tm->tm_sec;
391   aLastModificationDate.Minute = Tm->tm_min;
392   aLastModificationDate.Hour   = Tm->tm_hour;
393   aLastModificationDate.Day    = Tm->tm_mday;
394   aLastModificationDate.Month  = Tm->tm_mon + 1;
395   aLastModificationDate.Year   = Tm->tm_year + 1900;
396   LastModification( aLastModificationDate ) ;
397 }
398
399 void GraphEditor::OutNode::Coordinates( const char* NodeName ,
400                                         const int X ,
401                                         const int Y ) {
402   ((GraphEditor::InNode * ) GetChangeGraphNode( NodeName ))->Coordinates( X , Y ) ;
403 }
404
405 const int GraphEditor::OutNode::XCoordinate( const char* NodeName ) {
406   return ((GraphEditor::InNode * ) GetChangeGraphNode( NodeName ))->XCoordinate() ;
407 }
408
409 const int GraphEditor::OutNode::YCoordinate( const char* NodeName ) {
410   return ((GraphEditor::InNode * ) GetChangeGraphNode( NodeName ))->YCoordinate() ;
411 }
412
413 GraphEditor::InNode *GraphEditor::OutNode::AddNode(
414                       const SALOME_ModuleCatalog::Service& NodeService ,
415                       GraphBase::ListOfFuncName aFuncName ,
416                       GraphBase::ListOfPythonFunctions aPythonFunction ,
417                       const char *NodeComponentName ,
418                       const char* NodeInterfaceName ,
419                       const char *theNodeName ,
420                       const SUPERV::KindOfNode NodeKindOfNode ,
421                       const SUPERV::SDate NodeFirstCreation ,
422                       const SUPERV::SDate NodeLastModification  ,
423                       const char * NodeEditorRelease ,
424                       const char * NodeAuthor ,
425                       const char * NodeComputer ,
426                       const char * NodeComment ,
427                       const int NodeX ,
428                       const int NodeY ) {
429   cdebug_in << "GraphEditor::OutNode::AddNode(" << NodeComponentName << " , "
430             << theNodeName << ")" << endl;
431   char * RetVal = NULLSTRING ;
432   GraphEditor::InNode *Nd = NULL ;
433   char * aNodeName = NULL ;
434   bool   GeneratedName = false ;
435   if ( NodeKindOfNode == SUPERV::InLineNode ||
436        NodeKindOfNode == SUPERV::LoopNode ||
437        NodeKindOfNode == SUPERV::EndLoopNode ||
438        NodeKindOfNode == SUPERV::SwitchNode ||
439        NodeKindOfNode == SUPERV::EndSwitchNode ||
440        NodeKindOfNode == SUPERV::GOTONode ) {
441     if ( theNodeName == NULL || strlen( theNodeName ) == 0 ) {
442       if ( NodeKindOfNode == SUPERV::InLineNode ) {
443         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "InLine" ) ;
444       }
445       else if ( NodeKindOfNode == SUPERV::LoopNode ) {
446         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "Loop" ) ;
447       }
448       else if ( NodeKindOfNode == SUPERV::EndLoopNode ) {
449         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "EndLoop" ) ;
450       }
451       else if ( NodeKindOfNode == SUPERV::SwitchNode ) {
452         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "Switch" ) ;
453       }
454       else if ( NodeKindOfNode == SUPERV::EndSwitchNode ) {
455         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "EndSwitch" ) ;
456       }
457       else if ( NodeKindOfNode == SUPERV::GOTONode ) {
458         ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = my_strdup( "GOTO" ) ;
459       }
460     }
461     else {
462       ((SALOME_ModuleCatalog::Service& ) NodeService).ServiceName = CORBA::string_dup( theNodeName ) ;
463     }
464     theNodeName = NULL ;
465   }
466   if ( theNodeName == NULL ) {
467     aNodeName = new char[ strlen( NodeService.ServiceName )+1 ] ;
468     strcpy( aNodeName , NodeService.ServiceName ) ;
469     if ( GetGraphNode( NodeService.ServiceName ) ) {
470       GeneratedName = true ;
471       while ( GetGraphNode( aNodeName ) ) {
472         if ( aNodeName )
473           delete [] aNodeName ;
474         int num = GetServiceNameNumber( NodeService.ServiceName ) ;
475         ostrstream s ;
476         s << num << ends ;
477         const char * n_instance = s.str() ;
478         int lname = strlen( NodeService.ServiceName ) + 1 +
479                     strlen( n_instance ) + 1 ;
480         aNodeName = new char[lname] ;
481         strcpy( aNodeName , NodeService.ServiceName ) ;
482         strcat( aNodeName , "_" ) ;
483         strcat( aNodeName , n_instance ) ;
484       }
485     }
486   }
487   else {
488     if ( GetGraphNode( theNodeName ) == NULL ) {
489       aNodeName = new char[ strlen( theNodeName )+1 ] ;
490       strcpy( aNodeName , theNodeName ) ;
491     }
492   }
493   if ( aNodeName != NULL ) {
494     Nd = new GraphEditor::InNode( _Orb , NamingService() ,
495                                   aFuncName , aPythonFunction , NodeService ,
496                                   NodeComponentName , NodeInterfaceName ,
497                                   aNodeName , NodeKindOfNode ,
498                                   NodeFirstCreation , NodeLastModification ,
499                                   NodeEditorRelease , NodeAuthor ,
500                                   NodeComputer , NodeComment , GeneratedName ,
501                                   NodeX , NodeY ,
502                                   Graph_prof_debug() , Graph_fdebug() ) ;
503 //    MESSAGE( "GraphEditor::OutNode::AddNode " << hex << (void *) Nd << dec );
504 //    if ( GraphBase::Graph::AddNode( Nd ) ) {
505     if ( GraphBase::Graph::AddNode( Nd->ComputingNode() ) ) {
506       DateModification() ;
507       RetVal = Nd->Name() ;
508     }
509     else {
510       cdebug << "NodeName already exists." << endl ;
511     }
512   }
513   else {
514     cdebug << "NodeName is NULL or already exists." << endl ;
515   }
516 //  delete [] aNodeName ;
517   cdebug_out << "GraphEditor::OutNode::AddNode" << endl;
518   _Valid = false ;
519   return Nd ;
520 }
521
522 bool GraphEditor::OutNode::AddLinkCoord( const char* FromNodeName ,
523                                          const char* FromServiceParameterName ,
524                                          const char* ToNodeName ,
525                                          const char* ToServiceParameterName ,
526                                          const int nXY ,
527                                          const int* X ,
528                                          const int* Y ) {
529   GraphBase::InPort * aLink = GraphBase::Graph::GetChangeInPort( ToNodeName ,
530                                                ToServiceParameterName ) ;
531   if ( aLink ) {
532     if ( aLink->IsSwitch() ) {
533       return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->AddCoord( nXY , X , Y ) ;
534     }
535     else {
536       return aLink->AddCoord( nXY , X , Y ) ;
537     }
538   }
539   return false ;
540 }
541
542 bool GraphEditor::OutNode::AddLinkCoord( const char* FromNodeName ,
543                                          const char* FromServiceParameterName ,
544                                          const char* ToNodeName ,
545                                          const char* ToServiceParameterName ,
546                                          const int index ,
547                                          const int X ,
548                                          const int Y ) {
549   GraphBase::InPort * aLink = GraphBase::Graph::GetChangeInPort( ToNodeName ,
550                                                ToServiceParameterName ) ;
551   if ( aLink ) {
552     if ( aLink->IsSwitch() ) {
553       return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->AddCoord( index , X , Y ) ;
554     }
555     else {
556       return aLink->AddCoord( index , X , Y ) ;
557     }
558   }
559   return false ;
560 }
561
562 bool GraphEditor::OutNode::ChangeLinkCoord(
563                                          const char* FromNodeName ,
564                                          const char* FromServiceParameterName ,
565                                          const char* ToNodeName ,
566                                          const char* ToServiceParameterName ,
567                                          const int index ,
568                                          const int X ,
569                                          const int Y ) {
570   GraphBase::InPort * aLink = GraphBase::Graph::GetChangeInPort( ToNodeName ,
571                                                ToServiceParameterName ) ;
572   if ( aLink ) {
573     if ( aLink->IsSwitch() ) {
574       return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->ChangeCoord( index , X , Y ) ;
575     }
576     else {
577       return aLink->ChangeCoord( index , X , Y ) ;
578     }
579   }
580   return false ;
581 }
582
583 bool GraphEditor::OutNode::RemoveLinkCoord(
584                                          const char* FromNodeName ,
585                                          const char* FromServiceParameterName ,
586                                          const char* ToNodeName ,
587                                          const char* ToServiceParameterName ,
588                                          const int index ) {
589   GraphBase::InPort * aLink = GraphBase::Graph::GetChangeInPort( ToNodeName ,
590                                                ToServiceParameterName ) ;
591   if ( aLink ) {
592     if ( aLink->IsSwitch() ) {
593       return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->RemoveCoord( index ) ;
594     }
595     else {
596       return aLink->RemoveCoord( index ) ;
597     }
598   }
599   return false ;
600 }
601
602 int GraphEditor::OutNode::GetLinkCoordSize(
603                                          const char* FromNodeName ,
604                                          const char* FromServiceParameterName ,
605                                          const char* ToNodeName ,
606                                          const char* ToServiceParameterName ) {
607   const GraphBase::InPort * aLink = GraphBase::Graph::GetInPort( ToNodeName , ToServiceParameterName ) ;
608   if ( aLink ) {
609     if ( aLink->IsSwitch() ) {
610       return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord() ;
611     }
612     else {
613       return aLink->GetCoord() ;
614     }
615   }
616   return 0 ;
617 }
618
619 bool GraphEditor::OutNode::GetLinkCoord( const char* FromNodeName ,
620                                          const char* FromServiceParameterName ,
621                                          const char* ToNodeName ,
622                                          const char* ToServiceParameterName ,
623                                          int *X , int *Y ) {
624   const GraphBase::InPort * aLink = GraphBase::Graph::GetInPort( ToNodeName , ToServiceParameterName ) ;
625   if ( aLink ) {
626     if ( aLink->IsSwitch() ) {
627       return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord( X , Y ) ;
628     }
629     else {
630       return aLink->GetCoord( X , Y ) ;
631     }
632   }
633   return false ;
634 }
635
636 bool GraphEditor::OutNode::GetLinkCoord(
637                                   const char* FromNodeName ,
638                                   const char* FromServiceParameterName ,
639                                   const char* ToNodeName ,
640                                   const char* ToServiceParameterName ,
641                                   const int index , long &X , long &Y ) {
642   GraphBase::InPort * aLink = GraphBase::Graph::GetChangeInPort( ToNodeName ,
643                                                ToServiceParameterName ) ;
644   if ( aLink ) {
645     if ( aLink->IsSwitch() ) {
646       return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord( index , X , Y ) ;
647     }
648     else {
649       return aLink->GetCoord( index , X , Y ) ;
650     }
651   }
652   return false ;
653 }
654
655 bool GraphEditor::OutNode::AddInputData( const char* ToNodeName1 ,
656                                          const char* ToParameterName1 ,
657                                          const char* ToNodeName2 ,
658                                          const char* ToParameterName2 ) {
659   cdebug_in << "GraphEditor::OutNode::AddInputData" << endl;
660   bool RetVal = GraphBase::Graph::AddInputData( ToNodeName1 ,
661                                                 ToParameterName1 ,
662                                                 ToNodeName2 ,
663                                                 ToParameterName2 ) ;
664   cdebug_out << "GraphEditor::OutNode::AddInputData" << endl;
665   _Valid = false ;
666   return RetVal ;
667 }
668
669 bool GraphEditor::OutNode::Valid() {
670   if ( _Valid )
671     return true ;
672
673   cdebug_in << "GraphEditor::OutNode::Valid" << endl;
674   _Executable = false ;
675
676   CreateService() ;
677
678   if ( !Sort() ) {
679     cdebug << "This DataFlow is not valid." << endl ;
680     return false ;
681   }
682
683 //  CreateService() ;
684
685   InLineServices() ;
686
687   ComputingNodes() ;
688   
689   _Valid = true ;
690
691   cdebug_out << "GraphEditor::OutNode::Valid" << endl;
692   return _Valid ;
693 }
694
695 bool GraphEditor::OutNode::Executable() {
696
697   cdebug_in << "GraphEditor::OutNode::Executable" << endl;
698   if ( !IsValid() )
699     Valid() ;
700   if ( !IsValid() )
701     return false ;
702 //  if ( !_GT )
703 //  GraphExecutor::GraphControl _GT = new GraphExecutor::GraphControl( this );
704
705   if ( DataServerNodes() )
706     _Executable = true ;
707   else {
708     cdebug << "This DataFlow is not executable." << endl ;
709     _Executable = false ;
710   }
711
712   cdebug_out << "GraphEditor::OutNode::Executable" << endl;
713   return _Executable ;
714 }
715
716 const CORBA::Any *GraphEditor::OutNode::GetInData(
717                               const char * ToNodeName ,
718                               const char * ToParameterName ) {
719 //  cdebug_in << "GraphEditor::OutNode::GetInData " << ToNodeName
720 //            << " " << ToParameterName << endl ;
721   const CORBA::Any * retdata = PortInData( ToNodeName , ToParameterName ) ;
722 //  cdebug_out << "GraphEditor::OutNode::GetInData" << endl ;
723   return retdata ;
724 }
725
726 const CORBA::Any *GraphEditor::OutNode::GetOutData(
727                               const char * FromNodeName ,
728                               const char * FromParameterName ) {
729 //  cdebug_in << "GraphEditor::OutNode::GetOutData " << FromNodeName
730 //            << " " << FromParameterName << endl ;
731   const CORBA::Any * retdata = PortOutData( FromNodeName , FromParameterName ) ;
732 //  cdebug_out << "GraphEditor::OutNode::GetOutData" << endl ;
733   return retdata ;
734 }
735
736 //bool GraphEditor::OutNode::LinkSaveXML( ostream &f , char *Tabs ,
737 bool GraphEditor::OutNode::LinkSaveXML( QDomDocument & Graph , QDomElement & link ,
738                                         GraphBase::SLink aLink ,
739                                         bool wdata ) const {
740   QDomElement fromnodename = Graph.createElement( "fromnode-name" ) ;
741   QDomText aField ;
742   if ( strlen( aLink.FromNodeName.c_str() ) ) {
743 //    f << Tabs << "<fromnode-name>" << aLink.FromNodeName.c_str()
744 //      << "</fromnode-name>" << endl ;
745     aField = Graph.createTextNode( aLink.FromNodeName.c_str() ) ;
746   }
747   else {
748 //    f << Tabs << "<fromnode-name>?</fromnode-name>" << endl ;
749     aField = Graph.createTextNode( "?" ) ;
750   }
751   link.appendChild( fromnodename ) ;
752   fromnodename.appendChild( aField ) ;
753
754 //  f << Tabs << "<fromserviceparameter-name>"
755 //    << aLink.FromServiceParameterName.c_str() << "</fromserviceparameter-name>"
756 //    << endl ;
757   QDomElement fromserviceparametername = Graph.createElement( "fromserviceparameter-name" ) ;
758   aField = Graph.createTextNode( aLink.FromServiceParameterName.c_str() ) ;
759   link.appendChild( fromserviceparametername ) ;
760   fromserviceparametername.appendChild( aField ) ;
761
762   QDomElement tonodename = Graph.createElement( "tonode-name" ) ;
763   if ( strlen( aLink.ToNodeName.c_str() ) ) {
764 //    f << Tabs << "<tonode-name>" << aLink.ToNodeName.c_str()
765 //      << "</tonode-name>" << endl ;
766     aField = Graph.createTextNode( aLink.ToNodeName.c_str() ) ;
767   }
768   else {
769 //    f << Tabs << "<tonode-name>?</tonode-name>" << endl ;
770     aField = Graph.createTextNode( "?" ) ;
771   }
772   link.appendChild( tonodename ) ;
773   tonodename.appendChild( aField ) ;
774
775 //  f << Tabs << "<toserviceparameter-name>"
776 //    << aLink.ToServiceParameterName.c_str() << "</toserviceparameter-name>"
777 //    << endl ;
778   QDomElement toserviceparametername = Graph.createElement( "toserviceparameter-name" ) ;
779   aField = Graph.createTextNode( aLink.ToServiceParameterName.c_str() ) ;
780   link.appendChild( toserviceparametername ) ;
781   toserviceparametername.appendChild( aField ) ;
782
783   if ( wdata ) {
784 //    f << Tabs << "<data-value>" << endl ;
785     QDomElement datavalue = Graph.createElement( "data-value" ) ;
786     link.appendChild( datavalue ) ;
787 //    f << Tabs << "    <value-type>" << aLink.aLinkValue.type()->kind()
788 //      << "</value-type>" << endl ;
789     QDomElement valuetype = Graph.createElement( "value-type" ) ;
790     QString aKind ;
791     aKind = aKind.setNum( aLink.aLinkValue.type()->kind() ) ;
792     aField = Graph.createTextNode( aKind ) ;
793     datavalue.appendChild( valuetype ) ;
794     valuetype.appendChild( aField ) ;
795     switch (aLink.aLinkValue.type()->kind()) {
796       case CORBA::tk_string: {
797         char* retstr ;
798         aLink.aLinkValue >>= retstr;
799 //        f << Tabs << "        <value>" << retstr << "</value>" << endl ;
800         QDomElement value = Graph.createElement( "value" ) ;
801         aField = Graph.createTextNode( retstr ) ;
802         datavalue.appendChild( value ) ;
803         value.appendChild( aField ) ;
804 //        MESSAGE( "ToString( string ) " << retstr );
805         break ;
806       }
807       case CORBA::tk_double: {
808         double d;
809         aLink.aLinkValue >>= d;
810 //        f << Tabs << "        <value>" << d << "</value>" << endl ;
811         QDomElement value = Graph.createElement( "value" ) ;
812         QString aKind ;
813         aKind = aKind.setNum( d ) ;
814         aField = Graph.createTextNode( aKind ) ;
815         datavalue.appendChild( value ) ;
816         value.appendChild( aField ) ;
817 //        MESSAGE( "ToString( double ) " << d );
818         break ;
819       }
820       case CORBA::tk_long: {
821         long l;
822         aLink.aLinkValue >>= l;
823 //        f << Tabs << "        <value>" << l << "</value>" << endl ;
824         QDomElement value = Graph.createElement( "value" ) ;
825         QString aKind ;
826         aKind = aKind.setNum( l ) ;
827         aField = Graph.createTextNode( aKind ) ;
828         datavalue.appendChild( value ) ;
829         value.appendChild( aField ) ;
830 //        MESSAGE( "ToString( long ) " << l );
831         break ;
832       }
833       case CORBA::tk_objref: {
834         char* retstr ;
835         CORBA::Object_ptr obj ;
836         aLink.aLinkValue >>= obj ;
837         retstr = _Orb->object_to_string(obj );
838 //        f << Tabs << "        <value>" << retstr << "</value>" << endl ;
839         QDomElement value = Graph.createElement( "value" ) ;
840         aField = Graph.createTextNode( retstr ) ;
841         datavalue.appendChild( value ) ;
842         value.appendChild( aField ) ;
843 //        MESSAGE( "ToString( object ) " << retstr );
844         break ;
845       }
846       default: {
847 //        f << Tabs << "        <value>?</value>" << endl ;
848         QDomElement value = Graph.createElement( "value" ) ;
849         aField = Graph.createTextNode( "?" ) ;
850         datavalue.appendChild( value ) ;
851         value.appendChild( aField ) ;
852 //        MESSAGE( "Unknown CORBA::Any Type" );
853         break ;
854       }
855     }
856 //    f << Tabs << "</data-value>" << endl ;
857   }
858 //  f << Tabs << "<coord-list>" << endl ;
859   QDomElement coordlist = Graph.createElement( "coord-list" ) ;
860   link.appendChild( coordlist ) ;
861   
862   int i ;
863   for ( i = 0 ; i < aLink.aListOfCoords.size() ; i++ ) {
864 //    f << Tabs << "    <coord>" << endl ;
865     QDomElement coord = Graph.createElement( "coord" ) ;
866     coordlist.appendChild( coord ) ;
867 //    f << Tabs << "            <x>" << aLink.aListOfCoords[ i ].theX << "</x>" << endl ;
868     QDomElement x = Graph.createElement( "x" ) ;
869     QString ax ;
870     ax = ax.setNum( aLink.aListOfCoords[ i ].theX ) ;
871     aField = Graph.createTextNode( ax ) ;
872     coord.appendChild( x ) ;
873     x.appendChild( aField ) ;    
874 //    f << Tabs << "            <y>" << aLink.aListOfCoords[ i ].theY << "</y>" << endl ;
875     QDomElement y = Graph.createElement( "y" ) ;
876     QString ay ;
877     ay = ay.setNum( aLink.aListOfCoords[ i ].theY ) ;
878     aField = Graph.createTextNode( ay ) ;
879     coord.appendChild( y ) ;
880     y.appendChild( aField ) ;    
881 //    f << Tabs << "    </coord>" << endl ;
882   }
883 //  f << Tabs << "</coord-list>" << endl ;
884   return true ;
885 }
886
887 bool GraphEditor::OutNode::LinkSavePY( ostream &f , const char * aGraphName ,
888                                        GraphBase::SLink aLink ,
889                                        bool intervar , bool wdata ) const {
890   if ( !wdata ) {
891     if ( intervar ) {
892       f << aLink.FromNodeName.c_str() << aLink.FromServiceParameterName.c_str()
893         << " = "
894         << aLink.FromNodeName.c_str() << ".Port( '"
895         << aLink.FromServiceParameterName.c_str()
896         << "' )" << endl ;
897     }
898     f << aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str()
899       << " = " << aGraphName << ".Link( " << aLink.FromNodeName.c_str()
900       << aLink.FromServiceParameterName.c_str() << " , "
901       << aLink.ToNodeName.c_str() << ".Port( '"
902       << aLink.ToServiceParameterName.c_str() << "' ) )" << endl ;
903   }
904   else {
905     f << aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str()
906       << " = " << aLink.ToNodeName.c_str() << ".Input( '"
907       << aLink.ToServiceParameterName.c_str() << "' , " ;
908     switch (aLink.aLinkValue.type()->kind()) {
909       case CORBA::tk_string: {
910         char* retstr ;
911         aLink.aLinkValue >>= retstr;
912         f << "'" << retstr << "'" ;
913         break ;
914       }
915       case CORBA::tk_double: {
916         double d;
917         aLink.aLinkValue >>= d;
918         f << d ;
919         break ;
920       }
921       case CORBA::tk_long: {
922         long l;
923         aLink.aLinkValue >>= l;
924         f << l ;
925         break ;
926       }
927       case CORBA::tk_objref: {
928         char* retstr ;
929         CORBA::Object_ptr obj ;
930         aLink.aLinkValue >>= obj ;
931         retstr = _Orb->object_to_string(obj );
932         f << "'" << retstr << "'" ;
933         break ;
934       }
935       default: {
936         f << "?" ;
937 //        MESSAGE( "Unknown CORBA::Any Type" );
938         break ;
939       }
940     }
941     f << ")" << endl ;
942   }
943   int i ;
944   for ( i = 0 ; i < aLink.aListOfCoords.size() ; i++ ) {
945     f << aLink.ToNodeName.c_str()
946       << aLink.ToServiceParameterName.c_str() << ".AddCoord( " << i+1 << " , "
947       << aLink.aListOfCoords[ i ].theX << " , "
948       << aLink.aListOfCoords[ i ].theY << " )" << endl ;
949   }
950   return true ;
951 }
952
953 //bool GraphEditor::OutNode::SaveXML(ostream & f ) {
954 bool GraphEditor::OutNode::SaveXML(QDomDocument & Graph ) {
955   int i ;
956 //  f << "<?xml version='1.0' encoding='us-ascii' ?>" << endl << endl ;
957 //  f << "<!-- XML Dataflow -->" << endl << endl ;
958 //  f << "<!-- Dataflow information -->" << endl ;
959   QString Dataflow("Dataflow") ;
960   Graph = QDomDocument(Dataflow) ;
961 //  f << "<dataflow>" << endl ;
962   QDomElement dataflow = Graph.createElement( "dataflow" ) ;
963   Graph.appendChild( dataflow ) ;
964 //  f << "      <info-list>" << endl ;
965   QDomElement info = Graph.createElement( "info-list" ) ;
966   dataflow.appendChild( info ) ;
967
968 //  f << "              <node>" << endl ;
969
970 //  GraphBase::DataNode::SaveXML( f , "                 " , 0 , 0 ) ;
971   GraphBase::DataNode::SaveXML( Graph , info , 0 , 0 ) ;
972
973 //  f << "              </node>" << endl ;
974
975 //  f << "      </info-list>" << endl << endl ;
976
977 //  f << "      <node-list>" << endl ;
978   QDomElement nodelist = Graph.createElement( "node-list" ) ;
979   dataflow.appendChild( nodelist ) ;
980   for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
981 //      f << "          <node>" << endl ;
982       if ( GraphNodes( i )->IsComputingNode() ) {
983 //        ((GraphBase::ComputingNode *)GraphNodes( i ))->SaveXML( f ,
984 //                    "                 " ,
985         ((GraphBase::ComputingNode *)GraphNodes( i ))->SaveXML( Graph , nodelist ,
986                     GraphNodes( i )->XCoordinate() ,
987                     GraphNodes( i )->YCoordinate() ) ;
988       }
989       else if ( GraphNodes( i )->IsFactoryNode() ) {
990 //        ((GraphBase::FactoryNode * ) GraphNodes( i ))->SaveXML( f ,
991 //                    "                 " ,
992         ((GraphBase::FactoryNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
993                     GraphNodes( i )->XCoordinate() ,
994                     GraphNodes( i )->YCoordinate() ) ;
995       }
996       else if ( GraphNodes( i )->IsInLineNode() ) {
997 //        ((GraphBase::InLineNode * ) GraphNodes( i ))->SaveXML( f ,
998 //                    "                 " ,
999         ((GraphBase::InLineNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
1000                     GraphNodes( i )->XCoordinate() ,
1001                     GraphNodes( i )->YCoordinate() ) ;
1002       }
1003       else if ( GraphNodes( i )->IsGOTONode() ) {
1004 //        ((GraphBase::GOTONode * ) GraphNodes( i ))->SaveXML( f ,
1005 //                    "                 " ,
1006         ((GraphBase::GOTONode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
1007                     GraphNodes( i )->XCoordinate() ,
1008                     GraphNodes( i )->YCoordinate() ) ;
1009       }
1010       else if ( GraphNodes( i )->IsLoopNode() ) {
1011 //        ((GraphBase::LoopNode * ) GraphNodes( i ))->SaveXML( f ,
1012 //                    "                 " ,
1013         ((GraphBase::LoopNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
1014                     GraphNodes( i )->XCoordinate() ,
1015                     GraphNodes( i )->YCoordinate() ) ;
1016       }
1017       else if ( GraphNodes( i )->IsEndLoopNode() ) {
1018 //        ((GraphBase::EndOfLoopNode * ) GraphNodes( i ))->SaveXML( f ,
1019 //                    "                 " ,
1020         ((GraphBase::EndOfLoopNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
1021                     GraphNodes( i )->XCoordinate() ,
1022                     GraphNodes( i )->YCoordinate() ) ;
1023       }
1024       else if ( GraphNodes( i )->IsSwitchNode() ) {
1025 //        ((GraphBase::SwitchNode * ) GraphNodes( i ))->SaveXML( f ,
1026 //                    "                 " ,
1027         ((GraphBase::SwitchNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
1028                     GraphNodes( i )->XCoordinate() ,
1029                     GraphNodes( i )->YCoordinate() ) ;
1030       }
1031       else if ( GraphNodes( i )->IsEndSwitchNode() ) {
1032 //        ((GraphBase::EndOfSwitchNode * ) GraphNodes( i ))->SaveXML( f ,
1033 //                    "                 " ,
1034         ((GraphBase::EndOfSwitchNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
1035                     GraphNodes( i )->XCoordinate() ,
1036                     GraphNodes( i )->YCoordinate() ) ;
1037       }
1038 //      f << "          </node>" << endl ;
1039 //    }
1040   }
1041 //  f << "      </node-list>" << endl << endl ;
1042
1043 //  f << "      <link-list>" << endl ;
1044   QDomElement linklist = Graph.createElement( "link-list" ) ;
1045   dataflow.appendChild( linklist ) ;
1046   const GraphBase::ListOfLinks * Links = GetLinks() ;
1047   for ( i = 0 ; i < Links->size() ; i++ ) {
1048 //    f << "            <link>" << endl ;
1049     QDomElement link = Graph.createElement( "link" ) ;
1050     linklist.appendChild( link ) ;
1051 //    LinkSaveXML( f , "                        " , (*Links)[ i ] , false ) ;
1052     LinkSaveXML( Graph , link , (*Links)[ i ] , false ) ;
1053 //    f << "            </link>" << endl ;
1054   }
1055 //  f << "      </link-list>" << endl << endl ;
1056
1057 //  f << "      <data-list>" << endl ;
1058   QDomElement datalist = Graph.createElement( "data-list" ) ;
1059   dataflow.appendChild( datalist ) ;
1060   const GraphBase::ListOfLinks * Datas = GetDatas() ;
1061   for ( i = 0 ; i < Datas->size() ; i++ ) {
1062 //    f << "            <data>" << endl ;
1063     QDomElement data = Graph.createElement( "data" ) ;
1064     datalist.appendChild( data ) ;
1065 //    LinkSaveXML( f , "                        " , (*Datas)[ i ] , true ) ;
1066     LinkSaveXML( Graph , data , (*Datas)[ i ] , true ) ;
1067 //    f << "            </data>" << endl ;
1068   }
1069 //#if 0
1070 //  const GraphEditor::OutNode * aDataNode = (GraphEditor::OutNode *) this ;
1071 //  if ( aDataNode ) {
1072 //    int i ;
1073 //    for ( i = 0 ; i < aDataNode->GetNodeOutPortsSize() ; i++ ) {
1074 //      const GraphBase::InPort *aLink = aDataNode->GetNodeOutPort(i)->GetLink() ;
1075 //      if ( aLink ) {
1076 //        f << "                <data>" << endl ;
1077 //        aLink->SaveXML( f , "                 " ) ;
1078 //        f << "                </data>" << endl ;
1079 //      }
1080 //    }
1081 //    for ( i = 0 ; i < aDataNode->GetNodeInPortsSize() ; i++ ) {
1082 //      const GraphBase::InPort *aLink = aDataNode->GetNodeInPort(i)->GetLink() ;
1083 //      if ( aLink ) {
1084 //        f << "                <data>" << endl ;
1085 //        aLink->SaveXML( f , "                 " ) ;
1086 //        f << "                </data>" << endl ;
1087 //      }
1088 //    }
1089 //  }
1090 //#endif
1091
1092 #if 0
1093   f << "        </data-list>" << endl << endl ;
1094   f << "</dataflow>" << endl ;
1095 #endif
1096
1097   return true ;
1098 }
1099
1100 bool GraphEditor::OutNode::SavePY( ostream & f ) {
1101   int i ;
1102   f << endl << "# Generated python file of Graph " << Name() << endl << endl ;
1103
1104   f << "from SuperV import *" << endl ;
1105
1106   f << "# Graph creation " << endl ;
1107   GraphBase::DataNode::SavePY( f , Name() , 0 , 0 ) ;
1108
1109   f << endl << "# Creation of Factory Nodes" << endl ;
1110   for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1111     if ( GraphNodes( i )->IsFactoryNode() ) {
1112       ((GraphBase::FactoryNode * ) GraphNodes( i ))->SavePY( f , Name() ,
1113                 GraphNodes( i )->XCoordinate() ,
1114                 GraphNodes( i )->YCoordinate() ) ;
1115     }
1116   }
1117
1118   bool first = true ;
1119   for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1120     if ( GraphNodes( i )->IsComputingNode() ) {
1121       if ( first ) {
1122         f << endl << "# Creation of Computing Nodes" << endl ;
1123         first = false ;
1124       }
1125       ((GraphBase::ComputingNode * ) GraphNodes( i ))->SavePY( f , Name() ,
1126                 GraphNodes( i )->XCoordinate() ,
1127                 GraphNodes( i )->YCoordinate() ) ;
1128     }
1129   }
1130
1131   first = true ;
1132   for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1133     if ( GraphNodes( i )->IsInLineNode() ) {
1134       if ( first ) {
1135         f << endl << "# Creation of InLine Nodes" << endl ;
1136         first = false ;
1137       }
1138       ((GraphBase::InLineNode * ) GraphNodes( i ))->SavePY( f , Name() ,
1139                 GraphNodes( i )->XCoordinate() ,
1140                 GraphNodes( i )->YCoordinate() ) ;
1141     }
1142   }
1143
1144   first = true ;
1145   for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1146     if ( GraphNodes( i )->IsLoopNode() ) {
1147       if ( first ) {
1148         f << endl << "# Creation of Loop Nodes" << endl ;
1149         first = false ;
1150       }
1151       ((GraphBase::LoopNode * ) GraphNodes( i ))->SavePY( f , Name() ,
1152                 GraphNodes( i )->XCoordinate() ,
1153                 GraphNodes( i )->YCoordinate() ) ;
1154     }
1155   }
1156
1157   first = true ;
1158   for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1159     if ( GraphNodes( i )->IsSwitchNode() ) {
1160       if ( first ) {
1161         f << endl << "# Creation of Switch Nodes" << endl ;
1162         first = false ;
1163       }
1164       ((GraphBase::SwitchNode * ) GraphNodes( i ))->SavePY( f , Name() ,
1165                 GraphNodes( i )->XCoordinate() ,
1166                 GraphNodes( i )->YCoordinate() ) ;
1167     }
1168   }
1169
1170   first = true ;
1171   for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1172     if ( GraphNodes( i )->IsGOTONode() ) {
1173       if ( first ) {
1174         f << endl << "# Creation of GOTO Nodes" << endl ;
1175         first = false ;
1176       }
1177       ((GraphBase::GOTONode * ) GraphNodes( i ))->SavePY( f , Name() ,
1178                 GraphNodes( i )->XCoordinate() ,
1179                 GraphNodes( i )->YCoordinate() ) ;
1180     }
1181   }
1182
1183   const GraphBase::ListOfLinks * Links = GetLinks() ;
1184   bool intervar ;
1185   map< string , int > aMapOfOutPorts ;
1186   first = true ;
1187   for ( i = 0 ; i < Links->size() ; i++ ) {
1188     if ( GetGraphNode( (*Links)[ i ].FromNodeName.c_str() )->IsComputingNode() &&
1189          GetGraphNode( (*Links)[ i ].ToNodeName.c_str() )->IsComputingNode() ) {
1190       if ( first ) {
1191         f << endl
1192           << "# Creation of intermediate Output variables and of Computing Links"
1193           << endl ;
1194         first = false ;
1195       }
1196       char * NodePort = new char [ strlen( (*Links)[ i ].FromNodeName.c_str() ) +
1197                                    strlen( (*Links)[ i ].FromServiceParameterName.c_str() ) + 1 ] ;
1198       strcpy( NodePort , (*Links)[ i ].FromNodeName.c_str() ) ;
1199       strcat( NodePort , (*Links)[ i ].FromServiceParameterName.c_str() ) ;
1200       if ( aMapOfOutPorts[ NodePort ] == 0 ) {
1201         aMapOfOutPorts[ NodePort ] = i + 1 ;
1202         intervar = true ;
1203       }
1204       else {
1205         intervar = false ;
1206       }
1207       LinkSavePY( f , Name() , (*Links)[ i ] , intervar , false ) ;
1208       delete [] NodePort ;
1209     }
1210   }
1211
1212 #if 0
1213   first = true ;
1214   for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1215     if ( GraphNodes( i )->IsInLineNode() ||
1216          GraphNodes( i )->IsGOTONode() ) {
1217       int j ;
1218       for ( j = 0 ; j < GraphNodes( i )->GetNodeInPortsSize() ; j++ ) {
1219         if ( GraphNodes( i )->GetNodeInPort( j )->IsBus() ) {
1220           if ( first ) {
1221             f << endl
1222               << "# Creation of Output variables and of Bus Ports"
1223               << endl ;
1224             first = false ;
1225           }
1226           f << GraphNodes( i )->Name() << ".InOutPort( '"
1227             << GraphNodes( i )->GetNodeInPort( j )->PortName() << "' , '"
1228             << GraphNodes( i )->GetNodeInPort( j )->PortType() << "' , '"
1229             << GraphNodes( i )->GetNodeOutPort( GraphNodes( i )->GetNodeInPort( j )->PortIndex() )->PortName()
1230             << "' , '"
1231             << GraphNodes( i )->GetNodeOutPort( GraphNodes( i )->GetNodeInPort( j )->PortIndex() )->PortType()
1232             << "' )" << endl ;
1233         }
1234       }
1235     }
1236   }
1237 #endif
1238
1239   first = true ;
1240   for ( i = 0 ; i < Links->size() ; i++ ) {
1241     if ( !( GetGraphNode( (*Links)[ i ].FromNodeName.c_str() )->IsComputingNode() &&
1242            GetGraphNode( (*Links)[ i ].ToNodeName.c_str() )->IsComputingNode() ) &&
1243          !( GetGraphNode( (*Links)[ i ].FromNodeName.c_str() )->IsGOTONode() &&
1244            GetGraphNode( (*Links)[ i ].ToNodeName.c_str() )->IsInLineNode() ) ) {
1245       if ( first ) {
1246         f << endl
1247           << "# Creation of intermediate Output variables and of Control Links"
1248           << endl ;
1249         first = false ;
1250       }
1251       char * NodePort = new char [ strlen( (*Links)[ i ].FromNodeName.c_str() ) +
1252                                    strlen( (*Links)[ i ].FromServiceParameterName.c_str() ) + 1 ] ;
1253       strcpy( NodePort , (*Links)[ i ].FromNodeName.c_str() ) ;
1254       strcat( NodePort , (*Links)[ i ].FromServiceParameterName.c_str() ) ;
1255       if ( aMapOfOutPorts[ NodePort ] == 0 ) {
1256         aMapOfOutPorts[ NodePort ] = i + 1 ;
1257         intervar = true ;
1258       }
1259       else {
1260         intervar = false ;
1261       }
1262       LinkSavePY( f , Name() , (*Links)[ i ] , intervar , false ) ;
1263       delete [] NodePort ;
1264     }
1265   }
1266
1267   first = true ;
1268   for ( i = 0 ; i < Links->size() ; i++ ) {
1269     if ( GetGraphNode( (*Links)[ i ].FromNodeName.c_str() )->IsGOTONode() &&
1270          GetGraphNode( (*Links)[ i ].ToNodeName.c_str() )->IsInLineNode() ) {
1271       if ( first ) {
1272         f << endl
1273           << "# Creation of intermediate Output variables and of Loop Links"
1274           << endl ;
1275         first = false ;
1276       }
1277       char * NodePort = new char [ strlen( (*Links)[ i ].FromNodeName.c_str() ) +
1278                                    strlen( (*Links)[ i ].FromServiceParameterName.c_str() ) + 1 ] ;
1279       strcpy( NodePort , (*Links)[ i ].FromNodeName.c_str() ) ;
1280       strcat( NodePort , (*Links)[ i ].FromServiceParameterName.c_str() ) ;
1281       if ( aMapOfOutPorts[ NodePort ] == 0 ) {
1282         aMapOfOutPorts[ NodePort ] = i + 1 ;
1283         intervar = true ;
1284       }
1285       else {
1286         intervar = false ;
1287       }
1288       LinkSavePY( f , Name() , (*Links)[ i ] , intervar , false ) ;
1289       delete [] NodePort ;
1290     }
1291   }
1292
1293   const GraphBase::ListOfLinks * Datas = GetDatas() ;
1294   first = true ;
1295   for ( i = 0 ; i < Datas->size() ; i++ ) {
1296     if ( first ) {
1297       f << endl << "# Creation of Input datas" << endl ;
1298       first = false ;
1299     }
1300     LinkSavePY( f , Name() , (*Datas)[ i ] , false , true ) ;
1301   }
1302
1303   first = true ;
1304   const SALOME_ModuleCatalog::ListOfServicesParameter ListOfInParam = ServiceInParameter() ;
1305   for ( i = 0 ; i < ListOfInParam.length() ; i++ ) {
1306     string _aParam = CORBA::string_dup(ListOfInParam[ i ].Parametername) ;
1307     const char * aParam = _aParam.c_str() ;
1308     char * aNodeName ;
1309     char * aPortName ;
1310     int j , k ;
1311     for ( j = 0 ; j < strlen( aParam ) ; j++ ) {
1312       if ( aParam[ j ] == '\\' ) {
1313         aNodeName = new char[ j+1 ] ;
1314         strncpy( aNodeName , aParam , j ) ;
1315         aNodeName[ j ] = '\0' ;
1316         aPortName = new char[ strlen( aParam ) - j ] ;
1317         strncpy( aPortName , &aParam[ j+1 ] , strlen( aParam ) - j ) ;
1318         break ;
1319       }
1320     }
1321     if ( !GetChangeGraphNode( aNodeName )->GetInPort( aPortName )->IsDataConnected() ) {
1322       if ( first ) {
1323         f << endl << "# Missing Input datas" << endl ;
1324         first = false ;
1325       }
1326       f << aNodeName << aPortName << " = " << aNodeName << ".Port( '"
1327         << aPortName << "' )" << endl ;
1328     }
1329     delete [] aNodeName ;
1330     delete [] aPortName ;
1331   }
1332
1333   f << endl << "# Creation of Output variables" << endl ;
1334   const SALOME_ModuleCatalog::ListOfServicesParameter ListOfOutParam = ServiceOutParameter() ;
1335   for ( i = 0 ; i < ListOfOutParam.length() ; i++ ) {
1336     string _aParam = CORBA::string_dup(ListOfOutParam[ i ].Parametername) ;
1337     const char * aParam = _aParam.c_str() ;
1338     char * aNodeName ;
1339     char * aPortName ;
1340     int j , k ;
1341     for ( j = 0 ; j < strlen( aParam ) ; j++ ) {
1342       if ( aParam[ j ] == '\\' ) {
1343         aNodeName = new char[ j+1 ] ;
1344         strncpy( aNodeName , aParam , j ) ;
1345         aNodeName[ j ] = '\0' ;
1346         aPortName = new char[ strlen( aParam ) - j ] ;
1347         strncpy( aPortName , &aParam[ j+1 ] , strlen( aParam ) - j ) ;
1348         break ;
1349       }
1350     }
1351     f << aNodeName << aPortName << " = " << aNodeName << ".Port( '"
1352       << aPortName << "' )" << endl ;
1353     delete [] aNodeName ;
1354     delete [] aPortName ;
1355   }
1356   return true ;
1357 }
1358
1359
1360
1361 ostrstream & operator<< (ostrstream & f,const GraphEditor::OutNode & G) {
1362   f << (GraphBase::ComputingNode ) G ;
1363   f << endl ;
1364
1365   f << "  Nodes : " << G.GraphNodesSize() << " node" 
1366     << (G.GraphNodesSize() > 1 ? "s" : "") << endl;
1367   
1368   int i ;
1369   for ( i = 0 ; i < G.GraphNodesSize() ; i++ ) {
1370     f
1371 //      << hex << (void *) G.GraphNodes( i ) << dec << " "
1372       << *G.GraphNodes( i ) << endl;
1373   }
1374
1375   f << "  Links : " << endl ;
1376   for ( i = 0 ; i < G.GraphNodesSize() ; i++ ) {
1377     G.GraphNodes( i )->ListLinks( f ) ;
1378   }
1379
1380   f << "  Datas : " << endl ;
1381   G.ListDatas( f ) ;
1382
1383   f << "DataFlow " << G.Name() << " is " ;
1384   if ( G.IsNotValid() )
1385     f << "not " ;
1386   f << "valid and is " ;
1387   if ( G.IsNotExecutable() )
1388     f << "not " ;
1389   f << "executable." << endl ;
1390
1391   f << endl ;
1392   
1393   return f;
1394 }
1395
1396 ostream & operator<< (ostream &fOut,const SUPERV::SDate &D)
1397 {
1398 //  cdebug_in << "operator<< GraphEditor::Date" << endl;
1399
1400   fOut  << D.Day << "/" 
1401         << D.Month << "/" 
1402         << D.Year << " - " 
1403         << D.Hour << ":" 
1404         << D.Minute <<  ":"  
1405         << D.Second;
1406
1407 //  cdebug_out << "operator<< GraphEditor::Date" << endl;
1408   return fOut;
1409 }
1410
1411
1412
1413
1414
1415
1416
1417