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()) {
580 if(_current.IsNull()) {
581 _errorCode = "InvalidContext";
586 TDF_Label aTmp = _current;
587 SetContext(theContext);
591 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
592 for(; anIter.More(); anIter.Next()) {
593 TDF_Label aLabel = anIter.Value();
594 Handle(SALOMEDSImpl_AttributeName) aName;
595 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
601 //============================================================================
602 /*! Function : GetDirectoryNames
603 * Purpose : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
605 //============================================================================
606 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetDirectoryNames(const TCollection_AsciiString& theContext)
610 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
612 if (theContext.IsEmpty()) {
613 if(_current.IsNull()) {
614 _errorCode = "InvalidContext";
619 TDF_Label aTmp = _current;
620 SetContext(theContext);
624 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
625 for(; anIter.More(); anIter.Next()) {
626 TDF_Label aLabel = anIter.Value();
627 Handle(SALOMEDSImpl_AttributeLocalID) anID;
628 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
629 if (anID->Value() == DIRECTORYID) {
630 Handle(SALOMEDSImpl_AttributeName) aName;
631 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) {
632 aResultSeq->Append(aName->Value());
641 //============================================================================
642 /*! Function : GetFileNames
643 * Purpose : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
645 //============================================================================
646 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetFileNames(const TCollection_AsciiString& theContext)
650 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
652 if (theContext.IsEmpty()) {
653 if(_current.IsNull()) {
654 _errorCode = "InvalidContext";
659 TDF_Label aTmp = _current;
660 SetContext(theContext);
664 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
665 for(; anIter.More(); anIter.Next()) {
666 TDF_Label aLabel = anIter.Value();
667 Handle(SALOMEDSImpl_AttributeLocalID) anID;
668 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID(), anID)) {
669 if (anID->Value() == FILELOCALID) {
670 Handle(SALOMEDSImpl_AttributePersistentRef) aName;
671 if(aLabel.FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID(), aName)) {
672 TCollection_ExtendedString aFileName = aName->Value();
673 if(aFileName.Length() > 0)
674 aResultSeq->Append(aFileName.Split(strlen(FILEID)));
683 //============================================================================
684 /*! Function : GetComponentNames
685 * Purpose : method to get all components names
687 //============================================================================
688 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetComponentNames(const TCollection_AsciiString& theContext)
692 Handle(TColStd_HSequenceOfAsciiString) aResultSeq = new TColStd_HSequenceOfAsciiString;
693 TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
694 for(; anIter.More(); anIter.Next()) {
695 TDF_Label aLabel = anIter.Value();
696 Handle(SALOMEDSImpl_AttributeName) aName;
697 if (aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) aResultSeq->Append(aName->Value());
703 //============================================================================
704 /*! Function : NewChildIterator
705 * Purpose : Create a ChildIterator from an SObject
707 //============================================================================
708 Handle(SALOMEDSImpl_ChildIterator) SALOMEDSImpl_Study::NewChildIterator(const Handle(SALOMEDSImpl_SObject)& aSO)
711 return new SALOMEDSImpl_ChildIterator(aSO);
715 //============================================================================
716 /*! Function : NewComponentIterator
717 * Purpose : Create a SComponentIterator
719 //============================================================================
720 SALOMEDSImpl_SComponentIterator SALOMEDSImpl_Study::NewComponentIterator()
723 return SALOMEDSImpl_SComponentIterator(_doc);
727 //============================================================================
728 /*! Function : NewBuilder
729 * Purpose : Create a StudyBuilder
731 //============================================================================
732 Handle(SALOMEDSImpl_StudyBuilder) SALOMEDSImpl_Study::NewBuilder()
736 _builder->SetOnAddSObject(_cb);
737 _builder->SetOnRemoveSObject(_cb);
743 //============================================================================
745 * Purpose : get study name
747 //============================================================================
748 TCollection_AsciiString SALOMEDSImpl_Study::Name()
754 //============================================================================
756 * Purpose : set study name
758 //============================================================================
759 void SALOMEDSImpl_Study::Name(const TCollection_AsciiString& name)
765 //============================================================================
766 /*! Function : IsSaved
767 * Purpose : get if study has been saved
769 //============================================================================
770 bool SALOMEDSImpl_Study::IsSaved()
776 //============================================================================
777 /*! Function : IsSaved
778 * Purpose : set if study has been saved
780 //============================================================================
781 void SALOMEDSImpl_Study::IsSaved(bool save)
785 if(save) _doc->UnModify();
788 //============================================================================
789 /*! Function : IsModified
790 * Purpose : Detect if a Study has been modified since it has been saved
792 //============================================================================
793 bool SALOMEDSImpl_Study::IsModified()
797 // True if is modified
798 if (_doc->IsModified()) return true;
803 //============================================================================
805 * Purpose : get URL of the study (persistent reference of the study)
807 //============================================================================
808 TCollection_AsciiString SALOMEDSImpl_Study::URL()
814 //============================================================================
816 * Purpose : set URL of the study (persistent reference of the study)
818 //============================================================================
819 void SALOMEDSImpl_Study::URL(const TCollection_AsciiString& url)
824 /*jfa: Now name of SALOMEDS study will correspond to name of SalomeApp study
825 TCollection_AsciiString tmp(_URL);
827 char *aName = (char*)tmp.ToCString();
828 char *adr = strtok(aName, "/");
832 adr = strtok(NULL, "/");
839 //============================================================================
840 /*! Function : _FindObject
841 * Purpose : Find an Object with SALOMEDSImpl_Name = anObjectName
843 //============================================================================
844 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::_FindObject(const Handle(SALOMEDSImpl_SObject)& SO,
845 const TCollection_AsciiString& theObjectName,
848 if(SO.IsNull()) return NULL;
850 // Iterate on each objects and subobjects of the component
851 // If objectName find, stop the loop and get the object reference
852 Handle(SALOMEDSImpl_SObject) RefSO;
853 Handle(SALOMEDSImpl_AttributeName) anAttr;
855 TCollection_AsciiString soid = SO->GetID();
856 TDF_ChildIterator it(SO->GetLabel());
857 for (; it.More(); it.Next()){
860 if (it.Value().FindAttribute(SALOMEDSImpl_AttributeName::GetID(), anAttr))
862 TCollection_AsciiString Val(anAttr->Value());
863 if (Val == theObjectName)
865 RefSO = GetSObject(it.Value());
869 if (!_find) RefSO = _FindObject(GetSObject(it.Value()), theObjectName, _find);
875 //============================================================================
876 /*! Function : _FindObjectIOR
877 * Purpose : Find an Object with SALOMEDSImpl_IOR = anObjectIOR
879 //============================================================================
880 Handle(SALOMEDSImpl_SObject)
881 SALOMEDSImpl_Study::_FindObjectIOR(const Handle(SALOMEDSImpl_SObject)& SO,
882 const TCollection_AsciiString& theObjectIOR,
885 if(SO.IsNull()) return NULL;
887 // Iterate on each objects and subobjects of the component
888 // If objectName find, stop the loop and get the object reference
889 Handle(SALOMEDSImpl_SObject) RefSO, aSO;
890 Handle(SALOMEDSImpl_AttributeIOR) anAttr;
892 TDF_ChildIterator it(SO->GetLabel());
893 for (; it.More();it.Next()){
896 if (it.Value().FindAttribute(SALOMEDSImpl_AttributeIOR::GetID(), anAttr))
898 TCollection_AsciiString Val(anAttr->Value());
899 if (Val == theObjectIOR)
901 RefSO = GetSObject(it.Value());
905 aSO = GetSObject(it.Value());
906 if (!_find) RefSO = _FindObjectIOR(aSO, theObjectIOR, _find);
912 bool SALOMEDSImpl_Study::IsLocked()
915 return GetProperties()->IsLocked();
918 int SALOMEDSImpl_Study::StudyId()
924 void SALOMEDSImpl_Study::StudyId(int id)
930 void SALOMEDSImpl_Study::UpdateIORLabelMap(const TCollection_AsciiString& anIOR,const TCollection_AsciiString& anEntry)
934 char* anEn = (char*)anEntry.ToCString();
935 char* IOR = (char*)anIOR.ToCString();
936 TDF_Tool::Label(_doc->GetData(),anEn, aLabel, Standard_True);
937 if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
938 myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
941 Handle(SALOMEDSImpl_Study) SALOMEDSImpl_Study::GetStudy(const TDF_Label& theLabel)
943 Handle(SALOMEDSImpl_StudyHandle) Att;
944 if (theLabel.Root().FindAttribute(SALOMEDSImpl_StudyHandle::GetID(),Att)) {
945 return Att->GetHandle();
950 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::SObject(const TDF_Label& theLabel)
952 return GetStudy(theLabel)->GetSObject(theLabel);
955 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::SComponent(const TDF_Label& theLabel)
957 return GetStudy(theLabel)->GetSComponent(theLabel);
961 void SALOMEDSImpl_Study::IORUpdated(const Handle(SALOMEDSImpl_AttributeIOR)& theAttribute)
963 TCollection_AsciiString aString;
964 TDF_Tool::Entry(theAttribute->Label(), aString);
965 GetStudy(theAttribute->Label())->UpdateIORLabelMap(theAttribute->Value(), aString);
968 Handle(TColStd_HSequenceOfTransient) SALOMEDSImpl_Study::FindDependances(const Handle(SALOMEDSImpl_SObject)& anObject)
971 Handle(TColStd_HSequenceOfTransient) aSeq;
973 Handle(SALOMEDSImpl_AttributeTarget) aTarget;
974 if (anObject->GetLabel().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID(), aTarget)) {
975 return aTarget->Get();
982 Handle(SALOMEDSImpl_AttributeStudyProperties) SALOMEDSImpl_Study::GetProperties()
985 return SALOMEDSImpl_AttributeStudyProperties::Set(_doc->Main());
988 TCollection_AsciiString SALOMEDSImpl_Study::GetLastModificationDate()
991 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
993 Handle(TColStd_HSequenceOfExtendedString) aNames;
994 Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
995 aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
997 int aLastIndex = aNames->Length();
999 sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
1000 (int)(aDays->Value(aLastIndex)),(int)(aMonths->Value(aLastIndex)), (int)(aYears->Value(aLastIndex)),
1001 (int)(aHours->Value(aLastIndex)), (int)(aMinutes->Value(aLastIndex)));
1002 TCollection_AsciiString aResStr (aResult);
1006 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::GetModificationsDate()
1009 Handle(SALOMEDSImpl_AttributeStudyProperties) aProp = GetProperties();
1011 Handle(TColStd_HSequenceOfExtendedString) aNames;
1012 Handle(TColStd_HSequenceOfInteger) aMinutes, aHours, aDays, aMonths, aYears;
1013 aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
1015 int anIndex, aLength = aNames->Length();
1016 Handle(TColStd_HSequenceOfAsciiString) aDates = new TColStd_HSequenceOfAsciiString;
1018 for (anIndex = 2; anIndex <= aLength; anIndex++) {
1020 sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
1021 (int)(aDays->Value(anIndex)), (int)(aMonths->Value(anIndex)), (int)(aYears->Value(anIndex)),
1022 (int)(aHours->Value(anIndex)), (int)(aMinutes->Value(anIndex)));
1023 aDates->Append(aDate);
1030 //============================================================================
1031 /*! Function : GetUseCaseBuilder
1032 * Purpose : Returns a UseCase builder
1034 //============================================================================
1035 Handle(SALOMEDSImpl_UseCaseBuilder) SALOMEDSImpl_Study::GetUseCaseBuilder()
1038 return _useCaseBuilder;
1042 //============================================================================
1043 /*! Function : Close
1046 //============================================================================
1047 void SALOMEDSImpl_Study::Close()
1050 Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1051 if(!anApp.IsNull()) anApp->Close(_doc);
1057 //============================================================================
1058 /*! Function : AddPostponed
1061 //============================================================================
1062 void SALOMEDSImpl_Study::AddPostponed(const TCollection_AsciiString& theIOR)
1065 if (!NewBuilder()->HasOpenCommand()) return;
1066 TCollection_AsciiString anIOR(theIOR);
1068 myPostponedIORs.Append(anIOR); // add prefix: deleted
1069 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1072 //============================================================================
1073 /*! Function : AddCreatedPostponed
1076 //============================================================================
1077 void SALOMEDSImpl_Study::AddCreatedPostponed(const TCollection_AsciiString& theIOR)
1080 if (!NewBuilder()->HasOpenCommand()) return;
1081 TCollection_AsciiString anIOR(theIOR);
1083 myPostponedIORs.Append(anIOR); // add prefix: created
1084 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1087 //============================================================================
1088 /*! Function : RemovePostponed
1091 //============================================================================
1092 Handle(TColStd_HSequenceOfAsciiString) SALOMEDSImpl_Study::RemovePostponed(const int theUndoLimit)
1099 int aUndoLimit = theUndoLimit;
1100 if (theUndoLimit < 0) aUndoLimit = 0;
1102 Handle(TColStd_HSequenceOfAsciiString) aSeq = new TColStd_HSequenceOfAsciiString;
1104 if (myNbUndos > 0) { // remove undone
1106 for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1107 anOld += myNbPostponed(anIndex);
1108 int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1110 for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1111 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1112 if (anIOR.Value(1) == 'c') {
1113 aSeq->Append(anIOR.Split(1).ToCString());
1116 if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1117 if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1122 if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1124 for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1125 anOld += myNbPostponed(anIndex);
1126 for(anIndex = 1; anIndex <= anOld; anIndex++) {
1127 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1128 if (anIOR.Value(1) == 'd') {
1129 aSeq->Append(anIOR.Split(1).ToCString());
1132 if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1133 myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1136 if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1137 TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDSImpl_AttributeIOR::GetID(), Standard_True);
1138 for(; anIter.More(); anIter.Next()) {
1139 Handle(SALOMEDSImpl_AttributeIOR) anAttr = Handle(SALOMEDSImpl_AttributeIOR)::DownCast(anIter.Value());
1140 aSeq->Append(anAttr->Value());
1142 } else myNbPostponed.Append(0);
1147 //============================================================================
1148 /*! Function : UndoPostponed
1151 //============================================================================
1152 void SALOMEDSImpl_Study::UndoPostponed(const int theWay)
1156 myNbUndos += theWay;
1157 // remove current postponed
1158 if (myNbPostponed.Last() > 0)
1159 myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1160 myNbPostponed(myNbPostponed.Length()) = 0;
1164 //============================================================================
1165 /*! Function : GetSComponent
1168 //============================================================================
1169 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TCollection_AsciiString& theEntry)
1171 Handle(SALOMEDSImpl_SComponent) aSCO;
1172 if(_mapOfSCO.IsBound(theEntry))
1173 aSCO = Handle(SALOMEDSImpl_SComponent)::DownCast(_mapOfSCO.Find(theEntry));
1176 TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1177 aSCO = new SALOMEDSImpl_SComponent(aLabel);
1178 _mapOfSCO.Bind(theEntry, aSCO);
1184 //============================================================================
1185 /*! Function : GetSComponent
1188 //============================================================================
1189 Handle(SALOMEDSImpl_SComponent) SALOMEDSImpl_Study::GetSComponent(const TDF_Label& theLabel)
1191 TCollection_AsciiString anEntry;
1192 TDF_Tool::Entry(theLabel, anEntry);
1193 return GetSComponent(anEntry);
1196 //============================================================================
1197 /*! Function : GetSObject
1200 //============================================================================
1201 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TCollection_AsciiString& theEntry)
1203 Handle(SALOMEDSImpl_SObject) aSO;
1204 if(_mapOfSO.IsBound(theEntry))
1205 aSO = Handle(SALOMEDSImpl_SObject)::DownCast(_mapOfSO.Find(theEntry));
1208 TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
1209 aSO = new SALOMEDSImpl_SObject(aLabel);
1210 _mapOfSO.Bind(theEntry, aSO);
1216 //============================================================================
1217 /*! Function : GetSObject
1220 //============================================================================
1221 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_Study::GetSObject(const TDF_Label& theLabel)
1223 TCollection_AsciiString anEntry;
1224 TDF_Tool::Entry(theLabel, anEntry);
1225 return GetSObject(anEntry);
1228 //============================================================================
1229 /*! Function : GetAttribute
1232 //============================================================================
1233 Handle(TDF_Attribute) SALOMEDSImpl_Study::GetAttribute(const TCollection_AsciiString& theEntry,
1234 const TCollection_AsciiString& theType)
1236 Handle(SALOMEDSImpl_SObject) aSO = GetSObject(theEntry);
1237 Handle(TDF_Attribute) anAttr;
1238 aSO->FindAttribute(anAttr, theType);
1242 //============================================================================
1243 /*! Function : DumpStudy
1246 //============================================================================
1247 bool SALOMEDSImpl_Study::DumpStudy(const TCollection_AsciiString& thePath,
1248 const TCollection_AsciiString& theBaseName,
1250 SALOMEDSImpl_DriverFactory* theFactory)
1254 if(theFactory == NULL) {
1255 _errorCode = "Null factory for creation of Engines";
1259 TColStd_SequenceOfExtendedString aSeq;
1260 TCollection_AsciiString aCompType, aFactoryType;
1262 //Build a list of all components in the Study
1263 SALOMEDSImpl_SComponentIterator itcomponent = NewComponentIterator();
1265 for (; itcomponent.More(); itcomponent.Next()) {
1266 Handle(SALOMEDSImpl_SComponent) sco = itcomponent.Value();
1267 aCompType = sco->ComponentDataType();
1268 //GEOM and MED are independent components
1269 if (aCompType == "GEOM" || aCompType == "MED")
1270 aSeq.Prepend(TCollection_ExtendedString(aCompType));
1272 aSeq.Append(TCollection_ExtendedString(aCompType));
1276 TCollection_AsciiString aFileName =
1277 thePath + TCollection_AsciiString("\\") + theBaseName + TCollection_AsciiString(".py");
1279 TCollection_AsciiString aFileName =
1280 thePath + TCollection_AsciiString("/") + theBaseName + TCollection_AsciiString(".py");
1283 //Create a file that will contain a main Study script
1285 fp.open(aFileName.ToCString(), ios::out);
1288 bool isOpened = fp.is_open();
1290 bool isOpened = fp.rdbuf()->is_open();
1294 _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1298 TCollection_AsciiString aBatchModeScript = "salome";
1300 //Output to the main Study script required Python modules import,
1301 //set sys.path and add a creation of the study.
1302 fp << GetDumpStudyComment().ToCString() << endl << endl;
1303 fp << "import sys" << endl;
1304 fp << "import " << aBatchModeScript << endl << endl;
1306 fp << aBatchModeScript << ".salome_init()" << endl << endl;
1308 fp << "sys.path.insert( 0, \'" << thePath << "\')" << endl << endl;
1311 //Check if it's necessary to dump visual parameters
1312 bool isDumpVisuals = SALOMEDSImpl_IParameters::isDumpPython(this);
1313 int lastSavePoint = -1;
1315 lastSavePoint = SALOMEDSImpl_IParameters::getLastSavePoint(this);
1316 if(lastSavePoint > 0) {
1317 fp << SALOMEDSImpl_IParameters::getStudyScript(this, lastSavePoint) << endl << endl;
1322 Handle(TColStd_HSequenceOfAsciiString) aSeqOfFileNames = new TColStd_HSequenceOfAsciiString;
1324 //Iterate all components and create the componponents specific scripts.
1326 int aLength = aSeq.Length();
1327 for(int i = 1; i <= aLength; i++) {
1329 aCompType = aSeq.Value(i);
1330 Handle(SALOMEDSImpl_SComponent) sco = FindComponent(aCompType);
1331 SALOMEDSImpl_Driver* aDriver = NULL;
1332 // if there is an associated Engine call its method for saving
1333 TCollection_AsciiString IOREngine;
1335 if (!sco->ComponentIOR(IOREngine)) {
1336 if (!aCompType.IsEmpty()) {
1338 aDriver = theFactory->GetDriverByType(aCompType);
1340 if (aDriver != NULL) {
1341 Handle(SALOMEDSImpl_StudyBuilder) SB = NewBuilder();
1342 if(!SB->LoadWith(sco, aDriver)) {
1343 _errorCode = SB->GetErrorCode();
1351 aDriver = theFactory->GetDriverByIOR(IOREngine);
1354 _errorCode = "Can not restore information to dump it";
1358 if(aDriver == NULL) continue;
1361 long aStreamLength = 0;
1362 Handle(SALOMEDSImpl_TMPFile) aStream = aDriver->DumpPython(this, isPublished, isValidScript, aStreamLength);
1363 if ( !isValidScript )
1366 //Create a file that will contain the component specific script
1369 aFileName=thePath+TCollection_AsciiString("\\");
1371 aFileName=thePath+TCollection_AsciiString("/");
1373 TCollection_AsciiString aScriptName;
1374 aScriptName += theBaseName;
1376 aScriptName += aCompType;
1378 aFileName += aScriptName+ TCollection_AsciiString(".py");
1379 aSeqOfFileNames->Append(aFileName);
1381 fp2.open(aFileName.ToCString(), ios::out);
1384 isOpened = fp2.is_open();
1386 isOpened = fp2.rdbuf()->is_open();
1390 _errorCode = TCollection_AsciiString("Can't create a file ")+aFileName;
1391 SALOMEDSImpl_Tool::RemoveTemporaryFiles(thePath, aSeqOfFileNames, false);
1395 //Output the Python script generated by the component in the newly created file.
1396 fp2 << aStream->Data();
1399 //Add to the main script a call to RebuildData of the generated by the component the Python script
1400 fp << "import " << aScriptName << endl;
1401 fp << aScriptName << ".RebuildData(" << aBatchModeScript << ".myStudy)" << endl;
1405 fp << "if salome.sg.hasDesktop():" << endl;
1406 fp << "\tsalome.sg.updateObjBrowser(1)" << endl;
1408 if(isDumpVisuals) { //Output the call to Session's method restoreVisualState
1409 fp << "\tiparameters.getSession().restoreVisualState(1)" << endl;
1417 //=======================================================================
1418 //function : GetDumpStudyComment
1419 //purpose : return a header comment for a DumpStudy script
1420 //=======================================================================
1422 TCollection_AsciiString SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
1424 TCollection_AsciiString txt
1425 ("### This file is generated by SALOME automatically by dump python functionality");
1426 if ( theComponentName )
1427 txt += TCollection_AsciiString(" of ") + (char*) theComponentName + " component";
1431 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1433 const TCollection_AsciiString& Tab,
1434 const Handle(SALOMEDSImpl_Study) theStudy);
1435 //============================================================================
1439 //============================================================================
1440 void SALOMEDSImpl_Study::dump(const TCollection_AsciiString& theFileName)
1442 //Create a file that will contain a main Study script
1444 fp.open(theFileName.ToCString(), ios::out);
1447 bool isOpened = fp.is_open();
1449 bool isOpened = fp.rdbuf()->is_open();
1453 _errorCode = TCollection_AsciiString("Can't create a file ")+theFileName;
1454 cout << "### SALOMEDSImpl_Study::dump Error: " << _errorCode << endl;
1458 Handle(SALOMEDSImpl_SObject) aSO = FindObjectID("0:1");
1459 fp << "0:1" << endl;
1460 Handle(SALOMEDSImpl_ChildIterator) Itr = NewChildIterator(aSO);
1461 TCollection_AsciiString aTab(" ");
1462 for(; Itr->More(); Itr->Next()) {
1463 dumpSO(Itr->Value(), fp, aTab, this);
1470 void dumpSO(const Handle(SALOMEDSImpl_SObject)& theSO,
1472 const TCollection_AsciiString& Tab,
1473 const Handle(SALOMEDSImpl_Study) theStudy)
1475 TCollection_AsciiString aTab(Tab), anID(theSO->GetID());
1476 fp << aTab << anID << endl;
1477 TDF_AttributeIterator anItr(theSO->GetLabel());
1478 for(; anItr.More(); anItr.Next()) {
1479 Handle(SALOMEDSImpl_GenericAttribute) anAttr = Handle(SALOMEDSImpl_GenericAttribute)::DownCast(anItr.Value());
1481 if(anAttr.IsNull()) {
1482 fp << Tab << " -- " << anItr.Value()->DynamicType();
1486 TCollection_AsciiString aType = anAttr->GetClassType();
1487 fp << Tab << " -- " << aType;
1489 if(aType == "AttributeReal") {
1490 fp << " : " << Handle(SALOMEDSImpl_AttributeReal)::DownCast(anAttr)->Value();
1492 else if(aType == "AttributeInteger") {
1493 fp << " : " << Handle(SALOMEDSImpl_AttributeInteger)::DownCast(anAttr)->Value();
1495 else if(aType == "AttributeName") {
1496 fp << " : " << Handle(SALOMEDSImpl_AttributeName)::DownCast(anAttr)->Value();
1498 else if(aType == "AttributeComment") {
1499 fp << " : " << Handle(SALOMEDSImpl_AttributeComment)::DownCast(anAttr)->Value();
1501 else if(aType == "AttributeReference") {
1502 fp << " : " << Handle(SALOMEDSImpl_AttributeReference)::DownCast(anAttr)->Save();
1507 Handle(SALOMEDSImpl_ChildIterator) Itr = theStudy->NewChildIterator(theSO);
1508 TCollection_AsciiString aNewTab(" ");
1510 for(; Itr->More(); Itr->Next()) {
1511 dumpSO(Itr->Value(), fp, aNewTab, theStudy);
1517 void SALOMEDSImpl_Study::Modify()
1523 //============================================================================
1527 //============================================================================
1528 Handle(SALOMEDSImpl_AttributeParameter) SALOMEDSImpl_Study::GetCommonParameters(const char* theID, int theSavePoint)
1530 if (theSavePoint < 0) return NULL;
1531 Handle(SALOMEDSImpl_StudyBuilder) builder = NewBuilder();
1532 Handle(SALOMEDSImpl_SObject) so = FindComponent((char*)theID);
1533 if (so.IsNull()) so = builder->NewComponent((char*)theID);
1534 Handle(SALOMEDSImpl_AttributeParameter) attParam;
1536 if (theSavePoint > 0) { // Try to find SObject that contains attribute parameter ...
1537 TDF_Label savePointLabel = so->GetLabel().FindChild( theSavePoint, /*create=*/0 );
1538 if ( !savePointLabel.IsNull() )
1539 so = GetSObject( savePointLabel );
1540 else // ... if it does not exist - create a new one
1541 so = builder->NewObjectToTag( so, theSavePoint );
1545 builder->FindAttribute(so, attParam, "AttributeParameter");
1546 if ( attParam.IsNull() ) { // first call of GetCommonParameters on "Interface Applicative" component
1547 Handle(TDF_Attribute) att = builder->FindOrCreateAttribute(so, "AttributeParameter");
1548 attParam = Handle(SALOMEDSImpl_AttributeParameter)::DownCast( att );
1554 //============================================================================
1558 //============================================================================
1559 Handle(SALOMEDSImpl_AttributeParameter) SALOMEDSImpl_Study::GetModuleParameters(const char* theID,
1560 const char* theModuleName,
1563 if(theSavePoint <= 0) return NULL;
1564 Handle(SALOMEDSImpl_AttributeParameter) main_ap = GetCommonParameters(theID, theSavePoint);
1565 Handle(SALOMEDSImpl_SObject) main_so = main_ap->GetSObject();
1566 Handle(SALOMEDSImpl_AttributeParameter) par;
1568 Handle(SALOMEDSImpl_ChildIterator) it = NewChildIterator(main_so);
1569 string moduleName(theModuleName);
1570 for(; it->More(); it->Next()) {
1571 Handle(SALOMEDSImpl_SObject) so(it->Value());
1572 Handle(SALOMEDSImpl_GenericAttribute) ga;
1573 if(so->FindAttribute(ga, "AttributeParameter")) {
1574 par = Handle(SALOMEDSImpl_AttributeParameter)::DownCast(ga);
1575 if(!par->IsSet("AP_MODULE_NAME", (Parameter_Types)3)) continue; //3 -> PT_STRING
1576 if(par->GetString("AP_MODULE_NAME") == moduleName) return par;
1580 Handle(SALOMEDSImpl_StudyBuilder) builder = NewBuilder();
1581 Handle(SALOMEDSImpl_SObject) so = builder->NewObject(main_so);
1582 par = Handle(SALOMEDSImpl_AttributeParameter)::DownCast(builder->FindOrCreateAttribute(so, "AttributeParameter"));
1583 par->SetString("AP_MODULE_NAME", moduleName);