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