NCL Composer  0.1.5
 All Classes Functions Variables Pages
TreeModel.cpp
1 /*
2  * Copyright 2011 TeleMidia/PUC-Rio.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see
16  * <http://www.gnu.org/licenses/>.
17  */
18 /*
19  treemodel.cpp
20 
21  Provides a simple tree model to show how to create and use hierarchical
22  models.
23  */
24 
25 #include <QtGui>
26 
27 #include "TreeItem.h"
28 #include "TreeModel.h"
29 
30 TreeModel::TreeModel(const QString &data, QObject *parent)
31  : QAbstractItemModel(parent)
32 {
33  QList<QVariant> rootData;
34  rootData << "Title" << "Summary";
35  rootItem = new TreeItem(rootData);
36  setupModelData(data.split(QString("\n")), rootItem);
37 }
38 
39 TreeModel::~TreeModel()
40 {
41  delete rootItem;
42 }
43 
44 int TreeModel::columnCount(const QModelIndex &parent) const
45 {
46  if (parent.isValid())
47  return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
48  else
49  return rootItem->columnCount();
50 }
51 
52 QVariant TreeModel::data(const QModelIndex &index, int role) const
53 {
54  if (!index.isValid())
55  return QVariant();
56 
57  if (role != Qt::DisplayRole)
58  return QVariant();
59 
60  TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
61 
62  return item->data(index.column());
63 }
64 
65 Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
66 {
67  if (!index.isValid())
68  return 0;
69 
70  return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
71 }
72 
73 QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
74  int role) const
75 {
76  if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
77  return rootItem->data(section);
78 
79  return QVariant();
80 }
81 
82 QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)
83  const
84 {
85  if (!hasIndex(row, column, parent))
86  return QModelIndex();
87 
88  TreeItem *parentItem;
89 
90  if (!parent.isValid())
91  parentItem = rootItem;
92  else
93  parentItem = static_cast<TreeItem*>(parent.internalPointer());
94 
95  TreeItem *childItem = parentItem->child(row);
96  if (childItem)
97  return createIndex(row, column, childItem);
98  else
99  return QModelIndex();
100 }
101 
102 QModelIndex TreeModel::parent(const QModelIndex &index) const
103 {
104  if (!index.isValid())
105  return QModelIndex();
106 
107  TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
108  TreeItem *parentItem = childItem->parent();
109 
110  if (parentItem == rootItem)
111  return QModelIndex();
112 
113  return createIndex(parentItem->row(), 0, parentItem);
114 }
115 
116 int TreeModel::rowCount(const QModelIndex &parent) const
117 {
118  TreeItem *parentItem;
119  if (parent.column() > 0)
120  return 0;
121 
122  if (!parent.isValid())
123  parentItem = rootItem;
124  else
125  parentItem = static_cast<TreeItem*>(parent.internalPointer());
126 
127  return parentItem->childCount();
128 }
129 
130 void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent)
131 {
132  QList<TreeItem*> parents;
133  QList<int> indentations;
134  parents << parent;
135  indentations << 0;
136 
137  int number = 0;
138 
139  while (number < lines.count()) {
140  int position = 0;
141  while (position < lines[number].length()) {
142  if (lines[number].mid(position, 1) != " ")
143  break;
144  position++;
145  }
146 
147  QString lineData = lines[number].mid(position).trimmed();
148 
149  if (!lineData.isEmpty()) {
150  // Read the column data from the rest of the line.
151  QStringList columnStrings = lineData.split("\t", QString::SkipEmptyParts);
152  QList<QVariant> columnData;
153  for (int column = 0; column < columnStrings.count(); ++column)
154  columnData << columnStrings[column];
155 
156  if (position > indentations.last()) {
157  // The last child of the current parent is now the new parent
158  // unless the current parent has no children.
159 
160  if (parents.last()->childCount() > 0) {
161  parents << parents.last()->child(parents.last()->childCount()-1);
162  indentations << position;
163  }
164  } else {
165  while (position < indentations.last() && parents.count() > 0) {
166  parents.pop_back();
167  indentations.pop_back();
168  }
169  }
170 
171  // Append a new item to the current parent's list of children.
172  parents.last()->appendChild(new TreeItem(columnData, parents.last()));
173  }
174 
175  number++;
176  }
177 }