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/ or email : webmaster.salome@opencascade.com
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"
49 #include "SALOMEDSImpl_IParameters.hxx"
51 IMPLEMENT_STANDARD_HANDLE( SALOMEDSImpl_Study, MMgt_TShared )
52 IMPLEMENT_STANDARD_RTTIEXT( SALOMEDSImpl_Study, MMgt_TShared )
54 #define DIRECTORYID 16661
55 #define FILELOCALID 26662
56 #define FILEID "FILE: "
58 //============================================================================
59 /*! Function : SALOMEDSImpl_Study
60 * Purpose : SALOMEDSImpl_Study constructor
62 //============================================================================
63 SALOMEDSImpl_Study::SALOMEDSImpl_Study(const Handle(TDocStd_Document)& doc,
64 const TCollection_AsciiString& study_name)
66 doc->SetUndoLimit(1); // mpv (IPAL9237): if there is no undo limit, operations mechanism couldn't work
73 myNbPostponed.Append(0);
76 _useCaseBuilder = new SALOMEDSImpl_UseCaseBuilder(_doc);
77 _builder = new SALOMEDSImpl_StudyBuilder(this);
78 _cb = new SALOMEDSImpl_Callback(_useCaseBuilder);
79 //Put on the root label a StudyHandle attribute to store the address of this object
80 //It will be used to retrieve the study object by TDF_Label that belongs to the study
81 SALOMEDSImpl_StudyHandle::Set(_doc->Main().Root(), this);
85 //============================================================================
86 /*! Function : ~SALOMEDSImpl_Study
87 * Purpose : SALOMEDSImpl_Study destructor
89 //============================================================================
90 SALOMEDSImpl_Study::~SALOMEDSImpl_Study()
93 //============================================================================
94 /*! Function : GetPersistentReference
95 * Purpose : Get persistent reference of study (idem URL())
97 //============================================================================
98 TCollection_AsciiString SALOMEDSImpl_Study::GetPersistentReference()
103 //============================================================================
104 /*! Function : GetTransientReference
105 * Purpose : Get IOR of the Study (registred in OCAF document in doc->Root)
107 //============================================================================
108 TCollection_AsciiString SALOMEDSImpl_Study::GetTransientReference()
111 TCollection_AsciiString IOR = "";
113 Handle(SALOMEDSImpl_AttributeIOR) Att;
114 TDF_Label _lab = _doc->GetData()->Root();
115 if (_lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID(),Att)) {
119 _errorCode = "IOR is empty";
125 void SALOMEDSImpl_Study::SetTransientReference(const TCollection_AsciiString& theIOR)
129 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
130 int aLocked = aProp->IsLocked();
131 if (aLocked) aProp->SetLocked(Standard_False);
133 // Assign the value of the IOR in the study->root
134 SALOMEDSImpl_AttributeIOR::Set(_doc->Main().Root(), theIOR);
136 if (aLocked) aProp->SetLocked(Standard_True);
139 //============================================================================
140 /*! Function : IsEmpty
141 * Purpose : Detect if study is empty
143 //============================================================================
144 bool SALOMEDSImpl_Study::IsEmpty()
147 if (_doc.IsNull()) return true;
148 return _doc->IsEmpty();
151 //============================================================================
152 /*! Function : FindComponent
153 * Purpose : Find a Component with ComponentDataType = aComponentName
155 //============================================================================
156 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::FindComponent (const TCollection_AsciiString& aComponentName)
160 TCollection_AsciiString name;
161 SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
162 Handle(SALOMEDSImpl_SComponent) compo;
164 for (; itcomp.More(); itcomp.Next()) {
165 Handle(SALOMEDSImpl_SComponent) SC = itcomp.Value();
166 name = SC->ComponentDataType();
167 if(aComponentName == name) {
175 _errorCode = "No component was found";
181 //============================================================================
182 /*! Function : FindComponentID
183 * Purpose : Find a Component from it's ID
185 //============================================================================
186 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::FindComponentID(const TCollection_AsciiString& aComponentID)
190 // Iterate on each components defined in the study
191 // Get the component ID and compare with aComponentID
193 TCollection_AsciiString ID;
194 Handle(SALOMEDSImpl_SComponent) compo;
196 SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
197 for (; itcomp.More(); itcomp.Next()) {
198 Handle(SALOMEDSImpl_SComponent) SC = itcomp.Value();
200 if(aComponentID == ID)
209 _errorCode = "No component was found";
216 //============================================================================
217 /*! Function : FindObject
218 * Purpose : Find an Object with SALOMEDSImpl_Name = anObjectName
220 //============================================================================
221 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObject(const TCollection_AsciiString& anObjectName)
225 // Iterate to all components defined in the study
226 // After testing the component name, iterate in all objects defined under
227 // components (function _FindObject)
229 Handle(SALOMEDSImpl_SObject) RefSO = NULL;
231 SALOMEDSImpl_SComponentIterator it = NewComponentIterator();
232 for (; it.More();it.Next()){
235 Handle(SALOMEDSImpl_SComponent) SC = it.Value();
236 if (SC->GetName() == anObjectName)
242 if (!_find) RefSO = _FindObject(SC, anObjectName, _find);
245 if(RefSO.IsNull()) _errorCode = "No object was found";
249 //============================================================================
250 /*! Function : FindObjectID
251 * Purpose : Find an Object with ID = anObjectID
253 //============================================================================
254 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectID(const TCollection_AsciiString& anObjectID)
258 // Convert aSO->GetID in TDF_Label.
260 TDF_Tool::Label(_doc->Main().Data(), anObjectID, Lab);
263 _errorCode = "No label was found by ID";
266 return GetSObject(Lab);
270 //============================================================================
271 /*! Function : CreateObjectID
272 * Purpose : Creates an Object with ID = anObjectID
274 //============================================================================
275 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::CreateObjectID(const TCollection_AsciiString& anObjectID)
279 // Convert aSO->GetID in TDF_Label.
281 TDF_Tool::Label(_doc->Main().Data(), anObjectID, Lab, Standard_True);
284 _errorCode = "Can not create a label";
287 return GetSObject(Lab);
291 //============================================================================
292 /*! Function : FindObjectByName
293 * Purpose : Find Objects with SALOMEDSImpl_Name = anObjectName in a Component
294 * : with ComponentDataType = aComponentName
296 //============================================================================
297 Handle(TColStd_HSequenceOfTransient) SALOMEDSImpl_Study::FindObjectByName(const TCollection_AsciiString& anObjectName,
298 const TCollection_AsciiString& aComponentName)
302 Handle(TColStd_HSequenceOfTransient) listSO = new TColStd_HSequenceOfTransient();
304 Handle(SALOMEDSImpl_SComponent) compo = FindComponent(aComponentName) ;
305 if ( compo.IsNull() ) {
306 _errorCode = "Can not find the component";
310 // Iterate on each object and subobject of the component
311 // If objectName is found add it to the list of SObjects
312 TCollection_AsciiString childName ;
314 TCollection_AsciiString compoId = compo->GetID();
315 Handle(SALOMEDSImpl_ChildIterator) it = NewChildIterator(compo);
316 for ( ; it->More(); it->Next() ) {
318 Handle(SALOMEDSImpl_SObject) CSO = it->Value();
319 if ( CSO->GetName() == anObjectName ) {
321 listSO->Append(CSO) ;
324 /* looks also for eventual children */
326 CSO = _FindObject( CSO, anObjectName, found ) ;
328 listSO->Append(CSO) ;
337 //============================================================================
338 /*! Function : FindObjectIOR
339 * Purpose : Find an Object with IOR = anObjectIOR
341 //============================================================================
342 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectIOR(const TCollection_AsciiString& anObjectIOR)
346 // firstly searching in the datamap for optimization
347 if (myIORLabels.IsBound(anObjectIOR)) {
348 Handle(SALOMEDSImpl_SObject) aResult = GetSObject(myIORLabels.Find(anObjectIOR));
349 // 11 oct 2002: forbidden attributes must be checked here
350 if (!aResult->GetLabel().IsAttribute(SALOMEDSImpl_AttributeIOR::GetID())) {
351 myIORLabels.UnBind(anObjectIOR);
355 // Iterate to all components defined in the study
356 // After testing the component name, iterate in all objects defined under
357 // components (function _FindObject)
359 Handle(SALOMEDSImpl_SObject) RefSO = NULL;
361 SALOMEDSImpl_SComponentIterator it = NewComponentIterator();
362 Handle(SALOMEDSImpl_SComponent) SC;
363 for (; it.More();it.Next()){
367 TCollection_AsciiString ior = SC->GetIOR();
370 if (ior == anObjectIOR)
377 RefSO = _FindObjectIOR(SC, anObjectIOR, _find);
381 if(RefSO.IsNull()) _errorCode = "No object was found";
385 //============================================================================
386 /*! Function : FindObjectByPath
387 * Purpose : Find an Object by its path = thePath
389 //============================================================================
390 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::FindObjectByPath(const TCollection_AsciiString& thePath)
394 TCollection_AsciiString aPath(thePath), aToken;
395 Handle(SALOMEDSImpl_SObject) aSO = NULL;
396 int i = 1, aLength = aPath.Length();
397 bool isRelative = false;
399 if(aLength == 0) { //Empty path - return the current context
400 return GetSObject(_current);
403 if(aPath.Value(1) != '/') //Relative path
406 TDF_ChildIterator anIterator;
408 Handle(SALOMEDSImpl_AttributeName) anAttr;
411 if(_current.IsNull()) return NULL;
412 anIterator.Initialize(_current, Standard_False);
415 if(aPath.Length() == 1 && aPath.Value(1) == '/') { //Root
416 return GetSObject(_doc->Main());
418 anIterator.Initialize(_doc->Main(), Standard_False);
421 while(i <= aLength) {
423 aToken = aPath.Token("/", i);
424 if(aToken.Length() == 0) break;
426 for ( ; anIterator.More(); anIterator.Next() ) {
427 aLabel = anIterator.Value();
428 if(aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), anAttr)) {
429 if(anAttr->Value() == aToken) {
430 aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
431 if(aToken.Length() == 0) { //The searched label is found (no part of the path is left)
432 return GetSObject(aLabel);
435 anIterator.Initialize(aLabel, Standard_False);
444 if(aSO.IsNull()) _errorCode = "No object was found";
448 //============================================================================
449 /*! Function : GetObjectPath
452 //============================================================================
453 TCollection_AsciiString SALOMEDSImpl_Study::GetObjectPath(const Handle(SALOMEDSImpl_SObject)& theObject)
457 TCollection_AsciiString aPath("");
458 if(theObject.IsNull()) {
459 _errorCode = "Null object";
460 return aPath.ToCString();
463 TCollection_AsciiString aName = theObject->GetName();
464 if(!aName.IsEmpty() && aName != "" ) {
465 TCollection_AsciiString aValue((char*)aName.ToCString());
469 Handle(SALOMEDSImpl_SObject) aFather = theObject->GetFather();
470 if(!aFather.IsNull()) {
471 aName = aFather->GetName();
472 if(!aName.IsEmpty() && aName != "") {
473 aValue = (char*)GetObjectPath(aFather).ToCString();
474 aPath = aValue + aPath;
483 //============================================================================
484 /*! Function : GetObjectPathByIOR
487 //============================================================================
488 TCollection_AsciiString SALOMEDSImpl_Study::GetObjectPathByIOR(const TCollection_AsciiString& theIOR)
492 TCollection_AsciiString aPath;
493 Handle(SALOMEDSImpl_SObject) so = FindObjectIOR(theIOR);
495 _errorCode = "No SObject was found by IOR";
499 return GetObjectPath(so);
503 //============================================================================
504 /*! Function : SetContext
505 * Purpose : Sets the current context
507 //============================================================================
508 bool SALOMEDSImpl_Study::SetContext(const TCollection_AsciiString& thePath)
511 if(thePath.IsEmpty()) {
512 _errorCode = "InvalidPath";
516 TCollection_AsciiString aPath(thePath), aContext("");
517 bool isInvalid = false;
518 Handle(SALOMEDSImpl_SObject) aSO;
520 if(aPath.Value(1) != '/') { //Relative path
521 aContext = GetContext();
529 aSO = FindObjectByPath(aContext.ToCString());
535 if(isInvalid || aSO.IsNull()) {
536 _errorCode = "InvalidContext";
540 TDF_Label aLabel = aSO->GetLabel();
541 if(aLabel.IsNull()) {
542 _errorCode = "InvalidContext";
546 _current = aLabel; //Set the current context
551 //============================================================================
552 /*! Function : GetContext
553 * Purpose : Gets the current context
555 //============================================================================
556 TCollection_AsciiString SALOMEDSImpl_Study::GetContext()
560 if(_current.IsNull()) {
561 _errorCode = "InvaidContext";
564 Handle(SALOMEDSImpl_SObject) so = GetSObject(_current);
565 return GetObjectPath(so);
568 //============================================================================
569 /*! Function : GetObjectNames
570 * Purpose : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
572 //============================================================================
573 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetObjectNames(const TCollection_AsciiString& theContext)
577 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
579 if (theContext.IsEmpty()) {
582 TDF_Label aTmp = _current;
583 SetContext(theContext);
587 if (aLabel.IsNull()) {
588 _errorCode = "InvalidContext";
592 TDF_ChildIterator anIter (aLabel, Standard_False); // iterate all subchildren at all sublevels
593 for (; anIter.More(); anIter.Next()) {
594 TDF_Label aLabel = anIter.Value();
595 Handle(SALOMEDSImpl_AttributeName) aName;
596 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
602 //============================================================================
603 /*! Function : GetDirectoryNames
604 * Purpose : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
606 //============================================================================
607 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetDirectoryNames(const TCollection_AsciiString& theContext)
611 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
613 if (theContext.IsEmpty()) {
616 TDF_Label aTmp = _current;
617 SetContext(theContext);
621 if (aLabel.IsNull()) {
622 _errorCode = "InvalidContext";
626 TDF_ChildIterator anIter (aLabel, Standard_False); // iterate first-level children at all sublevels
627 for (; anIter.More(); anIter.Next()) {
628 TDF_Label aLabel = anIter.Value();
629 Handle(SALOMEDSImpl_AttributeLocalID) anID;
630 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
631 if (anID->Value() == DIRECTORYID) {
632 Handle(SALOMEDSImpl_AttributeName) aName;
633 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) {
634 aResultSeq->Append(aName->Value());
643 //============================================================================
644 /*! Function : GetFileNames
645 * Purpose : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
647 //============================================================================
648 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetFileNames(const TCollection_AsciiString& theContext)
652 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
654 if (theContext.IsEmpty()) {
657 TDF_Label aTmp = _current;
658 SetContext(theContext);
662 if (aLabel.IsNull()) {
663 _errorCode = "InvalidContext";
667 TDF_ChildIterator anIter (aLabel, Standard_False); // iterate all subchildren at all sublevels
668 for (; anIter.More(); anIter.Next()) {
669 TDF_Label aLabel = anIter.Value();
670 Handle(SALOMEDSImpl_AttributeLocalID) anID;
671 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
672 if (anID->Value() == FILELOCALID) {
673 Handle(SALOMEDSImpl_AttributePersistentRef) aName;
674 if (aLabel.FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID(), aName)) {
675 TCollection_ExtendedString aFileName = aName->Value();
676 if (aFileName.Length() > 0)
677 aResultSeq->Append(aFileName.Split(strlen(FILEID)));
686 //============================================================================
687 /*! Function : GetComponentNames
688 * Purpose : method to get all components names
690 //============================================================================
691 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetComponentNames(const TCollection_AsciiString& theContext)
695 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
696 TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
697 for(; anIter.More(); anIter.Next()) {
698 TDF_Label aLabel = anIter.Value();
699 Handle(SALOMEDSImpl_AttributeName) aName;
700 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
706 //============================================================================
707 /*! Function : NewChildIterator
708 * Purpose : Create a ChildIterator from an SObject
710 //============================================================================
711 Handle(SALOMEDSImpl_ChildIterator) SALOMEDSImpl_Study::NewChildIterator(const Handle(SALOMEDSImpl_SObject)& aSO)
714 return new SALOMEDSImpl_ChildIterator(aSO);
718 //============================================================================
719 /*! Function : NewComponentIterator
720 * Purpose : Create a SComponentIterator
722 //============================================================================
723 SALOMEDSImpl_SComponentIterator SALOMEDSImpl_Study::NewComponentIterator()
726 return SALOMEDSImpl_SComponentIterator(_doc);
730 //============================================================================
731 /*! Function : NewBuilder
732 * Purpose : Create a StudyBuilder
734 //============================================================================
735 Handle(SALOMEDSImpl_StudyBuilder) SALOMEDSImpl_Study::NewBuilder()
739 _builder->SetOnAddSObject(_cb);
740 _builder->SetOnRemoveSObject(_cb);
746 //============================================================================
748 * Purpose : get study name
750 //============================================================================
751 TCollection_AsciiString SALOMEDSImpl_Study::Name()
757 //============================================================================
759 * Purpose : set study name
761 //============================================================================
762 void SALOMEDSImpl_Study::Name(const TCollection_AsciiString& name)
768 //============================================================================
769 /*! Function : IsSaved
770 * Purpose : get if study has been saved
772 //============================================================================
773 bool SALOMEDSImpl_Study::IsSaved()
779 //============================================================================
780 /*! Function : IsSaved
781 * Purpose : set if study has been saved
783 //============================================================================
784 void SALOMEDSImpl_Study::IsSaved(bool save)
788 if(save) _doc->UnModify();
791 //============================================================================
792 /*! Function : IsModified
793 * Purpose : Detect if a Study has been modified since it has been saved
795 //============================================================================
796 bool SALOMEDSImpl_Study::IsModified()
800 // True if is modified
801 if (_doc->IsModified()) return true;
806 //============================================================================
808 * Purpose : get URL of the study (persistent reference of the study)
810 //============================================================================
811 TCollection_AsciiString SALOMEDSImpl_Study::URL()
817 //============================================================================
819 * Purpose : set URL of the study (persistent reference of the study)
821 //============================================================================
822 void SALOMEDSImpl_Study::URL(const TCollection_AsciiString& url)
827 /*jfa: Now name of SALOMEDS study will correspond to name of SalomeApp study
828 TCollection_AsciiString tmp(_URL);
830 char *aName = (char*)tmp.ToCString();
831 char *adr = strtok(aName, "/");
835 adr = strtok(NULL, "/");
842 //============================================================================
843 /*! Function : _FindObject
844 * Purpose : Find an Object with SALOMEDSImpl_Name = anObjectName
846 //============================================================================
847 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::_FindObject(const Handle(SALOMEDSImpl_SObject)& SO,
848 const TCollection_AsciiString& theObjectName,
851 if(SO.IsNull()) return NULL;
853 // Iterate on each objects and subobjects of the component
854 // If objectName find, stop the loop and get the object reference
855 Handle(SALOMEDSImpl_SObject) RefSO;
856 Handle(SALOMEDSImpl_AttributeName) anAttr;
858 TCollection_AsciiString soid = SO->GetID();
859 TDF_ChildIterator it(SO->GetLabel());
860 for (; it.More(); it.Next()){
863 if (it.Value().FindAttribute(SALOMEDSImpl_AttributeName::GetID(), anAttr))
865 TCollection_AsciiString Val(anAttr->Value());
866 if (Val == theObjectName)
868 RefSO = GetSObject(it.Value());
872 if (!_find) RefSO = _FindObject(GetSObject(it.Value()), theObjectName, _find);
878 //============================================================================
879 /*! Function : _FindObjectIOR
880 * Purpose : Find an Object with SALOMEDSImpl_IOR = anObjectIOR
882 //============================================================================
883 Handle(SALOMEDSImpl_SObject)
884 SALOMEDSImpl_Study::_FindObjectIOR(const Handle(SALOMEDSImpl_SObject)& SO,
885 const TCollection_AsciiString& theObjectIOR,
888 if(SO.IsNull()) return NULL;
890 // Iterate on each objects and subobjects of the component
891 // If objectName find, stop the loop and get the object reference
892 Handle(SALOMEDSImpl_SObject) RefSO, aSO;
893 Handle(SALOMEDSImpl_AttributeIOR) anAttr;
895 TDF_ChildIterator it(SO->GetLabel());
896 for (; it.More();it.Next()){
899 if (it.Value().FindAttribute(SALOMEDSImpl_AttributeIOR::GetID(), anAttr))
901 TCollection_AsciiString Val(anAttr->Value());
902 if (Val == theObjectIOR)
904 RefSO = GetSObject(it.Value());
908 aSO = GetSObject(it.Value());
909 if (!_find) RefSO = _FindObjectIOR(aSO, theObjectIOR, _find);
915 bool SALOMEDSImpl_Study::IsLocked()
918 return GetProperties()->IsLocked();
921 int SALOMEDSImpl_Study::StudyId()
927 void SALOMEDSImpl_Study::StudyId(int id)
933 void SALOMEDSImpl_Study::UpdateIORLabelMap(const TCollection_AsciiString& anIOR,const TCollection_AsciiString& anEntry)
937 char* anEn = (char*)anEntry.ToCString();
938 char* IOR = (char*)anIOR.ToCString();
939 TDF_Tool::Label(_doc->GetData(),anEn, aLabel, Standard_True);
940 if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
941 myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
944 Handle(SALOMEDSImpl_Study) SALOMEDSImpl_Study::GetStudy(const TDF_Label& theLabel)
946 Handle(SALOMEDSImpl_StudyHandle) Att;
947 if (theLabel.Root().FindAttribute(SALOMEDSImpl_StudyHandle::GetID(),Att)) {
948 return Att->GetHandle();
953 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::SObject(const TDF_Label& theLabel)
955 return GetStudy(theLabel)->GetSObject(theLabel);
958 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::SComponent(const TDF_Label& theLabel)
960 return GetStudy(theLabel)->GetSComponent(theLabel);
964 void SALOMEDSImpl_Study::IORUpdated(const Handle(SALOMEDSImpl_AttributeIOR)& theAttribute)
966 TCollection_AsciiString aString;
967 TDF_Tool::Entry(theAttribute->Label(), aString);
968 GetStudy(theAttribute->Label())->UpdateIORLabelMap(theAttribute->Value(), aString);
971 Handle(TColStd_HSequenceOfTransient) SALOMEDSImpl_Study::FindDependances(const Handle(SALOMEDSImpl_SObject)& anObject)
974 Handle(TColStd_HSequenceOfTransient) aSeq;
976 Handle(SALOMEDSImpl_AttributeTarget) aTarget;
977 if (anObject->GetLabel().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID(), aTarget)) {
978 return aTarget->Get();
985 Handle(SALOMEDSImpl_AttributeStudyProperties) SALOMEDSImpl_Study::GetProperties()
988 return SALOMEDSImpl_AttributeStudyProperties::Set(_doc->Main());
991 TCollection_AsciiString SALOMEDSImpl_Study::GetLastModificationDate()
994 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
996 Handle(TColStd_HSequenceOfExtendedString) aNames;
997 Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
998 aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
1000 int aLastIndex = aNames->Length();
1002 sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
1003 (int)(aDays->Value(aLastIndex)),(int)(aMonths->Value(aLastIndex)), (int)(aYears->Value(aLastIndex)),
1004 (int)(aHours->Value(aLastIndex)), (int)(aMinutes->Value(aLastIndex)));
1005 TCollection_AsciiString aResStr (aResult);
1009 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetModificationsDate()
1012 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
1014 Handle(TColStd_HSequenceOfExtendedString) aNames;
1015 Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
1016 aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
1018 int anIndex, aLength = aNames->Length();
1019 Handle(TColStd_HSequenceOfAsciiString) aDates = new TColStd_HSequenceOfAsciiString;
1021 for (anIndex = 2; anIndex <= aLength; anIndex++) {
1023 sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
1024 (int)(aDays->Value(anIndex)), (int)(aMonths->Value(anIndex)), (int)(aYears->Value(anIndex)),
1025 (int)(aHours->Value(anIndex)), (int)(aMinutes->Value(anIndex)));
1026 aDates->Append(aDate);
1033 //============================================================================
1034 /*! Function : GetUseCaseBuilder
1035 * Purpose : Returns a UseCase builder
1037 //============================================================================
1038 Handle(SALOMEDSImpl_UseCaseBuilder) SALOMEDSImpl_Study::GetUseCaseBuilder()
1041 return _useCaseBuilder;
1045 //============================================================================
1046 /*! Function : Close
1049 //============================================================================
1050 void SALOMEDSImpl_Study::Close()
1053 Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1054 if(!anApp.IsNull()) anApp->Close(_doc);
1060 //============================================================================
1061 /*! Function : AddPostponed
1064 //============================================================================
1065 void SALOMEDSImpl_Study::AddPostponed(const TCollection_AsciiString& theIOR)
1068 if (!NewBuilder()->HasOpenCommand()) return;
1069 TCollection_AsciiString anIOR(theIOR);
1071 myPostponedIORs.Append(anIOR); // add prefix: deleted
1072 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1075 //============================================================================
1076 /*! Function : AddCreatedPostponed
1079 //============================================================================
1080 void SALOMEDSImpl_Study::AddCreatedPostponed(const TCollection_AsciiString& theIOR)
1083 if (!NewBuilder()->HasOpenCommand()) return;
1084 TCollection_AsciiString anIOR(theIOR);
1086 myPostponedIORs.Append(anIOR); // add prefix: created
1087 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1090 //============================================================================
1091 /*! Function : RemovePostponed
1094 //============================================================================
1095 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::RemovePostponed(const int theUndoLimit)
1102 int aUndoLimit = theUndoLimit;
1103 if (theUndoLimit < 0) aUndoLimit = 0;
1105 Handle(TColStd_HSequenceOfAsciiString) aSeq = new TColStd_HSequenceOfAsciiString;
1107 if (myNbUndos > 0) { // remove undone
1109 for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1110 anOld += myNbPostponed(anIndex);
1111 int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1113 for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1114 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1115 if (anIOR.Value(1) == 'c') {
1116 aSeq->Append(anIOR.Split(1).ToCString());
1119 if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1120 if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1125 if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1127 for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1128 anOld += myNbPostponed(anIndex);
1129 for(anIndex = 1; anIndex <= anOld; anIndex++) {
1130 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1131 if (anIOR.Value(1) == 'd') {
1132 aSeq->Append(anIOR.Split(1).ToCString());
1135 if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1136 myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1139 if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1140 TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDSImpl_AttributeIOR::GetID(), Standard_True);
1141 for(; anIter.More(); anIter.Next()) {
1142 Handle(SALOMEDSImpl_AttributeIOR) anAttr = Handle(SALOMEDSImpl_AttributeIOR)::DownCast(anIter.Value());
1143 aSeq->Append(anAttr->Value());
1145 } else myNbPostponed.Append(0);
1150 //============================================================================
1151 /*! Function : UndoPostponed
1154 //============================================================================
1155 void SALOMEDSImpl_Study::UndoPostponed(const int theWay)
1159 myNbUndos += theWay;
1160 // remove current postponed
1161 if (myNbPostponed.Last() > 0)
1162 myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1163 myNbPostponed(myNbPostponed.Length()) = 0;
1167 //============================================================================
1168 /*! Function : GetSComponent
1171 //============================================================================
1172 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TCollection_AsciiString& theEntry)
1174 Handle(SALOMEDSImpl_SComponent) aSCO;
1175 if(_mapOfSCO.IsBound(theEntry))
1176 aSCO = Handle(SALOMEDSImpl_SComponent)::DownCast(_mapOfSCO.Find(theEntry));
1179 TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1180 aSCO = new SALOMEDSImpl_SComponent(aLabel);
1181 _mapOfSCO.Bind(theEntry, aSCO);
1187 //============================================================================
1188 /*! Function : GetSComponent
1191 //============================================================================
1192 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TDF_Label& theLabel)
1194 TCollection_AsciiString anEntry;
1195 TDF_Tool::Entry(theLabel, anEntry);
1196 return GetSComponent(anEntry);
1199 //============================================================================
1200 /*! Function : GetSObject
1203 //============================================================================
1204 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TCollection_AsciiString& theEntry)
1206 Handle(SALOMEDSImpl_SObject) aSO;
1207 if(_mapOfSO.IsBound(theEntry))
1208 aSO = Handle(SALOMEDSImpl_SObject)::DownCast(_mapOfSO.Find(theEntry));
1211 TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1212 aSO = new SALOMEDSImpl_SObject(aLabel);
1213 _mapOfSO.Bind(theEntry, aSO);
1219 //============================================================================
1220 /*! Function : GetSObject
1223 //============================================================================
1224 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TDF_Label& theLabel)
1226 TCollection_AsciiString anEntry;
1227 TDF_Tool::Entry(theLabel, anEntry);
1228 return GetSObject(anEntry);
1231 //============================================================================
1232 /*! Function : GetAttribute
1235 //============================================================================
1236 Handle(TDF_Attribute) SALOMEDSImpl_Study::GetAttribute(const TCollection_AsciiString& theEntry,
1237 const TCollection_AsciiString& theType)
1239 Handle(SALOMEDSImpl_SObject) aSO = GetSObject(theEntry);
1240 Handle(TDF_Attribute) anAttr;
1241 aSO->FindAttribute(anAttr, theType);
1245 //============================================================================
1246 /*! Function : DumpStudy
1249 //============================================================================
1250 bool SALOMEDSImpl_Study::DumpStudy(const TCollection_AsciiString& thePath,
1251 const TCollection_AsciiString& theBaseName,
1253 SALOMEDSImpl_DriverFactory* theFactory)
1257 if(theFactory == NULL) {
1258 _errorCode = "Null factory for creation of Engines";
1262 TColStd_SequenceOfExtendedString aSeq;
1263 TCollection_AsciiString aCompType, aFactoryType;
1265 //Build a list of all components in the Study
1266 SALOMEDSImpl_SComponentIterator itcomponent = NewComponentIterator();
1268 for (; itcomponent.More(); itcomponent.Next()) {
1269 Handle(SALOMEDSImpl_SComponent) sco = itcomponent.Value();
1270 aCompType = sco->ComponentDataType();
1271 //GEOM and MED are independent components
1272 if (aCompType == "GEOM" || aCompType == "MED")
1273 aSeq.Prepend(TCollection_ExtendedString(aCompType));
1275 aSeq.Append(TCollection_ExtendedString(aCompType));
1279 TCollection_AsciiString aFileName =
1280 thePath + TCollection_AsciiString("\\") + theBaseName + TCollection_AsciiString(".py");
1282 TCollection_AsciiString aFileName =
1283 thePath + TCollection_AsciiString("/") + theBaseName + TCollection_AsciiString(".py");
1286 //Create a file that will contain a main Study script
1288 fp.open(aFileName.ToCString(), ios::out);
1291 bool isOpened = fp.is_open();
1293 bool isOpened = fp.rdbuf()->is_open();
1297 _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1301 TCollection_AsciiString aBatchModeScript = "salome";
1303 //Output to the main Study script required Python modules import,
1304 //set sys.path and add a creation of the study.
1305 fp << GetDumpStudyComment().ToCString() << endl << endl;
1306 fp << "import sys" << endl;
1307 fp << "import " << aBatchModeScript << endl << endl;
1309 fp << aBatchModeScript << ".salome_init()" << endl << endl;
1311 fp << "sys.path.insert( 0, \'" << thePath << "\')" << endl << endl;
1314 //Check if it's necessary to dump visual parameters
1315 bool isDumpVisuals = SALOMEDSImpl_IParameters::isDumpPython(this);
1316 int lastSavePoint = -1;
1318 lastSavePoint = SALOMEDSImpl_IParameters::getLastSavePoint(this);
1319 if(lastSavePoint > 0) {
1320 fp << SALOMEDSImpl_IParameters::getStudyScript(this, lastSavePoint) << endl << endl;
1325 Handle(TColStd_HSequenceOfAsciiString) aSeqOfFileNames = new TColStd_HSequenceOfAsciiString;
1327 //Iterate all components and create the componponents specific scripts.
1329 int aLength = aSeq.Length();
1330 for(int i = 1; i <= aLength; i++) {
1332 aCompType = aSeq.Value(i);
1333 Handle(SALOMEDSImpl_SComponent) sco = FindComponent(aCompType);
1334 SALOMEDSImpl_Driver* aDriver = NULL;
1335 // if there is an associated Engine call its method for saving
1336 TCollection_AsciiString IOREngine;
1338 if (!sco->ComponentIOR(IOREngine)) {
1339 if (!aCompType.IsEmpty()) {
1341 aDriver = theFactory->GetDriverByType(aCompType);
1343 if (aDriver != NULL) {
1344 Handle(SALOMEDSImpl_StudyBuilder) SB = NewBuilder();
1345 if(!SB->LoadWith(sco, aDriver)) {
1346 _errorCode = SB->GetErrorCode();
1354 aDriver = theFactory->GetDriverByIOR(IOREngine);
1357 _errorCode = "Can not restore information to dump it";
1361 if(aDriver == NULL) continue;
1364 long aStreamLength = 0;
1365 Handle(SALOMEDSImpl_TMPFile) aStream = aDriver->DumpPython(this, isPublished, isValidScript, aStreamLength);
1366 if ( !isValidScript )
1369 //Create a file that will contain the component specific script
1372 aFileName=thePath+TCollection_AsciiString("\\");
1374 aFileName=thePath+TCollection_AsciiString("/");
1376 TCollection_AsciiString aScriptName;
1377 aScriptName += theBaseName;
1379 aScriptName += aCompType;
1381 aFileName += aScriptName+ TCollection_AsciiString(".py");
1382 aSeqOfFileNames->Append(aFileName);
1384 fp2.open(aFileName.ToCString(), ios::out);
1387 isOpened = fp2.is_open();
1389 isOpened = fp2.rdbuf()->is_open();
1393 _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1394 SALOMEDSImpl_Tool::RemoveTemporaryFiles(thePath, aSeqOfFileNames, false);
1398 //Output the Python script generated by the component in the newly created file.
1399 fp2 << aStream->Data();
1402 //Add to the main script a call to RebuildData of the generated by the component the Python script
1403 fp << "import " << aScriptName << endl;
1404 fp << aScriptName << ".RebuildData(" << aBatchModeScript << ".myStudy)" << endl;
1408 fp << "if salome.sg.hasDesktop():" << endl;
1409 fp << "\tsalome.sg.updateObjBrowser(1)" << endl;
1411 if(isDumpVisuals) { //Output the call to Session's method restoreVisualState
1412 fp << "\tiparameters.getSession().restoreVisualState(1)" << endl;
1420 //=======================================================================
1421 //function : GetDumpStudyComment
1422 //purpose : return a header comment for a DumpStudy script
1423 //=======================================================================
1425 TCollection_AsciiString SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
1427 TCollection_AsciiString txt
1428 ("### This file is generated by SALOME automatically by dump python functionality");
1429 if ( theComponentName )
1430 txt += TCollection_AsciiString(" of ") + (char*) theComponentName + " component";
1434 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1436 const TCollection_AsciiString& Tab,
1437 const Handle(SALOMEDSImpl_Study) theStudy);
1438 //============================================================================
1442 //============================================================================
1443 void SALOMEDSImpl_Study::dump(const TCollection_AsciiString& theFileName)
1445 //Create a file that will contain a main Study script
1447 fp.open(theFileName.ToCString(), ios::out);
1450 bool isOpened = fp.is_open();
1452 bool isOpened = fp.rdbuf()->is_open();
1456 _errorCode = TCollection_AsciiString("Can't create a file ")+theFileName;
1457 cout << "### SALOMEDSImpl_Study::dump Error: " << _errorCode << endl;
1461 Handle(SALOMEDSImpl_SObject) aSO = FindObjectID("0:1");
1462 fp << "0:1" << endl;
1463 Handle(SALOMEDSImpl_ChildIterator) Itr = NewChildIterator(aSO);
1464 TCollection_AsciiString aTab(" ");
1465 for(; Itr->More(); Itr->Next()) {
1466 dumpSO(Itr->Value(), fp, aTab, this);
1473 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1475 const TCollection_AsciiString& Tab,
1476 const Handle(SALOMEDSImpl_Study) theStudy)
1478 TCollection_AsciiString aTab(Tab), anID(theSO->GetID());
1479 fp << aTab << anID << endl;
1480 TDF_AttributeIterator anItr(theSO->GetLabel());
1481 for(; anItr.More(); anItr.Next()) {
1482 Handle(SALOMEDSImpl_GenericAttribute) anAttr = Handle(SALOMEDSImpl_GenericAttribute)::DownCast(anItr.Value());
1484 if(anAttr.IsNull()) {
1485 fp << Tab << " -- " << anItr.Value()->DynamicType();
1489 TCollection_AsciiString aType = anAttr->GetClassType();
1490 fp << Tab << " -- " << aType;
1492 if(aType == "AttributeReal") {
1493 fp << " : " << Handle(SALOMEDSImpl_AttributeReal)::DownCast(anAttr)->Value();
1495 else if(aType == "AttributeInteger") {
1496 fp << " : " << Handle(SALOMEDSImpl_AttributeInteger)::DownCast(anAttr)->Value();
1498 else if(aType == "AttributeName") {
1499 fp << " : " << Handle(SALOMEDSImpl_AttributeName)::DownCast(anAttr)->Value();
1501 else if(aType == "AttributeComment") {
1502 fp << " : " << Handle(SALOMEDSImpl_AttributeComment)::DownCast(anAttr)->Value();
1504 else if(aType == "AttributeReference") {
1505 fp << " : " << Handle(SALOMEDSImpl_AttributeReference)::DownCast(anAttr)->Save();
1510 Handle(SALOMEDSImpl_ChildIterator) Itr = theStudy->NewChildIterator(theSO);
1511 TCollection_AsciiString aNewTab(" ");
1513 for(; Itr->More(); Itr->Next()) {
1514 dumpSO(Itr->Value(), fp, aNewTab, theStudy);
1520 void SALOMEDSImpl_Study::Modify()
1526 //============================================================================
1530 //============================================================================
1531 Handle(SALOMEDSImpl_AttributeParameter) SALOMEDSImpl_Study::GetCommonParameters(const char* theID, int theSavePoint)
1533 if (theSavePoint < 0) return NULL;
1534 Handle(SALOMEDSImpl_StudyBuilder) builder = NewBuilder();
1535 Handle(SALOMEDSImpl_SObject) so = FindComponent((char*)theID);
1536 if (so.IsNull()) so = builder->NewComponent((char*)theID);
1537 Handle(SALOMEDSImpl_AttributeParameter) attParam;
1539 if (theSavePoint > 0) { // Try to find SObject that contains attribute parameter ...
1540 TDF_Label savePointLabel = so->GetLabel().FindChild( theSavePoint, /*create=*/0 );
1541 if ( !savePointLabel.IsNull() )
1542 so = GetSObject( savePointLabel );
1543 else // ... if it does not exist - create a new one
1544 so = builder->NewObjectToTag( so, theSavePoint );
1548 builder->FindAttribute(so, attParam, "AttributeParameter");
1549 if ( attParam.IsNull() ) { // first call of GetCommonParameters on "Interface Applicative" component
1550 Handle(TDF_Attribute) att = builder->FindOrCreateAttribute(so, "AttributeParameter");
1551 attParam = Handle(SALOMEDSImpl_AttributeParameter)::DownCast( att );
1557 //============================================================================
1561 //============================================================================
1562 Handle(SALOMEDSImpl_AttributeParameter) SALOMEDSImpl_Study::GetModuleParameters(const char* theID,
1563 const char* theModuleName,
1566 if(theSavePoint <= 0) return NULL;
1567 Handle(SALOMEDSImpl_AttributeParameter) main_ap = GetCommonParameters(theID, theSavePoint);
1568 Handle(SALOMEDSImpl_SObject) main_so = main_ap->GetSObject();
1569 Handle(SALOMEDSImpl_AttributeParameter) par;
1571 Handle(SALOMEDSImpl_ChildIterator) it = NewChildIterator(main_so);
1572 string moduleName(theModuleName);
1573 for(; it->More(); it->Next()) {
1574 Handle(SALOMEDSImpl_SObject) so(it->Value());
1575 Handle(SALOMEDSImpl_GenericAttribute) ga;
1576 if(so->FindAttribute(ga, "AttributeParameter")) {
1577 par = Handle(SALOMEDSImpl_AttributeParameter)::DownCast(ga);
1578 if(!par->IsSet("AP_MODULE_NAME", (Parameter_Types)3)) continue; //3 -> PT_STRING
1579 if(par->GetString("AP_MODULE_NAME") == moduleName) return par;
1583 Handle(SALOMEDSImpl_StudyBuilder) builder = NewBuilder();
1584 Handle(SALOMEDSImpl_SObject) so = builder->NewObject(main_so);
1585 par = Handle(SALOMEDSImpl_AttributeParameter)::DownCast(builder->FindOrCreateAttribute(so, "AttributeParameter"));
1586 par->SetString("AP_MODULE_NAME", moduleName);