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