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