Salome HOME
CCAR: Correction of a problem with management of genericobj in SALOMEDS
[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 "DF_Application.hxx"
32 #include "DF_ChildIterator.hxx"
33
34 #include "SALOMEDSImpl_ChildNodeIterator.hxx"
35 #include "SALOMEDSImpl_Attributes.hxx"
36 #include "SALOMEDSImpl_UseCaseIterator.hxx"
37 #include "SALOMEDSImpl_AttributeReference.hxx"
38 #include "SALOMEDSImpl_StudyHandle.hxx"
39 #include "SALOMEDSImpl_Tool.hxx"
40 #include "SALOMEDSImpl_IParameters.hxx"
41 #include "SALOMEDSImpl_ScalarVariable.hxx"
42
43 #include <fstream>
44
45 #define DIRECTORYID       16661
46 #define FILELOCALID       26662
47 #define FILEID            "FILE: "
48 #define VARIABLE_SEPARATOR  ':'
49 #define OPERATION_SEPARATOR '|'
50
51 //to disable automatic genericobj management comment the following line
52 #define WITHGENERICOBJ
53
54 #ifdef WITHGENERICOBJ
55 #include "SALOME_GenericObj_i.hh"
56 static CORBA::ORB_var getORB()
57 {
58   int argc=0;
59   return CORBA::ORB_init(argc,0);
60 }
61 #endif
62
63 //============================================================================
64 /*! Function : SALOMEDSImpl_Study
65  *  Purpose  : SALOMEDSImpl_Study constructor
66  */
67 //============================================================================
68 SALOMEDSImpl_Study::SALOMEDSImpl_Study(const DF_Document* doc,
69                                        const string& study_name)
70 {
71   _name = study_name;
72   _doc = (DF_Document*)doc;
73   _Saved = false ;
74   _URL = "";
75   _StudyId = -1;
76   _autoFill = false;
77   _errorCode = "";
78   _useCaseBuilder = new SALOMEDSImpl_UseCaseBuilder(_doc);
79   _builder = new SALOMEDSImpl_StudyBuilder(this);
80   _cb = new SALOMEDSImpl_Callback(_useCaseBuilder);
81   //Put on the root label a StudyHandle attribute to store the address of this object
82   //It will be used to retrieve the study object by DF_Label that belongs to the study
83   SALOMEDSImpl_StudyHandle::Set(_doc->Main().Root(), this);
84 }
85
86
87 //============================================================================
88 /*! Function : ~SALOMEDSImpl_Study
89  *  Purpose  : SALOMEDSImpl_Study destructor
90  */
91 //============================================================================
92 SALOMEDSImpl_Study::~SALOMEDSImpl_Study()
93 {
94   delete _builder;
95   delete _cb;
96   delete _useCaseBuilder;
97 }
98
99 //============================================================================
100 /*! Function : GetPersistentReference
101  *  Purpose  : Get persistent reference of study (idem URL())
102  */
103 //============================================================================
104 string SALOMEDSImpl_Study::GetPersistentReference()
105 {
106   _errorCode = "";
107   return URL();
108 }
109 //============================================================================
110 /*! Function : GetTransientReference
111  *  Purpose  : Get IOR of the Study (registred in Document in doc->Root)
112  */
113 //============================================================================
114 string SALOMEDSImpl_Study::GetTransientReference()
115 {
116   _errorCode = "";
117   string IOR = "";
118
119   SALOMEDSImpl_AttributeIOR* Att;
120   DF_Label _lab = _doc->Root();
121   if ((Att=(SALOMEDSImpl_AttributeIOR*)_lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
122     IOR = Att->Value();
123   }
124   else {
125     _errorCode = "IOR is empty";
126   }
127
128   return IOR;
129 }
130
131 void SALOMEDSImpl_Study::SetTransientReference(const string& theIOR)
132 {
133   _errorCode = "";
134
135   SALOMEDSImpl_AttributeStudyProperties* aProp = GetProperties();
136   int aLocked = aProp->IsLocked();
137   if (aLocked) aProp->SetLocked(false);
138
139   // Assign the value of the IOR in the study->root
140   SALOMEDSImpl_AttributeIOR::Set(_doc->Main().Root(), theIOR);
141
142   if (aLocked) aProp->SetLocked(true);
143 }
144
145 //============================================================================
146 /*! Function : IsEmpty
147  *  Purpose  : Detect if study is empty
148  */
149 //============================================================================
150 bool SALOMEDSImpl_Study::IsEmpty()
151 {
152   _errorCode = "";
153   if (!_doc) return true;
154   return _doc->IsEmpty();
155 }
156
157 //============================================================================
158 /*! Function : FindComponent
159  *  Purpose  : Find a Component with ComponentDataType = aComponentName
160  */
161 //============================================================================
162 SALOMEDSImpl_SComponent SALOMEDSImpl_Study::FindComponent (const string& aComponentName)
163 {
164   _errorCode = "";
165   bool _find = false;
166   string name;
167   SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
168   SALOMEDSImpl_SComponent compo;
169
170   for (; itcomp.More(); itcomp.Next()) {
171     SALOMEDSImpl_SComponent SC = itcomp.Value();
172     name = SC.ComponentDataType();
173     if(aComponentName == name) {
174       _find = true;
175       return SC;
176     }
177   }
178
179   if(!_find)
180     {
181       _errorCode = "No component was found";
182       return compo;
183     }
184   return compo;
185 }
186
187 //============================================================================
188 /*! Function : FindComponentID
189  *  Purpose  : Find a Component from it's ID
190  */
191 //============================================================================
192 SALOMEDSImpl_SComponent SALOMEDSImpl_Study::FindComponentID(const string& aComponentID)
193 {
194   _errorCode = "";
195
196   // Iterate on each components defined in the study
197   // Get the component ID and compare with aComponentID
198   bool _find = false;
199   string ID;
200   SALOMEDSImpl_SComponent compo;
201
202   SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
203   for (; itcomp.More(); itcomp.Next()) {
204     SALOMEDSImpl_SComponent SC = itcomp.Value();
205     ID = SC.GetID();
206     if(aComponentID == ID)
207       {
208         // ComponentID found
209         _find = true;
210         compo = SC;
211       }
212   }
213   if(!_find)
214     {
215       _errorCode = "No component was found";
216       compo = compo;
217     }
218
219   return compo;
220 }
221
222 //============================================================================
223 /*! Function : FindObject
224  *  Purpose  : Find an Object with SALOMEDSImpl_Name = anObjectName
225  */
226 //============================================================================
227 SALOMEDSImpl_SObject SALOMEDSImpl_Study::FindObject(const string& anObjectName)
228 {
229   _errorCode = "";
230
231   // Iterate to all components defined in the study
232   // After testing the component name, iterate in all objects defined under
233   // components (function _FindObject)
234   bool _find = false;
235   SALOMEDSImpl_SObject RefSO;
236
237   SALOMEDSImpl_SComponentIterator it = NewComponentIterator();
238   for (; it.More();it.Next()){
239     if(!_find)
240       {
241         SALOMEDSImpl_SComponent SC = it.Value();
242         if (SC.GetName() == anObjectName)
243         {
244             _find = true;
245             RefSO = SC;
246
247         }
248         if (!_find) RefSO =  _FindObject(SC, anObjectName, _find);
249       }
250   }
251   if(!RefSO) _errorCode = "No object was found";
252   return RefSO;
253 }
254
255 //============================================================================
256 /*! Function : FindObjectID
257  *  Purpose  : Find an Object with ID = anObjectID
258  */
259 //============================================================================
260 SALOMEDSImpl_SObject SALOMEDSImpl_Study::FindObjectID(const string& anObjectID)
261 {
262   _errorCode = "";
263   SALOMEDSImpl_SObject so;
264   
265   // Convert aSO->GetID in DF_Label.
266   DF_Label Lab = DF_Label::Label(_doc->Main(), anObjectID, false);
267
268   if (Lab.IsNull()) {
269     _errorCode = "No label was found by ID";
270     return so;
271   }
272   return GetSObject(Lab);
273
274 }
275
276 //============================================================================
277 /*! Function : CreateObjectID
278  *  Purpose  : Creates an Object with ID = anObjectID
279  */
280 //============================================================================
281 SALOMEDSImpl_SObject SALOMEDSImpl_Study::CreateObjectID(const string& anObjectID)
282 {
283   _errorCode = "";
284   SALOMEDSImpl_SObject so;
285
286   // Convert aSO->GetID in DF_Label.
287   DF_Label Lab = DF_Label::Label(_doc->Main(), anObjectID, true);
288
289   if (Lab.IsNull()) {
290     _errorCode = "Can not create a label";
291     return so;
292   }
293   return GetSObject(Lab);
294
295 }
296
297 //============================================================================
298 /*! Function : FindObjectByName
299  *  Purpose  : Find Objects with SALOMEDSImpl_Name = anObjectName in a Component
300  *           : with ComponentDataType = aComponentName
301  */
302 //============================================================================
303 vector<SALOMEDSImpl_SObject> SALOMEDSImpl_Study::FindObjectByName(const string& anObjectName,
304                                                           const string& aComponentName)
305 {
306   _errorCode = "";
307
308   vector<SALOMEDSImpl_SObject> listSO;
309
310   SALOMEDSImpl_SComponent compo = FindComponent(aComponentName) ;
311   if ( !compo ) {
312     _errorCode = "Can not find the component";
313     return listSO;
314   }
315
316   // Iterate on each object and subobject of the component
317   // If objectName is found add it to the list of SObjects
318   string childName ;
319
320   string compoId = compo.GetID();
321   SALOMEDSImpl_ChildIterator it = NewChildIterator(compo);
322   for ( ; it.More(); it.Next() ) {
323
324     SALOMEDSImpl_SObject CSO = it.Value();
325     if ( CSO.GetName() == anObjectName ) {
326         /* add to list */
327         listSO.push_back(CSO) ;
328     }
329
330     /* looks also for eventual children */
331     bool found = false ;
332     CSO = _FindObject( CSO, anObjectName, found ) ;
333     if( found) {
334       listSO.push_back(CSO) ;
335     }
336   }
337
338   return listSO;
339 }
340
341
342
343 //============================================================================
344 /*! Function : FindObjectIOR
345  *  Purpose  : Find an Object with IOR = anObjectIOR
346  */
347 //============================================================================
348 SALOMEDSImpl_SObject SALOMEDSImpl_Study::FindObjectIOR(const string& anObjectIOR)
349 {
350   _errorCode = "";
351   
352   SALOMEDSImpl_SObject aResult ;
353   
354   // searching in the datamap for optimization
355   if (myIORLabels.find(anObjectIOR) != myIORLabels.end()) {
356     aResult = GetSObject(myIORLabels[anObjectIOR]);
357     // 11 oct 2002: forbidden attributes must be checked here
358     if (!aResult.GetLabel().IsAttribute(SALOMEDSImpl_AttributeIOR::GetID())) {
359       myIORLabels.erase(anObjectIOR);
360       aResult = SALOMEDSImpl_SObject();  
361     }  
362   }
363   
364   if(!aResult) _errorCode = "No object was found";
365   return aResult;
366 }
367
368 //============================================================================
369 /*! Function : FindObjectByPath
370  *  Purpose  : Find an Object by its path = thePath
371  */
372 //============================================================================
373 SALOMEDSImpl_SObject SALOMEDSImpl_Study::FindObjectByPath(const string& thePath)
374 {
375   _errorCode = "";
376
377   string aPath(thePath), aToken;
378   SALOMEDSImpl_SObject aSO;
379   int aLength = aPath.size();
380   bool isRelative = false;
381
382   if(aLength == 0) {  //Empty path - return the current context
383     return GetSObject(_current);
384   }
385
386   if(aPath[0] != '/')  //Relative path
387     isRelative = true;
388
389   DF_ChildIterator anIterator;
390   DF_Label aLabel;
391   SALOMEDSImpl_AttributeName* anAttr;
392
393   if(isRelative) {
394     if(_current.IsNull()) return aSO;
395     anIterator.Init(_current, false);
396   }
397   else {
398     if(aPath.size() == 1 && aPath[0] == '/') {    //Root
399       return GetSObject(_doc->Main());
400     }
401     anIterator.Init(_doc->Main(), false);
402   }
403
404   vector<string> vs = SALOMEDSImpl_Tool::splitString(aPath, '/');
405   for(int i = 0, len = vs.size(); i<len; i++) {
406
407     aToken = vs[i];
408     if(aToken.size() == 0) break;
409
410     for ( ; anIterator.More(); anIterator.Next() ) {
411       aLabel = anIterator.Value();
412       if((anAttr=(SALOMEDSImpl_AttributeName*)aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) {
413         if(anAttr->Value() == aToken) {
414           if(i == (len-1)) {  //The searched label is found (no part of the path is left)
415               return GetSObject(aLabel);
416           }
417
418           anIterator.Init(aLabel, false);
419           break;
420         }
421       }
422     }
423
424   }
425
426   if(!aSO) _errorCode = "No object was found";
427   return aSO;
428 }
429
430 //============================================================================
431 /*! Function : GetObjectPath
432  *  Purpose  :
433  */
434 //============================================================================
435 string SALOMEDSImpl_Study::GetObjectPath(const SALOMEDSImpl_SObject& theObject)
436 {
437   _errorCode = "";
438
439   string aPath("");
440   if(!theObject) {
441     _errorCode = "Null object";
442     return aPath;
443   }
444
445   string aName = theObject.GetName();
446   if(!aName.empty() && aName != "" ) {
447     string aValue("/");
448     aValue+=aName;
449     aValue += aPath;
450     aPath = aValue;
451     SALOMEDSImpl_SObject aFather = theObject.GetFather();
452     if(aFather) {
453        aName = aFather.GetName();
454        if(!aName.empty() && aName != "") {
455            aValue = GetObjectPath(aFather);
456           aPath = aValue + aPath;
457        }
458     }
459   }
460
461   return aPath;
462 }
463
464
465 //============================================================================
466 /*! Function : GetObjectPathByIOR
467  *  Purpose  :
468  */
469 //============================================================================
470 string SALOMEDSImpl_Study::GetObjectPathByIOR(const string& theIOR)
471 {
472   _errorCode = "";
473
474   string aPath;
475   SALOMEDSImpl_SObject so = FindObjectIOR(theIOR);
476   if(!so) {
477     _errorCode = "No SObject was found by IOR";
478     return aPath;
479   }
480
481   return GetObjectPath(so);
482 }
483
484
485 //============================================================================
486 /*! Function : SetContext
487  *  Purpose  : Sets the current context
488  */
489 //============================================================================
490 bool SALOMEDSImpl_Study::SetContext(const string& thePath)
491 {
492   _errorCode = "";
493   if(thePath.empty()) {
494     _errorCode = "InvalidPath";
495     return false;
496   }
497
498   string aPath(thePath), aContext("");
499   bool isInvalid = false;
500   SALOMEDSImpl_SObject aSO;
501
502   if(aPath[0] != '/') { //Relative path
503     aContext = GetContext();
504     aContext += '/';
505     aContext += aPath;
506   }
507   else
508     aContext = aPath;
509
510   try {
511     aSO = FindObjectByPath(aContext);
512   }
513   catch( ... ) {
514     isInvalid = true;
515   }
516
517   if(isInvalid || !aSO) {
518     _errorCode = "InvalidContext";
519     return false;
520   }
521
522   DF_Label aLabel = aSO.GetLabel();
523   if(aLabel.IsNull()) {
524     _errorCode = "InvalidContext";
525     return false;
526   }
527   else
528     _current = aLabel;  //Set the current context
529
530   return true;
531 }
532
533 //============================================================================
534 /*! Function : GetContext
535  *  Purpose  : Gets the current context
536  */
537 //============================================================================
538 string SALOMEDSImpl_Study::GetContext()
539 {
540   _errorCode = "";
541
542   if(_current.IsNull()) {
543     _errorCode = "InvaidContext";
544     return "";
545   }
546   SALOMEDSImpl_SObject so = GetSObject(_current);
547   return GetObjectPath(so);
548 }
549
550 //============================================================================
551 /*! Function : GetObjectNames
552  *  Purpose  : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
553  */
554 //============================================================================
555 vector<string> SALOMEDSImpl_Study::GetObjectNames(const string& theContext)
556 {
557   _errorCode = "";
558
559   vector<string> aResultSeq;
560   DF_Label aLabel;
561   if (theContext.empty()) {
562     aLabel = _current;
563   } else {
564     DF_Label aTmp = _current;
565     SetContext(theContext);
566     aLabel = _current;
567     _current = aTmp;
568   }
569   if (aLabel.IsNull()) {
570     _errorCode = "InvalidContext";
571     return aResultSeq;
572   }
573
574   DF_ChildIterator anIter (aLabel, true); // iterate all subchildren at all sublevels
575   for (; anIter.More(); anIter.Next()) {
576     DF_Label aLabel = anIter.Value();
577     SALOMEDSImpl_AttributeName* aName;
578     if ((aName=(SALOMEDSImpl_AttributeName*)aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) 
579       aResultSeq.push_back(aName->Value());
580   }
581
582   return aResultSeq;
583 }
584
585 //============================================================================
586 /*! Function : GetDirectoryNames
587  *  Purpose  : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
588  */
589 //============================================================================
590 vector<string> SALOMEDSImpl_Study::GetDirectoryNames(const string& theContext)
591 {
592   _errorCode = "";
593
594   vector<string> aResultSeq;
595   DF_Label aLabel;
596   if (theContext.empty()) {
597     aLabel = _current;
598   } else {
599     DF_Label aTmp = _current;
600     SetContext(theContext);
601     aLabel = _current;
602     _current = aTmp;
603   }
604   if (aLabel.IsNull()) {
605     _errorCode = "InvalidContext";
606     return aResultSeq;
607   }
608
609   DF_ChildIterator anIter (aLabel, true); // iterate first-level children at all sublevels
610   for (; anIter.More(); anIter.Next()) {
611     DF_Label aLabel = anIter.Value();
612     SALOMEDSImpl_AttributeLocalID* anID;
613     if ((anID=(SALOMEDSImpl_AttributeLocalID*)aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID()))) {
614       if (anID->Value() == DIRECTORYID) {
615         SALOMEDSImpl_AttributeName* aName;
616         if ((aName=(SALOMEDSImpl_AttributeName*)aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) {
617           aResultSeq.push_back(aName->Value());
618         }
619       }
620     }
621   }
622
623   return aResultSeq;
624 }
625
626 //============================================================================
627 /*! Function : GetFileNames
628  *  Purpose  : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
629  */
630 //============================================================================
631 vector<string> SALOMEDSImpl_Study::GetFileNames(const string& theContext)
632 {
633   _errorCode = "";
634
635   vector<string> aResultSeq;
636   DF_Label aLabel;
637   if (theContext.empty()) {
638     aLabel = _current;
639   } else {
640     DF_Label aTmp = _current;
641     SetContext(theContext);
642     aLabel = _current;
643     _current = aTmp;
644   }
645   if (aLabel.IsNull()) {
646     _errorCode = "InvalidContext";
647     return aResultSeq;
648   }
649
650   DF_ChildIterator anIter (aLabel, true); // iterate all subchildren at all sublevels
651   for (; anIter.More(); anIter.Next()) {
652     DF_Label aLabel = anIter.Value();
653     SALOMEDSImpl_AttributeLocalID* anID;
654     if ((anID=(SALOMEDSImpl_AttributeLocalID*)aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID()))) {
655       if (anID->Value() == FILELOCALID) {
656         SALOMEDSImpl_AttributePersistentRef* aName;
657         if ((aName=(SALOMEDSImpl_AttributePersistentRef*)aLabel.FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID()))) {
658           std::string aFileName = aName->Value();
659           if (aFileName.size() > 0)
660             aResultSeq.push_back(aFileName.substr(strlen(FILEID), aFileName.size()));
661         }
662       }
663     }
664   }
665
666   return aResultSeq;
667 }
668
669 //============================================================================
670 /*! Function : GetComponentNames
671  *  Purpose  : method to get all components names
672  */
673 //============================================================================
674 vector<string> SALOMEDSImpl_Study::GetComponentNames(const string& theContext)
675 {
676   _errorCode = "";
677
678   vector<string> aResultSeq;
679   DF_ChildIterator anIter(_doc->Main(), false); // iterate all subchildren at first level
680   for(; anIter.More(); anIter.Next()) {
681     DF_Label aLabel = anIter.Value();
682     SALOMEDSImpl_AttributeName* aName;
683     if ((aName=(SALOMEDSImpl_AttributeName*)aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) 
684       aResultSeq.push_back(aName->Value());
685   }
686
687   return aResultSeq;
688 }
689
690 //============================================================================
691 /*! Function : NewChildIterator
692  *  Purpose  : Create a ChildIterator from an SObject
693  */
694 //============================================================================
695 SALOMEDSImpl_ChildIterator SALOMEDSImpl_Study::NewChildIterator(const SALOMEDSImpl_SObject& aSO)
696 {
697   _errorCode = "";
698   return SALOMEDSImpl_ChildIterator(aSO);
699 }
700
701
702 //============================================================================
703 /*! Function : NewComponentIterator
704  *  Purpose  : Create a SComponentIterator
705  */
706 //============================================================================
707 SALOMEDSImpl_SComponentIterator SALOMEDSImpl_Study::NewComponentIterator()
708 {
709   _errorCode = "";
710   return SALOMEDSImpl_SComponentIterator(_doc);
711 }
712
713
714 //============================================================================
715 /*! Function : NewBuilder
716  *  Purpose  : Create a StudyBuilder
717  */
718 //============================================================================
719 SALOMEDSImpl_StudyBuilder* SALOMEDSImpl_Study::NewBuilder()
720 {
721   _errorCode = "";
722   if(_autoFill) {
723     _builder->SetOnAddSObject(_cb);
724     _builder->SetOnRemoveSObject(_cb);
725   }
726   return _builder;
727
728 }
729
730 //============================================================================
731 /*! Function : Name
732  *  Purpose  : get study name
733  */
734 //============================================================================
735 string SALOMEDSImpl_Study::Name()
736 {
737   _errorCode = "";
738   return _name;
739 }
740
741 //============================================================================
742 /*! Function : Name
743  *  Purpose  : set study name
744  */
745 //============================================================================
746 void SALOMEDSImpl_Study::Name(const string& name)
747 {
748   _errorCode = "";
749   _name = name;
750 }
751
752 //============================================================================
753 /*! Function : IsSaved
754  *  Purpose  : get if study has been saved
755  */
756 //============================================================================
757 bool SALOMEDSImpl_Study::IsSaved()
758 {
759   _errorCode = "";
760   return _Saved;
761 }
762
763 //============================================================================
764 /*! Function : IsSaved
765  *  Purpose  : set if study has been saved
766  */
767 //============================================================================
768 void SALOMEDSImpl_Study::IsSaved(bool save)
769 {
770   _errorCode = "";
771   _Saved = save;
772   if(save) _doc->SetModified(false);
773 }
774
775 //============================================================================
776 /*! Function : IsModified
777  *  Purpose  : Detect if a Study has been modified since it has been saved
778  */
779 //============================================================================
780 bool SALOMEDSImpl_Study::IsModified()
781 {
782   _errorCode = "";
783
784   // True if is modified
785   if (_doc && _doc->IsModified()) return true;
786
787   return false;
788 }
789
790 //============================================================================
791 /*! Function : URL
792  *  Purpose  : get URL of the study (persistent reference of the study)
793  */
794 //============================================================================
795 string SALOMEDSImpl_Study::URL()
796 {
797   _errorCode = "";
798   return _URL;
799 }
800
801 //============================================================================
802 /*! Function : URL
803  *  Purpose  : set URL of the study (persistent reference of the study)
804  */
805 //============================================================================
806 void SALOMEDSImpl_Study::URL(const string& url)
807 {
808   _errorCode = "";
809   _URL = url;
810
811   /*jfa: Now name of SALOMEDS study will correspond to name of SalomeApp study
812   string tmp(_URL);
813
814   char *aName = (char*)tmp.ToCString();
815   char *adr = strtok(aName, "/");
816   while (adr)
817     {
818       aName = adr;
819       adr = strtok(NULL, "/");
820     }
821   Name(aName);*/
822   Name(url);
823 }
824
825
826 //============================================================================
827 /*! Function : _FindObject
828  *  Purpose  : Find an Object with SALOMEDSImpl_Name = anObjectName
829  */
830 //============================================================================
831 SALOMEDSImpl_SObject SALOMEDSImpl_Study::_FindObject(const SALOMEDSImpl_SObject& SO,
832                                                              const string& theObjectName,
833                                                              bool& _find)
834 {
835   SALOMEDSImpl_SObject RefSO;
836   if(!SO) return RefSO;
837
838   // Iterate on each objects and subobjects of the component
839   // If objectName find, stop the loop and get the object reference
840   SALOMEDSImpl_AttributeName* anAttr;
841
842   string soid = SO.GetID();
843   DF_ChildIterator it(SO.GetLabel());
844   for (; it.More(); it.Next()){
845     if(!_find)
846       {
847         if ((anAttr=(SALOMEDSImpl_AttributeName*)it.Value().FindAttribute(SALOMEDSImpl_AttributeName::GetID())))
848         {
849           string Val(anAttr->Value());
850           if (Val == theObjectName)
851             {
852               RefSO = GetSObject(it.Value());
853               _find = true;
854             }
855         }
856         if (!_find) RefSO = _FindObject(GetSObject(it.Value()), theObjectName, _find);
857       }
858   }
859   return RefSO;
860 }
861
862 //============================================================================
863 /*! Function : _FindObjectIOR
864  *  Purpose  : Find an Object with SALOMEDSImpl_IOR = anObjectIOR
865  */
866 //============================================================================
867 SALOMEDSImpl_SObject
868 SALOMEDSImpl_Study::_FindObjectIOR(const SALOMEDSImpl_SObject& SO,
869                                    const string& theObjectIOR,
870                                    bool& _find)
871 {
872   SALOMEDSImpl_SObject RefSO, aSO;
873   if(!SO) return RefSO;
874
875   // Iterate on each objects and subobjects of the component
876   // If objectName find, stop the loop and get the object reference
877   SALOMEDSImpl_AttributeIOR* anAttr;
878
879   DF_ChildIterator it(SO.GetLabel());
880   for (; it.More();it.Next()){
881     if(!_find)
882       {
883         if ((anAttr=(SALOMEDSImpl_AttributeIOR*)it.Value().FindAttribute(SALOMEDSImpl_AttributeIOR::GetID())))
884         {
885           string Val(anAttr->Value());
886           if (Val == theObjectIOR)
887             {
888               RefSO = GetSObject(it.Value());
889               _find = true;
890             }
891         }
892         aSO = GetSObject(it.Value());
893         if (!_find) RefSO =  _FindObjectIOR(aSO, theObjectIOR, _find);
894       }
895   }
896   return RefSO;
897 }
898
899 //============================================================================
900 /*! Function : _GetNoteBookAccessor
901  *  Purpose  : Find an Object with SALOMEDSImpl_IOR = anObjectIOR
902  */
903 //============================================================================
904 string SALOMEDSImpl_Study::_GetNoteBookAccessor(){
905   return string("notebook");
906 }
907
908 //============================================================================
909 /*! Function : _GetStudyVariablesScript
910  *  Purpose  : 
911  */
912 //============================================================================
913 string SALOMEDSImpl_Study::_GetStudyVariablesScript()
914 {
915   string dump("");
916   
917   if(myNoteBookVars.empty())
918     return dump;
919   
920   dump += "####################################################\n";
921   dump += "##       Begin of NoteBook variables section      ##\n";
922   dump += "####################################################\n";
923
924   string set_method = _GetNoteBookAccessor()+".set(";
925   string varName;
926   string varValue;
927   for(int i = 0 ; i < myNoteBookVars.size();i++ ) {
928     varName = myNoteBookVars[i]->Name();
929     varValue = myNoteBookVars[i]->SaveToScript();
930     dump+=set_method+"\""+varName+"\", "+varValue+")\n";
931   }
932   
933   dump += "####################################################\n";
934   dump += "##        End of NoteBook variables section       ##\n";
935   dump += "####################################################\n";
936
937   return dump;
938 }
939
940 //============================================================================
941 /*! Function : _GetNoteBookAccess
942  *  Purpose  :
943  */
944 //============================================================================
945 string SALOMEDSImpl_Study::_GetNoteBookAccess()
946 {
947   string accessor = _GetNoteBookAccessor();
948   string notebook = "import salome_notebook\n";
949          notebook += accessor+" = salome_notebook."+accessor + "\n";
950   return notebook;       
951 }
952
953 bool SALOMEDSImpl_Study::IsLocked()
954 {
955   _errorCode = "";
956   return GetProperties()->IsLocked();
957 }
958
959 int SALOMEDSImpl_Study::StudyId()
960 {
961   _errorCode = "";
962   return _StudyId;
963 }
964
965 void SALOMEDSImpl_Study::StudyId(int id)
966 {
967   _errorCode = "";
968   _StudyId = id;
969 }
970
971 void SALOMEDSImpl_Study::UpdateIORLabelMap(const string& anIOR,const string& anEntry)
972 {
973   _errorCode = "";
974   DF_Label aLabel = DF_Label::Label(_doc->Main(), anEntry, true);
975   if (myIORLabels.find(anIOR) != myIORLabels.end()) myIORLabels.erase(anIOR);
976 #ifdef WITHGENERICOBJ
977   else
978     {
979       // if the ior was not already registered, incref the genericobj (if it's one)
980       CORBA::Object_var obj;
981       SALOME::GenericObj_var gobj;
982       try
983         {
984           obj = getORB()->string_to_object(anIOR.c_str());
985           gobj = SALOME::GenericObj::_narrow(obj);
986           if(! CORBA::is_nil(gobj) )
987             {
988               gobj->Register();
989             }
990         }
991       catch(const CORBA::Exception& e)
992         {
993         }
994     }
995 #endif
996   myIORLabels[anIOR] = aLabel;
997 }
998
999 void SALOMEDSImpl_Study::DeleteIORLabelMapItem(const std::string& anIOR)
1000 {
1001   if (myIORLabels.find(anIOR) != myIORLabels.end()) 
1002     {
1003       //remove the ior entry and decref the genericobj (if it's one)
1004       myIORLabels.erase(anIOR);
1005 #ifdef WITHGENERICOBJ
1006        CORBA::Object_var obj;
1007        SALOME::GenericObj_var gobj;
1008        try
1009          {
1010            obj = getORB()->string_to_object(anIOR.c_str());
1011            gobj = SALOME::GenericObj::_narrow(obj);
1012            if(! CORBA::is_nil(gobj) )
1013              {
1014                gobj->Destroy();
1015              }
1016          }
1017        catch(const CORBA::Exception& e)
1018          {
1019          }
1020 #endif
1021     }
1022 }
1023
1024 SALOMEDSImpl_Study* SALOMEDSImpl_Study::GetStudy(const DF_Label& theLabel)
1025 {
1026   SALOMEDSImpl_StudyHandle* Att;
1027   if ((Att=(SALOMEDSImpl_StudyHandle*)theLabel.Root().FindAttribute(SALOMEDSImpl_StudyHandle::GetID()))) {
1028     return Att->Get();
1029   }
1030   return NULL;
1031 }
1032
1033 SALOMEDSImpl_SObject SALOMEDSImpl_Study::SObject(const DF_Label& theLabel)
1034 {
1035   return GetStudy(theLabel)->GetSObject(theLabel);
1036 }
1037
1038 SALOMEDSImpl_SComponent SALOMEDSImpl_Study::SComponent(const DF_Label& theLabel)
1039 {
1040   return GetStudy(theLabel)->GetSComponent(theLabel);
1041 }
1042
1043
1044 void SALOMEDSImpl_Study::IORUpdated(const SALOMEDSImpl_AttributeIOR* theAttribute)
1045 {
1046   string aString = theAttribute->Label().Entry();
1047   GetStudy(theAttribute->Label())->UpdateIORLabelMap(theAttribute->Value(), aString);
1048 }
1049
1050 vector<SALOMEDSImpl_SObject> SALOMEDSImpl_Study::FindDependances(const SALOMEDSImpl_SObject& anObject)
1051 {
1052   _errorCode = "";
1053   vector<SALOMEDSImpl_SObject> aSeq;
1054
1055   SALOMEDSImpl_AttributeTarget* aTarget;
1056   if ((aTarget=(SALOMEDSImpl_AttributeTarget*)anObject.GetLabel().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID()))) {
1057     return aTarget->Get();
1058   }
1059
1060   return aSeq;
1061 }
1062
1063
1064 SALOMEDSImpl_AttributeStudyProperties* SALOMEDSImpl_Study::GetProperties()
1065 {
1066   _errorCode = "";
1067   return SALOMEDSImpl_AttributeStudyProperties::Set(_doc->Main());
1068 }
1069
1070 string SALOMEDSImpl_Study::GetLastModificationDate()
1071 {
1072   _errorCode = "";
1073   SALOMEDSImpl_AttributeStudyProperties* aProp = GetProperties();
1074
1075   vector<string> aNames;
1076   vector<int> aMinutes, aHours, aDays, aMonths, aYears;
1077   aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
1078
1079   int aLastIndex = aNames.size()-1;
1080   char aResult[20];
1081   sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
1082           (int)(aDays[aLastIndex]),(int)(aMonths[aLastIndex]), (int)(aYears[aLastIndex]),
1083           (int)(aHours[aLastIndex]), (int)(aMinutes[aLastIndex]));
1084   string aResStr (aResult);
1085   return aResStr;
1086 }
1087
1088 vector<string> SALOMEDSImpl_Study::GetModificationsDate()
1089 {
1090   _errorCode = "";
1091   SALOMEDSImpl_AttributeStudyProperties* aProp = GetProperties();
1092
1093   vector<string> aNames;
1094   vector<int> aMinutes, aHours, aDays, aMonths, aYears;
1095   aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
1096
1097   int anIndex, aLength = aNames.size();
1098   vector<string> aDates;
1099
1100   for (anIndex = 1; anIndex < aLength; anIndex++) {
1101     char aDate[20];
1102     sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
1103             (int)(aDays[anIndex]), (int)(aMonths[anIndex]), (int)(aYears[anIndex]),
1104             (int)(aHours[anIndex]), (int)(aMinutes[anIndex]));
1105     aDates.push_back(aDate);
1106   }
1107   return aDates;
1108 }
1109
1110
1111
1112 //============================================================================
1113 /*! Function : GetUseCaseBuilder
1114  *  Purpose  : Returns a UseCase builder
1115  */
1116 //============================================================================
1117 SALOMEDSImpl_UseCaseBuilder* SALOMEDSImpl_Study::GetUseCaseBuilder()
1118 {
1119   _errorCode = "";
1120   return _useCaseBuilder;
1121 }
1122
1123
1124 //============================================================================
1125 /*! Function : Close
1126  *  Purpose  :
1127  */
1128 //============================================================================
1129 void SALOMEDSImpl_Study::Close()
1130 {
1131   _errorCode = "";
1132   _doc->GetApplication()->Close(_doc);
1133   _doc = NULL;
1134   _mapOfSO.clear();
1135   _mapOfSCO.clear();
1136 }
1137
1138
1139 //============================================================================
1140 /*! Function : GetSComponent
1141  *  Purpose  :
1142  */
1143 //============================================================================
1144 SALOMEDSImpl_SComponent SALOMEDSImpl_Study::GetSComponent(const string& theEntry)
1145 {
1146   SALOMEDSImpl_SComponent aSCO;
1147   if(_mapOfSCO.find(theEntry) != _mapOfSCO.end())
1148     aSCO = _mapOfSCO[theEntry];
1149   else {
1150     DF_Label aLabel = DF_Label::Label(_doc->Main(), theEntry);
1151     aSCO = SALOMEDSImpl_SComponent(aLabel);
1152     _mapOfSCO[theEntry] = aSCO;
1153   }
1154
1155   return aSCO;
1156 }
1157
1158 //============================================================================
1159 /*! Function : GetSComponent
1160  *  Purpose  :
1161  */
1162 //============================================================================
1163 SALOMEDSImpl_SComponent SALOMEDSImpl_Study::GetSComponent(const DF_Label& theLabel)
1164 {
1165   return SALOMEDSImpl_SComponent(theLabel);
1166 }
1167
1168 //============================================================================
1169 /*! Function : GetSObject
1170  *  Purpose  :
1171  */
1172 //============================================================================
1173 SALOMEDSImpl_SObject SALOMEDSImpl_Study::GetSObject(const string& theEntry)
1174 {
1175   SALOMEDSImpl_SObject aSO;
1176   if(_mapOfSO.find(theEntry) != _mapOfSO.end())
1177     aSO = _mapOfSO[theEntry];
1178   else {
1179     DF_Label aLabel = DF_Label::Label(_doc->Main(), theEntry);
1180     aSO = SALOMEDSImpl_SObject(aLabel);
1181     _mapOfSO[theEntry] = aSO;
1182   }
1183
1184   return aSO;
1185 }
1186
1187 //============================================================================
1188 /*! Function : GetSObject
1189  *  Purpose  :
1190  */
1191 //============================================================================
1192 SALOMEDSImpl_SObject SALOMEDSImpl_Study::GetSObject(const DF_Label& theLabel)
1193 {
1194   return SALOMEDSImpl_SObject(theLabel);
1195 }
1196
1197 //============================================================================
1198 /*! Function : GetAttribute
1199  *  Purpose  :
1200  */
1201 //============================================================================
1202 DF_Attribute* SALOMEDSImpl_Study::GetAttribute(const string& theEntry,
1203                                                const string& theType)
1204 {
1205   SALOMEDSImpl_SObject aSO = GetSObject(theEntry);
1206   DF_Attribute* anAttr;
1207   aSO.FindAttribute(anAttr, theType);
1208   return anAttr;
1209 }
1210
1211 //============================================================================
1212 /*! Function : DumpStudy
1213  *  Purpose  :
1214  */
1215 //============================================================================
1216 bool SALOMEDSImpl_Study::DumpStudy(const string& thePath,
1217                                    const string& theBaseName,
1218                                    bool isPublished,
1219                                    SALOMEDSImpl_DriverFactory* theFactory)
1220 {
1221   _errorCode = "";
1222
1223   if(theFactory == NULL) {
1224     _errorCode = "Null factory for creation of Engines";
1225     return false;
1226   }
1227
1228   vector<string> aSeq;
1229   string aCompType, aFactoryType;
1230
1231   //Build a list of all components in the Study
1232   SALOMEDSImpl_SComponentIterator itcomponent = NewComponentIterator();
1233
1234   for (; itcomponent.More(); itcomponent.Next()) {
1235     SALOMEDSImpl_SComponent sco = itcomponent.Value();
1236     aCompType = sco.ComponentDataType();
1237     //GEOM and MED are independent components
1238     if (aCompType == "GEOM" || aCompType == "MED")
1239       aSeq.insert(aSeq.begin(), aCompType);
1240     else
1241       aSeq.push_back(aCompType);
1242   }
1243
1244 #ifdef WIN32
1245   string aFileName =
1246     thePath + string("\\") + theBaseName + string(".py");
1247 #else
1248   string aFileName =
1249     thePath + string("/")  + theBaseName + string(".py");
1250 #endif
1251
1252   //Create a file that will contain a main Study script
1253   fstream fp;
1254   fp.open(aFileName.c_str(), ios::out);
1255
1256 #ifdef WIN32
1257   bool isOpened = fp.is_open();
1258 #else
1259   bool isOpened = fp.rdbuf()->is_open();
1260 #endif
1261
1262   if(!isOpened) {
1263     _errorCode = string("Can't create a file ")+aFileName;
1264     return false;
1265   }
1266
1267   string aBatchModeScript = "salome";
1268
1269   //Output to the main Study script required Python modules import,
1270   //set sys.path and add a creation of the study.
1271   fp << GetDumpStudyComment() << endl << endl;
1272   fp << "import sys" << endl;
1273   fp << "import " << aBatchModeScript << endl << endl;
1274
1275   fp << aBatchModeScript << ".salome_init()" << endl << endl;
1276
1277   fp << _GetNoteBookAccess();
1278
1279   fp << "sys.path.insert( 0, r\'" << thePath << "\')" << endl << endl;
1280
1281   //Dump NoteBook Variables
1282   fp << _GetStudyVariablesScript();
1283
1284   //Check if it's necessary to dump visual parameters
1285   bool isDumpVisuals = SALOMEDSImpl_IParameters::isDumpPython(this);
1286   int lastSavePoint = -1;
1287   if(isDumpVisuals) {
1288     lastSavePoint = SALOMEDSImpl_IParameters::getLastSavePoint(this);
1289     if(lastSavePoint > 0) {
1290       fp << SALOMEDSImpl_IParameters::getStudyScript(this, lastSavePoint) << endl << endl;
1291     }
1292   }
1293   
1294
1295   vector<string> aSeqOfFileNames;
1296
1297   //Iterate all components and create the componponents specific scripts.
1298   bool isOk = true;
1299   int aLength = aSeq.size();
1300   for(int i = 1; i <= aLength; i++) {
1301
1302     aCompType = aSeq[i-1];
1303     SALOMEDSImpl_SComponent sco = FindComponent(aCompType);
1304     SALOMEDSImpl_Driver* aDriver = NULL;
1305     // if there is an associated Engine call its method for saving
1306     string IOREngine;
1307     try {
1308       if (!sco.ComponentIOR(IOREngine)) {
1309         if (!aCompType.empty()) {
1310
1311           aDriver = theFactory->GetDriverByType(aCompType);
1312
1313           if (aDriver != NULL) {
1314             SALOMEDSImpl_StudyBuilder* SB = NewBuilder();
1315             if(!SB->LoadWith(sco, aDriver)) {
1316               _errorCode = SB->GetErrorCode();
1317               return false;
1318             }
1319           }
1320           else continue;
1321         }
1322       }
1323       else {
1324         aDriver = theFactory->GetDriverByIOR(IOREngine);
1325       }
1326     } catch(...) {
1327       _errorCode = "Can not restore information to dump it";
1328       return false;
1329     }
1330
1331     if(aDriver == NULL) continue;
1332
1333     bool isValidScript;
1334     long aStreamLength  = 0;
1335     SALOMEDSImpl_TMPFile* aStream = aDriver->DumpPython(this, isPublished, isValidScript, aStreamLength);
1336     if ( !isValidScript )
1337       isOk = false;
1338
1339     //Create a file that will contain the component specific script
1340     fstream fp2;
1341 #ifdef WIN32
1342     aFileName=thePath+string("\\");
1343 #else
1344     aFileName=thePath+string("/");
1345 #endif
1346     string aScriptName;
1347     aScriptName += theBaseName;
1348     aScriptName += "_";
1349     aScriptName += aCompType;
1350
1351     aFileName += aScriptName+ string(".py");
1352     aSeqOfFileNames.push_back(aFileName);
1353
1354     fp2.open(aFileName.c_str(), ios::out);
1355
1356 #ifdef WIN32
1357     isOpened = fp2.is_open();
1358 #else
1359     isOpened = fp2.rdbuf()->is_open();
1360 #endif
1361
1362     if(!isOpened) {
1363       _errorCode = string("Can't create a file ")+aFileName;
1364       SALOMEDSImpl_Tool::RemoveTemporaryFiles(thePath, aSeqOfFileNames, false);
1365       return false;
1366     }
1367
1368     //Output the Python script generated by the component in the newly created file.
1369     fp2 << aStream->Data();
1370     fp2.close();
1371
1372     if(aStream) delete aStream;
1373
1374     //Add to the main script a call to RebuildData of the generated by the component the Python script
1375     fp << "import " << aScriptName << endl;
1376     fp << aScriptName << ".RebuildData(" << aBatchModeScript << ".myStudy)" << endl;
1377   }
1378
1379   fp << endl;
1380   fp << "if salome.sg.hasDesktop():" << endl;
1381   fp << "\tsalome.sg.updateObjBrowser(1)" << endl;
1382
1383   if(isDumpVisuals) { //Output the call to Session's method restoreVisualState
1384     fp << "\tiparameters.getSession().restoreVisualState(1)" << endl;
1385   }
1386
1387
1388   fp.close();
1389   return isOk;
1390 }
1391
1392 //=======================================================================
1393 //function : GetDumpStudyComment
1394 //purpose  : return a header comment for a DumpStudy script
1395 //=======================================================================
1396
1397 string SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
1398 {
1399   string txt
1400     ("### This file is generated by SALOME automatically by dump python functionality");
1401   if ( theComponentName )
1402     txt += string(" of ") + (char*) theComponentName + " component";
1403   return txt;
1404 }
1405
1406 void dumpSO(const SALOMEDSImpl_SObject& theSO,
1407             fstream& fp,
1408             const string& Tab,
1409             SALOMEDSImpl_Study* theStudy);
1410
1411 //============================================================================
1412 /*! Function : dump
1413  *  Purpose  :
1414  */
1415 //============================================================================
1416 void SALOMEDSImpl_Study::dump(const string& theFileName)
1417 {
1418   //Create a file that will contain a main Study script
1419   fstream fp;
1420   fp.open(theFileName.c_str(), ios::out);
1421
1422 #ifdef WIN32
1423   bool isOpened = fp.is_open();
1424 #else
1425   bool isOpened = fp.rdbuf()->is_open();
1426 #endif
1427
1428   if(!isOpened) {
1429     _errorCode = string("Can't create a file ")+theFileName;
1430     cout << "### SALOMEDSImpl_Study::dump Error: " << _errorCode << endl;
1431     return;
1432   }
1433
1434   SALOMEDSImpl_SObject aSO = FindObjectID("0:1");
1435   fp << "0:1" << endl;
1436   SALOMEDSImpl_ChildIterator Itr = NewChildIterator(aSO);
1437   string aTab("   ");
1438   for(; Itr.More(); Itr.Next()) {
1439     dumpSO(Itr.Value(), fp, aTab, this);
1440   }
1441
1442   fp.close();
1443 }
1444
1445
1446 void dumpSO(const SALOMEDSImpl_SObject& theSO,
1447             fstream& fp,
1448             const string& Tab,
1449             SALOMEDSImpl_Study* theStudy)
1450 {
1451   string aTab(Tab), anID(theSO.GetID());
1452   fp << aTab << anID << endl;
1453   vector<DF_Attribute*> attribs = theSO.GetLabel().GetAttributes();
1454   for(int i = 0; i<attribs.size(); i++) {
1455     SALOMEDSImpl_GenericAttribute* anAttr = dynamic_cast<SALOMEDSImpl_GenericAttribute*>(attribs[i]);
1456
1457     if(!anAttr) {
1458       continue;
1459     }
1460
1461     string aType = anAttr->GetClassType();
1462     fp << Tab << "  -- " << aType;
1463
1464     if(aType == string("AttributeReal")) {
1465       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeReal*>(anAttr)->Value();
1466     }
1467     else if(aType == string("AttributeInteger")) {
1468       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeInteger*>(anAttr)->Value();
1469     }
1470     else if(aType ==  string("AttributeName")) {
1471       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeName*>(anAttr)->Value();
1472     }
1473     else if(aType == string("AttributeComment")) {
1474       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeComment*>(anAttr)->Value();
1475     }
1476     else if(aType == string("AttributeReference")) {
1477       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeReference*>(anAttr)->Save();
1478     }
1479     fp << endl;
1480   }
1481
1482   SALOMEDSImpl_ChildIterator Itr = theStudy->NewChildIterator(theSO);
1483   string aNewTab("   ");
1484   aNewTab+=aTab;
1485   for(; Itr.More(); Itr.Next()) {
1486     dumpSO(Itr.Value(), fp, aNewTab, theStudy);
1487   }
1488
1489   return;
1490 }
1491
1492 void SALOMEDSImpl_Study::Modify()
1493 {
1494   _errorCode = "";
1495   _doc->SetModified(true);
1496 }
1497
1498 //============================================================================
1499 /*! Function : 
1500  *  Purpose  :
1501  */
1502 //============================================================================
1503 SALOMEDSImpl_AttributeParameter* SALOMEDSImpl_Study::GetCommonParameters(const char* theID, int theSavePoint)
1504 {
1505   if (theSavePoint < 0) return NULL;
1506   SALOMEDSImpl_StudyBuilder* builder = NewBuilder();
1507   SALOMEDSImpl_SObject so = FindComponent((char*)theID);
1508   if (!so) so = builder->NewComponent((char*)theID);
1509   SALOMEDSImpl_AttributeParameter* attParam = NULL;
1510
1511   if (theSavePoint > 0) { // Try to find SObject that contains attribute parameter ...
1512     DF_Label savePointLabel = so.GetLabel().FindChild( theSavePoint, /*create=*/0 );
1513     if ( !savePointLabel.IsNull() )
1514       so = GetSObject( savePointLabel );
1515     else // ... if it does not exist - create a new one
1516       so = builder->NewObjectToTag( so, theSavePoint );
1517   }
1518
1519   DF_Attribute* A;
1520   if (so) {
1521     builder->FindAttribute(so, A, "AttributeParameter");
1522     if ( !A ) { // first call of GetCommonParameters on "Interface Applicative" component
1523       A = builder->FindOrCreateAttribute(so, "AttributeParameter"); 
1524     }
1525     attParam = dynamic_cast<SALOMEDSImpl_AttributeParameter*>( A );
1526   }
1527   return attParam;
1528 }
1529
1530 //============================================================================
1531 /*! Function : 
1532  *  Purpose  :
1533  */
1534 //============================================================================
1535 SALOMEDSImpl_AttributeParameter* SALOMEDSImpl_Study::GetModuleParameters(const char* theID, 
1536                                                                          const char* theModuleName,
1537                                                                          int theSavePoint)
1538 {
1539   if(theSavePoint <= 0) return NULL;
1540   SALOMEDSImpl_AttributeParameter* main_ap = GetCommonParameters(theID, theSavePoint);
1541   SALOMEDSImpl_SObject main_so = main_ap->GetSObject();
1542   SALOMEDSImpl_AttributeParameter* par = NULL;
1543
1544   SALOMEDSImpl_ChildIterator it = NewChildIterator(main_so);
1545   string moduleName(theModuleName);
1546   for(; it.More(); it.Next()) {
1547     SALOMEDSImpl_SObject so(it.Value());
1548     if((par=(SALOMEDSImpl_AttributeParameter*)so.GetLabel().FindAttribute(SALOMEDSImpl_AttributeParameter::GetID()))) {
1549       if(!par->IsSet("AP_MODULE_NAME", (Parameter_Types)3)) continue; //3 -> PT_STRING
1550       if(par->GetString("AP_MODULE_NAME") == moduleName) return par;
1551     }
1552   }
1553
1554   SALOMEDSImpl_StudyBuilder* builder = NewBuilder();
1555   SALOMEDSImpl_SObject so = builder->NewObject(main_so);
1556   par  = dynamic_cast<SALOMEDSImpl_AttributeParameter*>(builder->FindOrCreateAttribute(so, "AttributeParameter"));
1557   par->SetString("AP_MODULE_NAME", moduleName);
1558   return par;
1559 }
1560
1561 //============================================================================
1562 /*! Function : SetStudyLock
1563  *  Purpose  :
1564  */
1565 //============================================================================
1566 void SALOMEDSImpl_Study::SetStudyLock(const char* theLockerID)
1567 {
1568   _lockers.push_back(theLockerID);
1569 }
1570
1571 //============================================================================
1572 /*! Function : IsStudyLocked
1573  *  Purpose  :
1574  */
1575 //============================================================================
1576 bool SALOMEDSImpl_Study::IsStudyLocked()
1577 {
1578   return (_lockers.size() > 0);
1579 }
1580
1581 //============================================================================
1582 /*! Function : UnLockStudy
1583  *  Purpose  :
1584  */
1585 //============================================================================
1586 void SALOMEDSImpl_Study::UnLockStudy(const char* theLockerID)
1587 {
1588   vector<string>::iterator vsI = _lockers.begin();
1589   int length = _lockers.size();
1590   bool isFound = false;
1591   string id(theLockerID);
1592   for(int i = 0; i<length; i++, vsI++) {
1593     if(id == _lockers[i]) {
1594       isFound = true;;
1595       break;
1596     }
1597   }
1598   if(isFound) _lockers.erase(vsI);
1599 }
1600   
1601 //============================================================================
1602 /*! Function : GetLockerID
1603  *  Purpose  :
1604  */
1605 //============================================================================
1606 vector<string> SALOMEDSImpl_Study::GetLockerID()
1607 {
1608   return _lockers;
1609 }
1610
1611 //============================================================================
1612 /*! Function : SetVariable
1613  *  Purpose  :
1614  */
1615 //============================================================================
1616 void SALOMEDSImpl_Study::SetVariable(const string& theVarName,
1617                                      const double theValue,
1618                                      const SALOMEDSImpl_GenericVariable::VariableTypes theType)
1619 {
1620   bool modified = false;
1621   SALOMEDSImpl_GenericVariable* aGVar = GetVariable(theVarName);
1622   
1623   if( aGVar == NULL ) {
1624
1625     SALOMEDSImpl_ScalarVariable* aSVar = new SALOMEDSImpl_ScalarVariable(theType, theVarName);
1626
1627     aSVar->setValue(theValue);
1628     myNoteBookVars.push_back(aSVar);
1629     modified = true;
1630   }
1631   else {
1632     if(SALOMEDSImpl_ScalarVariable* aSVar = dynamic_cast<SALOMEDSImpl_ScalarVariable*>(aGVar)) {
1633       modified = aSVar->setValue(theValue) || modified;
1634       modified = aSVar->setType(theType) || modified;
1635     }
1636   }
1637   if(modified)
1638     Modify();
1639 }
1640
1641 //============================================================================
1642 /*! Function : GetReal
1643  *  Purpose  :
1644  */
1645 //============================================================================
1646 double SALOMEDSImpl_Study::GetVariableValue(const string& theVarName)
1647 {
1648   SALOMEDSImpl_GenericVariable* aGVar = GetVariable(theVarName);
1649   
1650   if(aGVar != NULL )
1651     if(SALOMEDSImpl_ScalarVariable* aSVar = dynamic_cast<SALOMEDSImpl_ScalarVariable*>(aGVar))
1652       return aSVar->getValue();
1653
1654   return 0;
1655 }
1656
1657 //============================================================================
1658 /*! Function : IsTypeOf
1659  *  Purpose  :
1660  */
1661 //============================================================================
1662 bool SALOMEDSImpl_Study::IsTypeOf(const string& theVarName,
1663                                   SALOMEDSImpl_GenericVariable::
1664                                   VariableTypes theType) const
1665 {
1666   SALOMEDSImpl_GenericVariable* aGVar = GetVariable(theVarName);
1667   
1668   if(aGVar != NULL )
1669     return aGVar->Type() == theType;
1670   
1671   return false;
1672 }
1673
1674 //============================================================================
1675 /*! Function : IsVariable
1676  *  Purpose  :
1677  */
1678 //============================================================================
1679 bool SALOMEDSImpl_Study::IsVariable(const string& theVarName) const
1680 {
1681   SALOMEDSImpl_GenericVariable* aGVar = GetVariable(theVarName);
1682   return (aGVar != NULL);
1683 }
1684
1685 //============================================================================
1686 /*! Function : GetVariableNames
1687  *  Purpose  :
1688  */
1689 //============================================================================
1690 vector<string> SALOMEDSImpl_Study::GetVariableNames() const
1691 {
1692   vector<string> aResult;
1693
1694   for(int i = 0; i < myNoteBookVars.size(); i++)
1695     aResult.push_back(myNoteBookVars[i]->Name());
1696   
1697   return aResult;
1698 }
1699
1700 //============================================================================
1701 /*! Function : AddVariable
1702  *  Purpose  :
1703  */
1704 //============================================================================
1705 void SALOMEDSImpl_Study::AddVariable(SALOMEDSImpl_GenericVariable* theVariable)
1706 {
1707   myNoteBookVars.push_back(theVariable);
1708 }
1709
1710 //============================================================================
1711 /*! Function : AddVariable
1712  *  Purpose  :
1713  */
1714 //============================================================================
1715 SALOMEDSImpl_GenericVariable* SALOMEDSImpl_Study::GetVariable(const std::string& theName) const
1716 {
1717   SALOMEDSImpl_GenericVariable* aResult = NULL;
1718   for(int i = 0; i < myNoteBookVars.size();i++) {
1719     if(theName.compare(myNoteBookVars[i]->Name()) == 0) {
1720       aResult = myNoteBookVars[i];
1721       break;
1722     }  
1723   }
1724   return aResult;
1725 }
1726
1727 //============================================================================
1728 /*! Function : RemoveVariable
1729  *  Purpose  :
1730  */
1731 //============================================================================
1732 bool SALOMEDSImpl_Study::RemoveVariable(const string& theVarName)
1733 {
1734   SALOMEDSImpl_GenericVariable* aVariable = GetVariable( theVarName );
1735   if( !aVariable )
1736     return false;
1737
1738   string aValue = aVariable->SaveToScript();
1739   ReplaceVariableAttribute( theVarName, aValue );
1740
1741   std::vector<SALOMEDSImpl_GenericVariable*>::iterator it = myNoteBookVars.begin(), itEnd = myNoteBookVars.end();
1742   for( ; it != itEnd; it++ )
1743   {
1744     SALOMEDSImpl_GenericVariable* aVariableRef = *it;
1745     if( aVariableRef && theVarName.compare( aVariableRef->Name() ) == 0 )
1746     {
1747       myNoteBookVars.erase( it );
1748       Modify();
1749       break;
1750     }
1751   }
1752
1753   return true;
1754 }
1755
1756 //============================================================================
1757 /*! Function : RenameVariable
1758  *  Purpose  :
1759  */
1760 //============================================================================
1761 bool SALOMEDSImpl_Study::RenameVariable(const string& theVarName, const string& theNewVarName)
1762 {
1763   SALOMEDSImpl_GenericVariable* aVariable = GetVariable( theVarName );
1764   if( !aVariable )
1765     return false;
1766
1767   ReplaceVariableAttribute( theVarName, theNewVarName );
1768
1769   std::vector<SALOMEDSImpl_GenericVariable*>::iterator it = myNoteBookVars.begin(), itEnd = myNoteBookVars.end();
1770   for( ; it != itEnd; it++ )
1771   {
1772     SALOMEDSImpl_GenericVariable* aVariableRef = *it;
1773     if( aVariableRef && theVarName.compare( aVariableRef->Name() ) == 0 )
1774     {
1775       aVariableRef->setName( theNewVarName );
1776       Modify();
1777       break;
1778     }
1779   }
1780
1781   return true;
1782 }
1783
1784 //============================================================================
1785 /*! Function : IsVariableUsed
1786  *  Purpose  :
1787  */
1788 //============================================================================
1789 bool SALOMEDSImpl_Study::IsVariableUsed(const string& theVarName)
1790 {
1791   return FindVariableAttribute( theVarName );
1792 }
1793
1794 //============================================================================
1795 /*! Function : FindVariableAttribute
1796  *  Purpose  :
1797  */
1798 //============================================================================
1799 bool SALOMEDSImpl_Study::FindVariableAttribute(SALOMEDSImpl_StudyBuilder* theStudyBuilder,
1800                                                SALOMEDSImpl_SObject theSObject,
1801                                                const std::string& theName)
1802 {
1803   SALOMEDSImpl_ChildIterator anIter = NewChildIterator( theSObject );
1804   for( ; anIter.More(); anIter.Next() )
1805     if( FindVariableAttribute( theStudyBuilder, anIter.Value(), theName ) )
1806       return true;
1807
1808   DF_Attribute* anAttr;
1809   if( theStudyBuilder->FindAttribute( theSObject, anAttr, "AttributeString" ) )
1810   {
1811     if( SALOMEDSImpl_AttributeString* aStringAttr = ( SALOMEDSImpl_AttributeString* )anAttr )
1812     {
1813       string aString = aStringAttr->Value();
1814
1815       vector< vector<string> > aSections = ParseVariables( aString );
1816       for( int i = 0, n = aSections.size(); i < n; i++ )
1817       {
1818         vector<string> aVector = aSections[i];
1819         for( int j = 0, m = aVector.size(); j < m; j++ )
1820         {
1821           string aStr = aVector[j];
1822           if( aStr.compare( theName ) == 0 )
1823             return true;
1824         }
1825       }
1826     }
1827   }
1828   return false;
1829 }
1830
1831 //============================================================================
1832 /*! Function : FindVariableAttribute
1833  *  Purpose  :
1834  */
1835 //============================================================================
1836 bool SALOMEDSImpl_Study::FindVariableAttribute(const std::string& theName)
1837 {
1838   SALOMEDSImpl_StudyBuilder* aStudyBuilder = NewBuilder();
1839   SALOMEDSImpl_SComponentIterator aCompIter = NewComponentIterator();
1840   for( ; aCompIter.More(); aCompIter.Next() )
1841   {
1842     SALOMEDSImpl_SObject aComp = aCompIter.Value();
1843     if( FindVariableAttribute( aStudyBuilder, aComp, theName ) )
1844       return true;
1845   }
1846   return false;
1847 }
1848
1849 //============================================================================
1850 /*! Function : ReplaceVariableAttribute
1851  *  Purpose  :
1852  */
1853 //============================================================================
1854 void SALOMEDSImpl_Study::ReplaceVariableAttribute(SALOMEDSImpl_StudyBuilder* theStudyBuilder,
1855                                                   SALOMEDSImpl_SObject theSObject,
1856                                                   const std::string& theSource,
1857                                                   const std::string& theDest)
1858 {
1859   SALOMEDSImpl_ChildIterator anIter = NewChildIterator( theSObject );
1860   for( ; anIter.More(); anIter.Next() )
1861     ReplaceVariableAttribute( theStudyBuilder, anIter.Value(), theSource, theDest );
1862
1863   DF_Attribute* anAttr;
1864   if( theStudyBuilder->FindAttribute( theSObject, anAttr, "AttributeString" ) )
1865   {
1866     if( SALOMEDSImpl_AttributeString* aStringAttr = ( SALOMEDSImpl_AttributeString* )anAttr )
1867     {
1868       bool isChanged = false;
1869       string aNewString, aCurrentString = aStringAttr->Value();
1870
1871       vector< vector<string> > aSections = ParseVariables( aCurrentString );
1872       for( int i = 0, n = aSections.size(); i < n; i++ )
1873       {
1874         vector<string> aVector = aSections[i];
1875         for( int j = 0, m = aVector.size(); j < m; j++ )
1876         {
1877           string aStr = aVector[j];
1878           if( aStr.compare( theSource ) == 0 )
1879           {
1880             isChanged = true;
1881             aStr = theDest;
1882           }
1883
1884           aNewString.append( aStr );
1885           if( j != m - 1 )
1886             aNewString.append( ":" );
1887         }
1888         if( i != n - 1 )
1889           aNewString.append( "|" );
1890       }
1891
1892       if( isChanged )
1893         aStringAttr->SetValue( aNewString );
1894     }
1895   }
1896 }
1897
1898 //============================================================================
1899 /*! Function : ReplaceVariableAttribute
1900  *  Purpose  :
1901  */
1902 //============================================================================
1903 void SALOMEDSImpl_Study::ReplaceVariableAttribute(const std::string& theSource, const std::string& theDest)
1904 {
1905   SALOMEDSImpl_StudyBuilder* aStudyBuilder = NewBuilder();
1906   SALOMEDSImpl_SComponentIterator aCompIter = NewComponentIterator();
1907   for( ; aCompIter.More(); aCompIter.Next() )
1908   {
1909     SALOMEDSImpl_SObject aComp = aCompIter.Value();
1910     ReplaceVariableAttribute( aStudyBuilder, aComp, theSource, theDest );
1911   }
1912 }
1913
1914 //============================================================================
1915 /*! Function : ParseVariables
1916  *  Purpose  :
1917  */
1918 //============================================================================
1919 vector< vector< string > > SALOMEDSImpl_Study::ParseVariables(const string& theVariables) const
1920 {
1921   return SALOMEDSImpl_Tool::splitStringWithEmpty( theVariables, OPERATION_SEPARATOR, VARIABLE_SEPARATOR );
1922 }
1923
1924 //============================================================================
1925 /*! Function : EnableUseCaseAutoFilling
1926  *  Purpose  :
1927  */
1928 //============================================================================
1929 void SALOMEDSImpl_Study::EnableUseCaseAutoFilling(bool isEnabled)
1930
1931   _errorCode = ""; _autoFill = isEnabled; 
1932   if(isEnabled) {
1933     _builder->SetOnAddSObject(_cb);
1934     _builder->SetOnRemoveSObject(_cb);
1935   }
1936   else {
1937     _builder->SetOnAddSObject(NULL);
1938     _builder->SetOnRemoveSObject(NULL);
1939   }
1940 }
1941
1942 //============================================================================
1943 /*! Function : GetIORs
1944  *  Purpose  :
1945  */
1946 //============================================================================
1947 vector<string> SALOMEDSImpl_Study::GetIORs()
1948 {
1949   vector<string> anIORs;
1950   map<string, DF_Label>::const_iterator MI;
1951   for(MI = myIORLabels.begin(); MI!=myIORLabels.end(); MI++)
1952     anIORs.push_back(MI->first);
1953
1954   return anIORs;
1955 }