Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 /*===========================================================================*\
43 * *
44 * $Revision: 10272 $ *
45 * $LastChangedBy: moebius $ *
46 * $Date: 2010-11-24 17:45:10 +0100 (Mi, 24 Nov 2010) $ *
47 * *
48 \*===========================================================================*/
49 
50 #include "TreeItem.hh"
51 
52 QMap<int,TreeItem*> TreeItem::kTreeMap_;
53 
54 //--------------------------------------------------------------------------------
55 
56 TreeItem::TreeItem(int _id, QString _name, DataType _type, TreeItem* _parent) :
57  id_(_id),
58  dataType_(_type),
59  target_(true),
60  source_(false),
61  visible_(true),
62  name_(_name),
63  parentItem_(_parent),
64  row_(0)
65 {
66  // Remember ourself ;-)
67  kTreeMap_[_id] = this;
68 }
69 
70 
71 TreeItem::~TreeItem() {
72  // Remove itself from map
73  QMap<int,TreeItem*>::iterator iter = kTreeMap_.find( id() );
74  if( iter != kTreeMap_.end() ) {
75  kTreeMap_.erase(iter);
76  } else {
77  std::cerr << "Map accelerator destructor in DataControl: Currently removing object that is not in the map!" << std::endl;
78  }
79 }
80 
81 
82 // ===============================================================================
83 // Static Members
84 // ===============================================================================
85 
86 int TreeItem::id() {
87  return id_;
88 }
89 
90 //--------------------------------------------------------------------------------
91 
92 bool TreeItem::dataType(DataType _type) {
93  if ( _type == DATA_ALL ) {
94  return true;
95  }
96 
97  return ( dataType_ & _type);
98 }
99 
100 //--------------------------------------------------------------------------------
101 
103  return dataType_;
104 }
105 
106 //--------------------------------------------------------------------------------
107 
109  // Skip root node
110  if ( parent() == 0 )
111  return -1;
112 
113  // Don't count root node as a group
114  if ( parent()->parent() == 0 )
115  return -1;
116 
117  // Only consider groups
118  if ( !parent()->dataType(DATA_GROUP) )
119  return -1;
120 
121  // Get the group id
122  return ( parent()->id() );
123 }
124 
125 //--------------------------------------------------------------------------------
126 
127 bool TreeItem::isGroup() {
128  return ( dataType(DATA_GROUP) );
129 }
130 
131 // ===============================================================================
132 // Dynamic Members
133 // ===============================================================================
134 
136  return target_;
137 }
138 
139 //--------------------------------------------------------------------------------
140 
141 void TreeItem::target(bool _target) {
142  target_= _target;
143 }
144 
145 //--------------------------------------------------------------------------------
146 
148  return source_;
149 }
150 
151 //--------------------------------------------------------------------------------
152 
153 void TreeItem::source(bool _source) {
154  source_ = _source;
155 }
156 
157 //--------------------------------------------------------------------------------
158 
160  return visible_;
161 }
162 
163 //--------------------------------------------------------------------------------
164 
165 void TreeItem::visible(bool _visible) {
166  visible_ = _visible;
167 }
168 
169 //--------------------------------------------------------------------------------
170 
171 QString TreeItem::name() {
172  return name_;
173 }
174 
175 //--------------------------------------------------------------------------------
176 
177 void TreeItem::name(QString _name ) {
178  name_ = _name;
179 }
180 
181 // ===============================================================================
182 // Tree Structure
183 // ===============================================================================
184 
186  // Visit child item of this node
187  if ( childItems_.size() > 0 ) {
188  return childItems_[0];
189  }
190 
191  // No Child Item so visit the next child of the parentItem_
192  if ( parentItem_ ) {
193 
194  TreeItem* parentPointer = parentItem_;
195  TreeItem* thisPointer = this;
196 
197  // while we are not at the root node
198  while ( parentPointer ) {
199 
200  // If there is an unvisited child of the parent, return this one
201  int position = thisPointer->row() + 1;
202  if ( parentPointer->childCount() > position ) {
203  return parentPointer->childItems_[ position ];
204  }
205 
206  // Go to the next level
207  thisPointer = parentPointer;
208  parentPointer = parentPointer->parentItem_;
209 
210  }
211 
212  return thisPointer;
213  }
214 
215  return this;
216 
217 }
218 
219 //--------------------------------------------------------------------------------
220 
222  int level = 0;
223  TreeItem* current = this;
224 
225  // Go up and count the levels to the root node
226  while ( current->parent() != 0 ) {
227  level++;
228  current = current->parent();
229  }
230 
231  return level;
232 }
233 
234 //--------------------------------------------------------------------------------
235 
236 int TreeItem::row() const
237 {
238  return row_;
239 }
240 
241 //--------------------------------------------------------------------------------
242 
244 {
245  return parentItem_;
246 }
247 
248 //--------------------------------------------------------------------------------
249 
251  parentItem_ = _parent;
252 }
253 
254 //--------------------------------------------------------------------------------
255 
257 {
258  kTreeMap_[item->id()] = item;
259  childItems_.append(item);
260  item->row_ = childItems_.size() - 1;
261 }
262 
263 //--------------------------------------------------------------------------------
264 
266 {
267  return childItems_.value(row);
268 }
269 
270 //--------------------------------------------------------------------------------
271 
273 {
274  return childItems_.count();
275 }
276 
277 //--------------------------------------------------------------------------------
278 
280 
281  // Check if this object has the requested id
282  if ( id_ == _objectId )
283  return this;
284 
285  // Check the map, for the item
286  QMap<int,TreeItem*>::const_iterator iter = kTreeMap_.find(_objectId);
287 
288  // Not found -> return 0
289  if( iter == kTreeMap_.end() ) {
290  return 0;
291  }
292 
293  // Move the tree up and check if we are in the line to the root
294  TreeItem* current = *iter;
295 
296  while ( true ) {
297 
298  // Current item is a parent of the found one
299  if ( current == this ) {
300  return *iter;
301  }
302 
303  // Move to parent or if there is no parent, we return 0
304  if ( current->parent() != 0) {
305  current = current->parent();
306  } else
307  return 0;
308  }
309 
310  // Not in the line, so child does not exist
311  return 0;
312 }
313 
314 //--------------------------------------------------------------------------------
315 
317 
318  int idx = (_item != 0) ? _item->row_ : -1;
319 
320  if ( (idx < 0) || (idx >= childItems_.size()) || (childItems_[idx] != _item) ) {
321  std::cerr << "TreeItem: Illegal remove request" << std::endl;
322  return;
323  }
324 
325  childItems_.removeAt(idx);
326 
327  for ( ; idx < childItems_.size(); ++idx ) {
328  --(childItems_[idx]->row_);
329  }
330 }
331 
332 //--------------------------------------------------------------------------------
333 
334 QList< TreeItem* > TreeItem::getLeafs() {
335 
336  QList< TreeItem* > items;
337 
338  for ( int i = 0 ; i < childItems_.size(); ++i ) {
339  items = items + childItems_[i]->getLeafs();
340  }
341 
342  // If we are a leave...
343  if ( childCount() == 0 )
344  items.push_back(this);
345 
346  return items;
347 }
348 
349 //--------------------------------------------------------------------------------
350 
352 
353  // call function for all children of this node
354  for ( int i = 0 ; i < childItems_.size(); ++i) {
355 
356  // remove the subtree recursively
357  childItems_[i]->deleteSubtree();
358 
359  // delete child
360  delete childItems_[i];
361  }
362 
363  // clear the array
364  childItems_.clear();
365 }
366 
367 //=============================================================================
int row() const
get the row of this item from the parent
Definition: TreeItem.cc:236
bool target()
target
Definition: TreeItem.cc:135
TreeItem * child(int row)
return a child
Definition: TreeItem.cc:265
DataType dataType()
dataType
Definition: TreeItem.cc:102
QList< TreeItem * > getLeafs()
get all leafes of the tree below this object ( These will be all visible objects ) ...
Definition: TreeItem.cc:334
const DataType DATA_GROUP(1)
Items used for Grouping.
void removeChild(TreeItem *_item)
Remove a child from this object.
Definition: TreeItem.cc:316
TreeItem * parentItem_
Parent item or 0 if root node.
Definition: TreeItem.hh:121
int id()
id
Definition: TreeItem.cc:86
int childCount() const
get the number of children
Definition: TreeItem.cc:272
void setParent(TreeItem *_parent)
Set the parent pointer.
Definition: TreeItem.cc:250
int row_
Index of this node in parent's childen.
Definition: TreeItem.hh:124
TreeItem * next()
Definition: TreeItem.cc:185
QList< TreeItem * > childItems_
Children of this node.
Definition: TreeItem.hh:127
TreeItem * parent()
Get the parent item ( 0 if root item )
Definition: TreeItem.cc:243
int level()
Definition: TreeItem.cc:221
bool visible()
visible
Definition: TreeItem.cc:159
bool source()
source
Definition: TreeItem.cc:147
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.
TreeItem * childExists(int _objectId)
Check if the element exists in the subtree of this element.
Definition: TreeItem.cc:279
static QMap< int, TreeItem * > kTreeMap_
Acceleration map.
Definition: TreeItem.hh:130
void appendChild(TreeItem *child)
add a child to this node
Definition: TreeItem.cc:256
int group()
group
Definition: TreeItem.cc:108
void deleteSubtree()
delete the whole subtree below this item ( The item itself is not touched )
Definition: TreeItem.cc:351
Predefined datatypes.
Definition: DataTypes.hh:96
QString name()
name
Definition: TreeItem.cc:171