Salome HOME
Merge from V5_1_4_BR 07/05/2010
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_StudyBuilder.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_StudyBuilder.cxx
24 //  Author : Sergey RUIN
25 //  Module : SALOME
26 //
27 #include "SALOMEDSImpl_Attributes.hxx"
28 #include "SALOMEDSImpl_Study.hxx"
29 #include "SALOMEDSImpl_StudyBuilder.hxx"
30 #include "SALOMEDSImpl_SObject.hxx"
31 #include "SALOMEDSImpl_SComponent.hxx"
32 #include "SALOMEDSImpl_Tool.hxx"
33 #include "SALOMEDSImpl_ChildNodeIterator.hxx"
34
35 #include "DF_ChildIterator.hxx"
36 #include "DF_Label.hxx"
37
38 #include <HDFOI.hxx>
39 #include <stdlib.h> 
40 #include <string.h> 
41
42 #define USE_CASE_LABEL_TAG            2
43 #define DIRECTORYID                   16661
44 #define FILELOCALID                   26662 
45
46 static void Translate_persistentID_to_IOR(DF_Label& Lab, SALOMEDSImpl_Driver* driver, bool isMultiFile, bool isASCII);
47
48 //============================================================================
49 /*! Function : constructor
50  *  Purpose  :
51  */
52 //============================================================================
53 SALOMEDSImpl_StudyBuilder::SALOMEDSImpl_StudyBuilder(const SALOMEDSImpl_Study* theOwner)
54 {
55    _errorCode = "";
56   _callbackOnAdd=NULL;
57   _callbackOnRemove = NULL;
58    _study = (SALOMEDSImpl_Study*)theOwner;
59    _doc = _study->GetDocument();
60 }
61
62 //============================================================================
63 /*! Function : destructor
64  *  Purpose  :
65  */
66 //============================================================================
67 SALOMEDSImpl_StudyBuilder::~SALOMEDSImpl_StudyBuilder()
68 {}
69
70 //============================================================================
71 /*! Function : NewComponent
72  *  Purpose  : Create a new component (Scomponent)
73  */
74 //============================================================================
75 SALOMEDSImpl_SComponent SALOMEDSImpl_StudyBuilder::NewComponent(const std::string& DataType)
76 {
77   _errorCode = "";
78   CheckLocked();
79
80   SALOMEDSImpl_SComponent sco;
81
82   if(DataType.size() == 0) return sco;
83
84   //Always create component under main label.
85   DF_Label L  = _doc->Main();
86
87   DF_Label NL = L.NewChild();
88
89   SALOMEDSImpl_AttributeComment::Set(NL, DataType);
90
91   SALOMEDSImpl_SComponent so =  _study->GetSComponent (NL);
92
93   if(_callbackOnAdd) _callbackOnAdd->OnAddSObject(so);
94
95   _doc->SetModified(true);
96
97   return so;
98 }
99
100 //============================================================================
101 /*! Function : DefineComponentInstance
102  *  Purpose  : Add IOR attribute of a Scomponent
103  */
104 //============================================================================
105 bool SALOMEDSImpl_StudyBuilder::DefineComponentInstance(const SALOMEDSImpl_SComponent& aComponent,
106                                                         const std::string& IOR)
107 {
108    _errorCode = "";
109
110   CheckLocked();
111   if(!aComponent || IOR.empty()) {
112     _errorCode = "Invalid arguments";
113     return false;
114   }
115   //add IOR definition 
116   SALOMEDSImpl_AttributeIOR::Set(aComponent.GetLabel(), IOR);  
117
118   return true;
119 }
120
121 //============================================================================
122 /*! Function : RemoveComponent
123  *  Purpose  : Delete a Scomponent
124  */
125 //============================================================================
126 bool SALOMEDSImpl_StudyBuilder::RemoveComponent(const SALOMEDSImpl_SComponent& aComponent)
127 {
128    _errorCode = "";
129   CheckLocked();
130   return RemoveObject(aComponent);
131 }
132
133 //============================================================================
134 /*! Function : NewObject
135  *  Purpose  : Create a new SObject
136  */
137 //============================================================================
138 SALOMEDSImpl_SObject SALOMEDSImpl_StudyBuilder::NewObject(const SALOMEDSImpl_SObject& theFatherObject)
139 {
140   _errorCode = "";
141   CheckLocked();
142
143   //Find label of father
144   DF_Label Lab = theFatherObject.GetLabel();
145   
146   //Create a new label
147   DF_Label NewLab = Lab.NewChild();
148   
149   SALOMEDSImpl_SObject so = _study->GetSObject(NewLab);
150   if(_callbackOnAdd) _callbackOnAdd->OnAddSObject(so);
151
152   _doc->SetModified(true);  
153   return so;
154 }
155
156 //============================================================================
157 /*! Function : NewObjectToTag
158  *  Purpose  :
159  */
160 //============================================================================
161 SALOMEDSImpl_SObject SALOMEDSImpl_StudyBuilder::NewObjectToTag(const SALOMEDSImpl_SObject& theFatherObject,
162                                                         const int theTag)
163 {
164   _errorCode = "";
165   CheckLocked();
166   //Find label of father
167   DF_Label Lab = theFatherObject.GetLabel();
168
169   //Create or find label
170   DF_Label NewLab = Lab.FindChild(theTag, 1);
171
172   SALOMEDSImpl_SObject so = _study->GetSObject(NewLab);
173
174   if(_callbackOnAdd) _callbackOnAdd->OnAddSObject(so);
175
176   _doc->SetModified(true);  
177   return so;
178 }
179
180 //============================================================================
181 /*! Function : RemoveObject
182  *  Purpose  :
183  */
184 //============================================================================
185 bool SALOMEDSImpl_StudyBuilder::RemoveObject(const SALOMEDSImpl_SObject& anObject)
186 {
187    _errorCode = "";
188   CheckLocked();
189   if(!anObject) {
190     _errorCode = "Null object";
191     return false;
192   }
193
194   if(_callbackOnRemove) _callbackOnRemove->OnRemoveSObject(anObject);
195
196   DF_Label Lab = anObject.GetLabel();
197
198   SALOMEDSImpl_AttributeReference* aReference = NULL;
199   if ((aReference=(SALOMEDSImpl_AttributeReference*)Lab.FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
200     SALOMEDSImpl_AttributeTarget* aTarget = NULL;
201     if ((aTarget=(SALOMEDSImpl_AttributeTarget*)aReference->Get().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID())))
202       aTarget->Remove(SALOMEDSImpl_Study::SObject(Lab));
203   }
204
205   SALOMEDSImpl_AttributeIOR* anAttr = NULL; //Remove from IORLabel map
206   if ((anAttr=(SALOMEDSImpl_AttributeIOR*)Lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
207     _study->DeleteIORLabelMapItem(anAttr->Value());
208   }
209
210   Lab.ForgetAllAttributes();
211  
212   _doc->SetModified(true);  
213     
214   return true;
215 }
216
217 //============================================================================
218 /*! Function : RemoveObjectWithChildren
219  *  Purpose  :
220  */
221 //============================================================================
222 bool SALOMEDSImpl_StudyBuilder::RemoveObjectWithChildren(const SALOMEDSImpl_SObject& anObject)
223 {
224    _errorCode = "";
225   CheckLocked();
226   if(!anObject) {
227     _errorCode = "Null object";
228     return false;
229   }
230
231   if(_callbackOnRemove) _callbackOnRemove->OnRemoveSObject(anObject);
232
233   DF_Label Lab = anObject.GetLabel();
234
235   SALOMEDSImpl_AttributeReference* aReference = NULL;
236   if ((aReference=(SALOMEDSImpl_AttributeReference*)Lab.FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
237     SALOMEDSImpl_AttributeTarget* aTarget = NULL;
238     if ((aTarget=(SALOMEDSImpl_AttributeTarget*)aReference->Get().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID())))
239       aTarget->Remove(SALOMEDSImpl_Study::SObject(Lab));
240   }
241   SALOMEDSImpl_AttributeIOR* anAttr = NULL; //Remove from IORLabel map
242   if ((anAttr=(SALOMEDSImpl_AttributeIOR*)Lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
243     _study->DeleteIORLabelMapItem(anAttr->Value());
244   }
245
246   DF_ChildIterator it(Lab, true);
247   for(;it.More();it.Next()) {
248     DF_Label aLabel = it.Value();
249     if ((aReference=(SALOMEDSImpl_AttributeReference*)aLabel.FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
250       SALOMEDSImpl_AttributeTarget* aTarget = NULL;
251       if ((aTarget=(SALOMEDSImpl_AttributeTarget*)aReference->Get().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID())))
252         aTarget->Remove(SALOMEDSImpl_Study::SObject(aLabel));
253     }
254     SALOMEDSImpl_AttributeIOR* anAttr = NULL; //Remove from IORLabel map
255     if ((anAttr=(SALOMEDSImpl_AttributeIOR*)aLabel.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
256       _study->DeleteIORLabelMapItem(anAttr->Value());
257     }
258   }
259
260   Lab.ForgetAllAttributes(true);
261
262   _doc->SetModified(true);  
263   
264   return true;
265 }
266
267 //============================================================================
268 /*! Function : LoadWith
269  *  Purpose  : 
270  */
271 //============================================================================
272 bool SALOMEDSImpl_StudyBuilder::LoadWith(const SALOMEDSImpl_SComponent& anSCO,
273                                          SALOMEDSImpl_Driver* aDriver) 
274 {
275   _errorCode = "";
276
277   DF_Label Lab = anSCO.GetLabel();
278   SALOMEDSImpl_AttributePersistentRef* Att = NULL;
279
280   //Find the current Url of the study  
281   if ((Att=(SALOMEDSImpl_AttributePersistentRef*)_doc->Main().FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID()))) {
282     int aLocked = _study->GetProperties()->IsLocked();
283     if (aLocked) _study->GetProperties()->SetLocked(false);
284
285     std::string Res(Att->Value());
286     std::string aHDFPath(Res);
287
288     SALOMEDSImpl_AttributeComment* type = NULL;
289     std::string DataType;
290     if ((type=(SALOMEDSImpl_AttributeComment*)Lab.FindAttribute(SALOMEDSImpl_AttributeComment::GetID())))
291       DataType = type->Value();
292
293     // associate the driver to the SComponent
294     if(aDriver == NULL) {
295       _errorCode = "Driver is null";
296       return false;
297     }
298
299     // mpv 06.03.2003: SAL1927 - if component data if already loaded, it is not necessary to do it again
300     SALOMEDSImpl_AttributeIOR* attrIOR = NULL;
301     if ((attrIOR=(SALOMEDSImpl_AttributeIOR*)Lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
302       if (aLocked) _study->GetProperties()->SetLocked(true);
303       return true;
304     }
305
306     DefineComponentInstance (anSCO, aDriver->GetIOR());
307
308     std::string aHDFUrl;
309     bool isASCII = false;
310     if (HDFascii::isASCII(aHDFPath.c_str())) {
311       isASCII = true;
312       aHDFUrl = HDFascii::ConvertFromASCIIToHDF(aHDFPath.c_str());
313       aHDFUrl += "hdf_from_ascii.hdf";
314     } else {
315       aHDFUrl = aHDFPath;
316     }
317
318     //Open the Study HDF file 
319     HDFfile *hdf_file = new HDFfile((char*)aHDFUrl.c_str()); 
320
321     char aMultifileState[2];
322     char ASCIIfileState[2];
323     try {
324       std::string scoid = anSCO.GetID();
325       hdf_file->OpenOnDisk(HDF_RDONLY);
326       HDFgroup *hdf_group = new HDFgroup("DATACOMPONENT",hdf_file);
327       hdf_group->OpenOnDisk();
328       HDFgroup *hdf_sco_group = new HDFgroup((char*)scoid.c_str(), hdf_group);
329       hdf_sco_group->OpenOnDisk();
330
331       unsigned char* aStreamFile = NULL;
332       int aStreamSize = 0;
333
334       if (hdf_sco_group->ExistInternalObject("FILE_STREAM")) {
335         HDFdataset *hdf_dataset = new HDFdataset("FILE_STREAM", hdf_sco_group);
336         hdf_dataset->OpenOnDisk();
337         aStreamSize = hdf_dataset->GetSize();
338         aStreamFile  = new unsigned char[aStreamSize];
339         if(aStreamFile == NULL) throw HDFexception("Unable to open dataset FILE_STREAM");
340         hdf_dataset->ReadFromDisk(aStreamFile);
341         hdf_dataset->CloseOnDisk();
342         hdf_dataset = 0;
343       } else
344         aStreamFile = NULL;
345
346       HDFdataset *multifile_hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group);
347       multifile_hdf_dataset->OpenOnDisk();
348       multifile_hdf_dataset->ReadFromDisk(aMultifileState);
349
350       HDFdataset *ascii_hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group);
351       ascii_hdf_dataset->OpenOnDisk();
352       ascii_hdf_dataset->ReadFromDisk(ASCIIfileState);
353
354       std::string aDir = SALOMEDSImpl_Tool::GetDirFromPath(Res);
355
356       bool aResult = (ASCIIfileState[0]=='A')?
357         aDriver->LoadASCII(anSCO, aStreamFile, aStreamSize, aDir.c_str(), aMultifileState[0]=='M'):
358         aDriver->Load(anSCO, aStreamFile, aStreamSize, aDir.c_str(), aMultifileState[0]=='M');
359
360       if(aStreamFile != NULL) delete []aStreamFile; 
361
362       if(!aResult) {
363         RemoveAttribute( anSCO, "AttributeIOR" );
364
365         _errorCode = "Can't load component";
366         throw HDFexception("Unable to load component");
367       }
368
369       //if(aDir != NULL) delete []aDir;
370
371       multifile_hdf_dataset->CloseOnDisk();
372       multifile_hdf_dataset = 0;
373       ascii_hdf_dataset->CloseOnDisk();
374       ascii_hdf_dataset = 0;
375
376       hdf_sco_group->CloseOnDisk();
377       hdf_sco_group = 0;
378       hdf_group->CloseOnDisk();
379       hdf_group = 0;
380       hdf_file->CloseOnDisk();
381       delete hdf_file;
382
383       if (isASCII) {
384         std::vector<std::string> aFilesToRemove;
385         aFilesToRemove.push_back("hdf_from_ascii.hdf");
386         SALOMEDSImpl_Tool::RemoveTemporaryFiles(SALOMEDSImpl_Tool::GetDirFromPath(aHDFUrl),
387                                                 aFilesToRemove, true);
388       }      
389     }
390     catch (HDFexception) {
391       delete hdf_file;
392
393       if (isASCII) {
394         std::vector<std::string> aFilesToRemove;
395         aFilesToRemove.push_back(aHDFUrl);
396         SALOMEDSImpl_Tool::RemoveTemporaryFiles(SALOMEDSImpl_Tool::GetDirFromPath(aHDFUrl), aFilesToRemove, true);
397       }
398
399       if (aLocked) _study->GetProperties()->SetLocked(true);
400       _errorCode = "No persistent file";   
401       return false;
402     }
403
404     try {
405       Translate_persistentID_to_IOR (Lab, aDriver, aMultifileState[0]=='M', ASCIIfileState[0] == 'A');
406     } catch(...) {
407       _errorCode = "Can not convert persistent IDs to IORs";
408       return false;
409     }
410
411     if (aLocked) _study->GetProperties()->SetLocked(true);
412   } else {
413     _errorCode = "No persistent file";   
414   }
415
416   return true;
417 }
418
419
420 //============================================================================
421 /*! Function : Load
422  *  Purpose  : 
423  */
424 //============================================================================
425 bool SALOMEDSImpl_StudyBuilder::Load(const SALOMEDSImpl_SObject& sco)
426 {
427   _errorCode = "Not implemented";
428   return false;
429 }
430
431 //============================================================================
432 /*! Function : FindOrCreateAttribute
433  *  Purpose  : Add attribute of given type to SObject, if there is attribute of such type, returns
434  *  existing one
435  */
436 //============================================================================
437 DF_Attribute* SALOMEDSImpl_StudyBuilder::FindOrCreateAttribute(const SALOMEDSImpl_SObject& anObject, 
438                                                                const std::string& aTypeOfAttribute)
439 {
440   _errorCode = "";
441   if(!anObject) {
442     _errorCode = "Invalid arguments";
443     return NULL;
444   }
445
446   DF_Label Lab = anObject.GetLabel();
447   if(Lab.IsNull()) {
448     _errorCode = "Null label";
449     return NULL;
450   }
451
452   _doc->SetModified(true);  
453
454   //The macro adds all necessary checks for standardly behaiving attributes
455   __FindOrCreateAttributeForBuilder
456
457  
458   //Add checks for TreeNode and UserID attributes  
459   if (strncmp(aTypeOfAttribute.c_str(), "AttributeTreeNode",17) == 0 ) {
460     
461     std::string aTreeNodeGUID;
462     if (strcmp(aTypeOfAttribute.c_str(), "AttributeTreeNode") == 0) {
463       aTreeNodeGUID = SALOMEDSImpl_AttributeTreeNode::GetDefaultTreeID();
464     } else {
465       aTreeNodeGUID = aTypeOfAttribute.substr(21, aTypeOfAttribute.size()); // create tree node GUID by name
466     }
467     SALOMEDSImpl_AttributeTreeNode* anAttr = NULL;
468     if (!(anAttr=(SALOMEDSImpl_AttributeTreeNode*)Lab.FindAttribute(aTreeNodeGUID))) {
469       CheckLocked();
470       anAttr = SALOMEDSImpl_AttributeTreeNode::Set(Lab, aTreeNodeGUID);
471     }
472     return anAttr;
473   }
474
475   if (strncmp(aTypeOfAttribute.c_str(), "AttributeUserID",15) == 0 ) {
476     std::string aUserGUID;
477     if (strcmp(aTypeOfAttribute.c_str(), "AttributeUserID") == 0) {
478       aUserGUID = SALOMEDSImpl_AttributeUserID::DefaultID();
479     } else {
480       aUserGUID = aTypeOfAttribute.substr(15, aTypeOfAttribute.size()); // create tree node GUID by name
481     }
482     SALOMEDSImpl_AttributeUserID* anAttr = NULL;
483     if (!(anAttr=(SALOMEDSImpl_AttributeUserID*)Lab.FindAttribute(aUserGUID))) {
484       CheckLocked();
485       anAttr = SALOMEDSImpl_AttributeUserID::Set(Lab, aUserGUID);
486     }
487     return anAttr;
488   }
489   _errorCode = "Can not create an attribute";
490
491   return NULL;
492 }
493
494 //============================================================================
495 /*! Function : FindAttribute
496  *  Purpose  : Find attribute of given type assigned SObject, returns Standard_True if it is found
497  */
498 //============================================================================
499
500 bool SALOMEDSImpl_StudyBuilder::FindAttribute(const SALOMEDSImpl_SObject& anObject, 
501                                               DF_Attribute*& anAttribute, 
502                                               const std::string& aTypeOfAttribute)
503 {
504   _errorCode = "";
505   if(!anObject) {
506     _errorCode = "Invalid arguments";
507     return false;
508   }
509   DF_Label Lab = anObject.GetLabel();
510   if ((anAttribute=Lab.FindAttribute(SALOMEDSImpl_SObject::GetGUID(aTypeOfAttribute)))) {
511     // commented out because NO MODIFICATION is done to attributes when calling FindAttribute()
512     // _doc->Modify();  
513     return true;
514   }
515   return false;
516 }
517
518 //============================================================================
519 /*! Function : RemoveAttribute
520  *  Purpose  : Remove attribute of given type assigned SObject
521  */
522 //============================================================================
523
524 bool SALOMEDSImpl_StudyBuilder::RemoveAttribute(const SALOMEDSImpl_SObject& anObject, 
525                                                 const std::string& aTypeOfAttribute)
526 {
527   _errorCode = "";
528   CheckLocked();
529   if(!anObject) {
530     _errorCode = "Invalid arguments";
531     return false;
532   }
533   DF_Label Lab = anObject.GetLabel();
534   
535   if (aTypeOfAttribute == std::string("AttributeIOR")) { // Remove from IORLabel map
536     SALOMEDSImpl_AttributeIOR* anAttr = NULL;
537     if ((anAttr=(SALOMEDSImpl_AttributeIOR*)Lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
538       _study->DeleteIORLabelMapItem(anAttr->Value());
539     }
540   }
541
542   Lab.ForgetAttribute (SALOMEDSImpl_SObject::GetGUID(aTypeOfAttribute));
543     
544   _doc->SetModified(true);  
545     
546   return true;
547 }
548
549 //============================================================================
550 /*! Function : Addreference
551  *  Purpose  : 
552  */
553 //============================================================================
554 bool SALOMEDSImpl_StudyBuilder::Addreference(const SALOMEDSImpl_SObject& me, 
555                                              const SALOMEDSImpl_SObject& theReferencedObject)
556 {
557   _errorCode = "";
558   if(!me || !theReferencedObject) {
559    _errorCode = "Invalid arguments";
560    return false;
561   }
562   CheckLocked();
563   DF_Label Lab = me.GetLabel();
564   DF_Label RefLab = theReferencedObject.GetLabel();
565   SALOMEDSImpl_AttributeReference::Set(Lab,RefLab);
566
567   SALOMEDSImpl_AttributeTarget::Set(RefLab)->Add(SALOMEDSImpl_Study::SObject(Lab));
568
569   if(_callbackOnRemove && Lab.IsDescendant(_doc->Main())) _callbackOnRemove->OnRemoveSObject(me);
570   
571   return true;
572 }
573
574 //============================================================================
575 /*! Function : RemoveReference
576  *  Purpose  : 
577  */
578 //============================================================================
579 bool SALOMEDSImpl_StudyBuilder::RemoveReference(const SALOMEDSImpl_SObject& me)
580 {
581   _errorCode = "";
582   SALOMEDSImpl_SObject theReferencedObject;
583   
584   if(!me.ReferencedObject(theReferencedObject)) return false;  //No reference is found
585   
586   CheckLocked();
587   DF_Label Lab = me.GetLabel();
588
589   //SRN: 30 Aug, 2004 : fix from Ecole l'ete version 
590
591   DF_Label RefLab = theReferencedObject.GetLabel();
592        
593   SALOMEDSImpl_AttributeTarget* aTarget = NULL;
594   if((aTarget=(SALOMEDSImpl_AttributeTarget*)RefLab.FindAttribute(SALOMEDSImpl_AttributeTarget::GetID()))) {
595     aTarget->Remove(SALOMEDSImpl_Study::SObject(Lab));
596   }
597   
598   Lab.ForgetAttribute(SALOMEDSImpl_AttributeReference::GetID());  
599   
600   _doc->SetModified(true);  
601   
602   return true;
603 }
604
605
606
607 //============================================================================
608 /*! Function : AddDirectory
609  *  Purpose  : adds a new directory with a path = thePath
610  */
611 //============================================================================
612 bool SALOMEDSImpl_StudyBuilder::AddDirectory(const std::string& thePath) 
613 {
614   _errorCode = "";
615   CheckLocked();
616   if(thePath.empty()) {
617     _errorCode = "Invalid path";
618     return false;
619   }
620
621   std::string aPath(thePath), aContext(""), aFatherPath;
622   DF_Label aLabel;
623   SALOMEDSImpl_SObject anObject;
624
625   try { 
626     anObject = _study->FindObjectByPath(thePath); //Check if the directory already exists
627   }
628   catch(...) { }
629
630   if(anObject) {
631     _errorCode = "StudyNameAlreadyUsed";
632     return false; 
633   }
634
635   if(aPath[0] != '/') { //Relative path 
636     aPath.insert(aPath.begin(), '/');
637     aPath = _study->GetContext() + aPath;
638   }
639
640   std::vector<std::string> vs = SALOMEDSImpl_Tool::splitString(aPath, '/');
641   if(vs.size() == 1) 
642     aFatherPath = "/";
643   else {
644     for(int i = 0, len = vs.size()-1; i<len; i++) { 
645       aFatherPath += "/";
646       aFatherPath += vs[i];
647     }
648   }
649
650   try { 
651     anObject = _study->FindObjectByPath(aFatherPath); //Check if the father directory exists
652   }
653   catch(...) { ; }
654   if(!anObject) {
655     _errorCode = "StudyInvalidDirectory";
656     return false; 
657   }
658
659   SALOMEDSImpl_SObject aNewObject = NewObject(anObject);
660   aLabel = aNewObject.GetLabel();
661   if(aLabel.IsNull()) {
662     _errorCode = "StudyInvalidComponent";
663     return false;
664   }
665
666   SALOMEDSImpl_AttributeName::Set(aLabel, vs.back());
667
668   //Set LocalID attribute to identify the directory object
669   SALOMEDSImpl_AttributeLocalID::Set(aLabel, DIRECTORYID);
670   
671   _doc->SetModified(true); 
672   
673   return true;
674 }
675
676
677 //============================================================================
678 /*! Function : SetGUID
679  *  Purpose  : 
680  */
681 //============================================================================
682 bool SALOMEDSImpl_StudyBuilder::SetGUID(const SALOMEDSImpl_SObject& anObject, 
683                                         const std::string& theGUID)
684 {
685   _errorCode = "";
686   CheckLocked();
687   if(!anObject) {
688     _errorCode = "Invalid arguments";
689     return false;
690   }
691
692   DF_Label aLabel = anObject.GetLabel();
693   SALOMEDSImpl_AttributeUserID::Set(aLabel, theGUID);
694
695   _doc->SetModified(true);  
696
697   return true;
698 }
699
700 //============================================================================
701 /*! Function : IsGUID
702  *  Purpose  : 
703  */
704 //============================================================================
705 bool SALOMEDSImpl_StudyBuilder::IsGUID(const SALOMEDSImpl_SObject& anObject, 
706                                        const std::string& theGUID)
707 {
708   _errorCode = "";
709   if(!anObject) {
710     _errorCode = "Invalid arguments";
711     return false;
712   }
713   DF_Label aLabel = anObject.GetLabel();
714   return aLabel.IsAttribute(theGUID);
715 }
716
717
718 //============================================================================
719 /*! Function : NewCommand
720  *  Purpose  : 
721  */
722 //============================================================================
723 void SALOMEDSImpl_StudyBuilder::NewCommand()
724 {
725   _errorCode = "";
726
727   // mpv: for SAL2114 - unset "lock changed" flag at the operation start
728   _study->GetProperties()->IsLockChanged(true);
729
730   //Not implemented
731 }
732
733 //============================================================================
734 /*! Function : CommitCommand
735  *  Purpose  : 
736  */
737 //============================================================================
738 void SALOMEDSImpl_StudyBuilder::CommitCommand()
739 {
740   _errorCode = "";
741   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
742   if (anAttr->IsLocked() && !anAttr->IsLockChanged(true)) {
743     _errorCode = "LockProtection";
744     throw LockProtection("LockProtection");
745   } else {
746     int aModif = anAttr->GetModified();
747     if (aModif < 0) aModif = 1000; // if user make undo and then - new transaction "modify" will never be zero
748     anAttr->SetModified(aModif+1);
749   }
750   
751
752   //Not implemented
753   _doc->SetModified(true);  
754 }
755
756 //============================================================================
757 /*! Function : HasOpenCommand
758  *  Purpose  : 
759  */
760 //============================================================================
761 bool SALOMEDSImpl_StudyBuilder::HasOpenCommand()
762 {
763   _errorCode = "";
764
765   //Not implememnted
766   return false;
767 }
768
769 //============================================================================
770 /*! Function : AbortCommand
771  *  Purpose  : 
772  */
773 //============================================================================
774 void SALOMEDSImpl_StudyBuilder::AbortCommand()
775 {
776   _errorCode = "";
777   //Not implemented    
778 }
779
780 //============================================================================
781 /*! Function : Undo
782  *  Purpose  : 
783  */
784 //============================================================================
785 void SALOMEDSImpl_StudyBuilder::Undo()
786 {
787   //Not implemented
788   _errorCode = "";
789   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
790   if (anAttr->IsLocked()) {
791     _errorCode = "LockProtection";
792     throw LockProtection("LockProtection");
793   } else {
794     anAttr->SetModified(anAttr->GetModified()-1);
795   }
796
797   _doc->SetModified(true);  
798 }
799
800 //============================================================================
801 /*! Function : Redo
802  *  Purpose  : 
803  */
804 //============================================================================
805 void SALOMEDSImpl_StudyBuilder::Redo() 
806 {
807   _errorCode = "";
808   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
809   if (anAttr->IsLocked()) {
810     _errorCode = "LockProtection";
811     throw LockProtection("LockProtection");
812   } else {
813     anAttr->SetModified(anAttr->GetModified()+1);
814   }
815
816   //Not implemented
817
818   _doc->SetModified(true);  
819 }
820
821 //============================================================================
822 /*! Function : GetAvailableUndos
823  *  Purpose  : 
824  */
825 //============================================================================
826 bool SALOMEDSImpl_StudyBuilder::GetAvailableUndos()
827 {
828   _errorCode = "";
829   return false;
830 }
831
832 //============================================================================
833 /*! Function : GetAvailableRedos
834  *  Purpose  : 
835  */
836 //============================================================================
837 bool  SALOMEDSImpl_StudyBuilder::GetAvailableRedos()
838 {
839   _errorCode = "";
840   return false;
841 }
842
843 //============================================================================
844 /*! Function : UndoLimit
845  *  Purpose  : 
846  */
847 //============================================================================
848 int  SALOMEDSImpl_StudyBuilder::UndoLimit()
849 {
850   _errorCode = "";
851   return 1;
852 }
853
854 //============================================================================
855 /*! Function : UndoLimit
856  *  Purpose  : 
857  */
858 //============================================================================
859 void SALOMEDSImpl_StudyBuilder::UndoLimit(int n)
860 {
861   _errorCode = "";
862   CheckLocked();
863   //Not implemented
864 }
865
866 //============================================================================
867 /*! Function : SetOnAddSObject
868  *  Purpose  : 
869  */
870 //============================================================================
871 SALOMEDSImpl_Callback*
872 SALOMEDSImpl_StudyBuilder::SetOnAddSObject(const SALOMEDSImpl_Callback* theCallback)
873 {
874   _errorCode = "";
875   SALOMEDSImpl_Callback* aRet = _callbackOnAdd;
876   _callbackOnAdd = (SALOMEDSImpl_Callback*)theCallback;
877   return aRet;
878 }
879
880 //============================================================================
881 /*! Function : SetOnNewSObject
882  *  Purpose  : 
883  */
884 //============================================================================
885 SALOMEDSImpl_Callback* 
886 SALOMEDSImpl_StudyBuilder::SetOnRemoveSObject(const SALOMEDSImpl_Callback* theCallback)
887 {
888   _errorCode = "";
889   SALOMEDSImpl_Callback* aRet = _callbackOnRemove;
890   _callbackOnRemove = (SALOMEDSImpl_Callback*)theCallback;
891   return aRet;
892 }
893
894 //============================================================================
895 /*! Function : CheckLocked
896  *  Purpose  : 
897  */
898 //============================================================================
899 void SALOMEDSImpl_StudyBuilder::CheckLocked()
900 {
901   _errorCode = "";
902   if (HasOpenCommand()) return;
903   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
904   if (anAttr->IsLocked()) {
905     _errorCode = "LockProtection";
906     throw LockProtection("LockProtection");
907   }
908 }
909
910 //============================================================================
911 /*! Function : SetName
912  *  Purpose  : 
913  */
914 //============================================================================
915 bool SALOMEDSImpl_StudyBuilder::SetName(const SALOMEDSImpl_SObject& theSO, 
916                                         const std::string& theValue)
917 {
918   _errorCode = "";
919   CheckLocked();
920   if(!theSO) {
921     _errorCode = "Invalid arguments";
922     return false;
923   }
924   SALOMEDSImpl_AttributeName::Set(theSO.GetLabel(), theValue);
925
926   _doc->SetModified(true);  
927
928   return true;
929 }
930
931 //============================================================================
932 /*! Function : SetComment
933  *  Purpose  : 
934  */
935 //============================================================================
936 bool SALOMEDSImpl_StudyBuilder::SetComment(const SALOMEDSImpl_SObject& theSO, 
937                                            const std::string& theValue)
938 {
939   _errorCode = "";
940   CheckLocked();
941   if(!theSO) {
942     _errorCode = "Invalid arguments";
943     return false;
944   }
945   SALOMEDSImpl_AttributeComment::Set(theSO.GetLabel(), theValue);
946
947   _doc->SetModified(true);  
948
949   return true;
950 }
951
952 //============================================================================
953 /*! Function : SetIOR
954  *  Purpose  : 
955  */
956 //============================================================================
957 bool SALOMEDSImpl_StudyBuilder::SetIOR(const SALOMEDSImpl_SObject& theSO, 
958                                        const std::string& theValue)
959 {
960   _errorCode = "";
961   CheckLocked();
962   if(!theSO) {
963     _errorCode = "Invalid arguments";
964     return false;
965   }
966   SALOMEDSImpl_AttributeIOR::Set(theSO.GetLabel(), theValue);
967
968   _doc->SetModified(true);  
969
970   return true;
971 }
972
973
974 //============================================================================
975 /*! Function : Translate_persistentID_to_IOR
976  *  Purpose  :
977  */
978 //============================================================================
979 static void Translate_persistentID_to_IOR(DF_Label& Lab, SALOMEDSImpl_Driver* driver, bool isMultiFile, bool isASCII)
980 {
981   if(driver == NULL) return;
982   DF_ChildIterator  itchild (Lab);
983   
984   for (; itchild.More(); itchild.Next()) {
985     DF_Label current = itchild.Value();
986     SALOMEDSImpl_AttributePersistentRef* Att = NULL;
987     if ((Att=(SALOMEDSImpl_AttributePersistentRef*)current.FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID()))) {  
988
989       SALOMEDSImpl_AttributeLocalID* anID = NULL;
990       if ((anID=(SALOMEDSImpl_AttributeLocalID*)current.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID()))) 
991         if (anID->Value() == FILELOCALID) continue;   //SRN: This attribute store a file name, skip it 
992
993       std::string persist_ref = Att->Value();
994       SALOMEDSImpl_SObject so = SALOMEDSImpl_Study::SObject(current);
995       std::string ior_string = driver->LocalPersistentIDToIOR(so, 
996                                                          persist_ref, 
997                                                          isMultiFile, 
998                                                          isASCII);
999       SALOMEDSImpl_AttributeIOR::Set (current, ior_string); 
1000      
1001     }
1002     Translate_persistentID_to_IOR (current, driver, isMultiFile, isASCII);
1003   }
1004 }
1005