1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "DF_definitions.hxx"
21 #include "DF_Label.hxx"
22 #include "DF_Document.hxx"
23 #include "DF_Attribute.hxx"
24 #include "DF_ChildIterator.hxx"
28 //Class DF_Label defines a persistence reference in DF_Document that contains a tree of Labels.
29 //This reference is named "entry" and is a sequence of tags divided by ":". The root entry is "0:".
30 //For example "0:1:1" corresponds the following structure
37 DF_Label DF_Label::Label(const DF_Label& theLabel, const std::string& theEntry, bool isCreated)
39 if(theLabel.IsNull()) return DF_Label();
41 DF_Label aLabel = theLabel.Root();
42 if(theEntry == "0:") return aLabel;
43 if(theEntry == "0:1") return theLabel.GetDocument()->Main();
45 char* cc = (char*)theEntry.c_str();
47 std::vector<int> tags;
50 while ( *cc >= '0' && *cc <= '9') {
51 n = 10*n + (*cc - '0');
54 if (*cc == ':' || *cc == '\0') {
57 if (*cc != '\0') ++cc;
65 if(!tags.size()) return DF_Label();
67 for(int i = 1, len = tags.size(); !aLabel.IsNull() && i<len; i++)
68 aLabel = aLabel.FindChild(tags[i], isCreated);
73 DF_Label::DF_Label(DF_LabelNode* theNode)
85 DF_Label::DF_Label(const DF_Label& theLabel)
87 _node = theLabel._node;
90 DF_Label& DF_Label::operator=(const DF_Label& theLabel)
92 _node = theLabel._node;
102 //Returns a smart pointer to Document which contains this Label
103 DF_Document* DF_Label::GetDocument() const
105 if(!_node) return NULL;
106 return _node->_document;
109 //Returns true if theLabel equals to this label
110 bool DF_Label::operator==(const DF_Label& theLabel)
112 if(IsNull() || theLabel.IsNull()) return false;
113 return (theLabel.Entry() == Entry());
116 //Returns true if theLabel doesn't equals to this label
117 bool DF_Label::operator!=(const DF_Label& theLabel)
119 if(IsNull() || theLabel.IsNull()) return true;
120 return (theLabel.Entry() != Entry());
124 //Returns a tag of this Label
125 int DF_Label::Tag() const
127 if(!_node) return -1;
131 //Returns true if this Label is attached to the tree in the Document.
132 bool DF_Label::IsAttached()
134 if(!_node) return false;
135 return _node->_document != 0;
138 //Searches an Attribute with given ID located on this Label.
139 //Returns true if the Attribute is found.
140 DF_Attribute* DF_Label::FindAttribute(const std::string& theID) const
142 if(!_node) return NULL;
144 if(_node->_attributes.find(theID) == _node->_attributes.end()) return NULL;
145 return _node->_attributes[theID];
148 //Returns true if there is an Attribute with given ID on this Label.
149 bool DF_Label::IsAttribute(const std::string& theID) const
151 if(!_node) return false;
153 return (_node->_attributes.find(theID) != _node->_attributes.end());
156 //Adds theAttribute to the Label where this Attribute is located.
157 //Returns true if theAttribute was added.
158 bool DF_Label::AddAttribute(DF_Attribute* theAttribute) const
160 if(!_node) return false;
162 if(_node->_attributes.find(theAttribute->ID()) != _node->_attributes.end()) return false;
163 theAttribute->_node = _node;
164 _node->_attributes[theAttribute->ID()] = theAttribute;
165 theAttribute->AfterAddition();
170 //Forgets an Attribute with given ID located on the this Label.
171 bool DF_Label::ForgetAttribute(const std::string& theID) const
173 if(!_node) return false;
175 if(_node->_attributes.find(theID) == _node->_attributes.end()) return false;
176 DF_Attribute* attr = _node->_attributes[theID];
177 attr->BeforeForget();
178 _node->_attributes.erase(theID);
184 //Forgets all Attributes located on this Label.
185 bool DF_Label::ForgetAllAttributes(bool clearChildren) const
187 if(!_node) return false;
189 std::vector<DF_Attribute*> va = GetAttributes();
190 _node->_attributes.clear();
192 for(int i = 0, len = va.size(); i<len; i++) {
193 va[i]->BeforeForget();
198 DF_ChildIterator CI(*this, true);
199 for(; CI.More(); CI.Next())
200 CI.Value().ForgetAllAttributes(true);
206 //Returns Father of this Label.
207 DF_Label DF_Label::Father() const
209 if(!_node) return DF_Label();
211 return _node->_father;
214 //Returns is this Label is not initialized
215 bool DF_Label::IsNull() const
217 return (!_node || (_node->_document == NULL));
220 //Returns is this Label is a Root label
221 bool DF_Label::IsRoot() const
223 if(IsNull() || Father().IsNull()) return true;
228 //Returns true if this Label has Attributes.
229 bool DF_Label::HasAttributes() const
231 if(!_node) return false;
233 return !(_node->_attributes.empty());
236 //Returns a list of Attributes of this Label.
237 std::vector<DF_Attribute*> DF_Label::GetAttributes() const
239 std::vector<DF_Attribute*> attributes;
240 if(!_node) return attributes;
242 typedef std::map<std::string, DF_Attribute*>::const_iterator AI;
243 std::vector<std::string> sorted;
244 for(AI p = _node->_attributes.begin(); p!=_node->_attributes.end(); p++)
245 sorted.push_back(p->first);
247 sort(sorted.begin(), sorted.end());
248 int len = sorted.size();
249 for(int i = 0; i<len; i++)
250 attributes.push_back(_node->_attributes[sorted[i]]);
255 //Returns true if this Label has a child Label.
256 bool DF_Label::HasChild() const
258 if(!_node) return false;
260 return _node->_firstChild != 0;
263 //Returns a number of child Labels.
264 int DF_Label::NbChildren() const
266 if(!_node) return -1;
268 if(!_node->_firstChild) return 0;
270 DF_LabelNode* next = _node->_firstChild->_next;
279 //Returns the depth (a number of fathers required to identify the Label) of this Label in the tree.
280 int DF_Label::Depth() const
282 if(!_node) return -1;
284 return _node->_depth;
287 //Returns true if this Label is a descendant of theLabel.
288 bool DF_Label::IsDescendant(const DF_Label& theLabel)
290 if(!_node) return false;
292 DF_LabelNode* father = _node->_father;
293 if(!father) return false;
296 if(father == theLabel._node) return true;
297 father = father->_father;
303 //Returns the root Label of a Label tree to which this Label belongs.
304 DF_Label DF_Label::Root() const
306 if(!_node) return DF_Label();
308 return _node->_document->Main().Father();
311 //Finds a child Label of this Label with a given tag. If isCreate = true and there is no child
312 //Label with the given tag, the child Label is created.
313 DF_Label DF_Label::FindChild(int theTag, bool isCreate)
315 if(!_node || IsNull()) return DF_Label();
317 DF_LabelNode *aLabel = NULL, *aPrevious = NULL, *aNext = NULL;
318 if(!_node->_firstChild && !isCreate) return DF_Label();
320 if(_node->_firstChild && _node->_firstChild->_tag == theTag)
321 return DF_Label(_node->_firstChild);
323 if(_node->_lastChild) {
324 if(_node->_lastChild->_tag == theTag) return DF_Label(_node->_lastChild);
325 if(_node->_lastChild->_tag < theTag) aPrevious = _node->_lastChild;
329 aLabel = _node->_firstChild;
331 if(aLabel->_tag == theTag) return DF_Label(aLabel);
332 if(aLabel->_tag > theTag) {
336 if(aLabel->_tag < theTag) aPrevious = aLabel;
337 aLabel = aLabel->_next;
341 if(!isCreate) return DF_Label();
343 DF_LabelNode* aChild = new DF_LabelNode();
344 aChild->_father = this->_node;
345 aChild->_document = _node->_document;
346 aChild->_tag = theTag;
347 aChild->_depth = _node->_depth+1;
349 aChild->_previous = aNext->_previous;
350 aChild->_next = aNext;
351 aNext->_previous = aChild;
354 aChild->_previous = aPrevious;
355 aChild->_next = aPrevious->_next;
356 aPrevious->_next = aChild;
359 if(!_node->_firstChild || (aNext && aNext == _node->_firstChild) ) _node->_firstChild = aChild;
360 if(!_node->_lastChild || !aNext) _node->_lastChild = aChild;
365 //Creates a new child Label of this Label.
366 DF_Label DF_Label::NewChild()
368 if(!_node || IsNull()) return DF_Label();
371 if(_node->_lastChild) tag = _node->_lastChild->_tag+1;
373 return FindChild(tag, true);
376 //Returns a string entry of this Label
377 std::string DF_Label::Entry() const
379 std::string entry = "";
381 DF_LabelNode* father = this->_node;
383 vi.push_back(father->_tag);
384 father = father->_father;
393 for(int i = len-1; i>=0; i--) {
395 sprintf(buffer, "%d", tag);
396 entry+=std::string(buffer);
404 bool DF_Label::IsEqual(const DF_Label& theLabel)
406 if(theLabel.IsNull() || IsNull()) return false;
407 DF_Label L(theLabel);
408 return (L.Entry() == Entry());
412 void DF_Label::Nullify()
418 void DF_Label::dump()
420 if(!_node) std::cout << "DF_Label addr : " << this << " NULL " << std::endl;
422 std::cout << "DF_Label addr : " << this->_node << " entry : " << Entry() << std::endl;
423 if(_node->_father) std::cout << " Father : " << _node->_father << " entry : " << Father().Entry() << std::endl;
424 else std::cout << " Father : NULL " << std::endl;
426 if(_node->_firstChild) std::cout << " FirstChild : " << _node->_firstChild << " entry : " << DF_Label(_node->_firstChild).Entry() << std::endl;
427 else std::cout << " FirstChild : NULL " << std::endl;
429 if(_node->_lastChild) std::cout << " LastChild : " << _node->_lastChild << " entry : " << DF_Label(_node->_lastChild).Entry() << std::endl;
430 else std::cout << " LastChild : NULL " << std::endl;
432 if(_node->_previous) std::cout << " Previous : " << _node->_previous << " entry : " << DF_Label(_node->_previous).Entry() << std::endl;
433 else std::cout << " Previous : NULL " << std::endl;
435 if(_node->_next) std::cout << " Next : " << _node->_next << " entry : " << DF_Label(_node->_next).Entry() << std::endl;
436 else std::cout << " Next : NULL " << std::endl;
442 ###############################################
444 ###############################################
447 DF_LabelNode::DF_LabelNode()
460 DF_LabelNode::~DF_LabelNode()
462 std::vector<DF_Attribute*> va;
463 typedef std::map<std::string, DF_Attribute*>::const_iterator AI;
464 for(AI p = _attributes.begin(); p!=_attributes.end(); p++)
465 va.push_back(p->second);
467 for(int i = 0, len = va.size(); i<len; i++)
474 void DF_LabelNode::Reset()
479 std::vector<DF_Attribute*> va;
480 typedef std::map<std::string, DF_Attribute*>::const_iterator AI;
481 for(AI p = _attributes.begin(); p!=_attributes.end(); p++)
482 va.push_back(p->second);
484 for(int i = 0, len = va.size(); i<len; i++)