1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/
20 // File : SALOMEDSImpl_AttributeTreeNode.cxx
21 // Author : Sergey RUIN
25 #include "SALOMEDSImpl_AttributeTreeNode.hxx"
26 #include <Standard_DomainError.hxx>
27 #include <TDF_Tool.hxx>
28 #include <TDF_Data.hxx>
29 #include <TDF_DataSet.hxx>
30 #include <TDF_RelocationTable.hxx>
31 #include <TCollection_AsciiString.hxx>
35 IMPLEMENT_STANDARD_HANDLE( SALOMEDSImpl_AttributeTreeNode, SALOMEDSImpl_GenericAttribute )
36 IMPLEMENT_STANDARD_RTTIEXT( SALOMEDSImpl_AttributeTreeNode, SALOMEDSImpl_GenericAttribute )
38 static char* Entry(const TDF_Label& theLabel)
40 TCollection_AsciiString anEntry;
41 TDF_Tool::Entry(theLabel, anEntry);
42 return anEntry.ToCString();
45 const Standard_GUID& SALOMEDSImpl_AttributeTreeNode::GetDefaultTreeID()
47 static Standard_GUID TreeNodeID ("0E1C36E6-379B-4d90-AC37-17A14310E648");
52 SALOMEDSImpl_AttributeTreeNode::SALOMEDSImpl_AttributeTreeNode()
53 :SALOMEDSImpl_GenericAttribute("AttributeTreeNode"), myFather(NULL), myPrevious(NULL), myNext(NULL), myFirst(NULL)
57 Handle(SALOMEDSImpl_AttributeTreeNode) SALOMEDSImpl_AttributeTreeNode::Set (const TDF_Label& L, const Standard_GUID& ID)
59 Handle(SALOMEDSImpl_AttributeTreeNode) TN;
61 if (!L.FindAttribute(ID,TN)) {
62 TN = new SALOMEDSImpl_AttributeTreeNode ();
70 //=======================================================================
72 //purpose : Returns GUID of the TreeNode
73 //=======================================================================
74 const Standard_GUID& SALOMEDSImpl_AttributeTreeNode::ID() const
79 //=======================================================================
81 //purpose : Add <TN> as last child of me
82 //=======================================================================
83 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::Append (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
87 if (!(TN->ID() == myTreeID) )
88 Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::Append : uncompatible GUID");
90 Handle(SALOMEDSImpl_AttributeTreeNode) bid;
91 TN->SetNext(bid); // Deconnects from next.
96 TN->SetPrevious(bid); // Deconnects from previous.
99 Handle(SALOMEDSImpl_AttributeTreeNode) Last = GetFirst();
100 while (Last->HasNext()) {
101 Last = Last->GetNext();
104 TN->SetPrevious(Last);
109 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
114 //=======================================================================
116 //purpose : Add <TN> as first child of me
117 //=======================================================================
118 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::Prepend (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
122 if (!(TN->ID() == myTreeID) )
123 Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::Prepend : uncompatible GUID");
125 Handle(SALOMEDSImpl_AttributeTreeNode) bid;
126 TN->SetPrevious(bid);
128 TN->SetNext(GetFirst());
129 GetFirst()->SetPrevious(TN);
137 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
143 //=======================================================================
144 //function : InsertBefore
145 //purpose : Inserts the TreeNode <TN> before me
146 //=======================================================================
147 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::InsertBefore (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
151 if (!(TN->ID() == myTreeID) )
152 Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::InsertBefore : uncompatible GUID");
154 TN->SetFather(GetFather());
155 TN->SetPrevious(GetPrevious());
159 GetFather()->SetFirst(TN);
161 GetPrevious()->SetNext(TN);
165 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
170 //=======================================================================
171 //function : InsertAfter
172 //purpose : Inserts the TreeNode <TN> after me
173 //=======================================================================
174 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::InsertAfter (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
178 if (!(TN->ID() == myTreeID) )
179 Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::InsertAfter : uncompatible GUID");
181 TN->SetFather(GetFather());
182 TN->SetPrevious(this);
183 TN->SetNext(GetNext());
185 if (HasNext()) GetNext()->SetPrevious(TN);
189 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
194 //=======================================================================
196 //purpose : Removees the function from the function tree
197 //=======================================================================
198 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::Remove ()
202 if (IsRoot()) return Standard_True;
204 Handle(SALOMEDSImpl_AttributeTreeNode) bid;
206 GetFather()->SetFirst(GetNext());
208 GetPrevious()->SetNext(GetNext());
211 if (HasPrevious()) GetNext()->SetPrevious(GetPrevious());
212 else GetNext()->SetPrevious(bid);
215 if (HasPrevious()) GetPrevious()->SetNext(bid);
218 if (GetFather()->HasFirst()) {
219 if (Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(this) == GetFather()->GetFirst()) {
221 GetFather()->SetFirst(GetNext());
223 else GetFather()->SetFirst(bid);
231 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
233 return Standard_True;
236 //=======================================================================
239 //=======================================================================
240 Standard_Integer SALOMEDSImpl_AttributeTreeNode::Depth () const
242 Standard_Integer depth = 0;
243 Handle(SALOMEDSImpl_AttributeTreeNode) current = this;
244 while (current->HasFather()) {
246 current = current->GetFather();
251 //=======================================================================
252 //function : SetTreeID
253 //purpose : Finds or creates a TreeNode attribute with explicit ID
255 //=======================================================================
256 void SALOMEDSImpl_AttributeTreeNode::SetTreeID (const Standard_GUID& explicitID)
258 myTreeID = explicitID;
260 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
264 //=======================================================================
265 //function : IsAscendant
267 //=======================================================================
268 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsAscendant (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
270 return ofTN->IsDescendant(this);
273 //=======================================================================
274 //function : IsDescendant
276 //=======================================================================
278 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsDescendant (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
280 Handle(SALOMEDSImpl_AttributeTreeNode) current = this;
281 while (current->HasFather()) {
282 if (current->GetFather() == ofTN) return Standard_True;
283 current = current->GetFather();
285 return Standard_False;
288 //=======================================================================
289 //function : IsFather
291 //=======================================================================
293 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsFather (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
295 return (ofTN->GetFather() == this);
299 //=======================================================================
302 //=======================================================================
304 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsChild (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
306 return (myFather == ofTN);
309 //=======================================================================
311 //purpose : Returns Standard_True if the TreeNode is not attached to a
312 // TreeNode tree or hasn't an Father.
313 //=======================================================================
314 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsRoot() const
316 if (myFather.IsNull() &&
317 myPrevious.IsNull() &&
319 return Standard_True;
320 return Standard_False;
323 //=======================================================================
325 //purpose : Returns the TreeNode which has no Father
326 //=======================================================================
327 Handle(SALOMEDSImpl_AttributeTreeNode) SALOMEDSImpl_AttributeTreeNode::Root() const
329 Handle(SALOMEDSImpl_AttributeTreeNode) O = this;
330 while (O->HasFather())
335 //=======================================================================
336 //TreeNode : SetFather
337 //purpose : Sets the TreeNode F as Father of me
338 //=======================================================================
339 void SALOMEDSImpl_AttributeTreeNode::SetFather(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
345 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
348 //=======================================================================
350 //purpose : Sets the TreeNode F next to me
351 //=======================================================================
352 void SALOMEDSImpl_AttributeTreeNode::SetNext(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
358 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
362 //=======================================================================
363 //TreeNode : SetPrevious
364 //purpose : Sets the TreeNode F previous to me
365 //=======================================================================
366 void SALOMEDSImpl_AttributeTreeNode::SetPrevious(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
372 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
375 //=======================================================================
376 //TreeNode : SetFirst
377 //purpose : Sets the TreeNode F as first in the TreeNode tree
378 //=======================================================================
379 void SALOMEDSImpl_AttributeTreeNode::SetFirst(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
385 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
388 //=======================================================================
389 //TreeNode : AfterAddition
390 //purpose : Connects the TreeNode to the tree.
391 // Backuped attribute must stay disconnected
392 //=======================================================================
393 void SALOMEDSImpl_AttributeTreeNode::AfterAddition()
396 if (!myPrevious.IsNull()) {
397 myPrevious->SetNext(this);
399 else if (!myFather.IsNull()) {
400 myFather->SetFirst(this);
402 if (!myNext.IsNull())
403 myNext->SetPrevious(this);
407 //=======================================================================
408 //TreeNode : BeforeForget
409 //purpose : Disconnect the TreeNode from the tree.
410 // Backuped attribute is normaly not concerned by such an operation
411 //=======================================================================
412 void SALOMEDSImpl_AttributeTreeNode::BeforeForget()
416 while (HasFirst()) GetFirst()->Remove();
420 //=======================================================================
421 //TreeNode : AfterResume
422 //purpose : Connects the TreeNode to the tree
423 //=======================================================================
424 void SALOMEDSImpl_AttributeTreeNode::AfterResume()
429 //=======================================================================
430 //TreeNode : BeforeUndo
431 //purpose : Disconnect the TreeNode from the tree.
432 //=======================================================================
433 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::BeforeUndo(const Handle(TDF_AttributeDelta)& anAttDelta,
434 const Standard_Boolean forceIt)
436 if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnAddition))) BeforeForget(); // Disconnect.
437 return Standard_True;
440 //=======================================================================
441 //TreeNode : AfterUndo
442 //purpose : Connect the TreeNode from the tree.
443 //=======================================================================
444 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::AfterUndo(const Handle(TDF_AttributeDelta)& anAttDelta,
445 const Standard_Boolean forceIt)
447 if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnRemoval))) AfterAddition(); // Reconnect.
448 return Standard_True;
451 //=======================================================================
454 //=======================================================================
455 void SALOMEDSImpl_AttributeTreeNode::Restore(const Handle(TDF_Attribute)& other)
457 Handle(SALOMEDSImpl_AttributeTreeNode) F = Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(other);
458 myFather = F->myFather;
459 myPrevious = F->myPrevious;
461 myFirst = F->myFirst;
462 myTreeID = F->myTreeID;
465 //=======================================================================
467 //purpose : Method for Copy mechanism
468 //=======================================================================
470 void SALOMEDSImpl_AttributeTreeNode::Paste(const Handle(TDF_Attribute)& into,
471 const Handle(TDF_RelocationTable)& RT) const
473 Handle(SALOMEDSImpl_AttributeTreeNode) intof = Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(into);
474 Handle(SALOMEDSImpl_AttributeTreeNode) func;
475 if (!RT->HasRelocation(myFather, func) && RT->AfterRelocate()) {
478 intof->SetFather(func);
479 if (!RT->HasRelocation(myNext, func) && RT->AfterRelocate()) {
482 intof->SetNext(func);
483 if (!RT->HasRelocation(myPrevious, func) && RT->AfterRelocate()) {
486 intof->SetPrevious(func);
487 if (!RT->HasRelocation(myFirst, func) && RT->AfterRelocate()) {
491 intof->SetFirst(func);
492 intof->SetTreeID(myTreeID);
495 //=======================================================================
496 //TreeNode : NewEmpty
497 //purpose : Returns new empty TreeNode attribute
498 //=======================================================================
500 Handle(TDF_Attribute) SALOMEDSImpl_AttributeTreeNode::NewEmpty() const
502 Handle(SALOMEDSImpl_AttributeTreeNode) T = new SALOMEDSImpl_AttributeTreeNode();
503 T->SetTreeID(myTreeID);
507 //=======================================================================
508 //TreeNode : References
509 //purpose : Collects the references
510 //=======================================================================
511 void SALOMEDSImpl_AttributeTreeNode::References(const Handle(TDF_DataSet)& aDataSet) const
513 Handle(SALOMEDSImpl_AttributeTreeNode) fct = myFirst;
514 while (!fct.IsNull()) {
515 aDataSet->AddAttribute(fct);
520 TCollection_AsciiString SALOMEDSImpl_AttributeTreeNode::Type()
522 char* aNodeName = new char[60];
524 ID().ToCString(aGUID);
525 sprintf(aNodeName, "AttributeTreeNodeGUID%s",aGUID);
526 TCollection_AsciiString ret(aNodeName);
532 TCollection_AsciiString SALOMEDSImpl_AttributeTreeNode::Save()
534 TCollection_AsciiString aFather, aPrevious, aNext, aFirst;
536 if (HasFather()) aFather = Entry(GetFather()->Label()); else aFather = "!";
537 if (HasPrevious()) aPrevious = Entry(GetPrevious()->Label()); else aPrevious = "!";
538 if (HasNext()) aNext = Entry(GetNext()->Label()); else aNext = "!";
539 if (HasFirst()) aFirst = Entry(GetFirst()->Label()); else aFirst = "!";
542 aLength += aFather.Length() + aPrevious.Length() + aNext.Length() + aFirst.Length();
543 char* aResult = new char[aLength];
544 sprintf(aResult, "%s %s %s %s", aFather.ToCString(), aPrevious.ToCString(), aNext.ToCString(), aFirst.ToCString());
545 TCollection_AsciiString ret(aResult);
550 void SALOMEDSImpl_AttributeTreeNode::Load(const TCollection_AsciiString& value)
552 Handle(TDF_Data) DF = Label().Data();
554 char* aCopy = (char*)value.ToCString();
555 char* adr = strtok(aCopy, " ");
558 Handle(SALOMEDSImpl_AttributeTreeNode) aDepNode;
560 if (adr && adr[0] != '!') {
561 TDF_Tool::Label(DF, adr, aLabel, 1);
562 if (!aLabel.FindAttribute(ID(), aDepNode))
563 aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
568 adr = strtok(NULL, " ");
569 if (adr && adr[0] != '!') {
570 TDF_Tool::Label(DF, adr, aLabel, 1);
571 if (!aLabel.FindAttribute(ID(), aDepNode))
572 aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
573 SetPrevious(aDepNode);
576 adr = strtok(NULL, " ");
577 if (adr && adr[0] != '!') {
578 TDF_Tool::Label(DF, adr, aLabel, 1);
579 if (!aLabel.FindAttribute(ID(), aDepNode))
580 aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
584 adr = strtok(NULL, " ");
585 if (adr && adr[0] != '!') {
586 TDF_Tool::Label(DF, adr, aLabel, 1);
587 if (!aLabel.FindAttribute(ID(), aDepNode))
588 aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());