Developer Documentation
Loading...
Searching...
No Matches
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
45
46
47#include <QtWidgets>
48
49
50#include "TreeModelObjectSelection.hh"
51
52
53#include "../OpenFlipper/BasePlugin/PluginFunctions.hh"
54
55
56//******************************************************************************
57
62TreeModelObjectSelection::TreeModelObjectSelection( QObject *_parent) : QAbstractItemModel(_parent)
63{
64 rootItem_ = new TreeItemObjectSelection( -1, "ROOT", DATA_UNKNOWN, 0);
65}
66
67
68//******************************************************************************
69
77
78
79//******************************************************************************
80
81
82int TreeModelObjectSelection::columnCount(const QModelIndex &/*_parent*/) const
83{
84 // Id, Name -> 2
85 return (2);
86}
87
88
89//******************************************************************************
90
97QVariant 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
142Qt::ItemFlags TreeModelObjectSelection::flags(const QModelIndex &index) const
143{
144#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
145 if (!index.isValid())
146 return 0;
147
148 Qt::ItemFlags flags = 0;
149#else
150 if (!index.isValid())
151 return Qt::ItemFlags();
152
153 Qt::ItemFlags flags = Qt::ItemFlags();
154#endif
155
156 // Show/Source/Target
157 if ( index.column() == 0 || index.column() == 1 )
158 flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
159 else
160 flags = Qt::ItemIsEnabled;
161
162 return flags;
163}
164
165
166//******************************************************************************
167
175QVariant TreeModelObjectSelection::headerData(int section, Qt::Orientation orientation,
176 int role) const
177{
178 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
179
180 if (section == 0)
181 return QVariant("ID");
182 else if (section == 1)
183 return QVariant("Name");
184 else
185 return QVariant();
186
187 }
188 return QVariant();
189}
190
191
192//******************************************************************************
193
201QModelIndex TreeModelObjectSelection::index(int row, int column, const QModelIndex &_parent) const
202{
203 TreeItemObjectSelection *parentItem;
204
205 if (!_parent.isValid())
206 parentItem = rootItem_;
207 else
208 parentItem = static_cast<TreeItemObjectSelection*>(_parent.internalPointer());
209
210 TreeItemObjectSelection *childItem = parentItem->child(row);
211 if (childItem)
212 return createIndex(row, column, childItem);
213 else
214 return QModelIndex();
215}
216
217
218//******************************************************************************
219
225QModelIndex TreeModelObjectSelection::parent(const QModelIndex &index) const
226{
227 if (!index.isValid())
228 return QModelIndex();
229
230 TreeItemObjectSelection *childItem = static_cast<TreeItemObjectSelection*>(index.internalPointer());
231 TreeItemObjectSelection *parentItem = childItem->parent();
232
233 if (parentItem == rootItem_)
234 return QModelIndex();
235
236 return createIndex(parentItem->row(), 0, parentItem);
237}
238
239
240//******************************************************************************
241
247int TreeModelObjectSelection::rowCount(const QModelIndex &_parent) const
248{
249 TreeItemObjectSelection *parentItem;
250 if (_parent.column() > 0)
251 return 0;
252
253 if (!_parent.isValid())
254 parentItem = rootItem_;
255 else
256 parentItem = static_cast<TreeItemObjectSelection*>(_parent.internalPointer());
257
258 return parentItem->childCount();
259}
260
261
262//******************************************************************************
263
269
270 if ( _id != -1 ){
271
272 BaseObject* obj = 0;
274
276
277 //if internal and external representation are both valid
278 if (obj != 0 && item != 0){
279 //update the name
280 if ( obj->name() != item->name() ){
281
282 item->name( obj->name() );
283
284 QModelIndex index = getModelIndex(item,0);
285 if ( index.isValid() )
286 emit dataChanged( index, index);
287 }
288
289 //update visibility
290 if ( obj->visible() != item->visible() || obj->isGroup() ){
291
292 item->visible( obj->visible() );
293
294 QModelIndex index0 = getModelIndex(item,0);
295 QModelIndex index1 = getModelIndex(item,3);
296
297 if ( index0.isValid() && index1.isValid() ){
298 //the whole row has to be updated because of the grey background-color
299 emit dataChanged( index0, index1);
300 propagateUpwards(item->parent(), 1, obj->visible() );
301 }
302
303 if ( obj->isGroup() )
304 propagateDownwards(item, 1 );
305 }
306
307 //update parent
308 if ( obj->parent() == PluginFunctions::objectRoot() && isRoot( item->parent() ) ){
309 return;
310 }else if ( obj->parent() == PluginFunctions::objectRoot() && !isRoot( item->parent() ) ){
311 moveItem(item, rootItem_ );
312 }else if ( obj->parent()->id() != item->parent()->id() ){
314
315 if (parent != 0)
316 moveItem(item, parent );
317 }
318 }
319 }
320}
321
322
328
329 objectAdded (_object, _object->parent());
330}
331
338
339 if (rootItem_->childExists(_object->id()))
340 return;
341
343 //find the parent
344 if ( _parent == PluginFunctions::objectRoot() )
346 else
347 parent = rootItem_->childExists( _parent->id() );
348
349 if (!parent)
350 {
351 objectAdded(_parent);
352 parent = rootItem_->childExists( _parent->id() );
353 }
354
355 QModelIndex parentIndex = getModelIndex(parent, 0);
356
357 beginInsertRows(parentIndex, parent->childCount(), parent->childCount()); //insert at the bottom
358
359 TreeItemObjectSelection* item = new TreeItemObjectSelection( _object->id(), _object->name(), _object->dataType(), parent);
360
361 parent->appendChild( item );
362
363 endInsertRows();
364
365 objectChanged( _object->id() );
366}
367
373
375
376 if ( item != 0 && !isRoot(item) ){
377
378 QModelIndex itemIndex = getModelIndex(item, 0);
379 QModelIndex parentIndex = itemIndex.parent();
380
381 beginRemoveRows( parentIndex, itemIndex.row(), itemIndex.row() );
382
383 item->parent()->removeChild(item);
384 item->deleteSubtree();
385
386 delete item;
387
388 endRemoveRows();
389 }
390}
391
392//******************************************************************************
393
400
401 QModelIndex itemIndex = getModelIndex(_item, 0);
402 QModelIndex oldParentIndex = itemIndex.parent();
403 QModelIndex newParentIndex = getModelIndex(_parent, 0);
404
405 //delete everything at the old location
406 beginRemoveRows( oldParentIndex, itemIndex.row(), itemIndex.row() );
407
408 _item->parent()->removeChild(_item);
409
410 endRemoveRows();
411
412 //insert it at the new location
413 beginInsertRows(newParentIndex, _parent->childCount(), _parent->childCount() ); //insert at the bottom
414 _item->setParent( _parent );
415 _parent->appendChild( _item );
416 endInsertRows();
417
418 emit layoutChanged();
419}
420
421//******************************************************************************
422
429{
430 if (index.isValid()) {
431 TreeItemObjectSelection *item = static_cast<TreeItemObjectSelection*>(index.internalPointer());
432 if (item) return item;
433 }
434 return rootItem_;
435}
436
437
438//******************************************************************************
439
445QString TreeModelObjectSelection::itemName(const QModelIndex &index) const
446{
447 if (index.isValid()) {
448 TreeItemObjectSelection *item = static_cast<TreeItemObjectSelection*>(index.internalPointer());
449 if (item)
450 return item->name();
451 }
452 return "not found";
453}
454
455//******************************************************************************
456
462int TreeModelObjectSelection::itemId(const QModelIndex &index) const
463{
464 if (index.isValid()) {
465 TreeItemObjectSelection *item = static_cast<TreeItemObjectSelection*>(index.internalPointer());
466 if (item)
467 return item->id();
468 }
469 return -1;
470}
471
472//******************************************************************************
473
483
484 // root item gets an invalid QModelIndex
485 if ( _object == rootItem_ )
486 return QModelIndex();
487
488 QModelIndex index = createIndex(_object->row(), _column, _object);
489
490 return index;
491}
492
493//******************************************************************************
494
503QModelIndex TreeModelObjectSelection::getModelIndex(int _id, int _column ){
504
506
507 if (obj)
508 return getModelIndex (obj, _column);
509
510 return QModelIndex();
511}
512
513
514//******************************************************************************
515
523
524 if ( isRoot(_item) || (!_item->isGroup()) )
525 return;
526
527 if (_column == 1){ //visibility
528 _item->visible( _value );
529
530 //the whole row has to be updated because of the grey background-color
531 QModelIndex index0 = getModelIndex(_item,0);
532 QModelIndex index1 = getModelIndex(_item,3);
533
534 emit dataChanged( index0, index1);
535
536 } else {
537
538 QModelIndex index = getModelIndex(_item,_column);
539 emit dataChanged(index, index);
540 }
541
542 propagateUpwards( _item->parent(), _column, _value );
543}
544
545//******************************************************************************
546
553
554 for (int i=0; i < _item->childCount(); i++){
555
556 TreeItemObjectSelection* current = _item->child(i);
557
558 bool changed = false;
559
560 switch ( _column ){
561
562 case 1: //VISIBILTY
563
564 if ( current->visible() != _item->visible() ){
565
566 current->visible( _item->visible() );
567 changed = true;
568 }
569 break;
570
571 default:
572 break;
573 }
574
575 if (changed){
576 QModelIndex index = getModelIndex(current,_column);
577 emit dataChanged(index, index);
578 }
579
580 if ( current->isGroup() )
581 propagateDownwards(current, _column);
582 }
583}
584
585//******************************************************************************
586
587bool TreeModelObjectSelection::setData(const QModelIndex &index, const QVariant &value, int /*role*/)
588{
589
590 emit dataChangedInside( itemId(index), index.column(), value );
591
592 return true;
593}
594
595
596//******************************************************************************
597
604 return ( _item == rootItem_ );
605}
const DataType DATA_UNKNOWN(0)
None of the other Objects.
QString name() const
return the name of the object. The name defaults to NONAME if unset.
BaseObject * parent()
Get the parent item ( 0 if rootitem )
bool dataType(DataType _type) const
bool isGroup() const
Check if object is a group.
int id() const
virtual bool visible()
return if object is visible
void removeChild(TreeItemObjectSelection *_item)
Remove a child from this object.
void deleteSubtree()
delete the whole subtree below this item ( The item itself is not touched )
void setParent(TreeItemObjectSelection *_parent)
Set the parent pointer.
TreeItemObjectSelection * childExists(int _objectId)
Check if the element exists in the subtree of this element.
void appendChild(TreeItemObjectSelection *child)
add a child to this node
TreeItemObjectSelection * parent()
Get the parent item ( 0 if rootitem )
int row() const
get the row of this item from the parent
int childCount() const
get the number of children
TreeItemObjectSelection * child(int row)
return a child
void objectChanged(int id_)
The object with the given id has been changed. Check if model also has to be changed.
void moveItem(TreeItemObjectSelection *_item, TreeItemObjectSelection *_parent)
move the item to a new parent
TreeItemObjectSelection * rootItem_
Rootitem of the tree.
QVariant data(const QModelIndex &index, int role) const
Get the data of the corresponding entry.
int columnCount(const QModelIndex &_parent=QModelIndex()) const
Return the number of columns.
bool isRoot(TreeItemObjectSelection *_item)
Check if the given item is the root item.
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
return the header data of the model
int itemId(const QModelIndex &index) const
Get the id of a TreeItemObjectSelection corresponding to a given ModelIndex.
void objectDeleted(int id_)
The object with the given id has been deleted. delete it from the internal tree.
bool setData(const QModelIndex &index, const QVariant &value, int role)
Set Data at 'index' to 'value'.
QModelIndex parent(const QModelIndex &index) const
Get the parent ModelIndex.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Get the ModelIndex at given row,column.
int rowCount(const QModelIndex &parent=QModelIndex()) const
get the number of rows
QModelIndex getModelIndex(TreeItemObjectSelection *_object, int _column)
Return the ModelIndex corresponding to a given TreeItemObjectSelection and Column.
TreeModelObjectSelection(QObject *_parent=0)
Constructor.
Qt::ItemFlags flags(const QModelIndex &index) const
return the types of the corresponding entry
void objectAdded(BaseObject *_object)
The object with the given id has been added. add it to the internal tree.
void propagateDownwards(TreeItemObjectSelection *_obj, int _column)
Recursively update a column up to the root of the tree.
void propagateUpwards(TreeItemObjectSelection *_obj, int _column, bool _value)
Recursively update a column up to the root of the tree.
TreeItemObjectSelection * getItem(const QModelIndex &index) const
Get the TreeItemObjectSelection corresponding to a given ModelIndex.
QString itemName(const QModelIndex &index) const
Get the name of a TreeItemObjectSelection corresponding to a given ModelIndex.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
BaseObject *& objectRoot()
Get the root of the object structure.