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/ or email : webmaster.salome@opencascade.com
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 if(TN->Label() == Label())
91 Standard_Failure::Raise("Attempt of self linking");
93 Handle(SALOMEDSImpl_AttributeTreeNode) bid;
94 TN->SetNext(bid); // Deconnects from next.
99 TN->SetPrevious(bid); // Deconnects from previous.
102 Handle(SALOMEDSImpl_AttributeTreeNode) Last = GetFirst();
103 while (Last->HasNext()) {
104 Last = Last->GetNext();
107 TN->SetPrevious(Last);
112 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
117 //=======================================================================
119 //purpose : Add <TN> as first child of me
120 //=======================================================================
121 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::Prepend (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
125 if (!(TN->ID() == myTreeID) )
126 Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::Prepend : uncompatible GUID");
128 if(TN->Label() == Label())
129 Standard_Failure::Raise("Attempt of self linking");
131 Handle(SALOMEDSImpl_AttributeTreeNode) bid;
132 TN->SetPrevious(bid);
134 TN->SetNext(GetFirst());
135 GetFirst()->SetPrevious(TN);
143 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
149 //=======================================================================
150 //function : InsertBefore
151 //purpose : Inserts the TreeNode <TN> before me
152 //=======================================================================
153 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::InsertBefore (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
157 if (!(TN->ID() == myTreeID) )
158 Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::InsertBefore : uncompatible GUID");
160 if(TN->Label() == Label())
161 Standard_Failure::Raise("Attempt of self linking");
163 TN->SetFather(GetFather());
164 TN->SetPrevious(GetPrevious());
168 GetFather()->SetFirst(TN);
170 GetPrevious()->SetNext(TN);
174 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
179 //=======================================================================
180 //function : InsertAfter
181 //purpose : Inserts the TreeNode <TN> after me
182 //=======================================================================
183 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::InsertAfter (const Handle(SALOMEDSImpl_AttributeTreeNode)& TN)
187 if(TN->Label() == Label())
188 Standard_Failure::Raise("Attempt of self linking");
190 if (!(TN->ID() == myTreeID) )
191 Standard_DomainError::Raise("SALOMEDSImpl_AttributeTreeNode::InsertAfter : uncompatible GUID");
193 TN->SetFather(GetFather());
194 TN->SetPrevious(this);
195 TN->SetNext(GetNext());
197 if (HasNext()) GetNext()->SetPrevious(TN);
201 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
206 //=======================================================================
208 //purpose : Removees the function from the function tree
209 //=======================================================================
210 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::Remove ()
214 if (IsRoot()) return Standard_True;
216 Handle(SALOMEDSImpl_AttributeTreeNode) bid;
218 GetFather()->SetFirst(GetNext());
220 GetPrevious()->SetNext(GetNext());
223 if (HasPrevious()) GetNext()->SetPrevious(GetPrevious());
224 else GetNext()->SetPrevious(bid);
227 if (HasPrevious()) GetPrevious()->SetNext(bid);
230 if (GetFather()->HasFirst()) {
231 if (Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(this) == GetFather()->GetFirst()) {
233 GetFather()->SetFirst(GetNext());
235 else GetFather()->SetFirst(bid);
243 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
245 return Standard_True;
248 //=======================================================================
251 //=======================================================================
252 Standard_Integer SALOMEDSImpl_AttributeTreeNode::Depth () const
254 Standard_Integer depth = 0;
255 Handle(SALOMEDSImpl_AttributeTreeNode) current = this;
256 while (current->HasFather()) {
258 current = current->GetFather();
263 //=======================================================================
264 //function : SetTreeID
265 //purpose : Finds or creates a TreeNode attribute with explicit ID
267 //=======================================================================
268 void SALOMEDSImpl_AttributeTreeNode::SetTreeID (const Standard_GUID& explicitID)
270 myTreeID = explicitID;
272 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
276 //=======================================================================
277 //function : IsAscendant
279 //=======================================================================
280 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsAscendant (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
282 return ofTN->IsDescendant(this);
285 //=======================================================================
286 //function : IsDescendant
288 //=======================================================================
290 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsDescendant (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
292 Handle(SALOMEDSImpl_AttributeTreeNode) current = this;
293 while (current->HasFather()) {
294 if (current->GetFather() == ofTN) return Standard_True;
295 current = current->GetFather();
297 return Standard_False;
300 //=======================================================================
301 //function : IsFather
303 //=======================================================================
305 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsFather (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
307 return (ofTN->GetFather() == this);
311 //=======================================================================
314 //=======================================================================
316 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsChild (const Handle(SALOMEDSImpl_AttributeTreeNode)& ofTN) const
318 return (myFather == ofTN);
321 //=======================================================================
323 //purpose : Returns Standard_True if the TreeNode is not attached to a
324 // TreeNode tree or hasn't an Father.
325 //=======================================================================
326 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::IsRoot() const
328 if (myFather.IsNull() &&
329 myPrevious.IsNull() &&
331 return Standard_True;
332 return Standard_False;
335 //=======================================================================
337 //purpose : Returns the TreeNode which has no Father
338 //=======================================================================
339 Handle(SALOMEDSImpl_AttributeTreeNode) SALOMEDSImpl_AttributeTreeNode::Root() const
341 Handle(SALOMEDSImpl_AttributeTreeNode) O = this;
342 while (O->HasFather())
347 //=======================================================================
348 //TreeNode : SetFather
349 //purpose : Sets the TreeNode F as Father of me
350 //=======================================================================
351 void SALOMEDSImpl_AttributeTreeNode::SetFather(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
357 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
360 //=======================================================================
362 //purpose : Sets the TreeNode F next to me
363 //=======================================================================
364 void SALOMEDSImpl_AttributeTreeNode::SetNext(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
370 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
374 //=======================================================================
375 //TreeNode : SetPrevious
376 //purpose : Sets the TreeNode F previous to me
377 //=======================================================================
378 void SALOMEDSImpl_AttributeTreeNode::SetPrevious(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
384 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
387 //=======================================================================
388 //TreeNode : SetFirst
389 //purpose : Sets the TreeNode F as first in the TreeNode tree
390 //=======================================================================
391 void SALOMEDSImpl_AttributeTreeNode::SetFirst(const Handle(SALOMEDSImpl_AttributeTreeNode)& F)
397 SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved
400 //=======================================================================
401 //TreeNode : AfterAddition
402 //purpose : Connects the TreeNode to the tree.
403 // Backuped attribute must stay disconnected
404 //=======================================================================
405 void SALOMEDSImpl_AttributeTreeNode::AfterAddition()
408 if (!myPrevious.IsNull()) {
409 myPrevious->SetNext(this);
411 else if (!myFather.IsNull()) {
412 myFather->SetFirst(this);
414 if (!myNext.IsNull())
415 myNext->SetPrevious(this);
419 //=======================================================================
420 //TreeNode : BeforeForget
421 //purpose : Disconnect the TreeNode from the tree.
422 // Backuped attribute is normaly not concerned by such an operation
423 //=======================================================================
424 void SALOMEDSImpl_AttributeTreeNode::BeforeForget()
428 while (HasFirst()) GetFirst()->Remove();
432 //=======================================================================
433 //TreeNode : AfterResume
434 //purpose : Connects the TreeNode to the tree
435 //=======================================================================
436 void SALOMEDSImpl_AttributeTreeNode::AfterResume()
441 //=======================================================================
442 //TreeNode : BeforeUndo
443 //purpose : Disconnect the TreeNode from the tree.
444 //=======================================================================
445 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::BeforeUndo(const Handle(TDF_AttributeDelta)& anAttDelta,
446 const Standard_Boolean forceIt)
448 if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnAddition))) BeforeForget(); // Disconnect.
449 return Standard_True;
452 //=======================================================================
453 //TreeNode : AfterUndo
454 //purpose : Connect the TreeNode from the tree.
455 //=======================================================================
456 Standard_Boolean SALOMEDSImpl_AttributeTreeNode::AfterUndo(const Handle(TDF_AttributeDelta)& anAttDelta,
457 const Standard_Boolean forceIt)
459 if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnRemoval))) AfterAddition(); // Reconnect.
460 return Standard_True;
463 //=======================================================================
466 //=======================================================================
467 void SALOMEDSImpl_AttributeTreeNode::Restore(const Handle(TDF_Attribute)& other)
469 Handle(SALOMEDSImpl_AttributeTreeNode) F = Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(other);
470 myFather = F->myFather;
471 myPrevious = F->myPrevious;
473 myFirst = F->myFirst;
474 myTreeID = F->myTreeID;
477 //=======================================================================
479 //purpose : Method for Copy mechanism
480 //=======================================================================
482 void SALOMEDSImpl_AttributeTreeNode::Paste(const Handle(TDF_Attribute)& into,
483 const Handle(TDF_RelocationTable)& RT) const
485 Handle(SALOMEDSImpl_AttributeTreeNode) intof = Handle(SALOMEDSImpl_AttributeTreeNode)::DownCast(into);
486 Handle(SALOMEDSImpl_AttributeTreeNode) func;
487 if (!RT->HasRelocation(myFather, func) && RT->AfterRelocate()) {
490 intof->SetFather(func);
491 if (!RT->HasRelocation(myNext, func) && RT->AfterRelocate()) {
494 intof->SetNext(func);
495 if (!RT->HasRelocation(myPrevious, func) && RT->AfterRelocate()) {
498 intof->SetPrevious(func);
499 if (!RT->HasRelocation(myFirst, func) && RT->AfterRelocate()) {
503 intof->SetFirst(func);
504 intof->SetTreeID(myTreeID);
507 //=======================================================================
508 //TreeNode : NewEmpty
509 //purpose : Returns new empty TreeNode attribute
510 //=======================================================================
512 Handle(TDF_Attribute) SALOMEDSImpl_AttributeTreeNode::NewEmpty() const
514 Handle(SALOMEDSImpl_AttributeTreeNode) T = new SALOMEDSImpl_AttributeTreeNode();
515 T->SetTreeID(myTreeID);
519 //=======================================================================
520 //TreeNode : References
521 //purpose : Collects the references
522 //=======================================================================
523 void SALOMEDSImpl_AttributeTreeNode::References(const Handle(TDF_DataSet)& aDataSet) const
525 Handle(SALOMEDSImpl_AttributeTreeNode) fct = myFirst;
526 while (!fct.IsNull()) {
527 aDataSet->AddAttribute(fct);
532 TCollection_AsciiString SALOMEDSImpl_AttributeTreeNode::Type()
534 char* aNodeName = new char[60];
536 ID().ToCString(aGUID);
537 sprintf(aNodeName, "AttributeTreeNodeGUID%s",aGUID);
538 TCollection_AsciiString ret(aNodeName);
544 TCollection_AsciiString SALOMEDSImpl_AttributeTreeNode::Save()
546 TCollection_AsciiString aFather, aPrevious, aNext, aFirst;
548 if (HasFather()) aFather = Entry(GetFather()->Label()); else aFather = "!";
549 if (HasPrevious()) aPrevious = Entry(GetPrevious()->Label()); else aPrevious = "!";
550 if (HasNext()) aNext = Entry(GetNext()->Label()); else aNext = "!";
551 if (HasFirst()) aFirst = Entry(GetFirst()->Label()); else aFirst = "!";
554 aLength += aFather.Length() + aPrevious.Length() + aNext.Length() + aFirst.Length();
555 char* aResult = new char[aLength];
556 sprintf(aResult, "%s %s %s %s", aFather.ToCString(), aPrevious.ToCString(), aNext.ToCString(), aFirst.ToCString());
557 TCollection_AsciiString ret(aResult);
562 void SALOMEDSImpl_AttributeTreeNode::Load(const TCollection_AsciiString& value)
564 Handle(TDF_Data) DF = Label().Data();
566 char* aCopy = (char*)value.ToCString();
567 char* adr = strtok(aCopy, " ");
570 Handle(SALOMEDSImpl_AttributeTreeNode) aDepNode;
572 if (adr && adr[0] != '!') {
573 TDF_Tool::Label(DF, adr, aLabel, 1);
574 if (!aLabel.FindAttribute(ID(), aDepNode))
575 aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
580 adr = strtok(NULL, " ");
581 if (adr && adr[0] != '!') {
582 TDF_Tool::Label(DF, adr, aLabel, 1);
583 if (!aLabel.FindAttribute(ID(), aDepNode))
584 aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
585 SetPrevious(aDepNode);
588 adr = strtok(NULL, " ");
589 if (adr && adr[0] != '!') {
590 TDF_Tool::Label(DF, adr, aLabel, 1);
591 if (!aLabel.FindAttribute(ID(), aDepNode))
592 aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
596 adr = strtok(NULL, " ");
597 if (adr && adr[0] != '!') {
598 TDF_Tool::Label(DF, adr, aLabel, 1);
599 if (!aLabel.FindAttribute(ID(), aDepNode))
600 aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());