Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
TreeModel.cpp
1 #include <Gui/TreeModel/TreeModel.hpp>
2 
3 #include <Core/Utils/Log.hpp>
4 #include <stack>
5 
6 #include <QApplication>
7 
8 namespace Ra {
9 namespace Gui {
10 
11 using namespace Ra::Core::Utils;
12 
13 int TreeModel::rowCount( const QModelIndex& parent ) const {
15  if ( parent.column() > 0 ) { return 0; }
16  TreeItem* parentItem = getItem( parent );
17  return int( parentItem->m_children.size() );
18 }
19 
20 TreeItem* TreeModel::getItem( const QModelIndex& index ) const {
21  if ( index.isValid() ) {
22  TreeItem* item = static_cast<TreeItem*>( index.internalPointer() );
23  CORE_ASSERT( item, "Null item found" );
24  // This can indicate that you have invalid pointers in your model index.
25  // e.g. after rebuilding the model.
26  CORE_ASSERT( findInTree( item ), "Item is not in tree" );
27  return item;
28  }
29  return m_rootItem.get();
30 }
31 
32 QVariant TreeModel::data( const QModelIndex& index, int role ) const {
33  if ( index.isValid() && index.column() == 0 ) {
34  if ( role == Qt::DisplayRole ) {
35  return QVariant( QString::fromStdString( getItem( index )->getName() ) );
36  }
37  else if ( role == Qt::CheckStateRole ) {
38  return static_cast<int>( getItem( index )->isChecked() ? Qt::Checked : Qt::Unchecked );
39  }
40  }
41  return QVariant();
42 }
43 
44 bool TreeModel::setData( const QModelIndex& index, const QVariant& value, int role ) {
45  if ( index.isValid() && index.column() == 0 && role == Qt::CheckStateRole ) {
46  if ( QApplication::keyboardModifiers() == Qt::CTRL ) {
47  setAllItemsChecked( false );
48  setItemChecked( index, true );
49  }
50  else { setItemChecked( index, value.toBool() ); }
51  return true;
52  }
53  return false;
54 }
55 
56 QVariant TreeModel::headerData( int section, Qt::Orientation orientation, int role ) const {
57  if ( section == 0 && orientation == Qt::Horizontal && role == Qt::DisplayRole ) {
58  return QVariant( QString::fromStdString( getHeaderString() ) );
59  }
60  else { return QVariant(); }
61 }
62 
63 QModelIndex TreeModel::index( int row, int column, const QModelIndex& parent ) const {
64  if ( !hasIndex( row, column, parent ) ) { return QModelIndex(); }
65  // Only items from the first column may have a parent
66  if ( parent.isValid() && parent.column() != 0 ) { return QModelIndex(); }
67  // Grab the parent and make an index of the child.
68  TreeItem* parentItem = getItem( parent );
69  if ( parentItem && size_t( row ) < parentItem->m_children.size() ) {
70  return createIndex( row, column, parentItem->m_children[row].get() );
71  }
72  else { return QModelIndex(); }
73 }
74 
75 QModelIndex TreeModel::parent( const QModelIndex& child ) const {
76  if ( child.isValid() ) {
77  TreeItem* childItem = getItem( child );
78  TreeItem* parentItem = childItem->m_parent;
79 
80  // No parents of the root item are indexed.
81  if ( parentItem && parentItem != m_rootItem.get() ) {
82  // Figure out which row the parent is in.
83  return createIndex( parentItem->getIndexInParent(), 0, parentItem );
84  }
85  }
86  return QModelIndex();
87 }
88 
89 Qt::ItemFlags TreeModel::flags( const QModelIndex& index ) const {
90  return index.isValid() && getItem( index )->isValid() && getItem( index )->isSelectable()
91  ? QAbstractItemModel::flags( index ) | Qt::ItemIsUserCheckable
92  : Qt::ItemFlags();
93 }
94 
96  // Need to call these function to invalidate the pointers
97  // in the QModelIndex.
98  beginResetModel();
99  buildModel();
100  endResetModel();
101  emit modelRebuilt();
102 }
103 
104 bool TreeModel::findInTree( const TreeItem* item ) const {
105  std::stack<const TreeItem*> stack;
106  stack.push( m_rootItem.get() );
107  while ( !stack.empty() ) {
108  const TreeItem* current = stack.top();
109  stack.pop();
110  if ( current == item ) { return true; }
111  for ( const auto& child : current->m_children ) {
112  stack.push( child.get() );
113  }
114  }
115  return false;
116 }
117 
118 void TreeModel::printModel() const {
119 #if defined CORE_DEBUG
120  LOG( logDEBUG ) << " Printing tree model";
121  std::stack<const TreeItem*> stack;
122  stack.push( m_rootItem.get() );
123  while ( !stack.empty() ) {
124  const TreeItem* current = stack.top();
125  stack.pop();
126  LOG( logDEBUG ) << current->getName();
127  for ( const auto& child : current->m_children ) {
128  stack.push( child.get() );
129  }
130  }
131 #endif
132 }
133 
134 void TreeModel::setAllItemsChecked( bool checked ) {
135  for ( int row = 0; row < rowCount(); ++row ) {
136  const QModelIndex index = this->index( row, 0 );
137  setItemChecked( index, checked );
138  }
139 }
140 
141 void TreeModel::setItemChecked( const QModelIndex& index, bool checked ) {
142  if ( index.isValid() ) {
143  TreeItem* item = getItem( index );
144  if ( item->isSelectable() ) {
145  item->setChecked( checked );
146  emit dataChanged( index, index, { Qt::CheckStateRole } );
147 
148  // recursion on all children
149  for ( int i = 0; i < rowCount( index ); ++i ) {
150  const QModelIndex child = this->index( i, 0, index );
151  setItemChecked( child, checked );
152  }
153  }
154  }
155 }
156 
157 } // namespace Gui
158 } // namespace Ra
int getIndexInParent() const
std::vector< std::unique_ptr< TreeItem > > m_children
Children of item in the tree.
Definition: TreeModel.hpp:68
virtual bool isSelectable() const =0
Return true if the represented object can be selected.
TreeItem * getItem(const QModelIndex &index) const
Get the tree item corresponding to the given index.
Definition: TreeModel.cpp:20
void setAllItemsChecked(bool checked=true)
Set the check state of all items.
Definition: TreeModel.cpp:134
void setItemChecked(const QModelIndex &index, bool checked=true)
Set the check state of one item and all of its children.
Definition: TreeModel.cpp:141
QModelIndex parent(const QModelIndex &child) const override
Definition: TreeModel.cpp:75
Qt::ItemFlags flags(const QModelIndex &index) const override
Definition: TreeModel.cpp:89
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: TreeModel.cpp:13
QVariant data(const QModelIndex &index, int role) const override
Definition: TreeModel.cpp:32
void printModel() const
Prints elements in the model to stdout (debug only)
Definition: TreeModel.cpp:118
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Definition: TreeModel.cpp:56
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: TreeModel.cpp:63
bool findInTree(const TreeItem *item) const
Internal functions to check if an item is in the tree.
Definition: TreeModel.cpp:104
Definition: Cage.cpp:3