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