]> SALOME platform Git repositories - modules/kernel.git/blob - src/SALOMEDS/SALOMEDS_StudyManager_i.cxx
Salome HOME
Initialisation de la base KERNEL avec la version operationnelle de KERNEL_SRC issue...
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_StudyManager_i.cxx
1 using namespace std;
2 //  File      : SALOMEDS_StudyManager_i.cxx
3 //  Created   : Wed Nov 28 13:45:43 2001
4 //  Author    : Yves FRICAUD 
5
6 //  Project   : SALOME
7 //  Module    : SALOMEDS
8 //  Copyright : Open CASCADE
9 //  $Header$
10 //  Modified by : Estelle DEVILLE : Implementation of Save methods
11
12 #include "utilities.h"
13 #include "SALOMEDS_StudyManager_i.hxx"
14 #include "SALOMEDS_Study_i.hxx"
15 #include "SALOMEDS_SComponent_i.hxx"
16
17 #include "SALOMEDS_IORAttribute.hxx"
18 #include "SALOMEDS_PersRefAttribute.hxx"
19 #include "SALOMEDS_Tool.hxx"
20
21 #include <TDF_Label.hxx>
22 #include <TDataStd_Name.hxx>
23 #include <TDataStd_Comment.hxx>
24 #include <TDataStd_TreeNode.hxx>
25 #include <TDataStd_UAttribute.hxx> 
26 #include <TDF_Tool.hxx>
27 #include <TDF_Reference.hxx>
28 #include <TDF_Data.hxx>
29 #include <TDF_RelocationTable.hxx>
30 #include <TDF_AttributeIterator.hxx>
31 //  #include <TDocStd_Owner.hxx>
32 #include <TColStd_HArray1OfCharacter.hxx>
33 #include <TCollection_ExtendedString.hxx>
34 #include "HDFexplorer.hxx"
35 #include "SALOMEDS_SequenceOfRealAttribute.hxx"
36 #include "SALOMEDS_SequenceOfIntegerAttribute.hxx"
37 #include <TColStd_HSequenceOfReal.hxx>
38 #include <TColStd_HSequenceOfInteger.hxx>
39 #include "SALOMEDS_PixMapAttribute.hxx"
40 #include "SALOMEDS_DrawableAttribute.hxx"
41 #include "SALOMEDS_SelectableAttribute.hxx"
42 #include "SALOMEDS_ExpandableAttribute.hxx"
43 #include "SALOMEDS_OpenedAttribute.hxx"
44 #include "SALOMEDS_TextColorAttribute.hxx"
45 #include "SALOMEDS_TextHighlightColorAttribute.hxx"
46 #include "SALOMEDS_LocalIDAttribute.hxx"
47 #include "SALOMEDS_TargetAttribute.hxx"
48 #include "SALOMEDS_TableOfIntegerAttribute.hxx"
49 #include "SALOMEDS_TableOfRealAttribute.hxx"
50 #include "SALOMEDS_TableOfStringAttribute.hxx"
51 #include "SALOMEDS_StudyPropertiesAttribute.hxx"
52 #include "SALOMEDS_PythonObjectAttribute.hxx"
53 #include <OSD_Process.hxx>
54 #include <Quantity_Date.hxx>
55
56 #include "Utils_CorbaException.hxx"
57
58 #include <strstream>
59
60 #define USE_CASE_LABEL_ID            "0:2"
61
62 //===========================================================================
63 //Function : LoadAttributes
64 //===========================================================================
65 static void ReadAttributes(Handle(TDF_Data)& DF,
66                            TDF_Label& Lab, 
67                            HDFdataset* hdf_dataset)
68 {
69   hdf_dataset->OpenOnDisk();
70   
71   if (hdf_dataset->GetType() == HDF_STRING) {
72
73     if (!strncmp(hdf_dataset->GetName(),"AttributeTreeNode",17)) {
74       MESSAGE("Create a Attribute :     AttributeTreeNode");
75       char current_strings[5][hdf_dataset->GetSize()/5];
76       hdf_dataset->ReadFromDisk(current_strings);
77
78       MESSAGE("Create an Attribute :     AttributeTreeNode"); 
79       Standard_GUID aGUID(current_strings[4]);
80       Handle(TDataStd_TreeNode) aNewNode = TDataStd_TreeNode::Set(Lab,aGUID);
81       TDF_Label aLabel;
82       Handle(TDataStd_TreeNode) aNode;
83       if (current_strings[0][0]) {
84         TDF_Tool::Label(DF,current_strings[0],aLabel,1);
85         if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
86         aNewNode->SetFather(aNode);
87       }
88       if (current_strings[1][0]) {
89         TDF_Tool::Label(DF,current_strings[1],aLabel,1);
90        if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
91         aNewNode->SetPrevious(aNode);
92       }
93       if (current_strings[2][0]) {
94         TDF_Tool::Label(DF,current_strings[2],aLabel,1);
95         if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
96         aNewNode->SetNext(aNode);
97       }
98       if (current_strings[3][0]) {
99         TDF_Tool::Label(DF,current_strings[3],aLabel,1);
100         if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
101         aNewNode->SetFirst(aNode);
102       }
103     } else {
104
105       int size =  hdf_dataset->GetSize();
106       char current_string[size];
107       hdf_dataset->ReadFromDisk(current_string);
108
109       if (!strcmp(hdf_dataset->GetName(),"COMPONENTDATATYPE")) {      
110         MESSAGE("Create a OCAF Attribute :    COMPONENTDATATYPE");
111         TDataStd_Comment::Set         (Lab,current_string); 
112       }
113       else if (!strcmp(hdf_dataset->GetName(),"AttributeComment")) {
114         MESSAGE("Create an Attribute :     AttributeComment"); 
115         TDataStd_Comment::Set         (Lab,current_string); 
116       }
117       else if (!strcmp(hdf_dataset->GetName(),"AttributeName")) {
118         MESSAGE("Create an  Attribute :     AttributeName");       
119         TDataStd_Name::Set            (Lab,current_string);
120       }
121       else if (!strcmp(hdf_dataset->GetName(),"AttributePersistentRef")) { 
122         MESSAGE("Create an Attribute :     AttributePersistentRef"); 
123         SALOMEDS_PersRefAttribute::Set(Lab,current_string);
124       }
125       else if (!strcmp(hdf_dataset->GetName(),"Reference")) {
126         MESSAGE("Create a OCAF Attribute :     Reference"); 
127         TDF_Label RefLab;
128         TDF_Tool::Label(DF,current_string,RefLab,1);
129         TDF_Reference::Set(Lab,RefLab);
130         SALOMEDS_TargetAttribute::Set(RefLab)->Append(Lab);
131       }
132       else if (!strcmp(hdf_dataset->GetName(),"AttributeReal")) {
133         MESSAGE("Create a Attribute :     AttributeReal");
134         char * err = NULL;
135         CORBA::Double r =  strtod(current_string, &err);
136         SCRUTE(r);
137         if (err == current_string) {
138           MESSAGE("AtttributeReal : conversion impossible");
139         }
140         else TDataStd_Real::Set (Lab,r);
141       }
142       else if (!strcmp(hdf_dataset->GetName(),"AttributeInteger")) {
143         MESSAGE("Create a Attribute :     AttributeInteger");
144         CORBA::Long r =  atol(current_string);
145         SCRUTE(r);
146         TDataStd_Integer::Set (Lab,r);
147       }
148       else if (!strcmp(hdf_dataset->GetName(),"AttributePixMap")) {
149         MESSAGE("Create an  Attribute :     AttributePixMap");       
150         SALOMEDS_PixMapAttribute::Set (Lab,current_string);
151       }
152       else if (!strcmp(hdf_dataset->GetName(),"AttributeDrawable")) {
153         MESSAGE("Create a Attribute :     DrawableAttribute");
154         CORBA::Long r =  atol(current_string);
155         SCRUTE(r);
156         SALOMEDS_DrawableAttribute::Set (Lab,r);
157       }
158       else if (!strcmp(hdf_dataset->GetName(),"AttributeSelectable")) {
159         MESSAGE("Create a Attribute :     AttributeSelectable");
160         CORBA::Long r =  atol(current_string);
161         SCRUTE(r);
162         SALOMEDS_SelectableAttribute::Set (Lab,r);
163       }
164       else if (!strcmp(hdf_dataset->GetName(),"AttributeExpandable")) {
165         MESSAGE("Create a Attribute :     AttributeExpandable");
166         CORBA::Long r =  atol(current_string);
167         SCRUTE(r);
168         SALOMEDS_ExpandableAttribute::Set (Lab,r);
169       }
170       else if (!strcmp(hdf_dataset->GetName(),"AttributeOpened")) {
171         MESSAGE("Create a Attribute :     AttributeOpened");
172         CORBA::Long r =  atol(current_string);
173         SCRUTE(r);
174         SALOMEDS_OpenedAttribute::Set (Lab,r);
175       }
176       else if (!strcmp(hdf_dataset->GetName(),"AttributeLocalID")) {
177         MESSAGE("Create a Attribute :     AttributeLocalID");
178         CORBA::Long r =  atol(current_string);
179         SCRUTE(r);
180         SALOMEDS_LocalIDAttribute::Set (Lab,r);
181       }
182       else if (!strncmp(hdf_dataset->GetName(),"AttributeUserID",15)) {
183         MESSAGE("Create an  Attribute :     AttributeUserID");       
184         TDataStd_UAttribute::Set       (Lab,Standard_GUID(current_string));
185       }
186       else if (!strcmp(hdf_dataset->GetName(),"AttributeTableOfInteger")) {
187         MESSAGE("Create a Attribute :     AttributeTableOfInteger");
188         int size = hdf_dataset->GetSize();
189         Handle(SALOMEDS_TableOfIntegerAttribute) Attr = SALOMEDS_TableOfIntegerAttribute::Set(Lab);
190         unsigned char* aBuffer = new unsigned char[size];
191         if(aBuffer == NULL) throw HDFexception("Unable to open dataset AttributeTableOfInteger");
192         hdf_dataset->ReadFromDisk(aBuffer);
193         SALOMEDS::TMPFile_var aTMPFile = new SALOMEDS::TMPFile(size, size, aBuffer, 1);
194         istrstream aStream((char*)&aTMPFile[0], aTMPFile->length());
195         Attr->RestoreFromString(aStream);
196       }
197       else if (!strcmp(hdf_dataset->GetName(),"AttributeTableOfReal")) {
198         MESSAGE("Create a Attribute :     AttributeTableOfReal");
199         int size = hdf_dataset->GetSize();
200         Handle(SALOMEDS_TableOfRealAttribute) Attr = SALOMEDS_TableOfRealAttribute::Set(Lab);
201         unsigned char* aBuffer = new unsigned char[size];
202         if(aBuffer == NULL) throw HDFexception("Unable to open dataset AttributeTableOfReal");
203         hdf_dataset->ReadFromDisk(aBuffer);
204         SALOMEDS::TMPFile_var aTMPFile = new SALOMEDS::TMPFile(size, size, aBuffer, 1);
205         istrstream aStream((char*)&aTMPFile[0], aTMPFile->length());
206         Attr->RestoreFromString(aStream);
207       }
208       else if (!strcmp(hdf_dataset->GetName(),"AttributeTableOfString")) {
209         MESSAGE("Create a Attribute :     AttributeTableOfString");
210         int size = hdf_dataset->GetSize();
211         Handle(SALOMEDS_TableOfStringAttribute) Attr = SALOMEDS_TableOfStringAttribute::Set(Lab);
212         unsigned char* aBuffer = new unsigned char[size];
213         if(aBuffer == NULL) throw HDFexception("Unable to open dataset AttributeTableOfString");
214         hdf_dataset->ReadFromDisk(aBuffer);
215         SALOMEDS::TMPFile_var aTMPFile = new SALOMEDS::TMPFile(size, size, aBuffer, 1);
216         istrstream aStream((char*)&aTMPFile[0], aTMPFile->length());
217         Attr->RestoreFromString(aStream);
218       }
219       else if (!strcmp(hdf_dataset->GetName(),"AttributeStudyProperties")) {
220         MESSAGE("Create an  Attribute :     AttributeStudyProperties");     
221 //      MESSAGE("current string :"<<current_string);
222         Handle(SALOMEDS_StudyPropertiesAttribute) aProp = SALOMEDS_StudyPropertiesAttribute::Set (Lab);
223         switch (current_string[0]) {
224         case 'f': aProp->SetCreationMode(1);break;
225         case 'c': aProp->SetCreationMode(2);break;
226         }
227
228         int anIndex;
229         for(anIndex = 2; anIndex + 2 < size ;) {
230           char str[10];
231           Standard_Integer aMinute, aHour, aDay, aMonth, aYear;
232           str[0] = current_string[anIndex++];
233           str[1] = current_string[anIndex++];
234           str[2] = 0;
235           aMinute = atoi(str);
236           str[0] = current_string[anIndex++];
237           str[1] = current_string[anIndex++];
238           aHour =  atoi(str);
239           str[0] = current_string[anIndex++];
240           str[1] = current_string[anIndex++];
241           aDay =  atoi(str);
242           str[0] = current_string[anIndex++];
243           str[1] = current_string[anIndex++];
244           aMonth =  atoi(str);
245           str[0] = current_string[anIndex++];
246           str[1] = current_string[anIndex++];
247           str[2] = current_string[anIndex++];
248           str[3] = current_string[anIndex++];
249           str[4] = 0;
250           aYear = atoi(str);
251           aProp->SetModificationDate(aMinute,aHour,aDay,aMonth,aYear);
252
253           int aNameSize;
254           for(aNameSize = 0; current_string[anIndex+aNameSize]!=1; aNameSize++);
255           char *aName = new char[aNameSize+1];
256           strncpy(aName, &(current_string[anIndex]), aNameSize);
257           aName[aNameSize] = 0;
258           aProp->SetUserName(TCollection_ExtendedString(aName));
259           delete(aName);
260           anIndex += aNameSize + 1;
261           if (current_string[1] == 'l') {
262             aProp->SetLocked(Standard_True);
263             aProp->IsLockChanged(true);
264           }
265           aProp->SetModified(0);
266         }
267       }
268       else if (!strcmp(hdf_dataset->GetName(),"AttributePythonObject")) {
269         MESSAGE("Create an  Attribute :     AttributePythonObject");       
270         Handle(SALOMEDS_PythonObjectAttribute) anObj = SALOMEDS_PythonObjectAttribute::Set(Lab);
271         Standard_Boolean aScript = (current_string[0] == 's')?Standard_True:Standard_False;
272         anObj->SetObject((char *)(current_string+1), aScript);
273       }
274       else {
275         MESSAGE(hdf_dataset->GetName());
276         MESSAGE("LoadAttributes: unknown types");
277       }
278     }
279   }
280   if (hdf_dataset->GetType() == HDF_FLOAT64) {
281     if (!strcmp(hdf_dataset->GetName(),"AttributeSequenceOfReal")) {
282       MESSAGE("Create a Attribute :     AttributeSequenceOfReal");
283       int size = hdf_dataset->GetSize();
284       hdf_float64* val = new hdf_float64[size];
285       hdf_dataset->ReadFromDisk(val);
286       Handle(TColStd_HSequenceOfReal) SeqReal = new TColStd_HSequenceOfReal;
287       for (Standard_Integer i = 0; i < size; i++) {
288         SeqReal->Append(val[i]);
289 //          MESSAGE( val[i] << " restored"   );
290       }
291       SALOMEDS_SequenceOfRealAttribute::Set (Lab);
292       Handle(SALOMEDS_SequenceOfRealAttribute) Attr;
293       Handle(TDF_Attribute) Att;
294       Lab.FindAttribute(SALOMEDS_SequenceOfRealAttribute::GetID(),Att);
295       Attr = Handle(SALOMEDS_SequenceOfRealAttribute)::DownCast(Att);
296       Attr->Assign(SeqReal);
297     } else
298     if (!strcmp(hdf_dataset->GetName(),"AttributeTextColor")) {
299       MESSAGE("Create a Attribute :     AttributeTextColor");
300       hdf_float64 val[3];
301       hdf_dataset->ReadFromDisk(val);
302       Handle(SALOMEDS_TextColorAttribute) TC = new SALOMEDS_TextColorAttribute;
303       Lab.AddAttribute(TC); 
304       TC->SetValue(1, val[0]);
305       TC->SetValue(2, val[1]);
306       TC->SetValue(3, val[2]);
307     } else
308     if (!strcmp(hdf_dataset->GetName(),"AttributeTextHighlightColor")) {
309       MESSAGE("Create a Attribute :     AttributeTextHighlightColor");
310       hdf_float64 val[3];
311       hdf_dataset->ReadFromDisk(val);
312       Handle(SALOMEDS_TextHighlightColorAttribute) TC = new SALOMEDS_TextHighlightColorAttribute;
313       Lab.AddAttribute(TC); 
314       TC->SetValue(1, val[0]);
315       TC->SetValue(2, val[1]);
316       TC->SetValue(3, val[2]);
317     }else {
318       MESSAGE(hdf_dataset->GetName());
319       MESSAGE("LoadAttributes: unknown types");
320     }
321   }
322   if (hdf_dataset->GetType() == HDF_INT32) {
323     if (!strcmp(hdf_dataset->GetName(),"AttributeSequenceOfInteger")) {
324       MESSAGE("Create a OCAF Attribute :     AttributeSequenceOfInteger");
325       int size = hdf_dataset->GetSize();
326       hdf_int32* val = new hdf_int32[size];
327       hdf_dataset->ReadFromDisk(val);
328       Handle(TColStd_HSequenceOfInteger) SeqInt = new TColStd_HSequenceOfInteger;
329       for (Standard_Integer i = 0; i < size; i++) {
330         SeqInt->Append(val[i]);
331 //          MESSAGE( val[i] << " restored"   );
332       }
333       SALOMEDS_SequenceOfIntegerAttribute::Set (Lab);
334       Handle(SALOMEDS_SequenceOfIntegerAttribute) Attr;
335       Handle(TDF_Attribute) Att;
336       Lab.FindAttribute(SALOMEDS_SequenceOfIntegerAttribute::GetID(),Att);
337       Attr = Handle(SALOMEDS_SequenceOfIntegerAttribute)::DownCast(Att);
338       Attr->Assign(SeqInt);
339     } 
340     else {
341       MESSAGE(hdf_dataset->GetName());
342       MESSAGE("LoadAttributes: unknown types");
343     }
344   }
345   hdf_dataset->CloseOnDisk();
346 }
347
348 //============================================================================
349 //Function : Translate_IOR_to_persistentID
350 //============================================================================
351 static void Translate_IOR_to_persistentID (SALOMEDS::Study_ptr        study,
352                                            SALOMEDS::StudyBuilder_ptr SB,
353                                            SALOMEDS::SObject_ptr      so,
354                                            SALOMEDS::Driver_ptr       engine,
355                                            CORBA::Boolean             isMultiFile)
356 {
357   MESSAGE("In Translate_IOR_to_persistentID");
358   SALOMEDS::ChildIterator_var itchild = study->NewChildIterator(so);
359   CORBA::String_var ior_string;
360   char* persistent_string = 0;
361   char *curid=0;
362
363   for (; itchild->More(); itchild->Next()) {
364     SALOMEDS::SObject_var current = itchild->Value();
365     SCRUTE(current->GetID());
366     SCRUTE(ior_string);
367     SALOMEDS::GenericAttribute_var SObj;
368     if (current->FindAttribute(SObj, "AttributeIOR")) {
369       SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(SObj);
370       ior_string = IOR->Value();
371       SCRUTE(ior_string);
372       
373       persistent_string = engine->IORToLocalPersistentID (current,ior_string,isMultiFile);
374       
375 //       SB->AddAttribute (current, SALOMEDS::PersistentRef,persistent_string);
376       SALOMEDS::AttributePersistentRef_var Pers = SALOMEDS::AttributePersistentRef::_narrow(SB->FindOrCreateAttribute (current, "AttributePersistentRef"));
377       Pers->SetValue(persistent_string);
378       SCRUTE(persistent_string);
379       curid = current->GetID();
380       MESSAGE("Translate " << curid <<
381               " to Persistent string "<<persistent_string);
382       persistent_string = 0;
383       curid = 0;
384     }
385     Translate_IOR_to_persistentID (study,SB,current,engine,isMultiFile);
386   }
387   CORBA::string_free(persistent_string);
388   CORBA::string_free(curid);
389 }
390
391 //============================================================================
392 //Function : BuildlTree
393 //============================================================================
394 static void BuildTree  (Handle(TDF_Data)& DF,HDFgroup* hdf_current_group)
395 {
396   hdf_current_group->OpenOnDisk();
397   
398   TDF_Label Lab;
399   Standard_CString Entry = hdf_current_group->GetName();
400   if (strcmp(Entry,"STUDY_STRUCTURE") == 0) {
401     MESSAGE("find the root of the document");
402     Lab =  DF->Root().FindChild(1,Standard_True);
403   }
404   else {
405     TDF_Tool::Label  (DF,Entry,Lab,1);
406     MESSAGE("BuildTree : Create a new label"<<Entry);
407   }
408   char name[HDF_NAME_MAX_LEN+1];
409   Standard_Integer nbsons = hdf_current_group->nInternalObjects(); 
410   
411   for (Standard_Integer i=0; i<nbsons; i++) {
412     hdf_current_group->InternalObjectIndentify(i,name);
413     if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
414     hdf_object_type type = hdf_current_group->InternalObjectType(name);
415
416     if  (type == HDF_DATASET) {
417       MESSAGE("--> Dataset: Internal Object Name : " << name);
418       HDFdataset* new_dataset = new HDFdataset(name,hdf_current_group);
419       ReadAttributes   (DF,Lab,new_dataset);      
420       new_dataset = 0; // will be deleted by father destructor
421
422     }
423     else if (type == HDF_GROUP)   {
424       MESSAGE( "--> Group: Internal Object Name : " << name);
425       HDFgroup* new_group = new HDFgroup(name,hdf_current_group);
426       BuildTree (DF,new_group);
427       new_group = 0; // will be deleted by father destructor
428     }
429   }
430   hdf_current_group->CloseOnDisk();
431 }
432
433
434 //============================================================================
435 /*! Function : SALOMEDS_StudyManager_i
436  *  Purpose  : SALOMEDS_StudyManager_i constructor 
437  */
438 //============================================================================
439 SALOMEDS_StudyManager_i::SALOMEDS_StudyManager_i(CORBA::ORB_ptr orb) 
440
441   _orb = CORBA::ORB::_duplicate(orb);
442   _OCAFApp = new SALOMEDS_OCAFApplication();  
443   _name_service = new SALOME_NamingService(_orb);
444   // Study directory creation in the naming service : to register all
445   // open studies in the session
446   _name_service->Create_Directory("/Study");
447   _IDcounter = 0;
448 }
449
450 //============================================================================
451 /*! Function : ~SALOMEDS_StudyManager_i
452  *  Purpose  : SALOMEDS_StudyManager_i destructor
453  */
454 //============================================================================
455 SALOMEDS_StudyManager_i::~SALOMEDS_StudyManager_i()
456 {
457   // Destroy directory to register open studies
458   _name_service->Destroy_Directory("/Study");
459   // Destroy OCAF document
460   delete &_OCAFApp;
461 }
462
463 //============================================================================
464 /*! Function : register_name
465  *  Purpose  : Register the study Manager in the naming service under the  
466  *             context name
467  */
468 //============================================================================
469 void SALOMEDS_StudyManager_i::register_name(char * name) {
470   SALOMEDS::StudyManager_ptr g = SALOMEDS::StudyManager::_narrow(_this());
471   _name_service->Register(g, name);
472 }
473
474
475 //============================================================================
476 /*! Function : NewStudy
477  *  Purpose  : Create a New Study of name study_name
478  */
479 //============================================================================
480 SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::NewStudy(const char* study_name) 
481 {
482   Handle(TDocStd_Document) Doc;
483   _OCAFApp->NewDocument("SALOME_STUDY",Doc); 
484
485   MESSAGE("NewStudy : Creating the CORBA servant holding it... ");
486   SALOMEDS_Study_i *Study_servant = new SALOMEDS_Study_i(Doc,_orb,study_name); 
487   SALOMEDS::Study_var Study = SALOMEDS::Study::_narrow(Study_servant->_this());
488
489   //Study->StudyId( _OCAFApp->NbDocuments() ); 
490   _IDcounter++;
491   Study->StudyId( _IDcounter );
492
493   // Register study in the naming service
494   // Path to acces the study
495   if(!_name_service->Change_Directory("/Study")) 
496       MESSAGE( "Unable to access the study directory" )
497   else
498       _name_service->Register(Study, study_name);
499
500   // Assign the value of the IOR in the study->root
501   const char*  IORStudy = _orb->object_to_string(Study);
502   SALOMEDS_IORAttribute::Set(Doc->Main().Root(),TCollection_ExtendedString(strdup(IORStudy)),_orb);
503
504   // set Study properties
505   SALOMEDS::AttributeStudyProperties_ptr aProp = Study->GetProperties();
506   OSD_Process aProcess;
507   Quantity_Date aDate = aProcess.SystemDate();
508   aProp->SetCreationDate(CORBA::Long(aDate.Minute()), CORBA::Long(aDate.Hour()), CORBA::Long(aDate.Day()),
509                          CORBA::Long(aDate.Month()), CORBA::Long(aDate.Year()));
510   aProp->SetCreationMode("from scratch");
511   aProp->SetUserName(aProcess.UserName().ToCString());
512
513   return Study;
514 }
515
516 //============================================================================
517 /*! Function : Open
518  *  Purpose  : Open a Study from it's persistent reference
519  */
520 //============================================================================
521 SALOMEDS::Study_ptr  SALOMEDS_StudyManager_i::Open(const char* aUrl)
522      throw(SALOME::SALOME_Exception)
523 {
524   MESSAGE("Begin of SALOMEDS_StudyManager_i::Open");
525   // open the HDFFile 
526   HDFfile *hdf_file =0;         
527   HDFgroup *hdf_group_study_structure =0;
528
529   hdf_file = new HDFfile((char *)aUrl);
530   try {
531     hdf_file->OpenOnDisk(HDF_RDONLY);// mpv: was RDWR, but opened file can be write-protected too
532   }
533   catch (HDFexception)
534     {
535 //        MESSAGE( "HDFexception ! " );
536 //        cerr << "HDFexception ! " << endl;
537       char eStr[strlen(aUrl)+17];
538       sprintf(eStr,"Can't open file %s",aUrl);
539       THROW_SALOME_CORBA_EXCEPTION(CORBA::string_dup(eStr),SALOME::BAD_PARAM);
540       
541     } 
542   MESSAGE("Open : Creating the CORBA servant holding it... ");
543
544   // Temporary aStudyUrl in place of study name
545   Handle(TDocStd_Document) Doc;
546   _OCAFApp->NewDocument("SALOME_STUDY",Doc); 
547
548   SALOMEDS_Study_i * Study_servant = new SALOMEDS_Study_i(Doc, _orb, aUrl);  
549   SALOMEDS::Study_var Study = SALOMEDS::Study::_narrow(Study_servant->_this()); 
550
551   //  Study->StudyId( _OCAFApp->NbDocuments() ); 
552   _IDcounter++;
553   Study->StudyId( _IDcounter );
554
555   // Register study in the naming service
556   // Path to acces the study
557   if(!_name_service->Change_Directory("/Study")) 
558       MESSAGE( "Unable to access the study directory" )
559   else
560     {
561       char* aPath = CORBA::string_dup(aUrl);
562       char *aName = NULL;
563       char *adr = strtok(aPath, "/");
564       while (adr)
565         {
566           aName = adr;
567           adr = strtok(NULL, "/");
568         }
569       adr = aName;
570       aName = strtok(adr, ".");
571       SCRUTE(aName);
572       _name_service->Register(Study, CORBA::string_dup(aName));
573       CORBA::string_free(aPath);
574     }
575
576   // Assign the value of the IOR in the study->root
577   CORBA::String_var IORStudy = _orb->object_to_string(Study);
578   SALOMEDS_IORAttribute::Set(Doc->Main().Root(),
579                              TCollection_ExtendedString(CORBA::string_dup(IORStudy)),_orb);
580
581   // Assign the value of the URL in the study object
582   Study->URL (aUrl);
583   SCRUTE(aUrl);
584   SALOMEDS_PersRefAttribute::Set(Doc->Main(),strdup(aUrl)); 
585
586   if (!hdf_file->ExistInternalObject("STUDY_STRUCTURE")) {
587     MESSAGE("SALOMEDS_StudyManager::Open : the study is empty");
588     return Study;
589   }
590
591   //Create  the Structure of the OCAF Document
592   hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file);
593
594   Handle(TDF_Data) DF = Doc->GetData();
595
596   try {
597     BuildTree (DF,hdf_group_study_structure);
598   }
599   catch (HDFexception)
600     {
601 //        MESSAGE( "HDFexception ! " );
602 //        cerr << "HDFexception ! " << endl;
603       char eStr[strlen(aUrl)+17];
604       sprintf(eStr,"Can't open file %s",aUrl);
605       THROW_SALOME_CORBA_EXCEPTION(CORBA::string_dup(eStr),SALOME::BAD_PARAM);
606     } 
607   
608   hdf_file->CloseOnDisk();
609   delete hdf_file; // all related hdf objects will be deleted
610
611   return Study;
612 }
613
614
615
616 //============================================================================
617 /*! Function : Close
618  *  Purpose  : Close a study.
619  *             If the study hasn't been saved, ask the user to confirm the
620  *             close action without saving 
621  */
622 //============================================================================
623 void  SALOMEDS_StudyManager_i::Close(SALOMEDS::Study_ptr aStudy)
624 {
625   if(aStudy->_is_nil()) return;
626     
627   // Destroy study name in the naming service
628   if(_name_service->Change_Directory("/Study")) 
629     _name_service->Destroy_Name(aStudy->Name());
630   
631   aStudy->Close();
632 }
633
634 //============================================================================
635 /*! Function : Save
636  *  Purpose  : Save a Study to it's persistent reference
637  */
638 //============================================================================
639 void SALOMEDS_StudyManager_i::Save(SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
640 {
641   CORBA::String_var url = aStudy->URL();
642   if (url==NULL)
643     MESSAGE( "No path specified to save the study. Nothing done")
644   else
645     {
646       _SaveAs(url,aStudy, theMultiFile);
647     }
648 }
649
650
651 //=============================================================================
652 /*! Function : SaveAs
653  *  Purpose  : Save a study to the persistent reference aUrl
654  */
655 //============================================================================
656 void SALOMEDS_StudyManager_i::SaveAs(const char* aUrl, SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
657 {
658   // Save the URL of the Study => to be used with the function "Save"
659   aStudy->URL(aUrl);
660   
661   _SaveAs(aUrl,aStudy,theMultiFile);
662 }
663
664 //============================================================================
665 /*! Function : GetOpenStudies
666  *  Purpose  : Get name list of open studies in the session
667  */
668 //============================================================================
669 SALOMEDS::ListOfOpenStudies*  SALOMEDS_StudyManager_i::GetOpenStudies()
670 {
671   // MESSAGE("Begin of GetOpenStudies");
672   SALOMEDS::ListOfOpenStudies_var _list_open_studies = new SALOMEDS::ListOfOpenStudies;
673   _list_open_studies->length(0);
674   vector<string> _list ;
675
676   if(!_name_service->Change_Directory("/Study"))
677     {
678       MESSAGE("No active study in this session");
679     }
680   else
681     {
682       _list = _name_service->list_directory();
683       _list_open_studies->length(_list.size());
684       for (unsigned int ind=0; ind < _list.size();ind++)
685         {
686           _list_open_studies[ind]=CORBA::string_dup(_list[ind].c_str());
687           SCRUTE(_list_open_studies[ind]) ;
688         }
689     }
690   return _list_open_studies._retn();
691 }
692
693 //============================================================================
694 /*! Function : GetStudyByName
695  *  Purpose  : Get a study from its name
696  */
697 //============================================================================
698 SALOMEDS::Study_ptr  
699 SALOMEDS_StudyManager_i::GetStudyByName(const char* aStudyName) 
700 {
701   SALOMEDS::Study_var Study;
702
703   // Go to study directory and look for aStudyName
704   if(!_name_service->Change_Directory("/Study"))
705     {
706       MESSAGE("No active study in this session");
707       ASSERT(false); // Stop here...
708     }
709   
710 //   const char *theStudyName = this->_SubstituteSlash(aStudyName);
711   const char* theStudyName = CORBA::string_dup(aStudyName);
712
713   if(_name_service->Find(theStudyName)>0)
714     {
715     // Study found
716     CORBA::Object_ptr obj= _name_service->Resolve(theStudyName) ;
717     Study = SALOMEDS::Study::_narrow(obj);
718     MESSAGE("Study " << theStudyName << " found in the naming service");
719     }
720   else  
721     {
722       Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil()); 
723       MESSAGE("Study " << theStudyName << " not found in the naming service");
724     }
725   return Study;
726 }
727
728 //============================================================================
729 /*! Function : GetStudyByID
730  *  Purpose  : Get a study from its ID
731  */
732 //============================================================================
733 SALOMEDS::Study_ptr  
734 SALOMEDS_StudyManager_i::GetStudyByID(CORBA::Short aStudyID) 
735 {
736   SALOMEDS::Study_var Study;
737   vector<string> _list ;
738
739   if(!_name_service->Change_Directory("/Study"))
740     {
741       MESSAGE("No active study in this session");
742     }
743   else
744     {
745       _list = _name_service->list_directory();
746       for (unsigned int ind=0; ind < _list.size();ind++)
747         {
748           const char* theStudyName = CORBA::string_dup(_list[ind].c_str());
749           MESSAGE ( "GetStudyByID = " << theStudyName )
750
751           if(_name_service->Find(theStudyName)>0) {
752             CORBA::Object_ptr obj= _name_service->Resolve(theStudyName) ;
753             Study = SALOMEDS::Study::_narrow(obj);
754
755             MESSAGE ( " aStudyID : " << aStudyID << "-" << Study->StudyId() )
756
757             if ( aStudyID == Study->StudyId() ) {
758               MESSAGE("Study with studyID = " << aStudyID << " found in the naming service");
759               return Study;
760             }
761           } else {
762             Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil()); 
763             MESSAGE("Study " << theStudyName << " not found in the naming service");
764           }
765         }
766       Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil()); 
767     }
768   return Study;
769 }
770 //============================================================================
771 /*! Function : SaveAttributes
772  *  Purpose  : Save attributes for object
773  */
774 //============================================================================
775 static void SaveAttributes(SALOMEDS::SObject_ptr SO, HDFgroup *hdf_group_sobject) {
776   HDFdataset *hdf_dataset = 0;
777   hdf_size size[1];
778   hdf_int32 name_len = 0;
779   SALOMEDS::GenericAttribute_var SObj;
780   if(SO->FindAttribute(SObj, "AttributeComment"))
781     {
782       SALOMEDS::AttributeComment_var Comment = SALOMEDS::AttributeComment::_narrow(SObj);
783         CORBA::String_var Val = Comment->Value();
784         name_len = (hdf_int32) strlen(Val);
785         size[0] = name_len +1 ; 
786         hdf_dataset = new HDFdataset("AttributeComment",hdf_group_sobject,HDF_STRING,size,1);
787         hdf_dataset->CreateOnDisk();
788         hdf_dataset->WriteOnDisk(Val);
789         MESSAGE("attribute comment " <<  Val << " wrote on file");
790         hdf_dataset->CloseOnDisk();
791         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
792       }
793   // Attribute  SALOMEDS::PersistentRef
794   if(SO->FindAttribute(SObj, "AttributePersistentRef"))
795     {
796       SALOMEDS::AttributePersistentRef_var PersRef = SALOMEDS::AttributePersistentRef::_narrow(SObj);
797         CORBA::String_var Val = PersRef->Value();
798         name_len = (hdf_int32) strlen(Val);
799         size[0] = name_len +1 ; 
800         hdf_dataset = new HDFdataset("AttributePersistentRef",hdf_group_sobject,HDF_STRING,size,1);
801         hdf_dataset->CreateOnDisk();
802         hdf_dataset->WriteOnDisk(Val);
803         MESSAGE("attribute persistentref " <<  Val << " wrote on file");
804         hdf_dataset->CloseOnDisk();
805         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
806       }
807   // Attribute  SALOMEDS::Name
808   if(SO->FindAttribute(SObj, "AttributeName"))
809     {
810       SALOMEDS::AttributeName_var NameRef = SALOMEDS::AttributeName::_narrow(SObj);
811         CORBA::String_var Val = NameRef->Value();
812         name_len = (hdf_int32) strlen(Val);
813         size[0] = name_len +1 ; 
814         hdf_dataset = new HDFdataset("AttributeName",hdf_group_sobject,HDF_STRING,size,1);
815         hdf_dataset->CreateOnDisk();
816         hdf_dataset->WriteOnDisk(Val);
817         MESSAGE("attribute name " <<  Val << " wrote on file");
818         hdf_dataset->CloseOnDisk();
819         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
820       }
821   if(SO->FindAttribute(SObj, "AttributeReal"))
822     {
823       char RealVal[25];
824       SALOMEDS::AttributeReal_var RealRef = SALOMEDS::AttributeReal::_narrow(SObj);
825       sprintf(RealVal, "%f", RealRef->Value());
826       name_len = (hdf_int32) strlen(RealVal);
827       size[0] = name_len +1 ; 
828       hdf_dataset = new HDFdataset("AttributeReal",hdf_group_sobject,HDF_STRING,size,1);
829       hdf_dataset->CreateOnDisk();
830       hdf_dataset->WriteOnDisk(RealVal);
831       MESSAGE("attribute Real " <<  RealVal << " wrote on file");
832       hdf_dataset->CloseOnDisk();
833       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
834     }
835   if(SO->FindAttribute(SObj, "AttributeInteger"))
836     {
837       char IntVal[25];
838       SALOMEDS::AttributeInteger_var IntRef = SALOMEDS::AttributeInteger::_narrow(SObj);
839       sprintf(IntVal, "%d", IntRef->Value());
840       name_len = (hdf_int32) strlen(IntVal);
841       size[0] = name_len +1 ; 
842       hdf_dataset = new HDFdataset("AttributeInteger",hdf_group_sobject,HDF_STRING,size,1);
843       hdf_dataset->CreateOnDisk();
844       hdf_dataset->WriteOnDisk(IntVal);
845       MESSAGE("attribute Real " <<  IntVal << " wrote on file");
846       hdf_dataset->CloseOnDisk();
847       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
848     }     
849   
850   if(SO->FindAttribute(SObj, "AttributeSequenceOfReal"))
851     {
852       SALOMEDS::AttributeSequenceOfReal_var RealSeq = SALOMEDS::AttributeSequenceOfReal::_narrow(SObj);
853         size[0] = RealSeq->Length();
854         SALOMEDS::DoubleSeq_var DS = RealSeq->CorbaSequence();
855         hdf_dataset = new HDFdataset("AttributeSequenceOfReal",hdf_group_sobject,HDF_FLOAT64,size,1);
856         hdf_dataset->CreateOnDisk();
857         hdf_float64 *data = new hdf_float64[RealSeq->Length()];
858         for (Standard_Integer i = 0; i < RealSeq->Length(); i++) {
859           MESSAGE("Value =  " << i << " = " << DS[i]  << " wrote on file");
860           data[i] = DS[i];
861         }
862         hdf_dataset->WriteOnDisk(data);
863         //               delete data;
864         hdf_dataset->CloseOnDisk();
865         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
866       }
867   if(SO->FindAttribute(SObj, "AttributeSequenceOfInteger"))
868     {
869       SALOMEDS::AttributeSequenceOfInteger_var IntSeq = SALOMEDS::AttributeSequenceOfInteger::_narrow(SObj);
870         size[0] = IntSeq->Length();
871         SALOMEDS::LongSeq_var LS = IntSeq->CorbaSequence();
872         hdf_dataset = new HDFdataset("AttributeSequenceOfInteger",hdf_group_sobject,HDF_INT32,size,1);
873         hdf_dataset->CreateOnDisk();
874         hdf_int32 *data = new hdf_int32[IntSeq->Length()];
875         for (Standard_Integer i = 0; i < IntSeq->Length(); i++) {
876           MESSAGE("Value =  " << i << " = " << LS[i]  << " wrote on file");
877           data[i] = LS[i];
878         }
879         hdf_dataset->WriteOnDisk(data);
880         hdf_dataset->CloseOnDisk();
881         //               delete data;
882         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
883       }
884     if(SO->FindAttribute(SObj, "AttributeDrawable"))
885     {
886       char IntVal[25];
887       SALOMEDS::AttributeDrawable_var DrRef = SALOMEDS::AttributeDrawable::_narrow(SObj);
888       sprintf(IntVal, "%d", DrRef->IsDrawable());
889       name_len = (hdf_int32) strlen(IntVal);
890       size[0] = name_len +1 ; 
891       hdf_dataset = new HDFdataset("AttributeDrawable",hdf_group_sobject,HDF_STRING,size,1);
892       hdf_dataset->CreateOnDisk();
893       hdf_dataset->WriteOnDisk(IntVal);
894       MESSAGE("attribute Drawable " <<  IntVal << " wrote on file");
895       hdf_dataset->CloseOnDisk();
896       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
897     }     
898   if(SO->FindAttribute(SObj, "AttributeSelectable"))
899     {
900       char IntVal[25];
901       SALOMEDS::AttributeSelectable_var SelRef = SALOMEDS::AttributeSelectable::_narrow(SObj);
902       sprintf(IntVal, "%d", SelRef->IsSelectable());
903       name_len = (hdf_int32) strlen(IntVal);
904       size[0] = name_len +1 ; 
905       hdf_dataset = new HDFdataset("AttributeSelectable",hdf_group_sobject,HDF_STRING,size,1);
906       hdf_dataset->CreateOnDisk();
907       hdf_dataset->WriteOnDisk(IntVal);
908       MESSAGE("attribute Selectable " <<  IntVal << " wrote on file");
909       hdf_dataset->CloseOnDisk();
910       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
911     }     
912   if(SO->FindAttribute(SObj, "AttributeExpandable"))
913     {
914       char IntVal[25];
915       SALOMEDS::AttributeExpandable_var ExRef = SALOMEDS::AttributeExpandable::_narrow(SObj);
916       sprintf(IntVal, "%d", ExRef->IsExpandable());
917       name_len = (hdf_int32) strlen(IntVal);
918       size[0] = name_len +1 ; 
919       hdf_dataset = new HDFdataset("AttributeExpandable",hdf_group_sobject,HDF_STRING,size,1);
920       hdf_dataset->CreateOnDisk();
921       hdf_dataset->WriteOnDisk(IntVal);
922       MESSAGE("attribute Expandable " <<  IntVal << " wrote on file");
923       hdf_dataset->CloseOnDisk();
924       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
925     }     
926   if(SO->FindAttribute(SObj, "AttributeOpened"))
927     {
928       char IntVal[25];
929       SALOMEDS::AttributeOpened_var OpRef = SALOMEDS::AttributeOpened::_narrow(SObj);
930       sprintf(IntVal, "%d", OpRef->IsOpened());
931       name_len = (hdf_int32) strlen(IntVal);
932       size[0] = name_len +1 ; 
933       hdf_dataset = new HDFdataset("AttributeOpened",hdf_group_sobject,HDF_STRING,size,1);
934       hdf_dataset->CreateOnDisk();
935       hdf_dataset->WriteOnDisk(IntVal);
936       MESSAGE("attribute Opened " <<  IntVal << " wrote on file");
937       hdf_dataset->CloseOnDisk();
938       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
939     }     
940   if(SO->FindAttribute(SObj, "AttributeTextColor"))
941     {
942       SALOMEDS::AttributeTextColor_var TextRef = SALOMEDS::AttributeTextColor::_narrow(SObj);
943       size[0] = 3;
944       hdf_float64 data[3];
945       SALOMEDS::Color C = TextRef->TextColor();
946       data[0] = C.R;
947       data[1] = C.G;
948       data[2] = C.B;
949       hdf_dataset = new HDFdataset("AttributeTextColor",hdf_group_sobject,HDF_FLOAT64,size,1);
950       hdf_dataset->CreateOnDisk();
951       hdf_dataset->WriteOnDisk(data);
952       MESSAGE("attribute  AttributeTextColor wrote on file");
953       hdf_dataset->CloseOnDisk();
954       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
955     }     
956     if(SO->FindAttribute(SObj, "AttributeTextHighlightColor"))
957     {
958       SALOMEDS::AttributeTextHighlightColor_var TextRef = SALOMEDS::AttributeTextHighlightColor::_narrow(SObj);
959       size[0] = 3;
960       hdf_float64 data[3];
961       SALOMEDS::Color C = TextRef->TextHighlightColor();
962       data[0] = C.R;
963       data[1] = C.G;
964       data[2] = C.B;
965       hdf_dataset = new HDFdataset("AttributeTextHighlightColor",hdf_group_sobject,HDF_FLOAT64,size,1);
966       hdf_dataset->CreateOnDisk();
967       hdf_dataset->WriteOnDisk(data);
968       MESSAGE("attribute  AttributeTextHighlightColor wrote on file");
969       hdf_dataset->CloseOnDisk();
970       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
971     }     
972   if(SO->FindAttribute(SObj, "AttributePixMap"))
973     {
974       SALOMEDS::AttributePixMap_var PMRef = SALOMEDS::AttributePixMap::_narrow(SObj);
975       if (PMRef->HasPixMap()) {
976         CORBA::String_var Val = PMRef->GetPixMap();
977         name_len = (hdf_int32) strlen(Val);
978         size[0] = name_len +1 ; 
979         hdf_dataset = new HDFdataset("AttributePixMap",hdf_group_sobject,HDF_STRING,size,1);
980         hdf_dataset->CreateOnDisk();
981         hdf_dataset->WriteOnDisk(Val);
982           MESSAGE("attribute PixMap " <<  Val << " wrote on file");
983         hdf_dataset->CloseOnDisk();
984         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
985       }
986     }
987   if(SO->FindAttribute(SObj, "AttributeLocalID"))
988     {
989       char IntVal[25];
990       SALOMEDS::AttributeLocalID_var LIDRef = SALOMEDS::AttributeLocalID::_narrow(SObj);
991       sprintf(IntVal, "%d", LIDRef->Value());
992       name_len = (hdf_int32) strlen(IntVal);
993       size[0] = name_len +1 ; 
994       hdf_dataset = new HDFdataset("AttributeLocalID",hdf_group_sobject,HDF_STRING,size,1);
995       hdf_dataset->CreateOnDisk();
996       hdf_dataset->WriteOnDisk(IntVal);
997       hdf_dataset->CloseOnDisk();
998       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
999       MESSAGE("attribute  AttributeLocalID wrote on file");
1000     }     
1001   if(SO->FindAttribute(SObj, "AttributeTableOfInteger"))
1002     {
1003       SALOMEDS::AttributeTableOfInteger_var IntTab = SALOMEDS::AttributeTableOfInteger::_narrow(SObj);
1004       SALOMEDS::TMPFile_var aStream = IntTab->SaveToFile();
1005       
1006       hdf_size aHDFSize[1];
1007       aHDFSize[0] = aStream->length();
1008       
1009       HDFdataset *hdf_dataset = new HDFdataset("AttributeTableOfInteger",hdf_group_sobject, HDF_STRING, aHDFSize, 1);
1010       hdf_dataset->CreateOnDisk();
1011       hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
1012       hdf_dataset->CloseOnDisk();
1013       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1014       
1015       MESSAGE("attribute  AttributeTableOfInteger wrote on file");
1016     }
1017   if(SO->FindAttribute(SObj, "AttributeTableOfReal"))
1018     {
1019       SALOMEDS::AttributeTableOfReal_var RealTab = SALOMEDS::AttributeTableOfReal::_narrow(SObj);
1020       SALOMEDS::TMPFile_var aStream = RealTab->SaveToFile();
1021       
1022       hdf_size aHDFSize[1];
1023       aHDFSize[0] = aStream->length();
1024       
1025       HDFdataset *hdf_dataset = new HDFdataset("AttributeTableOfReal",hdf_group_sobject, HDF_STRING, aHDFSize, 1);
1026       hdf_dataset->CreateOnDisk();
1027       hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
1028       hdf_dataset->CloseOnDisk();
1029       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1030
1031       MESSAGE("attribute  AttributeTableOfReal wrote on file")
1032     }
1033   if(SO->FindAttribute(SObj, "AttributeTableOfString"))
1034     {
1035       SALOMEDS::AttributeTableOfString_var StrTab = SALOMEDS::AttributeTableOfString::_narrow(SObj);
1036       SALOMEDS::TMPFile_var aStream = StrTab->SaveToFile();
1037       
1038       hdf_size aHDFSize[1];
1039       aHDFSize[0] = aStream->length();
1040       
1041       HDFdataset *hdf_dataset = new HDFdataset("AttributeTableOfString",hdf_group_sobject, HDF_STRING, aHDFSize, 1);
1042       hdf_dataset->CreateOnDisk();
1043       hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
1044       hdf_dataset->CloseOnDisk();
1045       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1046
1047       MESSAGE("attribute  AttributeTableOfString wrote on file")
1048     }
1049   if(SO->FindAttribute(SObj, "AttributePythonObject"))
1050     {
1051       SALOMEDS::AttributePythonObject_var anObj = SALOMEDS::AttributePythonObject::_narrow(SObj);
1052       char* aSeq = CORBA::string_dup(anObj->GetObject());
1053       int aLen = strlen(aSeq);
1054       char* aString = new char[aLen+2];
1055       aString[0] = anObj->IsScript()?'s':'n';
1056       for(int i = 0; i < aLen; i++) aString[i+1] = aSeq[i];
1057       aString[aLen+1] = 0;
1058       size[0] = aLen+2 ; 
1059       hdf_dataset = new HDFdataset("AttributePythonObject",hdf_group_sobject,HDF_STRING,size,1);
1060       hdf_dataset->CreateOnDisk();
1061       hdf_dataset->WriteOnDisk(aString);
1062       hdf_dataset->CloseOnDisk();
1063       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1064       MESSAGE("attribute  AttributePythonObject wrote on file");
1065     }     
1066
1067 // Reference
1068   SALOMEDS::SObject_var RefSO;
1069   if(SO->ReferencedObject(RefSO))
1070     {
1071       CORBA::String_var attribute_reference = strdup(RefSO->GetID());
1072       name_len = (hdf_int32) strlen(attribute_reference);
1073       size[0] = name_len +1 ; 
1074       hdf_dataset = new HDFdataset("Reference",hdf_group_sobject,HDF_STRING,size,1);
1075       hdf_dataset->CreateOnDisk();
1076       hdf_dataset->WriteOnDisk(attribute_reference);
1077       MESSAGE("attribute reference " <<  attribute_reference << " wrote on file");
1078       hdf_dataset->CloseOnDisk();
1079       hdf_dataset =0; // will be deleted by father hdf object destructor
1080     }
1081
1082 // TreeNodeAttributes with not constant GUID
1083   SALOMEDS::ListOfAttributes_var anAttrList = SO->GetAllAttributes();
1084   int anIndex, aLength = anAttrList->length();
1085   for(anIndex = 0; anIndex<aLength; anIndex++) {
1086     SALOMEDS::AttributeUserID_var UAttr = SALOMEDS::AttributeUserID::_narrow(anAttrList[anIndex]);
1087     if (!UAttr->_is_nil()) {
1088       char* Val = UAttr->Value();
1089       name_len = (hdf_int32) strlen(Val);
1090       size[0] = name_len + 1;
1091       char* aDataSetName = new char[60];
1092       sprintf(aDataSetName, "AttributeUserID_%s",Val);
1093       hdf_dataset = new HDFdataset(aDataSetName,hdf_group_sobject,HDF_STRING,size,1);
1094       hdf_dataset->CreateOnDisk();
1095       hdf_dataset->WriteOnDisk(Val);
1096       MESSAGE("attribute UesrID " <<  Val << " wrote on file");
1097       hdf_dataset->CloseOnDisk();
1098       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1099       delete(aDataSetName);
1100       continue;
1101     }
1102
1103     SALOMEDS::AttributeTreeNode_var TNRef = SALOMEDS::AttributeTreeNode::_narrow(anAttrList[anIndex]);
1104     if (!TNRef->_is_nil()) {
1105       hdf_size TNsize[2];
1106       int maxSize,index;
1107       CORBA::String_var Val[5];
1108       
1109       if (TNRef->HasFather()) Val[0] = TNRef->GetFather()->Label(); else Val[0] = "\0";
1110       maxSize = strlen(Val[0]);
1111       if (TNRef->HasPrevious()) Val[1] = TNRef->GetPrevious()->Label(); else Val[1] = "\0";
1112       maxSize = Max(maxSize,strlen(Val[1]));
1113       if (TNRef->HasNext()) Val[2] = TNRef->GetNext()->Label(); else Val[2] = "\0";
1114       maxSize = Max(maxSize,strlen(Val[2]));
1115       if (TNRef->HasFirst()) Val[3] = TNRef->GetFirst()->Label(); else Val[3] = "\0";
1116       maxSize = Max(maxSize,strlen(Val[3]));
1117       Val[4] = TNRef->GetTreeID();
1118       maxSize = Max(maxSize,strlen(Val[4]));
1119       
1120       TNsize[0]=5;
1121       TNsize[1]=maxSize+1;
1122       char Data[5][maxSize+1];
1123       for(index=0;index<5;index++) strcpy(Data[index],Val[index]);
1124       
1125       char* aDataSetName = new char[60];
1126       sprintf(aDataSetName, "AttributeTreeNodeGUID%s",TNRef->GetTreeID());
1127       hdf_dataset = new HDFdataset(aDataSetName,hdf_group_sobject,HDF_STRING,TNsize,2);
1128       hdf_dataset->CreateOnDisk();
1129       hdf_dataset->WriteOnDisk(Data);
1130       hdf_dataset->CloseOnDisk();
1131       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1132       MESSAGE("attribute AttributeTreeNode with various GUID wrote on file:");
1133       MESSAGE(aDataSetName);
1134       delete(aDataSetName);
1135     }
1136   }
1137 }
1138
1139 //=============================================================================
1140 /*! Function : _SaveProperties
1141  *  Purpose  : save the study properties in HDF file
1142  */
1143 //============================================================================
1144 void SALOMEDS_StudyManager_i::_SaveProperties(SALOMEDS::Study_ptr aStudy, HDFgroup *hdf_group) {
1145   HDFdataset *hdf_dataset = 0;
1146   hdf_size size[1];
1147   hdf_int32 name_len;
1148
1149   // add modifications list (user and date of save)
1150   SALOMEDS::AttributeStudyProperties_ptr aProp = aStudy->GetProperties();
1151   SALOMEDS::StudyBuilder_var SB= aStudy->NewBuilder();
1152 //    SB->NewCommand();
1153   int aLocked = aProp->IsLocked();
1154   if (aLocked) aProp->SetLocked(Standard_False);
1155   OSD_Process aProcess;
1156   Quantity_Date aDate = aProcess.SystemDate();
1157   aProp->SetModification(aProcess.UserName().ToCString(),
1158                          CORBA::Long(aDate.Minute()), CORBA::Long(aDate.Hour()), CORBA::Long(aDate.Day()),
1159                          CORBA::Long(aDate.Month()), CORBA::Long(aDate.Year()));
1160   if (aLocked) aProp->SetLocked(Standard_True);
1161 //    SB->CommitCommand();
1162   
1163
1164   SALOMEDS::StringSeq_var aNames;
1165   SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
1166   aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, true);
1167   int aLength, anIndex;
1168   for(aLength = 0, anIndex = aNames->length() - 1; anIndex >= 0; anIndex--) aLength += strlen(aNames[anIndex]) + 1;
1169
1170   // string length: 1 byte = locked flag, 1 byte = modified flag, (12 + name length + 1) for each name and date, "zero" byte
1171   char* aProperty = new char[3 + aLength + 12 * aNames->length()];
1172
1173   sprintf(aProperty,"%c%c",
1174           (strlen(aProp->GetCreationMode()) != 0)?aProp->GetCreationMode()[0]:'0',
1175           (aProp->IsLocked())?'l':'u');
1176
1177   aLength = aNames->length();
1178   int a = 2;
1179   for(anIndex = 0; anIndex  < aLength; anIndex++) {
1180     sprintf(&(aProperty[a]),"%2d%2d%2d%2d%4d%s",
1181             (int)(aMinutes[anIndex]),
1182             (int)(aHours[anIndex]),
1183             (int)(aDays[anIndex]),
1184             (int)(aMonths[anIndex]),
1185             (int)(aYears[anIndex]),
1186             (char*)aNames[anIndex]);
1187     a = strlen(aProperty);
1188     aProperty[a++] = 1;
1189   }
1190   aProperty[a] = 0;
1191
1192   name_len = (hdf_int32) a;
1193 //    MESSAGE("*** Property: "<<aProperty);
1194   size[0] = name_len + 1 ; 
1195   hdf_dataset = new HDFdataset("AttributeStudyProperties",hdf_group,HDF_STRING,size,1);
1196   hdf_dataset->CreateOnDisk();
1197   hdf_dataset->WriteOnDisk(aProperty);
1198   MESSAGE("attribute StudyProperties " <<  aProperty << " wrote on file");
1199   hdf_dataset->CloseOnDisk();
1200   hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1201   delete(aProperty);
1202   aProp->SetModified(0);
1203 }
1204
1205 //=============================================================================
1206 /*! Function : _SaveAs
1207  *  Purpose  : save the study in HDF file
1208  */
1209 //============================================================================
1210 void SALOMEDS_StudyManager_i::_SaveAs(const char* aUrl, 
1211                                       SALOMEDS::Study_ptr aStudy,
1212                                       CORBA::Boolean theMultiFile)
1213 {
1214   // HDF File will be composed of differents part :
1215   // * For each ComponentDataType, all data created by the component
1216   //   Informations in data group hdf_group_datacomponent
1217   // * Study Structure -> Exactly what is contained in OCAF document
1218   //   Informations in data group hdf_group_study_structure
1219
1220   HDFfile *hdf_file=0;         
1221   HDFgroup *hdf_group_study_structure =0;
1222   HDFgroup *hdf_sco_group =0;
1223   HDFgroup *hdf_sco_group2 =0;
1224
1225   HDFgroup *hdf_group_datacomponent =0;
1226   HDFdataset *hdf_dataset =0;
1227   HDFattribute *hdf_attribute=0;
1228   hdf_size size[1];
1229   hdf_int32 name_len = 0;
1230   char *component_name = 0;
1231   char *attribute_name = 0;
1232   char *attribute_comment = 0;
1233   char *attribute_persistentref = 0;
1234
1235   int aLocked = aStudy->GetProperties()->IsLocked();
1236   if (aLocked) aStudy->GetProperties()->SetLocked(false);
1237
1238   SALOMEDS::StudyBuilder_var SB= aStudy->NewBuilder();
1239
1240   aStudy->URL(aUrl);
1241
1242   ASSERT(!CORBA::is_nil(aStudy));
1243   try
1244     {
1245       // To change for Save 
1246       // Do not have to do a new file but just a Open??? Rewrite all informations after erasing evrything??
1247       hdf_file = new HDFfile((char *)aUrl);
1248       hdf_file->CreateOnDisk();
1249       MESSAGE("File " << aUrl << " created");
1250
1251       //-----------------------------------------------------------------------
1252       // 1 - Create a groupe for each SComponent and Update the PersistanceRef
1253       //-----------------------------------------------------------------------
1254       hdf_group_datacomponent = new HDFgroup("DATACOMPONENT",hdf_file);
1255       hdf_group_datacomponent->CreateOnDisk();
1256
1257       SALOMEDS::SComponentIterator_var itcomponent = aStudy->NewComponentIterator();
1258
1259       for (; itcomponent->More(); itcomponent->Next())
1260         {
1261           SALOMEDS::SComponent_var sco = itcomponent->Value();
1262           
1263           CORBA::String_var scoid = sco->GetID();
1264           hdf_sco_group = new HDFgroup(scoid,hdf_group_datacomponent);
1265           hdf_sco_group->CreateOnDisk();
1266
1267           CORBA::String_var componentDataType = sco->ComponentDataType();
1268           MESSAGE ( "Look for  an engine for data type :"<< componentDataType);
1269           // if there is an associated Engine call its method for saving
1270           CORBA::String_var IOREngine;
1271           if (sco->ComponentIOR(IOREngine))
1272             {
1273               // we have found the associated engine to write the data 
1274               MESSAGE ( "We have found an engine for data type :"<< componentDataType);
1275               CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1276               SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
1277               
1278               if (!CORBA::is_nil(Engine))
1279                 {
1280                   MESSAGE ( "Save the data of type:"<< componentDataType);
1281                   MESSAGE("Engine :"<<Engine->ComponentDataType());
1282
1283                   SALOMEDS::TMPFile_var aStream = Engine->Save(sco,
1284                                                                SALOMEDS_Tool::GetDirFromPath(aUrl),
1285                                                                theMultiFile);
1286                   HDFdataset *hdf_dataset;
1287                   hdf_size aHDFSize[1];
1288                   if(aStream->length() > 0) {  //The component saved some auxiliary files, then put them into HDF file 
1289
1290                     aHDFSize[0] = aStream->length();
1291                       
1292                     HDFdataset *hdf_dataset = new HDFdataset("FILE_STREAM", hdf_sco_group, HDF_STRING, aHDFSize, 1);
1293                     hdf_dataset->CreateOnDisk();
1294                     hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
1295                     hdf_dataset->CloseOnDisk();
1296                   }
1297                   // store multifile state
1298                   aHDFSize[0] = 2;
1299                   hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
1300                   hdf_dataset->CreateOnDisk();
1301                   hdf_dataset->WriteOnDisk((void*)(theMultiFile?"M":"S")); // save: multi or single
1302                   hdf_dataset->CloseOnDisk();
1303                   hdf_dataset=0; //will be deleted by hdf_sco_AuxFiles destructor                
1304
1305                   Translate_IOR_to_persistentID (aStudy,SB,sco,Engine,theMultiFile);
1306                   MESSAGE("After Translate_IOR_to_persistentID");
1307                   
1308                   // Creation of the persistance reference  attribute
1309                 }
1310             }
1311           hdf_sco_group->CloseOnDisk();
1312           hdf_sco_group=0; // will be deleted by hdf_group_datacomponent destructor
1313         }
1314       hdf_group_datacomponent->CloseOnDisk();
1315       hdf_group_datacomponent =0;  // will be deleted by hdf_file destructor
1316
1317
1318       //-----------------------------------------------------------------------
1319       //3 - Write the Study Structure
1320       //-----------------------------------------------------------------------
1321       hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file);
1322       hdf_group_study_structure->CreateOnDisk();
1323
1324       // save component attributes
1325       SALOMEDS::SComponentIterator_var itcomp = aStudy->NewComponentIterator();
1326       for (; itcomp->More(); itcomp->Next()) 
1327         {
1328           SALOMEDS::SComponent_var SC = itcomp->Value();
1329           
1330           CORBA::String_var scid = SC->GetID();
1331           hdf_sco_group2 = new HDFgroup(scid,hdf_group_study_structure);
1332           hdf_sco_group2->CreateOnDisk();
1333           SaveAttributes(SC, hdf_sco_group2);
1334           // ComponentDataType treatment
1335           component_name = SC->ComponentDataType();
1336           MESSAGE("Component data type " << component_name << " treated");
1337           
1338           name_len = (hdf_int32) strlen(component_name);
1339           size[0] = name_len +1 ; 
1340           hdf_dataset = new HDFdataset("COMPONENTDATATYPE",hdf_sco_group2,HDF_STRING,size,1);
1341           hdf_dataset->CreateOnDisk();
1342           hdf_dataset->WriteOnDisk(component_name);
1343           MESSAGE("component name " <<  component_name << " wrote on file");
1344           hdf_dataset->CloseOnDisk();
1345           hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1346           _SaveObject(aStudy, SC, hdf_sco_group2);
1347           hdf_sco_group2->CloseOnDisk();
1348           hdf_sco_group2=0; // will be deleted by hdf_group_study_structure destructor
1349           CORBA::string_free(component_name);       
1350         }
1351       //-----------------------------------------------------------------------
1352       //4 - Write the Study UseCases Structure
1353       //-----------------------------------------------------------------------
1354       SALOMEDS::SObject_var aSO = aStudy->FindObjectID(USE_CASE_LABEL_ID);
1355       if (!aSO->_is_nil()) {
1356         HDFgroup *hdf_soo_group = new HDFgroup(USE_CASE_LABEL_ID,hdf_group_study_structure);
1357         hdf_soo_group->CreateOnDisk();
1358         SaveAttributes(aSO, hdf_soo_group);
1359         _SaveObject(aStudy, aSO, hdf_soo_group);
1360         MESSAGE("Use cases data structure writed");
1361         hdf_soo_group->CloseOnDisk();
1362         hdf_soo_group=0; // will be deleted by hdf_group_study_structure destructor
1363       }
1364
1365       if (aLocked) aStudy->GetProperties()->SetLocked(true);
1366       //-----------------------------------------------------------------------
1367       //5 - Write the Study Properties
1368       //-----------------------------------------------------------------------
1369       name_len = (hdf_int32) strlen(aStudy->Name());
1370       size[0] = name_len +1 ; 
1371       hdf_dataset = new HDFdataset("STUDY_NAME",hdf_group_study_structure,HDF_STRING,size,1);
1372       hdf_dataset->CreateOnDisk();
1373       CORBA::String_var studid = aStudy->Name();
1374       hdf_dataset->WriteOnDisk(studid);
1375       MESSAGE("study name " << studid << " wrote on file");
1376       hdf_dataset->CloseOnDisk();
1377       hdf_dataset=0; // will be deleted by hdf_group_study_structure destructor
1378
1379       _SaveProperties(aStudy, hdf_group_study_structure);
1380
1381       hdf_group_study_structure->CloseOnDisk();
1382       hdf_file->CloseOnDisk();
1383       aStudy->IsSaved(true);
1384       hdf_group_study_structure =0; // will be deleted by hdf_file destructor
1385       delete hdf_file; // recursively deletes all hdf objects...
1386     }
1387   catch (HDFexception)
1388     {
1389       MESSAGE( "HDFexception ! " )
1390     } 
1391 }
1392
1393 //============================================================================
1394 /*! Function : _SaveObject
1395  *  Purpose  :
1396  */
1397 //============================================================================
1398 void SALOMEDS_StudyManager_i::_SaveObject(SALOMEDS::Study_ptr aStudy, 
1399                                           SALOMEDS::SObject_ptr SC, 
1400                                           HDFgroup *hdf_group_datatype)
1401 {
1402   // Write in group hdf_group_datatype all informations of SObject SC
1403   // Iterative function to parse all SObjects under a SComponent
1404   SALOMEDS::SObject_var RefSO;
1405   HDFgroup *hdf_group_sobject = 0;
1406   HDFdataset *hdf_dataset = 0;
1407   hdf_size size[1];
1408   hdf_int32 name_len = 0;
1409
1410   SALOMEDS::ChildIterator_var itchild = aStudy->NewChildIterator(SC);
1411   for (; itchild->More(); itchild->Next()) 
1412     {
1413       SALOMEDS::SObject_var SO = itchild->Value();
1414
1415       // mpv: don't save empty labels
1416       if (SO->GetAllAttributes()->length() == 0) {
1417         SALOMEDS::ChildIterator_var subchild = aStudy->NewChildIterator(SC);
1418         if (!subchild->More()) {
1419           continue;
1420         }
1421         subchild->InitEx(true);
1422         bool anEmpty = true;
1423         for (; subchild->More() && anEmpty; subchild->Next()) 
1424           if (subchild->Value()->GetAllAttributes()->length() != 0) anEmpty = false;
1425         if (anEmpty) {
1426           continue;
1427         }
1428       }
1429
1430       CORBA::String_var scoid = strdup(SO->GetID());
1431       hdf_group_sobject = new HDFgroup(scoid,hdf_group_datatype);
1432       hdf_group_sobject->CreateOnDisk();
1433       SaveAttributes(SO, hdf_group_sobject);
1434       _SaveObject(aStudy,SO, hdf_group_sobject);
1435       hdf_group_sobject->CloseOnDisk();
1436       hdf_group_sobject =0; // will be deleted by father hdf object destructor
1437
1438     }
1439 }
1440
1441 //============================================================================
1442 /*! Function : _SubstituteSlash
1443  *  Purpose  :
1444  */
1445 //============================================================================
1446
1447 const char *SALOMEDS_StudyManager_i::_SubstituteSlash(const char *aUrl)
1448 {
1449   ASSERT(1==0);
1450   TCollection_ExtendedString theUrl(CORBA::string_dup(aUrl));
1451   Standard_ExtCharacter val1 = ToExtCharacter('/');
1452   Standard_ExtCharacter val2 = ToExtCharacter(':');
1453   theUrl.ChangeAll(val1,val2);
1454   TCollection_AsciiString ch(theUrl);
1455   return strdup(ch.ToCString());
1456 }
1457
1458 //============================================================================
1459 /*! Function : CanCopy
1460  *  Purpose  : 
1461  */
1462 //============================================================================
1463 CORBA::Boolean SALOMEDS_StudyManager_i::CanCopy(SALOMEDS::SObject_ptr theObject) {
1464   SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
1465   if (aComponent->_is_nil()) return false;
1466   if (aComponent == theObject) return false;
1467
1468   CORBA::String_var IOREngine;
1469   if (!aComponent->ComponentIOR(IOREngine)) return false;
1470
1471   CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1472   SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
1473   if (CORBA::is_nil(Engine)) return false;
1474   return Engine->CanCopy(theObject);
1475 }
1476
1477 //============================================================================
1478 /*! Function : GetDocumentOfStudy
1479  *  Purpose  : 
1480  */
1481 //============================================================================
1482 Handle(TDocStd_Document) SALOMEDS_StudyManager_i::GetDocumentOfStudy(SALOMEDS::Study_ptr theStudy) {
1483   int a;
1484   int aNbDocs = _OCAFApp->NbDocuments();
1485   Handle(TDocStd_Document) aDocument;
1486   for(a = 1; a <= aNbDocs ; a++) {
1487     _OCAFApp->GetDocument(a, aDocument);
1488     if (!aDocument.IsNull()) {
1489       SALOMEDS_SObject_i *  aSOServant = new SALOMEDS_SObject_i (aDocument->Main(),_orb);
1490       SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_narrow(aSOServant->_this()); 
1491       if (aSO->GetStudy() == theStudy) break;
1492       aDocument.Nullify();
1493     }
1494   }
1495   return aDocument;
1496 }
1497
1498 //============================================================================
1499 /*! Function : CopyLabel
1500  *  Purpose  : 
1501  */
1502 //============================================================================
1503 void SALOMEDS_StudyManager_i::CopyLabel(const SALOMEDS::Study_ptr theSourceStudy,
1504                                         const SALOMEDS::Driver_ptr theEngine,
1505                                         const Standard_Integer theSourceStartDepth,
1506                                         const TDF_Label& theSource,
1507                                         const TDF_Label& theDestinationMain) {
1508   int a;
1509   TDF_Label aTargetLabel = theDestinationMain;
1510   TDF_Label aAuxTargetLabel = theDestinationMain.Father().FindChild(2);
1511   for(a = theSource.Depth() - theSourceStartDepth; a > 0 ; a--) {
1512     TDF_Label aSourceLabel = theSource;
1513     for(int aNbFather = 1; aNbFather < a; aNbFather++) aSourceLabel = aSourceLabel.Father();
1514     aTargetLabel = aTargetLabel.FindChild(aSourceLabel.Tag());
1515     aAuxTargetLabel = aAuxTargetLabel.FindChild(aSourceLabel.Tag());
1516   }
1517   // iterate attributes
1518   TDF_AttributeIterator anAttrIterator(theSource);
1519   Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable();
1520   for(; anAttrIterator.More(); anAttrIterator.Next()) {
1521     Handle(TDF_Attribute) anAttr = anAttrIterator.Value();
1522     if (!Handle(TDataStd_TreeNode)::DownCast(anAttr).IsNull()) continue; // never copy tree node attribute
1523     if (!Handle(SALOMEDS_TargetAttribute)::DownCast(anAttr).IsNull()) continue; // and target attribute
1524     
1525     if (!Handle(TDF_Reference)::DownCast(anAttr).IsNull()) { // reference copied as Comment in auxiliary tree
1526       TDF_Label aReferenced = Handle(TDF_Reference)::DownCast(anAttr)->Get();
1527       TCollection_AsciiString anEntry;
1528       TDF_Tool::Entry(aReferenced, anEntry);
1529       // store the value of name attribute of referenced label
1530       Handle(TDataStd_Name) aNameAttribute;
1531       if (aReferenced.FindAttribute(TDataStd_Name::GetID(), aNameAttribute)) {
1532         anEntry += " ";
1533         anEntry += aNameAttribute->Get();
1534       }
1535       TDataStd_Comment::Set(aAuxTargetLabel, TCollection_ExtendedString(anEntry));
1536       continue;
1537     }
1538     
1539     if (!Handle(SALOMEDS_IORAttribute)::DownCast(anAttr).IsNull()) { // IOR => ID and TMPFile of Engine
1540       TCollection_AsciiString anEntry;
1541       TDF_Tool::Entry(theSource, anEntry);
1542       SALOMEDS::SObject_var aSO = theSourceStudy->FindObjectID(strdup(anEntry.ToCString()));
1543 //        if (theEngine->CanCopy(aSO)) {
1544         CORBA::Long anObjID;
1545 //      TCollection_ExtendedString aResStr(strdup((char*)(theEngine->CopyFrom(aSO, anObjID))));
1546           SALOMEDS::TMPFile_var aStream = theEngine->CopyFrom(aSO, anObjID);
1547           int aLen = aStream->length();
1548           TCollection_ExtendedString aResStr("");
1549           for(a = 0; a < aLen; a++) {
1550             aResStr += TCollection_ExtendedString(ToExtCharacter((Standard_Character)aStream[a]));
1551           }
1552           TDataStd_Integer::Set(aAuxTargetLabel, anObjID);
1553           TDataStd_Name::Set(aAuxTargetLabel, aResStr);
1554 //        }
1555       continue;
1556     }
1557     Handle(TDF_Attribute) aNewAttribute = anAttr->NewEmpty();
1558     aTargetLabel.AddAttribute(aNewAttribute);
1559     anAttr->Paste(aNewAttribute, aRT);
1560 //      aRT->SetRelocation(anAttr, aNewAttribute);
1561   }
1562 }
1563
1564 //============================================================================
1565 /*! Function : Copy
1566  *  Purpose  :
1567  */
1568 //============================================================================
1569 CORBA::Boolean SALOMEDS_StudyManager_i::Copy(SALOMEDS::SObject_ptr theObject) {
1570   // adoptation for alliances datamodel copy: without IOR attributes !!!
1571   bool aStructureOnly; // copy only SObjects and attributes without component help
1572   SALOMEDS::GenericAttribute_var anAttribute;
1573   aStructureOnly = !theObject->FindAttribute(anAttribute, "AttributeIOR");
1574
1575   // get component-engine
1576   SALOMEDS::Study_var aStudy = theObject->GetStudy();
1577
1578   SALOMEDS::Driver_var Engine;
1579   if (!aStructureOnly) {
1580     SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
1581     CORBA::String_var IOREngine;
1582     if (!aComponent->ComponentIOR(IOREngine)) return false;
1583
1584     CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1585     Engine = SALOMEDS::Driver::_narrow(obj) ;
1586   }
1587   // CAF document of current study usage
1588   Handle(TDocStd_Document) aDocument = GetDocumentOfStudy(aStudy);
1589   if (aDocument.IsNull()) return false;
1590   // create new document for clipboard
1591   Handle(TDocStd_Document) aTargetDocument;
1592   _OCAFApp->NewDocument("SALOME_STUDY", aTargetDocument);
1593   // set component data type to the name attribute of root label
1594   if (!aStructureOnly) {
1595     TDataStd_Comment::Set(aTargetDocument->Main().Root(),
1596                           TCollection_ExtendedString(strdup(Engine->ComponentDataType())));
1597   }
1598   // set to the Root label integer attribute: study id
1599   TDataStd_Integer::Set(aTargetDocument->Main().Root(), aStudy->StudyId());
1600   // iterate all theObject's label children
1601   TDF_Label aStartLabel;
1602   char* aStartID = strdup(theObject->GetID());
1603   TDF_Tool::Label(aDocument->GetData(), aStartID, aStartLabel);
1604   Standard_Integer aSourceStartDepth = aStartLabel.Depth();
1605   
1606   // copy main source label
1607   CopyLabel(aStudy, Engine, aSourceStartDepth, aStartLabel, aTargetDocument->Main());
1608
1609   // copy all subchildren of the main source label (all levels)
1610   TDF_ChildIterator anIterator(aStartLabel, Standard_True);
1611   for(; anIterator.More(); anIterator.Next()) {
1612     CopyLabel(aStudy, Engine, aSourceStartDepth, anIterator.Value(), aTargetDocument->Main());
1613   }
1614   // done: free old clipboard document and 
1615   if (!_clipboard.IsNull()) {
1616 //      Handle(TDocStd_Owner) anOwner;
1617 //      if (_clipboard->Main().Root().FindAttribute(TDocStd_Owner::GetID(), anOwner)) {
1618 //        Handle(TDocStd_Document) anEmptyDoc;
1619 //        anOwner->SetDocument(anEmptyDoc);
1620 //      }
1621     _OCAFApp->Close(_clipboard);
1622   }
1623   _clipboard = aTargetDocument;
1624
1625   return true;
1626 }
1627 //============================================================================
1628 /*! Function : CanPaste
1629  *  Purpose  :
1630  */
1631 //============================================================================
1632 CORBA::Boolean SALOMEDS_StudyManager_i::CanPaste(SALOMEDS::SObject_ptr theObject) {
1633   if (_clipboard.IsNull()) return false;
1634
1635   Handle(TDataStd_Comment) aCompName;
1636   if (!_clipboard->Main().Root().FindAttribute(TDataStd_Comment::GetID(), aCompName)) return false;
1637   Handle(TDataStd_Integer) anObjID;
1638   if (!_clipboard->Main().Father().FindChild(2).FindAttribute(TDataStd_Integer::GetID(), anObjID))
1639     return false;
1640
1641   SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
1642   if (aComponent->_is_nil()) return false;
1643   
1644   CORBA::String_var IOREngine;
1645   if (!aComponent->ComponentIOR(IOREngine)) return false;
1646   
1647   CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1648   SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
1649   if (CORBA::is_nil(Engine)) return false;
1650   return Engine->CanPaste(strdup(TCollection_AsciiString(aCompName->Get()).ToCString()), anObjID->Get());
1651 }
1652 //============================================================================
1653 /*! Function : PasteLabel
1654  *  Purpose  :
1655  */
1656 //============================================================================
1657 TDF_Label SALOMEDS_StudyManager_i::PasteLabel(const SALOMEDS::Study_ptr theDestinationStudy,
1658                                               const SALOMEDS::Driver_ptr theEngine,
1659                                               const TDF_Label& theSource,
1660                                               const TDF_Label& theDestinationStart,
1661                                               const int theCopiedStudyID,
1662                                               const bool isFirstElement) {
1663   // get corresponding source, target and auxiliary labels
1664   TDF_Label aTargetLabel = theDestinationStart;
1665   TDF_Label aAuxSourceLabel = theSource.Root().FindChild(2);
1666   int a;
1667   if (!isFirstElement) {
1668     for(a = theSource.Depth() - 1; a > 0 ; a--) {
1669       TDF_Label aSourceLabel = theSource;
1670       for(int aNbFather = 1; aNbFather < a; aNbFather++) aSourceLabel = aSourceLabel.Father();
1671       aTargetLabel = aTargetLabel.FindChild(aSourceLabel.Tag());
1672       aAuxSourceLabel = aAuxSourceLabel.FindChild(aSourceLabel.Tag());
1673     }
1674   }
1675
1676   // check auxiliary label for TMPFile => IOR
1677   Handle(TDataStd_Name) aNameAttribute;
1678   if (aAuxSourceLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttribute)) {
1679     Handle(TDataStd_Integer) anObjID;
1680
1681     aAuxSourceLabel.FindAttribute(TDataStd_Integer::GetID(), anObjID);
1682     Handle(TDataStd_Comment) aComponentName;
1683     theSource.Root().FindAttribute(TDataStd_Comment::GetID(), aComponentName);
1684     CORBA::String_var aCompName = strdup(TCollection_AsciiString(aComponentName->Get()).ToCString());
1685
1686     if (theEngine->CanPaste(aCompName, anObjID->Get())) {
1687       SALOMEDS::TMPFile_var aTMPFil = new SALOMEDS::TMPFile();
1688       TCollection_ExtendedString aTMPStr = aNameAttribute->Get();
1689       int aLen = aTMPStr.Length();
1690       aTMPFil->length(aLen);
1691       for(a = 0; a < aLen; a++) {
1692         aTMPFil[a] = ToCharacter(aTMPStr.Value(a+1));
1693       }
1694 //        char* aTMPStr = strdup(TCollection_AsciiString(aNameAttribute->Get()).ToCString());
1695 //        int aLen = strlen(aTMPStr);
1696 //        SALOMEDS::TMPFile aTMPFil(aLen, aLen, (CORBA::Octet*)aTMPStr, 1);
1697       
1698       TCollection_AsciiString anEntry;
1699       TDF_Tool::Entry(aTargetLabel, anEntry);
1700       SALOMEDS::SObject_var aPastedSO = theDestinationStudy->FindObjectID(strdup(anEntry.ToCString()));
1701       if (isFirstElement) {
1702         SALOMEDS::SObject_var aDestSO =
1703           theEngine->PasteInto(aTMPFil.in(),
1704                                anObjID->Get(),
1705                                aPastedSO->GetFatherComponent());
1706         TDF_Tool::Label(theDestinationStart.Data(), aDestSO->GetID(), aTargetLabel);
1707       } else theEngine->PasteInto(aTMPFil.in(),anObjID->Get(),aPastedSO);
1708     }
1709   }
1710
1711   // iterate attributes
1712   TDF_AttributeIterator anAttrIterator(theSource);
1713   Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable();
1714   for(; anAttrIterator.More(); anAttrIterator.Next()) {
1715     Handle(TDF_Attribute) anAttr = anAttrIterator.Value();
1716     if (aTargetLabel.FindAttribute(anAttr->ID(), anAttr)) {
1717       aTargetLabel.ForgetAttribute(anAttr->ID());
1718       anAttr = anAttrIterator.Value();
1719     }
1720     Handle(TDF_Attribute) aNewAttribute = anAttr->NewEmpty();
1721     aTargetLabel.AddAttribute(aNewAttribute);
1722     anAttr->Paste(aNewAttribute, aRT);
1723 //      aRT->SetRelocation(anAttr, aNewAttribute);
1724   }
1725   // check auxiliary label for Comment => reference or name attribute of the referenced object
1726   Handle(TDataStd_Comment) aCommentAttribute;
1727   if (aAuxSourceLabel.FindAttribute(TDataStd_Comment::GetID(), aCommentAttribute)) {
1728     char * anEntry = new char[aCommentAttribute->Get().Length()];
1729     strcpy(anEntry, TCollection_AsciiString(aCommentAttribute->Get()).ToCString());
1730     char* aNameStart = strchr(anEntry, ' ');
1731     if (aNameStart) {
1732       *aNameStart = '\0';
1733       aNameStart++;
1734     }
1735     if (theCopiedStudyID == theDestinationStudy->StudyId()) { // if copy to the same study, reanimate reference
1736       TDF_Label aRefLabel;
1737       TDF_Tool::Label(aTargetLabel.Data(), anEntry, aRefLabel);
1738       TDF_Reference::Set(aTargetLabel, aRefLabel);
1739       SALOMEDS_TargetAttribute::Set(aRefLabel)->Append(aTargetLabel); // target attributes structure support
1740     } else {
1741       if (aNameStart) TDataStd_Name::Set(aTargetLabel, aNameStart);
1742       else TDataStd_Name::Set(aTargetLabel, TCollection_ExtendedString("Reference to:")+anEntry);
1743     }
1744     delete(anEntry);
1745   }
1746   return aTargetLabel;
1747 }
1748 //============================================================================
1749 /*! Function : Paste
1750  *  Purpose  :
1751  */
1752 //============================================================================
1753 SALOMEDS::SObject_ptr SALOMEDS_StudyManager_i::Paste(SALOMEDS::SObject_ptr theObject)
1754      throw(SALOMEDS::StudyBuilder::LockProtection)
1755 {
1756   SALOMEDS::Study_var aStudy = theObject->GetStudy();
1757   // if study is locked, then paste can't be done
1758   if (aStudy->GetProperties()->IsLocked())
1759     throw SALOMEDS::StudyBuilder::LockProtection();
1760   // if there is no component name, then paste only SObjects and attributes: without component help
1761   Handle(TDataStd_Comment) aComponentName;
1762   bool aStructureOnly = !_clipboard->Main().Root().FindAttribute(TDataStd_Comment::GetID(), aComponentName);
1763
1764   // get copied study ID
1765   Handle(TDataStd_Integer) aStudyIDAttribute;
1766   if (!_clipboard->Main().Root().FindAttribute(TDataStd_Integer::GetID(), aStudyIDAttribute)) return NULL;
1767   int aCStudyID = aStudyIDAttribute->Get();
1768
1769   // get component-engine
1770
1771   SALOMEDS::Driver_var Engine;
1772   SALOMEDS::SComponent_var aComponent;
1773   if (!aStructureOnly) {
1774     aComponent = theObject->GetFatherComponent();
1775     CORBA::String_var IOREngine;
1776     if (!aComponent->ComponentIOR(IOREngine)) return NULL;
1777     CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1778     Engine = SALOMEDS::Driver::_narrow(obj) ;
1779   }
1780   // CAF document of current study usage
1781   Handle(TDocStd_Document) aDocument = GetDocumentOfStudy(aStudy);
1782   if (aDocument.IsNull()) return NULL; 
1783   // fill root inserted SObject
1784   TDF_Label aStartLabel;
1785   if (aStructureOnly) {
1786     TDF_Label anObjectLabel;
1787     TDF_Tool::Label(aDocument->GetData(), theObject->GetID(), anObjectLabel);
1788     aStartLabel = PasteLabel(aStudy, Engine, _clipboard->Main(), anObjectLabel, aCStudyID, false);
1789   } else {
1790     TDF_Label aComponentLabel;
1791     TDF_Tool::Label(aDocument->GetData(), aComponent->GetID(), aComponentLabel);
1792     aStartLabel = PasteLabel(aStudy, Engine, _clipboard->Main(), aComponentLabel, aCStudyID, true);
1793   }
1794   // paste all sublebels
1795   TDF_ChildIterator anIterator(_clipboard->Main(), Standard_True);
1796   for(; anIterator.More(); anIterator.Next()) {
1797     PasteLabel(aStudy, Engine, anIterator.Value(), aStartLabel, aCStudyID, false);
1798   }
1799
1800   SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (aStartLabel, _orb);
1801   SALOMEDS::SObject_var so = SALOMEDS::SObject::_narrow(so_servant->_this()); 
1802   return so;
1803 }