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