1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/
20 // File : SALOMEDSImpl_Study.cxx
21 // Author : Sergey RUIN
25 #include "SALOMEDSImpl_Study.hxx"
29 #include <TColStd_SequenceOfExtendedString.hxx>
30 #include <TCollection_ExtendedString.hxx>
32 #include <TColStd_HSequenceOfAsciiString.hxx>
33 #include <TDocStd_Application.hxx>
34 #include <TDocStd_Owner.hxx>
35 #include <TDF_LabelList.hxx>
36 #include <TDF_ListIteratorOfLabelList.hxx>
37 #include <CDM_Document.hxx>
38 #include <CDM_Application.hxx>
39 #include <TDF_ChildIDIterator.hxx>
40 #include <TDF_ChildIterator.hxx>
41 #include <TDF_AttributeIterator.hxx>
43 #include "SALOMEDSImpl_ChildNodeIterator.hxx"
44 #include "SALOMEDSImpl_Attributes.hxx"
45 #include "SALOMEDSImpl_UseCaseIterator.hxx"
46 #include "SALOMEDSImpl_AttributeReference.hxx"
47 #include "SALOMEDSImpl_StudyHandle.hxx"
48 #include "SALOMEDSImpl_Tool.hxx"
50 IMPLEMENT_STANDARD_HANDLE( SALOMEDSImpl_Study, MMgt_TShared )
51 IMPLEMENT_STANDARD_RTTIEXT( SALOMEDSImpl_Study, MMgt_TShared )
53 #define DIRECTORYID 16661
54 #define FILELOCALID 26662
55 #define FILEID "FILE: "
57 //============================================================================
58 /*! Function : SALOMEDSImpl_Study
59 * Purpose : SALOMEDSImpl_Study constructor
61 //============================================================================
62 SALOMEDSImpl_Study::SALOMEDSImpl_Study(const Handle(TDocStd_Document)& doc,
63 const TCollection_AsciiString& study_name)
65 doc->SetUndoLimit(1); // mpv (IPAL9237): if there is no undo limit, operations mechanism couldn't work
72 myNbPostponed.Append(0);
75 _useCaseBuilder = new SALOMEDSImpl_UseCaseBuilder(_doc);
76 _builder = new SALOMEDSImpl_StudyBuilder(this);
77 _cb = new SALOMEDSImpl_Callback(_useCaseBuilder);
78 //Put on the root label a StudyHandle attribute to store the address of this object
79 //It will be used to retrieve the study object by TDF_Label that belongs to the study
80 SALOMEDSImpl_StudyHandle::Set(_doc->Main().Root(), this);
84 //============================================================================
85 /*! Function : ~SALOMEDSImpl_Study
86 * Purpose : SALOMEDSImpl_Study destructor
88 //============================================================================
89 SALOMEDSImpl_Study::~SALOMEDSImpl_Study()
92 //============================================================================
93 /*! Function : GetPersistentReference
94 * Purpose : Get persistent reference of study (idem URL())
96 //============================================================================
97 TCollection_AsciiString SALOMEDSImpl_Study::GetPersistentReference()
102 //============================================================================
103 /*! Function : GetTransientReference
104 * Purpose : Get IOR of the Study (registred in OCAF document in doc->Root)
106 //============================================================================
107 TCollection_AsciiString SALOMEDSImpl_Study::GetTransientReference()
110 TCollection_AsciiString IOR = "";
112 Handle(SALOMEDSImpl_AttributeIOR) Att;
113 TDF_Label _lab = _doc->GetData()->Root();
114 if (_lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID(),Att)) {
118 _errorCode = "IOR is empty";
124 void SALOMEDSImpl_Study::SetTransientReference(const TCollection_AsciiString& theIOR)
128 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
129 int aLocked = aProp->IsLocked();
130 if (aLocked) aProp->SetLocked(Standard_False);
132 // Assign the value of the IOR in the study->root
133 SALOMEDSImpl_AttributeIOR::Set(_doc->Main().Root(), theIOR);
135 if (aLocked) aProp->SetLocked(Standard_True);
138 //============================================================================
139 /*! Function : IsEmpty
140 * Purpose : Detect if study is empty
142 //============================================================================
143 bool SALOMEDSImpl_Study::IsEmpty()
146 if (_doc.IsNull()) return true;
147 return _doc->IsEmpty();
150 //============================================================================
151 /*! Function : FindComponent
152 * Purpose : Find a Component with ComponentDataType = aComponentName
154 //============================================================================
155 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::FindComponent (const TCollection_AsciiString& aComponentName)
159 TCollection_AsciiString name;
160 SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
161 Handle(SALOMEDSImpl_SComponent) compo;
163 for (; itcomp.More(); itcomp.Next()) {
164 Handle(SALOMEDSImpl_SComponent) SC = itcomp.Value();
165 name = SC->ComponentDataType();
166 if(aComponentName == name) {
174 _errorCode = "No component was found";
180 //============================================================================
181 /*! Function : FindComponentID
182 * Purpose : Find a Component from it's ID
184 //============================================================================
185 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::FindComponentID(const TCollection_AsciiString& aComponentID)
189 // Iterate on each components defined in the study
190 // Get the component ID and compare with aComponentID
192 TCollection_AsciiString ID;
193 Handle(SALOMEDSImpl_SComponent) compo;
195 SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
196 for (; itcomp.More(); itcomp.Next()) {
197 Handle(SALOMEDSImpl_SComponent) SC = itcomp.Value();
199 if(aComponentID == ID)
208 _errorCode = "No component was found";
215 //============================================================================
216 /*! Function : FindObject
217 * Purpose : Find an Object with SALOMEDSImpl_Name = anObjectName
219 //============================================================================
220 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObject(const TCollection_AsciiString& anObjectName)
224 // Iterate to all components defined in the study
225 // After testing the component name, iterate in all objects defined under
226 // components (function _FindObject)
228 Handle(SALOMEDSImpl_SObject) RefSO = NULL;
230 SALOMEDSImpl_SComponentIterator it = NewComponentIterator();
231 for (; it.More();it.Next()){
234 Handle(SALOMEDSImpl_SComponent) SC = it.Value();
235 if (SC->GetName() == anObjectName)
241 if (!_find) RefSO = _FindObject(SC, anObjectName, _find);
244 if(RefSO.IsNull()) _errorCode = "No object was found";
248 //============================================================================
249 /*! Function : FindObjectID
250 * Purpose : Find an Object with ID = anObjectID
252 //============================================================================
253 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectID(const TCollection_AsciiString& anObjectID)
257 // Convert aSO->GetID in TDF_Label.
259 TDF_Tool::Label(_doc->Main().Data(), anObjectID, Lab);
262 _errorCode = "No label was found by ID";
265 return GetSObject(Lab);
269 //============================================================================
270 /*! Function : CreateObjectID
271 * Purpose : Creates an Object with ID = anObjectID
273 //============================================================================
274 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::CreateObjectID(const TCollection_AsciiString& anObjectID)
278 // Convert aSO->GetID in TDF_Label.
280 TDF_Tool::Label(_doc->Main().Data(), anObjectID, Lab, Standard_True);
283 _errorCode = "Can not create a label";
286 return GetSObject(Lab);
290 //============================================================================
291 /*! Function : FindObjectByName
292 * Purpose : Find Objects with SALOMEDSImpl_Name = anObjectName in a Component
293 * : with ComponentDataType = aComponentName
295 //============================================================================
296 Handle(TColStd_HSequenceOfTransient) SALOMEDSImpl_Study::FindObjectByName(const TCollection_AsciiString& anObjectName,
297 const TCollection_AsciiString& aComponentName)
301 Handle(TColStd_HSequenceOfTransient) listSO = new TColStd_HSequenceOfTransient();
303 Handle(SALOMEDSImpl_SComponent) compo = FindComponent(aComponentName) ;
304 if ( compo.IsNull() ) {
305 _errorCode = "Can not find the component";
309 // Iterate on each object and subobject of the component
310 // If objectName is found add it to the list of SObjects
311 TCollection_AsciiString childName ;
313 TCollection_AsciiString compoId = compo->GetID();
314 Handle(SALOMEDSImpl_ChildIterator) it = NewChildIterator(compo);
315 for ( ; it->More(); it->Next() ) {
317 Handle(SALOMEDSImpl_SObject) CSO = it->Value();
318 if ( CSO->GetName() == anObjectName ) {
320 listSO->Append(CSO) ;
323 /* looks also for eventual children */
325 CSO = _FindObject( CSO, anObjectName, found ) ;
327 listSO->Append(CSO) ;
336 //============================================================================
337 /*! Function : FindObjectIOR
338 * Purpose : Find an Object with IOR = anObjectIOR
340 //============================================================================
341 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectIOR(const TCollection_AsciiString& anObjectIOR)
345 // firstly searching in the datamap for optimization
346 if (myIORLabels.IsBound(anObjectIOR)) {
347 Handle(SALOMEDSImpl_SObject) aResult = GetSObject(myIORLabels.Find(anObjectIOR));
348 // 11 oct 2002: forbidden attributes must be checked here
349 if (!aResult->GetLabel().IsAttribute(SALOMEDSImpl_AttributeIOR::GetID())) {
350 myIORLabels.UnBind(anObjectIOR);
354 // Iterate to all components defined in the study
355 // After testing the component name, iterate in all objects defined under
356 // components (function _FindObject)
358 Handle(SALOMEDSImpl_SObject) RefSO = NULL;
360 SALOMEDSImpl_SComponentIterator it = NewComponentIterator();
361 Handle(SALOMEDSImpl_SComponent) SC;
362 for (; it.More();it.Next()){
366 TCollection_AsciiString ior = SC->GetIOR();
369 if (ior == anObjectIOR)
376 RefSO = _FindObjectIOR(SC, anObjectIOR, _find);
380 if(RefSO.IsNull()) _errorCode = "No object was found";
384 //============================================================================
385 /*! Function : FindObjectByPath
386 * Purpose : Find an Object by its path = thePath
388 //============================================================================
389 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectByPath(const TCollection_AsciiString& thePath)
393 TCollection_AsciiString aPath(thePath), aToken;
394 Handle(SALOMEDSImpl_SObject) aSO = NULL;
395 int i = 1, aLength = aPath.Length();
396 bool isRelative = false;
398 if(aLength == 0) { //Empty path - return the current context
399 return GetSObject(_current);
402 if(aPath.Value(1) != '/') //Relative path
405 TDF_ChildIterator anIterator;
407 Handle(SALOMEDSImpl_AttributeName) anAttr;
410 if(_current.IsNull()) return NULL;
411 anIterator.Initialize(_current, Standard_False);
414 if(aPath.Length() == 1 && aPath.Value(1) == '/') { //Root
415 return GetSObject(_doc->Main());
417 anIterator.Initialize(_doc->Main(), Standard_False);
420 while(i <= aLength) {
422 aToken = aPath.Token("/", i);
423 if(aToken.Length() == 0) break;
425 for ( ; anIterator.More(); anIterator.Next() ) {
426 aLabel = anIterator.Value();
427 if(aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), anAttr)) {
428 if(anAttr->Value() == aToken) {
429 aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
430 if(aToken.Length() == 0) { //The searched label is found (no part of the path is left)
431 return GetSObject(aLabel);
434 anIterator.Initialize(aLabel, Standard_False);
443 if(aSO.IsNull()) _errorCode = "No object was found";
447 //============================================================================
448 /*! Function : GetObjectPath
451 //============================================================================
452 TCollection_AsciiString SALOMEDSImpl_Study::GetObjectPath(const Handle(SALOMEDSImpl_SObject)& theObject)
456 TCollection_AsciiString aPath("");
457 if(theObject.IsNull()) {
458 _errorCode = "Null object";
459 return aPath.ToCString();
462 TCollection_AsciiString aName = theObject->GetName();
463 if(!aName.IsEmpty() && aName != "" ) {
464 TCollection_AsciiString aValue((char*)aName.ToCString());
468 Handle(SALOMEDSImpl_SObject) aFather = theObject->GetFather();
469 if(!aFather.IsNull()) {
470 aName = aFather->GetName();
471 if(!aName.IsEmpty() && aName != "") {
472 aValue = (char*)GetObjectPath(aFather).ToCString();
473 aPath = aValue + aPath;
482 //============================================================================
483 /*! Function : GetObjectPathByIOR
486 //============================================================================
487 TCollection_AsciiString SALOMEDSImpl_Study::GetObjectPathByIOR(const TCollection_AsciiString& theIOR)
491 TCollection_AsciiString aPath;
492 Handle(SALOMEDSImpl_SObject) so = FindObjectIOR(theIOR);
494 _errorCode = "No SObject was found by IOR";
498 return GetObjectPath(so);
502 //============================================================================
503 /*! Function : SetContext
504 * Purpose : Sets the current context
506 //============================================================================
507 bool SALOMEDSImpl_Study::SetContext(const TCollection_AsciiString& thePath)
510 if(thePath.IsEmpty()) {
511 _errorCode = "InvalidPath";
515 TCollection_AsciiString aPath(thePath), aContext("");
516 bool isInvalid = false;
517 Handle(SALOMEDSImpl_SObject) aSO;
519 if(aPath.Value(1) != '/') { //Relative path
520 aContext = GetContext();
528 aSO = FindObjectByPath(aContext.ToCString());
534 if(isInvalid || aSO.IsNull()) {
535 _errorCode = "InvalidContext";
539 TDF_Label aLabel = aSO->GetLabel();
540 if(aLabel.IsNull()) {
541 _errorCode = "InvalidContext";
545 _current = aLabel; //Set the current context
550 //============================================================================
551 /*! Function : GetContext
552 * Purpose : Gets the current context
554 //============================================================================
555 TCollection_AsciiString SALOMEDSImpl_Study::GetContext()
559 if(_current.IsNull()) {
560 _errorCode = "InvaidContext";
563 Handle(SALOMEDSImpl_SObject) so = GetSObject(_current);
564 return GetObjectPath(so);
567 //============================================================================
568 /*! Function : GetObjectNames
569 * Purpose : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
571 //============================================================================
572 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetObjectNames(const TCollection_AsciiString& theContext)
576 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
578 if (theContext.IsEmpty()) {
579 if(_current.IsNull()) {
580 _errorCode = "InvalidContext";
585 TDF_Label aTmp = _current;
586 SetContext(theContext);
590 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
591 for(; anIter.More(); anIter.Next()) {
592 TDF_Label aLabel = anIter.Value();
593 Handle(SALOMEDSImpl_AttributeName) aName;
594 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
600 //============================================================================
601 /*! Function : GetDirectoryNames
602 * Purpose : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
604 //============================================================================
605 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetDirectoryNames(const TCollection_AsciiString& theContext)
609 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
611 if (theContext.IsEmpty()) {
612 if(_current.IsNull()) {
613 _errorCode = "InvalidContext";
618 TDF_Label aTmp = _current;
619 SetContext(theContext);
623 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
624 for(; anIter.More(); anIter.Next()) {
625 TDF_Label aLabel = anIter.Value();
626 Handle(SALOMEDSImpl_AttributeLocalID) anID;
627 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
628 if (anID->Value() == DIRECTORYID) {
629 Handle(SALOMEDSImpl_AttributeName) aName;
630 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) {
631 aResultSeq->Append(aName->Value());
640 //============================================================================
641 /*! Function : GetFileNames
642 * Purpose : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
644 //============================================================================
645 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetFileNames(const TCollection_AsciiString& theContext)
649 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
651 if (theContext.IsEmpty()) {
652 if(_current.IsNull()) {
653 _errorCode = "InvalidContext";
658 TDF_Label aTmp = _current;
659 SetContext(theContext);
663 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
664 for(; anIter.More(); anIter.Next()) {
665 TDF_Label aLabel = anIter.Value();
666 Handle(SALOMEDSImpl_AttributeLocalID) anID;
667 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
668 if (anID->Value() == FILELOCALID) {
669 Handle(SALOMEDSImpl_AttributePersistentRef) aName;
670 if(aLabel.FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID(), aName)) {
671 TCollection_ExtendedString aFileName = aName->Value();
672 if(aFileName.Length() > 0)
673 aResultSeq->Append(aFileName.Split(strlen(FILEID)));
682 //============================================================================
683 /*! Function : GetComponentNames
684 * Purpose : method to get all components names
686 //============================================================================
687 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetComponentNames(const TCollection_AsciiString& theContext)
691 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
692 TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
693 for(; anIter.More(); anIter.Next()) {
694 TDF_Label aLabel = anIter.Value();
695 Handle(SALOMEDSImpl_AttributeName) aName;
696 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
702 //============================================================================
703 /*! Function : NewChildIterator
704 * Purpose : Create a ChildIterator from an SObject
706 //============================================================================
707 Handle(SALOMEDSImpl_ChildIterator) SALOMEDSImpl_Study::NewChildIterator(const Handle(SALOMEDSImpl_SObject)& aSO)
710 return new SALOMEDSImpl_ChildIterator(aSO);
714 //============================================================================
715 /*! Function : NewComponentIterator
716 * Purpose : Create a SComponentIterator
718 //============================================================================
719 SALOMEDSImpl_SComponentIterator SALOMEDSImpl_Study::NewComponentIterator()
722 return SALOMEDSImpl_SComponentIterator(_doc);
726 //============================================================================
727 /*! Function : NewBuilder
728 * Purpose : Create a StudyBuilder
730 //============================================================================
731 Handle(SALOMEDSImpl_StudyBuilder) SALOMEDSImpl_Study::NewBuilder()
735 _builder->SetOnAddSObject(_cb);
736 _builder->SetOnRemoveSObject(_cb);
742 //============================================================================
744 * Purpose : get study name
746 //============================================================================
747 TCollection_AsciiString SALOMEDSImpl_Study::Name()
753 //============================================================================
755 * Purpose : set study name
757 //============================================================================
758 void SALOMEDSImpl_Study::Name(const TCollection_AsciiString& name)
764 //============================================================================
765 /*! Function : IsSaved
766 * Purpose : get if study has been saved
768 //============================================================================
769 bool SALOMEDSImpl_Study::IsSaved()
775 //============================================================================
776 /*! Function : IsSaved
777 * Purpose : set if study has been saved
779 //============================================================================
780 void SALOMEDSImpl_Study::IsSaved(bool save)
784 if(save) _doc->UnModify();
787 //============================================================================
788 /*! Function : IsModified
789 * Purpose : Detect if a Study has been modified since it has been saved
791 //============================================================================
792 bool SALOMEDSImpl_Study::IsModified()
796 // True if is modified
797 if (_doc->IsModified()) return true;
802 //============================================================================
804 * Purpose : get URL of the study (persistent reference of the study)
806 //============================================================================
807 TCollection_AsciiString SALOMEDSImpl_Study::URL()
813 //============================================================================
815 * Purpose : set URL of the study (persistent reference of the study)
817 //============================================================================
818 void SALOMEDSImpl_Study::URL(const TCollection_AsciiString& url)
823 /*jfa: Now name of SALOMEDS study will correspond to name of SalomeApp study
824 TCollection_AsciiString tmp(_URL);
826 char *aName = (char*)tmp.ToCString();
827 char *adr = strtok(aName, "/");
831 adr = strtok(NULL, "/");
838 //============================================================================
839 /*! Function : _FindObject
840 * Purpose : Find an Object with SALOMEDSImpl_Name = anObjectName
842 //============================================================================
843 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::_FindObject(const Handle(SALOMEDSImpl_SObject)& SO,
844 const TCollection_AsciiString& theObjectName,
847 if(SO.IsNull()) return NULL;
849 // Iterate on each objects and subobjects of the component
850 // If objectName find, stop the loop and get the object reference
851 Handle(SALOMEDSImpl_SObject) RefSO;
852 Handle(SALOMEDSImpl_AttributeName) anAttr;
854 TCollection_AsciiString soid = SO->GetID();
855 TDF_ChildIterator it(SO->GetLabel());
856 for (; it.More(); it.Next()){
859 if (it.Value().FindAttribute(SALOMEDSImpl_AttributeName::GetID(), anAttr))
861 TCollection_AsciiString Val(anAttr->Value());
862 if (Val == theObjectName)
864 RefSO = GetSObject(it.Value());
868 if (!_find) RefSO = _FindObject(GetSObject(it.Value()), theObjectName, _find);
874 //============================================================================
875 /*! Function : _FindObjectIOR
876 * Purpose : Find an Object with SALOMEDSImpl_IOR = anObjectIOR
878 //============================================================================
879 Handle(SALOMEDSImpl_SObject)
880 SALOMEDSImpl_Study::_FindObjectIOR(const Handle(SALOMEDSImpl_SObject)& SO,
881 const TCollection_AsciiString& theObjectIOR,
884 if(SO.IsNull()) return NULL;
886 // Iterate on each objects and subobjects of the component
887 // If objectName find, stop the loop and get the object reference
888 Handle(SALOMEDSImpl_SObject) RefSO, aSO;
889 Handle(SALOMEDSImpl_AttributeIOR) anAttr;
891 TDF_ChildIterator it(SO->GetLabel());
892 for (; it.More();it.Next()){
895 if (it.Value().FindAttribute(SALOMEDSImpl_AttributeIOR::GetID(), anAttr))
897 TCollection_AsciiString Val(anAttr->Value());
898 if (Val == theObjectIOR)
900 RefSO = GetSObject(it.Value());
904 aSO = GetSObject(it.Value());
905 if (!_find) RefSO = _FindObjectIOR(aSO, theObjectIOR, _find);
911 bool SALOMEDSImpl_Study::IsLocked()
914 return GetProperties()->IsLocked();
917 int SALOMEDSImpl_Study::StudyId()
923 void SALOMEDSImpl_Study::StudyId(int id)
929 void SALOMEDSImpl_Study::UpdateIORLabelMap(const TCollection_AsciiString& anIOR,const TCollection_AsciiString& anEntry)
933 char* anEn = (char*)anEntry.ToCString();
934 char* IOR = (char*)anIOR.ToCString();
935 TDF_Tool::Label(_doc->GetData(),anEn, aLabel, Standard_True);
936 if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
937 myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
940 Handle(SALOMEDSImpl_Study) SALOMEDSImpl_Study::GetStudy(const TDF_Label& theLabel)
942 Handle(SALOMEDSImpl_StudyHandle) Att;
943 if (theLabel.Root().FindAttribute(SALOMEDSImpl_StudyHandle::GetID(),Att)) {
944 return Att->GetHandle();
949 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::SObject(const TDF_Label& theLabel)
951 return GetStudy(theLabel)->GetSObject(theLabel);
954 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::SComponent(const TDF_Label& theLabel)
956 return GetStudy(theLabel)->GetSComponent(theLabel);
960 void SALOMEDSImpl_Study::IORUpdated(const Handle(SALOMEDSImpl_AttributeIOR)& theAttribute)
962 TCollection_AsciiString aString;
963 TDF_Tool::Entry(theAttribute->Label(), aString);
964 GetStudy(theAttribute->Label())->UpdateIORLabelMap(theAttribute->Value(), aString);
967 Handle(TColStd_HSequenceOfTransient) SALOMEDSImpl_Study::FindDependances(const Handle(SALOMEDSImpl_SObject)& anObject)
970 Handle(TColStd_HSequenceOfTransient) aSeq;
972 Handle(SALOMEDSImpl_AttributeTarget) aTarget;
973 if (anObject->GetLabel().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID(), aTarget)) {
974 return aTarget->Get();
981 Handle(SALOMEDSImpl_AttributeStudyProperties) SALOMEDSImpl_Study::GetProperties()
984 return SALOMEDSImpl_AttributeStudyProperties::Set(_doc->Main());
987 TCollection_AsciiString SALOMEDSImpl_Study::GetLastModificationDate()
990 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
992 Handle(TColStd_HSequenceOfExtendedString) aNames;
993 Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
994 aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
996 int aLastIndex = aNames->Length();
998 sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
999 (int)(aDays->Value(aLastIndex)),(int)(aMonths->Value(aLastIndex)), (int)(aYears->Value(aLastIndex)),
1000 (int)(aHours->Value(aLastIndex)), (int)(aMinutes->Value(aLastIndex)));
1001 TCollection_AsciiString aResStr (aResult);
1005 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetModificationsDate()
1008 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
1010 Handle(TColStd_HSequenceOfExtendedString) aNames;
1011 Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
1012 aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
1014 int anIndex, aLength = aNames->Length();
1015 Handle(TColStd_HSequenceOfAsciiString) aDates = new TColStd_HSequenceOfAsciiString;
1017 for (anIndex = 2; anIndex <= aLength; anIndex++) {
1019 sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
1020 (int)(aDays->Value(anIndex)), (int)(aMonths->Value(anIndex)), (int)(aYears->Value(anIndex)),
1021 (int)(aHours->Value(anIndex)), (int)(aMinutes->Value(anIndex)));
1022 aDates->Append(aDate);
1029 //============================================================================
1030 /*! Function : GetUseCaseBuilder
1031 * Purpose : Returns a UseCase builder
1033 //============================================================================
1034 Handle(SALOMEDSImpl_UseCaseBuilder) SALOMEDSImpl_Study::GetUseCaseBuilder()
1037 return _useCaseBuilder;
1041 //============================================================================
1042 /*! Function : Close
1045 //============================================================================
1046 void SALOMEDSImpl_Study::Close()
1049 Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1050 if(!anApp.IsNull()) anApp->Close(_doc);
1056 //============================================================================
1057 /*! Function : AddPostponed
1060 //============================================================================
1061 void SALOMEDSImpl_Study::AddPostponed(const TCollection_AsciiString& theIOR)
1064 if (!NewBuilder()->HasOpenCommand()) return;
1065 TCollection_AsciiString anIOR(theIOR);
1067 myPostponedIORs.Append(anIOR); // add prefix: deleted
1068 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1071 //============================================================================
1072 /*! Function : AddCreatedPostponed
1075 //============================================================================
1076 void SALOMEDSImpl_Study::AddCreatedPostponed(const TCollection_AsciiString& theIOR)
1079 if (!NewBuilder()->HasOpenCommand()) return;
1080 TCollection_AsciiString anIOR(theIOR);
1082 myPostponedIORs.Append(anIOR); // add prefix: created
1083 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1086 //============================================================================
1087 /*! Function : RemovePostponed
1090 //============================================================================
1091 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::RemovePostponed(const int theUndoLimit)
1098 int aUndoLimit = theUndoLimit;
1099 if (theUndoLimit < 0) aUndoLimit = 0;
1101 Handle(TColStd_HSequenceOfAsciiString) aSeq = new TColStd_HSequenceOfAsciiString;
1103 if (myNbUndos > 0) { // remove undone
1105 for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1106 anOld += myNbPostponed(anIndex);
1107 int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1109 for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1110 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1111 if (anIOR.Value(1) == 'c') {
1112 aSeq->Append(anIOR.Split(1).ToCString());
1115 if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1116 if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1121 if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1123 for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1124 anOld += myNbPostponed(anIndex);
1125 for(anIndex = 1; anIndex <= anOld; anIndex++) {
1126 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1127 if (anIOR.Value(1) == 'd') {
1128 aSeq->Append(anIOR.Split(1).ToCString());
1131 if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1132 myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1135 if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1136 TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDSImpl_AttributeIOR::GetID(), Standard_True);
1137 for(; anIter.More(); anIter.Next()) {
1138 Handle(SALOMEDSImpl_AttributeIOR) anAttr = Handle(SALOMEDSImpl_AttributeIOR)::DownCast(anIter.Value());
1139 aSeq->Append(anAttr->Value());
1141 } else myNbPostponed.Append(0);
1146 //============================================================================
1147 /*! Function : UndoPostponed
1150 //============================================================================
1151 void SALOMEDSImpl_Study::UndoPostponed(const int theWay)
1155 myNbUndos += theWay;
1156 // remove current postponed
1157 if (myNbPostponed.Last() > 0)
1158 myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1159 myNbPostponed(myNbPostponed.Length()) = 0;
1163 //============================================================================
1164 /*! Function : GetSComponent
1167 //============================================================================
1168 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TCollection_AsciiString& theEntry)
1170 Handle(SALOMEDSImpl_SComponent) aSCO;
1171 if(_mapOfSCO.IsBound(theEntry))
1172 aSCO = Handle(SALOMEDSImpl_SComponent)::DownCast(_mapOfSCO.Find(theEntry));
1175 TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1176 aSCO = new SALOMEDSImpl_SComponent(aLabel);
1177 _mapOfSCO.Bind(theEntry, aSCO);
1183 //============================================================================
1184 /*! Function : GetSComponent
1187 //============================================================================
1188 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TDF_Label& theLabel)
1190 TCollection_AsciiString anEntry;
1191 TDF_Tool::Entry(theLabel, anEntry);
1192 return GetSComponent(anEntry);
1195 //============================================================================
1196 /*! Function : GetSObject
1199 //============================================================================
1200 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TCollection_AsciiString& theEntry)
1202 Handle(SALOMEDSImpl_SObject) aSO;
1203 if(_mapOfSO.IsBound(theEntry))
1204 aSO = Handle(SALOMEDSImpl_SObject)::DownCast(_mapOfSO.Find(theEntry));
1207 TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1208 aSO = new SALOMEDSImpl_SObject(aLabel);
1209 _mapOfSO.Bind(theEntry, aSO);
1215 //============================================================================
1216 /*! Function : GetSObject
1219 //============================================================================
1220 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TDF_Label& theLabel)
1222 TCollection_AsciiString anEntry;
1223 TDF_Tool::Entry(theLabel, anEntry);
1224 return GetSObject(anEntry);
1227 //============================================================================
1228 /*! Function : GetAttribute
1231 //============================================================================
1232 Handle(TDF_Attribute) SALOMEDSImpl_Study::GetAttribute(const TCollection_AsciiString& theEntry,
1233 const TCollection_AsciiString& theType)
1235 Handle(SALOMEDSImpl_SObject) aSO = GetSObject(theEntry);
1236 Handle(TDF_Attribute) anAttr;
1237 aSO->FindAttribute(anAttr, theType);
1241 //============================================================================
1242 /*! Function : DumpStudy
1245 //============================================================================
1246 bool SALOMEDSImpl_Study::DumpStudy(const TCollection_AsciiString& thePath,
1247 const TCollection_AsciiString& theBaseName,
1249 SALOMEDSImpl_DriverFactory* theFactory)
1253 if(theFactory == NULL) {
1254 _errorCode = "Null factory for creation of Engines";
1258 TColStd_SequenceOfExtendedString aSeq;
1259 TCollection_AsciiString aCompType, aFactoryType;
1261 //Build a list of all components in the Study
1262 SALOMEDSImpl_SComponentIterator itcomponent = NewComponentIterator();
1264 for (; itcomponent.More(); itcomponent.Next()) {
1265 Handle(SALOMEDSImpl_SComponent) sco = itcomponent.Value();
1266 aCompType = sco->ComponentDataType();
1267 //GEOM and MED are independent components
1268 if (aCompType == "GEOM" || aCompType == "MED")
1269 aSeq.Prepend(TCollection_ExtendedString(aCompType));
1271 aSeq.Append(TCollection_ExtendedString(aCompType));
1275 TCollection_AsciiString aFileName =
1276 thePath + TCollection_AsciiString("\\") + theBaseName + TCollection_AsciiString(".py");
1278 TCollection_AsciiString aFileName =
1279 thePath + TCollection_AsciiString("/") + theBaseName + TCollection_AsciiString(".py");
1282 //Create a file that will contain a main Study script
1284 fp.open(aFileName.ToCString(), ios::out);
1287 bool isOpened = fp.is_open();
1289 bool isOpened = fp.rdbuf()->is_open();
1293 _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1297 TCollection_AsciiString aBatchModeScript = "salome";
1299 //Output to the main Study script required Python modules import,
1300 //set sys.path and add a creation of the study.
1301 fp << GetDumpStudyComment().ToCString() << endl << endl;
1302 fp << "import sys" << endl;
1303 fp << "import " << aBatchModeScript << "\n" << endl;
1304 fp << "sys.path.insert( 0, \'" << thePath << "\')\n" << endl;
1306 Handle(TColStd_HSequenceOfAsciiString) aSeqOfFileNames = new TColStd_HSequenceOfAsciiString;
1308 //Iterate all components and create the componponents specific scripts.
1310 int aLength = aSeq.Length();
1311 for(int i = 1; i <= aLength; i++) {
1313 aCompType = aSeq.Value(i);
1314 Handle(SALOMEDSImpl_SComponent) sco = FindComponent(aCompType);
1315 SALOMEDSImpl_Driver* aDriver = NULL;
1316 // if there is an associated Engine call its method for saving
1317 TCollection_AsciiString IOREngine;
1319 if (!sco->ComponentIOR(IOREngine)) {
1320 if (!aCompType.IsEmpty()) {
1322 aDriver = theFactory->GetDriverByType(aCompType);
1324 if (aDriver != NULL) {
1325 Handle(SALOMEDSImpl_StudyBuilder) SB = NewBuilder();
1326 cout << "Before SB" << endl;
1327 if(!SB->LoadWith(sco, aDriver)) {
1328 _errorCode = SB->GetErrorCode();
1331 cout << "After SB" << endl;
1337 aDriver = theFactory->GetDriverByIOR(IOREngine);
1340 _errorCode = "Can not restore information to dump it";
1344 if(aDriver == NULL) continue;
1347 long aStreamLength = 0;
1348 unsigned char* aStream = aDriver->DumpPython(this, isPublished, isValidScript, aStreamLength);
1349 if ( !isValidScript )
1352 //Create a file that will contain the component specific script
1355 aFileName=thePath+TCollection_AsciiString("\\");
1357 aFileName=thePath+TCollection_AsciiString("/");
1359 TCollection_AsciiString aScriptName;
1360 aScriptName += theBaseName;
1362 aScriptName += aCompType;
1364 aFileName += aScriptName+ TCollection_AsciiString(".py");
1365 aSeqOfFileNames->Append(aFileName);
1367 fp2.open(aFileName.ToCString(), ios::out);
1370 isOpened = fp2.is_open();
1372 isOpened = fp2.rdbuf()->is_open();
1376 _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1377 SALOMEDSImpl_Tool::RemoveTemporaryFiles(thePath, aSeqOfFileNames, false);
1381 //Output the Python script generated by the component in the newly created file.
1385 if (aStream != NULL) delete [] aStream;
1387 //Add to the main script a call to RebuildData of the generated by the component the Python script
1388 fp << "import " << aScriptName << endl;
1389 fp << aScriptName << ".RebuildData(" << aBatchModeScript << ".myStudy)" << endl;
1392 fp << "salome.sg.updateObjBrowser(1)" << endl;
1398 //=======================================================================
1399 //function : GetDumpStudyComment
1400 //purpose : return a header comment for a DumpStudy script
1401 //=======================================================================
1403 TCollection_AsciiString SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
1405 TCollection_AsciiString txt
1406 ("### This file is generated by SALOME automatically by dump python functionality");
1407 if ( theComponentName )
1408 txt += TCollection_AsciiString(" of ") + (char*) theComponentName + " component";
1412 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1414 const TCollection_AsciiString& Tab,
1415 const Handle(SALOMEDSImpl_Study) theStudy);
1416 //============================================================================
1420 //============================================================================
1421 void SALOMEDSImpl_Study::dump(const TCollection_AsciiString& theFileName)
1423 //Create a file that will contain a main Study script
1425 fp.open(theFileName.ToCString(), ios::out);
1428 bool isOpened = fp.is_open();
1430 bool isOpened = fp.rdbuf()->is_open();
1434 _errorCode = TCollection_AsciiString("Can't create a file ")+theFileName;
1435 cout << "### SALOMEDSImpl_Study::dump Error: " << _errorCode << endl;
1439 Handle(SALOMEDSImpl_SObject) aSO = FindObjectID("0:1");
1440 fp << "0:1" << endl;
1441 Handle(SALOMEDSImpl_ChildIterator) Itr = NewChildIterator(aSO);
1442 TCollection_AsciiString aTab(" ");
1443 for(; Itr->More(); Itr->Next()) {
1444 dumpSO(Itr->Value(), fp, aTab, this);
1451 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1453 const TCollection_AsciiString& Tab,
1454 const Handle(SALOMEDSImpl_Study) theStudy)
1456 TCollection_AsciiString aTab(Tab), anID(theSO->GetID());
1457 fp << aTab << anID << endl;
1458 TDF_AttributeIterator anItr(theSO->GetLabel());
1459 for(; anItr.More(); anItr.Next()) {
1460 Handle(SALOMEDSImpl_GenericAttribute) anAttr = Handle(SALOMEDSImpl_GenericAttribute)::DownCast(anItr.Value());
1462 if(anAttr.IsNull()) {
1463 fp << Tab << " -- " << anItr.Value()->DynamicType();
1467 TCollection_AsciiString aType = anAttr->GetClassType();
1468 fp << Tab << " -- " << aType;
1470 if(aType == "AttributeReal") {
1471 fp << " : " << Handle(SALOMEDSImpl_AttributeReal)::DownCast(anAttr)->Value();
1473 else if(aType == "AttributeInteger") {
1474 fp << " : " << Handle(SALOMEDSImpl_AttributeInteger)::DownCast(anAttr)->Value();
1476 else if(aType == "AttributeName") {
1477 fp << " : " << Handle(SALOMEDSImpl_AttributeName)::DownCast(anAttr)->Value();
1479 else if(aType == "AttributeComment") {
1480 fp << " : " << Handle(SALOMEDSImpl_AttributeComment)::DownCast(anAttr)->Value();
1482 else if(aType == "AttributeReference") {
1483 fp << " : " << Handle(SALOMEDSImpl_AttributeReference)::DownCast(anAttr)->Save();
1488 Handle(SALOMEDSImpl_ChildIterator) Itr = theStudy->NewChildIterator(theSO);
1489 TCollection_AsciiString aNewTab(" ");
1491 for(; Itr->More(); Itr->Next()) {
1492 dumpSO(Itr->Value(), fp, aNewTab, theStudy);
1498 void SALOMEDSImpl_Study::Modify()