comparison examples/itemviews/editabletreemodel/treemodel.d @ 153:ea0861a37bf6

add editabletreemodel, still buggy
author mandel
date Tue, 16 Jun 2009 00:51:38 +0000
parents
children
comparison
equal deleted inserted replaced
152:4d1c5d1d1bbf 153:ea0861a37bf6
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Qt Software Information (qt-info@nokia.com)
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 qt-sales@nokia.com.
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 module treemodel;
42
43
44 import qt.core.QAbstractItemModel;
45 import qt.core.QModelIndex;
46 import qt.core.QVariant;
47
48 import treeitem;
49
50 import tango.core.Array : find;
51 import tango.text.Util : trim;
52
53
54 //replacement for QString.split
55 T[][] split(T)(T[] str, T[] match, bool keep_empty = true)
56 {
57 uint pos, start = 0;
58
59 T[][] values;
60 if(str.length == 0)
61 return values;
62
63 while(true)
64 {
65 pos = start + find(str[start..$], match);
66 if(keep_empty)
67 {
68 if((pos - start) >= 0)
69 values ~= str[start..pos];
70 }
71 else
72 {
73 if((pos - start) != 0)
74 values ~= str[start..pos];
75 }
76
77 if(pos == str.length)
78 break;
79
80 start = pos + 1;
81 }
82
83 return values;
84 }
85
86
87 class TreeModel : public QAbstractItemModel
88 {
89 public:
90
91 this(string[] headers, string data, QObject parent = null)
92 {
93 super(parent);
94 QVariant[] rootData;
95 foreach(string header; headers)
96 rootData ~= new QVariant(header);
97
98 rootItem = new TreeItem(rootData);
99 setupModelData(split(data, "\n"), rootItem);
100 }
101
102 ~this()
103 {
104 delete rootItem;
105 }
106
107 QVariant data(QModelIndex index, int role)
108 {
109 if (!index.isValid())
110 return new QVariant();
111
112 if (role != Qt.DisplayRole && role != Qt.EditRole)
113 return new QVariant();
114
115 TreeItem item = getItem(index);
116 return item.data(index.column());
117 }
118
119 QVariant headerData(int section, Qt.Orientation orientation, int role = Qt.DisplayRole)
120 {
121 if (orientation == Qt.Horizontal && role == Qt.DisplayRole)
122 return rootItem.data(section);
123
124 return new QVariant();
125 }
126
127 QModelIndex index(int row, int column, QModelIndex parent = QModelIndex())
128 {
129 if (parent.isValid() && parent.column() != 0)
130 return QModelIndex();
131
132 TreeItem parentItem = getItem(parent);
133
134 TreeItem childItem = parentItem.child(row);
135 if (childItem)
136 return createIndex(row, column, cast(void*) childItem);
137 else
138 return QModelIndex();
139 }
140
141 QModelIndex parent(QModelIndex index)
142 {
143 if (!index.isValid())
144 return QModelIndex();
145
146 TreeItem childItem = getItem(index);
147 TreeItem parentItem = childItem.parent();
148
149 if (parentItem == rootItem)
150 return QModelIndex();
151
152 return createIndex(parentItem.childNumber(), 0, cast(void*) parentItem);
153 }
154
155 int rowCount(QModelIndex parent = QModelIndex())
156 {
157 TreeItem parentItem = getItem(parent);
158 return parentItem.childCount();
159 }
160
161 int columnCount(QModelIndex parent = QModelIndex())
162 {
163 return rootItem.columnCount();
164 }
165
166 int flags(QModelIndex index)
167 {
168 if (!index.isValid())
169 return 0;
170
171 return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable;
172 }
173
174
175 bool setData(QModelIndex index, QVariant value, int role = Qt.EditRole)
176 {
177 if (role != Qt.EditRole)
178 return false;
179
180 TreeItem item = getItem(index);
181 bool result = item.setData(index.column(), value);
182
183 if (result)
184 dataChanged.emit(index, index);
185
186 return result;
187 }
188
189 bool setHeaderData(int section, Qt.Orientation orientation, QVariant value, int role = Qt.EditRole)
190 {
191 if (role != Qt.EditRole || orientation != Qt.Horizontal)
192 return false;
193
194 bool result = rootItem.setData(section, value);
195
196 if (result)
197 headerDataChanged.emit(orientation, section, section);
198
199 return result;
200 }
201
202 bool insertColumns(int position, int columns, QModelIndex parent = QModelIndex())
203 {
204 bool success;
205
206 beginInsertColumns(parent, position, position + columns - 1);
207 success = rootItem.insertColumns(position, columns);
208 endInsertColumns();
209
210 return success;
211 }
212
213
214 bool removeColumns(int position, int columns, QModelIndex parent = QModelIndex())
215 {
216 bool success;
217
218 beginRemoveColumns(parent, position, position + columns - 1);
219 success = rootItem.removeColumns(position, columns);
220 endRemoveColumns();
221
222 if (rootItem.columnCount() == 0)
223 removeRows(0, rowCount());
224
225 return success;
226 }
227
228
229 bool insertRows(int position, int rows, QModelIndex parent = QModelIndex())
230 {
231 TreeItem parentItem = getItem(parent);
232 bool success;
233
234 beginInsertRows(parent, position, position + rows - 1);
235 success = parentItem.insertChildren(position, rows, rootItem.columnCount());
236 endInsertRows();
237
238 return success;
239 }
240
241 bool removeRows(int position, int rows, QModelIndex parent = QModelIndex())
242 {
243 TreeItem parentItem = getItem(parent);
244 bool success = true;
245
246 beginRemoveRows(parent, position, position + rows - 1);
247 success = parentItem.removeChildren(position, rows);
248 endRemoveRows();
249
250 return success;
251 }
252
253 private:
254
255 void setupModelData(string[] lines, TreeItem parent)
256 {
257 TreeItem[] parents;
258 int[] indentations;
259 parents ~= parent;
260 indentations ~= 0;
261
262 int number = 0;
263
264 while (number < lines.length) {
265 int position = 0;
266 while (position < lines[number].length) {
267 if (lines[number][position] != ' ')
268 break;
269 position++;
270 }
271
272 string lineData = trim(lines[number][position..$]);
273
274 if (lineData.length) {
275 // Read the column data from the rest of the line.
276 string[] columnStrings = split(lineData, "\t", false);
277 QVariant[] columnData;
278 for (int column = 0; column < columnStrings.length; ++column)
279 columnData ~= new QVariant(columnStrings[column]);
280
281 if (position > indentations[$-1]) {
282 // The last child of the current parent is now the new parent
283 // unless the current parent has no children.
284
285 if (parents[$-1].childCount() > 0) {
286 parents ~= parents[$-1].child(parents[$-1].childCount()-1);
287 indentations ~= position;
288 }
289 } else {
290 while (position < indentations[$-1] && parents.length > 0) {
291 parents = parents[0..$-1];
292 indentations = indentations[0..$-1];
293 }
294 }
295
296 // Append a new item to the current parent's list of children.
297 parent = parents[$-1];
298 parent.insertChildren(parent.childCount(), 1, rootItem.columnCount());
299 for (int column = 0; column < columnData.length; ++column)
300 parent.child(parent.childCount() - 1).setData(column, columnData[column]);
301 }
302
303 number++;
304 }
305 }
306
307 TreeItem getItem(QModelIndex index)
308 {
309 if (index.isValid()) {
310 TreeItem item = cast(TreeItem) index.internalPointer();
311 if (item) return item;
312 }
313 return rootItem;
314 }
315
316 TreeItem rootItem;
317 }