Salome HOME
add method NameChanged to update title name
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_StudyBuilder.cxx
1 // Copyright (C) 2007-2016  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] = { '0','0' };
327     char ASCIIfileState[2] = { '0','0' };
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       if (hdf_sco_group->ExistInternalObject("MULTIFILE_STATE")) {
354         HDFdataset *multifile_hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group);
355         multifile_hdf_dataset->OpenOnDisk();
356         multifile_hdf_dataset->ReadFromDisk(aMultifileState);
357         multifile_hdf_dataset->CloseOnDisk();
358         multifile_hdf_dataset = 0;
359       }
360
361       if (hdf_sco_group->ExistInternalObject("ASCII_STATE")) {
362         HDFdataset *ascii_hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group);
363         ascii_hdf_dataset->OpenOnDisk();
364         ascii_hdf_dataset->ReadFromDisk(ASCIIfileState);
365         ascii_hdf_dataset->CloseOnDisk();
366         ascii_hdf_dataset = 0;
367       }
368
369       std::string aDir = SALOMEDSImpl_Tool::GetDirFromPath(Res);
370
371       bool aResult = true;
372       if(aStreamFile && aStreamSize > 0 ) {
373         aResult = (ASCIIfileState[0]=='A')?
374         aDriver->LoadASCII(anSCO, aStreamFile, aStreamSize, aDir.c_str(), aMultifileState[0]=='M'):
375         aDriver->Load(anSCO, aStreamFile, aStreamSize, aDir.c_str(), aMultifileState[0]=='M');
376       }
377
378       if(aStreamFile != NULL) delete []aStreamFile; 
379
380       if(!aResult) {
381         RemoveAttribute( anSCO, "AttributeIOR" );
382
383         _errorCode = "Can't load component";
384         throw HDFexception("Unable to load component");
385       }
386
387       //if(aDir != NULL) delete []aDir;
388
389       hdf_sco_group->CloseOnDisk();
390       hdf_sco_group = 0;
391       hdf_group->CloseOnDisk();
392       hdf_group = 0;
393       hdf_file->CloseOnDisk();
394       delete hdf_file;
395
396       if (isASCII) {
397         std::vector<std::string> aFilesToRemove;
398         aFilesToRemove.push_back("hdf_from_ascii.hdf");
399         SALOMEDSImpl_Tool::RemoveTemporaryFiles(SALOMEDSImpl_Tool::GetDirFromPath(aHDFUrl),
400                                                 aFilesToRemove, true);
401       }      
402     }
403     catch (HDFexception) {
404       delete hdf_file;
405
406       if (isASCII) {
407         std::vector<std::string> aFilesToRemove;
408         aFilesToRemove.push_back(aHDFUrl);
409         SALOMEDSImpl_Tool::RemoveTemporaryFiles(SALOMEDSImpl_Tool::GetDirFromPath(aHDFUrl), aFilesToRemove, true);
410       }
411
412       if (aLocked) _study->GetProperties()->SetLocked(true);
413
414       if (!hasModuleData)
415         return true;
416
417       _errorCode = "No persistent file";   
418       return false;
419     }
420
421     try {
422       Translate_persistentID_to_IOR (Lab, aDriver, aMultifileState[0]=='M', ASCIIfileState[0] == 'A');
423     } catch(...) {
424       _errorCode = "Can not convert persistent IDs to IORs";
425       return false;
426     }
427
428     if (aLocked) _study->GetProperties()->SetLocked(true);
429   } else {
430     _errorCode = "No persistent file";   
431   }
432
433   return true;
434 }
435
436
437 //============================================================================
438 /*! Function : Load
439  *  Purpose  : 
440  */
441 //============================================================================
442 bool SALOMEDSImpl_StudyBuilder::Load(const SALOMEDSImpl_SObject& sco)
443 {
444   _errorCode = "Not implemented";
445   return false;
446 }
447
448 //============================================================================
449 /*! Function : FindOrCreateAttribute
450  *  Purpose  : Add attribute of given type to SObject, if there is attribute of such type, returns
451  *  existing one
452  */
453 //============================================================================
454 DF_Attribute* SALOMEDSImpl_StudyBuilder::FindOrCreateAttribute(const SALOMEDSImpl_SObject& anObject, 
455                                                                const std::string& aTypeOfAttribute)
456 {
457   _errorCode = "";
458   if(!anObject) {
459     _errorCode = "Invalid arguments";
460     return NULL;
461   }
462
463   DF_Label Lab = anObject.GetLabel();
464   if(Lab.IsNull()) {
465     _errorCode = "Null label";
466     return NULL;
467   }
468
469   _doc->SetModified(true);  
470
471   //The macro adds all necessary checks for standardly behaiving attributes
472   __FindOrCreateAttributeForBuilder
473
474  
475   //Add checks for TreeNode and UserID attributes  
476   if (strncmp(aTypeOfAttribute.c_str(), "AttributeTreeNode",17) == 0 ) {
477     
478     std::string aTreeNodeGUID;
479     if (strcmp(aTypeOfAttribute.c_str(), "AttributeTreeNode") == 0) {
480       aTreeNodeGUID = SALOMEDSImpl_AttributeTreeNode::GetDefaultTreeID();
481     } else {
482       aTreeNodeGUID = aTypeOfAttribute.substr(21, aTypeOfAttribute.size()); // create tree node GUID by name
483     }
484     SALOMEDSImpl_AttributeTreeNode* anAttr = NULL;
485     if (!(anAttr=(SALOMEDSImpl_AttributeTreeNode*)Lab.FindAttribute(aTreeNodeGUID))) {
486       CheckLocked();
487       anAttr = SALOMEDSImpl_AttributeTreeNode::Set(Lab, aTreeNodeGUID);
488     }
489     return anAttr;
490   }
491
492   if (strncmp(aTypeOfAttribute.c_str(), "AttributeUserID",15) == 0 ) {
493     std::string aUserGUID;
494     if (strcmp(aTypeOfAttribute.c_str(), "AttributeUserID") == 0) {
495       aUserGUID = SALOMEDSImpl_AttributeUserID::DefaultID();
496     } else {
497       aUserGUID = aTypeOfAttribute.substr(15, aTypeOfAttribute.size()); // create tree node GUID by name
498     }
499     SALOMEDSImpl_AttributeUserID* anAttr = NULL;
500     if (!(anAttr=(SALOMEDSImpl_AttributeUserID*)Lab.FindAttribute(aUserGUID))) {
501       CheckLocked();
502       anAttr = SALOMEDSImpl_AttributeUserID::Set(Lab, aUserGUID);
503     }
504     return anAttr;
505   }
506   _errorCode = "Can not create an attribute";
507
508   return NULL;
509 }
510
511 //============================================================================
512 /*! Function : FindAttribute
513  *  Purpose  : Find attribute of given type assigned SObject, returns Standard_True if it is found
514  */
515 //============================================================================
516
517 bool SALOMEDSImpl_StudyBuilder::FindAttribute(const SALOMEDSImpl_SObject& anObject, 
518                                               DF_Attribute*& anAttribute, 
519                                               const std::string& aTypeOfAttribute)
520 {
521   _errorCode = "";
522   if(!anObject) {
523     _errorCode = "Invalid arguments";
524     return false;
525   }
526   DF_Label Lab = anObject.GetLabel();
527   if ((anAttribute=Lab.FindAttribute(SALOMEDSImpl_SObject::GetGUID(aTypeOfAttribute)))) {
528     // commented out because NO MODIFICATION is done to attributes when calling FindAttribute()
529     // _doc->Modify();  
530     return true;
531   }
532   return false;
533 }
534
535 //============================================================================
536 /*! Function : RemoveAttribute
537  *  Purpose  : Remove attribute of given type assigned SObject
538  */
539 //============================================================================
540
541 bool SALOMEDSImpl_StudyBuilder::RemoveAttribute(const SALOMEDSImpl_SObject& anObject, 
542                                                 const std::string& aTypeOfAttribute)
543 {
544   _errorCode = "";
545   CheckLocked();
546   if(!anObject) {
547     _errorCode = "Invalid arguments";
548     return false;
549   }
550   DF_Label Lab = anObject.GetLabel();
551   
552   if (aTypeOfAttribute == std::string("AttributeIOR")) { // Remove from IORLabel map
553     SALOMEDSImpl_AttributeIOR* anAttr = NULL;
554     if ((anAttr=(SALOMEDSImpl_AttributeIOR*)Lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
555       _study->DeleteIORLabelMapItem(anAttr->Value());
556     }
557   }
558
559   Lab.ForgetAttribute (SALOMEDSImpl_SObject::GetGUID(aTypeOfAttribute));
560     
561   _doc->SetModified(true);  
562   _study->modifySO_Notification(anObject,0);
563     
564   return true;
565 }
566
567 //============================================================================
568 /*! Function : Addreference
569  *  Purpose  : 
570  */
571 //============================================================================
572 bool SALOMEDSImpl_StudyBuilder::Addreference(const SALOMEDSImpl_SObject& me, 
573                                              const SALOMEDSImpl_SObject& theReferencedObject)
574 {
575   _errorCode = "";
576   if(!me || !theReferencedObject) {
577    _errorCode = "Invalid arguments";
578    return false;
579   }
580   CheckLocked();
581   DF_Label Lab = me.GetLabel();
582   DF_Label RefLab = theReferencedObject.GetLabel();
583   SALOMEDSImpl_AttributeReference::Set(Lab,RefLab);
584
585   SALOMEDSImpl_AttributeTarget::Set(RefLab)->Add(SALOMEDSImpl_Study::SObject(Lab));
586
587   if(_callbackOnRemove && Lab.IsDescendant(_doc->Main())) _callbackOnRemove->OnRemoveSObject(me);
588   
589   return true;
590 }
591
592 //============================================================================
593 /*! Function : RemoveReference
594  *  Purpose  : 
595  */
596 //============================================================================
597 bool SALOMEDSImpl_StudyBuilder::RemoveReference(const SALOMEDSImpl_SObject& me)
598 {
599   _errorCode = "";
600   SALOMEDSImpl_SObject theReferencedObject;
601   
602   if(!me.ReferencedObject(theReferencedObject)) return false;  //No reference is found
603   
604   CheckLocked();
605   DF_Label Lab = me.GetLabel();
606
607   //SRN: 30 Aug, 2004 : fix from Ecole l'ete version 
608
609   DF_Label RefLab = theReferencedObject.GetLabel();
610        
611   SALOMEDSImpl_AttributeTarget* aTarget = NULL;
612   if((aTarget=(SALOMEDSImpl_AttributeTarget*)RefLab.FindAttribute(SALOMEDSImpl_AttributeTarget::GetID()))) {
613     aTarget->Remove(SALOMEDSImpl_Study::SObject(Lab));
614   }
615   
616   Lab.ForgetAttribute(SALOMEDSImpl_AttributeReference::GetID());  
617   
618   _doc->SetModified(true);  
619   
620   return true;
621 }
622
623
624
625 //============================================================================
626 /*! Function : AddDirectory
627  *  Purpose  : adds a new directory with a path = thePath
628  */
629 //============================================================================
630 bool SALOMEDSImpl_StudyBuilder::AddDirectory(const std::string& thePath) 
631 {
632   _errorCode = "";
633   CheckLocked();
634   if(thePath.empty()) {
635     _errorCode = "Invalid path";
636     return false;
637   }
638
639   std::string aPath(thePath), aContext(""), aFatherPath;
640   DF_Label aLabel;
641   SALOMEDSImpl_SObject anObject;
642
643   try { 
644     anObject = _study->FindObjectByPath(thePath); //Check if the directory already exists
645   }
646   catch(...) { }
647
648   if(anObject) {
649     _errorCode = "StudyNameAlreadyUsed";
650     return false; 
651   }
652
653   if(aPath[0] != '/') { //Relative path 
654     aPath.insert(aPath.begin(), '/');
655     aPath = _study->GetContext() + aPath;
656   }
657
658   std::vector<std::string> vs = SALOMEDSImpl_Tool::splitString(aPath, '/');
659   if(vs.size() == 1) 
660     aFatherPath = "/";
661   else {
662     for(int i = 0, len = vs.size()-1; i<len; i++) { 
663       aFatherPath += "/";
664       aFatherPath += vs[i];
665     }
666   }
667
668   try { 
669     anObject = _study->FindObjectByPath(aFatherPath); //Check if the father directory exists
670   }
671   catch(...) { ; }
672   if(!anObject) {
673     _errorCode = "StudyInvalidDirectory";
674     return false; 
675   }
676
677   SALOMEDSImpl_SObject aNewObject = NewObject(anObject);
678   aLabel = aNewObject.GetLabel();
679   if(aLabel.IsNull()) {
680     _errorCode = "StudyInvalidComponent";
681     return false;
682   }
683
684   SALOMEDSImpl_AttributeName::Set(aLabel, vs.back());
685
686   //Set LocalID attribute to identify the directory object
687   SALOMEDSImpl_AttributeLocalID::Set(aLabel, DIRECTORYID);
688   
689   _doc->SetModified(true); 
690   
691   return true;
692 }
693
694
695 //============================================================================
696 /*! Function : SetGUID
697  *  Purpose  : 
698  */
699 //============================================================================
700 bool SALOMEDSImpl_StudyBuilder::SetGUID(const SALOMEDSImpl_SObject& anObject, 
701                                         const std::string& theGUID)
702 {
703   _errorCode = "";
704   CheckLocked();
705   if(!anObject) {
706     _errorCode = "Invalid arguments";
707     return false;
708   }
709
710   DF_Label aLabel = anObject.GetLabel();
711   SALOMEDSImpl_AttributeUserID::Set(aLabel, theGUID);
712
713   _doc->SetModified(true);  
714
715   return true;
716 }
717
718 //============================================================================
719 /*! Function : IsGUID
720  *  Purpose  : 
721  */
722 //============================================================================
723 bool SALOMEDSImpl_StudyBuilder::IsGUID(const SALOMEDSImpl_SObject& anObject, 
724                                        const std::string& theGUID)
725 {
726   _errorCode = "";
727   if(!anObject) {
728     _errorCode = "Invalid arguments";
729     return false;
730   }
731   DF_Label aLabel = anObject.GetLabel();
732   return aLabel.IsAttribute(theGUID);
733 }
734
735
736 //============================================================================
737 /*! Function : NewCommand
738  *  Purpose  : 
739  */
740 //============================================================================
741 void SALOMEDSImpl_StudyBuilder::NewCommand()
742 {
743   _errorCode = "";
744
745   // mpv: for SAL2114 - unset "lock changed" flag at the operation start
746   _study->GetProperties()->IsLockChanged(true);
747
748   //Not implemented
749 }
750
751 //============================================================================
752 /*! Function : CommitCommand
753  *  Purpose  : 
754  */
755 //============================================================================
756 void SALOMEDSImpl_StudyBuilder::CommitCommand()
757 {
758   _errorCode = "";
759   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
760   if (anAttr->IsLocked() && !anAttr->IsLockChanged(true)) {
761     _errorCode = "LockProtection";
762     throw LockProtection("LockProtection");
763   } else {
764     int aModif = anAttr->GetModified();
765     if (aModif < 0) aModif = 1000; // if user make undo and then - new transaction "modify" will never be zero
766     anAttr->SetModified(aModif+1);
767   }
768   
769
770   //Not implemented
771   _doc->SetModified(true);  
772 }
773
774 //============================================================================
775 /*! Function : HasOpenCommand
776  *  Purpose  : 
777  */
778 //============================================================================
779 bool SALOMEDSImpl_StudyBuilder::HasOpenCommand()
780 {
781   _errorCode = "";
782
783   //Not implememnted
784   return false;
785 }
786
787 //============================================================================
788 /*! Function : AbortCommand
789  *  Purpose  : 
790  */
791 //============================================================================
792 void SALOMEDSImpl_StudyBuilder::AbortCommand()
793 {
794   _errorCode = "";
795   //Not implemented    
796 }
797
798 //============================================================================
799 /*! Function : Undo
800  *  Purpose  : 
801  */
802 //============================================================================
803 void SALOMEDSImpl_StudyBuilder::Undo()
804 {
805   //Not implemented
806   _errorCode = "";
807   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
808   if (anAttr->IsLocked()) {
809     _errorCode = "LockProtection";
810     throw LockProtection("LockProtection");
811   } else {
812     anAttr->SetModified(anAttr->GetModified()-1);
813   }
814
815   _doc->SetModified(true);  
816 }
817
818 //============================================================================
819 /*! Function : Redo
820  *  Purpose  : 
821  */
822 //============================================================================
823 void SALOMEDSImpl_StudyBuilder::Redo() 
824 {
825   _errorCode = "";
826   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
827   if (anAttr->IsLocked()) {
828     _errorCode = "LockProtection";
829     throw LockProtection("LockProtection");
830   } else {
831     anAttr->SetModified(anAttr->GetModified()+1);
832   }
833
834   //Not implemented
835
836   _doc->SetModified(true);  
837 }
838
839 //============================================================================
840 /*! Function : GetAvailableUndos
841  *  Purpose  : 
842  */
843 //============================================================================
844 bool SALOMEDSImpl_StudyBuilder::GetAvailableUndos()
845 {
846   _errorCode = "";
847   return false;
848 }
849
850 //============================================================================
851 /*! Function : GetAvailableRedos
852  *  Purpose  : 
853  */
854 //============================================================================
855 bool  SALOMEDSImpl_StudyBuilder::GetAvailableRedos()
856 {
857   _errorCode = "";
858   return false;
859 }
860
861 //============================================================================
862 /*! Function : UndoLimit
863  *  Purpose  : 
864  */
865 //============================================================================
866 int  SALOMEDSImpl_StudyBuilder::UndoLimit()
867 {
868   _errorCode = "";
869   return 1;
870 }
871
872 //============================================================================
873 /*! Function : UndoLimit
874  *  Purpose  : 
875  */
876 //============================================================================
877 void SALOMEDSImpl_StudyBuilder::UndoLimit(int n)
878 {
879   _errorCode = "";
880   CheckLocked();
881   //Not implemented
882 }
883
884 //============================================================================
885 /*! Function : SetOnAddSObject
886  *  Purpose  : 
887  */
888 //============================================================================
889 SALOMEDSImpl_Callback*
890 SALOMEDSImpl_StudyBuilder::SetOnAddSObject(const SALOMEDSImpl_Callback* theCallback)
891 {
892   _errorCode = "";
893   SALOMEDSImpl_Callback* aRet = _callbackOnAdd;
894   _callbackOnAdd = (SALOMEDSImpl_Callback*)theCallback;
895   return aRet;
896 }
897
898 //============================================================================
899 /*! Function : SetOnNewSObject
900  *  Purpose  : 
901  */
902 //============================================================================
903 SALOMEDSImpl_Callback* 
904 SALOMEDSImpl_StudyBuilder::SetOnRemoveSObject(const SALOMEDSImpl_Callback* theCallback)
905 {
906   _errorCode = "";
907   SALOMEDSImpl_Callback* aRet = _callbackOnRemove;
908   _callbackOnRemove = (SALOMEDSImpl_Callback*)theCallback;
909   return aRet;
910 }
911
912 //============================================================================
913 /*! Function : CheckLocked
914  *  Purpose  : 
915  */
916 //============================================================================
917 void SALOMEDSImpl_StudyBuilder::CheckLocked()
918 {
919   _errorCode = "";
920   if (HasOpenCommand()) return;
921   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
922   if (anAttr->IsLocked()) {
923     _errorCode = "LockProtection";
924     throw LockProtection("LockProtection");
925   }
926 }
927
928 //============================================================================
929 /*! Function : SetName
930  *  Purpose  : 
931  */
932 //============================================================================
933 bool SALOMEDSImpl_StudyBuilder::SetName(const SALOMEDSImpl_SObject& theSO, 
934                                         const std::string& theValue)
935 {
936   _errorCode = "";
937   CheckLocked();
938   if(!theSO) {
939     _errorCode = "Invalid arguments";
940     return false;
941   }
942   SALOMEDSImpl_AttributeName::Set(theSO.GetLabel(), theValue);
943
944   _doc->SetModified(true);  
945
946   return true;
947 }
948
949 //============================================================================
950 /*! Function : SetComment
951  *  Purpose  : 
952  */
953 //============================================================================
954 bool SALOMEDSImpl_StudyBuilder::SetComment(const SALOMEDSImpl_SObject& theSO, 
955                                            const std::string& theValue)
956 {
957   _errorCode = "";
958   CheckLocked();
959   if(!theSO) {
960     _errorCode = "Invalid arguments";
961     return false;
962   }
963   SALOMEDSImpl_AttributeComment::Set(theSO.GetLabel(), theValue);
964
965   _doc->SetModified(true);  
966
967   return true;
968 }
969
970 //============================================================================
971 /*! Function : SetIOR
972  *  Purpose  : 
973  */
974 //============================================================================
975 bool SALOMEDSImpl_StudyBuilder::SetIOR(const SALOMEDSImpl_SObject& theSO, 
976                                        const std::string& theValue)
977 {
978   _errorCode = "";
979   CheckLocked();
980   if(!theSO) {
981     _errorCode = "Invalid arguments";
982     return false;
983   }
984   SALOMEDSImpl_AttributeIOR::Set(theSO.GetLabel(), theValue);
985
986   _doc->SetModified(true);  
987
988   return true;
989 }
990
991
992 //============================================================================
993 /*! Function : Translate_persistentID_to_IOR
994  *  Purpose  :
995  */
996 //============================================================================
997 static void Translate_persistentID_to_IOR(DF_Label& Lab, SALOMEDSImpl_Driver* driver, bool isMultiFile, bool isASCII)
998 {
999   if(driver == NULL) return;
1000   DF_ChildIterator  itchild (Lab);
1001   
1002   for (; itchild.More(); itchild.Next()) {
1003     DF_Label current = itchild.Value();
1004     SALOMEDSImpl_AttributePersistentRef* Att = NULL;
1005     if ((Att=(SALOMEDSImpl_AttributePersistentRef*)current.FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID()))) {  
1006
1007       SALOMEDSImpl_AttributeLocalID* anID = NULL;
1008       if ((anID=(SALOMEDSImpl_AttributeLocalID*)current.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID()))) 
1009         if (anID->Value() == FILELOCALID) continue;   //SRN: This attribute store a file name, skip it 
1010
1011       std::string persist_ref = Att->Value();
1012       SALOMEDSImpl_SObject so = SALOMEDSImpl_Study::SObject(current);
1013       std::string ior_string = driver->LocalPersistentIDToIOR(so, 
1014                                                               persist_ref, 
1015                                                               isMultiFile, 
1016                                                               isASCII);
1017       SALOMEDSImpl_AttributeIOR* iorAttr = SALOMEDSImpl_AttributeIOR::Set (current, ior_string);
1018
1019       // make myRefCounter of a loaded GenericObj == 1
1020       SALOMEDSImpl_Study::UnRegisterGenObj( ior_string, iorAttr->Label());
1021     }
1022     Translate_persistentID_to_IOR (current, driver, isMultiFile, isASCII);
1023   }
1024 }