source: trunk/doc/src/snippets/qtreeview-dnd/treemodel.cpp@ 624

Last change on this file since 624 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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