OGS
TreeModel.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include "Base/TreeModel.h"
5
6#include <QModelIndex>
7#include <QStringList>
8#include <QVariant>
9
11
15TreeModel::TreeModel(QObject* parent) : QAbstractItemModel(parent)
16{
17 //_modelType = TREE_MODEL;
18 QList<QVariant> rootData;
19 rootData << "1"
20 << "2"
21 << "3";
22 _rootItem = new TreeItem(rootData, nullptr);
23 // setupModelData(data, _rootItem);
24}
25
27{
28 delete _rootItem;
29}
30
39QModelIndex TreeModel::index(int row, int column,
40 const QModelIndex& parent) const
41{
42 if (!hasIndex(row, column, parent))
43 {
44 return QModelIndex();
45 }
46
47 TreeItem* parentItem;
48
49 if (!parent.isValid())
50 {
51 parentItem = _rootItem;
52 }
53 else
54 {
55 parentItem = static_cast<TreeItem*>(parent.internalPointer());
56 }
57
58 TreeItem* childItem = parentItem->child(row);
59 if (childItem)
60 {
61 return createIndex(row, column, childItem);
62 }
63
64 return QModelIndex();
65}
66
70QModelIndex TreeModel::parent(const QModelIndex& index) const
71{
72 if (!index.isValid())
73 {
74 return QModelIndex();
75 }
76
77 auto* childItem = static_cast<TreeItem*>(index.internalPointer());
78 TreeItem* parentItem = childItem->parentItem();
79
80 if (parentItem == _rootItem)
81 {
82 return QModelIndex();
83 }
84
85 return createIndex(parentItem->row(), 0, parentItem);
86}
87
93int TreeModel::rowCount(const QModelIndex& parent) const
94{
95 TreeItem* parentItem;
96 if (parent.column() > 0)
97 {
98 return 0;
99 }
100
101 if (!parent.isValid())
102 {
103 parentItem = _rootItem;
104 }
105 else
106 {
107 parentItem = static_cast<TreeItem*>(parent.internalPointer());
108 }
109
110 return parentItem->childCount();
111}
112
116int TreeModel::columnCount(const QModelIndex& parent) const
117{
118 if (parent.isValid())
119 {
120 return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
121 }
122
123 return _rootItem->columnCount();
124}
125
131QVariant TreeModel::data(const QModelIndex& index, int role) const
132{
133 if (!index.isValid())
134 {
135 return QVariant();
136 }
137
138 if (role == Qt::EditRole || role == Qt::DisplayRole)
139 {
140 auto* item = static_cast<TreeItem*>(index.internalPointer());
141
142 return item->data(index.column());
143 }
144
145 return QVariant();
146}
147
148bool TreeModel::setData(const QModelIndex& index, const QVariant& value,
149 int role /* = Qt::EditRole */)
150{
151 if (!index.isValid())
152 {
153 return false;
154 }
155
156 if (role == Qt::EditRole)
157 {
158 auto* item = static_cast<TreeItem*>(index.internalPointer());
159 item->setData(index.column(), value);
160 return true;
161 }
162 return false;
163}
164Qt::ItemFlags TreeModel::flags(const QModelIndex& index) const
165{
166 if (!index.isValid())
167 {
168 return Qt::NoItemFlags;
169 }
170
171 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
172}
173
177TreeItem* TreeModel::getItem(const QModelIndex& index) const
178{
179 if (index.isValid())
180 {
181 auto* item = static_cast<TreeItem*>(index.internalPointer());
182 if (item)
183 {
184 return item;
185 }
186 }
187 return _rootItem;
188}
189
190QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
191 int role) const
192{
193 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
194 {
195 return _rootItem->data(section);
196 }
197
198 return QVariant();
199}
200
204bool TreeModel::removeRows(int position, int count, const QModelIndex& parent)
205{
206 TreeItem* parentItem = getItem(parent);
207 bool success = true;
208
209 beginRemoveRows(parent, position, position + count - 1);
210 success = parentItem->removeChildren(position, count);
211 endRemoveRows();
212
213 return success;
214}
215
219void TreeModel::setupModelData(const QStringList& lines, TreeItem* parent)
220{
221 QList<TreeItem*> parents;
222 QList<int> indentations;
223 parents << parent;
224 indentations << 0;
225
226 int number = 0;
227
228 while (number < lines.count())
229 {
230 int position = 0;
231 while (position < lines[number].length())
232 {
233 if (lines[number].mid(position, 1) != " ")
234 {
235 break;
236 }
237 position++;
238 }
239
240 QString lineData = lines[number].mid(position).trimmed();
241
242 if (!lineData.isEmpty())
243 {
244 // Read the column data from the rest of the line.
245 QStringList columnStrings =
246 lineData.split("\t", Qt::SkipEmptyParts);
247 QList<QVariant> columnData;
248 for (int column = 0; column < columnStrings.count(); ++column)
249 {
250 columnData << columnStrings[column];
251 }
252
253 if (position > indentations.last())
254 {
255 // The last child of the current parent is now the new parent
256 // unless the current parent has no children.
257
258 if (parents.last()->childCount() > 0)
259 {
260 parents << parents.last()->child(
261 parents.last()->childCount() - 1);
262 indentations << position;
263 }
264 }
265 else
266 {
267 while (position < indentations.last() && parents.count() > 0)
268 {
269 parents.pop_back();
270 indentations.pop_back();
271 }
272 }
273
274 // Append a new item to the current parent's list of children.
275 parents.last()->appendChild(
276 new TreeItem(columnData, parents.last()));
277 }
278
279 number++;
280 }
281}
282
284{
285 return _rootItem;
286}
Objects nodes for the TreeModel.
Definition TreeItem.h:17
virtual int childCount() const
Definition TreeItem.cpp:54
virtual int columnCount() const
Definition TreeItem.cpp:75
TreeItem * parentItem() const
Definition TreeItem.cpp:104
TreeItem * child(int row) const
Definition TreeItem.cpp:41
int row() const
Definition TreeItem.cpp:62
bool removeChildren(int position, int count)
Definition TreeItem.cpp:113
virtual bool setData(int column, const QVariant &value)
Definition TreeItem.cpp:91
virtual QVariant data(int column) const
Definition TreeItem.cpp:83
~TreeModel() override
Definition TreeModel.cpp:26
void setupModelData(const QStringList &lines, TreeItem *parent)
bool removeRows(int position, int count, const QModelIndex &parent) override
TreeItem * getItem(const QModelIndex &index) const
void updateData()
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition TreeModel.cpp:93
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition TreeModel.cpp:39
QVariant data(const QModelIndex &index, int role) const override
QModelIndex parent(const QModelIndex &index) const override
Definition TreeModel.cpp:70
TreeItem * rootItem() const
TreeModel(QObject *parent=nullptr)
Definition TreeModel.cpp:15
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Qt::ItemFlags flags(const QModelIndex &index) const override
TreeItem * _rootItem
Definition TreeModel.h:47
bool setData(const QModelIndex &index, const QVariant &value, int role) override