Mercurial > projects > qtd
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 } |