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