Salome HOME
Merge branch 'master' into V9_dev
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_UseCaseBuilder.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : SALOMEDSImpl_UseCaseBuilder.cxx
24 //  Author : Sergey RUIN
25 //  Module : SALOME
26
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"
32
33 #include "DF_ChildIterator.hxx"
34
35 #include <list>
36
37 #define USE_CASE_LABEL_TAG           2
38 #define USE_CASE_GUID                "AA43BB12-D9CD-11d6-945D-0050DA506788"
39
40 namespace {
41   // comparator to sort use case nodes in ascending order
42   struct AscSortSOs {
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;
53     }
54   };
55
56   // comparator to sort use case nodes in descending order
57   struct DescSortSOs {
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;
68     }
69   };
70 }
71
72 //============================================================================
73 /*! Function : constructor
74  *  Purpose  :
75  */
76 //============================================================================
77 SALOMEDSImpl_UseCaseBuilder::SALOMEDSImpl_UseCaseBuilder(DF_Document* theDocument)
78 :_doc(theDocument)
79 {
80   if(!_doc) return;
81   
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));
85   }
86  
87   SALOMEDSImpl_AttributeReference* aRef = NULL;
88   if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
89     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());  
90   }  
91
92   if(!aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID())) { 
93     SALOMEDSImpl_AttributeName::Set(aLabel, "Use cases"); 
94   }  
95 }
96
97 //============================================================================
98 /*! Function : destructor
99  *  Purpose  :
100  */
101 //============================================================================
102 SALOMEDSImpl_UseCaseBuilder::~SALOMEDSImpl_UseCaseBuilder()
103 {
104 }
105
106
107 //============================================================================
108 /*! Function : Append
109  *  Purpose  : 
110  */
111 //============================================================================
112 bool SALOMEDSImpl_UseCaseBuilder::Append(const SALOMEDSImpl_SObject& theObject)
113 {
114   if(!_root || !theObject) return false;
115
116   DF_Label aLabel = theObject.GetLabel();
117   if(aLabel.IsNull()) return false;
118
119   SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
120   SALOMEDSImpl_AttributeTreeNode* aCurrentNode = NULL;
121   aNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, _root->ID());
122   aNode->Remove();
123
124   SALOMEDSImpl_AttributeReference* aRef;
125   if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
126     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());  
127   }  
128
129   DF_Label aCurrent = aRef->Get();
130   if(aCurrent.IsNull() || !(aCurrentNode=(SALOMEDSImpl_AttributeTreeNode*)aCurrent.FindAttribute(_root->ID()))) 
131     aCurrentNode = _root;
132
133   aCurrentNode->Append(aNode);
134
135   // Mantis issue 0020136: Drag&Drop in OB
136   SALOMEDSImpl_Study::GetStudyImpl(theObject.GetLabel())->addSO_Notification(theObject);
137
138   return true;
139 }
140
141  //============================================================================
142 /*! Function : Remove
143  *  Purpose  :
144  */
145 //============================================================================
146 bool SALOMEDSImpl_UseCaseBuilder::Remove(const SALOMEDSImpl_SObject& theObject)
147 {
148   if(!_root || !theObject) return false;
149
150   DF_Label aLabel = theObject.GetLabel();   
151   if(aLabel.IsNull()) return false;
152
153   SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
154   if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
155
156   aNode->Remove();
157
158   std::vector<DF_Attribute*> aList;
159   aList.push_back(aNode);
160
161   SALOMEDSImpl_AttributeReference* aRef = NULL;
162   if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
163     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());  
164   }  
165
166   DF_Label aCurrent = aRef->Get();
167
168   SALOMEDSImpl_ChildNodeIterator aChildItr(aNode, true);
169   for(; aChildItr.More(); aChildItr.Next()) 
170     aList.push_back(aChildItr.Value());
171
172   for(int i = 0, len = aList.size(); i<len; i++) {
173     if(aList[i]->Label() ==  aCurrent) { //The current node is removed
174       aRef->Set(_root->Label()); //Reset the current node to the root
175     }
176     aList[i]->Label().ForgetAttribute(_root->ID());
177   }
178
179   return true;
180 }
181
182
183 //============================================================================
184 /*! Function : AppendTo
185  *  Purpose  :
186  */
187 //============================================================================
188 bool SALOMEDSImpl_UseCaseBuilder::AppendTo(const SALOMEDSImpl_SObject& theFather, 
189                                            const SALOMEDSImpl_SObject& theObject)
190 {
191   if(!_root || !theFather || !theObject) return false;
192
193   DF_Label aFatherLabel = theFather.GetLabel(), aLabel = theObject.GetLabel();
194   if(aFatherLabel == aLabel) return false;
195
196   SALOMEDSImpl_AttributeTreeNode *aFather = NULL, *aNode = NULL;
197   
198   if(aFatherLabel.IsNull()) return false;
199   if(!(aFather=(SALOMEDSImpl_AttributeTreeNode*)aFatherLabel.FindAttribute(_root->ID()))) return false;
200
201   if(aLabel.IsNull()) return false;
202   if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) {
203     aNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, _root->ID());
204   }
205
206   aNode->Remove();
207
208   bool ret = aFather->Append(aNode);
209
210   // Mantis issue 0020136: Drag&Drop in OB
211   SALOMEDSImpl_Study::GetStudyImpl(theObject.GetLabel())->addSO_Notification(theObject);
212
213   return ret;
214 }
215
216 //============================================================================
217 /*! Function : InsertBefore
218  *  Purpose  :
219  */
220 //============================================================================
221 bool SALOMEDSImpl_UseCaseBuilder::InsertBefore(const SALOMEDSImpl_SObject& theFirst, 
222                                                const SALOMEDSImpl_SObject& theNext)
223 {
224   if(!_root || !theFirst || !theNext) return false;
225
226   DF_Label aFirstLabel = theFirst.GetLabel(), aLabel= theNext.GetLabel();
227   if(aFirstLabel == aLabel) return false;
228
229   SALOMEDSImpl_AttributeTreeNode *aFirstNode = NULL, *aNode = NULL;
230   
231   if(aFirstLabel.IsNull()) return false;
232   if((aFirstNode=(SALOMEDSImpl_AttributeTreeNode*)aFirstLabel.FindAttribute(_root->ID()))) {
233     aFirstNode->Remove();
234     aFirstLabel.ForgetAttribute(aFirstNode->ID());
235   }
236
237   aFirstNode = SALOMEDSImpl_AttributeTreeNode::Set(aFirstLabel, _root->ID());
238   
239   if(aLabel.IsNull()) return false;
240   if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;    
241
242   aFirstNode->Remove();
243
244   bool ret = aNode->InsertBefore(aFirstNode);
245
246   // Mantis issue 0020136: Drag&Drop in OB
247   SALOMEDSImpl_Study::GetStudyImpl(theFirst.GetLabel())->addSO_Notification(theFirst);
248
249   return ret;
250 }
251
252
253 //============================================================================
254 /*! Function : SetCurrentObject
255  *  Purpose  :
256  */
257 //============================================================================
258 bool SALOMEDSImpl_UseCaseBuilder::SetCurrentObject(const SALOMEDSImpl_SObject& theObject)
259 {
260   if(!_root || !theObject) return false;
261
262   DF_Label aLabel = theObject.GetLabel();
263   SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
264   if(aLabel.IsNull()) return false;
265   if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
266
267   SALOMEDSImpl_AttributeReference* aRef = NULL;
268   if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
269     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), aNode->Label());  
270   }
271   
272   aRef->Set(aNode->Label());
273
274   return true;
275 }
276
277 //============================================================================
278 /*! Function : SetRootCurrent
279  *  Purpose  :
280  */
281 //============================================================================
282 bool SALOMEDSImpl_UseCaseBuilder::SetRootCurrent()
283 {
284   if(!_root) return false;
285    
286   SALOMEDSImpl_AttributeReference* aRef = NULL;
287   if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) 
288     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());  
289
290   aRef->Set(_root->Label());
291   return true;
292 }
293
294 //============================================================================
295 /*! Function : HasChildren
296  *  Purpose  :
297  */
298 //============================================================================
299 bool SALOMEDSImpl_UseCaseBuilder::HasChildren(const SALOMEDSImpl_SObject& theObject)
300 {
301   if(!_root) return false;
302
303   DF_Label aLabel;
304   if (!theObject) aLabel = _root->Label();
305   else 
306     aLabel = theObject.GetLabel(); 
307   if(aLabel.IsNull()) return false;
308
309   SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
310   if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false; 
311   
312   return (aNode->GetFirst());
313 }
314
315 //============================================================================
316 /*! Function : SortChildren
317  *  Purpose  :
318  */
319 //============================================================================
320 bool SALOMEDSImpl_UseCaseBuilder::SortChildren(const SALOMEDSImpl_SObject& theObject, bool theAscendingOrder)
321 {
322   if(!_root) return false;
323
324   DF_Label aLabel;
325   if (!theObject) aLabel = _root->Label();
326   else 
327     aLabel = theObject.GetLabel(); 
328   if(aLabel.IsNull()) return false;
329
330   SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
331   if (!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false;
332
333   std::list<SALOMEDSImpl_SObject> aRefSOs;
334   std::list<SALOMEDSImpl_SObject> aNodeSOs;
335   for ( SALOMEDSImpl_AttributeTreeNode* aChildNode=aNode->GetFirst(); aChildNode; aChildNode=aChildNode->GetNext() ) {
336     if ( SALOMEDSImpl_SObject aSO = SALOMEDSImpl_Study::SObject( aChildNode->Label() ) ) {
337       if ( aChildNode->FindAttribute( SALOMEDSImpl_AttributeReference::GetID() ) )
338         aRefSOs.push_back( aSO );      
339       else
340         aNodeSOs.push_back( aSO );
341     }
342   }
343   if ( aRefSOs.empty() && aNodeSOs.empty() ) return false;
344
345  //sort items by names in ascending/descending order
346   std::list<SALOMEDSImpl_SObject>::iterator it;  
347   if ( !aRefSOs.empty() ) {
348     theAscendingOrder ? aRefSOs.sort( AscSortSOs() ) : aRefSOs.sort( DescSortSOs() );
349     for ( it = aRefSOs.begin(); it != aRefSOs.end(); ++it ) {
350       AppendTo( theObject, *it );
351     }
352   }  
353   if ( !aNodeSOs.empty() ) {
354     theAscendingOrder ? aNodeSOs.sort( AscSortSOs() ) : aNodeSOs.sort( DescSortSOs() );
355     for ( it = aNodeSOs.begin(); it != aNodeSOs.end(); ++it ) {
356       AppendTo( theObject, *it );
357     }
358   }
359
360   return true;
361 }
362
363 //============================================================================
364 /*! Function : GetFather
365  *  Purpose  :
366  */
367 //============================================================================
368 SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::GetFather(const SALOMEDSImpl_SObject& theObject)
369 {
370   SALOMEDSImpl_SObject so;
371   if (!_root || !theObject) return so;
372
373   DF_Label aLabel = theObject.GetLabel(); 
374   if (aLabel.IsNull()) return so;
375
376   SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
377   if (!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return so; 
378
379   SALOMEDSImpl_AttributeTreeNode* aFatherNode = aNode->GetFather();
380   if (!aFatherNode) return so;
381
382   return aFatherNode->GetSObject();
383 }
384
385 //============================================================================
386 /*! Function : SetName
387  *  Purpose  :
388  */
389 //============================================================================
390 bool SALOMEDSImpl_UseCaseBuilder::SetName(const std::string& theName) {
391   if(!_root) return false;
392
393   SALOMEDSImpl_AttributeName* aNameAttrib = NULL;
394
395   if (!(aNameAttrib=(SALOMEDSImpl_AttributeName*)_root->FindAttribute(SALOMEDSImpl_AttributeName::GetID())))
396     aNameAttrib = SALOMEDSImpl_AttributeName::Set(_root->Label(), theName);
397      
398   aNameAttrib->SetValue(theName);
399     
400   return true;
401 }
402
403
404 //============================================================================
405 /*! Function : GetCurrentObject
406  *  Purpose  :
407  */
408 //============================================================================
409 SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::GetCurrentObject()
410 {
411   SALOMEDSImpl_SObject so;
412   if(!_root) return so;
413
414   SALOMEDSImpl_AttributeReference* aRef = NULL;
415   if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
416     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());  
417   }  
418   
419   DF_Label aCurrent = aRef->Get();  
420   if(aCurrent.IsNull()) return so;
421
422   return SALOMEDSImpl_Study::SObject(aCurrent);
423 }
424
425 //============================================================================
426 /*! Function : GetName
427  *  Purpose  :
428  */
429 //============================================================================
430 std::string SALOMEDSImpl_UseCaseBuilder::GetName() 
431 {
432   std::string aString;
433   if(!_root) return aString;
434   
435   SALOMEDSImpl_AttributeName* aName = NULL;
436   if (!(aName=(SALOMEDSImpl_AttributeName*)_root->FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) return aString;
437   return aName->Value();
438 }
439
440 //============================================================================ 
441 /*! Function :  IsUseCase
442  *  Purpose  :  
443  */ 
444 //============================================================================ 
445 bool SALOMEDSImpl_UseCaseBuilder::IsUseCase(const SALOMEDSImpl_SObject& theObject)
446 {
447   if(!theObject) return false;
448   DF_Label aFather, aLabel = theObject.GetLabel(); 
449   aFather = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG);
450   if(aLabel.Father() == aFather) return true;
451   return false;
452 }
453
454 //============================================================================ 
455 /*! Function :  IsUseCaseNode
456  *  Purpose  :  
457  */ 
458 //============================================================================ 
459 bool SALOMEDSImpl_UseCaseBuilder::IsUseCaseNode(const SALOMEDSImpl_SObject& theObject)
460 {
461   if(!_root) return false;
462
463   DF_Label aLabel;
464   if (!theObject) aLabel = _root->Label();
465   else 
466     aLabel = theObject.GetLabel(); 
467   if(aLabel.IsNull()) return false;
468
469   SALOMEDSImpl_AttributeTreeNode* aNode = NULL;
470   if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false; 
471   
472   return true;
473 }
474
475 //============================================================================ 
476 /*! Function : NewUseCase 
477  *  Purpose  :  
478  */ 
479 //============================================================================ 
480 SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::AddUseCase(const std::string& theName)
481 {
482   std::string aBasicGUID(USE_CASE_GUID);
483
484   //Create a use cases structure if it not exists 
485
486   SALOMEDSImpl_AttributeTreeNode *aFatherNode = NULL, *aNode = NULL;
487   SALOMEDSImpl_AttributeInteger* anInteger = NULL;
488   SALOMEDSImpl_AttributeReference* aRef = NULL;
489
490   DF_Label aLabel = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG);
491
492   if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
493     aRef = SALOMEDSImpl_AttributeReference::Set(aLabel, aLabel);
494   }
495  
496   if(!(aFatherNode=(SALOMEDSImpl_AttributeTreeNode*)aRef->Get().FindAttribute(aBasicGUID))) {
497     aFatherNode = SALOMEDSImpl_AttributeTreeNode::Set(aRef->Get(), aBasicGUID);
498   }
499
500   if(!(anInteger=(SALOMEDSImpl_AttributeInteger*)_root->FindAttribute(SALOMEDSImpl_AttributeInteger::GetID()))) {
501     anInteger = SALOMEDSImpl_AttributeInteger::Set(aLabel, 0);
502   }    
503
504   //Create a new use case
505   anInteger->SetValue(anInteger->Value()+1);
506   DF_Label aChild = aLabel.FindChild(anInteger->Value());
507   aNode = SALOMEDSImpl_AttributeTreeNode::Set(aChild, aBasicGUID);
508   aNode->Remove();
509   aFatherNode->Append(aNode);
510   SALOMEDSImpl_AttributeName::Set(aChild, theName);
511
512   return SALOMEDSImpl_Study::SObject(aChild);
513 }
514
515 //============================================================================
516 /*! Function : GetUseCaseIterator
517  *  Purpose  : Creates a new UseCase iterator, if anObject is null all use cases are iterated 
518  */
519 //============================================================================
520 SALOMEDSImpl_UseCaseIterator
521 SALOMEDSImpl_UseCaseBuilder::GetUseCaseIterator(const SALOMEDSImpl_SObject& theObject) 
522 {
523   DF_Label aLabel;
524
525   if(theObject) {
526     aLabel = theObject.GetLabel(); //Iterate only sub tree in the use case
527   }
528   else {
529     aLabel = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG); //Iterate all use cases
530   }
531
532   return SALOMEDSImpl_UseCaseIterator(aLabel, USE_CASE_GUID, false); 
533 }
534
535
536 SALOMEDSImpl_SObject SALOMEDSImpl_UseCaseBuilder::GetSObject(const std::string& theEntry)
537 {
538   DF_Label L = DF_Label::Label(_root->Label(), theEntry);
539   return SALOMEDSImpl_Study::SObject(L);    
540 }