Developer Documentation

TreeModelObjectSelection.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 #include <OpenFlipper/common/Types.hh>
45
46
47 #include <QtWidgets>
48
49
50 #include "TreeModelObjectSelection.hh"
51
52
53 #include "../OpenFlipper/BasePlugin/PluginFunctions.hh"
54
55
56 //******************************************************************************
57
62 TreeModelObjectSelection::TreeModelObjectSelection( QObject *_parent) : QAbstractItemModel(_parent)
63 {
64 rootItem_ = new TreeItemObjectSelection( -1, "ROOT", DATA_UNKNOWN, 0);
65 }
66
67
68 //******************************************************************************
69
73 TreeModelObjectSelection::~TreeModelObjectSelection()
74 {
75
76 }
77
78
79 //******************************************************************************
80
81
82 int TreeModelObjectSelection::columnCount(const QModelIndex &/*_parent*/) const
83 {
84 // Id, Name -> 2
85 return (2);
86 }
87
88
89 //******************************************************************************
90
97 QVariant TreeModelObjectSelection::data(const QModelIndex &index, int role) const
98 {
99
100 // Skip invalid requests
101 if (!index.isValid())
102 return QVariant();
103
104 // Get the corresponding tree item
105 TreeItemObjectSelection *item = static_cast<TreeItemObjectSelection*>(index.internalPointer());
106
107 if ( item == rootItem_ ) {
108 std::cerr << "Root" << std::endl;
109 }
110
111 // Set the background color of the objects row
112 if ( role == Qt::BackgroundRole ) {
113 if ( !item->visible() ) {
114 return QVariant (QBrush (QColor (192, 192, 192)));
115 }
116 }
117
118 if (role == Qt::DisplayRole)
119 {
120 switch (index.column ())
121 {
122 case 0:
123 return QVariant(item->id());
124 case 1:
125 return QVariant(item->name());
126 default:
127 return QVariant ();
128 }
129 }
130 else
131 return QVariant ();
132 }
133
134
135 //******************************************************************************
136
142 Qt::ItemFlags TreeModelObjectSelection::flags(const QModelIndex &index) const
143 {
144 if (!index.isValid())
145 return 0;
146
147 Qt::ItemFlags flags = 0;
148
149 // Show/Source/Target
150 if ( index.column() == 0 || index.column() == 1 )
151 flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
152 else
153 flags = Qt::ItemIsEnabled;
154
155 return flags;
156 }
157
158
159 //******************************************************************************
160
168 QVariant TreeModelObjectSelection::headerData(int section, Qt::Orientation orientation,
169 int role) const
170 {
171 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
172
173 if (section == 0)
174 return QVariant("ID");
175 else if (section == 1)
176 return QVariant("Name");
177 else
178 return QVariant();
179
180 }
181 return QVariant();
182 }
183
184
185 //******************************************************************************
186
194 QModelIndex TreeModelObjectSelection::index(int row, int column, const QModelIndex &_parent) const
195 {
196 TreeItemObjectSelection *parentItem;
197
198 if (!_parent.isValid())
199 parentItem = rootItem_;
200 else
201 parentItem = static_cast<TreeItemObjectSelection*>(_parent.internalPointer());
202
203 TreeItemObjectSelection *childItem = parentItem->child(row);
204 if (childItem)
205 return createIndex(row, column, childItem);
206 else
207 return QModelIndex();
208 }
209
210
211 //******************************************************************************
212
218 QModelIndex TreeModelObjectSelection::parent(const QModelIndex &index) const
219 {
220 if (!index.isValid())
221 return QModelIndex();
222
223 TreeItemObjectSelection *childItem = static_cast<TreeItemObjectSelection*>(index.internalPointer());
224 TreeItemObjectSelection *parentItem = childItem->parent();
225
226 if (parentItem == rootItem_)
227 return QModelIndex();
228
229 return createIndex(parentItem->row(), 0, parentItem);
230 }
231
232
233 //******************************************************************************
234
240 int TreeModelObjectSelection::rowCount(const QModelIndex &_parent) const
241 {
242 TreeItemObjectSelection *parentItem;
243 if (_parent.column() > 0)
244 return 0;
245
246 if (!_parent.isValid())
247 parentItem = rootItem_;
248 else
249 parentItem = static_cast<TreeItemObjectSelection*>(_parent.internalPointer());
250
251 return parentItem->childCount();
252 }
253
254
255 //******************************************************************************
256
261 void TreeModelObjectSelection::objectChanged(int _id) {
262
263 if ( _id != -1 ){
264
265 BaseObject* obj = 0;
266 PluginFunctions::getObject(_id, obj);
267
268 TreeItemObjectSelection* item = rootItem_->childExists(_id);
269
270 //if internal and external representation are both valid
271 if (obj != 0 && item != 0){
272 //update the name
273 if ( obj->name() != item->name() ){
274
275 item->name( obj->name() );
276
277 QModelIndex index = getModelIndex(item,0);
278 if ( index.isValid() )
279 emit dataChanged( index, index);
280 }
281
282 //update visibility
283 if ( obj->visible() != item->visible() || obj->isGroup() ){
284
285 item->visible( obj->visible() );
286
287 QModelIndex index0 = getModelIndex(item,0);
288 QModelIndex index1 = getModelIndex(item,3);
289
290 if ( index0.isValid() && index1.isValid() ){
291 //the whole row has to be updated because of the grey background-color
292 emit dataChanged( index0, index1);
293 propagateUpwards(item->parent(), 1, obj->visible() );
294 }
295
296 if ( obj->isGroup() )
297 propagateDownwards(item, 1 );
298 }
299
300 //update parent
301 if ( obj->parent() == PluginFunctions::objectRoot() && isRoot( item->parent() ) ){
302 return;
303 }else if ( obj->parent() == PluginFunctions::objectRoot() && !isRoot( item->parent() ) ){
304 moveItem(item, rootItem_ );
305 }else if ( obj->parent()->id() != item->parent()->id() ){
306 TreeItemObjectSelection* parent = rootItem_->childExists( obj->parent()->id() );
307
308 if (parent != 0)
309 moveItem(item, parent );
310 }
311 }
312 }
313 }
314
315
320 void TreeModelObjectSelection::objectAdded(BaseObject* _object){
321
322 objectAdded (_object, _object->parent());
323 }
324
330 void TreeModelObjectSelection::objectAdded(BaseObject* _object, BaseObject* _parent){
331
332 if (rootItem_->childExists(_object->id()))
333 return;
334
335 TreeItemObjectSelection* parent = 0;
336 //find the parent
337 if ( _parent == PluginFunctions::objectRoot() )
338 parent = rootItem_;
339 else
340 parent = rootItem_->childExists( _parent->id() );
341
342 if (!parent)
343 {
344 objectAdded(_parent);
345 parent = rootItem_->childExists( _parent->id() );
346 }
347
348 QModelIndex parentIndex = getModelIndex(parent, 0);
349
350 beginInsertRows(parentIndex, parent->childCount(), parent->childCount()); //insert at the bottom
351
352 TreeItemObjectSelection* item = new TreeItemObjectSelection( _object->id(), _object->name(), _object->dataType(), parent);
353
354 parent->appendChild( item );
355
356 endInsertRows();
357
358 objectChanged( _object->id() );
359 }
360
365 void TreeModelObjectSelection::objectDeleted(int _id){
366
367 TreeItemObjectSelection* item = rootItem_->childExists(_id);
368
369 if ( item != 0 && !isRoot(item) ){
370
371 QModelIndex itemIndex = getModelIndex(item, 0);
372 QModelIndex parentIndex = itemIndex.parent();
373
374 beginRemoveRows( parentIndex, itemIndex.row(), itemIndex.row() );
375
376 item->parent()->removeChild(item);
377 item->deleteSubtree();
378
379 delete item;
380
381 endRemoveRows();
382 }
383 }
384
385 //******************************************************************************
386
392 void TreeModelObjectSelection::moveItem(TreeItemObjectSelection* _item, TreeItemObjectSelection* _parent ){
393
394 QModelIndex itemIndex = getModelIndex(_item, 0);
395 QModelIndex oldParentIndex = itemIndex.parent();
396 QModelIndex newParentIndex = getModelIndex(_parent, 0);
397
398 //delete everything at the old location
399 beginRemoveRows( oldParentIndex, itemIndex.row(), itemIndex.row() );
400
401 _item->parent()->removeChild(_item);
402
403 endRemoveRows();
404
405 //insert it at the new location
406 beginInsertRows(newParentIndex, _parent->childCount(), _parent->childCount() ); //insert at the bottom
407 _item->setParent( _parent );
408 _parent->appendChild( _item );
409 endInsertRows();
410
411 emit layoutChanged();
412 }
413
414 //******************************************************************************
415
421 TreeItemObjectSelection* TreeModelObjectSelection::getItem(const QModelIndex &index) const
422 {
423 if (index.isValid()) {
424 TreeItemObjectSelection *item = static_cast<TreeItemObjectSelection*>(index.internalPointer());
425 if (item) return item;
426 }
427 return rootItem_;
428 }
429
430
431 //******************************************************************************
432
438 QString TreeModelObjectSelection::itemName(const QModelIndex &index) const
439 {
440 if (index.isValid()) {
441 TreeItemObjectSelection *item = static_cast<TreeItemObjectSelection*>(index.internalPointer());
442 if (item)
443 return item->name();
444 }
445 return "not found";
446 }
447
448 //******************************************************************************
449
455 int TreeModelObjectSelection::itemId(const QModelIndex &index) const
456 {
457 if (index.isValid()) {
458 TreeItemObjectSelection *item = static_cast<TreeItemObjectSelection*>(index.internalPointer());
459 if (item)
460 return item->id();
461 }
462 return -1;
463 }
464
465 //******************************************************************************
466
475 QModelIndex TreeModelObjectSelection::getModelIndex(TreeItemObjectSelection* _object, int _column ){
476
477 // root item gets an invalid QModelIndex
478 if ( _object == rootItem_ )
479 return QModelIndex();
480
481 QModelIndex index = createIndex(_object->row(), _column, _object);
482
483 return index;
484 }
485
486 //******************************************************************************
487
496 QModelIndex TreeModelObjectSelection::getModelIndex(int _id, int _column ){
497
498 TreeItemObjectSelection *obj = rootItem_->childExists(_id);
499
500 if (obj)
501 return getModelIndex (obj, _column);
502
503 return QModelIndex();
504 }
505
506
507 //******************************************************************************
508
515 void TreeModelObjectSelection::propagateUpwards(TreeItemObjectSelection* _item, int _column, bool _value ){
516
517 if ( isRoot(_item) || (!_item->isGroup()) )
518 return;
519
520 if (_column == 1){ //visibility
521 _item->visible( _value );
522
523 //the whole row has to be updated because of the grey background-color
524 QModelIndex index0 = getModelIndex(_item,0);
525 QModelIndex index1 = getModelIndex(_item,3);
526
527 emit dataChanged( index0, index1);
528
529 } else {
530
531 QModelIndex index = getModelIndex(_item,_column);
532 emit dataChanged(index, index);
533 }
534
535 propagateUpwards( _item->parent(), _column, _value );
536 }
537
538 //******************************************************************************
539
545 void TreeModelObjectSelection::propagateDownwards(TreeItemObjectSelection* _item, int _column ){
546
547 for (int i=0; i < _item->childCount(); i++){
548
549 TreeItemObjectSelection* current = _item->child(i);
550
551 bool changed = false;
552
553 switch ( _column ){
554
555 case 1: //VISIBILTY
556
557 if ( current->visible() != _item->visible() ){
558
559 current->visible( _item->visible() );
560 changed = true;
561 }
562 break;
563
564 default:
565 break;
566 }
567
568 if (changed){
569 QModelIndex index = getModelIndex(current,_column);
570 emit dataChanged(index, index);
571 }
572
573 if ( current->isGroup() )
574 propagateDownwards(current, _column);
575 }
576 }
577
578 //******************************************************************************
579
580 bool TreeModelObjectSelection::setData(const QModelIndex &index, const QVariant &value, int /*role*/)
581 {
582
583 emit dataChangedInside( itemId(index), index.column(), value );
584
585 return true;
586 }
587
588
589 //******************************************************************************
590
596 bool TreeModelObjectSelection::isRoot(TreeItemObjectSelection * _item) {
597 return ( _item == rootItem_ );
598 }
TreeModelObjectSelection::rootItem_
TreeItemObjectSelection * rootItem_
Rootitem of the tree.
Definition: TreeModelObjectSelection.hh:161
TreeModelObjectSelection::moveItem
void moveItem(TreeItemObjectSelection *_item, TreeItemObjectSelection *_parent)
move the item to a new parent
Definition: TreeModelObjectSelection.cc:392
TreeItemObjectSelection::child
TreeItemObjectSelection * child(int row)
return a child
Definition: TreeItemObjectSelection.cc:219
TreeModelObjectSelection::columnCount
int columnCount(const QModelIndex &_parent=QModelIndex()) const
Return the number of columns.
Definition: TreeModelObjectSelection.cc:82
TreeModelObjectSelection::flags
Qt::ItemFlags flags(const QModelIndex &index) const
return the types of the corresponding entry
Definition: TreeModelObjectSelection.cc:142
BaseObject
Definition: BaseObject.hh:82
PluginFunctions::getObject
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
Definition: PluginFunctions.cc:296
PluginFunctions::objectRoot
BaseObject *& objectRoot()
Get the root of the object structure.
Definition: PluginFunctions.cc:1101
TreeItemObjectSelection::childCount
int childCount() const
get the number of children
Definition: TreeItemObjectSelection.cc:226
TreeModelObjectSelection::objectAdded
void objectAdded(BaseObject *_object)
The object with the given id has been added. add it to the internal tree.
Definition: TreeModelObjectSelection.cc:320
TreeItemObjectSelection::setParent
void setParent(TreeItemObjectSelection *_parent)
Set the parent pointer.
Definition: TreeItemObjectSelection.cc:206
TreeModelObjectSelection::parent
QModelIndex parent(const QModelIndex &index) const
Get the parent ModelIndex.
Definition: TreeModelObjectSelection.cc:218
TreeModelObjectSelection::objectDeleted
void objectDeleted(int id_)
The object with the given id has been deleted. delete it from the internal tree.
Definition: TreeModelObjectSelection.cc:365
TreeModelObjectSelection::~TreeModelObjectSelection
~TreeModelObjectSelection()
Destructor.
Definition: TreeModelObjectSelection.cc:73
BaseObject::id
int id() const
Definition: BaseObject.cc:190
BaseObject::dataType
bool dataType(DataType _type) const
Definition: BaseObject.cc:221
TreeItemObjectSelection::id
int id()
id
Definition: TreeItemObjectSelection.cc:64
TreeModelObjectSelection::setData
bool setData(const QModelIndex &index, const QVariant &value, int role)
Set Data at &#39;index&#39; to &#39;value&#39;.
Definition: TreeModelObjectSelection.cc:580
TreeModelObjectSelection::isRoot
bool isRoot(TreeItemObjectSelection *_item)
Check if the given item is the root item.
Definition: TreeModelObjectSelection.cc:596
TreeItemObjectSelection::parent
TreeItemObjectSelection * parent()
Get the parent item ( 0 if rootitem )
Definition: TreeItemObjectSelection.cc:199
TreeModelObjectSelection::TreeModelObjectSelection
TreeModelObjectSelection(QObject *_parent=0)
Constructor.
Definition: TreeModelObjectSelection.cc:62
TreeItemObjectSelection::deleteSubtree
void deleteSubtree()
delete the whole subtree below this item ( The item itself is not touched )
Definition: TreeItemObjectSelection.cc:307
BaseObject::parent
BaseObject * parent()
Get the parent item ( 0 if rootitem )
Definition: BaseObject.cc:466
TreeModelObjectSelection::headerData
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
return the header data of the model
Definition: TreeModelObjectSelection.cc:168
TreeModelObjectSelection::getModelIndex
QModelIndex getModelIndex(TreeItemObjectSelection *_object, int _column)
Return the ModelIndex corresponding to a given TreeItemObjectSelection and Column.
Definition: TreeModelObjectSelection.cc:475
TreeItemObjectSelection::childExists
TreeItemObjectSelection * childExists(int _objectId)
Check if the element exists in the subtree of this element.
Definition: TreeItemObjectSelection.cc:233
TreeModelObjectSelection::objectChanged
void objectChanged(int id_)
The object with the given id has been changed. Check if model also has to be changed.
Definition: TreeModelObjectSelection.cc:261
BaseObject::name
QString name() const
return the name of the object. The name defaults to NONAME if unset.
Definition: BaseObject.cc:730
TreeItemObjectSelection::row
int row() const
get the row of this item from the parent
Definition: TreeItemObjectSelection.cc:189
TreeItemObjectSelection::visible
bool visible()
visible
Definition: TreeItemObjectSelection.cc:113
TreeItemObjectSelection
Definition: TreeItemObjectSelection.hh:53
BaseObject::isGroup
bool isGroup() const
Check if object is a group.
Definition: BaseObject.cc:619
TreeItemObjectSelection::name
QString name()
name
Definition: TreeItemObjectSelection.cc:125
TreeModelObjectSelection::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const
get the number of rows
Definition: TreeModelObjectSelection.cc:240
BaseObject::visible
virtual bool visible()
return if object is visible
Definition: BaseObject.cc:339
TreeModelObjectSelection::getItem
TreeItemObjectSelection * getItem(const QModelIndex &index) const
Get the TreeItemObjectSelection corresponding to a given ModelIndex.
Definition: TreeModelObjectSelection.cc:421
TreeModelObjectSelection::itemId
int itemId(const QModelIndex &index) const
Get the id of a TreeItemObjectSelection corresponding to a given ModelIndex.
Definition: TreeModelObjectSelection.cc:455
TreeModelObjectSelection::propagateDownwards
void propagateDownwards(TreeItemObjectSelection *_obj, int _column)
Recursively update a column up to the root of the tree.
Definition: TreeModelObjectSelection.cc:545
TreeItemObjectSelection::appendChild
void appendChild(TreeItemObjectSelection *child)
add a child to this node
Definition: TreeItemObjectSelection.cc:212
Types.hh
TreeModelObjectSelection::propagateUpwards
void propagateUpwards(TreeItemObjectSelection *_obj, int _column, bool _value)
Recursively update a column up to the root of the tree.
Definition: TreeModelObjectSelection.cc:515
TreeModelObjectSelection::data
QVariant data(const QModelIndex &index, int role) const
Get the data of the corresponding entry.
Definition: TreeModelObjectSelection.cc:97
TreeModelObjectSelection::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Get the ModelIndex at given row,column.
Definition: TreeModelObjectSelection.cc:194
TreeItemObjectSelection::removeChild
void removeChild(TreeItemObjectSelection *_item)
Remove a child from this object.
Definition: TreeItemObjectSelection.cc:269
TreeModelObjectSelection::itemName
QString itemName(const QModelIndex &index) const
Get the name of a TreeItemObjectSelection corresponding to a given ModelIndex.
Definition: TreeModelObjectSelection.cc:438
DATA_UNKNOWN
const DataType DATA_UNKNOWN(0)
None of the other Objects.