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