Salome HOME
PR: merge from branch BR_UnitTests tag mergeto_trunk_17oct05
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_Study.cxx
1 //  File   : SALOMEDSImpl_Study.cxx
2 //  Author : Sergey RUIN
3 //  Module : SALOME
4
5
6 #include "SALOMEDSImpl_Study.hxx"
7
8 using namespace std;
9
10 #include <TColStd_SequenceOfExtendedString.hxx>
11 #include <TCollection_ExtendedString.hxx>
12
13 #include <TColStd_HSequenceOfAsciiString.hxx>
14 #include <TDocStd_Application.hxx>
15 #include <TDocStd_Owner.hxx>
16 #include <TDF_LabelList.hxx>
17 #include <TDF_ListIteratorOfLabelList.hxx>
18 #include <CDM_Document.hxx>
19 #include <CDM_Application.hxx>
20 #include <TDF_ChildIDIterator.hxx>
21 #include <TDF_ChildIterator.hxx>
22 #include <TDF_AttributeIterator.hxx>
23
24 #include "SALOMEDSImpl_ChildNodeIterator.hxx"
25 #include "SALOMEDSImpl_Attributes.hxx"
26 #include "SALOMEDSImpl_UseCaseIterator.hxx"
27 #include "SALOMEDSImpl_AttributeReference.hxx"
28 #include "SALOMEDSImpl_StudyHandle.hxx"
29 #include "SALOMEDSImpl_Tool.hxx"
30
31 IMPLEMENT_STANDARD_HANDLE( SALOMEDSImpl_Study, MMgt_TShared )
32 IMPLEMENT_STANDARD_RTTIEXT( SALOMEDSImpl_Study, MMgt_TShared )
33
34 #define DIRECTORYID       16661
35 #define FILELOCALID       26662
36 #define FILEID            "FILE: "
37
38 //============================================================================
39 /*! Function : SALOMEDSImpl_Study
40  *  Purpose  : SALOMEDSImpl_Study constructor
41  */
42 //============================================================================
43 SALOMEDSImpl_Study::SALOMEDSImpl_Study(const Handle(TDocStd_Document)& doc,
44                                        const TCollection_AsciiString& study_name)
45 {
46   doc->SetUndoLimit(1); // mpv (IPAL9237): if there is no undo limit, operations mechanism couldn't work
47   _name = study_name;
48   _doc = doc;
49   _Saved = false ;
50   _URL = "";
51   _StudyId = -1;
52   _autoFill = true;
53   myNbPostponed.Append(0);
54   myNbUndos = 0;
55   _errorCode = "";
56   _useCaseBuilder = new SALOMEDSImpl_UseCaseBuilder(_doc);
57   _builder = new SALOMEDSImpl_StudyBuilder(this);
58   _cb = new SALOMEDSImpl_Callback(_useCaseBuilder);
59   //Put on the root label a StudyHandle attribute to store the address of this object
60   //It will be used to retrieve the study object by TDF_Label that belongs to the study
61   SALOMEDSImpl_StudyHandle::Set(_doc->Main().Root(), this);
62 }
63
64
65 //============================================================================
66 /*! Function : ~SALOMEDSImpl_Study
67  *  Purpose  : SALOMEDSImpl_Study destructor
68  */
69 //============================================================================
70 SALOMEDSImpl_Study::~SALOMEDSImpl_Study()
71 {}
72
73 //============================================================================
74 /*! Function : GetPersistentReference
75  *  Purpose  : Get persistent reference of study (idem URL())
76  */
77 //============================================================================
78 TCollection_AsciiString SALOMEDSImpl_Study::GetPersistentReference()
79 {
80   _errorCode = "";
81   return URL();
82 }
83 //============================================================================
84 /*! Function : GetTransientReference
85  *  Purpose  : Get IOR of the Study (registred in OCAF document in doc->Root)
86  */
87 //============================================================================
88 TCollection_AsciiString SALOMEDSImpl_Study::GetTransientReference()
89 {
90   _errorCode = "";
91   TCollection_AsciiString IOR = "";
92
93   Handle(SALOMEDSImpl_AttributeIOR) Att;
94   TDF_Label _lab = _doc->GetData()->Root();
95   if (_lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID(),Att)) {
96     IOR = Att->Value();
97   }
98   else {
99     _errorCode = "IOR is empty";
100   }
101
102   return IOR;
103 }
104
105 void SALOMEDSImpl_Study::SetTransientReference(const TCollection_AsciiString& theIOR)
106 {
107   _errorCode = "";
108
109   Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
110   int aLocked = aProp->IsLocked();
111   if (aLocked) aProp->SetLocked(Standard_False);
112
113   // Assign the value of the IOR in the study->root
114   SALOMEDSImpl_AttributeIOR::Set(_doc->Main().Root(), theIOR);
115
116   if (aLocked) aProp->SetLocked(Standard_True);
117 }
118
119 //============================================================================
120 /*! Function : IsEmpty
121  *  Purpose  : Detect if study is empty
122  */
123 //============================================================================
124 bool SALOMEDSImpl_Study::IsEmpty()
125 {
126   _errorCode = "";
127   if (_doc.IsNull()) return true;
128   return _doc->IsEmpty();
129 }
130
131 //============================================================================
132 /*! Function : FindComponent
133  *  Purpose  : Find a Component with ComponentDataType = aComponentName
134  */
135 //============================================================================
136 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::FindComponent (const TCollection_AsciiString& aComponentName)
137 {
138   _errorCode = "";
139   bool _find = false;
140   TCollection_AsciiString name;
141   SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
142   Handle(SALOMEDSImpl_SComponent) compo;
143
144   for (; itcomp.More(); itcomp.Next()) {
145     Handle(SALOMEDSImpl_SComponent) SC = itcomp.Value();
146     name = SC->ComponentDataType();
147     if(aComponentName == name) {
148       _find = true;
149       return SC;
150     }
151   }
152
153   if(!_find)
154     {
155       _errorCode = "No component was found";
156       return NULL;
157     }
158   return compo;
159 }
160
161 //============================================================================
162 /*! Function : FindComponentID
163  *  Purpose  : Find a Component from it's ID
164  */
165 //============================================================================
166 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::FindComponentID(const TCollection_AsciiString& aComponentID)
167 {
168   _errorCode = "";
169
170   // Iterate on each components defined in the study
171   // Get the component ID and compare with aComponentID
172   bool _find = false;
173   TCollection_AsciiString ID;
174   Handle(SALOMEDSImpl_SComponent) compo;
175
176   SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
177   for (; itcomp.More(); itcomp.Next()) {
178     Handle(SALOMEDSImpl_SComponent) SC = itcomp.Value();
179     ID = SC->GetID();
180     if(aComponentID == ID)
181       {
182         // ComponentID found
183         _find = true;
184         compo = SC;
185       }
186   }
187   if(!_find)
188     {
189       _errorCode = "No component was found";
190       compo = NULL;
191     }
192
193   return compo;
194 }
195
196 //============================================================================
197 /*! Function : FindObject
198  *  Purpose  : Find an Object with SALOMEDSImpl_Name = anObjectName
199  */
200 //============================================================================
201 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObject(const TCollection_AsciiString& anObjectName)
202 {
203   _errorCode = "";
204
205   // Iterate to all components defined in the study
206   // After testing the component name, iterate in all objects defined under
207   // components (function _FindObject)
208   bool _find = false;
209   Handle(SALOMEDSImpl_SObject) RefSO = NULL;
210
211   SALOMEDSImpl_SComponentIterator it = NewComponentIterator();
212   for (; it.More();it.Next()){
213     if(!_find)
214       {
215         Handle(SALOMEDSImpl_SComponent) SC = it.Value();
216         if (SC->GetName() == anObjectName)
217         {
218             _find = true;
219             RefSO = SC;
220
221         }
222         if (!_find) RefSO =  _FindObject(SC, anObjectName, _find);
223       }
224   }
225   if(RefSO.IsNull()) _errorCode = "No object was found";
226   return RefSO;
227 }
228
229 //============================================================================
230 /*! Function : FindObjectID
231  *  Purpose  : Find an Object with ID = anObjectID
232  */
233 //============================================================================
234 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectID(const TCollection_AsciiString& anObjectID)
235 {
236   _errorCode = "";
237
238   // Convert aSO->GetID in TDF_Label.
239   TDF_Label Lab;
240   TDF_Tool::Label(_doc->Main().Data(), anObjectID, Lab);
241
242   if (Lab.IsNull()) {
243     _errorCode = "No label was found by ID";
244     return NULL;
245   }
246   return GetSObject(Lab);
247
248 }
249
250 //============================================================================
251 /*! Function : CreateObjectID
252  *  Purpose  : Creates an Object with ID = anObjectID
253  */
254 //============================================================================
255 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::CreateObjectID(const TCollection_AsciiString& anObjectID)
256 {
257   _errorCode = "";
258
259   // Convert aSO->GetID in TDF_Label.
260   TDF_Label Lab;
261   TDF_Tool::Label(_doc->Main().Data(), anObjectID, Lab, Standard_True);
262
263   if (Lab.IsNull()) {
264     _errorCode = "Can not create a label";
265     return NULL;
266   }
267   return GetSObject(Lab);
268
269 }
270
271 //============================================================================
272 /*! Function : FindObjectByName
273  *  Purpose  : Find Objects with SALOMEDSImpl_Name = anObjectName in a Component
274  *           : with ComponentDataType = aComponentName
275  */
276 //============================================================================
277 Handle(TColStd_HSequenceOfTransient) SALOMEDSImpl_Study::FindObjectByName(const TCollection_AsciiString& anObjectName,
278                                                                           const TCollection_AsciiString& aComponentName)
279 {
280   _errorCode = "";
281
282   Handle(TColStd_HSequenceOfTransient) listSO = new TColStd_HSequenceOfTransient();
283
284   Handle(SALOMEDSImpl_SComponent) compo = FindComponent(aComponentName) ;
285   if ( compo.IsNull() ) {
286     _errorCode = "Can not find the component";
287     return listSO;
288   }
289
290   // Iterate on each object and subobject of the component
291   // If objectName is found add it to the list of SObjects
292   TCollection_AsciiString childName ;
293
294   TCollection_AsciiString compoId = compo->GetID();
295   Handle(SALOMEDSImpl_ChildIterator) it = NewChildIterator(compo);
296   for ( ; it->More(); it->Next() ) {
297
298     Handle(SALOMEDSImpl_SObject) CSO = it->Value();
299     if ( CSO->GetName() == anObjectName ) {
300         /* add to list */
301         listSO->Append(CSO) ;
302     }
303
304     /* looks also for eventual children */
305     bool found = false ;
306     CSO = _FindObject( CSO, anObjectName, found ) ;
307     if( found) {
308       listSO->Append(CSO) ;
309     }
310   }
311
312   return listSO;
313 }
314
315
316
317 //============================================================================
318 /*! Function : FindObjectIOR
319  *  Purpose  : Find an Object with IOR = anObjectIOR
320  */
321 //============================================================================
322 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectIOR(const TCollection_AsciiString& anObjectIOR)
323 {
324   _errorCode = "";
325
326   // firstly searching in the datamap for optimization
327   if (myIORLabels.IsBound(anObjectIOR)) {
328     Handle(SALOMEDSImpl_SObject) aResult = GetSObject(myIORLabels.Find(anObjectIOR));
329     // 11 oct 2002: forbidden attributes must be checked here
330     if (!aResult->GetLabel().IsAttribute(SALOMEDSImpl_AttributeIOR::GetID())) {
331       myIORLabels.UnBind(anObjectIOR);
332     } else
333       return aResult;
334   }
335   // Iterate to all components defined in the study
336   // After testing the component name, iterate in all objects defined under
337   // components (function _FindObject)
338   bool _find = false;
339   Handle(SALOMEDSImpl_SObject) RefSO = NULL;
340
341   SALOMEDSImpl_SComponentIterator it = NewComponentIterator();
342   Handle(SALOMEDSImpl_SComponent) SC;
343   for (; it.More();it.Next()){
344     if(!_find)
345       {
346         SC = it.Value();
347         TCollection_AsciiString ior = SC->GetIOR();
348         if (ior != "")
349         {
350           if (ior ==  anObjectIOR)
351             {
352               _find = true;
353               RefSO = SC;
354             }
355         }
356         if (!_find)
357           RefSO =  _FindObjectIOR(SC, anObjectIOR, _find);
358       }
359   }
360
361   if(RefSO.IsNull()) _errorCode = "No object was found";
362   return RefSO;
363 }
364
365 //============================================================================
366 /*! Function : FindObjectByPath
367  *  Purpose  : Find an Object by its path = thePath
368  */
369 //============================================================================
370 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectByPath(const TCollection_AsciiString& thePath)
371 {
372   _errorCode = "";
373
374   TCollection_AsciiString aPath(thePath), aToken;
375   Handle(SALOMEDSImpl_SObject) aSO = NULL;
376   int i = 1, aLength = aPath.Length();
377   bool isRelative = false;
378
379   if(aLength == 0) {  //Empty path - return the current context
380     return GetSObject(_current);
381   }
382
383   if(aPath.Value(1) != '/')  //Relative path
384     isRelative = true;
385
386   TDF_ChildIterator anIterator;
387   TDF_Label aLabel;
388   Handle(SALOMEDSImpl_AttributeName) anAttr;
389
390   if(isRelative) {
391     if(_current.IsNull()) return NULL;
392     anIterator.Initialize(_current, Standard_False);
393   }
394   else {
395     if(aPath.Length() == 1 && aPath.Value(1) == '/') {    //Root
396       return GetSObject(_doc->Main());
397     }
398     anIterator.Initialize(_doc->Main(), Standard_False);
399   }
400
401   while(i <= aLength) {
402
403     aToken = aPath.Token("/", i);
404     if(aToken.Length() == 0) break;
405
406     for ( ; anIterator.More(); anIterator.Next() ) {
407       aLabel = anIterator.Value();
408       if(aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), anAttr)) {
409         if(anAttr->Value() == aToken) {
410           aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
411           if(aToken.Length() == 0) {  //The searched label is found (no part of the path is left)
412               return GetSObject(aLabel);
413           }
414
415           anIterator.Initialize(aLabel, Standard_False);
416           break;
417         }
418       }
419     }
420
421     i++;
422   }
423
424   if(aSO.IsNull()) _errorCode = "No object was found";
425   return aSO;
426 }
427
428 //============================================================================
429 /*! Function : GetObjectPath
430  *  Purpose  :
431  */
432 //============================================================================
433 TCollection_AsciiString SALOMEDSImpl_Study::GetObjectPath(const Handle(SALOMEDSImpl_SObject)& theObject)
434 {
435   _errorCode = "";
436
437   TCollection_AsciiString aPath("");
438   if(theObject.IsNull()) {
439     _errorCode = "Null object";
440     return aPath.ToCString();
441   }
442
443   TCollection_AsciiString aName = theObject->GetName();
444   if(!aName.IsEmpty() && aName != "" ) {
445     TCollection_AsciiString aValue((char*)aName.ToCString());
446     aValue.Prepend("/");
447     aValue += aPath;
448     aPath = aValue;
449     Handle(SALOMEDSImpl_SObject) aFather = theObject->GetFather();
450     if(!aFather.IsNull()) {
451        aName = aFather->GetName();
452        if(!aName.IsEmpty() && aName != "") {
453           aValue = (char*)GetObjectPath(aFather).ToCString();
454           aPath = aValue + aPath;
455        }
456     }
457   }
458
459   return aPath;
460 }
461
462
463 //============================================================================
464 /*! Function : GetObjectPathByIOR
465  *  Purpose  :
466  */
467 //============================================================================
468 TCollection_AsciiString SALOMEDSImpl_Study::GetObjectPathByIOR(const TCollection_AsciiString& theIOR)
469 {
470   _errorCode = "";
471
472   TCollection_AsciiString aPath;
473   Handle(SALOMEDSImpl_SObject) so = FindObjectIOR(theIOR);
474   if(so.IsNull()) {
475     _errorCode = "No SObject was found by IOR";
476     return aPath;
477   }
478
479   return GetObjectPath(so);
480 }
481
482
483 //============================================================================
484 /*! Function : SetContext
485  *  Purpose  : Sets the current context
486  */
487 //============================================================================
488 bool SALOMEDSImpl_Study::SetContext(const TCollection_AsciiString& thePath)
489 {
490   _errorCode = "";
491   if(thePath.IsEmpty()) {
492     _errorCode = "InvalidPath";
493     return false;
494   }
495
496   TCollection_AsciiString aPath(thePath), aContext("");
497   bool isInvalid = false;
498   Handle(SALOMEDSImpl_SObject) aSO;
499
500   if(aPath.Value(1) != '/') { //Relative path
501     aContext = GetContext();
502     aContext += '/';
503     aContext += aPath;
504   }
505   else
506     aContext = aPath;
507
508   try {
509     aSO = FindObjectByPath(aContext.ToCString());
510   }
511   catch( ... ) {
512     isInvalid = true;
513   }
514
515   if(isInvalid || aSO.IsNull()) {
516     _errorCode = "InvalidContext";
517     return false;
518   }
519
520   TDF_Label aLabel = aSO->GetLabel();
521   if(aLabel.IsNull()) {
522     _errorCode = "InvalidContext";
523     return false;
524   }
525   else
526     _current = aLabel;  //Set the current context
527
528   return true;
529 }
530
531 //============================================================================
532 /*! Function : GetContext
533  *  Purpose  : Gets the current context
534  */
535 //============================================================================
536 TCollection_AsciiString SALOMEDSImpl_Study::GetContext()
537 {
538   _errorCode = "";
539
540   if(_current.IsNull()) {
541     _errorCode = "InvaidContext";
542     return "";
543   }
544   Handle(SALOMEDSImpl_SObject) so = GetSObject(_current);
545   return GetObjectPath(so);
546 }
547
548 //============================================================================
549 /*! Function : GetObjectNames
550  *  Purpose  : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
551  */
552 //============================================================================
553 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetObjectNames(const TCollection_AsciiString& theContext)
554 {
555   _errorCode = "";
556
557   Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
558   TDF_Label aLabel;
559   if (theContext.IsEmpty()) {
560     if(_current.IsNull()) {
561       _errorCode = "InvalidContext";
562       return aResultSeq;
563     }
564     aLabel = _current;
565   } else {
566     TDF_Label aTmp = _current;
567     SetContext(theContext);
568     aLabel = _current;
569     _current = aTmp;
570   }
571   TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
572   for(; anIter.More(); anIter.Next()) {
573     TDF_Label aLabel = anIter.Value();
574     Handle(SALOMEDSImpl_AttributeName) aName;
575     if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
576   }
577
578   return aResultSeq;
579 }
580
581 //============================================================================
582 /*! Function : GetDirectoryNames
583  *  Purpose  : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
584  */
585 //============================================================================
586 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetDirectoryNames(const TCollection_AsciiString& theContext)
587 {
588   _errorCode = "";
589
590   Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
591   TDF_Label aLabel;
592   if (theContext.IsEmpty()) {
593     if(_current.IsNull()) {
594       _errorCode = "InvalidContext";
595       return aResultSeq;
596     }
597     aLabel = _current;
598   } else {
599     TDF_Label aTmp = _current;
600     SetContext(theContext);
601     aLabel = _current;
602     _current = aTmp;
603   }
604   TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
605   for(; anIter.More(); anIter.Next()) {
606     TDF_Label aLabel = anIter.Value();
607     Handle(SALOMEDSImpl_AttributeLocalID) anID;
608     if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
609       if (anID->Value() == DIRECTORYID) {
610         Handle(SALOMEDSImpl_AttributeName) aName;
611         if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) {
612           aResultSeq->Append(aName->Value());
613         }
614       }
615     }
616   }
617
618   return aResultSeq;
619 }
620
621 //============================================================================
622 /*! Function : GetFileNames
623  *  Purpose  : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
624  */
625 //============================================================================
626 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetFileNames(const TCollection_AsciiString& theContext)
627 {
628   _errorCode = "";
629
630   Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
631   TDF_Label aLabel;
632   if (theContext.IsEmpty()) {
633     if(_current.IsNull()) {
634       _errorCode = "InvalidContext";
635       return aResultSeq;
636     }
637     aLabel = _current;
638   } else {
639     TDF_Label aTmp = _current;
640     SetContext(theContext);
641     aLabel = _current;
642     _current = aTmp;
643   }
644   TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
645   for(; anIter.More(); anIter.Next()) {
646     TDF_Label aLabel = anIter.Value();
647     Handle(SALOMEDSImpl_AttributeLocalID) anID;
648     if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
649       if (anID->Value() == FILELOCALID) {
650         Handle(SALOMEDSImpl_AttributePersistentRef) aName;
651         if(aLabel.FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID(), aName)) {
652           TCollection_ExtendedString aFileName = aName->Value();
653           if(aFileName.Length() > 0)
654             aResultSeq->Append(aFileName.Split(strlen(FILEID)));
655         }
656       }
657     }
658   }
659
660   return aResultSeq;
661 }
662
663 //============================================================================
664 /*! Function : GetComponentNames
665  *  Purpose  : method to get all components names
666  */
667 //============================================================================
668 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetComponentNames(const TCollection_AsciiString& theContext)
669 {
670   _errorCode = "";
671
672   Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
673   TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
674   for(; anIter.More(); anIter.Next()) {
675     TDF_Label aLabel = anIter.Value();
676     Handle(SALOMEDSImpl_AttributeName) aName;
677     if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
678   }
679
680   return aResultSeq;
681 }
682
683 //============================================================================
684 /*! Function : NewChildIterator
685  *  Purpose  : Create a ChildIterator from an SObject
686  */
687 //============================================================================
688 Handle(SALOMEDSImpl_ChildIterator) SALOMEDSImpl_Study::NewChildIterator(const Handle(SALOMEDSImpl_SObject)& aSO)
689 {
690   _errorCode = "";
691   return new SALOMEDSImpl_ChildIterator(aSO);
692 }
693
694
695 //============================================================================
696 /*! Function : NewComponentIterator
697  *  Purpose  : Create a SComponentIterator
698  */
699 //============================================================================
700 SALOMEDSImpl_SComponentIterator SALOMEDSImpl_Study::NewComponentIterator()
701 {
702   _errorCode = "";
703   return SALOMEDSImpl_SComponentIterator(_doc);
704 }
705
706
707 //============================================================================
708 /*! Function : NewBuilder
709  *  Purpose  : Create a StudyBuilder
710  */
711 //============================================================================
712 Handle(SALOMEDSImpl_StudyBuilder) SALOMEDSImpl_Study::NewBuilder()
713 {
714   _errorCode = "";
715   if(_autoFill) {
716     _builder->SetOnAddSObject(_cb);
717     _builder->SetOnRemoveSObject(_cb);
718   }
719   return _builder;
720
721 }
722
723 //============================================================================
724 /*! Function : Name
725  *  Purpose  : get study name
726  */
727 //============================================================================
728 TCollection_AsciiString SALOMEDSImpl_Study::Name()
729 {
730   _errorCode = "";
731   return _name;
732 }
733
734 //============================================================================
735 /*! Function : Name
736  *  Purpose  : set study name
737  */
738 //============================================================================
739 void SALOMEDSImpl_Study::Name(const TCollection_AsciiString& name)
740 {
741   _errorCode = "";
742   _name = name;
743 }
744
745 //============================================================================
746 /*! Function : IsSaved
747  *  Purpose  : get if study has been saved
748  */
749 //============================================================================
750 bool SALOMEDSImpl_Study::IsSaved()
751 {
752   _errorCode = "";
753   return _Saved;
754 }
755
756 //============================================================================
757 /*! Function : IsSaved
758  *  Purpose  : set if study has been saved
759  */
760 //============================================================================
761 void SALOMEDSImpl_Study::IsSaved(bool save)
762 {
763   _errorCode = "";
764   _Saved = save;
765   if(save) _doc->UnModify();
766 }
767
768 //============================================================================
769 /*! Function : IsModified
770  *  Purpose  : Detect if a Study has been modified since it has been saved
771  */
772 //============================================================================
773 bool SALOMEDSImpl_Study::IsModified()
774 {
775   _errorCode = "";
776
777   // True if is modified
778   if (_doc->IsModified()) return true;
779
780   return false;
781 }
782
783 //============================================================================
784 /*! Function : URL
785  *  Purpose  : get URL of the study (persistent reference of the study)
786  */
787 //============================================================================
788 TCollection_AsciiString SALOMEDSImpl_Study::URL()
789 {
790   _errorCode = "";
791   return _URL;
792 }
793
794 //============================================================================
795 /*! Function : URL
796  *  Purpose  : set URL of the study (persistent reference of the study)
797  */
798 //============================================================================
799 void SALOMEDSImpl_Study::URL(const TCollection_AsciiString& url)
800 {
801   _errorCode = "";
802   _URL = url;
803
804   /*jfa: Now name of SALOMEDS study will correspond to name of SalomeApp study
805   TCollection_AsciiString tmp(_URL);
806
807   char *aName = (char*)tmp.ToCString();
808   char *adr = strtok(aName, "/");
809   while (adr)
810     {
811       aName = adr;
812       adr = strtok(NULL, "/");
813     }
814   Name(aName);*/
815   Name(url);
816 }
817
818
819 //============================================================================
820 /*! Function : _FindObject
821  *  Purpose  : Find an Object with SALOMEDSImpl_Name = anObjectName
822  */
823 //============================================================================
824 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::_FindObject(const Handle(SALOMEDSImpl_SObject)& SO,
825                                                              const TCollection_AsciiString& theObjectName,
826                                                              bool& _find)
827 {
828   if(SO.IsNull()) return NULL;
829
830   // Iterate on each objects and subobjects of the component
831   // If objectName find, stop the loop and get the object reference
832   Handle(SALOMEDSImpl_SObject) RefSO;
833   Handle(SALOMEDSImpl_AttributeName) anAttr;
834
835   TCollection_AsciiString soid = SO->GetID();
836   TDF_ChildIterator it(SO->GetLabel());
837   for (; it.More(); it.Next()){
838     if(!_find)
839       {
840         if (it.Value().FindAttribute(SALOMEDSImpl_AttributeName::GetID(), anAttr))
841         {
842           TCollection_AsciiString Val(anAttr->Value());
843           if (Val == theObjectName)
844             {
845               RefSO = GetSObject(it.Value());
846               _find = true;
847             }
848         }
849         if (!_find) RefSO = _FindObject(GetSObject(it.Value()), theObjectName, _find);
850       }
851   }
852   return RefSO;
853 }
854
855 //============================================================================
856 /*! Function : _FindObjectIOR
857  *  Purpose  : Find an Object with SALOMEDSImpl_IOR = anObjectIOR
858  */
859 //============================================================================
860 Handle(SALOMEDSImpl_SObject)
861 SALOMEDSImpl_Study::_FindObjectIOR(const Handle(SALOMEDSImpl_SObject)& SO,
862                                    const TCollection_AsciiString& theObjectIOR,
863                                    bool& _find)
864 {
865   if(SO.IsNull()) return NULL;
866
867   // Iterate on each objects and subobjects of the component
868   // If objectName find, stop the loop and get the object reference
869   Handle(SALOMEDSImpl_SObject) RefSO, aSO;
870   Handle(SALOMEDSImpl_AttributeIOR) anAttr;
871
872   TDF_ChildIterator it(SO->GetLabel());
873   for (; it.More();it.Next()){
874     if(!_find)
875       {
876         if (it.Value().FindAttribute(SALOMEDSImpl_AttributeIOR::GetID(), anAttr))
877         {
878           TCollection_AsciiString Val(anAttr->Value());
879           if (Val == theObjectIOR)
880             {
881               RefSO = GetSObject(it.Value());
882               _find = true;
883             }
884         }
885         aSO = GetSObject(it.Value());
886         if (!_find) RefSO =  _FindObjectIOR(aSO, theObjectIOR, _find);
887       }
888   }
889   return RefSO;
890 }
891
892 bool SALOMEDSImpl_Study::IsLocked()
893 {
894   _errorCode = "";
895   return GetProperties()->IsLocked();
896 }
897
898 int SALOMEDSImpl_Study::StudyId()
899 {
900   _errorCode = "";
901   return _StudyId;
902 }
903
904 void SALOMEDSImpl_Study::StudyId(int id)
905 {
906   _errorCode = "";
907   _StudyId = id;
908 }
909
910 void SALOMEDSImpl_Study::UpdateIORLabelMap(const TCollection_AsciiString& anIOR,const TCollection_AsciiString& anEntry)
911 {
912   _errorCode = "";
913   TDF_Label aLabel;
914   char* anEn = (char*)anEntry.ToCString();
915   char* IOR = (char*)anIOR.ToCString();
916   TDF_Tool::Label(_doc->GetData(),anEn, aLabel, Standard_True);
917   if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
918   myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
919 }
920
921 Handle(SALOMEDSImpl_Study) SALOMEDSImpl_Study::GetStudy(const TDF_Label& theLabel)
922 {
923   Handle(SALOMEDSImpl_StudyHandle) Att;
924   if (theLabel.Root().FindAttribute(SALOMEDSImpl_StudyHandle::GetID(),Att)) {
925     return Att->GetHandle();
926   }
927   return NULL;
928 }
929
930 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::SObject(const TDF_Label& theLabel)
931 {
932   return GetStudy(theLabel)->GetSObject(theLabel);
933 }
934
935 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::SComponent(const TDF_Label& theLabel)
936 {
937   return GetStudy(theLabel)->GetSComponent(theLabel);
938 }
939
940
941 void SALOMEDSImpl_Study::IORUpdated(const Handle(SALOMEDSImpl_AttributeIOR)& theAttribute)
942 {
943   TCollection_AsciiString aString;
944   TDF_Tool::Entry(theAttribute->Label(), aString);
945   GetStudy(theAttribute->Label())->UpdateIORLabelMap(theAttribute->Value(), aString);
946 }
947
948 Handle(TColStd_HSequenceOfTransient) SALOMEDSImpl_Study::FindDependances(const Handle(SALOMEDSImpl_SObject)& anObject)
949 {
950   _errorCode = "";
951   Handle(TColStd_HSequenceOfTransient) aSeq;
952
953   Handle(SALOMEDSImpl_AttributeTarget) aTarget;
954   if (anObject->GetLabel().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID(), aTarget)) {
955     return aTarget->Get();
956   }
957
958   return aSeq;
959 }
960
961
962 Handle(SALOMEDSImpl_AttributeStudyProperties) SALOMEDSImpl_Study::GetProperties()
963 {
964   _errorCode = "";
965   return SALOMEDSImpl_AttributeStudyProperties::Set(_doc->Main());
966 }
967
968 TCollection_AsciiString SALOMEDSImpl_Study::GetLastModificationDate()
969 {
970   _errorCode = "";
971   Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
972
973   Handle(TColStd_HSequenceOfExtendedString) aNames;
974   Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
975   aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
976
977   int aLastIndex = aNames->Length();
978   char aResult[20];
979   sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
980           (int)(aDays->Value(aLastIndex)),(int)(aMonths->Value(aLastIndex)), (int)(aYears->Value(aLastIndex)),
981           (int)(aHours->Value(aLastIndex)), (int)(aMinutes->Value(aLastIndex)));
982   TCollection_AsciiString aResStr (aResult);
983   return aResStr;
984 }
985
986 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetModificationsDate()
987 {
988   _errorCode = "";
989   Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
990
991   Handle(TColStd_HSequenceOfExtendedString) aNames;
992   Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
993   aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
994
995   int anIndex, aLength = aNames->Length();
996   Handle(TColStd_HSequenceOfAsciiString) aDates = new TColStd_HSequenceOfAsciiString;
997
998   for (anIndex = 2; anIndex <= aLength; anIndex++) {
999     char aDate[20];
1000     sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
1001             (int)(aDays->Value(anIndex)), (int)(aMonths->Value(anIndex)), (int)(aYears->Value(anIndex)),
1002             (int)(aHours->Value(anIndex)), (int)(aMinutes->Value(anIndex)));
1003     aDates->Append(aDate);
1004   }
1005   return aDates;
1006 }
1007
1008
1009
1010 //============================================================================
1011 /*! Function : GetUseCaseBuilder
1012  *  Purpose  : Returns a UseCase builder
1013  */
1014 //============================================================================
1015 Handle(SALOMEDSImpl_UseCaseBuilder) SALOMEDSImpl_Study::GetUseCaseBuilder()
1016 {
1017   _errorCode = "";
1018   return _useCaseBuilder;
1019 }
1020
1021
1022 //============================================================================
1023 /*! Function : Close
1024  *  Purpose  :
1025  */
1026 //============================================================================
1027 void SALOMEDSImpl_Study::Close()
1028 {
1029   _errorCode = "";
1030   Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1031   if(!anApp.IsNull()) anApp->Close(_doc);
1032   _doc.Nullify();
1033   _mapOfSO.Clear();
1034   _mapOfSCO.Clear();
1035 }
1036
1037 //============================================================================
1038 /*! Function : AddPostponed
1039  *  Purpose  :
1040  */
1041  //============================================================================
1042 void SALOMEDSImpl_Study::AddPostponed(const TCollection_AsciiString& theIOR)
1043 {
1044   _errorCode = "";
1045   if (!NewBuilder()->HasOpenCommand()) return;
1046   TCollection_AsciiString anIOR(theIOR);
1047   anIOR.Prepend("d");
1048   myPostponedIORs.Append(anIOR); // add prefix: deleted
1049   myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1050 }
1051
1052 //============================================================================
1053 /*! Function : AddCreatedPostponed
1054  *  Purpose  :
1055  */
1056  //============================================================================
1057 void SALOMEDSImpl_Study::AddCreatedPostponed(const TCollection_AsciiString& theIOR)
1058 {
1059   _errorCode = "";
1060   if (!NewBuilder()->HasOpenCommand()) return;
1061   TCollection_AsciiString anIOR(theIOR);
1062   anIOR.Prepend("c");
1063   myPostponedIORs.Append(anIOR); // add prefix: created
1064   myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1065 }
1066
1067 //============================================================================
1068 /*! Function : RemovePostponed
1069  *  Purpose  :
1070  */
1071 //============================================================================
1072 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::RemovePostponed(const int theUndoLimit)
1073 {
1074   _errorCode = "";
1075
1076   int anIndex;
1077   int anOld;
1078
1079   int aUndoLimit = theUndoLimit;
1080   if (theUndoLimit < 0) aUndoLimit = 0;
1081
1082   Handle(TColStd_HSequenceOfAsciiString) aSeq = new TColStd_HSequenceOfAsciiString;
1083
1084   if (myNbUndos > 0) { // remove undone
1085     anOld = 0;
1086     for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1087       anOld += myNbPostponed(anIndex);
1088     int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1089
1090     for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1091       TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1092       if (anIOR.Value(1) == 'c') {
1093         aSeq->Append(anIOR.Split(1).ToCString());
1094       }
1095     }
1096     if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1097     if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1098
1099     myNbUndos = 0;
1100   }
1101
1102   if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1103     anOld = 0;
1104     for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1105       anOld += myNbPostponed(anIndex);
1106     for(anIndex = 1; anIndex <= anOld; anIndex++) {
1107       TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1108       if (anIOR.Value(1) == 'd') {
1109         aSeq->Append(anIOR.Split(1).ToCString());
1110       }
1111     }
1112     if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1113     myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1114   }
1115
1116   if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1117     TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDSImpl_AttributeIOR::GetID(), Standard_True);
1118     for(; anIter.More(); anIter.Next()) {
1119       Handle(SALOMEDSImpl_AttributeIOR) anAttr = Handle(SALOMEDSImpl_AttributeIOR)::DownCast(anIter.Value());
1120       aSeq->Append(anAttr->Value());
1121     }
1122   } else myNbPostponed.Append(0);
1123
1124   return aSeq;
1125 }
1126
1127 //============================================================================
1128 /*! Function : UndoPostponed
1129  *  Purpose  :
1130  */
1131 //============================================================================
1132 void SALOMEDSImpl_Study::UndoPostponed(const int theWay)
1133 {
1134   _errorCode = "";
1135
1136   myNbUndos += theWay;
1137   // remove current postponed
1138   if (myNbPostponed.Last() > 0)
1139     myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1140   myNbPostponed(myNbPostponed.Length()) = 0;
1141 }
1142
1143
1144 //============================================================================
1145 /*! Function : GetSComponent
1146  *  Purpose  :
1147  */
1148 //============================================================================
1149 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TCollection_AsciiString& theEntry)
1150 {
1151   Handle(SALOMEDSImpl_SComponent) aSCO;
1152   if(_mapOfSCO.IsBound(theEntry))
1153     aSCO = Handle(SALOMEDSImpl_SComponent)::DownCast(_mapOfSCO.Find(theEntry));
1154   else {
1155     TDF_Label aLabel;
1156     TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1157     aSCO = new SALOMEDSImpl_SComponent(aLabel);
1158     _mapOfSCO.Bind(theEntry, aSCO);
1159   }
1160
1161   return aSCO;
1162 }
1163
1164 //============================================================================
1165 /*! Function : GetSComponent
1166  *  Purpose  :
1167  */
1168 //============================================================================
1169 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TDF_Label& theLabel)
1170 {
1171   TCollection_AsciiString anEntry;
1172   TDF_Tool::Entry(theLabel, anEntry);
1173   return GetSComponent(anEntry);
1174 }
1175
1176 //============================================================================
1177 /*! Function : GetSObject
1178  *  Purpose  :
1179  */
1180 //============================================================================
1181 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TCollection_AsciiString& theEntry)
1182 {
1183   Handle(SALOMEDSImpl_SObject) aSO;
1184   if(_mapOfSO.IsBound(theEntry))
1185     aSO = Handle(SALOMEDSImpl_SObject)::DownCast(_mapOfSO.Find(theEntry));
1186   else {
1187     TDF_Label aLabel;
1188     TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1189     aSO = new SALOMEDSImpl_SObject(aLabel);
1190     _mapOfSO.Bind(theEntry, aSO);
1191   }
1192
1193   return aSO;
1194 }
1195
1196 //============================================================================
1197 /*! Function : GetSObject
1198  *  Purpose  :
1199  */
1200 //============================================================================
1201 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TDF_Label& theLabel)
1202 {
1203   TCollection_AsciiString anEntry;
1204   TDF_Tool::Entry(theLabel, anEntry);
1205   return GetSObject(anEntry);
1206 }
1207
1208 //============================================================================
1209 /*! Function : GetAttribute
1210  *  Purpose  :
1211  */
1212 //============================================================================
1213 Handle(TDF_Attribute) SALOMEDSImpl_Study::GetAttribute(const TCollection_AsciiString& theEntry,
1214                                                        const TCollection_AsciiString& theType)
1215 {
1216   Handle(SALOMEDSImpl_SObject) aSO = GetSObject(theEntry);
1217   Handle(TDF_Attribute) anAttr;
1218   aSO->FindAttribute(anAttr, theType);
1219   return anAttr;
1220 }
1221
1222 //============================================================================
1223 /*! Function : DumpStudy
1224  *  Purpose  :
1225  */
1226 //============================================================================
1227 bool SALOMEDSImpl_Study::DumpStudy(const TCollection_AsciiString& thePath,
1228                                    const TCollection_AsciiString& theBaseName,
1229                                    bool isPublished,
1230                                    SALOMEDSImpl_DriverFactory* theFactory)
1231 {
1232   _errorCode = "";
1233
1234   if(theFactory == NULL) {
1235     _errorCode = "Null factory for creation of Engines";
1236     return false;
1237   }
1238
1239   TColStd_SequenceOfExtendedString aSeq;
1240   TCollection_AsciiString aCompType, aFactoryType;
1241
1242   //Build a list of all components in the Study
1243   SALOMEDSImpl_SComponentIterator itcomponent = NewComponentIterator();
1244
1245   for (; itcomponent.More(); itcomponent.Next()) {
1246     Handle(SALOMEDSImpl_SComponent) sco = itcomponent.Value();
1247     aCompType = sco->ComponentDataType();
1248     //GEOM and MED are independent components
1249     if(aCompType == "GEOM" || aCompType == "MED") aSeq.Prepend(TCollection_ExtendedString(aCompType));
1250     else aSeq.Append(TCollection_ExtendedString(aCompType));
1251   }
1252
1253 #ifdef WIN32
1254   TCollection_AsciiString aFileName=thePath+TCollection_AsciiString("\\")+theBaseName+TCollection_AsciiString(".py");
1255 #else
1256   TCollection_AsciiString aFileName=thePath+TCollection_AsciiString("/")+theBaseName+TCollection_AsciiString(".py");
1257 #endif
1258
1259   //Create a file that will contain a main Study script
1260   fstream fp;
1261   fp.open(aFileName.ToCString(), ios::out);
1262
1263 #ifdef WIN32
1264   bool isOpened = fp.is_open();
1265 #else
1266   bool isOpened = fp.rdbuf()->is_open();
1267 #endif
1268
1269   if(!isOpened) {
1270     _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1271     return false;
1272   }
1273
1274   TCollection_AsciiString aBatchModeScript = "salome";
1275
1276   //Output to the main Study script required Python modules import, set sys.path and add a creation of the study.
1277   fp << GetDumpStudyComment().ToCString() << endl << endl;
1278   fp << "import sys" << endl;
1279   fp << "import " << aBatchModeScript << "\n" << endl;
1280   fp << "sys.path.insert( 0, \'" << thePath << "\')\n" << endl;
1281
1282   Handle(TColStd_HSequenceOfAsciiString) aSeqOfFileNames = new TColStd_HSequenceOfAsciiString;
1283
1284   //Iterate all components and create the componponents specific scripts.
1285   bool isOk = true;
1286   int aLength = aSeq.Length();
1287   for(int i = 1; i <= aLength; i++) {
1288
1289     aCompType = aSeq.Value(i);
1290     Handle(SALOMEDSImpl_SComponent) sco = FindComponent(aCompType);
1291     SALOMEDSImpl_Driver* aDriver = NULL;
1292     // if there is an associated Engine call its method for saving
1293     TCollection_AsciiString IOREngine;
1294     try {
1295       if (!sco->ComponentIOR(IOREngine)) {
1296         if (!aCompType.IsEmpty()) {
1297
1298           aDriver = theFactory->GetDriverByType(aCompType);
1299
1300           if (aDriver != NULL) {
1301             Handle(SALOMEDSImpl_StudyBuilder) SB = NewBuilder();
1302             cout << "Before SB" << endl;
1303             if(!SB->LoadWith(sco, aDriver)) {
1304               _errorCode = SB->GetErrorCode();
1305               return false;
1306             }
1307             cout << "After SB" << endl;
1308           }
1309           else continue;
1310         }
1311       }
1312       else {
1313         aDriver = theFactory->GetDriverByIOR(IOREngine);
1314       }
1315     } catch(...) {
1316       _errorCode = "Can not restore information to dump it";
1317       return false;
1318     }
1319
1320     if(aDriver == NULL) continue;
1321
1322     bool isValidScript;
1323     long aStreamLength  = 0;
1324     unsigned char* aStream = aDriver->DumpPython(this, isPublished, isValidScript, aStreamLength);
1325     if ( !isValidScript )
1326       isOk = false;
1327
1328     //Create a file that will contain the component specific script
1329     fstream fp2;
1330 #ifdef WIN32
1331     aFileName=thePath+TCollection_AsciiString("\\");
1332 #else
1333     aFileName=thePath+TCollection_AsciiString("/");
1334 #endif
1335     TCollection_AsciiString aScriptName;
1336     aScriptName += theBaseName;
1337     aScriptName += "_";
1338     aScriptName += aCompType;
1339
1340     aFileName += aScriptName+ TCollection_AsciiString(".py");
1341     aSeqOfFileNames->Append(aFileName);
1342
1343     fp2.open(aFileName.ToCString(), ios::out);
1344
1345 #ifdef WIN32
1346     isOpened = fp.is_open();
1347 #else
1348     isOpened = fp.rdbuf()->is_open();
1349 #endif
1350
1351     if(!isOpened) {
1352       _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1353       SALOMEDSImpl_Tool::RemoveTemporaryFiles(thePath, aSeqOfFileNames, false);
1354       return false;
1355     }
1356
1357     //Output the Python script generated by the component in the newly created file.
1358     fp2 << aStream;
1359     fp2.close();
1360
1361     //Add to the main script a call to RebuildData of the generated by the component the Python script
1362     fp << "import " << aScriptName << endl;
1363     fp << aScriptName << ".RebuildData(" << aBatchModeScript << ".myStudy)" << endl;
1364   }
1365
1366   fp << "salome.sg.updateObjBrowser(1)" << endl;
1367
1368   fp.close();
1369   return isOk;
1370 }
1371
1372 //=======================================================================
1373 //function : GetDumpStudyComment
1374 //purpose  : return a header comment for a DumpStudy script
1375 //=======================================================================
1376
1377 TCollection_AsciiString SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
1378 {
1379   TCollection_AsciiString txt
1380     ("### This file is generated by SALOME automatically by dump python functionality");
1381   if ( theComponentName )
1382     txt += TCollection_AsciiString(" of ") + (char*) theComponentName + " component";
1383   return txt;
1384 }
1385
1386 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1387             fstream& fp,
1388             const TCollection_AsciiString& Tab,
1389             const Handle(SALOMEDSImpl_Study) theStudy);
1390 //============================================================================
1391 /*! Function : dump
1392  *  Purpose  :
1393  */
1394 //============================================================================
1395 void SALOMEDSImpl_Study::dump(const TCollection_AsciiString& theFileName)
1396 {
1397   //Create a file that will contain a main Study script
1398   fstream fp;
1399   fp.open(theFileName.ToCString(), ios::out);
1400
1401 #ifdef WIN32
1402   bool isOpened = fp.is_open();
1403 #else
1404   bool isOpened = fp.rdbuf()->is_open();
1405 #endif
1406
1407   if(!isOpened) {
1408     _errorCode = TCollection_AsciiString("Can't create a file ")+theFileName;
1409     cout << "### SALOMEDSImpl_Study::dump Error: " << _errorCode << endl;
1410     return;
1411   }
1412
1413   Handle(SALOMEDSImpl_SObject) aSO = FindObjectID("0:1");
1414   fp << "0:1" << endl;
1415   Handle(SALOMEDSImpl_ChildIterator) Itr = NewChildIterator(aSO);
1416   TCollection_AsciiString aTab("   ");
1417   for(; Itr->More(); Itr->Next()) {
1418     dumpSO(Itr->Value(), fp, aTab, this);
1419   }
1420
1421   fp.close();
1422 }
1423
1424
1425 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1426             fstream& fp,
1427             const TCollection_AsciiString& Tab,
1428             const Handle(SALOMEDSImpl_Study) theStudy)
1429 {
1430   TCollection_AsciiString aTab(Tab), anID(theSO->GetID());
1431   fp << aTab << anID << endl;
1432   TDF_AttributeIterator anItr(theSO->GetLabel());
1433   for(; anItr.More(); anItr.Next()) {
1434     Handle(SALOMEDSImpl_GenericAttribute) anAttr = Handle(SALOMEDSImpl_GenericAttribute)::DownCast(anItr.Value());
1435
1436     if(anAttr.IsNull()) {
1437       fp << Tab << "  -- " << anItr.Value()->DynamicType();
1438       continue;
1439     }
1440
1441     TCollection_AsciiString aType = anAttr->GetClassType();
1442     fp << Tab << "  -- " << aType;
1443
1444     if(aType == "AttributeReal") {
1445       fp << " : " << Handle(SALOMEDSImpl_AttributeReal)::DownCast(anAttr)->Value();
1446     }
1447     else if(aType == "AttributeInteger") {
1448       fp << " : " << Handle(SALOMEDSImpl_AttributeInteger)::DownCast(anAttr)->Value();
1449     }
1450     else if(aType ==  "AttributeName") {
1451       fp << " : " << Handle(SALOMEDSImpl_AttributeName)::DownCast(anAttr)->Value();
1452     }
1453     else if(aType == "AttributeComment") {
1454       fp << " : " << Handle(SALOMEDSImpl_AttributeComment)::DownCast(anAttr)->Value();
1455     }
1456     else if(aType == "AttributeReference") {
1457       fp << " : " << Handle(SALOMEDSImpl_AttributeReference)::DownCast(anAttr)->Save();
1458     }
1459     fp << endl;
1460   }
1461
1462   Handle(SALOMEDSImpl_ChildIterator) Itr = theStudy->NewChildIterator(theSO);
1463   TCollection_AsciiString aNewTab("   ");
1464   aNewTab+=aTab;
1465   for(; Itr->More(); Itr->Next()) {
1466     dumpSO(Itr->Value(), fp, aNewTab, theStudy);
1467   }
1468
1469   return;
1470 }
1471
1472 void SALOMEDSImpl_Study::Modify()
1473 {
1474   _errorCode = "";
1475   _doc->Modify();
1476 }