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