1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include "DF_definitions.hxx"
23 #include "DF_Label.hxx"
24 #include "DF_Document.hxx"
25 #include "DF_Attribute.hxx"
26 #include "DF_ChildIterator.hxx"
32 //Class DF_Label defines a persistence reference in DF_Document that contains a tree of Labels.
33 //This reference is named "entry" and is a sequence of tags divided by ":". The root entry is "0:".
34 //For example "0:1:1" corresponds the following structure
41 DF_Label DF_Label::Label(const DF_Label& theLabel, const string& theEntry, bool isCreated)
43 if(theLabel.IsNull()) return DF_Label();
45 DF_Label aLabel = theLabel.Root();
46 if(theEntry == "0:") return aLabel;
47 if(theEntry == "0:1") return theLabel.GetDocument()->Main();
49 char* cc = (char*)theEntry.c_str();
54 while ( *cc >= '0' && *cc <= '9') {
55 n = 10*n + (*cc - '0');
58 if (*cc == ':' || *cc == '\0') {
61 if (*cc != '\0') ++cc;
69 if(!tags.size()) return DF_Label();
71 for(int i = 1, len = tags.size(); !aLabel.IsNull() && i<len; i++)
72 aLabel = aLabel.FindChild(tags[i], isCreated);
77 DF_Label::DF_Label(DF_LabelNode* theNode)
89 DF_Label::DF_Label(const DF_Label& theLabel)
91 _node = theLabel._node;
94 DF_Label& DF_Label::operator=(const DF_Label& theLabel)
96 _node = theLabel._node;
101 DF_Label::~DF_Label()
106 //Returns a smart pointer to Document which contains this Label
107 DF_Document* DF_Label::GetDocument() const
109 if(!_node) return NULL;
110 return _node->_document;
113 //Returns true if theLabel equals to this label
114 bool DF_Label::operator==(const DF_Label& theLabel)
116 if(IsNull() || theLabel.IsNull()) return false;
117 return (theLabel.Entry() == Entry());
120 //Returns true if theLabel doesn't equals to this label
121 bool DF_Label::operator!=(const DF_Label& theLabel)
123 if(IsNull() || theLabel.IsNull()) return true;
124 return (theLabel.Entry() != Entry());
128 //Returns a tag of this Label
129 int DF_Label::Tag() const
131 if(!_node) return -1;
135 //Returns true if this Label is attached to the tree in the Document.
136 bool DF_Label::IsAttached()
138 if(!_node) return false;
139 return (bool)(_node->_document);
142 //Searches an Attribute with given ID located on this Label.
143 //Returns true if the Attribute is found.
144 DF_Attribute* DF_Label::FindAttribute(const std::string& theID) const
146 if(!_node) return NULL;
148 if(_node->_attributes.find(theID) == _node->_attributes.end()) return NULL;
149 return _node->_attributes[theID];
152 //Returns true if there is an Attribute with given ID on this Label.
153 bool DF_Label::IsAttribute(const std::string& theID) const
155 if(!_node) return false;
157 return (_node->_attributes.find(theID) != _node->_attributes.end());
160 //Adds theAttribute to the Label where this Attribute is located.
161 //Returns true if theAttribute was added.
162 bool DF_Label::AddAttribute(DF_Attribute* theAttribute) const
164 if(!_node) return false;
166 if(_node->_attributes.find(theAttribute->ID()) != _node->_attributes.end()) return false;
167 theAttribute->_node = _node;
168 _node->_attributes[theAttribute->ID()] = theAttribute;
169 theAttribute->AfterAddition();
174 //Forgets an Attribute with given ID located on the this Label.
175 bool DF_Label::ForgetAttribute(const std::string& theID) const
177 if(!_node) return false;
179 if(_node->_attributes.find(theID) == _node->_attributes.end()) return false;
180 DF_Attribute* attr = _node->_attributes[theID];
181 attr->BeforeForget();
182 _node->_attributes.erase(theID);
188 //Forgets all Attributes located on this Label.
189 bool DF_Label::ForgetAllAttributes(bool clearChildren) const
191 if(!_node) return false;
193 vector<DF_Attribute*> va = GetAttributes();
194 _node->_attributes.clear();
196 for(int i = 0, len = va.size(); i<len; i++) {
197 va[i]->BeforeForget();
202 DF_ChildIterator CI(*this, true);
203 for(; CI.More(); CI.Next())
204 CI.Value().ForgetAllAttributes(true);
210 //Returns Father of this Label.
211 DF_Label DF_Label::Father() const
213 if(!_node) return DF_Label();
215 return _node->_father;
218 //Returns is this Label is not initialized
219 bool DF_Label::IsNull() const
221 return (!_node || (_node->_document == NULL));
224 //Returns is this Label is a Root label
225 bool DF_Label::IsRoot() const
227 if(IsNull() || Father().IsNull()) return true;
232 //Returns true if this Label has Attributes.
233 bool DF_Label::HasAttributes() const
235 if(!_node) return false;
237 return !(_node->_attributes.empty());
240 //Returns a list of Attributes of this Label.
241 vector<DF_Attribute*> DF_Label::GetAttributes() const
243 vector<DF_Attribute*> attributes;
244 if(!_node) return attributes;
246 typedef map<string, DF_Attribute*>::const_iterator AI;
247 vector<string> sorted;
248 for(AI p = _node->_attributes.begin(); p!=_node->_attributes.end(); p++)
249 sorted.push_back(p->first);
251 sort(sorted.begin(), sorted.end());
252 int len = sorted.size();
253 for(int i = 0; i<len; i++)
254 attributes.push_back(_node->_attributes[sorted[i]]);
259 //Returns true if this Label has a child Label.
260 bool DF_Label::HasChild() const
262 if(!_node) return false;
264 return (bool)(_node->_firstChild);
267 //Returns a number of child Labels.
268 int DF_Label::NbChildren() const
270 if(!_node) return -1;
272 if(!_node->_firstChild) return 0;
274 DF_LabelNode* next = _node->_firstChild->_next;
283 //Returns the depth (a number of fathers required to identify the Label) of this Label in the tree.
284 int DF_Label::Depth() const
286 if(!_node) return -1;
288 return _node->_depth;
291 //Returns true if this Label is a descendant of theLabel.
292 bool DF_Label::IsDescendant(const DF_Label& theLabel)
294 if(!_node) return false;
296 DF_LabelNode* father = _node->_father;
297 if(!father) return false;
300 if(father == theLabel._node) return true;
301 father = father->_father;
307 //Returns the root Label of a Label tree to which this Label belongs.
308 DF_Label DF_Label::Root() const
310 if(!_node) return DF_Label();
312 return _node->_document->Main().Father();
315 //Finds a child Label of this Label with a given tag. If isCreate = true and there is no child
316 //Label with the given tag, the child Label is created.
317 DF_Label DF_Label::FindChild(int theTag, bool isCreate)
319 if(!_node || IsNull()) return DF_Label();
321 DF_LabelNode *aLabel = NULL, *aPrevious = NULL, *aNext = NULL;
322 if(!_node->_firstChild && !isCreate) return DF_Label();
324 if(_node->_firstChild && _node->_firstChild->_tag == theTag)
325 return DF_Label(_node->_firstChild);
327 if(_node->_lastChild) {
328 if(_node->_lastChild->_tag == theTag) return DF_Label(_node->_lastChild);
329 if(_node->_lastChild->_tag < theTag) aPrevious = _node->_lastChild;
333 aLabel = _node->_firstChild;
335 if(aLabel->_tag == theTag) return DF_Label(aLabel);
336 if(aLabel->_tag > theTag) {
340 if(aLabel->_tag < theTag) aPrevious = aLabel;
341 aLabel = aLabel->_next;
345 if(!isCreate) return DF_Label();
347 DF_LabelNode* aChild = new DF_LabelNode();
348 aChild->_father = this->_node;
349 aChild->_document = _node->_document;
350 aChild->_tag = theTag;
351 aChild->_depth = _node->_depth+1;
353 aChild->_previous = aNext->_previous;
354 aChild->_next = aNext;
355 aNext->_previous = aChild;
358 aChild->_previous = aPrevious;
359 aChild->_next = aPrevious->_next;
360 aPrevious->_next = aChild;
363 if(!_node->_firstChild || (aNext && aNext == _node->_firstChild) ) _node->_firstChild = aChild;
364 if(!_node->_lastChild || !aNext) _node->_lastChild = aChild;
369 //Creates a new child Label of this Label.
370 DF_Label DF_Label::NewChild()
372 if(!_node || IsNull()) return DF_Label();
375 if(_node->_lastChild) tag = _node->_lastChild->_tag+1;
377 return FindChild(tag, true);
380 //Returns a string entry of this Label
381 string DF_Label::Entry() const
385 DF_LabelNode* father = this->_node;
387 vi.push_back(father->_tag);
388 father = father->_father;
397 for(int i = len-1; i>=0; i--) {
399 sprintf(buffer, "%d", tag);
400 entry+=string(buffer);
408 bool DF_Label::IsEqual(const DF_Label& theLabel)
410 if(theLabel.IsNull() || IsNull()) return false;
411 DF_Label L(theLabel);
412 return (L.Entry() == Entry());
416 void DF_Label::Nullify()
422 void DF_Label::dump()
424 if(!_node) cout << "DF_Label addr : " << this << " NULL " << endl;
426 cout << "DF_Label addr : " << this->_node << " entry : " << Entry() << endl;
427 if(_node->_father) cout << " Father : " << _node->_father << " entry : " << Father().Entry() << endl;
428 else cout << " Father : NULL " << endl;
430 if(_node->_firstChild) cout << " FirstChild : " << _node->_firstChild << " entry : " << DF_Label(_node->_firstChild).Entry() << endl;
431 else cout << " FirstChild : NULL " << endl;
433 if(_node->_lastChild) cout << " LastChild : " << _node->_lastChild << " entry : " << DF_Label(_node->_lastChild).Entry() << endl;
434 else cout << " LastChild : NULL " << endl;
436 if(_node->_previous) cout << " Previous : " << _node->_previous << " entry : " << DF_Label(_node->_previous).Entry() << endl;
437 else cout << " Previous : NULL " << endl;
439 if(_node->_next) cout << " Next : " << _node->_next << " entry : " << DF_Label(_node->_next).Entry() << endl;
440 else cout << " Next : NULL " << endl;
446 ###############################################
448 ###############################################
451 DF_LabelNode::DF_LabelNode()
464 DF_LabelNode::~DF_LabelNode()
466 vector<DF_Attribute*> va;
467 typedef map<string, DF_Attribute*>::const_iterator AI;
468 for(AI p = _attributes.begin(); p!=_attributes.end(); p++)
469 va.push_back(p->second);
471 for(int i = 0, len = va.size(); i<len; i++)
478 void DF_LabelNode::Reset()
483 vector<DF_Attribute*> va;
484 typedef map<string, DF_Attribute*>::const_iterator AI;
485 for(AI p = _attributes.begin(); p!=_attributes.end(); p++)
486 va.push_back(p->second);
488 for(int i = 0, len = va.size(); i<len; i++)