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
94 DataType TreeItem::dataType() {
95 return dataType_;
96 }
97
98 //--------------------------------------------------------------------------------
99
100 int TreeItem::group() {
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
127 bool TreeItem::target() {
128 return target_;
129 }
130
131 //--------------------------------------------------------------------------------
132
133 void TreeItem::target(bool _target) {
134 target_= _target;
135 }
136
137 //--------------------------------------------------------------------------------
138
139 bool TreeItem::source() {
140 return source_;
141 }
142
143 //--------------------------------------------------------------------------------
144
145 void TreeItem::source(bool _source) {
146 source_ = _source;
147 }
148
149 //--------------------------------------------------------------------------------
150
151 bool TreeItem::visible() {
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
177 TreeItem* TreeItem::next() {
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
213 int TreeItem::level() {
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
235 TreeItem* TreeItem::parent()
236 {
237 return parentItem_;
238 }
239
240 //--------------------------------------------------------------------------------
241
242 void TreeItem::setParent(TreeItem* _parent) {
243 parentItem_ = _parent;
244 }
245
246 //--------------------------------------------------------------------------------
247
248 void TreeItem::appendChild(TreeItem *item)
249 {
250 kTreeMap_[item->id()] = item;
251 childItems_.append(item);
252 item->row_ = childItems_.size() - 1;
253 }
254
255 //--------------------------------------------------------------------------------
256
257 TreeItem *TreeItem::child(int row)
258 {
259 return childItems_.value(row);
260 }
261
262 //--------------------------------------------------------------------------------
263
264 int TreeItem::childCount() const
265 {
266 return childItems_.count();
267 }
268
269 //--------------------------------------------------------------------------------
270
271 TreeItem* TreeItem::childExists(int _objectId) {
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
308 void TreeItem::removeChild( TreeItem* _item ) {
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
343 void TreeItem::deleteSubtree() {
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 //=============================================================================
TreeItem::dataType
DataType dataType()
dataType
Definition: TreeItem.cc:94
TreeItem::row
int row() const
get the row of this item from the parent
Definition: TreeItem.cc:228
TreeItem::deleteSubtree
void deleteSubtree()
delete the whole subtree below this item ( The item itself is not touched )
Definition: TreeItem.cc:343
TreeItem::target
bool target()
target
Definition: TreeItem.cc:127
TreeItem::level
int level()
Definition: TreeItem.cc:213
TreeItem::group
int group()
group
Definition: TreeItem.cc:100
TreeItem::child
TreeItem * child(int row)
return a child
Definition: TreeItem.cc:257
TreeItem::childExists
TreeItem * childExists(int _objectId)
Check if the element exists in the subtree of this element.
Definition: TreeItem.cc:271
TreeItem::visible
bool visible()
visible
Definition: TreeItem.cc:151
TreeItem::setParent
void setParent(TreeItem *_parent)
Set the parent pointer.
Definition: TreeItem.cc:242
DATA_GROUP
const DataType DATA_GROUP(1)
Items used for Grouping.
TreeItem::parent
TreeItem * parent()
Get the parent item ( 0 if root item )
Definition: TreeItem.cc:235
TreeItem::row_
int row_
Index of this node in parent&#39;s childen.
Definition: TreeItem.hh:117
DataType
Predefined datatypes.
Definition: DataTypes.hh:83
TreeItem::getLeafs
QList< TreeItem *> getLeafs()
get all leafes of the tree below this object ( These will be all visible objects ) ...
Definition: TreeItem.cc:326
TreeItem::appendChild
void appendChild(TreeItem *child)
add a child to this node
Definition: TreeItem.cc:248
TreeItem::source
bool source()
source
Definition: TreeItem.cc:139
TreeItem::childItems_
QList< TreeItem * > childItems_
Children of this node.
Definition: TreeItem.hh:120
TreeItem::next
TreeItem * next()
Definition: TreeItem.cc:177
TreeItem::id
int id()
id
Definition: TreeItem.cc:78
TreeItem
Definition: TreeItem.hh:52
TreeItem::name
QString name()
name
Definition: TreeItem.cc:163
TreeItem::parentItem_
TreeItem * parentItem_
Parent item or 0 if root node.
Definition: TreeItem.hh:114
TreeItem::kTreeMap_
static QMap< int, TreeItem * > kTreeMap_
Acceleration map.
Definition: TreeItem.hh:123
TreeItem::removeChild
void removeChild(TreeItem *_item)
Remove a child from this object.
Definition: TreeItem.cc:308
TreeItem::childCount
int childCount() const
get the number of children
Definition: TreeItem.cc:264
DATA_ALL
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.