Salome HOME
Updated copyright comment
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_AttributeTreeNode.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : SALOMEDSImpl_AttributeTreeNode.cxx
24 //  Author : Sergey RUIN
25 //  Module : SALOME
26 //
27 #include "SALOMEDSImpl_AttributeTreeNode.hxx"
28 #include <string.h>
29
30 const std::string&  SALOMEDSImpl_AttributeTreeNode::GetDefaultTreeID()
31 {
32   static std::string TreeNodeID ("0E1C36E6-379B-4d90-AC37-17A14310E648");
33   return TreeNodeID;
34 }    
35
36
37 SALOMEDSImpl_AttributeTreeNode::SALOMEDSImpl_AttributeTreeNode() 
38 :SALOMEDSImpl_GenericAttribute("AttributeTreeNode"), myFather(NULL),  myPrevious(NULL), myNext(NULL), myFirst(NULL) 
39 {}
40
41
42 SALOMEDSImpl_AttributeTreeNode* SALOMEDSImpl_AttributeTreeNode::Set (const DF_Label& L, const std::string& ID) 
43 {
44   SALOMEDSImpl_AttributeTreeNode* TN = NULL;
45
46   if (!(TN=(SALOMEDSImpl_AttributeTreeNode*)L.FindAttribute(ID))) {
47     TN = new SALOMEDSImpl_AttributeTreeNode ();
48     TN->SetTreeID(ID);
49     L.AddAttribute(TN);
50   }
51
52   return TN;    
53 }
54
55 //=======================================================================
56 //TreeNode : ID
57 //purpose  : Returns GUID of the TreeNode
58 //=======================================================================
59 const std::string& SALOMEDSImpl_AttributeTreeNode::ID() const
60 {
61   return myTreeID;
62 }  
63
64 //=======================================================================
65 //function : Append
66 //purpose  : Add <TN> as last child of me
67 //return   : index of TN under this, in C mode
68 //=======================================================================
69 bool SALOMEDSImpl_AttributeTreeNode::Append (SALOMEDSImpl_AttributeTreeNode* TN, int* childIndex)
70 {
71   CheckLocked();
72
73   if (!(TN->ID() == myTreeID)) throw DFexception("SALOMEDSImpl_AttributeTreeNode::Append : uncompatible GUID");
74
75   if(TN->Label() == Label()) throw DFexception("Attempt of self linking");
76
77   TN->SetNext(NULL); // Deconnects from next.
78
79   // Find the last
80   int index = 0;
81   if (!HasFirst()) {
82     SetFirst(TN);
83     TN->SetPrevious(NULL); // Deconnects from previous.
84   }
85   else {
86     SALOMEDSImpl_AttributeTreeNode* Last = GetFirst();
87     while (Last && Last->HasNext()) {
88       Last = Last->GetNext();
89       ++index;
90     }
91     Last->SetNext(TN);
92     TN->SetPrevious(Last);
93     ++index;
94   }
95   // Set Father
96   TN->SetFather(this);
97   
98   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
99
100   if ( childIndex )
101     *childIndex = index;
102
103   return (TN);
104 }
105
106 //=======================================================================
107 //function : Prepend
108 //purpose  : Add <TN> as first child of me
109 //=======================================================================
110 bool SALOMEDSImpl_AttributeTreeNode::Prepend (SALOMEDSImpl_AttributeTreeNode* TN)
111 {
112   CheckLocked();
113
114   if (!(TN->ID() == myTreeID) ) throw DFexception("SALOMEDSImpl_AttributeTreeNode::Prepend : uncompatible GUID");
115
116   if(TN->Label() == Label()) throw DFexception("Attempt of self linking");
117
118   TN->SetPrevious(NULL);
119   if (HasFirst()) {
120     TN->SetNext(GetFirst());
121     GetFirst()->SetPrevious(TN);
122   }
123   else {
124     TN->SetNext(NULL);
125   }
126   TN->SetFather(this);
127   SetFirst(TN);
128   
129   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
130   
131   return (TN);
132 }                     
133
134
135 //=======================================================================
136 //function : InsertBefore
137 //purpose  : Inserts the TreeNode  <TN> before me
138 //=======================================================================
139 bool SALOMEDSImpl_AttributeTreeNode::InsertBefore (SALOMEDSImpl_AttributeTreeNode* TN)
140 {
141   CheckLocked();
142
143   if (!(TN->ID() == myTreeID) ) throw DFexception("SALOMEDSImpl_AttributeTreeNode::InsertBefore : uncompatible GUID");
144
145   if(TN->Label() == Label()) throw DFexception("Attempt of self linking");
146
147   TN->SetFather(GetFather());
148   TN->SetPrevious(GetPrevious());
149   TN->SetNext(this);
150
151   if (!HasPrevious())
152     GetFather()->SetFirst(TN);
153   else
154     GetPrevious()->SetNext(TN);
155
156   SetPrevious(TN);
157   
158   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
159   
160   return (TN);
161 }
162
163 //=======================================================================
164 //function : InsertAfter
165 //purpose  : Inserts the TreeNode  <TN> after me
166 //=======================================================================
167 bool SALOMEDSImpl_AttributeTreeNode::InsertAfter (SALOMEDSImpl_AttributeTreeNode* TN)
168 {
169   CheckLocked();
170
171   if(TN->Label() == Label()) throw DFexception("Attempt of self linking");
172
173   if (!(TN->ID() == myTreeID) ) throw DFexception("SALOMEDSImpl_AttributeTreeNode::InsertAfter : uncompatible GUID");
174
175   TN->SetFather(GetFather());
176   TN->SetPrevious(this);
177   TN->SetNext(GetNext());
178
179   if (HasNext()) GetNext()->SetPrevious(TN);
180
181   SetNext(TN);
182   
183   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
184   
185   return (TN);
186 }         
187
188 //=======================================================================
189 //function : Remove
190 //purpose  : Removees the function from the function tree
191 //=======================================================================
192 bool SALOMEDSImpl_AttributeTreeNode::Remove ()
193 {
194   CheckLocked();
195
196   if (IsRoot()) return true;
197
198   if (!HasPrevious())
199     GetFather()->SetFirst(GetNext());
200   else
201     GetPrevious()->SetNext(GetNext());
202
203   if (HasNext()) {
204     if (HasPrevious()) GetNext()->SetPrevious(GetPrevious());
205     else GetNext()->SetPrevious(NULL);
206   }
207   else {
208     if (HasPrevious()) GetPrevious()->SetNext(NULL);
209   }
210
211   if (GetFather()->HasFirst()) {
212     if (this == GetFather()->GetFirst()) {
213       if (HasNext()) {
214         GetFather()->SetFirst(GetNext());
215       }
216       else GetFather()->SetFirst(NULL);
217     }
218   }
219
220   SetFather(NULL);
221   SetNext(NULL);
222   SetPrevious(NULL);
223
224   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
225
226   return true;
227 }         
228
229 //=======================================================================
230 //function : Depth
231 //purpose  :
232 //=======================================================================
233 int SALOMEDSImpl_AttributeTreeNode::Depth () const
234 {
235   int depth = 0;
236   SALOMEDSImpl_AttributeTreeNode* current = (SALOMEDSImpl_AttributeTreeNode*)this;
237   while (current) {
238     depth++;
239     current = current->GetFather();
240   }
241   return depth;
242 }
243
244 //=======================================================================
245 //function : SetTreeID
246 //purpose  : Finds or creates a TreeNode  attribute with explicit ID
247 //         : a driver for it
248 //=======================================================================
249 void SALOMEDSImpl_AttributeTreeNode::SetTreeID (const std::string& explicitID)
250 {
251   myTreeID = explicitID;
252   
253   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
254 }
255
256
257 //=======================================================================
258 //function : IsAscendant
259 //purpose  :
260 //=======================================================================
261 bool SALOMEDSImpl_AttributeTreeNode::IsAscendant (const SALOMEDSImpl_AttributeTreeNode* ofTN) const
262 {
263   return ofTN->IsDescendant(this);
264 }                
265
266 //=======================================================================
267 //function : IsDescendant
268 //purpose  :
269 //=======================================================================
270
271 bool SALOMEDSImpl_AttributeTreeNode::IsDescendant (const SALOMEDSImpl_AttributeTreeNode* ofTN) const
272 {
273   SALOMEDSImpl_AttributeTreeNode* current = (SALOMEDSImpl_AttributeTreeNode*)this;
274   while (current) {
275     if (current->GetFather() == ofTN) return true;
276     current = current->GetFather();
277   }
278   return false;
279 }
280
281 //=======================================================================
282 //function : IsFather
283 //purpose  :
284 //=======================================================================
285
286 bool SALOMEDSImpl_AttributeTreeNode::IsFather (const SALOMEDSImpl_AttributeTreeNode* ofTN) const
287 {
288   return (ofTN->GetFather() == this);
289 }
290
291
292 //=======================================================================
293 //function : IsChild
294 //purpose  :
295 //=======================================================================
296
297 bool SALOMEDSImpl_AttributeTreeNode::IsChild (const SALOMEDSImpl_AttributeTreeNode* ofTN) const
298 {
299   return (myFather == ofTN);
300 }
301
302 //=======================================================================
303 //TreeNode : IsRoot
304 //purpose  : Returns Standard_True if the TreeNode is not attached to a
305 //           TreeNode tree or hasn't an Father.
306 //=======================================================================
307 bool SALOMEDSImpl_AttributeTreeNode::IsRoot() const
308 {
309   if (!myFather && !myPrevious && !myNext)
310     return true;
311   return false;
312 }
313
314 //=======================================================================
315 //TreeNode : Root
316 //purpose  : Returns the TreeNode which has no Father
317 //=======================================================================
318 SALOMEDSImpl_AttributeTreeNode* SALOMEDSImpl_AttributeTreeNode::Root() const
319 {
320   SALOMEDSImpl_AttributeTreeNode* O = (SALOMEDSImpl_AttributeTreeNode*)this;
321   while (O && O->HasFather())
322     O = O->GetFather();
323   return O;
324 }       
325
326 //=======================================================================
327 //TreeNode : SetFather
328 //purpose  : Sets the TreeNode F as Father of me
329 //=======================================================================
330 void SALOMEDSImpl_AttributeTreeNode::SetFather(const SALOMEDSImpl_AttributeTreeNode* F)
331 {
332   CheckLocked();
333   Backup();
334   myFather = (SALOMEDSImpl_AttributeTreeNode*)F;
335   
336   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
337 }
338
339 //=======================================================================
340 //TreeNode : SetNext
341 //purpose  : Sets the TreeNode F next to me
342 //=======================================================================
343 void SALOMEDSImpl_AttributeTreeNode::SetNext(const SALOMEDSImpl_AttributeTreeNode* F)
344 {
345   CheckLocked();
346   Backup();
347   myNext = (SALOMEDSImpl_AttributeTreeNode*)F;
348   
349   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
350 }
351
352
353 //=======================================================================
354 //TreeNode : SetPrevious
355 //purpose  : Sets the TreeNode F previous to me
356 //=======================================================================
357 void SALOMEDSImpl_AttributeTreeNode::SetPrevious(const SALOMEDSImpl_AttributeTreeNode* F)
358 {
359   CheckLocked();
360   Backup();
361   myPrevious = (SALOMEDSImpl_AttributeTreeNode*)F;
362   
363   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
364 }
365
366 //=======================================================================
367 //TreeNode : SetFirst
368 //purpose  : Sets the TreeNode F as first in the TreeNode tree
369 //=======================================================================
370 void SALOMEDSImpl_AttributeTreeNode::SetFirst(const SALOMEDSImpl_AttributeTreeNode* F)
371 {
372   CheckLocked();
373   Backup();
374   myFirst = (SALOMEDSImpl_AttributeTreeNode*)F;
375   
376   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
377 }         
378
379 //=======================================================================
380 //TreeNode : AfterAddition
381 //purpose  : Connects the TreeNode to the tree.
382 //=======================================================================
383 void SALOMEDSImpl_AttributeTreeNode::AfterAddition() 
384 {
385   if (myPrevious) {
386     myPrevious->SetNext(this);
387   }
388   else if (myFather) {
389     myFather->SetFirst(this);
390   }
391   if (myNext) {
392     myNext->SetPrevious(this);
393   }
394 }
395
396 //=======================================================================
397 //TreeNode : BeforeForget
398 //purpose  : Disconnect the TreeNode from the tree.
399 //=======================================================================
400 void SALOMEDSImpl_AttributeTreeNode::BeforeForget() 
401 {
402     Remove();
403     while (HasFirst()) GetFirst()->Remove();
404 }
405
406 //=======================================================================
407 //TreeNode : Restore
408 //purpose  :
409 //=======================================================================
410 void SALOMEDSImpl_AttributeTreeNode::Restore(DF_Attribute* other) 
411 {
412   SALOMEDSImpl_AttributeTreeNode* F =  dynamic_cast<SALOMEDSImpl_AttributeTreeNode*>(other);
413   myFather     = F->myFather;
414   myPrevious   = F->myPrevious;
415   myNext       = F->myNext;
416   myFirst      = F->myFirst;
417   myTreeID     = F->myTreeID;
418 }       
419
420 //=======================================================================
421 //TreeNode : Paste
422 //purpose  : Method for Copy mechanism
423 //=======================================================================
424
425 void SALOMEDSImpl_AttributeTreeNode::Paste(DF_Attribute* into)
426 {
427   SALOMEDSImpl_AttributeTreeNode* intof = dynamic_cast<SALOMEDSImpl_AttributeTreeNode*>(into);
428   intof->SetFather(myFather);
429   intof->SetNext(myNext);
430   intof->SetPrevious(myPrevious);
431   intof->SetFirst(myFirst);
432   intof->SetTreeID(myTreeID);
433 }
434
435 //=======================================================================
436 //TreeNode : NewEmpty
437 //purpose  : Returns new empty TreeNode attribute
438 //=======================================================================
439
440 DF_Attribute* SALOMEDSImpl_AttributeTreeNode::NewEmpty() const
441 {
442   SALOMEDSImpl_AttributeTreeNode* T = new SALOMEDSImpl_AttributeTreeNode();
443   T->SetTreeID(myTreeID);
444   return T;
445 }
446
447 std::string SALOMEDSImpl_AttributeTreeNode::Type()
448 {
449    char* aNodeName = new char[127];
450    sprintf(aNodeName, "AttributeTreeNodeGUID%s", ID().c_str());
451    std::string ret(aNodeName); 
452    delete [] aNodeName;
453    
454    return ret;                               
455 }
456
457 std::string SALOMEDSImpl_AttributeTreeNode::Save() 
458 {
459   std::string aFather, aPrevious, aNext, aFirst;
460
461   if (HasFather()) aFather = GetFather()->Label().Entry(); else aFather = "!";
462   if (HasPrevious()) aPrevious = GetPrevious()->Label().Entry(); else aPrevious = "!";
463   if (HasNext()) aNext = GetNext()->Label().Entry(); else aNext = "!";
464   if (HasFirst()) aFirst = GetFirst()->Label().Entry(); else aFirst = "!";
465
466   int aLength = 4;
467   aLength += (int)(aFather.size() + aPrevious.size() + aNext.size() + aFirst.size()); //!< TODO: conversion from size_t to int
468   char* aResult = new char[aLength];
469   sprintf(aResult, "%s %s %s %s", aFather.c_str(), aPrevious.c_str(), aNext.c_str(), aFirst.c_str());
470   std::string ret(aResult);
471   delete [] aResult;
472   return ret;
473 }
474
475 void SALOMEDSImpl_AttributeTreeNode::Load(const std::string& value) 
476 {
477   char* aCopy = (char*)value.c_str();
478   char* adr = strtok(aCopy, " ");
479   
480   DF_Label aLabel;
481   SALOMEDSImpl_AttributeTreeNode* aDepNode = NULL;
482
483   if (adr && adr[0] != '!') {
484     aLabel = DF_Label::Label(Label(), adr, true);
485     if (!(aDepNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(ID()))) 
486       aDepNode =  SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
487
488     SetFather(aDepNode);
489   }
490
491   adr = strtok(NULL, " ");
492   if (adr && adr[0] != '!') {
493     aLabel = DF_Label::Label(Label(), adr, true);
494     if (!(aDepNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(ID()))) 
495       aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
496     SetPrevious(aDepNode);
497   }
498
499   adr = strtok(NULL, " ");
500   if (adr && adr[0] != '!') {
501     aLabel = DF_Label::Label(Label(), adr, true);
502     if (!(aDepNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(ID()))) 
503       aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
504     SetNext(aDepNode);
505   }
506
507   adr = strtok(NULL, " ");
508   if (adr && adr[0] != '!') {
509     aLabel = DF_Label::Label(Label(), adr, true);
510     if (!(aDepNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(ID()))) 
511       aDepNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, ID());
512     SetFirst(aDepNode);
513   }
514 }
515
516