Salome HOME
PAL13000: Crash with 'import CALCULATOR_TEST_STUDY_WITHOUTIHM'
[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/ or email : webmaster.salome@opencascade.com
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     aLabel = _current;
581   } else {
582     TDF_Label aTmp = _current;
583     SetContext(theContext);
584     aLabel = _current;
585     _current = aTmp;
586   }
587   if (aLabel.IsNull()) {
588     _errorCode = "InvalidContext";
589     return aResultSeq;
590   }
591
592   TDF_ChildIterator anIter (aLabel, Standard_False); // iterate all subchildren at all sublevels
593   for (; anIter.More(); anIter.Next()) {
594     TDF_Label aLabel = anIter.Value();
595     Handle(SALOMEDSImpl_AttributeName) aName;
596     if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
597   }
598
599   return aResultSeq;
600 }
601
602 //============================================================================
603 /*! Function : GetDirectoryNames
604  *  Purpose  : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
605  */
606 //============================================================================
607 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetDirectoryNames(const TCollection_AsciiString& theContext)
608 {
609   _errorCode = "";
610
611   Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
612   TDF_Label aLabel;
613   if (theContext.IsEmpty()) {
614     aLabel = _current;
615   } else {
616     TDF_Label aTmp = _current;
617     SetContext(theContext);
618     aLabel = _current;
619     _current = aTmp;
620   }
621   if (aLabel.IsNull()) {
622     _errorCode = "InvalidContext";
623     return aResultSeq;
624   }
625
626   TDF_ChildIterator anIter (aLabel, Standard_False); // iterate first-level children at all sublevels
627   for (; anIter.More(); anIter.Next()) {
628     TDF_Label aLabel = anIter.Value();
629     Handle(SALOMEDSImpl_AttributeLocalID) anID;
630     if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
631       if (anID->Value() == DIRECTORYID) {
632         Handle(SALOMEDSImpl_AttributeName) aName;
633         if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) {
634           aResultSeq->Append(aName->Value());
635         }
636       }
637     }
638   }
639
640   return aResultSeq;
641 }
642
643 //============================================================================
644 /*! Function : GetFileNames
645  *  Purpose  : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
646  */
647 //============================================================================
648 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetFileNames(const TCollection_AsciiString& theContext)
649 {
650   _errorCode = "";
651
652   Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
653   TDF_Label aLabel;
654   if (theContext.IsEmpty()) {
655     aLabel = _current;
656   } else {
657     TDF_Label aTmp = _current;
658     SetContext(theContext);
659     aLabel = _current;
660     _current = aTmp;
661   }
662   if (aLabel.IsNull()) {
663     _errorCode = "InvalidContext";
664     return aResultSeq;
665   }
666
667   TDF_ChildIterator anIter (aLabel, Standard_False); // iterate all subchildren at all sublevels
668   for (; anIter.More(); anIter.Next()) {
669     TDF_Label aLabel = anIter.Value();
670     Handle(SALOMEDSImpl_AttributeLocalID) anID;
671     if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
672       if (anID->Value() == FILELOCALID) {
673         Handle(SALOMEDSImpl_AttributePersistentRef) aName;
674         if (aLabel.FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID(), aName)) {
675           TCollection_ExtendedString aFileName = aName->Value();
676           if (aFileName.Length() > 0)
677             aResultSeq->Append(aFileName.Split(strlen(FILEID)));
678         }
679       }
680     }
681   }
682
683   return aResultSeq;
684 }
685
686 //============================================================================
687 /*! Function : GetComponentNames
688  *  Purpose  : method to get all components names
689  */
690 //============================================================================
691 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetComponentNames(const TCollection_AsciiString& theContext)
692 {
693   _errorCode = "";
694
695   Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
696   TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
697   for(; anIter.More(); anIter.Next()) {
698     TDF_Label aLabel = anIter.Value();
699     Handle(SALOMEDSImpl_AttributeName) aName;
700     if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
701   }
702
703   return aResultSeq;
704 }
705
706 //============================================================================
707 /*! Function : NewChildIterator
708  *  Purpose  : Create a ChildIterator from an SObject
709  */
710 //============================================================================
711 Handle(SALOMEDSImpl_ChildIterator) SALOMEDSImpl_Study::NewChildIterator(const Handle(SALOMEDSImpl_SObject)& aSO)
712 {
713   _errorCode = "";
714   return new SALOMEDSImpl_ChildIterator(aSO);
715 }
716
717
718 //============================================================================
719 /*! Function : NewComponentIterator
720  *  Purpose  : Create a SComponentIterator
721  */
722 //============================================================================
723 SALOMEDSImpl_SComponentIterator SALOMEDSImpl_Study::NewComponentIterator()
724 {
725   _errorCode = "";
726   return SALOMEDSImpl_SComponentIterator(_doc);
727 }
728
729
730 //============================================================================
731 /*! Function : NewBuilder
732  *  Purpose  : Create a StudyBuilder
733  */
734 //============================================================================
735 Handle(SALOMEDSImpl_StudyBuilder) SALOMEDSImpl_Study::NewBuilder()
736 {
737   _errorCode = "";
738   if(_autoFill) {
739     _builder->SetOnAddSObject(_cb);
740     _builder->SetOnRemoveSObject(_cb);
741   }
742   return _builder;
743
744 }
745
746 //============================================================================
747 /*! Function : Name
748  *  Purpose  : get study name
749  */
750 //============================================================================
751 TCollection_AsciiString SALOMEDSImpl_Study::Name()
752 {
753   _errorCode = "";
754   return _name;
755 }
756
757 //============================================================================
758 /*! Function : Name
759  *  Purpose  : set study name
760  */
761 //============================================================================
762 void SALOMEDSImpl_Study::Name(const TCollection_AsciiString& name)
763 {
764   _errorCode = "";
765   _name = name;
766 }
767
768 //============================================================================
769 /*! Function : IsSaved
770  *  Purpose  : get if study has been saved
771  */
772 //============================================================================
773 bool SALOMEDSImpl_Study::IsSaved()
774 {
775   _errorCode = "";
776   return _Saved;
777 }
778
779 //============================================================================
780 /*! Function : IsSaved
781  *  Purpose  : set if study has been saved
782  */
783 //============================================================================
784 void SALOMEDSImpl_Study::IsSaved(bool save)
785 {
786   _errorCode = "";
787   _Saved = save;
788   if(save) _doc->UnModify();
789 }
790
791 //============================================================================
792 /*! Function : IsModified
793  *  Purpose  : Detect if a Study has been modified since it has been saved
794  */
795 //============================================================================
796 bool SALOMEDSImpl_Study::IsModified()
797 {
798   _errorCode = "";
799
800   // True if is modified
801   if (_doc->IsModified()) return true;
802
803   return false;
804 }
805
806 //============================================================================
807 /*! Function : URL
808  *  Purpose  : get URL of the study (persistent reference of the study)
809  */
810 //============================================================================
811 TCollection_AsciiString SALOMEDSImpl_Study::URL()
812 {
813   _errorCode = "";
814   return _URL;
815 }
816
817 //============================================================================
818 /*! Function : URL
819  *  Purpose  : set URL of the study (persistent reference of the study)
820  */
821 //============================================================================
822 void SALOMEDSImpl_Study::URL(const TCollection_AsciiString& url)
823 {
824   _errorCode = "";
825   _URL = url;
826
827   /*jfa: Now name of SALOMEDS study will correspond to name of SalomeApp study
828   TCollection_AsciiString tmp(_URL);
829
830   char *aName = (char*)tmp.ToCString();
831   char *adr = strtok(aName, "/");
832   while (adr)
833     {
834       aName = adr;
835       adr = strtok(NULL, "/");
836     }
837   Name(aName);*/
838   Name(url);
839 }
840
841
842 //============================================================================
843 /*! Function : _FindObject
844  *  Purpose  : Find an Object with SALOMEDSImpl_Name = anObjectName
845  */
846 //============================================================================
847 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::_FindObject(const Handle(SALOMEDSImpl_SObject)& SO,
848                                                              const TCollection_AsciiString& theObjectName,
849                                                              bool& _find)
850 {
851   if(SO.IsNull()) return NULL;
852
853   // Iterate on each objects and subobjects of the component
854   // If objectName find, stop the loop and get the object reference
855   Handle(SALOMEDSImpl_SObject) RefSO;
856   Handle(SALOMEDSImpl_AttributeName) anAttr;
857
858   TCollection_AsciiString soid = SO->GetID();
859   TDF_ChildIterator it(SO->GetLabel());
860   for (; it.More(); it.Next()){
861     if(!_find)
862       {
863         if (it.Value().FindAttribute(SALOMEDSImpl_AttributeName::GetID(), anAttr))
864         {
865           TCollection_AsciiString Val(anAttr->Value());
866           if (Val == theObjectName)
867             {
868               RefSO = GetSObject(it.Value());
869               _find = true;
870             }
871         }
872         if (!_find) RefSO = _FindObject(GetSObject(it.Value()), theObjectName, _find);
873       }
874   }
875   return RefSO;
876 }
877
878 //============================================================================
879 /*! Function : _FindObjectIOR
880  *  Purpose  : Find an Object with SALOMEDSImpl_IOR = anObjectIOR
881  */
882 //============================================================================
883 Handle(SALOMEDSImpl_SObject)
884 SALOMEDSImpl_Study::_FindObjectIOR(const Handle(SALOMEDSImpl_SObject)& SO,
885                                    const TCollection_AsciiString& theObjectIOR,
886                                    bool& _find)
887 {
888   if(SO.IsNull()) return NULL;
889
890   // Iterate on each objects and subobjects of the component
891   // If objectName find, stop the loop and get the object reference
892   Handle(SALOMEDSImpl_SObject) RefSO, aSO;
893   Handle(SALOMEDSImpl_AttributeIOR) anAttr;
894
895   TDF_ChildIterator it(SO->GetLabel());
896   for (; it.More();it.Next()){
897     if(!_find)
898       {
899         if (it.Value().FindAttribute(SALOMEDSImpl_AttributeIOR::GetID(), anAttr))
900         {
901           TCollection_AsciiString Val(anAttr->Value());
902           if (Val == theObjectIOR)
903             {
904               RefSO = GetSObject(it.Value());
905               _find = true;
906             }
907         }
908         aSO = GetSObject(it.Value());
909         if (!_find) RefSO =  _FindObjectIOR(aSO, theObjectIOR, _find);
910       }
911   }
912   return RefSO;
913 }
914
915 bool SALOMEDSImpl_Study::IsLocked()
916 {
917   _errorCode = "";
918   return GetProperties()->IsLocked();
919 }
920
921 int SALOMEDSImpl_Study::StudyId()
922 {
923   _errorCode = "";
924   return _StudyId;
925 }
926
927 void SALOMEDSImpl_Study::StudyId(int id)
928 {
929   _errorCode = "";
930   _StudyId = id;
931 }
932
933 void SALOMEDSImpl_Study::UpdateIORLabelMap(const TCollection_AsciiString& anIOR,const TCollection_AsciiString& anEntry)
934 {
935   _errorCode = "";
936   TDF_Label aLabel;
937   char* anEn = (char*)anEntry.ToCString();
938   char* IOR = (char*)anIOR.ToCString();
939   TDF_Tool::Label(_doc->GetData(),anEn, aLabel, Standard_True);
940   if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
941   myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
942 }
943
944 Handle(SALOMEDSImpl_Study) SALOMEDSImpl_Study::GetStudy(const TDF_Label& theLabel)
945 {
946   Handle(SALOMEDSImpl_StudyHandle) Att;
947   if (theLabel.Root().FindAttribute(SALOMEDSImpl_StudyHandle::GetID(),Att)) {
948     return Att->GetHandle();
949   }
950   return NULL;
951 }
952
953 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::SObject(const TDF_Label& theLabel)
954 {
955   return GetStudy(theLabel)->GetSObject(theLabel);
956 }
957
958 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::SComponent(const TDF_Label& theLabel)
959 {
960   return GetStudy(theLabel)->GetSComponent(theLabel);
961 }
962
963
964 void SALOMEDSImpl_Study::IORUpdated(const Handle(SALOMEDSImpl_AttributeIOR)& theAttribute)
965 {
966   TCollection_AsciiString aString;
967   TDF_Tool::Entry(theAttribute->Label(), aString);
968   GetStudy(theAttribute->Label())->UpdateIORLabelMap(theAttribute->Value(), aString);
969 }
970
971 Handle(TColStd_HSequenceOfTransient) SALOMEDSImpl_Study::FindDependances(const Handle(SALOMEDSImpl_SObject)& anObject)
972 {
973   _errorCode = "";
974   Handle(TColStd_HSequenceOfTransient) aSeq;
975
976   Handle(SALOMEDSImpl_AttributeTarget) aTarget;
977   if (anObject->GetLabel().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID(), aTarget)) {
978     return aTarget->Get();
979   }
980
981   return aSeq;
982 }
983
984
985 Handle(SALOMEDSImpl_AttributeStudyProperties) SALOMEDSImpl_Study::GetProperties()
986 {
987   _errorCode = "";
988   return SALOMEDSImpl_AttributeStudyProperties::Set(_doc->Main());
989 }
990
991 TCollection_AsciiString SALOMEDSImpl_Study::GetLastModificationDate()
992 {
993   _errorCode = "";
994   Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
995
996   Handle(TColStd_HSequenceOfExtendedString) aNames;
997   Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
998   aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
999
1000   int aLastIndex = aNames->Length();
1001   char aResult[20];
1002   sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
1003           (int)(aDays->Value(aLastIndex)),(int)(aMonths->Value(aLastIndex)), (int)(aYears->Value(aLastIndex)),
1004           (int)(aHours->Value(aLastIndex)), (int)(aMinutes->Value(aLastIndex)));
1005   TCollection_AsciiString aResStr (aResult);
1006   return aResStr;
1007 }
1008
1009 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetModificationsDate()
1010 {
1011   _errorCode = "";
1012   Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
1013
1014   Handle(TColStd_HSequenceOfExtendedString) aNames;
1015   Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
1016   aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
1017
1018   int anIndex, aLength = aNames->Length();
1019   Handle(TColStd_HSequenceOfAsciiString) aDates = new TColStd_HSequenceOfAsciiString;
1020
1021   for (anIndex = 2; anIndex <= aLength; anIndex++) {
1022     char aDate[20];
1023     sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
1024             (int)(aDays->Value(anIndex)), (int)(aMonths->Value(anIndex)), (int)(aYears->Value(anIndex)),
1025             (int)(aHours->Value(anIndex)), (int)(aMinutes->Value(anIndex)));
1026     aDates->Append(aDate);
1027   }
1028   return aDates;
1029 }
1030
1031
1032
1033 //============================================================================
1034 /*! Function : GetUseCaseBuilder
1035  *  Purpose  : Returns a UseCase builder
1036  */
1037 //============================================================================
1038 Handle(SALOMEDSImpl_UseCaseBuilder) SALOMEDSImpl_Study::GetUseCaseBuilder()
1039 {
1040   _errorCode = "";
1041   return _useCaseBuilder;
1042 }
1043
1044
1045 //============================================================================
1046 /*! Function : Close
1047  *  Purpose  :
1048  */
1049 //============================================================================
1050 void SALOMEDSImpl_Study::Close()
1051 {
1052   _errorCode = "";
1053   Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1054   if(!anApp.IsNull()) anApp->Close(_doc);
1055   _doc.Nullify();
1056   _mapOfSO.Clear();
1057   _mapOfSCO.Clear();
1058 }
1059
1060 //============================================================================
1061 /*! Function : AddPostponed
1062  *  Purpose  :
1063  */
1064  //============================================================================
1065 void SALOMEDSImpl_Study::AddPostponed(const TCollection_AsciiString& theIOR)
1066 {
1067   _errorCode = "";
1068   if (!NewBuilder()->HasOpenCommand()) return;
1069   TCollection_AsciiString anIOR(theIOR);
1070   anIOR.Prepend("d");
1071   myPostponedIORs.Append(anIOR); // add prefix: deleted
1072   myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1073 }
1074
1075 //============================================================================
1076 /*! Function : AddCreatedPostponed
1077  *  Purpose  :
1078  */
1079  //============================================================================
1080 void SALOMEDSImpl_Study::AddCreatedPostponed(const TCollection_AsciiString& theIOR)
1081 {
1082   _errorCode = "";
1083   if (!NewBuilder()->HasOpenCommand()) return;
1084   TCollection_AsciiString anIOR(theIOR);
1085   anIOR.Prepend("c");
1086   myPostponedIORs.Append(anIOR); // add prefix: created
1087   myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1088 }
1089
1090 //============================================================================
1091 /*! Function : RemovePostponed
1092  *  Purpose  :
1093  */
1094 //============================================================================
1095 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::RemovePostponed(const int theUndoLimit)
1096 {
1097   _errorCode = "";
1098
1099   int anIndex;
1100   int anOld;
1101
1102   int aUndoLimit = theUndoLimit;
1103   if (theUndoLimit < 0) aUndoLimit = 0;
1104
1105   Handle(TColStd_HSequenceOfAsciiString) aSeq = new TColStd_HSequenceOfAsciiString;
1106
1107   if (myNbUndos > 0) { // remove undone
1108     anOld = 0;
1109     for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1110       anOld += myNbPostponed(anIndex);
1111     int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1112
1113     for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1114       TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1115       if (anIOR.Value(1) == 'c') {
1116         aSeq->Append(anIOR.Split(1).ToCString());
1117       }
1118     }
1119     if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1120     if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1121
1122     myNbUndos = 0;
1123   }
1124
1125   if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1126     anOld = 0;
1127     for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1128       anOld += myNbPostponed(anIndex);
1129     for(anIndex = 1; anIndex <= anOld; anIndex++) {
1130       TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1131       if (anIOR.Value(1) == 'd') {
1132         aSeq->Append(anIOR.Split(1).ToCString());
1133       }
1134     }
1135     if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1136     myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1137   }
1138
1139   if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1140     TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDSImpl_AttributeIOR::GetID(), Standard_True);
1141     for(; anIter.More(); anIter.Next()) {
1142       Handle(SALOMEDSImpl_AttributeIOR) anAttr = Handle(SALOMEDSImpl_AttributeIOR)::DownCast(anIter.Value());
1143       aSeq->Append(anAttr->Value());
1144     }
1145   } else myNbPostponed.Append(0);
1146
1147   return aSeq;
1148 }
1149
1150 //============================================================================
1151 /*! Function : UndoPostponed
1152  *  Purpose  :
1153  */
1154 //============================================================================
1155 void SALOMEDSImpl_Study::UndoPostponed(const int theWay)
1156 {
1157   _errorCode = "";
1158
1159   myNbUndos += theWay;
1160   // remove current postponed
1161   if (myNbPostponed.Last() > 0)
1162     myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1163   myNbPostponed(myNbPostponed.Length()) = 0;
1164 }
1165
1166
1167 //============================================================================
1168 /*! Function : GetSComponent
1169  *  Purpose  :
1170  */
1171 //============================================================================
1172 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TCollection_AsciiString& theEntry)
1173 {
1174   Handle(SALOMEDSImpl_SComponent) aSCO;
1175   if(_mapOfSCO.IsBound(theEntry))
1176     aSCO = Handle(SALOMEDSImpl_SComponent)::DownCast(_mapOfSCO.Find(theEntry));
1177   else {
1178     TDF_Label aLabel;
1179     TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1180     aSCO = new SALOMEDSImpl_SComponent(aLabel);
1181     _mapOfSCO.Bind(theEntry, aSCO);
1182   }
1183
1184   return aSCO;
1185 }
1186
1187 //============================================================================
1188 /*! Function : GetSComponent
1189  *  Purpose  :
1190  */
1191 //============================================================================
1192 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TDF_Label& theLabel)
1193 {
1194   TCollection_AsciiString anEntry;
1195   TDF_Tool::Entry(theLabel, anEntry);
1196   return GetSComponent(anEntry);
1197 }
1198
1199 //============================================================================
1200 /*! Function : GetSObject
1201  *  Purpose  :
1202  */
1203 //============================================================================
1204 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TCollection_AsciiString& theEntry)
1205 {
1206   Handle(SALOMEDSImpl_SObject) aSO;
1207   if(_mapOfSO.IsBound(theEntry))
1208     aSO = Handle(SALOMEDSImpl_SObject)::DownCast(_mapOfSO.Find(theEntry));
1209   else {
1210     TDF_Label aLabel;
1211     TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1212     aSO = new SALOMEDSImpl_SObject(aLabel);
1213     _mapOfSO.Bind(theEntry, aSO);
1214   }
1215
1216   return aSO;
1217 }
1218
1219 //============================================================================
1220 /*! Function : GetSObject
1221  *  Purpose  :
1222  */
1223 //============================================================================
1224 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TDF_Label& theLabel)
1225 {
1226   TCollection_AsciiString anEntry;
1227   TDF_Tool::Entry(theLabel, anEntry);
1228   return GetSObject(anEntry);
1229 }
1230
1231 //============================================================================
1232 /*! Function : GetAttribute
1233  *  Purpose  :
1234  */
1235 //============================================================================
1236 Handle(TDF_Attribute) SALOMEDSImpl_Study::GetAttribute(const TCollection_AsciiString& theEntry,
1237                                                        const TCollection_AsciiString& theType)
1238 {
1239   Handle(SALOMEDSImpl_SObject) aSO = GetSObject(theEntry);
1240   Handle(TDF_Attribute) anAttr;
1241   aSO->FindAttribute(anAttr, theType);
1242   return anAttr;
1243 }
1244
1245 //============================================================================
1246 /*! Function : DumpStudy
1247  *  Purpose  :
1248  */
1249 //============================================================================
1250 bool SALOMEDSImpl_Study::DumpStudy(const TCollection_AsciiString& thePath,
1251                                    const TCollection_AsciiString& theBaseName,
1252                                    bool isPublished,
1253                                    SALOMEDSImpl_DriverFactory* theFactory)
1254 {
1255   _errorCode = "";
1256
1257   if(theFactory == NULL) {
1258     _errorCode = "Null factory for creation of Engines";
1259     return false;
1260   }
1261
1262   TColStd_SequenceOfExtendedString aSeq;
1263   TCollection_AsciiString aCompType, aFactoryType;
1264
1265   //Build a list of all components in the Study
1266   SALOMEDSImpl_SComponentIterator itcomponent = NewComponentIterator();
1267
1268   for (; itcomponent.More(); itcomponent.Next()) {
1269     Handle(SALOMEDSImpl_SComponent) sco = itcomponent.Value();
1270     aCompType = sco->ComponentDataType();
1271     //GEOM and MED are independent components
1272     if (aCompType == "GEOM" || aCompType == "MED")
1273       aSeq.Prepend(TCollection_ExtendedString(aCompType));
1274     else
1275       aSeq.Append(TCollection_ExtendedString(aCompType));
1276   }
1277
1278 #ifdef WIN32
1279   TCollection_AsciiString aFileName =
1280     thePath + TCollection_AsciiString("\\") + theBaseName + TCollection_AsciiString(".py");
1281 #else
1282   TCollection_AsciiString aFileName =
1283     thePath + TCollection_AsciiString("/")  + theBaseName + TCollection_AsciiString(".py");
1284 #endif
1285
1286   //Create a file that will contain a main Study script
1287   fstream fp;
1288   fp.open(aFileName.ToCString(), ios::out);
1289
1290 #ifdef WIN32
1291   bool isOpened = fp.is_open();
1292 #else
1293   bool isOpened = fp.rdbuf()->is_open();
1294 #endif
1295
1296   if(!isOpened) {
1297     _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1298     return false;
1299   }
1300
1301   TCollection_AsciiString aBatchModeScript = "salome";
1302
1303   //Output to the main Study script required Python modules import,
1304   //set sys.path and add a creation of the study.
1305   fp << GetDumpStudyComment().ToCString() << endl << endl;
1306   fp << "import sys" << endl;
1307   fp << "import " << aBatchModeScript << endl << endl;
1308
1309   fp << aBatchModeScript << ".salome_init()" << endl << endl;
1310
1311   fp << "sys.path.insert( 0, \'" << thePath << "\')" << endl << endl;
1312
1313
1314   //Check if it's necessary to dump visual parameters
1315   bool isDumpVisuals = SALOMEDSImpl_IParameters::isDumpPython(this);
1316   int lastSavePoint = -1;
1317   if(isDumpVisuals) {
1318     lastSavePoint = SALOMEDSImpl_IParameters::getLastSavePoint(this);
1319     if(lastSavePoint > 0) {
1320       fp << SALOMEDSImpl_IParameters::getStudyScript(this, lastSavePoint) << endl << endl;
1321     }
1322   }
1323   
1324
1325   Handle(TColStd_HSequenceOfAsciiString) aSeqOfFileNames = new TColStd_HSequenceOfAsciiString;
1326
1327   //Iterate all components and create the componponents specific scripts.
1328   bool isOk = true;
1329   int aLength = aSeq.Length();
1330   for(int i = 1; i <= aLength; i++) {
1331
1332     aCompType = aSeq.Value(i);
1333     Handle(SALOMEDSImpl_SComponent) sco = FindComponent(aCompType);
1334     SALOMEDSImpl_Driver* aDriver = NULL;
1335     // if there is an associated Engine call its method for saving
1336     TCollection_AsciiString IOREngine;
1337     try {
1338       if (!sco->ComponentIOR(IOREngine)) {
1339         if (!aCompType.IsEmpty()) {
1340
1341           aDriver = theFactory->GetDriverByType(aCompType);
1342
1343           if (aDriver != NULL) {
1344             Handle(SALOMEDSImpl_StudyBuilder) SB = NewBuilder();
1345             if(!SB->LoadWith(sco, aDriver)) {
1346               _errorCode = SB->GetErrorCode();
1347               return false;
1348             }
1349           }
1350           else continue;
1351         }
1352       }
1353       else {
1354         aDriver = theFactory->GetDriverByIOR(IOREngine);
1355       }
1356     } catch(...) {
1357       _errorCode = "Can not restore information to dump it";
1358       return false;
1359     }
1360
1361     if(aDriver == NULL) continue;
1362
1363     bool isValidScript;
1364     long aStreamLength  = 0;
1365     Handle(SALOMEDSImpl_TMPFile) aStream = aDriver->DumpPython(this, isPublished, isValidScript, aStreamLength);
1366     if ( !isValidScript )
1367       isOk = false;
1368
1369     //Create a file that will contain the component specific script
1370     fstream fp2;
1371 #ifdef WIN32
1372     aFileName=thePath+TCollection_AsciiString("\\");
1373 #else
1374     aFileName=thePath+TCollection_AsciiString("/");
1375 #endif
1376     TCollection_AsciiString aScriptName;
1377     aScriptName += theBaseName;
1378     aScriptName += "_";
1379     aScriptName += aCompType;
1380
1381     aFileName += aScriptName+ TCollection_AsciiString(".py");
1382     aSeqOfFileNames->Append(aFileName);
1383
1384     fp2.open(aFileName.ToCString(), ios::out);
1385
1386 #ifdef WIN32
1387     isOpened = fp2.is_open();
1388 #else
1389     isOpened = fp2.rdbuf()->is_open();
1390 #endif
1391
1392     if(!isOpened) {
1393       _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1394       SALOMEDSImpl_Tool::RemoveTemporaryFiles(thePath, aSeqOfFileNames, false);
1395       return false;
1396     }
1397
1398     //Output the Python script generated by the component in the newly created file.
1399     fp2 << aStream->Data();
1400     fp2.close();
1401
1402     //Add to the main script a call to RebuildData of the generated by the component the Python script
1403     fp << "import " << aScriptName << endl;
1404     fp << aScriptName << ".RebuildData(" << aBatchModeScript << ".myStudy)" << endl;
1405   }
1406
1407   fp << endl;
1408   fp << "if salome.sg.hasDesktop():" << endl;
1409   fp << "\tsalome.sg.updateObjBrowser(1)" << endl;
1410
1411   if(isDumpVisuals) { //Output the call to Session's method restoreVisualState
1412     fp << "\tiparameters.getSession().restoreVisualState(1)" << endl;
1413   }
1414
1415
1416   fp.close();
1417   return isOk;
1418 }
1419
1420 //=======================================================================
1421 //function : GetDumpStudyComment
1422 //purpose  : return a header comment for a DumpStudy script
1423 //=======================================================================
1424
1425 TCollection_AsciiString SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
1426 {
1427   TCollection_AsciiString txt
1428     ("### This file is generated by SALOME automatically by dump python functionality");
1429   if ( theComponentName )
1430     txt += TCollection_AsciiString(" of ") + (char*) theComponentName + " component";
1431   return txt;
1432 }
1433
1434 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1435             fstream& fp,
1436             const TCollection_AsciiString& Tab,
1437             const Handle(SALOMEDSImpl_Study) theStudy);
1438 //============================================================================
1439 /*! Function : dump
1440  *  Purpose  :
1441  */
1442 //============================================================================
1443 void SALOMEDSImpl_Study::dump(const TCollection_AsciiString& theFileName)
1444 {
1445   //Create a file that will contain a main Study script
1446   fstream fp;
1447   fp.open(theFileName.ToCString(), ios::out);
1448
1449 #ifdef WIN32
1450   bool isOpened = fp.is_open();
1451 #else
1452   bool isOpened = fp.rdbuf()->is_open();
1453 #endif
1454
1455   if(!isOpened) {
1456     _errorCode = TCollection_AsciiString("Can't create a file ")+theFileName;
1457     cout << "### SALOMEDSImpl_Study::dump Error: " << _errorCode << endl;
1458     return;
1459   }
1460
1461   Handle(SALOMEDSImpl_SObject) aSO = FindObjectID("0:1");
1462   fp << "0:1" << endl;
1463   Handle(SALOMEDSImpl_ChildIterator) Itr = NewChildIterator(aSO);
1464   TCollection_AsciiString aTab("   ");
1465   for(; Itr->More(); Itr->Next()) {
1466     dumpSO(Itr->Value(), fp, aTab, this);
1467   }
1468
1469   fp.close();
1470 }
1471
1472
1473 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1474             fstream& fp,
1475             const TCollection_AsciiString& Tab,
1476             const Handle(SALOMEDSImpl_Study) theStudy)
1477 {
1478   TCollection_AsciiString aTab(Tab), anID(theSO->GetID());
1479   fp << aTab << anID << endl;
1480   TDF_AttributeIterator anItr(theSO->GetLabel());
1481   for(; anItr.More(); anItr.Next()) {
1482     Handle(SALOMEDSImpl_GenericAttribute) anAttr = Handle(SALOMEDSImpl_GenericAttribute)::DownCast(anItr.Value());
1483
1484     if(anAttr.IsNull()) {
1485       fp << Tab << "  -- " << anItr.Value()->DynamicType();
1486       continue;
1487     }
1488
1489     TCollection_AsciiString aType = anAttr->GetClassType();
1490     fp << Tab << "  -- " << aType;
1491
1492     if(aType == "AttributeReal") {
1493       fp << " : " << Handle(SALOMEDSImpl_AttributeReal)::DownCast(anAttr)->Value();
1494     }
1495     else if(aType == "AttributeInteger") {
1496       fp << " : " << Handle(SALOMEDSImpl_AttributeInteger)::DownCast(anAttr)->Value();
1497     }
1498     else if(aType ==  "AttributeName") {
1499       fp << " : " << Handle(SALOMEDSImpl_AttributeName)::DownCast(anAttr)->Value();
1500     }
1501     else if(aType == "AttributeComment") {
1502       fp << " : " << Handle(SALOMEDSImpl_AttributeComment)::DownCast(anAttr)->Value();
1503     }
1504     else if(aType == "AttributeReference") {
1505       fp << " : " << Handle(SALOMEDSImpl_AttributeReference)::DownCast(anAttr)->Save();
1506     }
1507     fp << endl;
1508   }
1509
1510   Handle(SALOMEDSImpl_ChildIterator) Itr = theStudy->NewChildIterator(theSO);
1511   TCollection_AsciiString aNewTab("   ");
1512   aNewTab+=aTab;
1513   for(; Itr->More(); Itr->Next()) {
1514     dumpSO(Itr->Value(), fp, aNewTab, theStudy);
1515   }
1516
1517   return;
1518 }
1519
1520 void SALOMEDSImpl_Study::Modify()
1521 {
1522   _errorCode = "";
1523   _doc->Modify();
1524 }
1525
1526 //============================================================================
1527 /*! Function : 
1528  *  Purpose  :
1529  */
1530 //============================================================================
1531 Handle(SALOMEDSImpl_AttributeParameter) SALOMEDSImpl_Study::GetCommonParameters(const char* theID, int theSavePoint)
1532 {
1533   if (theSavePoint < 0) return NULL;
1534   Handle(SALOMEDSImpl_StudyBuilder) builder = NewBuilder();
1535   Handle(SALOMEDSImpl_SObject) so = FindComponent((char*)theID);
1536   if (so.IsNull()) so = builder->NewComponent((char*)theID);
1537   Handle(SALOMEDSImpl_AttributeParameter) attParam;
1538
1539   if (theSavePoint > 0) { // Try to find SObject that contains attribute parameter ...
1540     TDF_Label savePointLabel = so->GetLabel().FindChild( theSavePoint, /*create=*/0 );
1541     if ( !savePointLabel.IsNull() )
1542       so = GetSObject( savePointLabel );
1543     else // ... if it does not exist - create a new one
1544       so = builder->NewObjectToTag( so, theSavePoint );
1545   }
1546
1547   if (!so.IsNull()) {
1548     builder->FindAttribute(so, attParam, "AttributeParameter");
1549     if ( attParam.IsNull() ) { // first call of GetCommonParameters on "Interface Applicative" component
1550       Handle(TDF_Attribute) att = builder->FindOrCreateAttribute(so, "AttributeParameter");
1551       attParam = Handle(SALOMEDSImpl_AttributeParameter)::DownCast( att );
1552     }
1553   }
1554   return attParam;
1555 }
1556
1557 //============================================================================
1558 /*! Function : 
1559  *  Purpose  :
1560  */
1561 //============================================================================
1562 Handle(SALOMEDSImpl_AttributeParameter) SALOMEDSImpl_Study::GetModuleParameters(const char* theID, 
1563                                                                                 const char* theModuleName,
1564                                                                                 int theSavePoint)
1565 {
1566   if(theSavePoint <= 0) return NULL;
1567   Handle(SALOMEDSImpl_AttributeParameter) main_ap = GetCommonParameters(theID, theSavePoint);
1568   Handle(SALOMEDSImpl_SObject) main_so = main_ap->GetSObject();
1569   Handle(SALOMEDSImpl_AttributeParameter) par;
1570
1571   Handle(SALOMEDSImpl_ChildIterator) it = NewChildIterator(main_so);
1572   string moduleName(theModuleName);
1573   for(; it->More(); it->Next()) {
1574     Handle(SALOMEDSImpl_SObject) so(it->Value());
1575     Handle(SALOMEDSImpl_GenericAttribute) ga;
1576     if(so->FindAttribute(ga, "AttributeParameter")) {
1577       par = Handle(SALOMEDSImpl_AttributeParameter)::DownCast(ga);
1578       if(!par->IsSet("AP_MODULE_NAME", (Parameter_Types)3)) continue; //3 -> PT_STRING
1579       if(par->GetString("AP_MODULE_NAME") == moduleName) return par;
1580     }
1581   }
1582
1583   Handle(SALOMEDSImpl_StudyBuilder) builder = NewBuilder();
1584   Handle(SALOMEDSImpl_SObject) so = builder->NewObject(main_so);
1585   par  = Handle(SALOMEDSImpl_AttributeParameter)::DownCast(builder->FindOrCreateAttribute(so, "AttributeParameter"));
1586   par->SetString("AP_MODULE_NAME", moduleName);
1587   return par;
1588 }