]> SALOME platform Git repositories - modules/kernel.git/blob - src/SALOMEDSImpl/SALOMEDSImpl_AttributeTreeNode.cxx
Salome HOME
PR: merge from branch BR_UnitTests tag mergeto_trunk_17oct05
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_AttributeTreeNode.cxx
1 //  File   : SALOMEDSImpl_AttributeTreeNode.cxx
2 //  Author : Sergey RUIN
3 //  Module : SALOME
4
5
6 #include "SALOMEDSImpl_AttributeTreeNode.hxx"
7 #include <Standard_DomainError.hxx>
8 #include <TDF_Tool.hxx>
9 #include <TDF_Data.hxx>
10 #include <TDF_DataSet.hxx>
11 #include <TDF_RelocationTable.hxx>
12 #include <TCollection_AsciiString.hxx> 
13
14 using namespace std;
15
16 IMPLEMENT_STANDARD_HANDLE( SALOMEDSImpl_AttributeTreeNode, SALOMEDSImpl_GenericAttribute )
17 IMPLEMENT_STANDARD_RTTIEXT( SALOMEDSImpl_AttributeTreeNode, SALOMEDSImpl_GenericAttribute )
18
19 static char* Entry(const TDF_Label& theLabel) 
20 {
21   TCollection_AsciiString anEntry;
22   TDF_Tool::Entry(theLabel, anEntry);
23   return anEntry.ToCString();
24 }  
25
26 const Standard_GUID&  SALOMEDSImpl_AttributeTreeNode::GetDefaultTreeID()
27 {
28   static Standard_GUID TreeNodeID ("0E1C36E6-379B-4d90-AC37-17A14310E648");
29   return TreeNodeID;
30 }    
31
32
33 SALOMEDSImpl_AttributeTreeNode::SALOMEDSImpl_AttributeTreeNode() 
34 :SALOMEDSImpl_GenericAttribute("AttributeTreeNode"), myFather(NULL),  myPrevious(NULL), myNext(NULL), myFirst(NULL) 
35 {}
36
37
38 Handle(SALOMEDSImpl_AttributeTreeNode) SALOMEDSImpl_AttributeTreeNode::Set (const TDF_Label& L, const Standard_GUID& ID) 
39 {
40   Handle(SALOMEDSImpl_AttributeTreeNode) TN;
41
42   if (!L.FindAttribute(ID,TN)) {
43     TN = new SALOMEDSImpl_AttributeTreeNode ();
44     TN->SetTreeID(ID);
45     L.AddAttribute(TN);
46   }
47
48   return TN;    
49 }
50
51 //=======================================================================
52 //TreeNode : ID
53 //purpose  : Returns GUID of the TreeNode
54 //=======================================================================
55 const Standard_GUID& SALOMEDSImpl_AttributeTreeNode::ID() const
56 {
57   return myTreeID;
58 }  
59
60 //=======================================================================
61 //function : Append
62 //purpose  : Add <TN> as last child of me
63 //=======================================================================
64 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::Append (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
65 {
66   CheckLocked();
67
68   if (!(TN->ID() == myTreeID) )
69     Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::Append : uncompatible GUID");
70
71   Handle(SALOMEDSImpl_AttributeTreeNode) bid;
72   TN->SetNext(bid); // Deconnects from next.
73
74   // Find the last
75   if (!HasFirst()) {
76     SetFirst(TN);
77     TN->SetPrevious(bid); // Deconnects from previous.
78   }
79   else {
80     Handle(SALOMEDSImpl_AttributeTreeNode) Last = GetFirst();
81     while (Last->HasNext()) {
82       Last = Last->GetNext();
83     }
84     Last->SetNext(TN);
85     TN->SetPrevious(Last);
86   }
87   // Set Father
88   TN->SetFather(this);
89   
90   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
91   
92   return !TN.IsNull();
93 }
94
95 //=======================================================================
96 //function : Prepend
97 //purpose  : Add <TN> as first child of me
98 //=======================================================================
99 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::Prepend (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
100 {
101   CheckLocked();
102
103   if (!(TN->ID() == myTreeID) )
104     Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::Prepend : uncompatible GUID");
105
106   Handle(SALOMEDSImpl_AttributeTreeNode) bid;
107   TN->SetPrevious(bid);
108   if (HasFirst()) {
109     TN->SetNext(GetFirst());
110     GetFirst()->SetPrevious(TN);
111   }
112   else {
113     TN->SetNext(bid);
114   }
115   TN->SetFather(this);
116   SetFirst(TN);
117   
118   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
119   
120   return !TN.IsNull();
121 }                     
122
123
124 //=======================================================================
125 //function : InsertBefore
126 //purpose  : Inserts the TreeNode  <TN> before me
127 //=======================================================================
128 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::InsertBefore (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
129 {
130   CheckLocked();
131
132   if (!(TN->ID() == myTreeID) )
133     Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::InsertBefore : uncompatible GUID");
134
135   TN->SetFather(GetFather());
136   TN->SetPrevious(GetPrevious());
137   TN->SetNext(this);
138
139   if (!HasPrevious())
140     GetFather()->SetFirst(TN);
141   else
142     GetPrevious()->SetNext(TN);
143
144   SetPrevious(TN);
145   
146   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
147   
148   return !TN.IsNull();
149 }
150
151 //=======================================================================
152 //function : InsertAfter
153 //purpose  : Inserts the TreeNode  <TN> after me
154 //=======================================================================
155 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::InsertAfter (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
156 {
157   CheckLocked();
158
159   if (!(TN->ID() == myTreeID) )
160     Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::InsertAfter : uncompatible GUID");
161
162   TN->SetFather(GetFather());
163   TN->SetPrevious(this);
164   TN->SetNext(GetNext());
165
166   if (HasNext()) GetNext()->SetPrevious(TN);
167
168   SetNext(TN);
169   
170   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
171   
172   return !TN.IsNull();
173 }         
174
175 //=======================================================================
176 //function : Remove
177 //purpose  : Removees the function from the function tree
178 //=======================================================================
179 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::Remove ()
180 {
181   CheckLocked();
182
183   if (IsRoot()) return Standard_True;
184
185   Handle(SALOMEDSImpl_AttributeTreeNode) bid;
186   if (!HasPrevious())
187     GetFather()->SetFirst(GetNext());
188   else
189     GetPrevious()->SetNext(GetNext());
190
191   if (HasNext()) {
192     if (HasPrevious()) GetNext()->SetPrevious(GetPrevious());
193     else GetNext()->SetPrevious(bid);
194   }
195   else {
196     if (HasPrevious()) GetPrevious()->SetNext(bid);
197   }
198
199   if (GetFather()->HasFirst()) {
200     if (Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(this) == GetFather()->GetFirst()) {
201       if (HasNext()) {
202         GetFather()->SetFirst(GetNext());
203       }
204       else GetFather()->SetFirst(bid);
205     }
206   }
207
208   SetFather(bid);
209   SetNext(bid);
210   SetPrevious(bid);
211
212   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
213
214   return Standard_True;
215 }         
216
217 //=======================================================================
218 //function : Depth
219 //purpose  :
220 //=======================================================================
221 Standard_Integer SALOMEDSImpl_AttributeTreeNode::Depth () const
222 {
223   Standard_Integer depth = 0;
224   Handle(SALOMEDSImpl_AttributeTreeNode) current = this;
225   while (current->HasFather()) {
226     depth++;
227     current = current->GetFather();
228   }
229   return depth;
230 }
231
232 //=======================================================================
233 //function : SetTreeID
234 //purpose  : Finds or creates a TreeNode  attribute with explicit ID
235 //         : a driver for it
236 //=======================================================================
237 void SALOMEDSImpl_AttributeTreeNode::SetTreeID (const Standard_GUID& explicitID)
238 {
239   myTreeID = explicitID;
240   
241   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
242 }
243
244
245 //=======================================================================
246 //function : IsAscendant
247 //purpose  :
248 //=======================================================================
249 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsAscendant (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
250 {
251   return ofTN->IsDescendant(this);
252 }                
253
254 //=======================================================================
255 //function : IsDescendant
256 //purpose  :
257 //=======================================================================
258
259 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsDescendant (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
260 {
261   Handle(SALOMEDSImpl_AttributeTreeNode) current = this;
262   while (current->HasFather()) {
263     if (current->GetFather() == ofTN) return Standard_True;
264     current = current->GetFather();
265   }
266   return Standard_False;
267 }
268
269 //=======================================================================
270 //function : IsFather
271 //purpose  :
272 //=======================================================================
273
274 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsFather (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
275 {
276   return (ofTN->GetFather() == this);
277 }
278
279
280 //=======================================================================
281 //function : IsChild
282 //purpose  :
283 //=======================================================================
284
285 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsChild (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
286 {
287   return (myFather == ofTN);
288 }
289
290 //=======================================================================
291 //TreeNode : IsRoot
292 //purpose  : Returns Standard_True if the TreeNode is not attached to a
293 //           TreeNode tree or hasn't an Father.
294 //=======================================================================
295 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsRoot() const
296 {
297   if (myFather.IsNull() &&
298       myPrevious.IsNull() &&
299       myNext.IsNull())
300     return Standard_True;
301   return Standard_False;
302 }
303
304 //=======================================================================
305 //TreeNode : Root
306 //purpose  : Returns the TreeNode which has no Father
307 //=======================================================================
308 Handle(SALOMEDSImpl_AttributeTreeNode) SALOMEDSImpl_AttributeTreeNode::Root() const
309 {
310   Handle(SALOMEDSImpl_AttributeTreeNode) O = this;
311   while (O->HasFather())
312     O = O->GetFather();
313   return O;
314 }       
315
316 //=======================================================================
317 //TreeNode : SetFather
318 //purpose  : Sets the TreeNode F as Father of me
319 //=======================================================================
320 void SALOMEDSImpl_AttributeTreeNode::SetFather(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
321 {
322   CheckLocked();
323   Backup();
324   myFather = F;
325   
326   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
327 }
328
329 //=======================================================================
330 //TreeNode : SetNext
331 //purpose  : Sets the TreeNode F next to me
332 //=======================================================================
333 void SALOMEDSImpl_AttributeTreeNode::SetNext(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
334 {
335   CheckLocked();
336   Backup();
337   myNext = F;
338   
339   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
340 }
341
342
343 //=======================================================================
344 //TreeNode : SetPrevious
345 //purpose  : Sets the TreeNode F previous to me
346 //=======================================================================
347 void SALOMEDSImpl_AttributeTreeNode::SetPrevious(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
348 {
349   CheckLocked();
350   Backup();
351   myPrevious = F;
352   
353   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
354 }
355
356 //=======================================================================
357 //TreeNode : SetFirst
358 //purpose  : Sets the TreeNode F as first in the TreeNode tree
359 //=======================================================================
360 void SALOMEDSImpl_AttributeTreeNode::SetFirst(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
361 {
362   CheckLocked();
363   Backup();
364   myFirst = F;
365   
366   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
367 }         
368
369 //=======================================================================
370 //TreeNode : AfterAddition
371 //purpose  : Connects the TreeNode to the tree.
372 //           Backuped attribute must stay disconnected
373 //=======================================================================
374 void SALOMEDSImpl_AttributeTreeNode::AfterAddition() 
375 {
376   if (!IsBackuped()) {
377     if (!myPrevious.IsNull()) {
378       myPrevious->SetNext(this);
379     }
380     else if (!myFather.IsNull()) {
381       myFather->SetFirst(this);
382     }
383     if (!myNext.IsNull())
384       myNext->SetPrevious(this);
385   }
386 }
387
388 //=======================================================================
389 //TreeNode : BeforeForget
390 //purpose  : Disconnect the TreeNode from the tree.
391 //           Backuped attribute is normaly not concerned by such an operation
392 //=======================================================================
393 void SALOMEDSImpl_AttributeTreeNode::BeforeForget() 
394 {
395   if (!IsBackuped()) {
396     Remove();
397     while (HasFirst()) GetFirst()->Remove();
398   }
399 }
400
401 //=======================================================================
402 //TreeNode : AfterResume
403 //purpose  : Connects the TreeNode to the tree
404 //=======================================================================
405 void SALOMEDSImpl_AttributeTreeNode::AfterResume() 
406 {
407   AfterAddition();
408 }
409
410 //=======================================================================
411 //TreeNode : BeforeUndo
412 //purpose  : Disconnect the TreeNode from the tree.
413 //=======================================================================
414 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::BeforeUndo(const Handle(TDF_AttributeDelta)& anAttDelta,
415                                                             const Standard_Boolean forceIt)
416 {
417   if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnAddition))) BeforeForget(); // Disconnect.
418   return Standard_True;
419 }           
420
421 //=======================================================================
422 //TreeNode : AfterUndo
423 //purpose  : Connect the TreeNode from the tree.
424 //=======================================================================
425 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::AfterUndo(const Handle(TDF_AttributeDelta)& anAttDelta,
426                                                            const Standard_Boolean forceIt)
427 {
428   if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnRemoval))) AfterAddition(); // Reconnect.
429   return Standard_True;
430 }
431
432 //=======================================================================
433 //TreeNode : Restore
434 //purpose  :
435 //=======================================================================
436 void SALOMEDSImpl_AttributeTreeNode::Restore(const Handle(TDF_Attribute)& other) 
437 {
438   Handle(SALOMEDSImpl_AttributeTreeNode) F =  Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(other);
439   myFather     = F->myFather;
440   myPrevious   = F->myPrevious;
441   myNext       = F->myNext;
442   myFirst      = F->myFirst;
443   myTreeID     = F->myTreeID;
444 }       
445
446 //=======================================================================
447 //TreeNode : Paste
448 //purpose  : Method for Copy mechanism
449 //=======================================================================
450
451 void SALOMEDSImpl_AttributeTreeNode::Paste(const Handle(TDF_Attribute)& into,
452                                            const Handle(TDF_RelocationTable)& RT) const
453 {
454   Handle(SALOMEDSImpl_AttributeTreeNode) intof = Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(into);
455   Handle(SALOMEDSImpl_AttributeTreeNode) func;
456   if (!RT->HasRelocation(myFather, func) && RT->AfterRelocate()) {
457     func.Nullify();
458   }
459   intof->SetFather(func);
460   if (!RT->HasRelocation(myNext, func) && RT->AfterRelocate()) {
461     func.Nullify();
462   }
463   intof->SetNext(func);
464   if (!RT->HasRelocation(myPrevious, func) && RT->AfterRelocate()) {
465     func.Nullify();
466   }
467   intof->SetPrevious(func);
468   if (!RT->HasRelocation(myFirst, func) && RT->AfterRelocate()) {
469     func.Nullify();
470   }
471
472   intof->SetFirst(func);
473   intof->SetTreeID(myTreeID);
474 }
475
476 //=======================================================================
477 //TreeNode : NewEmpty
478 //purpose  : Returns new empty TreeNode attribute
479 //=======================================================================
480
481 Handle(TDF_Attribute) SALOMEDSImpl_AttributeTreeNode::NewEmpty() const
482 {
483   Handle(SALOMEDSImpl_AttributeTreeNode) T = new SALOMEDSImpl_AttributeTreeNode();
484   T->SetTreeID(myTreeID);
485   return T;
486 }
487
488 //=======================================================================
489 //TreeNode : References
490 //purpose  : Collects the references
491 //=======================================================================
492 void SALOMEDSImpl_AttributeTreeNode::References(const Handle(TDF_DataSet)& aDataSet) const
493 {
494   Handle(SALOMEDSImpl_AttributeTreeNode) fct = myFirst;
495   while (!fct.IsNull()) {
496     aDataSet->AddAttribute(fct);
497     fct = fct->myNext;
498   }
499 }          
500
501 TCollection_AsciiString SALOMEDSImpl_AttributeTreeNode::Type()
502 {
503    char* aNodeName = new char[60];
504    char aGUID[40];
505    ID().ToCString(aGUID);
506    sprintf(aNodeName, "AttributeTreeNodeGUID%s",aGUID);
507    TCollection_AsciiString ret(aNodeName); 
508    delete aNodeName;
509    
510    return ret;                               
511 }
512
513 TCollection_AsciiString SALOMEDSImpl_AttributeTreeNode::Save() 
514 {
515   TCollection_AsciiString aFather, aPrevious, aNext, aFirst;
516
517   if (HasFather()) aFather = Entry(GetFather()->Label()); else aFather = "!";
518   if (HasPrevious()) aPrevious = Entry(GetPrevious()->Label()); else aPrevious = "!";
519   if (HasNext()) aNext = Entry(GetNext()->Label()); else aNext = "!";
520   if (HasFirst()) aFirst = Entry(GetFirst()->Label()); else aFirst = "!";
521
522   int aLength = 4;
523   aLength += aFather.Length() + aPrevious.Length() + aNext.Length() + aFirst.Length();
524   char* aResult = new char[aLength];
525   sprintf(aResult, "%s %s %s %s", aFather.ToCString(), aPrevious.ToCString(), aNext.ToCString(), aFirst.ToCString());
526   TCollection_AsciiString ret(aResult);
527   delete aResult;
528   return ret;
529 }
530
531 void SALOMEDSImpl_AttributeTreeNode::Load(const TCollection_AsciiString& value) 
532 {
533   Handle(TDF_Data) DF = Label().Data();
534   
535   char* aCopy = (char*)value.ToCString();
536   char* adr = strtok(aCopy, " ");
537   
538   TDF_Label aLabel;
539   Handle(SALOMEDSImpl_AttributeTreeNode) aDepNode;
540
541   if (adr && adr[0] != '!') {
542     TDF_Tool::Label(DF, adr, aLabel, 1);
543     if (!aLabel.FindAttribute(ID(), aDepNode)) 
544       aDepNode =  SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
545
546     SetFather(aDepNode);
547   }
548
549   adr = strtok(NULL, " ");
550   if (adr && adr[0] != '!') {
551     TDF_Tool::Label(DF, adr, aLabel, 1);
552     if (!aLabel.FindAttribute(ID(), aDepNode)) 
553       aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
554     SetPrevious(aDepNode);
555   }
556
557   adr = strtok(NULL, " ");
558   if (adr && adr[0] != '!') {
559     TDF_Tool::Label(DF, adr, aLabel, 1);
560     if (!aLabel.FindAttribute(ID(), aDepNode)) 
561       aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
562     SetNext(aDepNode);
563   }
564
565   adr = strtok(NULL, " ");
566   if (adr && adr[0] != '!') {
567     TDF_Tool::Label(DF, adr, aLabel, 1);
568     if (!aLabel.FindAttribute(ID(), aDepNode)) 
569       aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
570     SetFirst(aDepNode);
571   }
572 }
573
574