VPTissue Reference Manual
CheckableTreeModel.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2016 Universiteit Antwerpen
3  *
4  * Licensed under the EUPL, Version 1.1 or as soon they will be approved by
5  * the European Commission - subsequent versions of the EUPL (the "Licence");
6  * You may not use this work except in compliance with the Licence.
7  * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl5
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the Licence is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the Licence for the specific language governing
13  * permissions and limitations under the Licence.
14  */
20 #include "CheckableTreeModel.h"
21 
22 using namespace std;
23 using namespace boost::property_tree;
24 
25 namespace SimShell {
26 namespace Gui {
27 
28 CheckableTreeModel::Item::~Item() {
29  for (auto c : children) {
30  delete c;
31  }
32 }
33 
34 
35 CheckableTreeModel::CheckableTreeModel(const ptree& tree, QObject* parent)
36  : QAbstractItemModel(parent)
37 {
38  m_root = new Item({nullptr, {}, QString(), false});
39  m_root->children.reserve(tree.size());
40 
41  function<void(const ptree&, Item*)> work_recursively;
42  (work_recursively = [&](const ptree& tree, Item* parent) {
43  for (auto it = tree.ordered_begin(); it != tree.not_found(); it++) {
44  auto& node = *it;
45  auto checked = node.second.get<bool>("checked");
46  auto item = new Item({parent, {}, QString::fromStdString(node.first), checked});
47  parent->children.push_back(item);
48 
49  auto children_optional = node.second.get_child_optional("children");
50  if (children_optional) {
51  auto& children = children_optional.get();
52  item->children.reserve(children.size());
53  work_recursively(children, item);
54  }
55  }
56  })(tree, m_root);
57 }
58 
59 CheckableTreeModel::~CheckableTreeModel() {
60  if (m_root) {
61  delete m_root;
62  m_root = nullptr;
63  }
64 }
65 
67 {
68  function<ptree(Item*)> work_recursive;
69  return (work_recursive = [&](Item* root) -> ptree {
70  ptree result;
71  for (auto c : root->children) {
72  ptree child_pt;
73  child_pt.put("checked", c->checked);
74  child_pt.put_child("children", work_recursive(c));
75  result.put_child(c->data.toStdString(), child_pt);
76  }
77  return result;
78  })(m_root);
79 }
80 
81 int CheckableTreeModel::columnCount(QModelIndex const&) const {
82  return 1;
83 }
84 
85 QVariant CheckableTreeModel::data(const QModelIndex& index, int role) const
86 {
87  if (!index.isValid()) {
88  return QVariant();
89  }
90 
91  auto item = static_cast<Item*>(index.internalPointer());
92 
93  if (role == Qt::CheckStateRole) {
94  return item->checked? Qt::Checked : Qt::Unchecked;
95  }
96 
97  if (role == Qt::DisplayRole) {
98  return item->data;
99  }
100 
101  return QVariant();
102 }
103 
104 Qt::ItemFlags CheckableTreeModel::flags(const QModelIndex& index) const
105 {
106  if (!index.isValid()) {
107  return 0;
108  }
109 
110  return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
111 }
112 
113 QVariant CheckableTreeModel::headerData(int , Qt::Orientation , int ) const
114 {
115  return QVariant();
116 }
117 
118 QModelIndex CheckableTreeModel::index(int row, int column, QModelIndex const& parent) const
119 {
120  if (!hasIndex(row, column, parent)) {
121  return QModelIndex();
122  }
123 
124  Item* parent_item;
125  if (!parent.isValid()) {
126  parent_item = m_root;
127  } else {
128  parent_item = static_cast<Item*>(parent.internalPointer());
129  }
130 
131  return createIndex(row, column, parent_item->children[row]);
132 }
133 
134 QModelIndex CheckableTreeModel::parent(QModelIndex const& index) const
135 {
136  if (!index.isValid()) {
137  return QModelIndex();
138  }
139  Item* child = static_cast<Item*>(index.internalPointer());
140  Item* parent = child->parent;
141  if (parent != nullptr) {
142  Item* grandparent = parent->parent;
143  if (grandparent != nullptr) {
144  auto it = find(grandparent->children.begin(), grandparent->children.end(), parent);
145  return createIndex(it - grandparent->children.begin(), 0, parent);
146  }
147  }
148  return QModelIndex();
149 }
150 
151 int CheckableTreeModel::rowCount(QModelIndex const& parent) const
152 {
153  Item* parent_item;
154  if (!parent.isValid()) {
155  parent_item = m_root;
156  } else {
157  parent_item = static_cast<Item*>(parent.internalPointer());
158  }
159  return parent_item->children.size();
160 }
161 
162 bool CheckableTreeModel::setData(QModelIndex const& index, const QVariant& value, int role)
163 {
164  if (!index.isValid()) {
165  return false;
166  }
167 
168  Item* item = static_cast<Item*>(index.internalPointer());
169  if (role == Qt::CheckStateRole) {
170  if (index.column() == 0) {
171  item->checked = value.toBool();
172  }
173  emit dataChanged(index, index);
174  return true;
175  }
176  return false;
177 }
178 
179 } // namespace Gui
180 } // namespace SimShell
virtual QVariant headerData(int section, Qt::Orientation o, int role) const
STL namespace.
see the online Qt documentation
virtual int columnCount(QModelIndex const &) const
virtual QVariant data(const QModelIndex &index, int role) const
virtual bool setData(QModelIndex const &index, const QVariant &value, int role)
virtual int rowCount(QModelIndex const &parent) const
virtual QModelIndex parent(QModelIndex const &index) const
virtual QModelIndex index(int row, int column, QModelIndex const &parent) const
CheckableTreeModel header.
boost::property_tree::ptree ToPTree()
Get checked/unchecked state of items, represented by a ptree of the form discussed in the constructor...
virtual Qt::ItemFlags flags(const QModelIndex &index) const
see the online Qt documentation
Namespace for generic graphical shell for simulators.
Definition: SimSession.h:32