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 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
51 
52 #if QT_VERSION >= 0x050000
53  #include <QtWidgets>
54 #else
55  #include <QtGui>
56 #endif
57 
58 #include "TreeModelObjectSelection.hh"
59 
60 
61 #include "../OpenFlipper/BasePlugin/PluginFunctions.hh"
62 
63 
64 //******************************************************************************
65 
70 TreeModelObjectSelection::TreeModelObjectSelection( QObject *_parent) : QAbstractItemModel(_parent)
71 {
72  rootItem_ = new TreeItemObjectSelection( -1, "ROOT", DATA_UNKNOWN, 0);
73 }
74 
75 
76 //******************************************************************************
77 
82 {
83 
84 }
85 
86 
87 //******************************************************************************
88 
89 
90 int TreeModelObjectSelection::columnCount(const QModelIndex &/*_parent*/) const
91 {
92  // Id, Name -> 2
93  return (2);
94 }
95 
96 
97 //******************************************************************************
98 
105 QVariant TreeModelObjectSelection::data(const QModelIndex &index, int role) const
106 {
107 
108  // Skip invalid requests
109  if (!index.isValid())
110  return QVariant();
111 
112  // Get the corresponding tree item
113  TreeItemObjectSelection *item = static_cast<TreeItemObjectSelection*>(index.internalPointer());
114 
115  if ( item == rootItem_ ) {
116  std::cerr << "Root" << std::endl;
117  }
118 
119  // Set the background color of the objects row
120  if ( role == Qt::BackgroundRole ) {
121  if ( !item->visible() ) {
122  return QVariant (QBrush (QColor (192, 192, 192)));
123  }
124  }
125 
126  if (role == Qt::DisplayRole)
127  {
128  switch (index.column ())
129  {
130  case 0:
131  return QVariant(item->id());
132  case 1:
133  return QVariant(item->name());
134  default:
135  return QVariant ();
136  }
137  }
138  else
139  return QVariant ();
140 }
141 
142 
143 //******************************************************************************
144 
150 Qt::ItemFlags TreeModelObjectSelection::flags(const QModelIndex &index) const
151 {
152  if (!index.isValid())
153  return 0;
154 
155  Qt::ItemFlags flags = 0;
156 
157  // Show/Source/Target
158  if ( index.column() == 0 || index.column() == 1 )
159  flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
160  else
161  flags = Qt::ItemIsEnabled;
162 
163  return flags;
164 }
165 
166 
167 //******************************************************************************
168 
176 QVariant TreeModelObjectSelection::headerData(int section, Qt::Orientation orientation,
177  int role) const
178 {
179  if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
180 
181  if (section == 0)
182  return QVariant("ID");
183  else if (section == 1)
184  return QVariant("Name");
185  else
186  return QVariant();
187 
188  }
189  return QVariant();
190 }
191 
192 
193 //******************************************************************************
194 
202 QModelIndex TreeModelObjectSelection::index(int row, int column, const QModelIndex &_parent) const
203 {
204  TreeItemObjectSelection *parentItem;
205 
206  if (!_parent.isValid())
207  parentItem = rootItem_;
208  else
209  parentItem = static_cast<TreeItemObjectSelection*>(_parent.internalPointer());
210 
211  TreeItemObjectSelection *childItem = parentItem->child(row);
212  if (childItem)
213  return createIndex(row, column, childItem);
214  else
215  return QModelIndex();
216 }
217 
218 
219 //******************************************************************************
220 
226 QModelIndex TreeModelObjectSelection::parent(const QModelIndex &index) const
227 {
228  if (!index.isValid())
229  return QModelIndex();
230 
231  TreeItemObjectSelection *childItem = static_cast<TreeItemObjectSelection*>(index.internalPointer());
232  TreeItemObjectSelection *parentItem = childItem->parent();
233 
234  if (parentItem == rootItem_)
235  return QModelIndex();
236 
237  return createIndex(parentItem->row(), 0, parentItem);
238 }
239 
240 
241 //******************************************************************************
242 
248 int TreeModelObjectSelection::rowCount(const QModelIndex &_parent) const
249 {
250  TreeItemObjectSelection *parentItem;
251  if (_parent.column() > 0)
252  return 0;
253 
254  if (!_parent.isValid())
255  parentItem = rootItem_;
256  else
257  parentItem = static_cast<TreeItemObjectSelection*>(_parent.internalPointer());
258 
259  return parentItem->childCount();
260 }
261 
262 
263 //******************************************************************************
264 
270 
271  if ( _id != -1 ){
272 
273  BaseObject* obj = 0;
274  PluginFunctions::getObject(_id, obj);
275 
277 
278  //if internal and external representation are both valid
279  if (obj != 0 && item != 0){
280  //update the name
281  if ( obj->name() != item->name() ){
282 
283  item->name( obj->name() );
284 
285  QModelIndex index = getModelIndex(item,0);
286  if ( index.isValid() )
287  emit dataChanged( index, index);
288  }
289 
290  //update visibility
291  if ( obj->visible() != item->visible() || obj->isGroup() ){
292 
293  item->visible( obj->visible() );
294 
295  QModelIndex index0 = getModelIndex(item,0);
296  QModelIndex index1 = getModelIndex(item,3);
297 
298  if ( index0.isValid() && index1.isValid() ){
299  //the whole row has to be updated because of the grey background-color
300  emit dataChanged( index0, index1);
301  propagateUpwards(item->parent(), 1, obj->visible() );
302  }
303 
304  if ( obj->isGroup() )
305  propagateDownwards(item, 1 );
306  }
307 
308  //update parent
309  if ( obj->parent() == PluginFunctions::objectRoot() && isRoot( item->parent() ) ){
310  return;
311  }else if ( obj->parent() == PluginFunctions::objectRoot() && !isRoot( item->parent() ) ){
312  moveItem(item, rootItem_ );
313  }else if ( obj->parent()->id() != item->parent()->id() ){
315 
316  if (parent != 0)
317  moveItem(item, parent );
318  }
319  }
320  }
321 }
322 
323 
329 
330  objectAdded (_object, _object->parent());
331 }
332 
339 
340  if (rootItem_->childExists(_object->id()))
341  return;
342 
344  //find the parent
345  if ( _parent == PluginFunctions::objectRoot() )
346  parent = rootItem_;
347  else
348  parent = rootItem_->childExists( _parent->id() );
349 
350  if (!parent)
351  {
352  objectAdded(_parent);
353  parent = rootItem_->childExists( _parent->id() );
354  }
355 
356  QModelIndex parentIndex = getModelIndex(parent, 0);
357 
358  beginInsertRows(parentIndex, parent->childCount(), parent->childCount()); //insert at the bottom
359 
360  TreeItemObjectSelection* item = new TreeItemObjectSelection( _object->id(), _object->name(), _object->dataType(), parent);
361 
362  parent->appendChild( item );
363 
364  endInsertRows();
365 
366  objectChanged( _object->id() );
367 }
368 
374 
376 
377  if ( item != 0 && !isRoot(item) ){
378 
379  QModelIndex itemIndex = getModelIndex(item, 0);
380  QModelIndex parentIndex = itemIndex.parent();
381 
382  beginRemoveRows( parentIndex, itemIndex.row(), itemIndex.row() );
383 
384  item->parent()->removeChild(item);
385  item->deleteSubtree();
386 
387  delete item;
388 
389  endRemoveRows();
390  }
391 }
392 
393 //******************************************************************************
394 
401 
402  QModelIndex itemIndex = getModelIndex(_item, 0);
403  QModelIndex oldParentIndex = itemIndex.parent();
404  QModelIndex newParentIndex = getModelIndex(_parent, 0);
405 
406  //delete everything at the old location
407  beginRemoveRows( oldParentIndex, itemIndex.row(), itemIndex.row() );
408 
409  _item->parent()->removeChild(_item);
410 
411  endRemoveRows();
412 
413  //insert it at the new location
414  beginInsertRows(newParentIndex, _parent->childCount(), _parent->childCount() ); //insert at the bottom
415  _item->setParent( _parent );
416  _parent->appendChild( _item );
417  endInsertRows();
418 
419  emit layoutChanged();
420 }
421 
422 //******************************************************************************
423 
430 {
431  if (index.isValid()) {
432  TreeItemObjectSelection *item = static_cast<TreeItemObjectSelection*>(index.internalPointer());
433  if (item) return item;
434  }
435  return rootItem_;
436 }
437 
438 
439 //******************************************************************************
440 
446 QString TreeModelObjectSelection::itemName(const QModelIndex &index) const
447 {
448  if (index.isValid()) {
449  TreeItemObjectSelection *item = static_cast<TreeItemObjectSelection*>(index.internalPointer());
450  if (item)
451  return item->name();
452  }
453  return "not found";
454 }
455 
456 //******************************************************************************
457 
463 int TreeModelObjectSelection::itemId(const QModelIndex &index) const
464 {
465  if (index.isValid()) {
466  TreeItemObjectSelection *item = static_cast<TreeItemObjectSelection*>(index.internalPointer());
467  if (item)
468  return item->id();
469  }
470  return -1;
471 }
472 
473 //******************************************************************************
474 
484 
485  // root item gets an invalid QModelIndex
486  if ( _object == rootItem_ )
487  return QModelIndex();
488 
489  QModelIndex index = createIndex(_object->row(), _column, _object);
490 
491  return index;
492 }
493 
494 //******************************************************************************
495 
504 QModelIndex TreeModelObjectSelection::getModelIndex(int _id, int _column ){
505 
507 
508  if (obj)
509  return getModelIndex (obj, _column);
510 
511  return QModelIndex();
512 }
513 
514 
515 //******************************************************************************
516 
524 
525  if ( isRoot(_item) || (!_item->isGroup()) )
526  return;
527 
528  if (_column == 1){ //visibility
529  _item->visible( _value );
530 
531  //the whole row has to be updated because of the grey background-color
532  QModelIndex index0 = getModelIndex(_item,0);
533  QModelIndex index1 = getModelIndex(_item,3);
534 
535  emit dataChanged( index0, index1);
536 
537  } else {
538 
539  QModelIndex index = getModelIndex(_item,_column);
540  emit dataChanged(index, index);
541  }
542 
543  propagateUpwards( _item->parent(), _column, _value );
544 }
545 
546 //******************************************************************************
547 
554 
555  for (int i=0; i < _item->childCount(); i++){
556 
557  TreeItemObjectSelection* current = _item->child(i);
558 
559  bool changed = false;
560 
561  switch ( _column ){
562 
563  case 1: //VISIBILTY
564 
565  if ( current->visible() != _item->visible() ){
566 
567  current->visible( _item->visible() );
568  changed = true;
569  }
570  break;
571 
572  default:
573  break;
574  }
575 
576  if (changed){
577  QModelIndex index = getModelIndex(current,_column);
578  emit dataChanged(index, index);
579  }
580 
581  if ( current->isGroup() )
582  propagateDownwards(current, _column);
583  }
584 }
585 
586 //******************************************************************************
587 
588 bool TreeModelObjectSelection::setData(const QModelIndex &index, const QVariant &value, int /*role*/)
589 {
590 
591  emit dataChangedInside( itemId(index), index.column(), value );
592 
593  return true;
594 }
595 
596 
597 //******************************************************************************
598 
605  return ( _item == rootItem_ );
606 }
BaseObject *& objectRoot()
Get the root of the object structure.
int columnCount(const QModelIndex &_parent=QModelIndex()) const
Return the number of columns.
void appendChild(TreeItemObjectSelection *child)
add a child to this node
QModelIndex parent(const QModelIndex &index) const
Get the parent ModelIndex.
virtual bool visible()
return if object is visible
Definition: BaseObject.cc:350
TreeItemObjectSelection * getItem(const QModelIndex &index) const
Get the TreeItemObjectSelection corresponding to a given ModelIndex.
Qt::ItemFlags flags(const QModelIndex &index) const
return the types of the corresponding entry
TreeItemObjectSelection * parent()
Get the parent item ( 0 if rootitem )
bool getObject(int _identifier, BSplineCurveObject *&_object)
bool dataType(DataType _type) const
Definition: BaseObject.cc:232
const DataType DATA_UNKNOWN(0)
None of the other Objects.
int rowCount(const QModelIndex &parent=QModelIndex()) const
get the number of rows
void objectAdded(BaseObject *_object)
The object with the given id has been added. add it to the internal tree.
int id() const
Definition: BaseObject.cc:201
void propagateDownwards(TreeItemObjectSelection *_obj, int _column)
Recursively update a column up to the root of the tree.
BaseObject * parent()
Get the parent item ( 0 if rootitem )
Definition: BaseObject.cc:477
int row() const
get the row of this item from the parent
void objectChanged(int id_)
The object with the given id has been changed. Check if model also has to be changed.
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 )
int itemId(const QModelIndex &index) const
Get the id of a TreeItemObjectSelection corresponding to a given ModelIndex.
bool setData(const QModelIndex &index, const QVariant &value, int role)
Set Data at &#39;index&#39; to &#39;value&#39;.
QString itemName(const QModelIndex &index) const
Get the name of a TreeItemObjectSelection corresponding to a given ModelIndex.
bool isGroup() const
Check if object is a group.
Definition: BaseObject.cc:630
void propagateUpwards(TreeItemObjectSelection *_obj, int _column, bool _value)
Recursively update a column up to the root of the tree.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Get the ModelIndex at given row,column.
TreeModelObjectSelection(QObject *_parent=0)
Constructor.
QString name() const
return the name of the object. The name defaults to NONAME if unset.
Definition: BaseObject.cc:741
TreeItemObjectSelection * rootItem_
Rootitem of the tree.
QVariant data(const QModelIndex &index, int role) const
Get the data of the corresponding entry.
void moveItem(TreeItemObjectSelection *_item, TreeItemObjectSelection *_parent)
move the item to a new parent
void removeChild(TreeItemObjectSelection *_item)
Remove a child from this object.
void objectDeleted(int id_)
The object with the given id has been deleted. delete it from the internal tree.
TreeItemObjectSelection * child(int row)
return a child
void setParent(TreeItemObjectSelection *_parent)
Set the parent pointer.
int childCount() const
get the number of children
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.
bool isRoot(TreeItemObjectSelection *_item)
Check if the given item is the root item.