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 TCollection_AsciiString tmp(_URL);
806 char *aName = (char*)tmp.ToCString();
807 char *adr = strtok(aName, "/");
811 adr = strtok(NULL, "/");
817 //============================================================================
818 /*! Function : _FindObject
819 * Purpose : Find an Object with SALOMEDSImpl_Name = anObjectName
821 //============================================================================
822 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::_FindObject(const Handle(SALOMEDSImpl_SObject)& SO,
823 const TCollection_AsciiString& theObjectName,
826 if(SO.IsNull()) return NULL;
828 // Iterate on each objects and subobjects of the component
829 // If objectName find, stop the loop and get the object reference
830 Handle(SALOMEDSImpl_SObject) RefSO;
831 Handle(SALOMEDSImpl_AttributeName) anAttr;
833 TCollection_AsciiString soid = SO->GetID();
834 TDF_ChildIterator it(SO->GetLabel());
835 for (; it.More(); it.Next()){
838 if (it.Value().FindAttribute(SALOMEDSImpl_AttributeName::GetID(), anAttr))
840 TCollection_AsciiString Val(anAttr->Value());
841 if (Val == theObjectName)
843 RefSO = GetSObject(it.Value());
847 if (!_find) RefSO = _FindObject(GetSObject(it.Value()), theObjectName, _find);
853 //============================================================================
854 /*! Function : _FindObjectIOR
855 * Purpose : Find an Object with SALOMEDSImpl_IOR = anObjectIOR
857 //============================================================================
858 Handle(SALOMEDSImpl_SObject)
859 SALOMEDSImpl_Study::_FindObjectIOR(const Handle(SALOMEDSImpl_SObject)& SO,
860 const TCollection_AsciiString& theObjectIOR,
863 if(SO.IsNull()) return NULL;
865 // Iterate on each objects and subobjects of the component
866 // If objectName find, stop the loop and get the object reference
867 Handle(SALOMEDSImpl_SObject) RefSO, aSO;
868 Handle(SALOMEDSImpl_AttributeIOR) anAttr;
870 TDF_ChildIterator it(SO->GetLabel());
871 for (; it.More();it.Next()){
874 if (it.Value().FindAttribute(SALOMEDSImpl_AttributeIOR::GetID(), anAttr))
876 TCollection_AsciiString Val(anAttr->Value());
877 if (Val == theObjectIOR)
879 RefSO = GetSObject(it.Value());
883 aSO = GetSObject(it.Value());
884 if (!_find) RefSO = _FindObjectIOR(aSO, theObjectIOR, _find);
890 bool SALOMEDSImpl_Study::IsLocked()
893 return GetProperties()->IsLocked();
896 int SALOMEDSImpl_Study::StudyId()
902 void SALOMEDSImpl_Study::StudyId(int id)
908 void SALOMEDSImpl_Study::UpdateIORLabelMap(const TCollection_AsciiString& anIOR,const TCollection_AsciiString& anEntry)
912 char* anEn = (char*)anEntry.ToCString();
913 char* IOR = (char*)anIOR.ToCString();
914 TDF_Tool::Label(_doc->GetData(),anEn, aLabel, Standard_True);
915 if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
916 myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
919 Handle(SALOMEDSImpl_Study) SALOMEDSImpl_Study::GetStudy(const TDF_Label& theLabel)
921 Handle(SALOMEDSImpl_StudyHandle) Att;
922 if (theLabel.Root().FindAttribute(SALOMEDSImpl_StudyHandle::GetID(),Att)) {
923 return Att->GetHandle();
928 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::SObject(const TDF_Label& theLabel)
930 return GetStudy(theLabel)->GetSObject(theLabel);
933 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::SComponent(const TDF_Label& theLabel)
935 return GetStudy(theLabel)->GetSComponent(theLabel);
939 void SALOMEDSImpl_Study::IORUpdated(const Handle(SALOMEDSImpl_AttributeIOR)& theAttribute)
941 TCollection_AsciiString aString;
942 TDF_Tool::Entry(theAttribute->Label(), aString);
943 GetStudy(theAttribute->Label())->UpdateIORLabelMap(theAttribute->Value(), aString);
946 Handle(TColStd_HSequenceOfTransient) SALOMEDSImpl_Study::FindDependances(const Handle(SALOMEDSImpl_SObject)& anObject)
949 Handle(TColStd_HSequenceOfTransient) aSeq;
951 Handle(SALOMEDSImpl_AttributeTarget) aTarget;
952 if (anObject->GetLabel().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID(), aTarget)) {
953 return aTarget->Get();
960 Handle(SALOMEDSImpl_AttributeStudyProperties) SALOMEDSImpl_Study::GetProperties()
963 return SALOMEDSImpl_AttributeStudyProperties::Set(_doc->Main());
966 TCollection_AsciiString SALOMEDSImpl_Study::GetLastModificationDate()
969 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
971 Handle(TColStd_HSequenceOfExtendedString) aNames;
972 Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
973 aNames = aProp->GetUserNames();
974 aProp->GetModificationDates(aMinutes, aHours, aDays, aMonths, aYears);
976 int aLastIndex = aNames->Length();
978 sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays->Value(aLastIndex)),(int)(aMonths->Value(aLastIndex)),
979 (int)(aYears->Value(aLastIndex)), (int)(aHours->Value(aLastIndex)), (int)(aMinutes->Value(aLastIndex)));
980 TCollection_AsciiString aResStr(aResult);
984 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetModificationsDate()
987 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
989 Handle(TColStd_HSequenceOfExtendedString) aNames;
990 Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
991 aNames = aProp->GetUserNames();
992 aProp->GetModificationDates(aMinutes, aHours, aDays, aMonths, aYears);
994 int anIndex, aLength = aNames->Length();
995 Handle(TColStd_HSequenceOfAsciiString) aDates = new TColStd_HSequenceOfAsciiString;
997 for(anIndex = 2; anIndex <= aLength; anIndex++) {
999 sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays->Value(anIndex)), (int)(aMonths->Value(anIndex)),
1000 (int)(aYears->Value(anIndex)), (int)(aHours->Value(anIndex)), (int)(aMinutes->Value(anIndex)));
1001 aDates->Append(aDate);
1008 //============================================================================
1009 /*! Function : GetUseCaseBuilder
1010 * Purpose : Returns a UseCase builder
1012 //============================================================================
1013 Handle(SALOMEDSImpl_UseCaseBuilder) SALOMEDSImpl_Study::GetUseCaseBuilder()
1016 return _useCaseBuilder;
1020 //============================================================================
1021 /*! Function : Close
1024 //============================================================================
1025 void SALOMEDSImpl_Study::Close()
1028 Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1029 if(!anApp.IsNull()) anApp->Close(_doc);
1035 //============================================================================
1036 /*! Function : AddPostponed
1039 //============================================================================
1040 void SALOMEDSImpl_Study::AddPostponed(const TCollection_AsciiString& theIOR)
1043 if (!NewBuilder()->HasOpenCommand()) return;
1044 TCollection_AsciiString anIOR(theIOR);
1046 myPostponedIORs.Append(anIOR); // add prefix: deleted
1047 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1050 //============================================================================
1051 /*! Function : AddCreatedPostponed
1054 //============================================================================
1055 void SALOMEDSImpl_Study::AddCreatedPostponed(const TCollection_AsciiString& theIOR)
1058 if (!NewBuilder()->HasOpenCommand()) return;
1059 TCollection_AsciiString anIOR(theIOR);
1061 myPostponedIORs.Append(anIOR); // add prefix: created
1062 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1065 //============================================================================
1066 /*! Function : RemovePostponed
1069 //============================================================================
1070 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::RemovePostponed(const int theUndoLimit)
1077 int aUndoLimit = theUndoLimit;
1078 if (theUndoLimit < 0) aUndoLimit = 0;
1080 Handle(TColStd_HSequenceOfAsciiString) aSeq = new TColStd_HSequenceOfAsciiString;
1082 if (myNbUndos > 0) { // remove undone
1084 for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1085 anOld += myNbPostponed(anIndex);
1086 int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1088 for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1089 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1090 if (anIOR.Value(1) == 'c') {
1091 aSeq->Append(anIOR.Split(1).ToCString());
1094 if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1095 if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1100 if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1102 for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1103 anOld += myNbPostponed(anIndex);
1104 for(anIndex = 1; anIndex <= anOld; anIndex++) {
1105 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1106 if (anIOR.Value(1) == 'd') {
1107 aSeq->Append(anIOR.Split(1).ToCString());
1110 if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1111 myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1114 if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1115 TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDSImpl_AttributeIOR::GetID(), Standard_True);
1116 for(; anIter.More(); anIter.Next()) {
1117 Handle(SALOMEDSImpl_AttributeIOR) anAttr = Handle(SALOMEDSImpl_AttributeIOR)::DownCast(anIter.Value());
1118 aSeq->Append(anAttr->Value());
1120 } else myNbPostponed.Append(0);
1125 //============================================================================
1126 /*! Function : UndoPostponed
1129 //============================================================================
1130 void SALOMEDSImpl_Study::UndoPostponed(const int theWay)
1134 myNbUndos += theWay;
1135 // remove current postponed
1136 if (myNbPostponed.Last() > 0)
1137 myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1138 myNbPostponed(myNbPostponed.Length()) = 0;
1142 //============================================================================
1143 /*! Function : GetSComponent
1146 //============================================================================
1147 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TCollection_AsciiString& theEntry)
1149 Handle(SALOMEDSImpl_SComponent) aSCO;
1150 if(_mapOfSCO.IsBound(theEntry))
1151 aSCO = Handle(SALOMEDSImpl_SComponent)::DownCast(_mapOfSCO.Find(theEntry));
1154 TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1155 aSCO = new SALOMEDSImpl_SComponent(aLabel);
1156 _mapOfSCO.Bind(theEntry, aSCO);
1162 //============================================================================
1163 /*! Function : GetSComponent
1166 //============================================================================
1167 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TDF_Label& theLabel)
1169 TCollection_AsciiString anEntry;
1170 TDF_Tool::Entry(theLabel, anEntry);
1171 return GetSComponent(anEntry);
1174 //============================================================================
1175 /*! Function : GetSObject
1178 //============================================================================
1179 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TCollection_AsciiString& theEntry)
1181 Handle(SALOMEDSImpl_SObject) aSO;
1182 if(_mapOfSO.IsBound(theEntry))
1183 aSO = Handle(SALOMEDSImpl_SObject)::DownCast(_mapOfSO.Find(theEntry));
1186 TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1187 aSO = new SALOMEDSImpl_SObject(aLabel);
1188 _mapOfSO.Bind(theEntry, aSO);
1194 //============================================================================
1195 /*! Function : GetSObject
1198 //============================================================================
1199 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TDF_Label& theLabel)
1201 TCollection_AsciiString anEntry;
1202 TDF_Tool::Entry(theLabel, anEntry);
1203 return GetSObject(anEntry);
1206 //============================================================================
1207 /*! Function : GetAttribute
1210 //============================================================================
1211 Handle(TDF_Attribute) SALOMEDSImpl_Study::GetAttribute(const TCollection_AsciiString& theEntry,
1212 const TCollection_AsciiString& theType)
1214 Handle(SALOMEDSImpl_SObject) aSO = GetSObject(theEntry);
1215 Handle(TDF_Attribute) anAttr;
1216 aSO->FindAttribute(anAttr, theType);
1220 //============================================================================
1221 /*! Function : DumpStudy
1224 //============================================================================
1225 bool SALOMEDSImpl_Study::DumpStudy(const TCollection_AsciiString& thePath,
1226 const TCollection_AsciiString& theBaseName,
1228 SALOMEDSImpl_DriverFactory* theFactory)
1232 if(theFactory == NULL) {
1233 _errorCode = "Null factory for creation of Engines";
1237 TColStd_SequenceOfExtendedString aSeq;
1238 TCollection_AsciiString aCompType, aFactoryType;
1240 //Build a list of all components in the Study
1241 SALOMEDSImpl_SComponentIterator itcomponent = NewComponentIterator();
1243 for (; itcomponent.More(); itcomponent.Next()) {
1244 Handle(SALOMEDSImpl_SComponent) sco = itcomponent.Value();
1245 aCompType = sco->ComponentDataType();
1246 //GEOM and MED are independent components
1247 if(aCompType == "GEOM" || aCompType == "MED") aSeq.Prepend(TCollection_ExtendedString(aCompType));
1248 else aSeq.Append(TCollection_ExtendedString(aCompType));
1252 TCollection_AsciiString aFileName=thePath+TCollection_AsciiString("\\")+theBaseName+TCollection_AsciiString(".py");
1254 TCollection_AsciiString aFileName=thePath+TCollection_AsciiString("/")+theBaseName+TCollection_AsciiString(".py");
1257 //Create a file that will contain a main Study script
1259 fp.open(aFileName.ToCString(), ios::out);
1262 bool isOpened = fp.is_open();
1264 bool isOpened = fp.rdbuf()->is_open();
1268 _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1272 TCollection_AsciiString aBatchModeScript = "salome";
1274 //Output to the main Study script required Python modules import, set sys.path and add a creation of the study.
1275 fp << GetDumpStudyComment().ToCString() << endl << endl;
1276 fp << "import sys" << endl;
1277 fp << "import " << aBatchModeScript << "\n" << endl;
1278 fp << "sys.path.insert( 0, \'" << thePath << "\')\n" << endl;
1280 Handle(TColStd_HSequenceOfAsciiString) aSeqOfFileNames = new TColStd_HSequenceOfAsciiString;
1282 //Iterate all components and create the componponents specific scripts.
1284 int aLength = aSeq.Length();
1285 for(int i = 1; i <= aLength; i++) {
1287 aCompType = aSeq.Value(i);
1288 Handle(SALOMEDSImpl_SComponent) sco = FindComponent(aCompType);
1289 SALOMEDSImpl_Driver* aDriver = NULL;
1290 // if there is an associated Engine call its method for saving
1291 TCollection_AsciiString IOREngine;
1293 if (!sco->ComponentIOR(IOREngine)) {
1294 if (!aCompType.IsEmpty()) {
1296 aDriver = theFactory->GetDriverByType(aCompType);
1298 if (aDriver != NULL) {
1299 Handle(SALOMEDSImpl_StudyBuilder) SB = NewBuilder();
1300 cout << "Before SB" << endl;
1301 if(!SB->LoadWith(sco, aDriver)) {
1302 _errorCode = SB->GetErrorCode();
1305 cout << "After SB" << endl;
1311 aDriver = theFactory->GetDriverByIOR(IOREngine);
1314 _errorCode = "Can not restore information to dump it";
1318 if(aDriver == NULL) continue;
1321 long aStreamLength = 0;
1322 unsigned char* aStream = aDriver->DumpPython(this, isPublished, isValidScript, aStreamLength);
1323 if ( !isValidScript )
1326 //Create a file that will contain the component specific script
1329 aFileName=thePath+TCollection_AsciiString("\\");
1331 aFileName=thePath+TCollection_AsciiString("/");
1333 TCollection_AsciiString aScriptName;
1334 aScriptName += theBaseName;
1336 aScriptName += aCompType;
1338 aFileName += aScriptName+ TCollection_AsciiString(".py");
1339 aSeqOfFileNames->Append(aFileName);
1341 fp2.open(aFileName.ToCString(), ios::out);
1344 isOpened = fp.is_open();
1346 isOpened = fp.rdbuf()->is_open();
1350 _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1351 SALOMEDSImpl_Tool::RemoveTemporaryFiles(thePath, aSeqOfFileNames, false);
1355 //Output the Python script generated by the component in the newly created file.
1359 //Add to the main script a call to RebuildData of the generated by the component the Python script
1360 fp << "import " << aScriptName << endl;
1361 fp << aScriptName << ".RebuildData(" << aBatchModeScript << ".myStudy)" << endl;
1364 fp << "salome.sg.updateObjBrowser(1)" << endl;
1370 //=======================================================================
1371 //function : GetDumpStudyComment
1372 //purpose : return a header comment for a DumpStudy script
1373 //=======================================================================
1375 TCollection_AsciiString SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
1377 TCollection_AsciiString txt
1378 ("### This file is generated by SALOME automatically by dump python funcitonality");
1379 if ( theComponentName )
1380 txt += TCollection_AsciiString(" of ") + (char*) theComponentName + " component";
1384 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1386 const TCollection_AsciiString& Tab,
1387 const Handle(SALOMEDSImpl_Study) theStudy);
1388 //============================================================================
1392 //============================================================================
1393 void SALOMEDSImpl_Study::dump(const TCollection_AsciiString& theFileName)
1395 //Create a file that will contain a main Study script
1397 fp.open(theFileName.ToCString(), ios::out);
1400 bool isOpened = fp.is_open();
1402 bool isOpened = fp.rdbuf()->is_open();
1406 _errorCode = TCollection_AsciiString("Can't create a file ")+theFileName;
1407 cout << "### SALOMEDSImpl_Study::dump Error: " << _errorCode << endl;
1411 Handle(SALOMEDSImpl_SObject) aSO = FindObjectID("0:1");
1412 fp << "0:1" << endl;
1413 Handle(SALOMEDSImpl_ChildIterator) Itr = NewChildIterator(aSO);
1414 TCollection_AsciiString aTab(" ");
1415 for(; Itr->More(); Itr->Next()) {
1416 dumpSO(Itr->Value(), fp, aTab, this);
1423 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1425 const TCollection_AsciiString& Tab,
1426 const Handle(SALOMEDSImpl_Study) theStudy)
1428 TCollection_AsciiString aTab(Tab), anID(theSO->GetID());
1429 fp << aTab << anID << endl;
1430 TDF_AttributeIterator anItr(theSO->GetLabel());
1431 for(; anItr.More(); anItr.Next()) {
1432 Handle(SALOMEDSImpl_GenericAttribute) anAttr = Handle(SALOMEDSImpl_GenericAttribute)::DownCast(anItr.Value());
1434 if(anAttr.IsNull()) {
1435 fp << Tab << " -- " << anItr.Value()->DynamicType();
1439 TCollection_AsciiString aType = anAttr->GetClassType();
1440 fp << Tab << " -- " << aType;
1442 if(aType == "AttributeReal") {
1443 fp << " : " << Handle(SALOMEDSImpl_AttributeReal)::DownCast(anAttr)->Value();
1445 else if(aType == "AttributeInteger") {
1446 fp << " : " << Handle(SALOMEDSImpl_AttributeInteger)::DownCast(anAttr)->Value();
1448 else if(aType == "AttributeName") {
1449 fp << " : " << Handle(SALOMEDSImpl_AttributeName)::DownCast(anAttr)->Value();
1451 else if(aType == "AttributeComment") {
1452 fp << " : " << Handle(SALOMEDSImpl_AttributeComment)::DownCast(anAttr)->Value();
1454 else if(aType == "AttributeReference") {
1455 fp << " : " << Handle(SALOMEDSImpl_AttributeReference)::DownCast(anAttr)->Save();
1460 Handle(SALOMEDSImpl_ChildIterator) Itr = theStudy->NewChildIterator(theSO);
1461 TCollection_AsciiString aNewTab(" ");
1463 for(; Itr->More(); Itr->Next()) {
1464 dumpSO(Itr->Value(), fp, aNewTab, theStudy);
1470 void SALOMEDSImpl_Study::Modify()