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