source: trunk/examples/itemviews/editabletreemodel/treemodel.cpp@ 440

Last change on this file since 440 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 8.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtGui>
43
44#include "treeitem.h"
45#include "treemodel.h"
46
47//! [0]
48TreeModel::TreeModel(const QStringList &headers, const QString &data,
49 QObject *parent)
50 : QAbstractItemModel(parent)
51{
52 QVector<QVariant> rootData;
53 foreach (QString header, headers)
54 rootData << header;
55
56 rootItem = new TreeItem(rootData);
57 setupModelData(data.split(QString("\n")), rootItem);
58}
59//! [0]
60
61//! [1]
62TreeModel::~TreeModel()
63{
64 delete rootItem;
65}
66//! [1]
67
68//! [2]
69int TreeModel::columnCount(const QModelIndex & /* parent */) const
70{
71 return rootItem->columnCount();
72}
73//! [2]
74
75QVariant TreeModel::data(const QModelIndex &index, int role) const
76{
77 if (!index.isValid())
78 return QVariant();
79
80 if (role != Qt::DisplayRole && role != Qt::EditRole)
81 return QVariant();
82
83 TreeItem *item = getItem(index);
84
85 return item->data(index.column());
86}
87
88//! [3]
89Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
90{
91 if (!index.isValid())
92 return 0;
93
94 return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
95}
96//! [3]
97
98//! [4]
99TreeItem *TreeModel::getItem(const QModelIndex &index) const
100{
101 if (index.isValid()) {
102 TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
103 if (item) return item;
104 }
105 return rootItem;
106}
107//! [4]
108
109QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
110 int role) const
111{
112 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
113 return rootItem->data(section);
114
115 return QVariant();
116}
117
118//! [5]
119QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
120{
121 if (parent.isValid() && parent.column() != 0)
122 return QModelIndex();
123//! [5]
124
125//! [6]
126 TreeItem *parentItem = getItem(parent);
127
128 TreeItem *childItem = parentItem->child(row);
129 if (childItem)
130 return createIndex(row, column, childItem);
131 else
132 return QModelIndex();
133}
134//! [6]
135
136bool TreeModel::insertColumns(int position, int columns, const QModelIndex &parent)
137{
138 bool success;
139
140 beginInsertColumns(parent, position, position + columns - 1);
141 success = rootItem->insertColumns(position, columns);
142 endInsertColumns();
143
144 return success;
145}
146
147bool TreeModel::insertRows(int position, int rows, const QModelIndex &parent)
148{
149 TreeItem *parentItem = getItem(parent);
150 bool success;
151
152 beginInsertRows(parent, position, position + rows - 1);
153 success = parentItem->insertChildren(position, rows, rootItem->columnCount());
154 endInsertRows();
155
156 return success;
157}
158
159//! [7]
160QModelIndex TreeModel::parent(const QModelIndex &index) const
161{
162 if (!index.isValid())
163 return QModelIndex();
164
165 TreeItem *childItem = getItem(index);
166 TreeItem *parentItem = childItem->parent();
167
168 if (parentItem == rootItem)
169 return QModelIndex();
170
171 return createIndex(parentItem->childNumber(), 0, parentItem);
172}
173//! [7]
174
175bool TreeModel::removeColumns(int position, int columns, const QModelIndex &parent)
176{
177 bool success;
178
179 beginRemoveColumns(parent, position, position + columns - 1);
180 success = rootItem->removeColumns(position, columns);
181 endRemoveColumns();
182
183 if (rootItem->columnCount() == 0)
184 removeRows(0, rowCount());
185
186 return success;
187}
188
189bool TreeModel::removeRows(int position, int rows, const QModelIndex &parent)
190{
191 TreeItem *parentItem = getItem(parent);
192 bool success = true;
193
194 beginRemoveRows(parent, position, position + rows - 1);
195 success = parentItem->removeChildren(position, rows);
196 endRemoveRows();
197
198 return success;
199}
200
201//! [8]
202int TreeModel::rowCount(const QModelIndex &parent) const
203{
204 TreeItem *parentItem = getItem(parent);
205
206 return parentItem->childCount();
207}
208//! [8]
209
210bool TreeModel::setData(const QModelIndex &index, const QVariant &value,
211 int role)
212{
213 if (role != Qt::EditRole)
214 return false;
215
216 TreeItem *item = getItem(index);
217 bool result = item->setData(index.column(), value);
218
219 if (result)
220 emit dataChanged(index, index);
221
222 return result;
223}
224
225bool TreeModel::setHeaderData(int section, Qt::Orientation orientation,
226 const QVariant &value, int role)
227{
228 if (role != Qt::EditRole || orientation != Qt::Horizontal)
229 return false;
230
231 bool result = rootItem->setData(section, value);
232
233 if (result)
234 emit headerDataChanged(orientation, section, section);
235
236 return result;
237}
238
239void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent)
240{
241 QList<TreeItem*> parents;
242 QList<int> indentations;
243 parents << parent;
244 indentations << 0;
245
246 int number = 0;
247
248 while (number < lines.count()) {
249 int position = 0;
250 while (position < lines[number].length()) {
251 if (lines[number].mid(position, 1) != " ")
252 break;
253 position++;
254 }
255
256 QString lineData = lines[number].mid(position).trimmed();
257
258 if (!lineData.isEmpty()) {
259 // Read the column data from the rest of the line.
260 QStringList columnStrings = lineData.split("\t", QString::SkipEmptyParts);
261 QVector<QVariant> columnData;
262 for (int column = 0; column < columnStrings.count(); ++column)
263 columnData << columnStrings[column];
264
265 if (position > indentations.last()) {
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 parents << parents.last()->child(parents.last()->childCount()-1);
271 indentations << position;
272 }
273 } else {
274 while (position < indentations.last() && parents.count() > 0) {
275 parents.pop_back();
276 indentations.pop_back();
277 }
278 }
279
280 // Append a new item to the current parent's list of children.
281 TreeItem *parent = parents.last();
282 parent->insertChildren(parent->childCount(), 1, rootItem->columnCount());
283 for (int column = 0; column < columnData.size(); ++column)
284 parent->child(parent->childCount() - 1)->setData(column, columnData[column]);
285 }
286
287 number++;
288 }
289}
Note: See TracBrowser for help on using the repository browser.