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