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
44QMap<int,TreeItem*> TreeItem::kTreeMap_;
45
46//--------------------------------------------------------------------------------
47
48TreeItem::TreeItem(int _id, const 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
63TreeItem::~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
79 return id_;
80}
81
82//--------------------------------------------------------------------------------
83
84bool 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
119bool TreeItem::isGroup() {
120 return ( dataType(DATA_GROUP) );
121}
122
123// ===============================================================================
124// Dynamic Members
125// ===============================================================================
126
128 return target_;
129}
130
131//--------------------------------------------------------------------------------
132
133void TreeItem::target(bool _target) {
134 target_= _target;
135}
136
137//--------------------------------------------------------------------------------
138
140 return source_;
141}
142
143//--------------------------------------------------------------------------------
144
145void TreeItem::source(bool _source) {
146 source_ = _source;
147}
148
149//--------------------------------------------------------------------------------
150
152 return visible_;
153}
154
155//--------------------------------------------------------------------------------
156
157void TreeItem::visible(bool _visible) {
158 visible_ = _visible;
159}
160
161//--------------------------------------------------------------------------------
162
163QString TreeItem::name() {
164 return name_;
165}
166
167//--------------------------------------------------------------------------------
168
169void TreeItem::name(const 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
228int 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
326QList< 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//=============================================================================
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.
const DataType DATA_GROUP(1)
Items used for Grouping.
Predefined datatypes.
Definition: DataTypes.hh:83
int childCount() const
get the number of children
Definition: TreeItem.cc:264
QList< TreeItem * > getLeafs()
get all leafes of the tree below this object ( These will be all visible objects )
Definition: TreeItem.cc:326
int id()
id
Definition: TreeItem.cc:78
TreeItem * parentItem_
Parent item or 0 if root node.
Definition: TreeItem.hh:114
TreeItem * parent()
Get the parent item ( 0 if root item )
Definition: TreeItem.cc:235
bool target()
target
Definition: TreeItem.cc:127
QString name()
name
Definition: TreeItem.cc:163
int row_
Index of this node in parent's childen.
Definition: TreeItem.hh:117
int group()
group
Definition: TreeItem.cc:100
DataType dataType()
dataType
Definition: TreeItem.cc:94
bool visible()
visible
Definition: TreeItem.cc:151
QList< TreeItem * > childItems_
Children of this node.
Definition: TreeItem.hh:120
TreeItem * child(int row)
return a child
Definition: TreeItem.cc:257
void deleteSubtree()
delete the whole subtree below this item ( The item itself is not touched )
Definition: TreeItem.cc:343
int row() const
get the row of this item from the parent
Definition: TreeItem.cc:228
int level()
Definition: TreeItem.cc:213
TreeItem * next()
Definition: TreeItem.cc:177
static QMap< int, TreeItem * > kTreeMap_
Acceleration map.
Definition: TreeItem.hh:123
void appendChild(TreeItem *child)
add a child to this node
Definition: TreeItem.cc:248
void setParent(TreeItem *_parent)
Set the parent pointer.
Definition: TreeItem.cc:242
void removeChild(TreeItem *_item)
Remove a child from this object.
Definition: TreeItem.cc:308
bool source()
source
Definition: TreeItem.cc:139
TreeItem * childExists(int _objectId)
Check if the element exists in the subtree of this element.
Definition: TreeItem.cc:271