Salome HOME
tag 5.1.2 --> 5.1.3
[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 << "# -*- coding: iso-8859-1 -*-\n" << endl;
1224
1225   fp << GetDumpStudyComment() << endl << endl;
1226   fp << "import sys" << endl;
1227   fp << "import " << aBatchModeScript << endl << endl;
1228
1229   fp << aBatchModeScript << ".salome_init()" << endl << endl;
1230
1231   fp << _GetNoteBookAccess();
1232
1233   fp << "sys.path.insert( 0, r\'" << thePath << "\')" << endl << endl;
1234
1235   //Dump NoteBook Variables
1236   fp << _GetStudyVariablesScript();
1237
1238   //Check if it's necessary to dump visual parameters
1239   bool isDumpVisuals = SALOMEDSImpl_IParameters::isDumpPython(this);
1240   int lastSavePoint = -1;
1241   if(isDumpVisuals) {
1242     lastSavePoint = SALOMEDSImpl_IParameters::getLastSavePoint(this);
1243     if(lastSavePoint > 0) {
1244       fp << SALOMEDSImpl_IParameters::getStudyScript(this, lastSavePoint) << endl << endl;
1245     }
1246   }
1247   
1248
1249   vector<string> aSeqOfFileNames;
1250
1251   //Iterate all components and create the componponents specific scripts.
1252   bool isOk = true;
1253   int aLength = aSeq.size();
1254   for(int i = 1; i <= aLength; i++) {
1255
1256     aCompType = aSeq[i-1];
1257     SALOMEDSImpl_SComponent sco = FindComponent(aCompType);
1258     SALOMEDSImpl_Driver* aDriver = NULL;
1259     // if there is an associated Engine call its method for saving
1260     string IOREngine;
1261     try {
1262       if (!sco.ComponentIOR(IOREngine)) {
1263         if (!aCompType.empty()) {
1264
1265           aDriver = theFactory->GetDriverByType(aCompType);
1266
1267           if (aDriver != NULL) {
1268             SALOMEDSImpl_StudyBuilder* SB = NewBuilder();
1269             if(!SB->LoadWith(sco, aDriver)) {
1270               _errorCode = SB->GetErrorCode();
1271               return false;
1272             }
1273           }
1274           else continue;
1275         }
1276       }
1277       else {
1278         aDriver = theFactory->GetDriverByIOR(IOREngine);
1279       }
1280     } catch(...) {
1281       _errorCode = "Can not restore information to dump it";
1282       return false;
1283     }
1284
1285     if(aDriver == NULL) continue;
1286
1287     bool isValidScript;
1288     long aStreamLength  = 0;
1289     SALOMEDSImpl_TMPFile* aStream = aDriver->DumpPython(this, isPublished, isValidScript, aStreamLength);
1290     if ( !isValidScript )
1291       isOk = false;
1292
1293     //Create a file that will contain the component specific script
1294     fstream fp2;
1295 #ifdef WIN32
1296     aFileName=thePath+string("\\");
1297 #else
1298     aFileName=thePath+string("/");
1299 #endif
1300     string aScriptName;
1301     aScriptName += theBaseName;
1302     aScriptName += "_";
1303     aScriptName += aCompType;
1304
1305     aFileName += aScriptName+ string(".py");
1306     aSeqOfFileNames.push_back(aFileName);
1307
1308     fp2.open(aFileName.c_str(), ios::out);
1309
1310 #ifdef WIN32
1311     isOpened = fp2.is_open();
1312 #else
1313     isOpened = fp2.rdbuf()->is_open();
1314 #endif
1315
1316     if(!isOpened) {
1317       _errorCode = string("Can't create a file ")+aFileName;
1318       SALOMEDSImpl_Tool::RemoveTemporaryFiles(thePath, aSeqOfFileNames, false);
1319       return false;
1320     }
1321
1322     //Output the Python script generated by the component in the newly created file.
1323     fp2 << aStream->Data();
1324     fp2.close();
1325
1326     if(aStream) delete aStream;
1327
1328     //Add to the main script a call to RebuildData of the generated by the component the Python script
1329     fp << "import " << aScriptName << endl;
1330     fp << aScriptName << ".RebuildData(" << aBatchModeScript << ".myStudy)" << endl;
1331   }
1332
1333   fp << endl;
1334   fp << "if salome.sg.hasDesktop():" << endl;
1335   fp << "\tsalome.sg.updateObjBrowser(1)" << endl;
1336
1337   if(isDumpVisuals) { //Output the call to Session's method restoreVisualState
1338     fp << "\tiparameters.getSession().restoreVisualState(1)" << endl;
1339   }
1340
1341
1342   fp.close();
1343   return isOk;
1344 }
1345
1346 //=======================================================================
1347 //function : GetDumpStudyComment
1348 //purpose  : return a header comment for a DumpStudy script
1349 //=======================================================================
1350
1351 string SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
1352 {
1353   string txt
1354     ("### This file is generated by SALOME automatically by dump python functionality");
1355   if ( theComponentName )
1356     txt += string(" of ") + (char*) theComponentName + " component";
1357   return txt;
1358 }
1359
1360 void dumpSO(const SALOMEDSImpl_SObject& theSO,
1361             fstream& fp,
1362             const string& Tab,
1363             SALOMEDSImpl_Study* theStudy);
1364
1365 //============================================================================
1366 /*! Function : dump
1367  *  Purpose  :
1368  */
1369 //============================================================================
1370 void SALOMEDSImpl_Study::dump(const string& theFileName)
1371 {
1372   //Create a file that will contain a main Study script
1373   fstream fp;
1374   fp.open(theFileName.c_str(), ios::out);
1375
1376 #ifdef WIN32
1377   bool isOpened = fp.is_open();
1378 #else
1379   bool isOpened = fp.rdbuf()->is_open();
1380 #endif
1381
1382   if(!isOpened) {
1383     _errorCode = string("Can't create a file ")+theFileName;
1384     cout << "### SALOMEDSImpl_Study::dump Error: " << _errorCode << endl;
1385     return;
1386   }
1387
1388   SALOMEDSImpl_SObject aSO = FindObjectID("0:1");
1389   fp << "0:1" << endl;
1390   SALOMEDSImpl_ChildIterator Itr = NewChildIterator(aSO);
1391   string aTab("   ");
1392   for(; Itr.More(); Itr.Next()) {
1393     dumpSO(Itr.Value(), fp, aTab, this);
1394   }
1395
1396   fp.close();
1397 }
1398
1399
1400 void dumpSO(const SALOMEDSImpl_SObject& theSO,
1401             fstream& fp,
1402             const string& Tab,
1403             SALOMEDSImpl_Study* theStudy)
1404 {
1405   string aTab(Tab), anID(theSO.GetID());
1406   fp << aTab << anID << endl;
1407   vector<DF_Attribute*> attribs = theSO.GetLabel().GetAttributes();
1408   for(int i = 0; i<attribs.size(); i++) {
1409     SALOMEDSImpl_GenericAttribute* anAttr = dynamic_cast<SALOMEDSImpl_GenericAttribute*>(attribs[i]);
1410
1411     if(!anAttr) {
1412       continue;
1413     }
1414
1415     string aType = anAttr->GetClassType();
1416     fp << Tab << "  -- " << aType;
1417
1418     if(aType == string("AttributeReal")) {
1419       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeReal*>(anAttr)->Value();
1420     }
1421     else if(aType == string("AttributeInteger")) {
1422       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeInteger*>(anAttr)->Value();
1423     }
1424     else if(aType ==  string("AttributeName")) {
1425       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeName*>(anAttr)->Value();
1426     }
1427     else if(aType == string("AttributeComment")) {
1428       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeComment*>(anAttr)->Value();
1429     }
1430     else if(aType == string("AttributeReference")) {
1431       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeReference*>(anAttr)->Save();
1432     }
1433     fp << endl;
1434   }
1435
1436   SALOMEDSImpl_ChildIterator Itr = theStudy->NewChildIterator(theSO);
1437   string aNewTab("   ");
1438   aNewTab+=aTab;
1439   for(; Itr.More(); Itr.Next()) {
1440     dumpSO(Itr.Value(), fp, aNewTab, theStudy);
1441   }
1442
1443   return;
1444 }
1445
1446 void SALOMEDSImpl_Study::Modify()
1447 {
1448   _errorCode = "";
1449   _doc->SetModified(true);
1450 }
1451
1452 //============================================================================
1453 /*! Function : 
1454  *  Purpose  :
1455  */
1456 //============================================================================
1457 SALOMEDSImpl_AttributeParameter* SALOMEDSImpl_Study::GetCommonParameters(const char* theID, int theSavePoint)
1458 {
1459   if (theSavePoint < 0) return NULL;
1460   SALOMEDSImpl_StudyBuilder* builder = NewBuilder();
1461   SALOMEDSImpl_SObject so = FindComponent((char*)theID);
1462   if (!so) so = builder->NewComponent((char*)theID);
1463   SALOMEDSImpl_AttributeParameter* attParam = NULL;
1464
1465   if (theSavePoint > 0) { // Try to find SObject that contains attribute parameter ...
1466     DF_Label savePointLabel = so.GetLabel().FindChild( theSavePoint, /*create=*/0 );
1467     if ( !savePointLabel.IsNull() )
1468       so = GetSObject( savePointLabel );
1469     else // ... if it does not exist - create a new one
1470       so = builder->NewObjectToTag( so, theSavePoint );
1471   }
1472
1473   DF_Attribute* A;
1474   if (so) {
1475     builder->FindAttribute(so, A, "AttributeParameter");
1476     if ( !A ) { // first call of GetCommonParameters on "Interface Applicative" component
1477       A = builder->FindOrCreateAttribute(so, "AttributeParameter"); 
1478     }
1479     attParam = dynamic_cast<SALOMEDSImpl_AttributeParameter*>( A );
1480   }
1481   return attParam;
1482 }
1483
1484 //============================================================================
1485 /*! Function : 
1486  *  Purpose  :
1487  */
1488 //============================================================================
1489 SALOMEDSImpl_AttributeParameter* SALOMEDSImpl_Study::GetModuleParameters(const char* theID, 
1490                                                                          const char* theModuleName,
1491                                                                          int theSavePoint)
1492 {
1493   if(theSavePoint <= 0) return NULL;
1494   SALOMEDSImpl_AttributeParameter* main_ap = GetCommonParameters(theID, theSavePoint);
1495   SALOMEDSImpl_SObject main_so = main_ap->GetSObject();
1496   SALOMEDSImpl_AttributeParameter* par = NULL;
1497
1498   SALOMEDSImpl_ChildIterator it = NewChildIterator(main_so);
1499   string moduleName(theModuleName);
1500   for(; it.More(); it.Next()) {
1501     SALOMEDSImpl_SObject so(it.Value());
1502     if((par=(SALOMEDSImpl_AttributeParameter*)so.GetLabel().FindAttribute(SALOMEDSImpl_AttributeParameter::GetID()))) {
1503       if(!par->IsSet("AP_MODULE_NAME", (Parameter_Types)3)) continue; //3 -> PT_STRING
1504       if(par->GetString("AP_MODULE_NAME") == moduleName) return par;
1505     }
1506   }
1507
1508   SALOMEDSImpl_StudyBuilder* builder = NewBuilder();
1509   SALOMEDSImpl_SObject so = builder->NewObject(main_so);
1510   par  = dynamic_cast<SALOMEDSImpl_AttributeParameter*>(builder->FindOrCreateAttribute(so, "AttributeParameter"));
1511   par->SetString("AP_MODULE_NAME", moduleName);
1512   return par;
1513 }
1514
1515 //============================================================================
1516 /*! Function : SetStudyLock
1517  *  Purpose  :
1518  */
1519 //============================================================================
1520 void SALOMEDSImpl_Study::SetStudyLock(const char* theLockerID)
1521 {
1522   _lockers.push_back(theLockerID);
1523 }
1524
1525 //============================================================================
1526 /*! Function : IsStudyLocked
1527  *  Purpose  :
1528  */
1529 //============================================================================
1530 bool SALOMEDSImpl_Study::IsStudyLocked()
1531 {
1532   return (_lockers.size() > 0);
1533 }
1534
1535 //============================================================================
1536 /*! Function : UnLockStudy
1537  *  Purpose  :
1538  */
1539 //============================================================================
1540 void SALOMEDSImpl_Study::UnLockStudy(const char* theLockerID)
1541 {
1542   vector<string>::iterator vsI = _lockers.begin();
1543   int length = _lockers.size();
1544   bool isFound = false;
1545   string id(theLockerID);
1546   for(int i = 0; i<length; i++, vsI++) {
1547     if(id == _lockers[i]) {
1548       isFound = true;;
1549       break;
1550     }
1551   }
1552   if(isFound) _lockers.erase(vsI);
1553 }
1554   
1555 //============================================================================
1556 /*! Function : GetLockerID
1557  *  Purpose  :
1558  */
1559 //============================================================================
1560 vector<string> SALOMEDSImpl_Study::GetLockerID()
1561 {
1562   return _lockers;
1563 }
1564
1565 //============================================================================
1566 /*! Function : SetVariable
1567  *  Purpose  :
1568  */
1569 //============================================================================
1570 void SALOMEDSImpl_Study::SetVariable(const string& theVarName,
1571                                      const double theValue,
1572                                      const SALOMEDSImpl_GenericVariable::VariableTypes theType)
1573 {
1574   bool modified = false;
1575   SALOMEDSImpl_GenericVariable* aGVar = GetVariable(theVarName);
1576   
1577   if( aGVar == NULL ) {
1578
1579     SALOMEDSImpl_ScalarVariable* aSVar = new SALOMEDSImpl_ScalarVariable(theType, theVarName);
1580
1581     aSVar->setValue(theValue);
1582     myNoteBookVars.push_back(aSVar);
1583     modified = true;
1584   }
1585   else {
1586     if(SALOMEDSImpl_ScalarVariable* aSVar = dynamic_cast<SALOMEDSImpl_ScalarVariable*>(aGVar)) {
1587       modified = aSVar->setValue(theValue) || modified;
1588       modified = aSVar->setType(theType) || modified;
1589     }
1590   }
1591   if(modified)
1592     Modify();
1593 }
1594
1595 //============================================================================
1596 /*! Function : SetStringVariable
1597  *  Purpose  :
1598  */
1599 //============================================================================
1600 void SALOMEDSImpl_Study::SetStringVariable(const string& theVarName,
1601                                            const string& theValue,
1602                                            const SALOMEDSImpl_GenericVariable::VariableTypes theType)
1603 {
1604   bool modified = false;
1605   SALOMEDSImpl_GenericVariable* aGVar = GetVariable(theVarName);
1606   
1607   if( aGVar == NULL ) {
1608     
1609     SALOMEDSImpl_ScalarVariable* aSVar = new SALOMEDSImpl_ScalarVariable(theType, theVarName);
1610     
1611     aSVar->setStringValue(theValue);
1612     myNoteBookVars.push_back(aSVar);
1613     modified = true;
1614   }
1615   else {
1616     if(SALOMEDSImpl_ScalarVariable* aSVar = dynamic_cast<SALOMEDSImpl_ScalarVariable*>(aGVar)) {
1617       modified = aSVar->setStringValue(theValue) || modified;
1618       modified = aSVar->setType(theType) || modified;
1619     }
1620   }
1621   if(modified)
1622     Modify();
1623 }
1624
1625 //============================================================================
1626 /*! Function : SetStringVariableAsDouble
1627  *  Purpose  :
1628  */
1629 //============================================================================
1630 void SALOMEDSImpl_Study::SetStringVariableAsDouble(const string& theVarName,
1631                                                    const double theValue,
1632                                                    const SALOMEDSImpl_GenericVariable::VariableTypes theType)
1633 {
1634   SALOMEDSImpl_GenericVariable* aGVar = GetVariable(theVarName);
1635   if(SALOMEDSImpl_ScalarVariable* aSVar = dynamic_cast<SALOMEDSImpl_ScalarVariable*>(aGVar))
1636     aSVar->setValue(theValue);
1637 }
1638
1639 //============================================================================
1640 /*! Function : GetReal
1641  *  Purpose  :
1642  */
1643 //============================================================================
1644 double SALOMEDSImpl_Study::GetVariableValue(const string& theVarName)
1645 {
1646   SALOMEDSImpl_GenericVariable* aGVar = GetVariable(theVarName);
1647   
1648   if(aGVar != NULL )
1649     if(SALOMEDSImpl_ScalarVariable* aSVar = dynamic_cast<SALOMEDSImpl_ScalarVariable*>(aGVar))
1650       return aSVar->getValue();
1651
1652   return 0;
1653 }
1654
1655 //============================================================================
1656 /*! Function : GetString
1657  *  Purpose  :
1658  */
1659 //============================================================================
1660 string SALOMEDSImpl_Study::GetStringVariableValue(const string& theVarName)
1661 {
1662   SALOMEDSImpl_GenericVariable* aGVar = GetVariable(theVarName);
1663   
1664   if(aGVar != NULL )
1665     if(SALOMEDSImpl_ScalarVariable* aSVar = dynamic_cast<SALOMEDSImpl_ScalarVariable*>(aGVar))
1666       return aSVar->getStringValue();
1667   
1668   return 0;
1669 }
1670
1671 //============================================================================
1672 /*! Function : IsTypeOf
1673  *  Purpose  :
1674  */
1675 //============================================================================
1676 bool SALOMEDSImpl_Study::IsTypeOf(const string& theVarName,
1677                                   SALOMEDSImpl_GenericVariable::
1678                                   VariableTypes theType) const
1679 {
1680   SALOMEDSImpl_GenericVariable* aGVar = GetVariable(theVarName);
1681   
1682   if(aGVar != NULL )
1683     return aGVar->Type() == theType;
1684   
1685   return false;
1686 }
1687
1688 //============================================================================
1689 /*! Function : IsVariable
1690  *  Purpose  :
1691  */
1692 //============================================================================
1693 bool SALOMEDSImpl_Study::IsVariable(const string& theVarName) const
1694 {
1695   SALOMEDSImpl_GenericVariable* aGVar = GetVariable(theVarName);
1696   return (aGVar != NULL);
1697 }
1698
1699 //============================================================================
1700 /*! Function : GetVariableNames
1701  *  Purpose  :
1702  */
1703 //============================================================================
1704 vector<string> SALOMEDSImpl_Study::GetVariableNames() const
1705 {
1706   vector<string> aResult;
1707
1708   for(int i = 0; i < myNoteBookVars.size(); i++)
1709     aResult.push_back(myNoteBookVars[i]->Name());
1710   
1711   return aResult;
1712 }
1713
1714 //============================================================================
1715 /*! Function : AddVariable
1716  *  Purpose  :
1717  */
1718 //============================================================================
1719 void SALOMEDSImpl_Study::AddVariable(SALOMEDSImpl_GenericVariable* theVariable)
1720 {
1721   myNoteBookVars.push_back(theVariable);
1722 }
1723
1724 //============================================================================
1725 /*! Function : AddVariable
1726  *  Purpose  :
1727  */
1728 //============================================================================
1729 SALOMEDSImpl_GenericVariable* SALOMEDSImpl_Study::GetVariable(const std::string& theName) const
1730 {
1731   SALOMEDSImpl_GenericVariable* aResult = NULL;
1732   for(int i = 0; i < myNoteBookVars.size();i++) {
1733     if(theName.compare(myNoteBookVars[i]->Name()) == 0) {
1734       aResult = myNoteBookVars[i];
1735       break;
1736     }  
1737   }
1738   return aResult;
1739 }
1740
1741 //============================================================================
1742 /*! Function : RemoveVariable
1743  *  Purpose  :
1744  */
1745 //============================================================================
1746 bool SALOMEDSImpl_Study::RemoveVariable(const string& theVarName)
1747 {
1748   SALOMEDSImpl_GenericVariable* aVariable = GetVariable( theVarName );
1749   if( !aVariable )
1750     return false;
1751
1752   string aValue = aVariable->SaveToScript();
1753   ReplaceVariableAttribute( theVarName, aValue );
1754
1755   std::vector<SALOMEDSImpl_GenericVariable*>::iterator it = myNoteBookVars.begin(), itEnd = myNoteBookVars.end();
1756   for( ; it != itEnd; it++ )
1757   {
1758     SALOMEDSImpl_GenericVariable* aVariableRef = *it;
1759     if( aVariableRef && theVarName.compare( aVariableRef->Name() ) == 0 )
1760     {
1761       myNoteBookVars.erase( it );
1762       Modify();
1763       break;
1764     }
1765   }
1766
1767   return true;
1768 }
1769
1770 //============================================================================
1771 /*! Function : RenameVariable
1772  *  Purpose  :
1773  */
1774 //============================================================================
1775 bool SALOMEDSImpl_Study::RenameVariable(const string& theVarName, const string& theNewVarName)
1776 {
1777   SALOMEDSImpl_GenericVariable* aVariable = GetVariable( theVarName );
1778   if( !aVariable )
1779     return false;
1780
1781   ReplaceVariableAttribute( theVarName, theNewVarName );
1782
1783   std::vector<SALOMEDSImpl_GenericVariable*>::iterator it = myNoteBookVars.begin(), itEnd = myNoteBookVars.end();
1784   for( ; it != itEnd; it++ )
1785   {
1786     SALOMEDSImpl_GenericVariable* aVariableRef = *it;
1787     if( aVariableRef && theVarName.compare( aVariableRef->Name() ) == 0 )
1788     {
1789       aVariableRef->setName( theNewVarName );
1790       Modify();
1791       break;
1792     }
1793   }
1794
1795   return true;
1796 }
1797
1798 //============================================================================
1799 /*! Function : IsVariableUsed
1800  *  Purpose  :
1801  */
1802 //============================================================================
1803 bool SALOMEDSImpl_Study::IsVariableUsed(const string& theVarName)
1804 {
1805   return FindVariableAttribute( theVarName );
1806 }
1807
1808 //============================================================================
1809 /*! Function : FindVariableAttribute
1810  *  Purpose  :
1811  */
1812 //============================================================================
1813 bool SALOMEDSImpl_Study::FindVariableAttribute(SALOMEDSImpl_StudyBuilder* theStudyBuilder,
1814                                                SALOMEDSImpl_SObject theSObject,
1815                                                const std::string& theName)
1816 {
1817   SALOMEDSImpl_ChildIterator anIter = NewChildIterator( theSObject );
1818   for( ; anIter.More(); anIter.Next() )
1819     if( FindVariableAttribute( theStudyBuilder, anIter.Value(), theName ) )
1820       return true;
1821
1822   DF_Attribute* anAttr;
1823   if( theStudyBuilder->FindAttribute( theSObject, anAttr, "AttributeString" ) )
1824   {
1825     if( SALOMEDSImpl_AttributeString* aStringAttr = ( SALOMEDSImpl_AttributeString* )anAttr )
1826     {
1827       string aString = aStringAttr->Value();
1828
1829       vector< vector<string> > aSections = ParseVariables( aString );
1830       for( int i = 0, n = aSections.size(); i < n; i++ )
1831       {
1832         vector<string> aVector = aSections[i];
1833         for( int j = 0, m = aVector.size(); j < m; j++ )
1834         {
1835           string aStr = aVector[j];
1836           if( aStr.compare( theName ) == 0 )
1837             return true;
1838         }
1839       }
1840     }
1841   }
1842   return false;
1843 }
1844
1845 //============================================================================
1846 /*! Function : FindVariableAttribute
1847  *  Purpose  :
1848  */
1849 //============================================================================
1850 bool SALOMEDSImpl_Study::FindVariableAttribute(const std::string& theName)
1851 {
1852   SALOMEDSImpl_StudyBuilder* aStudyBuilder = NewBuilder();
1853   SALOMEDSImpl_SComponentIterator aCompIter = NewComponentIterator();
1854   for( ; aCompIter.More(); aCompIter.Next() )
1855   {
1856     SALOMEDSImpl_SObject aComp = aCompIter.Value();
1857     if( FindVariableAttribute( aStudyBuilder, aComp, theName ) )
1858       return true;
1859   }
1860   return false;
1861 }
1862
1863 //============================================================================
1864 /*! Function : ReplaceVariableAttribute
1865  *  Purpose  :
1866  */
1867 //============================================================================
1868 void SALOMEDSImpl_Study::ReplaceVariableAttribute(SALOMEDSImpl_StudyBuilder* theStudyBuilder,
1869                                                   SALOMEDSImpl_SObject theSObject,
1870                                                   const std::string& theSource,
1871                                                   const std::string& theDest)
1872 {
1873   SALOMEDSImpl_ChildIterator anIter = NewChildIterator( theSObject );
1874   for( ; anIter.More(); anIter.Next() )
1875     ReplaceVariableAttribute( theStudyBuilder, anIter.Value(), theSource, theDest );
1876
1877   DF_Attribute* anAttr;
1878   if( theStudyBuilder->FindAttribute( theSObject, anAttr, "AttributeString" ) )
1879   {
1880     if( SALOMEDSImpl_AttributeString* aStringAttr = ( SALOMEDSImpl_AttributeString* )anAttr )
1881     {
1882       bool isChanged = false;
1883       string aNewString, aCurrentString = aStringAttr->Value();
1884
1885       vector< vector<string> > aSections = ParseVariables( aCurrentString );
1886       for( int i = 0, n = aSections.size(); i < n; i++ )
1887       {
1888         vector<string> aVector = aSections[i];
1889         for( int j = 0, m = aVector.size(); j < m; j++ )
1890         {
1891           string aStr = aVector[j];
1892           if( aStr.compare( theSource ) == 0 )
1893           {
1894             isChanged = true;
1895             aStr = theDest;
1896           }
1897
1898           aNewString.append( aStr );
1899           if( j != m - 1 )
1900             aNewString.append( ":" );
1901         }
1902         if( i != n - 1 )
1903           aNewString.append( "|" );
1904       }
1905
1906       if( isChanged )
1907         aStringAttr->SetValue( aNewString );
1908     }
1909   }
1910 }
1911
1912 //============================================================================
1913 /*! Function : ReplaceVariableAttribute
1914  *  Purpose  :
1915  */
1916 //============================================================================
1917 void SALOMEDSImpl_Study::ReplaceVariableAttribute(const std::string& theSource, const std::string& theDest)
1918 {
1919   SALOMEDSImpl_StudyBuilder* aStudyBuilder = NewBuilder();
1920   SALOMEDSImpl_SComponentIterator aCompIter = NewComponentIterator();
1921   for( ; aCompIter.More(); aCompIter.Next() )
1922   {
1923     SALOMEDSImpl_SObject aComp = aCompIter.Value();
1924     ReplaceVariableAttribute( aStudyBuilder, aComp, theSource, theDest );
1925   }
1926 }
1927
1928 //============================================================================
1929 /*! Function : ParseVariables
1930  *  Purpose  :
1931  */
1932 //============================================================================
1933 vector< vector< string > > SALOMEDSImpl_Study::ParseVariables(const string& theVariables) const
1934 {
1935   return SALOMEDSImpl_Tool::splitStringWithEmpty( theVariables, OPERATION_SEPARATOR, VARIABLE_SEPARATOR );
1936 }
1937
1938 //============================================================================
1939 /*! Function : EnableUseCaseAutoFilling
1940  *  Purpose  :
1941  */
1942 //============================================================================
1943 void SALOMEDSImpl_Study::EnableUseCaseAutoFilling(bool isEnabled)
1944
1945   _errorCode = ""; _autoFill = isEnabled; 
1946   if(isEnabled) {
1947     _builder->SetOnAddSObject(_cb);
1948     _builder->SetOnRemoveSObject(_cb);
1949   }
1950   else {
1951     _builder->SetOnAddSObject(NULL);
1952     _builder->SetOnRemoveSObject(NULL);
1953   }
1954 }
1955
1956 //============================================================================
1957 /*! Function : GetIORs
1958  *  Purpose  :
1959  */
1960 //============================================================================
1961 vector<string> SALOMEDSImpl_Study::GetIORs()
1962 {
1963   vector<string> anIORs;
1964   map<string, DF_Label>::const_iterator MI;
1965   for(MI = myIORLabels.begin(); MI!=myIORLabels.end(); MI++)
1966     anIORs.push_back(MI->first);
1967
1968   return anIORs;
1969 }