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