OGS
TreeModel.cpp
Go to the documentation of this file.
1 
15 #include "Base/TreeModel.h"
16 
17 #include <QModelIndex>
18 #include <QStringList>
19 #include <QVariant>
20 
21 #include "Base/TreeItem.h"
22 
26 TreeModel::TreeModel(QObject* parent) : QAbstractItemModel(parent)
27 {
28  //_modelType = TREE_MODEL;
29  QList<QVariant> rootData;
30  rootData << "1"
31  << "2"
32  << "3";
33  _rootItem = new TreeItem(rootData, nullptr);
34  // setupModelData(data, _rootItem);
35 }
36 
38 {
39  delete _rootItem;
40 }
41 
50 QModelIndex TreeModel::index(int row, int column,
51  const QModelIndex& parent) const
52 {
53  if (!hasIndex(row, column, parent))
54  {
55  return QModelIndex();
56  }
57 
58  TreeItem* parentItem;
59 
60  if (!parent.isValid())
61  {
62  parentItem = _rootItem;
63  }
64  else
65  {
66  parentItem = static_cast<TreeItem*>(parent.internalPointer());
67  }
68 
69  TreeItem* childItem = parentItem->child(row);
70  if (childItem)
71  {
72  return createIndex(row, column, childItem);
73  }
74 
75  return QModelIndex();
76 }
77 
81 QModelIndex TreeModel::parent(const QModelIndex& index) const
82 {
83  if (!index.isValid())
84  {
85  return QModelIndex();
86  }
87 
88  auto* childItem = static_cast<TreeItem*>(index.internalPointer());
89  TreeItem* parentItem = childItem->parentItem();
90 
91  if (parentItem == _rootItem)
92  {
93  return QModelIndex();
94  }
95 
96  return createIndex(parentItem->row(), 0, parentItem);
97 }
98 
104 int TreeModel::rowCount(const QModelIndex& parent) const
105 {
106  TreeItem* parentItem;
107  if (parent.column() > 0)
108  {
109  return 0;
110  }
111 
112  if (!parent.isValid())
113  {
114  parentItem = _rootItem;
115  }
116  else
117  {
118  parentItem = static_cast<TreeItem*>(parent.internalPointer());
119  }
120 
121  return parentItem->childCount();
122 }
123 
127 int TreeModel::columnCount(const QModelIndex& parent) const
128 {
129  if (parent.isValid())
130  {
131  return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
132  }
133 
134  return _rootItem->columnCount();
135 }
136 
142 QVariant TreeModel::data(const QModelIndex& index, int role) const
143 {
144  if (!index.isValid())
145  {
146  return QVariant();
147  }
148 
149  if (role == Qt::EditRole || role == Qt::DisplayRole)
150  {
151  auto* item = static_cast<TreeItem*>(index.internalPointer());
152 
153  return item->data(index.column());
154  }
155 
156  return QVariant();
157 }
158 
159 bool TreeModel::setData(const QModelIndex& index, const QVariant& value,
160  int role /* = Qt::EditRole */)
161 {
162  if (!index.isValid())
163  {
164  return false;
165  }
166 
167  if (role == Qt::EditRole)
168  {
169  auto* item = static_cast<TreeItem*>(index.internalPointer());
170  item->setData(index.column(), value);
171  return true;
172  }
173  return false;
174 }
175 Qt::ItemFlags TreeModel::flags(const QModelIndex& index) const
176 {
177  if (!index.isValid())
178  {
179  return Qt::NoItemFlags;
180  }
181 
182  return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
183 }
184 
188 TreeItem* TreeModel::getItem(const QModelIndex& index) const
189 {
190  if (index.isValid())
191  {
192  auto* item = static_cast<TreeItem*>(index.internalPointer());
193  if (item)
194  {
195  return item;
196  }
197  }
198  return _rootItem;
199 }
200 
201 QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
202  int role) const
203 {
204  if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
205  {
206  return _rootItem->data(section);
207  }
208 
209  return QVariant();
210 }
211 
215 bool TreeModel::removeRows(int position, int count, const QModelIndex& parent)
216 {
217  TreeItem* parentItem = getItem(parent);
218  bool success = true;
219 
220  beginRemoveRows(parent, position, position + count - 1);
221  success = parentItem->removeChildren(position, count);
222  endRemoveRows();
223 
224  return success;
225 }
226 
230 void TreeModel::setupModelData(const QStringList& lines, TreeItem* parent)
231 {
232  QList<TreeItem*> parents;
233  QList<int> indentations;
234  parents << parent;
235  indentations << 0;
236 
237  int number = 0;
238 
239  while (number < lines.count())
240  {
241  int position = 0;
242  while (position < lines[number].length())
243  {
244  if (lines[number].mid(position, 1) != " ")
245  {
246  break;
247  }
248  position++;
249  }
250 
251  QString lineData = lines[number].mid(position).trimmed();
252 
253  if (!lineData.isEmpty())
254  {
255  // Read the column data from the rest of the line.
256  QStringList columnStrings =
257  lineData.split("\t", Qt::SkipEmptyParts);
258  QList<QVariant> columnData;
259  for (int column = 0; column < columnStrings.count(); ++column)
260  {
261  columnData << columnStrings[column];
262  }
263 
264  if (position > indentations.last())
265  {
266  // The last child of the current parent is now the new parent
267  // unless the current parent has no children.
268 
269  if (parents.last()->childCount() > 0)
270  {
271  parents << parents.last()->child(
272  parents.last()->childCount() - 1);
273  indentations << position;
274  }
275  }
276  else
277  {
278  while (position < indentations.last() && parents.count() > 0)
279  {
280  parents.pop_back();
281  indentations.pop_back();
282  }
283  }
284 
285  // Append a new item to the current parent's list of children.
286  parents.last()->appendChild(
287  new TreeItem(columnData, parents.last()));
288  }
289 
290  number++;
291  }
292 }
293 
295 {
296  return _rootItem;
297 }
Definition of the TreeItem class.
Definition of the TreeModel class.
Objects nodes for the TreeModel.
Definition: TreeItem.h:28
virtual int childCount() const
Definition: TreeItem.cpp:65
virtual int columnCount() const
Definition: TreeItem.cpp:86
TreeItem * parentItem() const
Definition: TreeItem.cpp:115
TreeItem * child(int row) const
Definition: TreeItem.cpp:52
int row() const
Definition: TreeItem.cpp:73
bool removeChildren(int position, int count)
Definition: TreeItem.cpp:124
virtual bool setData(int column, const QVariant &value)
Definition: TreeItem.cpp:102
virtual QVariant data(int column) const
Definition: TreeItem.cpp:94
~TreeModel() override
Definition: TreeModel.cpp:37
void setupModelData(const QStringList &lines, TreeItem *parent)
Definition: TreeModel.cpp:230
bool removeRows(int position, int count, const QModelIndex &parent) override
Definition: TreeModel.cpp:215
TreeItem * getItem(const QModelIndex &index) const
Definition: TreeModel.cpp:188
void updateData()
Definition: TreeModel.cpp:137
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: TreeModel.cpp:104
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: TreeModel.cpp:50
QVariant data(const QModelIndex &index, int role) const override
Definition: TreeModel.cpp:142
QModelIndex parent(const QModelIndex &index) const override
Definition: TreeModel.cpp:81
TreeItem * rootItem() const
Definition: TreeModel.cpp:294
TreeModel(QObject *parent=nullptr)
Definition: TreeModel.cpp:26
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Definition: TreeModel.cpp:127
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Definition: TreeModel.cpp:201
Qt::ItemFlags flags(const QModelIndex &index) const override
Definition: TreeModel.cpp:175
TreeItem * _rootItem
Definition: TreeModel.h:58
bool setData(const QModelIndex &index, const QVariant &value, int role) override
Definition: TreeModel.cpp:159