1 // Created on: 1999-06-10
2 // Created by: Vladislav ROMASHKO
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <TDataStd_TreeNode.hxx>
19 #include <TDF_Label.hxx>
20 #include <TDF_DataSet.hxx>
21 #include <TDF_DeltaOnAddition.hxx>
22 #include <TDF_DeltaOnRemoval.hxx>
23 #include <TDF_RelocationTable.hxx>
24 #include <TDF_Tool.hxx>
25 #include <Standard_DomainError.hxx>
26 #include <Standard_Dump.hxx>
28 IMPLEMENT_STANDARD_RTTIEXT(TDataStd_TreeNode,TDF_Attribute)
30 //=======================================================================
33 //=======================================================================
35 Standard_Boolean TDataStd_TreeNode::Find(const TDF_Label& L,
36 Handle(TDataStd_TreeNode)& T)
38 return L.FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), T);
41 //=======================================================================
42 //TreeNode : GetDefaultTreeID
43 //purpose : Static method to get the default ID of a TreeNode
44 //=======================================================================
46 const Standard_GUID& TDataStd_TreeNode::GetDefaultTreeID()
48 static Standard_GUID TDataStd_TreeNodeID ("2a96b621-ec8b-11d0-bee7-080009dc3333");
49 return TDataStd_TreeNodeID;
52 //=======================================================================
54 //purpose : Finds or creates a TreeNode attribute with default ID
55 //=======================================================================
57 Handle(TDataStd_TreeNode) TDataStd_TreeNode::Set(const TDF_Label& L)
59 Handle(TDataStd_TreeNode) TN;
60 if (!L.FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(),TN)) {
61 TN = new TDataStd_TreeNode();
62 TN->SetTreeID(TDataStd_TreeNode::GetDefaultTreeID());
68 //=======================================================================
70 //purpose : Finds or creates a TreeNode attribute with explicit ID
72 //=======================================================================
74 Handle(TDataStd_TreeNode) TDataStd_TreeNode::Set (const TDF_Label& L,
75 const Standard_GUID& explicitID)
77 Handle(TDataStd_TreeNode) TN;
78 if (!L.FindAttribute(explicitID,TN)) {
79 TN = new TDataStd_TreeNode ();
80 TN->SetTreeID(explicitID);
86 //=======================================================================
88 //purpose : Returns GUID of the TreeNode
89 //=======================================================================
91 const Standard_GUID& TDataStd_TreeNode::ID() const
96 //=======================================================================
97 //TreeNode : TDataStd_TreeNode
98 //purpose : Constructor
99 //=======================================================================
101 TDataStd_TreeNode::TDataStd_TreeNode () :
102 myFather(NULL), myPrevious(NULL), myNext(NULL), myFirst(NULL), myLast(NULL)
106 //=======================================================================
108 //purpose : Add <TN> as last child of me
109 //=======================================================================
111 Standard_Boolean TDataStd_TreeNode::Append (const Handle(TDataStd_TreeNode)& TN)
113 if (!(TN->ID() == myTreeID) )
114 throw Standard_DomainError("TDataStd_TreeNode::Append : uncompatible GUID");
116 Handle(TDataStd_TreeNode) bid;
117 TN->SetNext(bid); // Deconnects from next.
122 TN->SetPrevious(bid); // Deconnects from previous.
126 Handle(TDataStd_TreeNode) L = Last();
132 myLast=TN.operator->();
136 //=======================================================================
138 //purpose : Add <TN> as first child of me
139 //=======================================================================
141 Standard_Boolean TDataStd_TreeNode::Prepend (const Handle(TDataStd_TreeNode)& TN)
143 if (!(TN->ID() == myTreeID) )
144 throw Standard_DomainError("TDataStd_TreeNode::Prepend : uncompatible GUID");
146 Handle(TDataStd_TreeNode) bid;
147 TN->SetPrevious(bid);
149 TN->SetNext(First());
150 First()->SetPrevious(TN);
161 //=======================================================================
162 //function : InsertBefore
163 //purpose : Inserts the TreeNode <TN> before me
164 //=======================================================================
166 Standard_Boolean TDataStd_TreeNode::InsertBefore (const Handle(TDataStd_TreeNode)& TN)
168 if (!(TN->ID() == myTreeID) )
169 throw Standard_DomainError("TDataStd_TreeNode::InsertBefore : uncompatible GUID");
171 TN->SetFather(Father());
172 TN->SetPrevious(Previous());
176 Father()->SetFirst(TN);
178 Previous()->SetNext(TN);
184 //=======================================================================
185 //function : InsertAfter
186 //purpose : Inserts the TreeNode <TN> after me
187 //=======================================================================
189 Standard_Boolean TDataStd_TreeNode::InsertAfter (const Handle(TDataStd_TreeNode)& TN)
191 if (!(TN->ID() == myTreeID) )
192 throw Standard_DomainError("TDataStd_TreeNode::InsertAfter : uncompatible GUID");
194 if (HasFather() && !HasNext())
195 Father()->SetLast(TN);
197 TN->SetFather(Father());
198 TN->SetPrevious(this);
202 Next()->SetPrevious(TN);
208 //=======================================================================
210 //purpose : Removees the function from the function tree
211 //=======================================================================
213 Standard_Boolean TDataStd_TreeNode::Remove ()
215 if (IsRoot()) return Standard_True;
217 Handle(TDataStd_TreeNode) bid;
219 Father()->SetFirst(Next());
221 Previous()->SetNext(Next());
224 if (HasPrevious()) Next()->SetPrevious(Previous());
225 else Next()->SetPrevious(bid);
228 if (HasPrevious()) Previous()->SetNext(bid);
231 if (Father()->HasFirst()) {
232 if (this == Father()->First().operator->()) {
234 Father()->SetFirst(Next());
236 else Father()->SetFirst(bid);
240 if(Father()->HasLast()) {
241 Father()->SetLast(bid);
247 return Standard_True;
251 //=======================================================================
254 //=======================================================================
256 Standard_Integer TDataStd_TreeNode::Depth () const
258 Standard_Integer depth = 0;
260 TDataStd_TreeNode* O = (TDataStd_TreeNode*) this;
261 while (O->myFather != NULL)
270 //=======================================================================
271 //function : NbChildren
272 //purpose : Returns the number of child nodes.
273 // If <allLevels> is true, the method counts children of all levels
274 // (children of children ...)
275 //=======================================================================
276 Standard_Integer TDataStd_TreeNode::NbChildren(const Standard_Boolean allLevels) const
278 Standard_Integer nb = 0;
279 TDataStd_TreeNode* C = myFirst;
285 nb += C->NbChildren(allLevels);
293 //=======================================================================
294 //function : SetTreeID
295 //purpose : Finds or creates a TreeNode attribute with explicit ID
297 //=======================================================================
299 void TDataStd_TreeNode::SetTreeID (const Standard_GUID& explicitID)
301 myTreeID = explicitID;
305 //=======================================================================
306 //function : IsAscendant
308 //=======================================================================
310 Standard_Boolean TDataStd_TreeNode::IsAscendant (const Handle(TDataStd_TreeNode)& ofTN) const
312 return ofTN->IsDescendant(this);
316 //=======================================================================
317 //function : IsDescendant
319 //=======================================================================
321 Standard_Boolean TDataStd_TreeNode::IsDescendant (const Handle(TDataStd_TreeNode)& ofTN) const
323 TDataStd_TreeNode* O = (TDataStd_TreeNode*) this;
324 while (O->myFather != NULL)
326 if (O->myFather == ofTN)
327 return Standard_True;
330 return Standard_False;
333 //=======================================================================
334 //function : IsFather
336 //=======================================================================
338 Standard_Boolean TDataStd_TreeNode::IsFather (const Handle(TDataStd_TreeNode)& ofTN) const
340 return (ofTN->Father() == this);
344 //=======================================================================
347 //=======================================================================
349 Standard_Boolean TDataStd_TreeNode::IsChild (const Handle(TDataStd_TreeNode)& ofTN) const
351 return (myFather == ofTN.operator->());
355 //=======================================================================
357 //purpose : Returns the Father of the TreeNode
358 //=======================================================================
360 Handle(TDataStd_TreeNode) TDataStd_TreeNode::Father() const
362 Handle(TDataStd_TreeNode) O = myFather;
366 //=======================================================================
368 //purpose : Returns Standard_True if the TreeNode is not attached to a
369 // TreeNode tree or hasn't an Father.
370 //=======================================================================
372 Standard_Boolean TDataStd_TreeNode::IsRoot() const
374 if (myFather == NULL &&
375 myPrevious == NULL &&
377 return Standard_True;
378 return Standard_False;
381 //=======================================================================
383 //purpose : Returns the TreeNode which has no Father
384 //=======================================================================
386 Handle(TDataStd_TreeNode) TDataStd_TreeNode::Root() const
388 TDataStd_TreeNode* O = (TDataStd_TreeNode*) this;
389 while (O->myFather != NULL)
396 //=======================================================================
398 //purpose : Returns next (in the TreeNode tree) TreeNode
399 //=======================================================================
401 Handle(TDataStd_TreeNode) TDataStd_TreeNode::Next() const
403 Handle(TDataStd_TreeNode) O = myNext;
407 //=======================================================================
408 //TreeNode : Previous
409 //purpose : Returns previous (in the TreeNode tree) TreeNode
410 //=======================================================================
412 Handle(TDataStd_TreeNode) TDataStd_TreeNode::Previous() const
414 Handle(TDataStd_TreeNode) O = myPrevious;
418 //=======================================================================
420 //purpose : Returns first child
421 //=======================================================================
423 Handle(TDataStd_TreeNode) TDataStd_TreeNode::First () const
425 Handle(TDataStd_TreeNode) O = myFirst;
429 //=======================================================================
431 //purpose : Returns last child
432 // Optimize an Append operation if it is called in a circle
433 //=======================================================================
435 Handle(TDataStd_TreeNode) TDataStd_TreeNode::Last ()
437 if(myLast && !myLast->IsChild(this))
446 //=======================================================================
447 //TreeNode : FindLast
448 //purpose : Returns last child
449 // Optimizes an Append operation if it is called in a circle
450 //=======================================================================
451 Handle(TDataStd_TreeNode) TDataStd_TreeNode::FindLast ()
455 TDataStd_TreeNode* L = myFirst;
456 while (L->myNext != NULL)
463 //=======================================================================
464 //TreeNode : SetFather
465 //purpose : Sets the TreeNode F as Father of me
466 //=======================================================================
468 void TDataStd_TreeNode::SetFather(const Handle(TDataStd_TreeNode)& F)
471 if (F.IsNull()) myFather = NULL;
472 else myFather = F.operator->();
476 //=======================================================================
478 //purpose : Sets the TreeNode F next to me
479 //=======================================================================
481 void TDataStd_TreeNode::SetNext(const Handle(TDataStd_TreeNode)& F)
484 if (F.IsNull()) myNext = NULL;
485 else myNext = F.operator->();
490 //=======================================================================
491 //TreeNode : SetPrevious
492 //purpose : Sets the TreeNode F previous to me
493 //=======================================================================
495 void TDataStd_TreeNode::SetPrevious(const Handle(TDataStd_TreeNode)& F)
498 if (F.IsNull()) myPrevious = NULL;
499 else myPrevious = F.operator->();
503 //=======================================================================
504 //TreeNode : SetFirst
505 //purpose : Sets the TreeNode F as first in the TreeNode tree
506 //=======================================================================
508 void TDataStd_TreeNode::SetFirst(const Handle(TDataStd_TreeNode)& F)
511 if (F.IsNull()) myFirst = NULL;
512 else myFirst = F.operator->();
516 //=======================================================================
518 //purpose : Sets the TreeNode F as last in the TreeNode tree
519 //=======================================================================
521 void TDataStd_TreeNode::SetLast(const Handle(TDataStd_TreeNode)& F)
524 if (F.IsNull()) myLast = NULL;
525 else myLast = F.operator->();
528 //=======================================================================
529 //TreeNode : AfterAddition
530 //purpose : Connects the TreeNode to the tree.
531 // Backuped attribute must stay disconnected
532 //=======================================================================
534 void TDataStd_TreeNode::AfterAddition() {
537 myPrevious->SetNext(this);
539 myFather->SetFirst(this);
541 myNext->SetPrevious(this);
545 //=======================================================================
546 //TreeNode : BeforeForget
547 //purpose : Disconnect the TreeNode from the tree.
548 // Backuped attribute is normaly not concerned by such an operation
549 //=======================================================================
551 void TDataStd_TreeNode::BeforeForget() {
554 while (HasFirst()) First()->Remove();
558 //=======================================================================
559 //TreeNode : AfterResume
560 //purpose : Connects the TreeNode to the tree
561 //=======================================================================
563 void TDataStd_TreeNode::AfterResume() {
567 //=======================================================================
568 //TreeNode : BeforeUndo
569 //purpose : Disconnect the TreeNode from the tree.
570 //=======================================================================
572 Standard_Boolean TDataStd_TreeNode::BeforeUndo(const Handle(TDF_AttributeDelta)& anAttDelta,
573 const Standard_Boolean /*forceIt*/)
575 if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnAddition))) BeforeForget(); // Disconnect.
576 return Standard_True;
579 //=======================================================================
580 //TreeNode : AfterUndo
581 //purpose : Connect the TreeNode from the tree.
582 //=======================================================================
584 Standard_Boolean TDataStd_TreeNode::AfterUndo(const Handle(TDF_AttributeDelta)& anAttDelta,
585 const Standard_Boolean /*forceIt*/)
587 if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnRemoval))) AfterAddition(); // Reconnect.
588 return Standard_True;
591 //=======================================================================
594 //=======================================================================
596 void TDataStd_TreeNode::Restore(const Handle(TDF_Attribute)& other) {
597 Handle(TDataStd_TreeNode) F = Handle(TDataStd_TreeNode)::DownCast(other);
598 myFather = F->myFather;
599 myPrevious = F->myPrevious;
601 myFirst = F->myFirst;
602 myTreeID = F->myTreeID;
606 //=======================================================================
608 //purpose : Method for Copy mechanism
609 //=======================================================================
611 void TDataStd_TreeNode::Paste(const Handle(TDF_Attribute)& into,
612 const Handle(TDF_RelocationTable)& RT) const
614 Handle(TDataStd_TreeNode) intof = Handle(TDataStd_TreeNode)::DownCast(into);
615 Handle(TDataStd_TreeNode) func;
616 if (!RT->HasRelocation(myFather, func) && RT->AfterRelocate()) {
619 intof->SetFather(func);
620 if (!RT->HasRelocation(myNext, func) && RT->AfterRelocate()) {
623 intof->SetNext(func);
624 if (!RT->HasRelocation(myPrevious, func) && RT->AfterRelocate()) {
627 intof->SetPrevious(func);
628 if (!RT->HasRelocation(myFirst, func) && RT->AfterRelocate()) {
632 intof->SetFirst(func);
633 intof->SetTreeID(myTreeID);
636 //=======================================================================
637 //TreeNode : NewEmpty
638 //purpose : Returns new empty TreeNode attribute
639 //=======================================================================
641 Handle(TDF_Attribute) TDataStd_TreeNode::NewEmpty() const
643 Handle(TDataStd_TreeNode) T = new TDataStd_TreeNode();
644 T->SetTreeID(myTreeID);
648 //=======================================================================
649 //TreeNode : References
650 //purpose : Collects the references
651 //=======================================================================
653 void TDataStd_TreeNode::References(const Handle(TDF_DataSet)& aDataSet) const
655 TDataStd_TreeNode* fct = myFirst;
656 while (fct != NULL) {
657 aDataSet->AddAttribute(fct);
662 //=======================================================================
664 //purpose : Dump of the TreeNode
665 //=======================================================================
667 Standard_OStream& TDataStd_TreeNode::Dump (Standard_OStream& anOS) const
669 TDF_Attribute::Dump (anOS);
672 if (!myFather->Label().IsNull()) myFather->Label().EntryDump(anOS);
676 if (!myPrevious->Label().IsNull()) myPrevious->Label().EntryDump(anOS);
680 if (!myNext->Label().IsNull()) myNext->Label().EntryDump(anOS);
684 if (!myFirst->Label().IsNull()) myFirst->Label().EntryDump(anOS);
688 if (!myLast->Label().IsNull()) myLast->Label().EntryDump(anOS);
694 //=======================================================================
695 //function : DumpJson
697 //=======================================================================
698 void TDataStd_TreeNode::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
700 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
701 OCCT_DUMP_BASE_CLASS (theOStream, theDepth, TDF_Attribute)
705 TCollection_AsciiString aFather;
706 TDF_Tool::Entry (myFather->Label(), aFather);
707 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aFather)
711 TCollection_AsciiString aPrevious;
712 TDF_Tool::Entry (myPrevious->Label(), aPrevious);
713 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aPrevious)
717 TCollection_AsciiString aNext;
718 TDF_Tool::Entry (myNext->Label(), aNext);
719 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aNext)
723 TCollection_AsciiString aFirst;
724 TDF_Tool::Entry (myFirst->Label(), aFirst);
725 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aFirst)
729 TCollection_AsciiString aLast;
730 TDF_Tool::Entry (myLast->Label(), aLast);
731 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aLast)
734 OCCT_DUMP_FIELD_VALUE_GUID (theOStream, myTreeID)