1 // File : SALOMEDSImpl_AttributeTreeNode.cxx
2 // Author : Sergey RUIN
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>
16 IMPLEMENT_STANDARD_HANDLE( SALOMEDSImpl_AttributeTreeNode, SALOMEDSImpl_GenericAttribute )
17 IMPLEMENT_STANDARD_RTTIEXT( SALOMEDSImpl_AttributeTreeNode, SALOMEDSImpl_GenericAttribute )
19 static char* Entry(const TDF_Label& theLabel)
21 TCollection_AsciiString anEntry;
22 TDF_Tool::Entry(theLabel, anEntry);
23 return anEntry.ToCString();
26 const Standard_GUID& SALOMEDSImpl_AttributeTreeNode::GetDefaultTreeID()
28 static Standard_GUID TreeNodeID ("0E1C36E6-379B-4d90-AC37-17A14310E648");
33 SALOMEDSImpl_AttributeTreeNode::SALOMEDSImpl_AttributeTreeNode()
34 :SALOMEDSImpl_GenericAttribute("AttributeTreeNode"), myFather(NULL), myPrevious(NULL), myNext(NULL), myFirst(NULL)
38 Handle(SALOMEDSImpl_AttributeTreeNode) SALOMEDSImpl_AttributeTreeNode::Set (const TDF_Label& L, const Standard_GUID& ID)
40 Handle(SALOMEDSImpl_AttributeTreeNode) TN;
42 if (!L.FindAttribute(ID,TN)) {
43 TN = new SALOMEDSImpl_AttributeTreeNode ();
51 //=======================================================================
53 //purpose : Returns GUID of the TreeNode
54 //=======================================================================
55 const Standard_GUID& SALOMEDSImpl_AttributeTreeNode::ID() const
60 //=======================================================================
62 //purpose : Add <TN> as last child of me
63 //=======================================================================
64 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::Append (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
68 if (!(TN->ID() == myTreeID) )
69 Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::Append : uncompatible GUID");
71 Handle(SALOMEDSImpl_AttributeTreeNode) bid;
72 TN->SetNext(bid); // Deconnects from next.
77 TN->SetPrevious(bid); // Deconnects from previous.
80 Handle(SALOMEDSImpl_AttributeTreeNode) Last = GetFirst();
81 while (Last->HasNext()) {
82 Last = Last->GetNext();
85 TN->SetPrevious(Last);
90 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
95 //=======================================================================
97 //purpose : Add <TN> as first child of me
98 //=======================================================================
99 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::Prepend (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
103 if (!(TN->ID() == myTreeID) )
104 Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::Prepend : uncompatible GUID");
106 Handle(SALOMEDSImpl_AttributeTreeNode) bid;
107 TN->SetPrevious(bid);
109 TN->SetNext(GetFirst());
110 GetFirst()->SetPrevious(TN);
118 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
124 //=======================================================================
125 //function : InsertBefore
126 //purpose : Inserts the TreeNode <TN> before me
127 //=======================================================================
128 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::InsertBefore (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
132 if (!(TN->ID() == myTreeID) )
133 Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::InsertBefore : uncompatible GUID");
135 TN->SetFather(GetFather());
136 TN->SetPrevious(GetPrevious());
140 GetFather()->SetFirst(TN);
142 GetPrevious()->SetNext(TN);
146 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
151 //=======================================================================
152 //function : InsertAfter
153 //purpose : Inserts the TreeNode <TN> after me
154 //=======================================================================
155 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::InsertAfter (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
159 if (!(TN->ID() == myTreeID) )
160 Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::InsertAfter : uncompatible GUID");
162 TN->SetFather(GetFather());
163 TN->SetPrevious(this);
164 TN->SetNext(GetNext());
166 if (HasNext()) GetNext()->SetPrevious(TN);
170 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
175 //=======================================================================
177 //purpose : Removees the function from the function tree
178 //=======================================================================
179 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::Remove ()
183 if (IsRoot()) return Standard_True;
185 Handle(SALOMEDSImpl_AttributeTreeNode) bid;
187 GetFather()->SetFirst(GetNext());
189 GetPrevious()->SetNext(GetNext());
192 if (HasPrevious()) GetNext()->SetPrevious(GetPrevious());
193 else GetNext()->SetPrevious(bid);
196 if (HasPrevious()) GetPrevious()->SetNext(bid);
199 if (GetFather()->HasFirst()) {
200 if (Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(this) == GetFather()->GetFirst()) {
202 GetFather()->SetFirst(GetNext());
204 else GetFather()->SetFirst(bid);
212 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
214 return Standard_True;
217 //=======================================================================
220 //=======================================================================
221 Standard_Integer SALOMEDSImpl_AttributeTreeNode::Depth () const
223 Standard_Integer depth = 0;
224 Handle(SALOMEDSImpl_AttributeTreeNode) current = this;
225 while (current->HasFather()) {
227 current = current->GetFather();
232 //=======================================================================
233 //function : SetTreeID
234 //purpose : Finds or creates a TreeNode attribute with explicit ID
236 //=======================================================================
237 void SALOMEDSImpl_AttributeTreeNode::SetTreeID (const Standard_GUID& explicitID)
239 myTreeID = explicitID;
241 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
245 //=======================================================================
246 //function : IsAscendant
248 //=======================================================================
249 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsAscendant (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
251 return ofTN->IsDescendant(this);
254 //=======================================================================
255 //function : IsDescendant
257 //=======================================================================
259 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsDescendant (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
261 Handle(SALOMEDSImpl_AttributeTreeNode) current = this;
262 while (current->HasFather()) {
263 if (current->GetFather() == ofTN) return Standard_True;
264 current = current->GetFather();
266 return Standard_False;
269 //=======================================================================
270 //function : IsFather
272 //=======================================================================
274 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsFather (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
276 return (ofTN->GetFather() == this);
280 //=======================================================================
283 //=======================================================================
285 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsChild (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
287 return (myFather == ofTN);
290 //=======================================================================
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
297 if (myFather.IsNull() &&
298 myPrevious.IsNull() &&
300 return Standard_True;
301 return Standard_False;
304 //=======================================================================
306 //purpose : Returns the TreeNode which has no Father
307 //=======================================================================
308 Handle(SALOMEDSImpl_AttributeTreeNode) SALOMEDSImpl_AttributeTreeNode::Root() const
310 Handle(SALOMEDSImpl_AttributeTreeNode) O = this;
311 while (O->HasFather())
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)
326 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
329 //=======================================================================
331 //purpose : Sets the TreeNode F next to me
332 //=======================================================================
333 void SALOMEDSImpl_AttributeTreeNode::SetNext(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
339 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
343 //=======================================================================
344 //TreeNode : SetPrevious
345 //purpose : Sets the TreeNode F previous to me
346 //=======================================================================
347 void SALOMEDSImpl_AttributeTreeNode::SetPrevious(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
353 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
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)
366 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
369 //=======================================================================
370 //TreeNode : AfterAddition
371 //purpose : Connects the TreeNode to the tree.
372 // Backuped attribute must stay disconnected
373 //=======================================================================
374 void SALOMEDSImpl_AttributeTreeNode::AfterAddition()
377 if (!myPrevious.IsNull()) {
378 myPrevious->SetNext(this);
380 else if (!myFather.IsNull()) {
381 myFather->SetFirst(this);
383 if (!myNext.IsNull())
384 myNext->SetPrevious(this);
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()
397 while (HasFirst()) GetFirst()->Remove();
401 //=======================================================================
402 //TreeNode : AfterResume
403 //purpose : Connects the TreeNode to the tree
404 //=======================================================================
405 void SALOMEDSImpl_AttributeTreeNode::AfterResume()
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)
417 if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnAddition))) BeforeForget(); // Disconnect.
418 return Standard_True;
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)
428 if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnRemoval))) AfterAddition(); // Reconnect.
429 return Standard_True;
432 //=======================================================================
435 //=======================================================================
436 void SALOMEDSImpl_AttributeTreeNode::Restore(const Handle(TDF_Attribute)& other)
438 Handle(SALOMEDSImpl_AttributeTreeNode) F = Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(other);
439 myFather = F->myFather;
440 myPrevious = F->myPrevious;
442 myFirst = F->myFirst;
443 myTreeID = F->myTreeID;
446 //=======================================================================
448 //purpose : Method for Copy mechanism
449 //=======================================================================
451 void SALOMEDSImpl_AttributeTreeNode::Paste(const Handle(TDF_Attribute)& into,
452 const Handle(TDF_RelocationTable)& RT) const
454 Handle(SALOMEDSImpl_AttributeTreeNode) intof = Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(into);
455 Handle(SALOMEDSImpl_AttributeTreeNode) func;
456 if (!RT->HasRelocation(myFather, func) && RT->AfterRelocate()) {
459 intof->SetFather(func);
460 if (!RT->HasRelocation(myNext, func) && RT->AfterRelocate()) {
463 intof->SetNext(func);
464 if (!RT->HasRelocation(myPrevious, func) && RT->AfterRelocate()) {
467 intof->SetPrevious(func);
468 if (!RT->HasRelocation(myFirst, func) && RT->AfterRelocate()) {
472 intof->SetFirst(func);
473 intof->SetTreeID(myTreeID);
476 //=======================================================================
477 //TreeNode : NewEmpty
478 //purpose : Returns new empty TreeNode attribute
479 //=======================================================================
481 Handle(TDF_Attribute) SALOMEDSImpl_AttributeTreeNode::NewEmpty() const
483 Handle(SALOMEDSImpl_AttributeTreeNode) T = new SALOMEDSImpl_AttributeTreeNode();
484 T->SetTreeID(myTreeID);
488 //=======================================================================
489 //TreeNode : References
490 //purpose : Collects the references
491 //=======================================================================
492 void SALOMEDSImpl_AttributeTreeNode::References(const Handle(TDF_DataSet)& aDataSet) const
494 Handle(SALOMEDSImpl_AttributeTreeNode) fct = myFirst;
495 while (!fct.IsNull()) {
496 aDataSet->AddAttribute(fct);
501 TCollection_AsciiString SALOMEDSImpl_AttributeTreeNode::Type()
503 char* aNodeName = new char[60];
505 ID().ToCString(aGUID);
506 sprintf(aNodeName, "AttributeTreeNodeGUID%s",aGUID);
507 TCollection_AsciiString ret(aNodeName);
513 TCollection_AsciiString SALOMEDSImpl_AttributeTreeNode::Save()
515 TCollection_AsciiString aFather, aPrevious, aNext, aFirst;
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 = "!";
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);
531 void SALOMEDSImpl_AttributeTreeNode::Load(const TCollection_AsciiString& value)
533 Handle(TDF_Data) DF = Label().Data();
535 char* aCopy = (char*)value.ToCString();
536 char* adr = strtok(aCopy, " ");
539 Handle(SALOMEDSImpl_AttributeTreeNode) aDepNode;
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());
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);
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());
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());