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