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