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