Developer Documentation
TreeItem.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 #include "TreeItem.hh"
43 
44 QMap<int,TreeItem*> TreeItem::kTreeMap_;
45 
46 //--------------------------------------------------------------------------------
47 
48 TreeItem::TreeItem(int _id, QString _name, DataType _type, TreeItem* _parent) :
49  id_(_id),
50  dataType_(_type),
51  target_(true),
52  source_(false),
53  visible_(true),
54  name_(_name),
55  parentItem_(_parent),
56  row_(0)
57 {
58  // Remember ourself ;-)
59  kTreeMap_[_id] = this;
60 }
61 
62 
63 TreeItem::~TreeItem() {
64  // Remove itself from map
65  QMap<int,TreeItem*>::iterator iter = kTreeMap_.find( id() );
66  if( iter != kTreeMap_.end() ) {
67  kTreeMap_.erase(iter);
68  } else {
69  std::cerr << "Map accelerator destructor in DataControl: Currently removing object that is not in the map!" << std::endl;
70  }
71 }
72 
73 
74 // ===============================================================================
75 // Static Members
76 // ===============================================================================
77 
78 int TreeItem::id() {
79  return id_;
80 }
81 
82 //--------------------------------------------------------------------------------
83 
84 bool TreeItem::dataType(DataType _type) {
85  if ( _type == DATA_ALL ) {
86  return true;
87  }
88 
89  return ( dataType_ & _type);
90 }
91 
92 //--------------------------------------------------------------------------------
93 
95  return dataType_;
96 }
97 
98 //--------------------------------------------------------------------------------
99 
101  // Skip root node
102  if ( parent() == 0 )
103  return -1;
104 
105  // Don't count root node as a group
106  if ( parent()->parent() == 0 )
107  return -1;
108 
109  // Only consider groups
110  if ( !parent()->dataType(DATA_GROUP) )
111  return -1;
112 
113  // Get the group id
114  return ( parent()->id() );
115 }
116 
117 //--------------------------------------------------------------------------------
118 
119 bool TreeItem::isGroup() {
120  return ( dataType(DATA_GROUP) );
121 }
122 
123 // ===============================================================================
124 // Dynamic Members
125 // ===============================================================================
126 
128  return target_;
129 }
130 
131 //--------------------------------------------------------------------------------
132 
133 void TreeItem::target(bool _target) {
134  target_= _target;
135 }
136 
137 //--------------------------------------------------------------------------------
138 
140  return source_;
141 }
142 
143 //--------------------------------------------------------------------------------
144 
145 void TreeItem::source(bool _source) {
146  source_ = _source;
147 }
148 
149 //--------------------------------------------------------------------------------
150 
152  return visible_;
153 }
154 
155 //--------------------------------------------------------------------------------
156 
157 void TreeItem::visible(bool _visible) {
158  visible_ = _visible;
159 }
160 
161 //--------------------------------------------------------------------------------
162 
163 QString TreeItem::name() {
164  return name_;
165 }
166 
167 //--------------------------------------------------------------------------------
168 
169 void TreeItem::name(QString _name ) {
170  name_ = _name;
171 }
172 
173 // ===============================================================================
174 // Tree Structure
175 // ===============================================================================
176 
178  // Visit child item of this node
179  if ( childItems_.size() > 0 ) {
180  return childItems_[0];
181  }
182 
183  // No Child Item so visit the next child of the parentItem_
184  if ( parentItem_ ) {
185 
186  TreeItem* parentPointer = parentItem_;
187  TreeItem* thisPointer = this;
188 
189  // while we are not at the root node
190  while ( parentPointer ) {
191 
192  // If there is an unvisited child of the parent, return this one
193  int position = thisPointer->row() + 1;
194  if ( parentPointer->childCount() > position ) {
195  return parentPointer->childItems_[ position ];
196  }
197 
198  // Go to the next level
199  thisPointer = parentPointer;
200  parentPointer = parentPointer->parentItem_;
201 
202  }
203 
204  return thisPointer;
205  }
206 
207  return this;
208 
209 }
210 
211 //--------------------------------------------------------------------------------
212 
214  int level = 0;
215  TreeItem* current = this;
216 
217  // Go up and count the levels to the root node
218  while ( current->parent() != 0 ) {
219  level++;
220  current = current->parent();
221  }
222 
223  return level;
224 }
225 
226 //--------------------------------------------------------------------------------
227 
228 int TreeItem::row() const
229 {
230  return row_;
231 }
232 
233 //--------------------------------------------------------------------------------
234 
236 {
237  return parentItem_;
238 }
239 
240 //--------------------------------------------------------------------------------
241 
243  parentItem_ = _parent;
244 }
245 
246 //--------------------------------------------------------------------------------
247 
249 {
250  kTreeMap_[item->id()] = item;
251  childItems_.append(item);
252  item->row_ = childItems_.size() - 1;
253 }
254 
255 //--------------------------------------------------------------------------------
256 
258 {
259  return childItems_.value(row);
260 }
261 
262 //--------------------------------------------------------------------------------
263 
265 {
266  return childItems_.count();
267 }
268 
269 //--------------------------------------------------------------------------------
270 
272 
273  // Check if this object has the requested id
274  if ( id_ == _objectId )
275  return this;
276 
277  // Check the map, for the item
278  QMap<int,TreeItem*>::const_iterator iter = kTreeMap_.find(_objectId);
279 
280  // Not found -> return 0
281  if( iter == kTreeMap_.end() ) {
282  return 0;
283  }
284 
285  // Move the tree up and check if we are in the line to the root
286  TreeItem* current = *iter;
287 
288  while ( true ) {
289 
290  // Current item is a parent of the found one
291  if ( current == this ) {
292  return *iter;
293  }
294 
295  // Move to parent or if there is no parent, we return 0
296  if ( current->parent() != 0) {
297  current = current->parent();
298  } else
299  return 0;
300  }
301 
302  // Not in the line, so child does not exist
303  return 0;
304 }
305 
306 //--------------------------------------------------------------------------------
307 
309 
310  int idx = (_item != 0) ? _item->row_ : -1;
311 
312  if ( (idx < 0) || (idx >= childItems_.size()) || (childItems_[idx] != _item) ) {
313  std::cerr << "TreeItem: Illegal remove request" << std::endl;
314  return;
315  }
316 
317  childItems_.removeAt(idx);
318 
319  for ( ; idx < childItems_.size(); ++idx ) {
320  --(childItems_[idx]->row_);
321  }
322 }
323 
324 //--------------------------------------------------------------------------------
325 
326 QList< TreeItem* > TreeItem::getLeafs() {
327 
328  QList< TreeItem* > items;
329 
330  for ( int i = 0 ; i < childItems_.size(); ++i ) {
331  items = items + childItems_[i]->getLeafs();
332  }
333 
334  // If we are a leave...
335  if ( childCount() == 0 )
336  items.push_back(this);
337 
338  return items;
339 }
340 
341 //--------------------------------------------------------------------------------
342 
344 
345  // call function for all children of this node
346  for ( int i = 0 ; i < childItems_.size(); ++i) {
347 
348  // remove the subtree recursively
349  childItems_[i]->deleteSubtree();
350 
351  // delete child
352  delete childItems_[i];
353  }
354 
355  // clear the array
356  childItems_.clear();
357 }
358 
359 //=============================================================================
DataType dataType()
dataType
Definition: TreeItem.cc:94
int row() const
get the row of this item from the parent
Definition: TreeItem.cc:228
void deleteSubtree()
delete the whole subtree below this item ( The item itself is not touched )
Definition: TreeItem.cc:343
bool target()
target
Definition: TreeItem.cc:127
int level()
Definition: TreeItem.cc:213
int group()
group
Definition: TreeItem.cc:100
TreeItem * child(int row)
return a child
Definition: TreeItem.cc:257
TreeItem * childExists(int _objectId)
Check if the element exists in the subtree of this element.
Definition: TreeItem.cc:271
bool visible()
visible
Definition: TreeItem.cc:151
void setParent(TreeItem *_parent)
Set the parent pointer.
Definition: TreeItem.cc:242
const DataType DATA_GROUP(1)
Items used for Grouping.
TreeItem * parent()
Get the parent item ( 0 if root item )
Definition: TreeItem.cc:235
int row_
Index of this node in parent&#39;s childen.
Definition: TreeItem.hh:117
Predefined datatypes.
Definition: DataTypes.hh:83
QList< TreeItem *> getLeafs()
get all leafes of the tree below this object ( These will be all visible objects ) ...
Definition: TreeItem.cc:326
void appendChild(TreeItem *child)
add a child to this node
Definition: TreeItem.cc:248
bool source()
source
Definition: TreeItem.cc:139
QList< TreeItem * > childItems_
Children of this node.
Definition: TreeItem.hh:120
TreeItem * next()
Definition: TreeItem.cc:177
int id()
id
Definition: TreeItem.cc:78
QString name()
name
Definition: TreeItem.cc:163
TreeItem * parentItem_
Parent item or 0 if root node.
Definition: TreeItem.hh:114
static QMap< int, TreeItem * > kTreeMap_
Acceleration map.
Definition: TreeItem.hh:123
void removeChild(TreeItem *_item)
Remove a child from this object.
Definition: TreeItem.cc:308
int childCount() const
get the number of children
Definition: TreeItem.cc:264
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.