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