1 // Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : SALOMEDSImpl_UseCaseBuilder.cxx
24 // Author : Sergey RUIN
27 #include "SALOMEDSImpl_UseCaseBuilder.hxx"
28 #include "SALOMEDSImpl_SObject.hxx"
29 #include "SALOMEDSImpl_SComponent.hxx"
30 #include "SALOMEDSImpl_Study.hxx"
31 #include "SALOMEDSImpl_Attributes.hxx"
33 #include "DF_ChildIterator.hxx"
37 #define USE_CASE_LABEL_TAG 2
38 #define USE_CASE_GUID "AA43BB12-D9CD-11d6-945D-0050DA506788"
41 // comparator to sort use case nodes in ascending order
43 bool operator()( SALOMEDSImpl_SObject firstSO, SALOMEDSImpl_SObject secondSO ) const {
44 std::string firstName, secondName;
45 SALOMEDSImpl_SObject refSO;
46 firstSO.ReferencedObject(refSO) ?
47 firstName = refSO.GetName() :
48 firstName = firstSO.GetName();
49 secondSO.ReferencedObject(refSO) ?
50 secondName = refSO.GetName() :
51 secondName = secondSO.GetName();
52 return firstName < secondName;
56 // comparator to sort use case nodes in descending order
58 bool operator()( SALOMEDSImpl_SObject firstSO, SALOMEDSImpl_SObject secondSO ) const {
59 std::string firstName, secondName;
60 SALOMEDSImpl_SObject refSO;
61 firstSO.ReferencedObject(refSO) ?
62 firstName = refSO.GetName() :
63 firstName = firstSO.GetName();
64 secondSO.ReferencedObject(refSO) ?
65 secondName = refSO.GetName() :
66 secondName = secondSO.GetName();
67 return firstName > secondName;
72 //============================================================================
73 /*! Function : constructor
76 //============================================================================
77 SALOMEDSImpl_UseCaseBuilder::SALOMEDSImpl_UseCaseBuilder(DF_Document* theDocument)
78 :_doc(theDocument), _lastChild(0), _childIndex(-1)
82 DF_Label aLabel = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG); //Iterate all use cases
83 if(!(_root = (SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(std::string(USE_CASE_GUID)))) {
84 _root = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, std::string(USE_CASE_GUID));
87 SALOMEDSImpl_AttributeReference* aRef = NULL;
88 if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
89 aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());
92 if(!aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID())) {
93 SALOMEDSImpl_AttributeName::Set(aLabel, "Use cases");
97 //============================================================================
98 /*! Function : destructor
101 //============================================================================
102 SALOMEDSImpl_UseCaseBuilder::~SALOMEDSImpl_UseCaseBuilder()
107 //============================================================================
108 /*! Function : Append
111 //============================================================================
112 bool SALOMEDSImpl_UseCaseBuilder::Append(const SALOMEDSImpl_SObject& theObject)
114 if(!_root || !theObject) return false;
116 DF_Label aLabel = theObject.GetLabel();
117 if(aLabel.IsNull()) return false;
119 SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
120 SALOMEDSImpl_AttributeTreeNode* aCurrentNode = NULL;
121 aNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, _root->ID());
124 SALOMEDSImpl_AttributeReference* aRef;
125 if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
126 aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());
129 DF_Label aCurrent = aRef->Get();
130 if(aCurrent.IsNull() || !(aCurrentNode=(SALOMEDSImpl_AttributeTreeNode*)aCurrent.FindAttribute(_root->ID())))
131 aCurrentNode = _root;
133 aCurrentNode->Append(aNode, &_childIndex);
136 // Mantis issue 0020136: Drag&Drop in OB
137 SALOMEDSImpl_Study::GetStudyImpl(theObject.GetLabel())->addSO_Notification(theObject);
142 //============================================================================
143 /*! Function : Remove
146 //============================================================================
147 bool SALOMEDSImpl_UseCaseBuilder::Remove(const SALOMEDSImpl_SObject& theObject)
149 if(!_root || !theObject) return false;
151 DF_Label aLabel = theObject.GetLabel();
152 if(aLabel.IsNull()) return false;
154 SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
155 if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
157 if ( _lastChild && aNode->GetFather() == _lastChild->GetFather() )
162 std::vector<DF_Attribute*> aList;
163 aList.push_back(aNode);
165 SALOMEDSImpl_AttributeReference* aRef = NULL;
166 if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
167 aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());
170 DF_Label aCurrent = aRef->Get();
172 SALOMEDSImpl_ChildNodeIterator aChildItr(aNode, true);
173 for(; aChildItr.More(); aChildItr.Next())
174 aList.push_back(aChildItr.Value());
176 for(size_t i = 0, len = aList.size(); i<len; i++) {
177 if(aList[i]->Label() == aCurrent) { //The current node is removed
178 aRef->Set(_root->Label()); //Reset the current node to the root
180 aList[i]->Label().ForgetAttribute(_root->ID());
187 //============================================================================
188 /*! Function : AppendTo
191 //============================================================================
192 bool SALOMEDSImpl_UseCaseBuilder::AppendTo(const SALOMEDSImpl_SObject& theFather,
193 const SALOMEDSImpl_SObject& theObject)
195 if(!_root || !theFather || !theObject) return false;
197 DF_Label aFatherLabel = theFather.GetLabel(), aLabel = theObject.GetLabel();
198 if(aFatherLabel == aLabel) return false;
200 SALOMEDSImpl_AttributeTreeNode *aFather = NULL, *aNode = NULL;
202 if(aFatherLabel.IsNull()) return false;
203 if(!(aFather=(SALOMEDSImpl_AttributeTreeNode*)aFatherLabel.FindAttribute(_root->ID()))) return false;
205 if(aLabel.IsNull()) return false;
206 if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) {
207 aNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, _root->ID());
210 if ( aNode == _lastChild && !_lastChild->HasNext() && _lastChild->GetFather() == aFather )
211 return true; // aNode is already the last child
216 if ( _lastChild && _lastChild->GetFather() == aFather &&
217 !_lastChild->HasNext() ) // _lastChild is the last under aFather
219 _lastChild->InsertAfter( aNode );
225 ret = aFather->Append(aNode, &_childIndex);
229 // Mantis issue 0020136: Drag&Drop in OB
230 SALOMEDSImpl_Study::GetStudyImpl(theObject.GetLabel())->addSO_Notification(theObject);
235 //============================================================================
236 /*! Function : GetIndexInFather
239 //============================================================================
240 int SALOMEDSImpl_UseCaseBuilder::GetIndexInFather(const SALOMEDSImpl_SObject& theFather,
241 const SALOMEDSImpl_SObject& theObject)
244 if(!_root || !theFather || !theObject) return index;
246 DF_Label aFatherLabel = theFather.GetLabel(), aLabel = theObject.GetLabel();
247 if(aFatherLabel == aLabel) return index;
249 SALOMEDSImpl_AttributeTreeNode *aFather = NULL, *aNode = NULL;
251 if(aFatherLabel.IsNull()) return index;
252 if(!(aFather=(SALOMEDSImpl_AttributeTreeNode*)aFatherLabel.FindAttribute(_root->ID()))) return index;
254 if(aLabel.IsNull()) return index;
255 if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) {
256 aNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, _root->ID());
259 if ( _lastChild && _lastChild->GetFather() == aFather )
261 if ( aNode == _lastChild )
263 else if ( aNode == _lastChild->GetPrevious())
264 index = _childIndex - 1;
265 else if ( aNode == _lastChild->GetNext())
267 index = ++_childIndex;
274 SALOMEDSImpl_AttributeTreeNode* Last = aFather->GetFirst();
275 for ( index = 0; Last && aNode != Last && Last->HasNext(); ++index )
277 Last = Last->GetNext();
281 else if ( !Last->HasNext() )
291 //============================================================================
292 /*! Function : InsertBefore
295 //============================================================================
296 bool SALOMEDSImpl_UseCaseBuilder::InsertBefore(const SALOMEDSImpl_SObject& theFirst,
297 const SALOMEDSImpl_SObject& theNext)
299 if(!_root || !theFirst || !theNext) return false;
301 DF_Label aFirstLabel = theFirst.GetLabel(), aLabel= theNext.GetLabel();
302 if(aFirstLabel == aLabel) return false;
304 SALOMEDSImpl_AttributeTreeNode *aFirstNode = NULL, *aNode = NULL;
306 if(aFirstLabel.IsNull()) return false;
307 if((aFirstNode=(SALOMEDSImpl_AttributeTreeNode*)aFirstLabel.FindAttribute(_root->ID()))) {
308 aFirstNode->Remove();
309 aFirstLabel.ForgetAttribute(aFirstNode->ID());
312 aFirstNode = SALOMEDSImpl_AttributeTreeNode::Set(aFirstLabel, _root->ID());
314 if(aLabel.IsNull()) return false;
315 if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
317 aFirstNode->Remove();
319 bool ret = aNode->InsertBefore(aFirstNode);
321 if ( _lastChild && _lastChild->GetFather() == aNode->GetFather() )
323 if ( aNode == _lastChild )
329 // Mantis issue 0020136: Drag&Drop in OB
330 SALOMEDSImpl_Study::GetStudyImpl(theFirst.GetLabel())->addSO_Notification(theFirst);
336 //============================================================================
337 /*! Function : SetCurrentObject
340 //============================================================================
341 bool SALOMEDSImpl_UseCaseBuilder::SetCurrentObject(const SALOMEDSImpl_SObject& theObject)
343 if(!_root || !theObject) return false;
345 DF_Label aLabel = theObject.GetLabel();
346 SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
347 if(aLabel.IsNull()) return false;
348 if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
350 SALOMEDSImpl_AttributeReference* aRef = NULL;
351 if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
352 aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), aNode->Label());
355 aRef->Set(aNode->Label());
360 //============================================================================
361 /*! Function : SetRootCurrent
364 //============================================================================
365 bool SALOMEDSImpl_UseCaseBuilder::SetRootCurrent()
367 if(!_root) return false;
369 SALOMEDSImpl_AttributeReference* aRef = NULL;
370 if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID())))
371 aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());
373 aRef->Set(_root->Label());
377 //============================================================================
378 /*! Function : HasChildren
381 //============================================================================
382 bool SALOMEDSImpl_UseCaseBuilder::HasChildren(const SALOMEDSImpl_SObject& theObject)
384 if(!_root) return false;
387 if (!theObject) aLabel = _root->Label();
389 aLabel = theObject.GetLabel();
390 if(aLabel.IsNull()) return false;
392 SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
393 if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
395 return (aNode->GetFirst());
398 //============================================================================
399 /*! Function : SortChildren
402 //============================================================================
403 bool SALOMEDSImpl_UseCaseBuilder::SortChildren(const SALOMEDSImpl_SObject& theObject, bool theAscendingOrder)
405 if(!_root) return false;
408 if (!theObject) aLabel = _root->Label();
410 aLabel = theObject.GetLabel();
411 if(aLabel.IsNull()) return false;
413 SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
414 if (!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
416 std::list<SALOMEDSImpl_SObject> aRefSOs;
417 std::list<SALOMEDSImpl_SObject> aNodeSOs;
418 for ( SALOMEDSImpl_AttributeTreeNode* aChildNode=aNode->GetFirst(); aChildNode; aChildNode=aChildNode->GetNext() ) {
419 if ( SALOMEDSImpl_SObject aSO = SALOMEDSImpl_Study::SObject( aChildNode->Label() ) ) {
420 if ( aChildNode->FindAttribute( SALOMEDSImpl_AttributeReference::GetID() ) )
421 aRefSOs.push_back( aSO );
423 aNodeSOs.push_back( aSO );
426 if ( aRefSOs.empty() && aNodeSOs.empty() ) return false;
428 //sort items by names in ascending/descending order
430 std::list<SALOMEDSImpl_SObject>::iterator it;
431 if ( !aRefSOs.empty() ) {
432 theAscendingOrder ? aRefSOs.sort( AscSortSOs() ) : aRefSOs.sort( DescSortSOs() );
433 for ( it = aRefSOs.begin(); it != aRefSOs.end(); ++it ) {
434 AppendTo( theObject, *it );
437 if ( !aNodeSOs.empty() ) {
438 theAscendingOrder ? aNodeSOs.sort( AscSortSOs() ) : aNodeSOs.sort( DescSortSOs() );
439 for ( it = aNodeSOs.begin(); it != aNodeSOs.end(); ++it ) {
440 AppendTo( theObject, *it );
447 //============================================================================
448 /*! Function : GetFather
451 //============================================================================
452 SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::GetFather(const SALOMEDSImpl_SObject& theObject)
454 SALOMEDSImpl_SObject so;
455 if (!_root || !theObject) return so;
457 DF_Label aLabel = theObject.GetLabel();
458 if (aLabel.IsNull()) return so;
460 SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
461 if (!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return so;
463 SALOMEDSImpl_AttributeTreeNode* aFatherNode = aNode->GetFather();
464 if (!aFatherNode) return so;
466 return aFatherNode->GetSObject();
469 //============================================================================
470 /*! Function : SetName
473 //============================================================================
474 bool SALOMEDSImpl_UseCaseBuilder::SetName(const std::string& theName) {
475 if(!_root) return false;
477 SALOMEDSImpl_AttributeName* aNameAttrib = NULL;
479 if (!(aNameAttrib=(SALOMEDSImpl_AttributeName*)_root->FindAttribute(SALOMEDSImpl_AttributeName::GetID())))
480 aNameAttrib = SALOMEDSImpl_AttributeName::Set(_root->Label(), theName);
482 aNameAttrib->SetValue(theName);
488 //============================================================================
489 /*! Function : GetCurrentObject
492 //============================================================================
493 SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::GetCurrentObject()
495 SALOMEDSImpl_SObject so;
496 if(!_root) return so;
498 SALOMEDSImpl_AttributeReference* aRef = NULL;
499 if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
500 aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());
503 DF_Label aCurrent = aRef->Get();
504 if(aCurrent.IsNull()) return so;
506 return SALOMEDSImpl_Study::SObject(aCurrent);
509 //============================================================================
510 /*! Function : GetName
513 //============================================================================
514 std::string SALOMEDSImpl_UseCaseBuilder::GetName()
517 if(!_root) return aString;
519 SALOMEDSImpl_AttributeName* aName = NULL;
520 if (!(aName=(SALOMEDSImpl_AttributeName*)_root->FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) return aString;
521 return aName->Value();
524 //============================================================================
525 /*! Function : IsUseCase
528 //============================================================================
529 bool SALOMEDSImpl_UseCaseBuilder::IsUseCase(const SALOMEDSImpl_SObject& theObject)
531 if(!theObject) return false;
532 DF_Label aFather, aLabel = theObject.GetLabel();
533 aFather = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG);
534 if(aLabel.Father() == aFather) return true;
538 //============================================================================
539 /*! Function : IsUseCaseNode
542 //============================================================================
543 bool SALOMEDSImpl_UseCaseBuilder::IsUseCaseNode(const SALOMEDSImpl_SObject& theObject)
545 if(!_root) return false;
548 if (!theObject) aLabel = _root->Label();
550 aLabel = theObject.GetLabel();
551 if(aLabel.IsNull()) return false;
553 SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
554 if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
559 //============================================================================
560 /*! Function : NewUseCase
563 //============================================================================
564 SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::AddUseCase(const std::string& theName)
566 std::string aBasicGUID(USE_CASE_GUID);
568 //Create a use cases structure if it not exists
570 SALOMEDSImpl_AttributeTreeNode *aFatherNode = NULL, *aNode = NULL;
571 SALOMEDSImpl_AttributeInteger* anInteger = NULL;
572 SALOMEDSImpl_AttributeReference* aRef = NULL;
574 DF_Label aLabel = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG);
576 if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
577 aRef = SALOMEDSImpl_AttributeReference::Set(aLabel, aLabel);
580 if(!(aFatherNode=(SALOMEDSImpl_AttributeTreeNode*)aRef->Get().FindAttribute(aBasicGUID))) {
581 aFatherNode = SALOMEDSImpl_AttributeTreeNode::Set(aRef->Get(), aBasicGUID);
584 if(!(anInteger=(SALOMEDSImpl_AttributeInteger*)_root->FindAttribute(SALOMEDSImpl_AttributeInteger::GetID()))) {
585 anInteger = SALOMEDSImpl_AttributeInteger::Set(aLabel, 0);
588 //Create a new use case
589 anInteger->SetValue(anInteger->Value()+1);
590 DF_Label aChild = aLabel.FindChild(anInteger->Value());
591 aNode = SALOMEDSImpl_AttributeTreeNode::Set(aChild, aBasicGUID);
593 aFatherNode->Append(aNode);
594 SALOMEDSImpl_AttributeName::Set(aChild, theName);
596 return SALOMEDSImpl_Study::SObject(aChild);
599 //============================================================================
600 /*! Function : GetUseCaseIterator
601 * Purpose : Creates a new UseCase iterator, if anObject is null all use cases are iterated
603 //============================================================================
604 SALOMEDSImpl_UseCaseIterator
605 SALOMEDSImpl_UseCaseBuilder::GetUseCaseIterator(const SALOMEDSImpl_SObject& theObject)
610 aLabel = theObject.GetLabel(); //Iterate only sub tree in the use case
613 aLabel = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG); //Iterate all use cases
616 return SALOMEDSImpl_UseCaseIterator(aLabel, USE_CASE_GUID, false);
620 SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::GetSObject(const std::string& theEntry)
622 DF_Label L = DF_Label::Label(_root->Label(), theEntry);
623 return SALOMEDSImpl_Study::SObject(L);