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 
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 
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 
262 
263  if ( _id != -1 ){
264 
265  BaseObject* obj = 0;
266  PluginFunctions::getObject(_id, obj);
267 
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() ){
307 
308  if (parent != 0)
309  moveItem(item, parent );
310  }
311  }
312  }
313 }
314 
315 
321 
322  objectAdded (_object, _object->parent());
323 }
324 
331 
332  if (rootItem_->childExists(_object->id()))
333  return;
334 
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 
366 
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 
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 
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 
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 
499 
500  if (obj)
501  return getModelIndex (obj, _column);
502 
503  return QModelIndex();
504 }
505 
506 
507 //******************************************************************************
508 
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 
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 
597  return ( _item == rootItem_ );
598 }
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Get the ModelIndex at given row,column.
bool isGroup() const
Check if object is a group.
Definition: BaseObject.cc:619
void propagateDownwards(TreeItemObjectSelection *_obj, int _column)
Recursively update a column up to the root of the tree.
int childCount() const
get the number of children
int id() const
Definition: BaseObject.cc:190
TreeItemObjectSelection * parent()
Get the parent item ( 0 if rootitem )
void removeChild(TreeItemObjectSelection *_item)
Remove a child from this object.
void setParent(TreeItemObjectSelection *_parent)
Set the parent pointer.
void appendChild(TreeItemObjectSelection *child)
add a child to this node
bool dataType(DataType _type) const
Definition: BaseObject.cc:221
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
return the header data of the model
void deleteSubtree()
delete the whole subtree below this item ( The item itself is not touched )
QVariant data(const QModelIndex &index, int role) const
Get the data of the corresponding entry.
TreeItemObjectSelection * childExists(int _objectId)
Check if the element exists in the subtree of this element.
void objectAdded(BaseObject *_object)
The object with the given id has been added. add it to the internal tree.
void propagateUpwards(TreeItemObjectSelection *_obj, int _column, bool _value)
Recursively update a column up to the root of the tree.
const DataType DATA_UNKNOWN(0)
None of the other Objects.
int rowCount(const QModelIndex &parent=QModelIndex()) const
get the number of rows
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
int columnCount(const QModelIndex &_parent=QModelIndex()) const
Return the number of columns.
QString name() const
return the name of the object. The name defaults to NONAME if unset.
Definition: BaseObject.cc:730
BaseObject *& objectRoot()
Get the root of the object structure.
void objectChanged(int id_)
The object with the given id has been changed. Check if model also has to be changed.
virtual bool visible()
return if object is visible
Definition: BaseObject.cc:339
QString itemName(const QModelIndex &index) const
Get the name of a TreeItemObjectSelection corresponding to a given ModelIndex.
TreeModelObjectSelection(QObject *_parent=0)
Constructor.
TreeItemObjectSelection * child(int row)
return a child
TreeItemObjectSelection * rootItem_
Rootitem of the tree.
Qt::ItemFlags flags(const QModelIndex &index) const
return the types of the corresponding entry
bool setData(const QModelIndex &index, const QVariant &value, int role)
Set Data at &#39;index&#39; to &#39;value&#39;.
int itemId(const QModelIndex &index) const
Get the id of a TreeItemObjectSelection corresponding to a given ModelIndex.
void moveItem(TreeItemObjectSelection *_item, TreeItemObjectSelection *_parent)
move the item to a new parent
BaseObject * parent()
Get the parent item ( 0 if rootitem )
Definition: BaseObject.cc:466
QModelIndex getModelIndex(TreeItemObjectSelection *_object, int _column)
Return the ModelIndex corresponding to a given TreeItemObjectSelection and Column.
bool isRoot(TreeItemObjectSelection *_item)
Check if the given item is the root item.
void objectDeleted(int id_)
The object with the given id has been deleted. delete it from the internal tree.
TreeItemObjectSelection * getItem(const QModelIndex &index) const
Get the TreeItemObjectSelection corresponding to a given ModelIndex.
int row() const
get the row of this item from the parent
QModelIndex parent(const QModelIndex &index) const
Get the parent ModelIndex.