1 // SALOME SALOMEDS : data structure of SALOME and sources of Salome data server
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SALOMEDS_StudyManager_i.cxx
25 // Author : Yves FRICAUD
29 #include "utilities.h"
30 #include "SALOME_LifeCycleCORBA.hxx"
31 #include "SALOMEDS_StudyManager_i.hxx"
32 #include "SALOMEDS_Study_i.hxx"
33 #include "SALOMEDS_SComponent_i.hxx"
35 #include "SALOMEDS_IORAttribute.hxx"
36 #include "SALOMEDS_PersRefAttribute.hxx"
37 #include "SALOMEDS_Tool.hxx"
39 #include <TDF_Label.hxx>
40 #include <TDataStd_Name.hxx>
41 #include <TDataStd_Comment.hxx>
42 #include <TDataStd_TreeNode.hxx>
43 #include <TDataStd_UAttribute.hxx>
44 #include <TDF_Tool.hxx>
45 #include <TDF_Reference.hxx>
46 #include <TDF_Data.hxx>
47 #include <TDF_RelocationTable.hxx>
48 #include <TDF_AttributeIterator.hxx>
49 // #include <TDocStd_Owner.hxx>
50 #include <TColStd_HArray1OfCharacter.hxx>
51 #include <TCollection_ExtendedString.hxx>
52 #include "HDFexplorer.hxx"
53 #include "SALOMEDS_SequenceOfRealAttribute.hxx"
54 #include "SALOMEDS_SequenceOfIntegerAttribute.hxx"
55 #include <TColStd_HSequenceOfReal.hxx>
56 #include <TColStd_HSequenceOfInteger.hxx>
57 #include "SALOMEDS_PixMapAttribute.hxx"
58 #include "SALOMEDS_DrawableAttribute.hxx"
59 #include "SALOMEDS_SelectableAttribute.hxx"
60 #include "SALOMEDS_ExpandableAttribute.hxx"
61 #include "SALOMEDS_OpenedAttribute.hxx"
62 #include "SALOMEDS_TextColorAttribute.hxx"
63 #include "SALOMEDS_TextHighlightColorAttribute.hxx"
64 #include "SALOMEDS_LocalIDAttribute.hxx"
65 #include "SALOMEDS_TargetAttribute.hxx"
66 #include "SALOMEDS_TableOfIntegerAttribute.hxx"
67 #include "SALOMEDS_TableOfRealAttribute.hxx"
68 #include "SALOMEDS_TableOfStringAttribute.hxx"
69 #include "SALOMEDS_StudyPropertiesAttribute.hxx"
70 #include "SALOMEDS_PythonObjectAttribute.hxx"
71 #include <OSD_Process.hxx>
72 #include <Quantity_Date.hxx>
74 #include "Utils_CorbaException.hxx"
79 #include "SALOME_GenericObj_i.hh"
81 #include "Utils_ExceptHandlers.hxx"
83 UNEXPECT_CATCH(SalomeException,SALOME::SALOME_Exception);
84 UNEXPECT_CATCH(LockProtection, SALOMEDS::StudyBuilder::LockProtection);
86 #define USE_CASE_LABEL_ID "0:2"
87 #define AUTO_SAVE_GUID "128268A3-71C9-4036-89B1-F81BD6A4FCF2"
88 #define AUTO_SAVE_TAG "0:8"
89 #define AUTO_SAVE_TIME_OUT_IN_SECONDS 1200
90 //===========================================================================
91 //Function : LoadAttributes
92 //===========================================================================
93 static void ReadAttributes(SALOMEDS::Study_ptr theStudy,
94 SALOMEDS::SObject_ptr aSO,
95 HDFdataset* hdf_dataset)
97 hdf_dataset->OpenOnDisk();
99 SALOMEDS::GenericAttribute_var anAttr;
101 char* current_string = new char[hdf_dataset->GetSize()];
102 hdf_dataset->ReadFromDisk(current_string);
104 if (!strcmp(hdf_dataset->GetName(),"COMPONENTDATATYPE")) {
105 anAttr = theStudy->NewBuilder()->FindOrCreateAttribute(aSO, "AttributeComment");
106 } else if (!strcmp(hdf_dataset->GetName(),"Reference")) {
107 theStudy->NewBuilder()->Addreference(aSO, theStudy->CreateObjectID(current_string));
108 delete(current_string);
109 hdf_dataset->CloseOnDisk();
112 MESSAGE("Read attribute "<<hdf_dataset->GetName())
113 anAttr = theStudy->NewBuilder()->FindOrCreateAttribute(aSO, hdf_dataset->GetName());
116 if (!CORBA::is_nil(anAttr)) {
117 anAttr->Restore(current_string);
118 MESSAGE("Restoring attribute "<<hdf_dataset->GetName()<<" by string '"<<current_string<<"' done")
120 MESSAGE(hdf_dataset->GetName());
121 MESSAGE("LoadAttributes: unknown types");
123 delete(current_string);
124 hdf_dataset->CloseOnDisk();
127 //============================================================================
128 //Function : Translate_IOR_to_persistentID
129 //============================================================================
130 static void Translate_IOR_to_persistentID (SALOMEDS::Study_ptr study,
131 SALOMEDS::StudyBuilder_ptr SB,
132 SALOMEDS::SObject_ptr so,
133 SALOMEDS::Driver_ptr engine,
134 CORBA::Boolean isMultiFile,
135 CORBA::Boolean isASCII)
137 MESSAGE("In Translate_IOR_to_persistentID");
138 SALOMEDS::ChildIterator_var itchild = study->NewChildIterator(so);
139 CORBA::String_var ior_string;
140 char* persistent_string = 0;
143 for (; itchild->More(); itchild->Next()) {
144 SALOMEDS::SObject_var current = itchild->Value();
145 SCRUTE(current->GetID());
146 SALOMEDS::GenericAttribute_var SObj;
147 if (current->FindAttribute(SObj, "AttributeIOR")) {
148 SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(SObj);
149 ior_string = IOR->Value();
152 persistent_string = engine->IORToLocalPersistentID (current,ior_string,isMultiFile, isASCII);
154 // SB->AddAttribute (current, SALOMEDS::PersistentRef,persistent_string);
155 SALOMEDS::AttributePersistentRef_var Pers = SALOMEDS::AttributePersistentRef::_narrow(SB->FindOrCreateAttribute (current, "AttributePersistentRef"));
156 Pers->SetValue(persistent_string);
157 SCRUTE(persistent_string);
158 curid = current->GetID();
159 MESSAGE("Translate " << curid <<
160 " to Persistent string "<<persistent_string);
161 persistent_string = 0;
164 Translate_IOR_to_persistentID (study,SB,current,engine,isMultiFile, isASCII);
166 CORBA::string_free(persistent_string);
167 CORBA::string_free(curid);
170 //============================================================================
171 //Function : BuildlTree
172 //============================================================================
173 static void BuildTree (SALOMEDS::Study_ptr theStudy,HDFgroup* hdf_current_group)
175 hdf_current_group->OpenOnDisk();
177 SALOMEDS::SObject_var aSO;
178 char* Entry = hdf_current_group->GetName();
179 if (strcmp(Entry,"STUDY_STRUCTURE") == 0) {
180 MESSAGE("find the root of the document");
181 aSO = theStudy->CreateObjectID("0:1");
184 aSO = theStudy->CreateObjectID(Entry);
185 MESSAGE("BuildTree : Create a new label"<<Entry);
187 char name[HDF_NAME_MAX_LEN+1];
188 Standard_Integer nbsons = hdf_current_group->nInternalObjects();
190 for (Standard_Integer i=0; i<nbsons; i++) {
191 hdf_current_group->InternalObjectIndentify(i,name);
192 if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
193 hdf_object_type type = hdf_current_group->InternalObjectType(name);
195 if (type == HDF_DATASET) {
196 MESSAGE("--> Dataset: Internal Object Name : " << name);
197 HDFdataset* new_dataset = new HDFdataset(name,hdf_current_group);
198 ReadAttributes(theStudy,aSO,new_dataset);
199 new_dataset = 0; // will be deleted by father destructor
202 else if (type == HDF_GROUP) {
203 MESSAGE( "--> Group: Internal Object Name : " << name);
204 HDFgroup* new_group = new HDFgroup(name,hdf_current_group);
205 BuildTree (theStudy, new_group);
206 new_group = 0; // will be deleted by father destructor
209 hdf_current_group->CloseOnDisk();
213 //============================================================================
214 /*! Function : SALOMEDS_StudyManager_i
215 * Purpose : SALOMEDS_StudyManager_i constructor
217 //============================================================================
218 SALOMEDS_StudyManager_i::SALOMEDS_StudyManager_i(CORBA::ORB_ptr orb)
220 _orb = CORBA::ORB::_duplicate(orb);
221 _OCAFApp = new SALOMEDS_OCAFApplication();
222 _name_service = new SALOME_NamingService(_orb);
223 // Study directory creation in the naming service : to register all
224 // open studies in the session
225 _name_service->Create_Directory("/Study");
229 //============================================================================
230 /*! Function : ~SALOMEDS_StudyManager_i
231 * Purpose : SALOMEDS_StudyManager_i destructor
233 //============================================================================
234 SALOMEDS_StudyManager_i::~SALOMEDS_StudyManager_i()
236 // Destroy directory to register open studies
237 _name_service->Destroy_Directory("/Study");
238 // Destroy OCAF document
242 //============================================================================
243 /*! Function : register_name
244 * Purpose : Register the study Manager in the naming service under the
247 //============================================================================
248 void SALOMEDS_StudyManager_i::register_name(char * name) {
249 SALOMEDS::StudyManager_ptr g = SALOMEDS::StudyManager::_narrow(_this());
250 _name_service->Register(g, name);
254 //============================================================================
255 /*! Function : NewStudy
256 * Purpose : Create a New Study of name study_name
258 //============================================================================
259 SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::NewStudy(const char* study_name)
261 Handle(TDocStd_Document) Doc;
262 _OCAFApp->NewDocument("SALOME_STUDY",Doc);
264 MESSAGE("NewStudy : Creating the CORBA servant holding it... ");
265 SALOMEDS_Study_i *Study_servant = new SALOMEDS_Study_i(Doc,_orb,study_name);
266 SALOMEDS::Study_var Study = SALOMEDS::Study::_narrow(Study_servant->_this());
268 //Study->StudyId( _OCAFApp->NbDocuments() );
270 Study->StudyId( _IDcounter );
272 // Register study in the naming service
273 // Path to acces the study
274 if(!_name_service->Change_Directory("/Study"))
275 MESSAGE( "Unable to access the study directory" )
277 _name_service->Register(Study, study_name);
279 // Assign the value of the IOR in the study->root
280 const char* IORStudy = _orb->object_to_string(Study);
281 SALOMEDS_IORAttribute::Set(Doc->Main().Root(),TCollection_ExtendedString(strdup(IORStudy)),_orb);
283 // set Study properties
284 SALOMEDS::AttributeStudyProperties_ptr aProp = Study->GetProperties();
285 OSD_Process aProcess;
286 Quantity_Date aDate = aProcess.SystemDate();
287 aProp->SetCreationDate(CORBA::Long(aDate.Minute()), CORBA::Long(aDate.Hour()), CORBA::Long(aDate.Day()),
288 CORBA::Long(aDate.Month()), CORBA::Long(aDate.Year()));
289 aProp->SetCreationMode("from scratch");
290 aProp->SetUserName(aProcess.UserName().ToCString());
295 //============================================================================
297 * Purpose : Open a Study from it's persistent reference
299 //============================================================================
300 SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::Open(const char* aUrl)
301 throw(SALOME::SALOME_Exception)
303 Unexpect aCatch(SalomeException);
304 MESSAGE("Begin of SALOMEDS_StudyManager_i::Open");
306 HDFfile *hdf_file =0;
307 HDFgroup *hdf_group_study_structure =0;
310 bool isASCII = false;
311 if (HDFascii::isASCII(aUrl)) {
313 char* aResultPath = HDFascii::ConvertFromASCIIToHDF(aUrl);
314 aHDFUrl = new char[strlen(aResultPath) + 19];
315 sprintf(aHDFUrl, "%shdf_from_ascii.hdf", aResultPath);
318 aHDFUrl = strdup(aUrl);
321 hdf_file = new HDFfile(aHDFUrl);
323 hdf_file->OpenOnDisk(HDF_RDONLY);// mpv: was RDWR, but opened file can be write-protected too
327 // MESSAGE( "HDFexception ! " );
328 // cerr << "HDFexception ! " << endl;
330 char eStr[strlen(aUrl)+17];
331 sprintf(eStr,"Can't open file %s",aUrl);
332 THROW_SALOME_CORBA_EXCEPTION(CORBA::string_dup(eStr),SALOME::BAD_PARAM);
335 MESSAGE("Open : Creating the CORBA servant holding it... ");
337 // Temporary aStudyUrl in place of study name
338 Handle(TDocStd_Document) Doc;
339 _OCAFApp->NewDocument("SALOME_STUDY",Doc);
341 SALOMEDS_Study_i * Study_servant = new SALOMEDS_Study_i(Doc, _orb, aUrl);
342 SALOMEDS::Study_var Study = SALOMEDS::Study::_narrow(Study_servant->_this());
344 // Study->StudyId( _OCAFApp->NbDocuments() );
346 Study->StudyId( _IDcounter );
348 // Assign the value of the URL in the study object
352 // Assign the value of the IOR in the study->root
353 CORBA::String_var IORStudy = _orb->object_to_string(Study);
354 SALOMEDS_IORAttribute::Set(Doc->Main().Root(),
355 TCollection_ExtendedString(CORBA::string_dup(IORStudy)),_orb);
357 SALOMEDS_PersRefAttribute::Set(Doc->Main(),strdup(aUrl));
359 if (!hdf_file->ExistInternalObject("STUDY_STRUCTURE")) {
361 MESSAGE("SALOMEDS_StudyManager::Open : the study is empty");
365 //Create the Structure of the OCAF Document
366 hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file);
368 Handle(TDF_Data) DF = Doc->GetData();
371 BuildTree (Study,hdf_group_study_structure);
375 // MESSAGE( "HDFexception ! " );
376 // cerr << "HDFexception ! " << endl;
378 char eStr[strlen(aUrl)+17];
379 sprintf(eStr,"Can't open file %s",aUrl);
380 THROW_SALOME_CORBA_EXCEPTION(CORBA::string_dup(eStr),SALOME::BAD_PARAM);
383 hdf_file->CloseOnDisk();
385 // Register study in the naming service
386 // Path to acces the study
387 if(!_name_service->Change_Directory("/Study")) MESSAGE( "Unable to access the study directory" )
388 else _name_service->Register(Study, CORBA::string_dup(Study->Name()));
392 SALOMEDS::ListOfFileNames_var aFilesToRemove = new SALOMEDS::ListOfFileNames;
393 aFilesToRemove->length(1);
394 aFilesToRemove[0] = strdup(&(aHDFUrl[strlen(SALOMEDS_Tool::GetDirFromPath(aHDFUrl))]));
395 SALOMEDS_Tool::RemoveTemporaryFiles(SALOMEDS_Tool::GetDirFromPath(aHDFUrl), aFilesToRemove, true);
398 delete hdf_file; // all related hdf objects will be deleted
404 //============================================================================
406 * Purpose : Close a study.
407 * If the study hasn't been saved, ask the user to confirm the
408 * close action without saving
410 //============================================================================
411 void SALOMEDS_StudyManager_i::Close(SALOMEDS::Study_ptr aStudy)
413 if(aStudy->_is_nil()) return;
415 aStudy->RemovePostponed(-1);
417 // Destroy study name in the naming service
418 if(_name_service->Change_Directory("/Study"))
419 _name_service->Destroy_Name(aStudy->Name());
424 //============================================================================
426 * Purpose : Save a Study to it's persistent reference
428 //============================================================================
429 void SALOMEDS_StudyManager_i::Save(SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
431 CORBA::String_var url = aStudy->URL();
433 MESSAGE( "No path specified to save the study. Nothing done")
436 _SaveAs(url,aStudy, theMultiFile, false);
440 void SALOMEDS_StudyManager_i::SaveASCII(SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
442 CORBA::String_var url = aStudy->URL();
444 MESSAGE( "No path specified to save the study. Nothing done")
447 _SaveAs(url,aStudy, theMultiFile, true);
451 //=============================================================================
452 /*! Function : SaveAs
453 * Purpose : Save a study to the persistent reference aUrl
455 //============================================================================
456 void SALOMEDS_StudyManager_i::SaveAs(const char* aUrl, SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
458 _SaveAs(aUrl,aStudy,theMultiFile, false);
462 void SALOMEDS_StudyManager_i::SaveAsASCII(const char* aUrl, SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
464 _SaveAs(aUrl,aStudy,theMultiFile, true);
467 //============================================================================
468 /*! Function : GetOpenStudies
469 * Purpose : Get name list of open studies in the session
471 //============================================================================
472 SALOMEDS::ListOfOpenStudies* SALOMEDS_StudyManager_i::GetOpenStudies()
474 // MESSAGE("Begin of GetOpenStudies");
475 SALOMEDS::ListOfOpenStudies_var _list_open_studies = new SALOMEDS::ListOfOpenStudies;
476 _list_open_studies->length(0);
477 vector<string> _list ;
479 if(!_name_service->Change_Directory("/Study"))
481 MESSAGE("No active study in this session");
485 _list = _name_service->list_directory();
486 _list_open_studies->length(_list.size());
487 for (unsigned int ind=0; ind < _list.size();ind++)
489 _list_open_studies[ind]=CORBA::string_dup(_list[ind].c_str());
490 SCRUTE(_list_open_studies[ind]) ;
493 return _list_open_studies._retn();
496 //============================================================================
497 /*! Function : GetStudyByName
498 * Purpose : Get a study from its name
500 //============================================================================
502 SALOMEDS_StudyManager_i::GetStudyByName(const char* aStudyName)
504 SALOMEDS::Study_var Study;
506 // Go to study directory and look for aStudyName
507 if(!_name_service->Change_Directory("/Study"))
509 MESSAGE("No active study in this session");
510 ASSERT(false); // Stop here...
513 // const char *theStudyName = this->_SubstituteSlash(aStudyName);
514 const char* theStudyName = CORBA::string_dup(aStudyName);
516 if(_name_service->Find(theStudyName)>0)
519 CORBA::Object_ptr obj= _name_service->Resolve(theStudyName) ;
520 Study = SALOMEDS::Study::_narrow(obj);
521 MESSAGE("Study " << theStudyName << " found in the naming service");
525 Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil());
526 MESSAGE("Study " << theStudyName << " not found in the naming service");
531 //============================================================================
532 /*! Function : GetStudyByID
533 * Purpose : Get a study from its ID
535 //============================================================================
537 SALOMEDS_StudyManager_i::GetStudyByID(CORBA::Short aStudyID)
539 SALOMEDS::Study_var Study;
540 vector<string> _list ;
542 if(!_name_service->Change_Directory("/Study"))
544 MESSAGE("No active study in this session");
548 _list = _name_service->list_directory();
549 for (unsigned int ind=0; ind < _list.size();ind++)
551 const char* theStudyName = CORBA::string_dup(_list[ind].c_str());
552 MESSAGE ( "GetStudyByID = " << theStudyName )
554 if(_name_service->Find(theStudyName)>0) {
555 CORBA::Object_ptr obj= _name_service->Resolve(theStudyName) ;
556 Study = SALOMEDS::Study::_narrow(obj);
558 MESSAGE ( " aStudyID : " << aStudyID << "-" << Study->StudyId() )
560 if ( aStudyID == Study->StudyId() ) {
561 MESSAGE("Study with studyID = " << aStudyID << " found in the naming service");
565 Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil());
566 MESSAGE("Study " << theStudyName << " not found in the naming service");
569 Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil());
573 //============================================================================
574 /*! Function : SaveAttributes
575 * Purpose : Save attributes for object
577 //============================================================================
578 static void SaveAttributes(SALOMEDS::SObject_ptr SO, HDFgroup *hdf_group_sobject) {
581 SALOMEDS::ListOfAttributes_var anAttrList = SO->GetAllAttributes();
582 for(a = anAttrList->length() - 1; a >= 0; a--) {
583 if (strcmp(anAttrList[a]->Type(), "AttributeIOR") == 0) continue; // never write AttributeIOR to file
584 if (strcmp(anAttrList[a]->Type(), "AttributeExternalFileDef") == 0) continue; // never write ExternalFileDef to file
585 if (strcmp(anAttrList[a]->Type(), "AttributeFileType") == 0) continue; // never write FileType to file
586 CORBA::String_var aSaveStr = strdup(anAttrList[a]->Store());
587 size[0] = (hdf_int32) strlen(aSaveStr) + 1;
588 HDFdataset *hdf_dataset = new HDFdataset(anAttrList[a]->Type(),hdf_group_sobject,HDF_STRING,size,1);
589 hdf_dataset->CreateOnDisk();
590 hdf_dataset->WriteOnDisk(aSaveStr);
591 hdf_dataset->CloseOnDisk();
592 //cout<<"********** Write Attribute "<<anAttrList[a]->Type()<<" : "<<aSaveStr<<" done"<<endl;
593 hdf_dataset=0; //will be deleted by hdf_sco_group destructor
596 // Reference attribute has no CORBA attribute representation, so, GetAllAttributes can not return this attribute
597 SALOMEDS::SObject_var RefSO;
598 if(SO->ReferencedObject(RefSO)) {
599 CORBA::String_var attribute_reference = strdup(RefSO->GetID());
600 size[0] = strlen(attribute_reference) + 1 ;
601 HDFdataset *hdf_dataset = new HDFdataset("Reference",hdf_group_sobject,HDF_STRING,size,1);
602 hdf_dataset->CreateOnDisk();
603 hdf_dataset->WriteOnDisk(attribute_reference);
604 hdf_dataset->CloseOnDisk();
605 hdf_dataset =0; // will be deleted by father hdf object destructor
609 //=============================================================================
610 /*! Function : _SaveProperties
611 * Purpose : save the study properties in HDF file
613 //============================================================================
614 void SALOMEDS_StudyManager_i::_SaveProperties(SALOMEDS::Study_ptr aStudy, HDFgroup *hdf_group) {
615 HDFdataset *hdf_dataset = 0;
619 // add modifications list (user and date of save)
620 SALOMEDS::AttributeStudyProperties_ptr aProp = aStudy->GetProperties();
621 SALOMEDS::StudyBuilder_var SB= aStudy->NewBuilder();
623 int aLocked = aProp->IsLocked();
624 if (aLocked) aProp->SetLocked(Standard_False);
625 OSD_Process aProcess;
626 Quantity_Date aDate = aProcess.SystemDate();
627 aProp->SetModification(aProcess.UserName().ToCString(),
628 CORBA::Long(aDate.Minute()), CORBA::Long(aDate.Hour()), CORBA::Long(aDate.Day()),
629 CORBA::Long(aDate.Month()), CORBA::Long(aDate.Year()));
630 if (aLocked) aProp->SetLocked(Standard_True);
631 // SB->CommitCommand();
634 SALOMEDS::StringSeq_var aNames;
635 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
636 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, true);
637 int aLength, anIndex;
638 for(aLength = 0, anIndex = aNames->length() - 1; anIndex >= 0; anIndex--) aLength += strlen(aNames[anIndex]) + 1;
640 // string length: 1 byte = locked flag, 1 byte = modified flag, (12 + name length + 1) for each name and date, "zero" byte
641 char* aProperty = new char[3 + aLength + 12 * aNames->length()];
643 sprintf(aProperty,"%c%c",
644 (strlen(aProp->GetCreationMode()) != 0)?aProp->GetCreationMode()[0]:'0',
645 (aProp->IsLocked())?'l':'u');
647 aLength = aNames->length();
649 for(anIndex = 0; anIndex < aLength; anIndex++) {
650 sprintf(&(aProperty[a]),"%2d%2d%2d%2d%4d%s",
651 (int)(aMinutes[anIndex]),
652 (int)(aHours[anIndex]),
653 (int)(aDays[anIndex]),
654 (int)(aMonths[anIndex]),
655 (int)(aYears[anIndex]),
656 (char*)aNames[anIndex]);
657 a = strlen(aProperty);
662 name_len = (hdf_int32) a;
663 // MESSAGE("*** Property: "<<aProperty);
664 size[0] = name_len + 1 ;
665 hdf_dataset = new HDFdataset("AttributeStudyProperties",hdf_group,HDF_STRING,size,1);
666 hdf_dataset->CreateOnDisk();
667 hdf_dataset->WriteOnDisk(aProperty);
668 MESSAGE("attribute StudyProperties " << aProperty << " wrote on file");
669 hdf_dataset->CloseOnDisk();
670 hdf_dataset=0; //will be deleted by hdf_sco_group destructor
672 aProp->SetModified(0);
675 //=============================================================================
676 /*! Function : _SaveAs
677 * Purpose : save the study in HDF file
679 //============================================================================
680 void SALOMEDS_StudyManager_i::_SaveAs(const char* aUrl,
681 SALOMEDS::Study_ptr aStudy,
682 CORBA::Boolean theMultiFile,
683 CORBA::Boolean theASCII)
685 // HDF File will be composed of differents part :
686 // * For each ComponentDataType, all data created by the component
687 // Informations in data group hdf_group_datacomponent
688 // * Study Structure -> Exactly what is contained in OCAF document
689 // Informations in data group hdf_group_study_structure
692 HDFgroup *hdf_group_study_structure =0;
693 HDFgroup *hdf_sco_group =0;
694 HDFgroup *hdf_sco_group2 =0;
696 HDFgroup *hdf_group_datacomponent =0;
697 HDFdataset *hdf_dataset =0;
698 HDFattribute *hdf_attribute=0;
700 hdf_int32 name_len = 0;
701 char *component_name = 0;
702 char *attribute_name = 0;
703 char *attribute_comment = 0;
704 char *attribute_persistentref = 0;
706 int aLocked = aStudy->GetProperties()->IsLocked();
707 if (aLocked) aStudy->GetProperties()->SetLocked(false);
709 SALOMEDS::StudyBuilder_var SB= aStudy->NewBuilder();
711 ASSERT(!CORBA::is_nil(aStudy));
714 // mpv 15.12.2003: for saving components we have to load all data from all modules
716 SALOMEDS::SComponentIterator_var itcomponent1 = aStudy->NewComponentIterator();
717 for (; itcomponent1->More(); itcomponent1->Next())
719 SALOMEDS::SComponent_var sco = itcomponent1->Value();
720 // if there is an associated Engine call its method for saving
721 CORBA::String_var IOREngine;
724 if (!sco->ComponentIOR(IOREngine)) {
725 SALOMEDS::GenericAttribute_var aGeneric;
726 SALOMEDS::AttributeName_var aName;
727 if(sco->FindAttribute(aGeneric, "AttributeName"))
728 aName = SALOMEDS::AttributeName::_narrow(aGeneric);
730 if (!aName->_is_nil()) {
732 CORBA::String_var aCompType = aName->Value();
735 CORBA::String_var aFactoryType;
736 if (strcmp(aCompType, "SUPERV") == 0) aFactoryType = "SuperVisionContainer";
737 else aFactoryType = "FactoryServer";
739 Engines::Component_var aComp =
740 SALOME_LifeCycleCORBA(_name_service).FindOrLoad_Component(aFactoryType, aCompType);
742 if (aComp->_is_nil()) {
743 Engines::Component_var aComp =
744 SALOME_LifeCycleCORBA(_name_service).FindOrLoad_Component("FactoryServerPy", aCompType);
747 if (!aComp->_is_nil()) {
748 SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(aComp);
749 if (!CORBA::is_nil(aDriver)) {
750 SB->LoadWith(sco, aDriver);
756 MESSAGE("Can not restore information to resave it");
763 CORBA::String_var anOldName = aStudy->Name();
766 // To change for Save
767 // Do not have to do a new file but just a Open??? Rewrite all informations after erasing evrything??
768 hdf_file = new HDFfile((char *)aUrl);
769 hdf_file->CreateOnDisk();
770 MESSAGE("File " << aUrl << " created");
772 //-----------------------------------------------------------------------
773 // 1 - Create a groupe for each SComponent and Update the PersistanceRef
774 //-----------------------------------------------------------------------
775 hdf_group_datacomponent = new HDFgroup("DATACOMPONENT",hdf_file);
776 hdf_group_datacomponent->CreateOnDisk();
778 SALOMEDS::SComponentIterator_var itcomponent = aStudy->NewComponentIterator();
780 //SRN: Added 17 Nov, 2003
781 SALOMEDS::SObject_var anAutoSaveSO = aStudy->FindObjectID(AUTO_SAVE_TAG);
784 for (; itcomponent->More(); itcomponent->Next())
786 SALOMEDS::SComponent_var sco = itcomponent->Value();
788 CORBA::String_var scoid = sco->GetID();
789 hdf_sco_group = new HDFgroup(scoid,hdf_group_datacomponent);
790 hdf_sco_group->CreateOnDisk();
792 CORBA::String_var componentDataType = sco->ComponentDataType();
793 MESSAGE ( "Look for an engine for data type :"<< componentDataType);
795 //SRN: Added 17 Nov 2003: If there is a specified attribute, the component peforms a special save
796 if(!CORBA::is_nil(anAutoSaveSO) && SB->IsGUID(sco, AUTO_SAVE_GUID)) {
798 SALOMEDS::GenericAttribute_var aGeneric;
799 SALOMEDS::AttributeTableOfString_var aTable;
800 if(anAutoSaveSO->FindAttribute(aGeneric, "AttributeTableOfString")) {
801 aTable = SALOMEDS::AttributeTableOfString::_narrow(aGeneric);
802 Standard_Integer nbRows = aTable->GetNbRows(), k, aTimeOut = 0;
803 if(nbRows > 0 && aTable->GetNbColumns() > 1) {
805 SALOMEDS::StringSeq_var aRow;
806 for(k=1; k<=nbRows; k++) {
807 aRow = aTable->GetRow(k);
808 if (strcmp(aRow[0], componentDataType) == 0) {
809 CORBA::String_var anEntry = CORBA::string_dup(aRow[1]);
810 SALOMEDS::SObject_var aCompSpecificSO = aStudy->FindObjectID(anEntry);
811 if(!CORBA::is_nil(aCompSpecificSO)) {
812 SALOMEDS::AttributeInteger_var anInteger;
813 if(aCompSpecificSO->FindAttribute(aGeneric, "AttributeInteger")) {
814 anInteger = SALOMEDS::AttributeInteger::_narrow(aGeneric);
815 anInteger->SetValue(-1);
816 while(anInteger->Value() < 0) { sleep(2); if(++aTimeOut > AUTO_SAVE_TIME_OUT_IN_SECONDS) break; }
817 } // if(aCompSpecificSO->FindAttribute(anInteger, "AttributeInteger"))
818 } // if(!CORBA::is_nil(aCompSpecificSO))
819 } // if (strcmp(aRow[0], componentDataType) == 0)
822 } // if(nbRows > 0 && aTable->GetNbColumns() > 1)
824 } // if(anAutoSaveSO->FindAttribute(aTable, "AttributeTableOfString")
826 } // if(SB->IsGUID(AUTO_SAVE_GUID)
830 CORBA::String_var IOREngine;
831 if (sco->ComponentIOR(IOREngine))
833 // we have found the associated engine to write the data
834 MESSAGE ( "We have found an engine for data type :"<< componentDataType);
835 CORBA::Object_var obj = _orb->string_to_object(IOREngine);
836 SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
838 if (!CORBA::is_nil(Engine))
840 MESSAGE ( "Save the data of type:"<< componentDataType);
841 MESSAGE("Engine :"<<Engine->ComponentDataType());
843 SALOMEDS::TMPFile_var aStream;
845 if (theASCII) aStream = Engine->SaveASCII(sco,SALOMEDS_Tool::GetDirFromPath(aUrl),theMultiFile);
846 else aStream = Engine->Save(sco,SALOMEDS_Tool::GetDirFromPath(aUrl),theMultiFile);
848 HDFdataset *hdf_dataset;
849 hdf_size aHDFSize[1];
850 if(aStream->length() > 0) { //The component saved some auxiliary files, then put them into HDF file
852 aHDFSize[0] = aStream->length();
854 HDFdataset *hdf_dataset = new HDFdataset("FILE_STREAM", hdf_sco_group, HDF_STRING, aHDFSize, 1);
855 hdf_dataset->CreateOnDisk();
856 hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]); //Save the stream in the HDF file
857 hdf_dataset->CloseOnDisk();
859 // store multifile state
861 hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
862 hdf_dataset->CreateOnDisk();
863 hdf_dataset->WriteOnDisk((void*)(theMultiFile?"M":"S")); // save: multi or single
864 hdf_dataset->CloseOnDisk();
865 hdf_dataset=0; //will be deleted by hdf_sco_AuxFiles destructor
869 hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
870 hdf_dataset->CreateOnDisk();
871 hdf_dataset->WriteOnDisk((void*)(theASCII?"A":"B")); // save: ASCII or BINARY
872 hdf_dataset->CloseOnDisk();
873 hdf_dataset=0; //will be deleted by hdf_sco_AuxFiles destructor
875 Translate_IOR_to_persistentID (aStudy,SB,sco,Engine,theMultiFile, theASCII);
876 MESSAGE("After Translate_IOR_to_persistentID");
878 // Creation of the persistance reference attribute
881 hdf_sco_group->CloseOnDisk();
882 hdf_sco_group=0; // will be deleted by hdf_group_datacomponent destructor
884 hdf_group_datacomponent->CloseOnDisk();
885 hdf_group_datacomponent =0; // will be deleted by hdf_file destructor
888 //-----------------------------------------------------------------------
889 //3 - Write the Study Structure
890 //-----------------------------------------------------------------------
891 hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file);
892 hdf_group_study_structure->CreateOnDisk();
894 // save component attributes
895 SALOMEDS::SComponentIterator_var itcomp = aStudy->NewComponentIterator();
896 for (; itcomp->More(); itcomp->Next())
898 SALOMEDS::SComponent_var SC = itcomp->Value();
900 CORBA::String_var scid = SC->GetID();
901 hdf_sco_group2 = new HDFgroup(scid,hdf_group_study_structure);
902 hdf_sco_group2->CreateOnDisk();
903 SaveAttributes(SC, hdf_sco_group2);
904 // ComponentDataType treatment
905 component_name = SC->ComponentDataType();
906 MESSAGE("Component data type " << component_name << " treated");
908 name_len = (hdf_int32) strlen(component_name);
909 size[0] = name_len +1 ;
910 hdf_dataset = new HDFdataset("COMPONENTDATATYPE",hdf_sco_group2,HDF_STRING,size,1);
911 hdf_dataset->CreateOnDisk();
912 hdf_dataset->WriteOnDisk(component_name);
913 MESSAGE("component name " << component_name << " wrote on file");
914 hdf_dataset->CloseOnDisk();
915 hdf_dataset=0; //will be deleted by hdf_sco_group destructor
916 _SaveObject(aStudy, SC, hdf_sco_group2);
917 hdf_sco_group2->CloseOnDisk();
918 hdf_sco_group2=0; // will be deleted by hdf_group_study_structure destructor
919 CORBA::string_free(component_name);
921 //-----------------------------------------------------------------------
922 //4 - Write the Study UseCases Structure
923 //-----------------------------------------------------------------------
924 SALOMEDS::SObject_var aSO = aStudy->FindObjectID(USE_CASE_LABEL_ID);
925 if (!aSO->_is_nil()) {
926 HDFgroup *hdf_soo_group = new HDFgroup(USE_CASE_LABEL_ID,hdf_group_study_structure);
927 hdf_soo_group->CreateOnDisk();
928 SaveAttributes(aSO, hdf_soo_group);
929 _SaveObject(aStudy, aSO, hdf_soo_group);
930 MESSAGE("Use cases data structure writed");
931 hdf_soo_group->CloseOnDisk();
932 hdf_soo_group=0; // will be deleted by hdf_group_study_structure destructor
935 if (aLocked) aStudy->GetProperties()->SetLocked(true);
936 //-----------------------------------------------------------------------
937 //5 - Write the Study Properties
938 //-----------------------------------------------------------------------
939 name_len = (hdf_int32) strlen(aStudy->Name());
940 size[0] = name_len +1 ;
941 hdf_dataset = new HDFdataset("STUDY_NAME",hdf_group_study_structure,HDF_STRING,size,1);
942 hdf_dataset->CreateOnDisk();
943 CORBA::String_var studid = aStudy->Name();
944 hdf_dataset->WriteOnDisk(studid);
945 MESSAGE("study name " << studid << " wrote on file");
946 hdf_dataset->CloseOnDisk();
947 hdf_dataset=0; // will be deleted by hdf_group_study_structure destructor
949 _SaveProperties(aStudy, hdf_group_study_structure);
951 hdf_group_study_structure->CloseOnDisk();
952 hdf_file->CloseOnDisk();
954 _name_service->Change_Directory("/Study");
955 _name_service->Destroy_Name(anOldName);
956 _name_service->Register(aStudy, aStudy->Name());
958 aStudy->IsSaved(true);
959 hdf_group_study_structure =0; // will be deleted by hdf_file destructor
960 delete hdf_file; // recursively deletes all hdf objects...
964 MESSAGE( "HDFexception ! " )
966 if (theASCII) { // save file in ASCII format
967 HDFascii::ConvertFromHDFToASCII(aUrl, true);
971 //============================================================================
972 /*! Function : _SaveObject
975 //============================================================================
976 void SALOMEDS_StudyManager_i::_SaveObject(SALOMEDS::Study_ptr aStudy,
977 SALOMEDS::SObject_ptr SC,
978 HDFgroup *hdf_group_datatype)
980 // Write in group hdf_group_datatype all informations of SObject SC
981 // Iterative function to parse all SObjects under a SComponent
982 SALOMEDS::SObject_var RefSO;
983 HDFgroup *hdf_group_sobject = 0;
984 HDFdataset *hdf_dataset = 0;
986 hdf_int32 name_len = 0;
988 SALOMEDS::ChildIterator_var itchild = aStudy->NewChildIterator(SC);
989 for (; itchild->More(); itchild->Next())
991 SALOMEDS::SObject_var SO = itchild->Value();
993 // mpv: don't save empty labels
994 if (SO->GetAllAttributes()->length() == 0 && !SO->ReferencedObject(RefSO)) {
995 SALOMEDS::ChildIterator_var subchild = aStudy->NewChildIterator(SC);
996 if (!subchild->More()) {
999 subchild->InitEx(true);
1000 bool anEmpty = true;
1001 for (; subchild->More() && anEmpty; subchild->Next())
1002 if (subchild->Value()->GetAllAttributes()->length() != 0 ||
1003 subchild->Value()->ReferencedObject(RefSO)) anEmpty = false;
1009 CORBA::String_var scoid = strdup(SO->GetID());
1010 hdf_group_sobject = new HDFgroup(scoid,hdf_group_datatype);
1011 hdf_group_sobject->CreateOnDisk();
1012 SaveAttributes(SO, hdf_group_sobject);
1013 _SaveObject(aStudy,SO, hdf_group_sobject);
1014 hdf_group_sobject->CloseOnDisk();
1015 hdf_group_sobject =0; // will be deleted by father hdf object destructor
1020 //============================================================================
1021 /*! Function : _SubstituteSlash
1024 //============================================================================
1026 const char *SALOMEDS_StudyManager_i::_SubstituteSlash(const char *aUrl)
1029 TCollection_ExtendedString theUrl(CORBA::string_dup(aUrl));
1030 Standard_ExtCharacter val1 = ToExtCharacter('/');
1031 Standard_ExtCharacter val2 = ToExtCharacter(':');
1032 theUrl.ChangeAll(val1,val2);
1033 TCollection_AsciiString ch(theUrl);
1034 return strdup(ch.ToCString());
1037 //============================================================================
1038 /*! Function : CanCopy
1041 //============================================================================
1042 CORBA::Boolean SALOMEDS_StudyManager_i::CanCopy(SALOMEDS::SObject_ptr theObject) {
1043 SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
1044 if (aComponent->_is_nil()) return false;
1045 if (aComponent == theObject) return false;
1047 CORBA::String_var IOREngine;
1048 if (!aComponent->ComponentIOR(IOREngine)) return false;
1050 CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1051 SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
1052 if (CORBA::is_nil(Engine)) return false;
1053 Standard_Boolean a = Engine->CanCopy(theObject);
1057 //============================================================================
1058 /*! Function : GetDocumentOfStudy
1061 //============================================================================
1062 Handle(TDocStd_Document) SALOMEDS_StudyManager_i::GetDocumentOfStudy(SALOMEDS::Study_ptr theStudy) {
1064 int aNbDocs = _OCAFApp->NbDocuments();
1065 Handle(TDocStd_Document) aDocument;
1066 for(a = 1; a <= aNbDocs ; a++) {
1067 _OCAFApp->GetDocument(a, aDocument);
1068 if (!aDocument.IsNull()) {
1069 SALOMEDS_SObject_i * aSOServant = new SALOMEDS_SObject_i (aDocument->Main(),_orb);
1070 SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_narrow(aSOServant->_this());
1071 SALOMEDS::Study_var aStudy = aSO->GetStudy();
1072 if(CORBA::is_nil(aStudy)) continue; //The clipboard document ( hopefully :) )
1073 if (aStudy->StudyId() == theStudy->StudyId()) break;
1074 aDocument.Nullify();
1081 //============================================================================
1082 /*! Function : CopyLabel
1085 //============================================================================
1086 void SALOMEDS_StudyManager_i::CopyLabel(const SALOMEDS::Study_ptr theSourceStudy,
1087 const SALOMEDS::Driver_ptr theEngine,
1088 const Standard_Integer theSourceStartDepth,
1089 const TDF_Label& theSource,
1090 const TDF_Label& theDestinationMain) {
1092 TDF_Label aTargetLabel = theDestinationMain;
1093 TDF_Label aAuxTargetLabel = theDestinationMain.Father().FindChild(2);
1094 for(a = theSource.Depth() - theSourceStartDepth; a > 0 ; a--) {
1095 TDF_Label aSourceLabel = theSource;
1096 for(int aNbFather = 1; aNbFather < a; aNbFather++) aSourceLabel = aSourceLabel.Father();
1097 aTargetLabel = aTargetLabel.FindChild(aSourceLabel.Tag());
1098 aAuxTargetLabel = aAuxTargetLabel.FindChild(aSourceLabel.Tag());
1100 // iterate attributes
1101 TDF_AttributeIterator anAttrIterator(theSource);
1102 Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable();
1103 for(; anAttrIterator.More(); anAttrIterator.Next()) {
1104 Handle(TDF_Attribute) anAttr = anAttrIterator.Value();
1105 if (!Handle(TDataStd_TreeNode)::DownCast(anAttr).IsNull()) continue; // never copy tree node attribute
1106 if (!Handle(SALOMEDS_TargetAttribute)::DownCast(anAttr).IsNull()) continue; // and target attribute
1108 if (!Handle(TDF_Reference)::DownCast(anAttr).IsNull()) { // reference copied as Comment in auxiliary tree
1109 TDF_Label aReferenced = Handle(TDF_Reference)::DownCast(anAttr)->Get();
1110 TCollection_AsciiString anEntry;
1111 TDF_Tool::Entry(aReferenced, anEntry);
1112 // store the value of name attribute of referenced label
1113 Handle(TDataStd_Name) aNameAttribute;
1114 if (aReferenced.FindAttribute(TDataStd_Name::GetID(), aNameAttribute)) {
1116 anEntry += aNameAttribute->Get();
1118 TDataStd_Comment::Set(aAuxTargetLabel, TCollection_ExtendedString(anEntry));
1122 if (!Handle(SALOMEDS_IORAttribute)::DownCast(anAttr).IsNull()) { // IOR => ID and TMPFile of Engine
1123 TCollection_AsciiString anEntry;
1124 TDF_Tool::Entry(theSource, anEntry);
1125 SALOMEDS::SObject_var aSO = theSourceStudy->FindObjectID(strdup(anEntry.ToCString()));
1126 // if (theEngine->CanCopy(aSO)) {
1127 CORBA::Long anObjID;
1128 // TCollection_ExtendedString aResStr(strdup((char*)(theEngine->CopyFrom(aSO, anObjID))));
1129 SALOMEDS::TMPFile_var aStream = theEngine->CopyFrom(aSO, anObjID);
1130 int aLen = aStream->length();
1131 TCollection_ExtendedString aResStr("");
1132 for(a = 0; a < aLen; a++) {
1133 aResStr += TCollection_ExtendedString(ToExtCharacter((Standard_Character)aStream[a]));
1135 TDataStd_Integer::Set(aAuxTargetLabel, anObjID);
1136 TDataStd_Name::Set(aAuxTargetLabel, aResStr);
1140 Handle(TDF_Attribute) aNewAttribute = anAttr->NewEmpty();
1141 aTargetLabel.AddAttribute(aNewAttribute);
1142 anAttr->Paste(aNewAttribute, aRT);
1143 // aRT->SetRelocation(anAttr, aNewAttribute);
1147 //============================================================================
1151 //============================================================================
1152 CORBA::Boolean SALOMEDS_StudyManager_i::Copy(SALOMEDS::SObject_ptr theObject) {
1153 // adoptation for alliances datamodel copy: without IOR attributes !!!
1154 bool aStructureOnly; // copy only SObjects and attributes without component help
1155 SALOMEDS::GenericAttribute_var anAttribute;
1156 aStructureOnly = !theObject->FindAttribute(anAttribute, "AttributeIOR");
1158 // get component-engine
1159 SALOMEDS::Study_var aStudy = theObject->GetStudy();
1161 SALOMEDS::Driver_var Engine;
1162 if (!aStructureOnly) {
1163 SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
1164 CORBA::String_var IOREngine;
1165 if (!aComponent->ComponentIOR(IOREngine)) return false;
1167 CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1168 Engine = SALOMEDS::Driver::_narrow(obj) ;
1170 // CAF document of current study usage
1171 Handle(TDocStd_Document) aDocument = GetDocumentOfStudy(aStudy);
1172 if (aDocument.IsNull()) return false;
1173 // create new document for clipboard
1174 Handle(TDocStd_Document) aTargetDocument;
1175 _OCAFApp->NewDocument("SALOME_STUDY", aTargetDocument);
1176 // set component data type to the name attribute of root label
1177 if (!aStructureOnly) {
1178 TDataStd_Comment::Set(aTargetDocument->Main().Root(),
1179 TCollection_ExtendedString(strdup(Engine->ComponentDataType())));
1181 // set to the Root label integer attribute: study id
1182 TDataStd_Integer::Set(aTargetDocument->Main().Root(), aStudy->StudyId());
1183 // iterate all theObject's label children
1184 TDF_Label aStartLabel;
1185 char* aStartID = strdup(theObject->GetID());
1186 TDF_Tool::Label(aDocument->GetData(), aStartID, aStartLabel);
1187 Standard_Integer aSourceStartDepth = aStartLabel.Depth();
1189 // copy main source label
1190 CopyLabel(aStudy, Engine, aSourceStartDepth, aStartLabel, aTargetDocument->Main());
1192 // copy all subchildren of the main source label (all levels)
1193 TDF_ChildIterator anIterator(aStartLabel, Standard_True);
1194 for(; anIterator.More(); anIterator.Next()) {
1195 CopyLabel(aStudy, Engine, aSourceStartDepth, anIterator.Value(), aTargetDocument->Main());
1197 // done: free old clipboard document and
1198 if (!_clipboard.IsNull()) {
1199 // Handle(TDocStd_Owner) anOwner;
1200 // if (_clipboard->Main().Root().FindAttribute(TDocStd_Owner::GetID(), anOwner)) {
1201 // Handle(TDocStd_Document) anEmptyDoc;
1202 // anOwner->SetDocument(anEmptyDoc);
1204 _OCAFApp->Close(_clipboard);
1206 _clipboard = aTargetDocument;
1210 //============================================================================
1211 /*! Function : CanPaste
1214 //============================================================================
1215 CORBA::Boolean SALOMEDS_StudyManager_i::CanPaste(SALOMEDS::SObject_ptr theObject) {
1216 if (_clipboard.IsNull()) return false;
1218 Handle(TDataStd_Comment) aCompName;
1219 if (!_clipboard->Main().Root().FindAttribute(TDataStd_Comment::GetID(), aCompName)) return false;
1220 Handle(TDataStd_Integer) anObjID;
1221 if (!_clipboard->Main().Father().FindChild(2).FindAttribute(TDataStd_Integer::GetID(), anObjID))
1224 SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
1225 if (aComponent->_is_nil()) return false;
1227 CORBA::String_var IOREngine;
1228 if (!aComponent->ComponentIOR(IOREngine)) return false;
1230 CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1231 SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
1232 if (CORBA::is_nil(Engine)) return false;
1233 return Engine->CanPaste(strdup(TCollection_AsciiString(aCompName->Get()).ToCString()), anObjID->Get());
1235 //============================================================================
1236 /*! Function : PasteLabel
1239 //============================================================================
1240 TDF_Label SALOMEDS_StudyManager_i::PasteLabel(const SALOMEDS::Study_ptr theDestinationStudy,
1241 const SALOMEDS::Driver_ptr theEngine,
1242 const TDF_Label& theSource,
1243 const TDF_Label& theDestinationStart,
1244 const int theCopiedStudyID,
1245 const bool isFirstElement) {
1247 // get corresponding source, target and auxiliary labels
1248 TDF_Label aTargetLabel = theDestinationStart;
1249 TDF_Label aAuxSourceLabel = theSource.Root().FindChild(2);
1251 if (!isFirstElement) {
1252 for(a = theSource.Depth() - 1; a > 0 ; a--) {
1253 TDF_Label aSourceLabel = theSource;
1254 for(int aNbFather = 1; aNbFather < a; aNbFather++) aSourceLabel = aSourceLabel.Father();
1255 aTargetLabel = aTargetLabel.FindChild(aSourceLabel.Tag());
1256 aAuxSourceLabel = aAuxSourceLabel.FindChild(aSourceLabel.Tag());
1260 // check auxiliary label for TMPFile => IOR
1261 Handle(TDataStd_Name) aNameAttribute;
1262 if (aAuxSourceLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttribute)) {
1263 Handle(TDataStd_Integer) anObjID;
1265 aAuxSourceLabel.FindAttribute(TDataStd_Integer::GetID(), anObjID);
1266 Handle(TDataStd_Comment) aComponentName;
1267 theSource.Root().FindAttribute(TDataStd_Comment::GetID(), aComponentName);
1268 CORBA::String_var aCompName = strdup(TCollection_AsciiString(aComponentName->Get()).ToCString());
1270 if (theEngine->CanPaste(aCompName, anObjID->Get())) {
1271 SALOMEDS::TMPFile_var aTMPFil = new SALOMEDS::TMPFile();
1272 TCollection_ExtendedString aTMPStr = aNameAttribute->Get();
1273 int aLen = aTMPStr.Length();
1274 aTMPFil->length(aLen);
1275 for(a = 0; a < aLen; a++) {
1276 aTMPFil[a] = ToCharacter(aTMPStr.Value(a+1));
1278 // char* aTMPStr = strdup(TCollection_AsciiString(aNameAttribute->Get()).ToCString());
1279 // int aLen = strlen(aTMPStr);
1280 // SALOMEDS::TMPFile aTMPFil(aLen, aLen, (CORBA::Octet*)aTMPStr, 1);
1282 TCollection_AsciiString anEntry;
1283 TDF_Tool::Entry(aTargetLabel, anEntry);
1284 SALOMEDS::SObject_var aPastedSO = theDestinationStudy->FindObjectID(strdup(anEntry.ToCString()));
1285 if (isFirstElement) {
1286 SALOMEDS::SObject_var aDestSO =
1287 theEngine->PasteInto(aTMPFil.in(),
1289 aPastedSO->GetFatherComponent());
1290 TDF_Tool::Label(theDestinationStart.Data(), aDestSO->GetID(), aTargetLabel);
1291 } else theEngine->PasteInto(aTMPFil.in(),anObjID->Get(),aPastedSO);
1295 // iterate attributes
1296 TDF_AttributeIterator anAttrIterator(theSource);
1297 Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable();
1298 for(; anAttrIterator.More(); anAttrIterator.Next()) {
1299 Handle(TDF_Attribute) anAttr = anAttrIterator.Value();
1300 if (aTargetLabel.FindAttribute(anAttr->ID(), anAttr)) {
1301 aTargetLabel.ForgetAttribute(anAttr->ID());
1302 anAttr = anAttrIterator.Value();
1304 Handle(TDF_Attribute) aNewAttribute = anAttr->NewEmpty();
1305 aTargetLabel.AddAttribute(aNewAttribute);
1306 anAttr->Paste(aNewAttribute, aRT);
1307 // aRT->SetRelocation(anAttr, aNewAttribute);
1309 // check auxiliary label for Comment => reference or name attribute of the referenced object
1310 Handle(TDataStd_Comment) aCommentAttribute;
1311 if (aAuxSourceLabel.FindAttribute(TDataStd_Comment::GetID(), aCommentAttribute)) {
1312 char * anEntry = new char[aCommentAttribute->Get().Length() + 1];
1313 strcpy(anEntry, TCollection_AsciiString(aCommentAttribute->Get()).ToCString());
1314 char* aNameStart = strchr(anEntry, ' ');
1319 if (theCopiedStudyID == theDestinationStudy->StudyId()) { // if copy to the same study, reanimate reference
1320 TDF_Label aRefLabel;
1321 TDF_Tool::Label(aTargetLabel.Data(), anEntry, aRefLabel);
1322 TDF_Reference::Set(aTargetLabel, aRefLabel);
1323 SALOMEDS_TargetAttribute::Set(aRefLabel)->Append(aTargetLabel); // target attributes structure support
1325 if (aNameStart) TDataStd_Name::Set(aTargetLabel, aNameStart);
1326 else TDataStd_Name::Set(aTargetLabel, TCollection_ExtendedString("Reference to:")+anEntry);
1331 return aTargetLabel;
1333 //============================================================================
1334 /*! Function : Paste
1337 //============================================================================
1338 SALOMEDS::SObject_ptr SALOMEDS_StudyManager_i::Paste(SALOMEDS::SObject_ptr theObject)
1339 throw(SALOMEDS::StudyBuilder::LockProtection)
1341 Unexpect aCatch(LockProtection);
1342 SALOMEDS::Study_var aStudy = theObject->GetStudy();
1344 // if study is locked, then paste can't be done
1345 if (aStudy->GetProperties()->IsLocked())
1346 throw SALOMEDS::StudyBuilder::LockProtection();
1348 // if there is no component name, then paste only SObjects and attributes: without component help
1349 Handle(TDataStd_Comment) aComponentName;
1350 bool aStructureOnly = !_clipboard->Main().Root().FindAttribute(TDataStd_Comment::GetID(), aComponentName);
1352 // get copied study ID
1353 Handle(TDataStd_Integer) aStudyIDAttribute;
1354 if (!_clipboard->Main().Root().FindAttribute(TDataStd_Integer::GetID(), aStudyIDAttribute))
1355 return SALOMEDS::SObject::_nil();
1356 int aCStudyID = aStudyIDAttribute->Get();
1358 // get component-engine
1359 SALOMEDS::Driver_var Engine;
1360 SALOMEDS::SComponent_var aComponent;
1361 if (!aStructureOnly) {
1362 aComponent = theObject->GetFatherComponent();
1363 CORBA::String_var IOREngine;
1364 if (!aComponent->ComponentIOR(IOREngine)) return SALOMEDS::SObject::_nil();
1365 CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1366 Engine = SALOMEDS::Driver::_narrow(obj) ;
1369 // CAF document of current study usage
1370 Handle(TDocStd_Document) aDocument = GetDocumentOfStudy(aStudy);
1371 if (aDocument.IsNull()) return SALOMEDS::SObject::_nil();
1372 // fill root inserted SObject
1373 TDF_Label aStartLabel;
1374 if (aStructureOnly) {
1375 TDF_Label anObjectLabel;
1376 TDF_Tool::Label(aDocument->GetData(), theObject->GetID(), anObjectLabel);
1377 aStartLabel = PasteLabel(aStudy, Engine, _clipboard->Main(), anObjectLabel, aCStudyID, false);
1379 TDF_Label aComponentLabel;
1380 TDF_Tool::Label(aDocument->GetData(), aComponent->GetID(), aComponentLabel);
1381 aStartLabel = PasteLabel(aStudy, Engine, _clipboard->Main(), aComponentLabel, aCStudyID, true);
1384 // paste all sublebels
1385 TDF_ChildIterator anIterator(_clipboard->Main(), Standard_True);
1386 for(; anIterator.More(); anIterator.Next()) {
1387 PasteLabel(aStudy, Engine, anIterator.Value(), aStartLabel, aCStudyID, false);
1390 SALOMEDS_SObject_i * so_servant = new SALOMEDS_SObject_i (aStartLabel, _orb);
1391 SALOMEDS::SObject_var so = SALOMEDS::SObject::_narrow(so_servant->_this());