1 // File : SALOMEDSImpl_Study.cxx
2 // Author : Sergey RUIN
6 #include "SALOMEDSImpl_Study.hxx"
10 #include <TColStd_SequenceOfExtendedString.hxx>
11 #include <TCollection_ExtendedString.hxx>
13 #include <TColStd_HSequenceOfAsciiString.hxx>
14 #include <TDocStd_Application.hxx>
15 #include <TDocStd_Owner.hxx>
16 #include <TDF_LabelList.hxx>
17 #include <TDF_ListIteratorOfLabelList.hxx>
18 #include <CDM_Document.hxx>
19 #include <CDM_Application.hxx>
20 #include <TDF_ChildIDIterator.hxx>
21 #include <TDF_ChildIterator.hxx>
22 #include <TDF_AttributeIterator.hxx>
24 #include "SALOMEDSImpl_ChildNodeIterator.hxx"
25 #include "SALOMEDSImpl_Attributes.hxx"
26 #include "SALOMEDSImpl_UseCaseIterator.hxx"
27 #include "SALOMEDSImpl_AttributeReference.hxx"
28 #include "SALOMEDSImpl_StudyHandle.hxx"
29 #include "SALOMEDSImpl_Tool.hxx"
31 IMPLEMENT_STANDARD_HANDLE( SALOMEDSImpl_Study, MMgt_TShared )
32 IMPLEMENT_STANDARD_RTTIEXT( SALOMEDSImpl_Study, MMgt_TShared )
34 #define DIRECTORYID 16661
35 #define FILELOCALID 26662
36 #define FILEID "FILE: "
38 //============================================================================
39 /*! Function : SALOMEDSImpl_Study
40 * Purpose : SALOMEDSImpl_Study constructor
42 //============================================================================
43 SALOMEDSImpl_Study::SALOMEDSImpl_Study(const Handle(TDocStd_Document)& doc,
44 const TCollection_AsciiString& study_name)
46 doc->SetUndoLimit(1); // mpv (IPAL9237): if there is no undo limit, operations mechanism couldn't work
53 myNbPostponed.Append(0);
56 _useCaseBuilder = new SALOMEDSImpl_UseCaseBuilder(_doc);
57 _builder = new SALOMEDSImpl_StudyBuilder(this);
58 _cb = new SALOMEDSImpl_Callback(_useCaseBuilder);
59 //Put on the root label a StudyHandle attribute to store the address of this object
60 //It will be used to retrieve the study object by TDF_Label that belongs to the study
61 SALOMEDSImpl_StudyHandle::Set(_doc->Main().Root(), this);
65 //============================================================================
66 /*! Function : ~SALOMEDSImpl_Study
67 * Purpose : SALOMEDSImpl_Study destructor
69 //============================================================================
70 SALOMEDSImpl_Study::~SALOMEDSImpl_Study()
73 //============================================================================
74 /*! Function : GetPersistentReference
75 * Purpose : Get persistent reference of study (idem URL())
77 //============================================================================
78 TCollection_AsciiString SALOMEDSImpl_Study::GetPersistentReference()
83 //============================================================================
84 /*! Function : GetTransientReference
85 * Purpose : Get IOR of the Study (registred in OCAF document in doc->Root)
87 //============================================================================
88 TCollection_AsciiString SALOMEDSImpl_Study::GetTransientReference()
91 TCollection_AsciiString IOR = "";
93 Handle(SALOMEDSImpl_AttributeIOR) Att;
94 TDF_Label _lab = _doc->GetData()->Root();
95 if (_lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID(),Att)) {
99 _errorCode = "IOR is empty";
105 void SALOMEDSImpl_Study::SetTransientReference(const TCollection_AsciiString& theIOR)
109 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
110 int aLocked = aProp->IsLocked();
111 if (aLocked) aProp->SetLocked(Standard_False);
113 // Assign the value of the IOR in the study->root
114 SALOMEDSImpl_AttributeIOR::Set(_doc->Main().Root(), theIOR);
116 if (aLocked) aProp->SetLocked(Standard_True);
119 //============================================================================
120 /*! Function : IsEmpty
121 * Purpose : Detect if study is empty
123 //============================================================================
124 bool SALOMEDSImpl_Study::IsEmpty()
127 if (_doc.IsNull()) return true;
128 return _doc->IsEmpty();
131 //============================================================================
132 /*! Function : FindComponent
133 * Purpose : Find a Component with ComponentDataType = aComponentName
135 //============================================================================
136 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::FindComponent (const TCollection_AsciiString& aComponentName)
140 TCollection_AsciiString name;
141 SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
142 Handle(SALOMEDSImpl_SComponent) compo;
144 for (; itcomp.More(); itcomp.Next()) {
145 Handle(SALOMEDSImpl_SComponent) SC = itcomp.Value();
146 name = SC->ComponentDataType();
147 if(aComponentName == name) {
155 _errorCode = "No component was found";
161 //============================================================================
162 /*! Function : FindComponentID
163 * Purpose : Find a Component from it's ID
165 //============================================================================
166 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::FindComponentID(const TCollection_AsciiString& aComponentID)
170 // Iterate on each components defined in the study
171 // Get the component ID and compare with aComponentID
173 TCollection_AsciiString ID;
174 Handle(SALOMEDSImpl_SComponent) compo;
176 SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
177 for (; itcomp.More(); itcomp.Next()) {
178 Handle(SALOMEDSImpl_SComponent) SC = itcomp.Value();
180 if(aComponentID == ID)
189 _errorCode = "No component was found";
196 //============================================================================
197 /*! Function : FindObject
198 * Purpose : Find an Object with SALOMEDSImpl_Name = anObjectName
200 //============================================================================
201 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObject(const TCollection_AsciiString& anObjectName)
205 // Iterate to all components defined in the study
206 // After testing the component name, iterate in all objects defined under
207 // components (function _FindObject)
209 Handle(SALOMEDSImpl_SObject) RefSO = NULL;
211 SALOMEDSImpl_SComponentIterator it = NewComponentIterator();
212 for (; it.More();it.Next()){
215 Handle(SALOMEDSImpl_SComponent) SC = it.Value();
216 if (SC->GetName() == anObjectName)
222 if (!_find) RefSO = _FindObject(SC, anObjectName, _find);
225 if(RefSO.IsNull()) _errorCode = "No object was found";
229 //============================================================================
230 /*! Function : FindObjectID
231 * Purpose : Find an Object with ID = anObjectID
233 //============================================================================
234 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectID(const TCollection_AsciiString& anObjectID)
238 // Convert aSO->GetID in TDF_Label.
240 TDF_Tool::Label(_doc->Main().Data(), anObjectID, Lab);
243 _errorCode = "No label was found by ID";
246 return GetSObject(Lab);
250 //============================================================================
251 /*! Function : CreateObjectID
252 * Purpose : Creates an Object with ID = anObjectID
254 //============================================================================
255 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::CreateObjectID(const TCollection_AsciiString& anObjectID)
259 // Convert aSO->GetID in TDF_Label.
261 TDF_Tool::Label(_doc->Main().Data(), anObjectID, Lab, Standard_True);
264 _errorCode = "Can not create a label";
267 return GetSObject(Lab);
271 //============================================================================
272 /*! Function : FindObjectByName
273 * Purpose : Find Objects with SALOMEDSImpl_Name = anObjectName in a Component
274 * : with ComponentDataType = aComponentName
276 //============================================================================
277 Handle(TColStd_HSequenceOfTransient) SALOMEDSImpl_Study::FindObjectByName(const TCollection_AsciiString& anObjectName,
278 const TCollection_AsciiString& aComponentName)
282 Handle(TColStd_HSequenceOfTransient) listSO = new TColStd_HSequenceOfTransient();
284 Handle(SALOMEDSImpl_SComponent) compo = FindComponent(aComponentName) ;
285 if ( compo.IsNull() ) {
286 _errorCode = "Can not find the component";
290 // Iterate on each object and subobject of the component
291 // If objectName is found add it to the list of SObjects
292 TCollection_AsciiString childName ;
294 TCollection_AsciiString compoId = compo->GetID();
295 Handle(SALOMEDSImpl_ChildIterator) it = NewChildIterator(compo);
296 for ( ; it->More(); it->Next() ) {
298 Handle(SALOMEDSImpl_SObject) CSO = it->Value();
299 if ( CSO->GetName() == anObjectName ) {
301 listSO->Append(CSO) ;
304 /* looks also for eventual children */
306 CSO = _FindObject( CSO, anObjectName, found ) ;
308 listSO->Append(CSO) ;
317 //============================================================================
318 /*! Function : FindObjectIOR
319 * Purpose : Find an Object with IOR = anObjectIOR
321 //============================================================================
322 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectIOR(const TCollection_AsciiString& anObjectIOR)
326 // firstly searching in the datamap for optimization
327 if (myIORLabels.IsBound(anObjectIOR)) {
328 Handle(SALOMEDSImpl_SObject) aResult = GetSObject(myIORLabels.Find(anObjectIOR));
329 // 11 oct 2002: forbidden attributes must be checked here
330 if (!aResult->GetLabel().IsAttribute(SALOMEDSImpl_AttributeIOR::GetID())) {
331 myIORLabels.UnBind(anObjectIOR);
335 // Iterate to all components defined in the study
336 // After testing the component name, iterate in all objects defined under
337 // components (function _FindObject)
339 Handle(SALOMEDSImpl_SObject) RefSO = NULL;
341 SALOMEDSImpl_SComponentIterator it = NewComponentIterator();
342 Handle(SALOMEDSImpl_SComponent) SC;
343 for (; it.More();it.Next()){
347 TCollection_AsciiString ior = SC->GetIOR();
350 if (ior == anObjectIOR)
357 RefSO = _FindObjectIOR(SC, anObjectIOR, _find);
361 if(RefSO.IsNull()) _errorCode = "No object was found";
365 //============================================================================
366 /*! Function : FindObjectByPath
367 * Purpose : Find an Object by its path = thePath
369 //============================================================================
370 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectByPath(const TCollection_AsciiString& thePath)
374 TCollection_AsciiString aPath(thePath), aToken;
375 Handle(SALOMEDSImpl_SObject) aSO = NULL;
376 int i = 1, aLength = aPath.Length();
377 bool isRelative = false;
379 if(aLength == 0) { //Empty path - return the current context
380 return GetSObject(_current);
383 if(aPath.Value(1) != '/') //Relative path
386 TDF_ChildIterator anIterator;
388 Handle(SALOMEDSImpl_AttributeName) anAttr;
391 if(_current.IsNull()) return NULL;
392 anIterator.Initialize(_current, Standard_False);
395 if(aPath.Length() == 1 && aPath.Value(1) == '/') { //Root
396 return GetSObject(_doc->Main());
398 anIterator.Initialize(_doc->Main(), Standard_False);
401 while(i <= aLength) {
403 aToken = aPath.Token("/", i);
404 if(aToken.Length() == 0) break;
406 for ( ; anIterator.More(); anIterator.Next() ) {
407 aLabel = anIterator.Value();
408 if(aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), anAttr)) {
409 if(anAttr->Value() == aToken) {
410 aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
411 if(aToken.Length() == 0) { //The searched label is found (no part of the path is left)
412 return GetSObject(aLabel);
415 anIterator.Initialize(aLabel, Standard_False);
424 if(aSO.IsNull()) _errorCode = "No object was found";
428 //============================================================================
429 /*! Function : GetObjectPath
432 //============================================================================
433 TCollection_AsciiString SALOMEDSImpl_Study::GetObjectPath(const Handle(SALOMEDSImpl_SObject)& theObject)
437 TCollection_AsciiString aPath("");
438 if(theObject.IsNull()) {
439 _errorCode = "Null object";
440 return aPath.ToCString();
443 TCollection_AsciiString aName = theObject->GetName();
444 if(!aName.IsEmpty() && aName != "" ) {
445 TCollection_AsciiString aValue((char*)aName.ToCString());
449 Handle(SALOMEDSImpl_SObject) aFather = theObject->GetFather();
450 if(!aFather.IsNull()) {
451 aName = aFather->GetName();
452 if(!aName.IsEmpty() && aName != "") {
453 aValue = (char*)GetObjectPath(aFather).ToCString();
454 aPath = aValue + aPath;
463 //============================================================================
464 /*! Function : GetObjectPathByIOR
467 //============================================================================
468 TCollection_AsciiString SALOMEDSImpl_Study::GetObjectPathByIOR(const TCollection_AsciiString& theIOR)
472 TCollection_AsciiString aPath;
473 Handle(SALOMEDSImpl_SObject) so = FindObjectIOR(theIOR);
475 _errorCode = "No SObject was found by IOR";
479 return GetObjectPath(so);
483 //============================================================================
484 /*! Function : SetContext
485 * Purpose : Sets the current context
487 //============================================================================
488 bool SALOMEDSImpl_Study::SetContext(const TCollection_AsciiString& thePath)
491 if(thePath.IsEmpty()) {
492 _errorCode = "InvalidPath";
496 TCollection_AsciiString aPath(thePath), aContext("");
497 bool isInvalid = false;
498 Handle(SALOMEDSImpl_SObject) aSO;
500 if(aPath.Value(1) != '/') { //Relative path
501 aContext = GetContext();
509 aSO = FindObjectByPath(aContext.ToCString());
515 if(isInvalid || aSO.IsNull()) {
516 _errorCode = "InvalidContext";
520 TDF_Label aLabel = aSO->GetLabel();
521 if(aLabel.IsNull()) {
522 _errorCode = "InvalidContext";
526 _current = aLabel; //Set the current context
531 //============================================================================
532 /*! Function : GetContext
533 * Purpose : Gets the current context
535 //============================================================================
536 TCollection_AsciiString SALOMEDSImpl_Study::GetContext()
540 if(_current.IsNull()) {
541 _errorCode = "InvaidContext";
544 Handle(SALOMEDSImpl_SObject) so = GetSObject(_current);
545 return GetObjectPath(so);
548 //============================================================================
549 /*! Function : GetObjectNames
550 * Purpose : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
552 //============================================================================
553 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetObjectNames(const TCollection_AsciiString& theContext)
557 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
559 if (theContext.IsEmpty()) {
560 if(_current.IsNull()) {
561 _errorCode = "InvalidContext";
566 TDF_Label aTmp = _current;
567 SetContext(theContext);
571 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
572 for(; anIter.More(); anIter.Next()) {
573 TDF_Label aLabel = anIter.Value();
574 Handle(SALOMEDSImpl_AttributeName) aName;
575 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
581 //============================================================================
582 /*! Function : GetDirectoryNames
583 * Purpose : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
585 //============================================================================
586 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetDirectoryNames(const TCollection_AsciiString& theContext)
590 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
592 if (theContext.IsEmpty()) {
593 if(_current.IsNull()) {
594 _errorCode = "InvalidContext";
599 TDF_Label aTmp = _current;
600 SetContext(theContext);
604 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
605 for(; anIter.More(); anIter.Next()) {
606 TDF_Label aLabel = anIter.Value();
607 Handle(SALOMEDSImpl_AttributeLocalID) anID;
608 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
609 if (anID->Value() == DIRECTORYID) {
610 Handle(SALOMEDSImpl_AttributeName) aName;
611 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) {
612 aResultSeq->Append(aName->Value());
621 //============================================================================
622 /*! Function : GetFileNames
623 * Purpose : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
625 //============================================================================
626 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetFileNames(const TCollection_AsciiString& theContext)
630 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
632 if (theContext.IsEmpty()) {
633 if(_current.IsNull()) {
634 _errorCode = "InvalidContext";
639 TDF_Label aTmp = _current;
640 SetContext(theContext);
644 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
645 for(; anIter.More(); anIter.Next()) {
646 TDF_Label aLabel = anIter.Value();
647 Handle(SALOMEDSImpl_AttributeLocalID) anID;
648 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
649 if (anID->Value() == FILELOCALID) {
650 Handle(SALOMEDSImpl_AttributePersistentRef) aName;
651 if(aLabel.FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID(), aName)) {
652 TCollection_ExtendedString aFileName = aName->Value();
653 if(aFileName.Length() > 0)
654 aResultSeq->Append(aFileName.Split(strlen(FILEID)));
663 //============================================================================
664 /*! Function : GetComponentNames
665 * Purpose : method to get all components names
667 //============================================================================
668 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetComponentNames(const TCollection_AsciiString& theContext)
672 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
673 TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
674 for(; anIter.More(); anIter.Next()) {
675 TDF_Label aLabel = anIter.Value();
676 Handle(SALOMEDSImpl_AttributeName) aName;
677 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
683 //============================================================================
684 /*! Function : NewChildIterator
685 * Purpose : Create a ChildIterator from an SObject
687 //============================================================================
688 Handle(SALOMEDSImpl_ChildIterator) SALOMEDSImpl_Study::NewChildIterator(const Handle(SALOMEDSImpl_SObject)& aSO)
691 return new SALOMEDSImpl_ChildIterator(aSO);
695 //============================================================================
696 /*! Function : NewComponentIterator
697 * Purpose : Create a SComponentIterator
699 //============================================================================
700 SALOMEDSImpl_SComponentIterator SALOMEDSImpl_Study::NewComponentIterator()
703 return SALOMEDSImpl_SComponentIterator(_doc);
707 //============================================================================
708 /*! Function : NewBuilder
709 * Purpose : Create a StudyBuilder
711 //============================================================================
712 Handle(SALOMEDSImpl_StudyBuilder) SALOMEDSImpl_Study::NewBuilder()
716 _builder->SetOnAddSObject(_cb);
717 _builder->SetOnRemoveSObject(_cb);
723 //============================================================================
725 * Purpose : get study name
727 //============================================================================
728 TCollection_AsciiString SALOMEDSImpl_Study::Name()
734 //============================================================================
736 * Purpose : set study name
738 //============================================================================
739 void SALOMEDSImpl_Study::Name(const TCollection_AsciiString& name)
745 //============================================================================
746 /*! Function : IsSaved
747 * Purpose : get if study has been saved
749 //============================================================================
750 bool SALOMEDSImpl_Study::IsSaved()
756 //============================================================================
757 /*! Function : IsSaved
758 * Purpose : set if study has been saved
760 //============================================================================
761 void SALOMEDSImpl_Study::IsSaved(bool save)
765 if(save) _doc->UnModify();
768 //============================================================================
769 /*! Function : IsModified
770 * Purpose : Detect if a Study has been modified since it has been saved
772 //============================================================================
773 bool SALOMEDSImpl_Study::IsModified()
777 // True if is modified
778 if (_doc->IsModified()) return true;
783 //============================================================================
785 * Purpose : get URL of the study (persistent reference of the study)
787 //============================================================================
788 TCollection_AsciiString SALOMEDSImpl_Study::URL()
794 //============================================================================
796 * Purpose : set URL of the study (persistent reference of the study)
798 //============================================================================
799 void SALOMEDSImpl_Study::URL(const TCollection_AsciiString& url)
804 /*jfa: Now name of SALOMEDS study will correspond to name of SalomeApp study
805 TCollection_AsciiString tmp(_URL);
807 char *aName = (char*)tmp.ToCString();
808 char *adr = strtok(aName, "/");
812 adr = strtok(NULL, "/");
819 //============================================================================
820 /*! Function : _FindObject
821 * Purpose : Find an Object with SALOMEDSImpl_Name = anObjectName
823 //============================================================================
824 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::_FindObject(const Handle(SALOMEDSImpl_SObject)& SO,
825 const TCollection_AsciiString& theObjectName,
828 if(SO.IsNull()) return NULL;
830 // Iterate on each objects and subobjects of the component
831 // If objectName find, stop the loop and get the object reference
832 Handle(SALOMEDSImpl_SObject) RefSO;
833 Handle(SALOMEDSImpl_AttributeName) anAttr;
835 TCollection_AsciiString soid = SO->GetID();
836 TDF_ChildIterator it(SO->GetLabel());
837 for (; it.More(); it.Next()){
840 if (it.Value().FindAttribute(SALOMEDSImpl_AttributeName::GetID(), anAttr))
842 TCollection_AsciiString Val(anAttr->Value());
843 if (Val == theObjectName)
845 RefSO = GetSObject(it.Value());
849 if (!_find) RefSO = _FindObject(GetSObject(it.Value()), theObjectName, _find);
855 //============================================================================
856 /*! Function : _FindObjectIOR
857 * Purpose : Find an Object with SALOMEDSImpl_IOR = anObjectIOR
859 //============================================================================
860 Handle(SALOMEDSImpl_SObject)
861 SALOMEDSImpl_Study::_FindObjectIOR(const Handle(SALOMEDSImpl_SObject)& SO,
862 const TCollection_AsciiString& theObjectIOR,
865 if(SO.IsNull()) return NULL;
867 // Iterate on each objects and subobjects of the component
868 // If objectName find, stop the loop and get the object reference
869 Handle(SALOMEDSImpl_SObject) RefSO, aSO;
870 Handle(SALOMEDSImpl_AttributeIOR) anAttr;
872 TDF_ChildIterator it(SO->GetLabel());
873 for (; it.More();it.Next()){
876 if (it.Value().FindAttribute(SALOMEDSImpl_AttributeIOR::GetID(), anAttr))
878 TCollection_AsciiString Val(anAttr->Value());
879 if (Val == theObjectIOR)
881 RefSO = GetSObject(it.Value());
885 aSO = GetSObject(it.Value());
886 if (!_find) RefSO = _FindObjectIOR(aSO, theObjectIOR, _find);
892 bool SALOMEDSImpl_Study::IsLocked()
895 return GetProperties()->IsLocked();
898 int SALOMEDSImpl_Study::StudyId()
904 void SALOMEDSImpl_Study::StudyId(int id)
910 void SALOMEDSImpl_Study::UpdateIORLabelMap(const TCollection_AsciiString& anIOR,const TCollection_AsciiString& anEntry)
914 char* anEn = (char*)anEntry.ToCString();
915 char* IOR = (char*)anIOR.ToCString();
916 TDF_Tool::Label(_doc->GetData(),anEn, aLabel, Standard_True);
917 if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
918 myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
921 Handle(SALOMEDSImpl_Study) SALOMEDSImpl_Study::GetStudy(const TDF_Label& theLabel)
923 Handle(SALOMEDSImpl_StudyHandle) Att;
924 if (theLabel.Root().FindAttribute(SALOMEDSImpl_StudyHandle::GetID(),Att)) {
925 return Att->GetHandle();
930 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::SObject(const TDF_Label& theLabel)
932 return GetStudy(theLabel)->GetSObject(theLabel);
935 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::SComponent(const TDF_Label& theLabel)
937 return GetStudy(theLabel)->GetSComponent(theLabel);
941 void SALOMEDSImpl_Study::IORUpdated(const Handle(SALOMEDSImpl_AttributeIOR)& theAttribute)
943 TCollection_AsciiString aString;
944 TDF_Tool::Entry(theAttribute->Label(), aString);
945 GetStudy(theAttribute->Label())->UpdateIORLabelMap(theAttribute->Value(), aString);
948 Handle(TColStd_HSequenceOfTransient) SALOMEDSImpl_Study::FindDependances(const Handle(SALOMEDSImpl_SObject)& anObject)
951 Handle(TColStd_HSequenceOfTransient) aSeq;
953 Handle(SALOMEDSImpl_AttributeTarget) aTarget;
954 if (anObject->GetLabel().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID(), aTarget)) {
955 return aTarget->Get();
962 Handle(SALOMEDSImpl_AttributeStudyProperties) SALOMEDSImpl_Study::GetProperties()
965 return SALOMEDSImpl_AttributeStudyProperties::Set(_doc->Main());
968 TCollection_AsciiString SALOMEDSImpl_Study::GetLastModificationDate()
971 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
973 Handle(TColStd_HSequenceOfExtendedString) aNames;
974 Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
975 aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
977 int aLastIndex = aNames->Length();
979 sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
980 (int)(aDays->Value(aLastIndex)),(int)(aMonths->Value(aLastIndex)), (int)(aYears->Value(aLastIndex)),
981 (int)(aHours->Value(aLastIndex)), (int)(aMinutes->Value(aLastIndex)));
982 TCollection_AsciiString aResStr (aResult);
986 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetModificationsDate()
989 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
991 Handle(TColStd_HSequenceOfExtendedString) aNames;
992 Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
993 aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
995 int anIndex, aLength = aNames->Length();
996 Handle(TColStd_HSequenceOfAsciiString) aDates = new TColStd_HSequenceOfAsciiString;
998 for (anIndex = 2; anIndex <= aLength; anIndex++) {
1000 sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
1001 (int)(aDays->Value(anIndex)), (int)(aMonths->Value(anIndex)), (int)(aYears->Value(anIndex)),
1002 (int)(aHours->Value(anIndex)), (int)(aMinutes->Value(anIndex)));
1003 aDates->Append(aDate);
1010 //============================================================================
1011 /*! Function : GetUseCaseBuilder
1012 * Purpose : Returns a UseCase builder
1014 //============================================================================
1015 Handle(SALOMEDSImpl_UseCaseBuilder) SALOMEDSImpl_Study::GetUseCaseBuilder()
1018 return _useCaseBuilder;
1022 //============================================================================
1023 /*! Function : Close
1026 //============================================================================
1027 void SALOMEDSImpl_Study::Close()
1030 Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1031 if(!anApp.IsNull()) anApp->Close(_doc);
1037 //============================================================================
1038 /*! Function : AddPostponed
1041 //============================================================================
1042 void SALOMEDSImpl_Study::AddPostponed(const TCollection_AsciiString& theIOR)
1045 if (!NewBuilder()->HasOpenCommand()) return;
1046 TCollection_AsciiString anIOR(theIOR);
1048 myPostponedIORs.Append(anIOR); // add prefix: deleted
1049 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1052 //============================================================================
1053 /*! Function : AddCreatedPostponed
1056 //============================================================================
1057 void SALOMEDSImpl_Study::AddCreatedPostponed(const TCollection_AsciiString& theIOR)
1060 if (!NewBuilder()->HasOpenCommand()) return;
1061 TCollection_AsciiString anIOR(theIOR);
1063 myPostponedIORs.Append(anIOR); // add prefix: created
1064 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1067 //============================================================================
1068 /*! Function : RemovePostponed
1071 //============================================================================
1072 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::RemovePostponed(const int theUndoLimit)
1079 int aUndoLimit = theUndoLimit;
1080 if (theUndoLimit < 0) aUndoLimit = 0;
1082 Handle(TColStd_HSequenceOfAsciiString) aSeq = new TColStd_HSequenceOfAsciiString;
1084 if (myNbUndos > 0) { // remove undone
1086 for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1087 anOld += myNbPostponed(anIndex);
1088 int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1090 for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1091 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1092 if (anIOR.Value(1) == 'c') {
1093 aSeq->Append(anIOR.Split(1).ToCString());
1096 if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1097 if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1102 if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1104 for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1105 anOld += myNbPostponed(anIndex);
1106 for(anIndex = 1; anIndex <= anOld; anIndex++) {
1107 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1108 if (anIOR.Value(1) == 'd') {
1109 aSeq->Append(anIOR.Split(1).ToCString());
1112 if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1113 myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1116 if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1117 TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDSImpl_AttributeIOR::GetID(), Standard_True);
1118 for(; anIter.More(); anIter.Next()) {
1119 Handle(SALOMEDSImpl_AttributeIOR) anAttr = Handle(SALOMEDSImpl_AttributeIOR)::DownCast(anIter.Value());
1120 aSeq->Append(anAttr->Value());
1122 } else myNbPostponed.Append(0);
1127 //============================================================================
1128 /*! Function : UndoPostponed
1131 //============================================================================
1132 void SALOMEDSImpl_Study::UndoPostponed(const int theWay)
1136 myNbUndos += theWay;
1137 // remove current postponed
1138 if (myNbPostponed.Last() > 0)
1139 myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1140 myNbPostponed(myNbPostponed.Length()) = 0;
1144 //============================================================================
1145 /*! Function : GetSComponent
1148 //============================================================================
1149 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TCollection_AsciiString& theEntry)
1151 Handle(SALOMEDSImpl_SComponent) aSCO;
1152 if(_mapOfSCO.IsBound(theEntry))
1153 aSCO = Handle(SALOMEDSImpl_SComponent)::DownCast(_mapOfSCO.Find(theEntry));
1156 TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1157 aSCO = new SALOMEDSImpl_SComponent(aLabel);
1158 _mapOfSCO.Bind(theEntry, aSCO);
1164 //============================================================================
1165 /*! Function : GetSComponent
1168 //============================================================================
1169 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TDF_Label& theLabel)
1171 TCollection_AsciiString anEntry;
1172 TDF_Tool::Entry(theLabel, anEntry);
1173 return GetSComponent(anEntry);
1176 //============================================================================
1177 /*! Function : GetSObject
1180 //============================================================================
1181 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TCollection_AsciiString& theEntry)
1183 Handle(SALOMEDSImpl_SObject) aSO;
1184 if(_mapOfSO.IsBound(theEntry))
1185 aSO = Handle(SALOMEDSImpl_SObject)::DownCast(_mapOfSO.Find(theEntry));
1188 TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1189 aSO = new SALOMEDSImpl_SObject(aLabel);
1190 _mapOfSO.Bind(theEntry, aSO);
1196 //============================================================================
1197 /*! Function : GetSObject
1200 //============================================================================
1201 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TDF_Label& theLabel)
1203 TCollection_AsciiString anEntry;
1204 TDF_Tool::Entry(theLabel, anEntry);
1205 return GetSObject(anEntry);
1208 //============================================================================
1209 /*! Function : GetAttribute
1212 //============================================================================
1213 Handle(TDF_Attribute) SALOMEDSImpl_Study::GetAttribute(const TCollection_AsciiString& theEntry,
1214 const TCollection_AsciiString& theType)
1216 Handle(SALOMEDSImpl_SObject) aSO = GetSObject(theEntry);
1217 Handle(TDF_Attribute) anAttr;
1218 aSO->FindAttribute(anAttr, theType);
1222 //============================================================================
1223 /*! Function : DumpStudy
1226 //============================================================================
1227 bool SALOMEDSImpl_Study::DumpStudy(const TCollection_AsciiString& thePath,
1228 const TCollection_AsciiString& theBaseName,
1230 SALOMEDSImpl_DriverFactory* theFactory)
1234 if(theFactory == NULL) {
1235 _errorCode = "Null factory for creation of Engines";
1239 TColStd_SequenceOfExtendedString aSeq;
1240 TCollection_AsciiString aCompType, aFactoryType;
1242 //Build a list of all components in the Study
1243 SALOMEDSImpl_SComponentIterator itcomponent = NewComponentIterator();
1245 for (; itcomponent.More(); itcomponent.Next()) {
1246 Handle(SALOMEDSImpl_SComponent) sco = itcomponent.Value();
1247 aCompType = sco->ComponentDataType();
1248 //GEOM and MED are independent components
1249 if(aCompType == "GEOM" || aCompType == "MED") aSeq.Prepend(TCollection_ExtendedString(aCompType));
1250 else aSeq.Append(TCollection_ExtendedString(aCompType));
1254 TCollection_AsciiString aFileName=thePath+TCollection_AsciiString("\\")+theBaseName+TCollection_AsciiString(".py");
1256 TCollection_AsciiString aFileName=thePath+TCollection_AsciiString("/")+theBaseName+TCollection_AsciiString(".py");
1259 //Create a file that will contain a main Study script
1261 fp.open(aFileName.ToCString(), ios::out);
1264 bool isOpened = fp.is_open();
1266 bool isOpened = fp.rdbuf()->is_open();
1270 _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1274 TCollection_AsciiString aBatchModeScript = "salome";
1276 //Output to the main Study script required Python modules import, set sys.path and add a creation of the study.
1277 fp << GetDumpStudyComment().ToCString() << endl << endl;
1278 fp << "import sys" << endl;
1279 fp << "import " << aBatchModeScript << "\n" << endl;
1280 fp << "sys.path.insert( 0, \'" << thePath << "\')\n" << endl;
1282 Handle(TColStd_HSequenceOfAsciiString) aSeqOfFileNames = new TColStd_HSequenceOfAsciiString;
1284 //Iterate all components and create the componponents specific scripts.
1286 int aLength = aSeq.Length();
1287 for(int i = 1; i <= aLength; i++) {
1289 aCompType = aSeq.Value(i);
1290 Handle(SALOMEDSImpl_SComponent) sco = FindComponent(aCompType);
1291 SALOMEDSImpl_Driver* aDriver = NULL;
1292 // if there is an associated Engine call its method for saving
1293 TCollection_AsciiString IOREngine;
1295 if (!sco->ComponentIOR(IOREngine)) {
1296 if (!aCompType.IsEmpty()) {
1298 aDriver = theFactory->GetDriverByType(aCompType);
1300 if (aDriver != NULL) {
1301 Handle(SALOMEDSImpl_StudyBuilder) SB = NewBuilder();
1302 cout << "Before SB" << endl;
1303 if(!SB->LoadWith(sco, aDriver)) {
1304 _errorCode = SB->GetErrorCode();
1307 cout << "After SB" << endl;
1313 aDriver = theFactory->GetDriverByIOR(IOREngine);
1316 _errorCode = "Can not restore information to dump it";
1320 if(aDriver == NULL) continue;
1323 long aStreamLength = 0;
1324 unsigned char* aStream = aDriver->DumpPython(this, isPublished, isValidScript, aStreamLength);
1325 if ( !isValidScript )
1328 //Create a file that will contain the component specific script
1331 aFileName=thePath+TCollection_AsciiString("\\");
1333 aFileName=thePath+TCollection_AsciiString("/");
1335 TCollection_AsciiString aScriptName;
1336 aScriptName += theBaseName;
1338 aScriptName += aCompType;
1340 aFileName += aScriptName+ TCollection_AsciiString(".py");
1341 aSeqOfFileNames->Append(aFileName);
1343 fp2.open(aFileName.ToCString(), ios::out);
1346 isOpened = fp.is_open();
1348 isOpened = fp.rdbuf()->is_open();
1352 _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1353 SALOMEDSImpl_Tool::RemoveTemporaryFiles(thePath, aSeqOfFileNames, false);
1357 //Output the Python script generated by the component in the newly created file.
1361 //Add to the main script a call to RebuildData of the generated by the component the Python script
1362 fp << "import " << aScriptName << endl;
1363 fp << aScriptName << ".RebuildData(" << aBatchModeScript << ".myStudy)" << endl;
1366 fp << "salome.sg.updateObjBrowser(1)" << endl;
1372 //=======================================================================
1373 //function : GetDumpStudyComment
1374 //purpose : return a header comment for a DumpStudy script
1375 //=======================================================================
1377 TCollection_AsciiString SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
1379 TCollection_AsciiString txt
1380 ("### This file is generated by SALOME automatically by dump python functionality");
1381 if ( theComponentName )
1382 txt += TCollection_AsciiString(" of ") + (char*) theComponentName + " component";
1386 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1388 const TCollection_AsciiString& Tab,
1389 const Handle(SALOMEDSImpl_Study) theStudy);
1390 //============================================================================
1394 //============================================================================
1395 void SALOMEDSImpl_Study::dump(const TCollection_AsciiString& theFileName)
1397 //Create a file that will contain a main Study script
1399 fp.open(theFileName.ToCString(), ios::out);
1402 bool isOpened = fp.is_open();
1404 bool isOpened = fp.rdbuf()->is_open();
1408 _errorCode = TCollection_AsciiString("Can't create a file ")+theFileName;
1409 cout << "### SALOMEDSImpl_Study::dump Error: " << _errorCode << endl;
1413 Handle(SALOMEDSImpl_SObject) aSO = FindObjectID("0:1");
1414 fp << "0:1" << endl;
1415 Handle(SALOMEDSImpl_ChildIterator) Itr = NewChildIterator(aSO);
1416 TCollection_AsciiString aTab(" ");
1417 for(; Itr->More(); Itr->Next()) {
1418 dumpSO(Itr->Value(), fp, aTab, this);
1425 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1427 const TCollection_AsciiString& Tab,
1428 const Handle(SALOMEDSImpl_Study) theStudy)
1430 TCollection_AsciiString aTab(Tab), anID(theSO->GetID());
1431 fp << aTab << anID << endl;
1432 TDF_AttributeIterator anItr(theSO->GetLabel());
1433 for(; anItr.More(); anItr.Next()) {
1434 Handle(SALOMEDSImpl_GenericAttribute) anAttr = Handle(SALOMEDSImpl_GenericAttribute)::DownCast(anItr.Value());
1436 if(anAttr.IsNull()) {
1437 fp << Tab << " -- " << anItr.Value()->DynamicType();
1441 TCollection_AsciiString aType = anAttr->GetClassType();
1442 fp << Tab << " -- " << aType;
1444 if(aType == "AttributeReal") {
1445 fp << " : " << Handle(SALOMEDSImpl_AttributeReal)::DownCast(anAttr)->Value();
1447 else if(aType == "AttributeInteger") {
1448 fp << " : " << Handle(SALOMEDSImpl_AttributeInteger)::DownCast(anAttr)->Value();
1450 else if(aType == "AttributeName") {
1451 fp << " : " << Handle(SALOMEDSImpl_AttributeName)::DownCast(anAttr)->Value();
1453 else if(aType == "AttributeComment") {
1454 fp << " : " << Handle(SALOMEDSImpl_AttributeComment)::DownCast(anAttr)->Value();
1456 else if(aType == "AttributeReference") {
1457 fp << " : " << Handle(SALOMEDSImpl_AttributeReference)::DownCast(anAttr)->Save();
1462 Handle(SALOMEDSImpl_ChildIterator) Itr = theStudy->NewChildIterator(theSO);
1463 TCollection_AsciiString aNewTab(" ");
1465 for(; Itr->More(); Itr->Next()) {
1466 dumpSO(Itr->Value(), fp, aNewTab, theStudy);
1472 void SALOMEDSImpl_Study::Modify()