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