Salome HOME
NRI : First integration.
[modules/superv.git] / src / GraphBase / DataFlowBase_ComputingNode.cxx
1 using namespace std;
2 //=============================================================================
3 // File      : DataFlowBase_Node.cxx
4 // Created   : 2002
5 // Author    : Jean Rahuel, CEA
6 // Project   : SALOME
7 // $Header:
8 //=============================================================================
9
10 #include <strstream>
11 #include <iostream>
12
13 #include "DataFlowBase_InLineNode.hxx"
14 #include "DataFlowBase_LoopNode.hxx"
15
16 static void InitFields( SUPERV::KindOfNode &_Kind ,
17                         SUPERV::SDate      &_FirstCreation ,
18                         SUPERV::SDate      &_LastModification ,
19                         char *              &_EditorRelease ,
20                         char *              &_Author ,
21                         char *              &_Comment ,
22                         bool                &_HeadNode ,
23                         bool                &_GeneratedName ,
24                         int                 &_ConnectedInPortsNumber ,
25                         int                 &_DecrConnectedInPortsNumber,
26                         int                 &_LinkedNodesSize ,
27                         int                 &_SubGraphNumber ) {
28   time_t T = time(NULL);
29   struct tm * Tm = localtime(&T);
30
31   _Kind = SUPERV::DataFlowNode ;
32
33   _FirstCreation.Second = _LastModification.Second = Tm->tm_sec;
34   _FirstCreation.Minute = _LastModification.Minute = Tm->tm_min;
35   _FirstCreation.Hour   = _LastModification.Hour   = Tm->tm_hour;
36   _FirstCreation.Day    = _LastModification.Day    = Tm->tm_mday;
37   _FirstCreation.Month  = _LastModification.Month  = Tm->tm_mon + 1;
38   _FirstCreation.Year   = _LastModification.Year   = Tm->tm_year + 1900; 
39
40   _EditorRelease = new char[ strlen( SuperVision_Version ) + 1 ] ;
41   strcpy( _EditorRelease , SuperVision_Version ) ;
42   _Author = NULLSTRING ;
43 //  _Computer = new char[ strlen( FACTORYSERVER ) + 1 ] ;
44 //  strcpy( _Computer  , FACTORYSERVER ) ;
45   _Comment = NULLSTRING ;
46
47   _SubGraphNumber = 0 ;
48   _HeadNode = false ;
49   _GeneratedName = false ;
50
51   _ConnectedInPortsNumber = 0 ;
52   _DecrConnectedInPortsNumber = 0 ;
53   _LinkedNodesSize = 0 ;
54   _SubGraphNumber = 0 ;
55 }
56
57 GraphBase::ComputingNode::ComputingNode() :
58   GraphBase::PortsOfNode::PortsOfNode() {
59
60   InitFields( _Kind ,
61               _FirstCreation ,
62               _LastModification ,
63               _EditorRelease ,
64               _Author ,
65               _Comment ,
66               _HeadNode ,
67               _GeneratedName ,
68               _ConnectedInPortsNumber ,
69               _DecrConnectedInPortsNumber ,
70               _LinkedNodesSize ,
71               _SubGraphNumber ) ;
72   _NamingService = NULL ;
73   _Node = SUPERV::CNode::_nil() ;
74   _InNode = NULL ;
75   _ThreadNo = pthread_self() ;
76   _Name = NULL ;
77   cdebug << "GraphBase::Node::Node "  << this 
78           << " _Name "
79          << (void *) _Name << " " << _Name << " _Comment "
80          << (void *) _Comment << " "  << _Comment << " "  << endl ;
81
82 }
83
84 GraphBase::ComputingNode::ComputingNode( CORBA::ORB_ptr ORB ,
85                                          SALOME_NamingService* ptrNamingService ,
86                                          const char * aDataFlowName ,
87                                          int * Graph_prof_debug ,
88                                          ostream * Graph_fdebug ) :
89   GraphBase::PortsOfNode::PortsOfNode( aDataFlowName ) {
90
91   InitFields( _Kind ,
92               _FirstCreation ,
93               _LastModification ,
94               _EditorRelease ,
95               _Author ,
96               _Comment ,
97               _HeadNode ,
98               _GeneratedName ,
99               _ConnectedInPortsNumber ,
100               _DecrConnectedInPortsNumber ,
101               _LinkedNodesSize ,
102               _SubGraphNumber ) ;
103
104   _ORB = CORBA::ORB::_duplicate( ORB ) ;
105   _NamingService = ptrNamingService ;
106   _Graph_prof_debug = Graph_prof_debug ;
107   _Graph_fdebug = Graph_fdebug ;
108   _Node = SUPERV::CNode::_nil() ;
109   _InNode = NULL ;
110   _ThreadNo = pthread_self() ;
111
112   if ( aDataFlowName && strlen( aDataFlowName ) ) {
113     _Name = new char[ strlen( aDataFlowName )+1 ] ;
114     strcpy( _Name , aDataFlowName ) ;
115   }
116   else
117     _Name = NULL ;
118   if ( Graph_prof_debug ) {
119     SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
120 //    MESSAGE( "Invalid DataFlow Name." );
121   }
122   cdebug << "GraphBase::ComputingNode::ComputingNode "  << this 
123          << "' _Name "
124          << (void *) _Name << " '" << _Name << " _Comment "
125          << (void *) _Comment << " "  << _Comment << " "  << _FirstCreation
126          << " "  << _LastModification << endl ;
127 }
128
129 GraphBase::ComputingNode::ComputingNode( CORBA::ORB_ptr ORB ,
130                                          SALOME_NamingService* ptrNamingService ,
131                                          const SALOME_ModuleCatalog::Service& aService ,
132                                          const char *NodeName ,
133                                          const SUPERV::KindOfNode akind ,
134                                          const SUPERV::SDate NodeFirstCreation ,
135                                          const SUPERV::SDate NodeLastModification  ,
136                                          const char * NodeEditorRelease ,
137                                          const char * NodeAuthor ,
138                                          const char * NodeComment ,
139                                          const bool   GeneratedName ,
140                                          const long   X ,
141                                          const long   Y ,
142                                          int * Graph_prof_debug ,
143                                          ostream * Graph_fdebug ) :
144   GraphBase::PortsOfNode::PortsOfNode() {
145
146   _ORB = CORBA::ORB::_duplicate( ORB ) ;
147   _NamingService = ptrNamingService ;
148   _Graph_prof_debug = Graph_prof_debug ;
149   _Graph_fdebug = Graph_fdebug ;
150   _Node = SUPERV::CNode::_nil() ;
151   _InNode = NULL ;
152   _ThreadNo = pthread_self() ;
153
154   _Kind = akind ;
155
156   time_t T = time(NULL);
157   struct tm * Tm = localtime(&T);
158
159   _FirstCreation.Second = _LastModification.Second = Tm->tm_sec;
160   _FirstCreation.Minute = _LastModification.Minute = Tm->tm_min;
161   _FirstCreation.Hour   = _LastModification.Hour   = Tm->tm_hour;
162   _FirstCreation.Day    = _LastModification.Day    = Tm->tm_mday;
163   _FirstCreation.Month  = _LastModification.Month  = Tm->tm_mon + 1;
164   _FirstCreation.Year   = _LastModification.Year   = Tm->tm_year + 1900; 
165
166   if ( NodeEditorRelease ) {
167     _EditorRelease = new char[ strlen( NodeEditorRelease ) + 1 ] ;
168     strcpy( _EditorRelease , NodeEditorRelease ) ;
169   }
170   else {
171     _EditorRelease = new char[ strlen( SuperVision_Version ) + 1 ] ;
172     strcpy( _EditorRelease , SuperVision_Version ) ;
173   }
174
175   if ( NodeAuthor ) {
176     _Author = new char[ strlen( NodeAuthor ) + 1 ] ;
177     strcpy( _Author  , NodeAuthor ) ;
178   }
179   else
180     _Author = NULLSTRING ;
181
182   if ( NodeComment  ) {
183     _Comment = new char[ strlen( NodeComment ) + 1 ] ;
184     strcpy( _Comment  , NodeComment ) ;
185   }
186   else
187     _Comment = NULLSTRING ;
188
189   _SubGraphNumber = 0 ;
190   _HeadNode = false ;
191   _GeneratedName = GeneratedName ;
192
193   const char *aNodeName = NodeName ;
194   _Name = new char[strlen(aNodeName)+1];
195   strcpy(_Name , aNodeName);
196
197   _ConnectedInPortsNumber = 0 ;
198   _DecrConnectedInPortsNumber = 0 ;
199   _LinkedNodesSize = 0 ;
200
201   _X = X ;
202   _Y = Y ;
203
204   if ( Graph_prof_debug )
205     SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
206
207 //  if ( !IsOneOfInLineNodes() ) {
208     DefPortsOfNode( ORB , aService , NamePtr() , Kind() ,
209                     IsDataFlowNode() || IsComputingNode() ||
210                     IsFactoryNode() ,                        // DataFlowOrComputing
211                     IsLoopNode() || IsEndLoopNode() ,        // WithInLoop
212                       IsComputingNode() || IsFactoryNode() ||// WithInGate
213                       IsInLineNode() || IsLoopNode() || IsSwitchNode() ||
214                       IsEndSwitchNode() ,
215 //                      IsGOTONode() || IsEndLoopNode() || IsEndSwitchNode() ,
216                     IsComputingNode() || IsFactoryNode() ||  // WithOutGate
217                     IsInLineNode() || IsSwitchNode() || IsGOTONode() ,
218 //                    IsEndLoopNode() || IsEndSwitchNode() ,
219                     Graph_prof_debug , Graph_fdebug ) ;
220 //  }
221
222   cdebug_in << "GraphBase::ComputingNode::ComputingNode(" << aService.ServiceName << ","
223             << aNodeName << "," << akind
224             << "," << NodeComment << ")" << endl;
225   
226   cdebug << "GraphBase::ComputingNode::ComputingNode "  << this 
227          << " _Name "
228          << (void *) _Name << " '" << _Name << "' _Comment "
229          << (void *) _Comment << " "  << _Comment << " " 
230          << " KindOfNode " << _Kind
231          << " ServiceName " << ServiceName() << " In(" << ServiceInParameter().length()
232          << ") Out(" << ServiceOutParameter().length() << ")" << endl ;
233
234   cdebug_out << "GraphBase::ComputingNode::ComputingNode" << endl;
235 }
236
237 GraphBase::ComputingNode::~ComputingNode() {
238   cdebug << "GraphBase::ComputingNode::~ComputingNode "  << this 
239          << " _Name "
240          << (void *) _Name << " " << _Name << " _Comment "
241          << (void *) _Comment << " "  << _Comment << " "  << endl ;
242 //  if ( _ComponentName != NULLSTRING )
243 //    delete [] _ComponentName ;
244 //  delete [] _Name ;
245 //  delete [] _EditorRelease ;
246 //  if ( _Author != NULLSTRING )
247 //    delete [] _Author ;
248 //  if ( _Computer != FACTORYSERVER )
249 //    delete [] _Computer;
250 //  if ( _Comment != NULLSTRING )
251 //    delete [] _Comment;
252 }
253
254 bool GraphBase::ComputingNode::Name( const char * aName) {
255   if ( _Name ) {
256     cdebug << "GraphBase::ComputingNode::ReName "  << _Name << " --> " << aName << endl ;
257     delete [] _Name ;
258   }
259   _Name = new char[strlen(aName)+1] ;
260   strcpy( _Name , aName ) ;
261   return true ;
262 }
263
264 SUPERV::SDate GraphBase::ComputingNode::FirstCreation () const {
265   cdebug << "GraphBase::ComputingNode::FirstCreation "
266          << "' _Name " << _Name << " "  << _FirstCreation << " "  
267          << _LastModification << endl ;
268   return _FirstCreation;
269 }
270
271 SUPERV::SDate GraphBase::ComputingNode::LastModification () const {
272   return _LastModification ;
273 }
274
275 bool GraphBase::ComputingNode::Kind(const SUPERV::KindOfNode aKind) {
276   _Kind = aKind ;
277   return true ;
278 }
279
280 void GraphBase::ComputingNode::FirstCreation(const SUPERV::SDate aDate ) {
281   _FirstCreation = aDate ;
282 }
283
284 void GraphBase::ComputingNode::LastModification(const SUPERV::SDate aDate ) {
285   _LastModification = aDate ;
286 }
287
288 bool GraphBase::ComputingNode::EditorRelease(const char * c){
289   if ( _EditorRelease && _EditorRelease != NULLSTRING )
290     delete _EditorRelease;
291   _EditorRelease = my_strdup(c);
292   return true ;
293 }
294
295 bool GraphBase::ComputingNode::Author(const char * a) {
296   if ( _Author && _Author != NULLSTRING )
297     delete _Author;
298   _Author = my_strdup(a);
299   return true ;
300 }
301
302 bool GraphBase::ComputingNode::Comment(const char *c) {
303   cdebug_in << "GraphBase::ComputingNode::Comment" << endl;
304   if ( _Comment != NULLSTRING )
305     delete [] _Comment;
306   _Comment = my_strdup(c);
307   cdebug_out << "GraphBase::ComputingNode::Comment" << endl;
308   return true ;
309 }
310
311 void GraphBase::ComputingNode::NodePort( const char * NodeName ,
312                                 const char * ServiceParameterName ,
313                                 char ** aNode , char ** aPort ) {
314   if ( strcmp( NodeName , Name() ) ) {
315     *aNode = my_strdup( NodeName ) ;
316     *aPort = my_strdup( ServiceParameterName ) ;
317   }
318   else {
319     char * BPort = strchr( ServiceParameterName , '\\' ) ;
320     if ( BPort ) {
321       int len = BPort - ServiceParameterName ;
322       *aNode = new char [ len + 1 ] ;
323       strncpy( *aNode , ServiceParameterName , len ) ;
324       (*aNode)[ len ] = '\0' ;
325       *aPort = my_strdup( &BPort[ 1 ] ) ;
326     }
327     else {
328       *aNode = my_strdup( NULLSTRING ) ;
329       *aPort = my_strdup( NULLSTRING ) ;
330     }
331   }
332 }
333
334 bool GraphBase::ComputingNode::IsLinked(const char * ToServiceParameterName ) {
335   bool RetVal = false ;
336   const GraphBase::InPort * thePort = GetInPort( ToServiceParameterName ) ;
337   if ( thePort ) {
338     RetVal = thePort->IsConnected() ;
339   }
340   else {
341     const GraphBase::OutPort * thePort = GetOutPort( ToServiceParameterName ) ;
342     if ( thePort ) {
343       RetVal = thePort->IsConnected() ;
344     }
345   }
346   return RetVal ;
347 }
348
349 bool GraphBase::ComputingNode::HasInput(const char * ToServiceParameterName ) {
350   bool RetVal = false ;
351   const GraphBase::InPort * thePort = GetInPort( ToServiceParameterName ) ;
352   if ( IsDataFlowNode() && thePort ) {
353     RetVal = true ;
354   }
355   else if ( thePort ) {
356     RetVal = thePort->IsDataConnected() ;
357   }
358   else {
359     const GraphBase::OutPort * thePort = GetOutPort( ToServiceParameterName ) ;
360     if ( thePort ) {
361       RetVal = thePort->IsDataConnected() ;
362     }
363   }
364   return RetVal ;
365 }
366
367 GraphBase::SNode * GraphBase::ComputingNode::GetInfo() {
368   cdebug_in << "GraphBase::ComputingNode::GetInfo" << endl;
369   GraphBase::SNode * Info = new GraphBase::SNode ;
370 //  Info->theComponentName = ComponentName() ;
371 //  Info->theInterfaceName = InterfaceName() ;
372   Info->theName = Name() ;
373   Info->theKind = Kind() ;
374   Info->theService = *GetService() ;
375 //  Info->theListOfParameters = *GetListOfParameters() ;
376   Info->theFirstCreation = FirstCreation() ;
377   Info->theLastModification = LastModification() ;
378   Info->theEditorRelease = EditorRelease() ;
379   Info->theAuthor = Author() ;
380 //  Info->theContainer = Computer() ;
381   Info->theComment = Comment() ;
382   Info->theCoords.theX = GraphBase::ComputingNode::XCoordinate() ;
383   Info->theCoords.theY = GraphBase::ComputingNode::YCoordinate() ;
384   cdebug_out << "GraphBase::ComputingNode::GetInfo" << endl;
385   return Info ;
386 }
387
388 GraphBase::InPort * GraphBase::ComputingNode::AddInPort( const char * InputParameterName ,
389                                                 const char * InputParameterType ) {
390   return GraphBase::PortsOfNode::AddInPort( _ORB , NamePtr() ,
391                                             Kind() ,
392                                             InputParameterName ,
393                                             InputParameterType ,
394                                             _Graph_prof_debug , _Graph_fdebug ) ;
395 }
396 GraphBase::OutPort * GraphBase::ComputingNode::AddOutPort( const char * OutputParameterName ,
397                                                   const char * OutputParameterType ) {
398   return GraphBase::PortsOfNode::AddOutPort( _ORB , NamePtr() ,
399                                              Kind() ,
400                                              OutputParameterName ,
401                                              OutputParameterType ,
402                                              _Graph_prof_debug , _Graph_fdebug ) ;
403 }
404
405 void GraphBase::ComputingNode::AddLink( GraphBase::ComputingNode * ToNode ) {
406   int index = GetLinkedNodeIndex( ToNode->Name() ) ;
407   if ( index < 0 ) {
408     cdebug << Name() << "->GraphBase::ComputingNode::AddLinkedNode( " << ToNode->Name()
409            << " ) new LinkedNode " << endl ;
410     _LinkedNodes.resize( _LinkedNodesSize+1 ) ;
411     _LinkedInPortsNumber.resize( _LinkedNodesSize+1 ) ;
412     _LinkedNodes[ _LinkedNodesSize ] = ToNode ;
413     _LinkedInPortsNumber[ _LinkedNodesSize ] = 1 ;
414     SetLinkedNodeIndex( ToNode->Name() , _LinkedNodesSize ) ;
415     index = _LinkedNodesSize ;
416     _LinkedNodesSize++ ;
417   }
418   else {
419     cdebug << Name() << "->GraphBase::ComputingNode::AddLinkedNode( " << ToNode->Name()
420            << " ) old LinkedNode " << _LinkedNodes[index ]->Name() << endl ;
421     _LinkedInPortsNumber[ index ] += 1 ;
422   }
423   cdebug << Name() << "->GraphBase::ComputingNode::AddLinkedNode( " << ToNode->Name()
424          << " ) LinkedNodesSize " << _LinkedNodesSize << " [ " << index
425          << " ] _LinkedInPortsNumber " << _LinkedInPortsNumber[ index ]
426          << " ConnectedInPortsNumber " << ToNode->ConnectedInPortsNumber()
427          << " + 1 Service " << ServiceName() << endl ;
428   ToNode->IncrConnectedInPortsNumber() ;
429 }
430
431 void GraphBase::ComputingNode::RemoveLink( GraphBase::ComputingNode * ToNode ) {
432   int index = GetLinkedNodeIndex( ToNode->Name() ) ;
433   if ( index >= 0 ) {
434     cdebug << "GraphBase::ComputingNode::RemoveLink( to " << ToNode->Name() << " from "
435            << Name() << " index : " << index << " ConnectedInPortsNumber "
436            << ToNode->ConnectedInPortsNumber() - 1 << " LinkedInPortsNumber "
437            << _LinkedInPortsNumber[ index ] << " - 1" << endl ;
438     ToNode->DecrConnectedInPortsNumber() ;
439     _LinkedInPortsNumber[ index ] -= 1 ;
440     if ( _LinkedInPortsNumber[ index ] == 0 ) {
441       _LinkedNodesSize-- ;
442       cdebug << "GraphBase::ComputingNode::RemoveLink new LinkedNodesSize "
443              << _LinkedNodesSize << " " << ToNode->Name() << " removed from "
444              << " linkednodes of " << Name() << endl ;
445       int i ;
446       for ( i = index ; i < _LinkedNodesSize ; i++ ) {
447         _LinkedNodes[ i ] = _LinkedNodes[ i+1 ] ;
448         _LinkedInPortsNumber[ i ] =  _LinkedInPortsNumber[ i+1 ] ;
449         SetLinkedNodeIndex( _LinkedNodes[ i ]->Name() , i ) ;
450       }
451       DelLinkedNodeIndex( ToNode->Name() ) ;
452       _LinkedNodes.resize( _LinkedNodesSize+1 ) ;
453       _LinkedInPortsNumber.resize( _LinkedNodesSize+1 ) ;
454     }
455   }
456   else {
457     cdebug << " Error index " << index << endl ;
458   }
459 }
460
461 void GraphBase::ComputingNode::ReNameLink( const char* OldNodeName ,
462                                   const char* NewNodeName ) {
463   cdebug_in << "GraphBase::ComputingNode::ReNameLink (" << OldNodeName << " , "
464             << NewNodeName << ")" << endl;
465   int index = GetLinkedNodeIndex( OldNodeName ) ;
466   if ( index >= 0 ) {
467     _MapOfLinkedNodes.erase( OldNodeName ) ;
468     SetLinkedNodeIndex( NewNodeName , index ) ;
469   }
470   cdebug_out << "GraphBase::ComputingNode::ReNameLink" << endl ;
471 }
472
473 #if 0
474 const GraphBase::ListOfParameters * GraphBase::ComputingNode::GetListOfParameters() const {
475   GraphBase::ListOfParameters * aListOfParameters = new GraphBase::ListOfParameters ;
476   if ( IsInLineNode() || IsGOTONode() ) {
477     unsigned int i;
478     for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
479       const InPort * anInPort = GetNodeInPort( i ) ;
480       if ( anInPort->IsBus() ) {
481         int size = aListOfParameters->size() ;
482         aListOfParameters->resize( size + 1 ) ;
483         (*aListOfParameters)[size].theInParameter.Parametername = anInPort->PortName() ;
484         (*aListOfParameters)[size].theInParameter.Parametertype = anInPort->PortType() ;
485         const OutPort * anOutPort = GetNodeOutPort( anInPort->PortIndex() ) ;
486         (*aListOfParameters)[size].theOutParameter.Parametername = anOutPort->PortName() ;
487         (*aListOfParameters)[size].theOutParameter.Parametertype = anOutPort->PortType() ;
488       }
489     }
490   }
491   return aListOfParameters ;
492 }
493 #endif
494
495 bool GraphBase::ComputingNode::SaveXML( QDomDocument & Graph , QDomElement & info ,
496                                         const char * ComponentName ,
497                                         const char * InterfaceName ,
498                                         const char * Computer ,
499                                         const char * CoupledNode ,
500                                         const ListOfFuncName FuncNames ,
501                                         const ListOfPythonFunctions PythonFunctions ,
502                                         int XCoordinate , int YCoordinate ) const {
503   QDomElement node = Graph.createElement( "node" ) ;
504   info.appendChild( node ) ;
505   QDomElement componentname = Graph.createElement( "component-name" ) ;
506   QDomText aField ;
507   if ( strlen( ComponentName ) ) {
508 //    f << Tabs << "<component-name>" << ComponentName << "</component-name>"
509 //      << endl ;
510 //    componentname.setNodeValue( ComponentName ) ;
511     aField = Graph.createTextNode( ComponentName ) ;
512   }
513   else {
514 //    f << Tabs << "<component-name>?</component-name>" << endl ;
515 //    componentname.setNodeValue( "?" ) ;
516     aField = Graph.createTextNode( "?" ) ;
517   }
518   node.appendChild( componentname ) ;
519   componentname.appendChild( aField ) ;
520
521   QDomElement interfacename = Graph.createElement("interface-name") ;
522   if ( strlen( InterfaceName ) ) {
523 //    f << Tabs << "<interface-name>" << InterfaceName << "</interface-name>"
524 //      << endl ;
525 //    interfacename.setAttribute("name" , InterfaceName ) ;
526     aField = Graph.createTextNode( InterfaceName ) ;
527   }
528   else {
529 //    f << Tabs << "<interface-name>?</interface-name>" << endl ;
530 //    interfacename.setAttribute("name" , "?" ) ;
531     aField = Graph.createTextNode( "?" ) ;
532   }
533   node.appendChild(interfacename) ;
534   interfacename.appendChild( aField ) ;
535
536 //  f << Tabs << "<node-name>" << Name() << "</node-name>" << endl ;
537   QDomElement nodename = Graph.createElement("node-name") ;
538   aField = Graph.createTextNode( Name() ) ;
539   node.appendChild( nodename ) ;
540   nodename.appendChild( aField ) ;
541
542 //  f << Tabs << "<kind>" << (int ) Kind() << "</kind>" << endl ;
543   QDomElement kind = Graph.createElement( "kind" ) ;
544   QString aKind ;
545   aKind = aKind.setNum( Kind() ) ;
546   aField = Graph.createTextNode( aKind ) ;
547   node.appendChild( kind ) ;
548   kind.appendChild( aField ) ;
549
550   QDomElement couplednode = Graph.createElement("coupled-node") ;
551   if ( IsGOTONode() || IsLoopNode() || IsEndLoopNode() ||
552        IsSwitchNode() || IsEndSwitchNode() ) {
553 //    f << Tabs << "<coupled-node>" << CoupledNode << "</coupled-node>"
554 //      << endl ;
555     aField = Graph.createTextNode( CoupledNode ) ;
556   }
557   else {
558 //    f << Tabs << "<coupled-node>?</coupled-node>" << endl ;
559     aField = Graph.createTextNode( "?" ) ;
560   }
561   node.appendChild(couplednode) ;
562   couplednode.appendChild( aField ) ;
563
564 //  f << Tabs << "<service>" << endl ;
565   QDomElement service = Graph.createElement("service") ;
566   node.appendChild(service) ;
567   QDomElement servicename = Graph.createElement("service-name") ;
568   if ( strlen( ServiceName() ) ) {
569 //    f << Tabs << "    <service-name>" << ServiceName() << "</service-name>" << endl ;
570     aField = Graph.createTextNode( ServiceName() ) ;
571   }
572   else {
573 //    f << Tabs << "    <service-name>?</service-name>" << endl ;
574     aField = Graph.createTextNode( "?" ) ;
575   }
576   service.appendChild(servicename) ;
577   servicename.appendChild( aField ) ;
578
579 //  f << Tabs << "      <inParameter-list>" << endl ;
580   QDomElement inParameterlist = Graph.createElement("inParameter-list") ;
581   service.appendChild(inParameterlist) ;
582   unsigned int i;
583   for ( i = 0 ; i < ServiceInParameter().length() ; i++ ) {
584 //    f << Tabs << "            <inParameter>" << endl ;
585     QDomElement inParameter = Graph.createElement("inParameter") ;
586     inParameterlist.appendChild(inParameter) ;
587 //    f << Tabs << "                    <inParameter-type>"
588 //      << ServiceInParameter()[i].Parametertype << "</inParameter-type>"
589 //      << endl ;
590     QDomElement inParametertype = Graph.createElement("inParameter-type") ;
591     // mpv: Linux 8.0 compiler compatibility
592 //    aField = Graph.createTextNode( (char *)ServiceInParameter()[i].Parametertype ) ;
593     aField = Graph.createTextNode( strdup(ServiceInParameter()[i].Parametertype) ) ;
594     inParameter.appendChild(inParametertype) ;
595     inParametertype.appendChild( aField ) ;
596 //    f << Tabs << "                    <inParameter-name>"
597 //      << ServiceInParameter()[i].Parametername << "</inParameter-name>"
598 //      << endl ;
599     QDomElement inParametername = Graph.createElement("inParameter-name") ;
600     // mpv: Linux 8.0 compiler compatibility
601 //    aField = Graph.createTextNode( (char *) ServiceInParameter()[i].Parametername ) ;
602     aField = Graph.createTextNode( strdup(ServiceInParameter()[i].Parametername) ) ;
603     inParameter.appendChild(inParametername) ;
604     inParametername.appendChild( aField ) ;
605 //    f << Tabs << "            </inParameter>" << endl ;
606   }
607 //  f << Tabs << "      </inParameter-list>" << endl ;
608 //  f << Tabs << "      <outParameter-list>" << endl ;
609   QDomElement outParameterlist = Graph.createElement("outParameter-list") ;
610   service.appendChild(outParameterlist) ;
611   for ( i = 0 ; i < ServiceOutParameter().length() ; i++ ) {
612 //    f << Tabs << "            <outParameter>" << endl ;
613     QDomElement outParameter = Graph.createElement("outParameter") ;
614     outParameterlist.appendChild(outParameter) ;
615 //    f << Tabs << "                    <outParameter-type>"
616 //      << ServiceOutParameter()[i].Parametertype << "</outParameter-type>"
617 //      << endl ;
618     QDomElement outParametertype = Graph.createElement("outParameter-type") ;
619     // mpv: Linux 8.0 compiler compatibility
620 //    aField = Graph.createTextNode( (char *) ServiceOutParameter()[i].Parametertype ) ;
621     aField = Graph.createTextNode( strdup(ServiceOutParameter()[i].Parametertype) ) ;
622     outParameter.appendChild(outParametertype) ;
623     outParametertype.appendChild( aField ) ;
624 //    f << Tabs << "                    <outParameter-name>"
625 //      << ServiceOutParameter()[i].Parametername << "</outParameter-name>"
626 //      << endl ;
627     QDomElement outParametername = Graph.createElement("outParameter-name") ;
628     // mpv: Linux 8.0 compiler compatibility
629 //    aField = Graph.createTextNode( (char *) ServiceOutParameter()[i].Parametername ) ;
630     aField = Graph.createTextNode( strdup(ServiceOutParameter()[i].Parametername) ) ;
631     outParameter.appendChild(outParametername) ;
632     outParametername.appendChild( aField ) ;
633 //    f << Tabs << "            </outParameter>" << endl ;
634   }
635 //  f << Tabs << "      </outParameter-list>" << endl ;
636 //  f << Tabs << "</service>" << endl ;
637
638 //  f << Tabs << "<Parameter-list>" << endl ;
639   QDomElement Parameterlist = Graph.createElement("Parameter-list") ;
640   node.appendChild( Parameterlist ) ;
641 #if 0
642   if ( IsInLineNode() || IsGOTONode() ||
643        IsLoopNode() || IsEndLoopNode() ||
644        IsSwitchNode() || IsEndSwitchNode() ) {
645     unsigned int i;
646     for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
647       const InPort * anInPort = GetNodeInPort( i ) ;
648       if ( anInPort->IsBus() ) {
649         f << Tabs << "  <inParameter>" << endl ;
650         f << Tabs << "          <inParameter-type>"
651           << anInPort->PortType() << "</inParameter-type>"
652           << endl ;
653         f << Tabs << "          <inParameter-name>"
654           << anInPort->PortName() << "</inParameter-name>"
655           << endl ;
656         f << Tabs << "  </inParameter>" << endl ;
657         const OutPort * anOutPort = GetNodeOutPort( anInPort->PortIndex() ) ;
658         f << Tabs << "  <outParameter>" << endl ;
659         f << Tabs << "          <outParameter-type>"
660           << anOutPort->PortType() << "</outParameter-type>"
661           << endl ;
662         f << Tabs << "          <outParameter-name>"
663           << anOutPort->PortName() << "</outParameter-name>"
664           << endl ;
665         f << Tabs << "  </outParameter>" << endl ;
666       }
667     }
668   }
669 #endif
670 //  f << Tabs << "</Parameter-list>" << endl ;    
671
672 //  f << Tabs << "<PyFunction-list>" << endl ;
673   QDomElement PyFunctionlist = Graph.createElement("PyFunction-list") ;
674   node.appendChild( PyFunctionlist ) ;
675   for ( i = 0 ; i < PythonFunctions.size() ; i++ ) {
676 //    f << Tabs << "    <PyFunction>" << endl ;
677     QDomElement PyFunction = Graph.createElement("PyFunction") ;
678     PyFunctionlist.appendChild( PyFunction ) ;
679     int j ;
680     for ( j = 0 ; j < (*PythonFunctions[i]).length() ; j++ ) {
681       if ( j == 0 ) {
682 //        if ( i == 0 ) {
683 //          f << Tabs << "              <FuncName>" << FuncNames[i].c_str()
684 //            << "</FuncName>" << endl ;
685           QDomElement FuncName = Graph.createElement("FuncName") ;
686           aField = Graph.createTextNode( FuncNames[i].c_str() ) ;
687           PyFunction.appendChild( FuncName ) ;
688           FuncName.appendChild( aField ) ;
689 //      }
690 //        else if ( i == 1 ) {
691 //          f << Tabs << "              <FuncName>" << FuncNames[i].c_str()
692 //            << "</FuncName>" << endl ;
693 //      }
694 //        else if ( i == 2 ) {
695 //          f << Tabs << "              <FuncName>" << FuncNames[i].c_str()
696 //            << "</FuncName>" << endl ;
697 //      }
698       }
699 //      f << Tabs << "          <PyFunc>" << (*PythonFunctions[i])[j]
700 //        << "</PyFunc>" << endl ;
701       QDomElement PyFunc = Graph.createElement("PyFunc") ;
702       QDomCDATASection aCDATA ;
703       // mpv: Linux 8.0 compiler compatibility
704 //       char * aCDATAChar = (char *) (*PythonFunctions[i])[j] ;
705       char * aCDATAChar = strdup ((*PythonFunctions[i])[j]) ;
706       int i ;
707       for ( i = 0 ; i < strlen( aCDATAChar ) ; i++ ) {
708         if ( aCDATAChar[ i ] != ' ' ) {
709           break ;
710         }
711       }
712       if ( i == strlen( aCDATAChar ) ) {
713         aCDATA = Graph.createCDATASection( "?" ) ;
714       }
715       else {
716         aCDATA = Graph.createCDATASection( aCDATAChar ) ;
717       }
718       PyFunction.appendChild( PyFunc ) ;
719       PyFunc.appendChild( aCDATA ) ;
720     }
721 //    f << Tabs << "    </PyFunction>" << endl ;
722   }
723 //  f << Tabs << "</PyFunction-list>" << endl ;
724
725 //  f << Tabs << "<creation-date>" << FirstCreation() << "</creation-date>"
726 //    << endl ;
727   QDomElement creationdate = Graph.createElement("creation-date") ;
728   char fdate[30] ;
729   sprintf( fdate , "%d/%d/%d - %d:%d:%d" ,  FirstCreation().Day , FirstCreation().Month , FirstCreation().Year , FirstCreation().Hour , FirstCreation().Minute , FirstCreation().Second ) ;
730   aField = Graph.createTextNode( fdate ) ;
731   node.appendChild( creationdate ) ;
732   creationdate.appendChild( aField ) ;
733 //  f << Tabs << "<lastmodification-date>" << LastModification()
734 //    << "</lastmodification-date>" << endl ;
735   QDomElement lastmodificationdate = Graph.createElement("lastmodification-date") ;
736   char ldate[30] ;
737   sprintf( ldate , "%d/%d/%d - %d:%d:%d" , LastModification().Day , LastModification().Month , LastModification().Year , LastModification().Hour , LastModification().Minute , LastModification().Second ) ;
738   aField = Graph.createTextNode( ldate ) ;
739   node.appendChild( lastmodificationdate ) ;
740   lastmodificationdate.appendChild( aField ) ;
741 //  f << Tabs << "<editor-release>" << EditorRelease() << "</editor-release>"
742 //    << endl ;
743   QDomElement editorrelease = Graph.createElement("editor-release") ;
744   aField = Graph.createTextNode( EditorRelease() ) ;
745   node.appendChild( editorrelease ) ;
746   editorrelease.appendChild( aField ) ;
747   QDomElement author = Graph.createElement("author") ;
748   if ( strlen( Author() ) ) {
749 //    f << Tabs << "<author>" << Author() << "</author>" << endl ;
750     aField = Graph.createTextNode( Author() ) ;
751   }
752   else {
753 //    f << Tabs << "<author>?</author>" << endl ;
754     aField = Graph.createTextNode( "?" ) ;
755   }
756   node.appendChild( author ) ;
757   author.appendChild( aField ) ;
758   QDomElement container = Graph.createElement("container") ;
759   if ( IsFactoryNode() && strlen( Computer) ) {
760 //    f << Tabs << "<container>" << Computer << "</container>" << endl ;
761     aField = Graph.createTextNode( Computer ) ;
762   }
763   else {
764 //    f << Tabs << "<container>?</container>" << endl ;
765     aField = Graph.createTextNode( "?" ) ;
766   }
767   node.appendChild( container ) ;
768   container.appendChild( aField ) ;
769   QDomElement comment = Graph.createElement("comment") ;
770   if ( strlen( Comment() ) ) {
771 //    f << Tabs << "<comment>" << Comment() << "</comment>" << endl ;
772     aField = Graph.createTextNode( Comment() ) ;
773   }
774   else {
775 //    f << Tabs << "<comment>?</comment>" << endl ;
776     aField = Graph.createTextNode( "?" ) ;
777   }
778   node.appendChild( comment ) ;
779   comment.appendChild( aField ) ;
780 //  f << Tabs << "<x-position>" << XCoordinate << "</x-position>" << endl ;
781   QDomElement xposition = Graph.createElement("x-position") ;
782   QString aXCoordinate ;
783   aXCoordinate = aKind.setNum( XCoordinate ) ;
784   aField = Graph.createTextNode( aXCoordinate ) ;
785   node.appendChild( xposition ) ;
786   xposition.appendChild( aField ) ;
787 //  f << Tabs << "<y-position>" << YCoordinate << "</y-position>" << endl ;
788   QDomElement yposition = Graph.createElement("y-position") ;
789   QString aYCoordinate ;
790   aYCoordinate = aKind.setNum( YCoordinate ) ;
791   aField = Graph.createTextNode( aYCoordinate ) ;
792   node.appendChild( yposition ) ;
793   yposition.appendChild( aField ) ;
794   return true ;
795 }
796
797 bool GraphBase::ComputingNode::SavePY( ostream &f , const char * aGraphName ,
798                                        const char * ComponentName ,
799                                        const char * InterfaceName ,
800                                        const char * Computer ,
801                                        const GraphBase::InLineNode * aCoupledNode ,
802                                        const ListOfFuncName FuncNames ,
803                                        const ListOfPythonFunctions PythonFunctions ,
804                                        int XCoordinate , int YCoordinate ) const {
805   if ( IsDataFlowNode() ) {
806     f << Name() << " = Graph( '" << Name() << "' )" << endl ;
807   }
808   else if ( IsComputingNode() ) {
809     int i ;
810     f << Name() << "_ServiceinParameter = []" << endl ;
811     for ( i = 0 ; i < ServiceInParameter().length() ; i++ ) {
812       f << Name() << "_ServiceinParameter.append( SALOME_ModuleCatalog.ServicesParameter( '"
813         << ServiceInParameter()[i].Parametertype << "' , '"
814         << ServiceInParameter()[i].Parametername << "' ) )" << endl ;
815     }
816     f << Name() << "_ServiceoutParameter = []" << endl ;
817     for ( i = 0 ; i < ServiceOutParameter().length() ; i++ ) {
818       f << Name() << "_ServiceoutParameter.append( SALOME_ModuleCatalog.ServicesParameter( '"
819         << ServiceOutParameter()[i].Parametertype << "' , '"
820         << ServiceOutParameter()[i].Parametername << "' ) )" << endl ;
821     }
822     f << Name() << "_Service = SALOME_ModuleCatalog.Service( '" << ServiceName()
823       << "' , " << Name() << "_ServiceinParameter" << " , "
824       << Name() << "_ServiceoutParameter" << " , 0 )" << endl ;
825     f << Name() << " = " << aGraphName << ".CNode( " << Name() << "_Service" << " )"
826       << endl ;
827   }
828   else if ( IsFactoryNode() ) {
829     f << Name() << " = " << aGraphName << ".FNode( '" << ComponentName
830       << "' , '" << InterfaceName << "' , '" << ServiceName() << "' )"
831       << endl ;
832   }
833   else {
834     f << "Py" << Name() << " = []" << endl ;
835     int i ;
836     SUPERV::ListOfStrings aPyFunc ;
837     if ( PythonFunctions.size() ) {
838       aPyFunc = *PythonFunctions[0] ;
839       for ( i = 0 ; i < aPyFunc.length() ; i++ ) {
840         f << "Py" << Name() << ".append( '" << aPyFunc[i] << "' )" << endl ;
841       }
842     }
843     if ( IsInLineNode() ) {
844       f << Name() << " = " << aGraphName << ".INode( '" << FuncNames[0].c_str() << "' , Py"
845         << Name() << " )" << endl ;
846     }
847     else if ( IsGOTONode() ) {
848       if ( aCoupledNode ) {
849         f << Name() << " = " << aGraphName << ".GNode( '" << FuncNames[0].c_str() << "' , Py"
850           << Name() << " , '" << aCoupledNode->Name() << "' )" << endl ;
851       }
852       else {
853         f << Name() << " = " << aGraphName << ".GNode( '" << FuncNames[0].c_str() << "' , Py"
854           << Name() << " , '' )" << endl ;
855       }
856     }
857     else {
858 //      char * EndName = NULL ;
859 //      EndName = new char[ 3 + strlen( Name() ) + 1 ] ;
860 //      strcpy( EndName , "End" ) ;
861 //      strcat( EndName , Name() ) ;
862       char * EndName = aCoupledNode->Name() ;
863       if ( IsLoopNode() ) {
864         SUPERV::ListOfStrings aPyMore = *PythonFunctions[1] ;
865         SUPERV::ListOfStrings aPyNext = *PythonFunctions[2] ;
866         f << "PyMore" << Name() << " = []" << endl ;
867         for ( i = 0 ; i < aPyMore.length() ; i++ ) {
868           f << "PyMore" << Name() << ".append( '" << aPyMore[i] << "' )" << endl ;
869         }
870         f << "PyNext" << Name() << " = []" << endl ;
871         for ( i = 0 ; i < aPyNext.length() ; i++ ) {
872           f << "PyNext" << Name() << ".append( '" << aPyNext[i] << "' )" << endl ;
873         }
874         f << Name() << "," << EndName << " = " << aGraphName << ".LNode( '"
875           << FuncNames[0].c_str() << "' , Py" << Name() << " , '"
876           << FuncNames[1].c_str() << "' , PyMore" << Name()
877           << " , '" << FuncNames[2].c_str() << "' , PyNext"
878           << Name() << " )" << endl ;
879         f << EndName << ".SetName( '" << aCoupledNode->Name() << "' )" << endl ;
880         f << EndName << ".SetAuthor( '" << aCoupledNode->Author() << "' )" << endl ;
881         f << EndName << ".SetComment( '" << aCoupledNode->Comment() << "' )" << endl ;
882         f << EndName << ".Coords( " << aCoupledNode->XCoordinate() << " , "
883           << aCoupledNode->YCoordinate() << " )" << endl ;
884       }
885       else if ( IsSwitchNode() ) {
886         f << Name() << "," << EndName << " = " << aGraphName << ".SNode( '"
887           << FuncNames[0].c_str() << "' , Py" << Name() << " )" << endl ;
888         f << EndName << ".SetName( '" << aCoupledNode->Name() << "' )" << endl ;
889         f << EndName << ".SetAuthor( '" << aCoupledNode->Author() << "' )" << endl ;
890         f << EndName << ".SetComment( '" << aCoupledNode->Comment() << "' )" << endl ;
891         f << EndName << ".Coords( " << aCoupledNode->XCoordinate() << " , "
892           << aCoupledNode->YCoordinate() << " )" << endl ;
893         SUPERV::ListOfStrings aPyFunc = *aCoupledNode->PythonFunction() ;
894         f << "Py" << aCoupledNode->Name() << " = []" << endl ;
895         for ( i = 0 ; i < aPyFunc.length() ; i++ ) {
896           f << "Py" << aCoupledNode->Name() << ".append( '" << aPyFunc[i] << "' )"
897             << endl ;
898         }
899         f << EndName << ".SetPyFunction( 'End" << FuncNames[0].c_str() << "' , Py" << aCoupledNode->Name() << " )" << endl ;
900         for ( i = 0 ; i < aCoupledNode->GetNodeInPortsSize() ; i++ ) {
901           const GraphBase::InPort * anInPort = aCoupledNode->GetNodeInPort(i) ;
902           if ( anInPort->IsInLine() || anInPort->IsEndSwitch() ) {
903             f << EndName << ".InPort( '" << anInPort->PortName()
904               << "' , '" << anInPort->PortType() << "' )" << endl ;
905           }
906         }
907         for ( i = 0 ; i < aCoupledNode->GetNodeOutPortsSize() ; i++ ) {
908           const GraphBase::OutPort * anOutPort = aCoupledNode->GetNodeOutPort(i) ;
909           if ( anOutPort->IsInLine() ) {
910             f << EndName << ".OutPort( '" << anOutPort->PortName()
911               << "' , '" << anOutPort->PortType() << "' )" << endl ;
912           }
913         }
914       }
915       delete [] EndName ;
916     }
917     for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
918       const GraphBase::InPort * anInPort = GetNodeInPort(i) ;
919       if ( anInPort->IsInLine() ) {
920         f << Name() << ".InPort( '" << anInPort->PortName() << "' , '"
921           << anInPort->PortType() << "' )" << endl ;
922       }
923     }
924     for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
925       const GraphBase::OutPort * anOutPort = GetNodeOutPort(i) ;
926       if ( anOutPort->IsInLine() || anOutPort->IsSwitch() ) {
927         f << Name() << ".OutPort( '" << anOutPort->PortName()
928           << "' , '" << anOutPort->PortType() << "' )" << endl ;
929       }
930     }
931   }
932
933   f << Name() << ".SetName( '" << Name() << "' )" << endl ;
934   f << Name() << ".SetAuthor( '" << Author() << "' )" << endl ;
935   if ( IsFactoryNode() ) {
936     f << Name() << ".SetContainer( '" << Computer << "' )" << endl ;
937   }
938   f << Name() << ".SetComment( '" << Comment() << "' )" << endl ;
939   f << Name() << ".Coords( " << XCoordinate << " , " << YCoordinate << " )" << endl ;
940
941 #if 0
942   if ( IsLoopNode() || IsSwitchNode() ) {
943     f << EndName << ".SetName( '" << CoupledNode
944       << "' )" << endl ;
945     f << EndName << ".SetAuthor( '" << CoupledNode->Author()
946       << "' )" << endl ;
947     f << EndName << ".SetComment( '" << CoupledNode->Comment()
948       << "' )" << endl ;
949     f << EndName << ".Coords( " << CoupledNode->XCoordinate() << " , "
950       << CoupledNode->YCoordinate() << " )" << endl ;
951     unsigned int i;
952     for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
953       const InPort * anInPort = GetNodeInPort( i ) ;
954       if ( anInPort->IsBus() ) {
955         const OutPort * anOutPort = GetNodeOutPort( anInPort->PortIndex() ) ;
956         f << Name() << ".BusPorts( '" << anInPort->PortName() << "' , '"
957           << anInPort->PortType() << "' , '" << anOutPort->PortName()
958           << "' , '" << anOutPort->PortType() << "' )" << endl ;
959       }
960     }
961   }
962 #endif
963   return true ;
964 }
965
966 void GraphBase::ComputingNode::NodeInfo(ostrstream & s) const {
967   int i ;
968   s << *this ;
969   ListPorts( s , true ) ;
970   s << ends ;
971 }
972
973 ostream & operator<< (ostream & f,const GraphBase::ComputingNode & G) {
974 //  f << "ComponentName    " << G.ComponentName() << endl ;
975   if ( G.IsComputingNode() )
976     f << "NodeName         " << G.Name() << endl ;
977   else
978     f << "DataFlowName     " << G.Name() << endl ;
979   f << "Kind             " << G.Kind() << endl ;
980   f << "Service          " << *G.GetService() ;
981   f << "FirstCreation    " << G.FirstCreation () << endl ;
982   f << "LastModification " << G.LastModification() << endl ;
983   f << "EditorRelease    " << G.EditorRelease() << endl ;
984   f << "Author           " << G.Author() << endl ;
985 //  f << "Computer         " << G.Computer() << endl ;
986   f << "Comment          " << G.Comment() << endl ;
987   f << endl ;
988   
989   return f;
990 }
991
992 void GraphBase::ComputingNode::ListLinks(ostream &f ) const {
993   int i ;
994   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
995     const GraphBase::OutPort* fromPort = GetNodeOutPort( i ) ;
996     if ( fromPort->IsPortConnected() ) {
997       int j ;
998       for ( j = 0 ; j < fromPort->InPortsSize() ; j++ ) {
999         if ( j == 0 )
1000           f << "FromNode " << Name() << endl ;
1001         f << "         FromServiceParameterName "
1002           << fromPort->GetServicesParameter().Parametername ;
1003         const GraphBase::InPort* toPort = fromPort->InPorts( j ) ;
1004         f << " ToNode " << toPort->NodeName() ;
1005         f << " ToServiceParameterName "
1006           << toPort->GetServicesParameter().Parametername;
1007         f << " Value " ;
1008         fromPort->StringValue( f ) ;
1009         f << endl ;
1010       }
1011     }
1012   }
1013 }
1014
1015 ostream & operator<< (ostream &fOut,const SUPERV::SDate &D) {
1016 //  cdebug_in << "operator<< GraphEditor::Date" << endl;
1017
1018   fOut  << D.Day << "/" 
1019         << D.Month << "/" 
1020         << D.Year << " - " 
1021         << D.Hour << ":" 
1022         << D.Minute <<  ":"  
1023         << D.Second;
1024
1025 //  cdebug_out << "operator<< GraphEditor::Date" << endl;
1026   return fOut;
1027 }
1028