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