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