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