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