1
/****************************************************************************
3
** Copyright (C) 2007 Trolltech ASA. All rights reserved.
5
** This file is part of the Qt Concurrent project on Trolltech Labs.
7
** This file may be used under the terms of the GNU General Public
8
** License version 2.0 as published by the Free Software Foundation
9
** and appearing in the file LICENSE.GPL included in the packaging of
10
** this file. Please review the following information to ensure GNU
11
** General Public Licensing requirements will be met:
12
** http://www.trolltech.com/products/qt/opensource.html
14
** If you are unsure which license is appropriate for your use, please
15
** review the following information:
16
** http://www.trolltech.com/products/qt/licensing.html or contact the
17
** sales department at sales@trolltech.com.
19
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22
****************************************************************************/
24
#include "modeltest.h"
26
#include <QtGui/QtGui>
28
Q_DECLARE_METATYPE ( QModelIndex )
31
Connect to all of the models signals. Whenever anything happens recheck everything.
33
ModelTest::ModelTest ( QAbstractItemModel *_model, QObject *parent ) : QObject ( parent ), model ( _model ), fetchingMore ( false )
37
connect ( model, SIGNAL ( columnsAboutToBeInserted ( const QModelIndex &, int, int ) ),
38
this, SLOT ( runAllTests() ) );
39
connect ( model, SIGNAL ( columnsAboutToBeRemoved ( const QModelIndex &, int, int ) ),
40
this, SLOT ( runAllTests() ) );
41
connect ( model, SIGNAL ( columnsInserted ( const QModelIndex &, int, int ) ),
42
this, SLOT ( runAllTests() ) );
43
connect ( model, SIGNAL ( columnsRemoved ( const QModelIndex &, int, int ) ),
44
this, SLOT ( runAllTests() ) );
45
connect ( model, SIGNAL ( dataChanged ( const QModelIndex &, const QModelIndex & ) ),
46
this, SLOT ( runAllTests() ) );
47
connect ( model, SIGNAL ( headerDataChanged ( Qt::Orientation, int, int ) ),
48
this, SLOT ( runAllTests() ) );
49
connect ( model, SIGNAL ( layoutAboutToBeChanged () ), this, SLOT ( runAllTests() ) );
50
connect ( model, SIGNAL ( layoutChanged () ), this, SLOT ( runAllTests() ) );
51
connect ( model, SIGNAL ( modelReset () ), this, SLOT ( runAllTests() ) );
52
connect ( model, SIGNAL ( modelAboutToBeReset () ), this, SLOT ( modelAboutToBeReset() ) );
53
connect ( model, SIGNAL ( modelReset () ), this, SLOT ( modelReset() ) );
54
connect ( model, SIGNAL ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ),
55
this, SLOT ( runAllTests() ) );
56
connect ( model, SIGNAL ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ),
57
this, SLOT ( runAllTests() ) );
58
connect ( model, SIGNAL ( rowsInserted ( const QModelIndex &, int, int ) ),
59
this, SLOT ( runAllTests() ) );
60
connect ( model, SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ),
61
this, SLOT ( runAllTests() ) );
63
// Special checks for inserting/removing
64
connect ( model, SIGNAL ( layoutAboutToBeChanged() ),
65
this, SLOT ( layoutAboutToBeChanged() ) );
66
connect ( model, SIGNAL ( layoutChanged() ),
67
this, SLOT ( layoutChanged() ) );
69
connect ( model, SIGNAL ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ),
70
this, SLOT ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ) );
71
connect ( model, SIGNAL ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ),
72
this, SLOT ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ) );
73
connect ( model, SIGNAL ( rowsInserted ( const QModelIndex &, int, int ) ),
74
this, SLOT ( rowsInserted ( const QModelIndex &, int, int ) ) );
75
connect ( model, SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ),
76
this, SLOT ( rowsRemoved ( const QModelIndex &, int, int ) ) );
78
connect ( model, SIGNAL ( rowsAboutToBeMoved ( const QModelIndex &, int, int, const QModelIndex &, int ) ),
79
this, SLOT ( rowsAboutToBeMoved ( const QModelIndex &, int, int, const QModelIndex &, int ) ) );
80
connect ( model, SIGNAL ( rowsMoved ( const QModelIndex &, int, int, const QModelIndex &, int ) ),
81
this, SLOT ( rowsMoved ( const QModelIndex &, int, int, const QModelIndex &, int ) ) );
86
void ModelTest::runAllTests()
89
// qDebug() << "rats";
92
nonDestructiveBasicTest();
102
nonDestructiveBasicTest tries to call a number of the basic functions (not all)
103
to make sure the model doesn't outright segfault, testing the functions that makes sense.
105
void ModelTest::nonDestructiveBasicTest()
107
Q_ASSERT ( model->buddy ( QModelIndex() ) == QModelIndex() );
108
// model->canFetchMore ( QModelIndex() );
109
Q_ASSERT ( model->columnCount ( QModelIndex() ) >= 0 );
110
Q_ASSERT ( model->data ( QModelIndex() ) == QVariant() );
111
// fetchingMore = true;
112
// model->fetchMore ( QModelIndex() );
113
// fetchingMore = false;
114
Qt::ItemFlags flags = model->flags ( QModelIndex() );
115
Q_ASSERT ( flags == Qt::ItemIsDropEnabled || flags == 0 );
116
model->hasChildren ( QModelIndex() );
117
model->hasIndex ( 0, 0 );
118
model->headerData ( 0, Qt::Horizontal );
119
model->index ( 0, 0 );
120
model->itemData ( QModelIndex() );
122
model->match ( QModelIndex(), -1, cache );
124
Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() );
125
Q_ASSERT ( model->rowCount() >= 0 );
127
model->setData ( QModelIndex(), variant, -1 );
128
model->setHeaderData ( -1, Qt::Horizontal, QVariant() );
129
model->setHeaderData ( 999999, Qt::Horizontal, QVariant() );
130
QMap<int, QVariant> roles;
131
model->sibling ( 0, 0, QModelIndex() );
132
model->span ( QModelIndex() );
133
model->supportedDropActions();
137
Tests model's implementation of QAbstractItemModel::rowCount() and hasChildren()
139
Models that are dynamically populated are not as fully tested here.
141
void ModelTest::rowCount()
145
QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
146
int rows = model->rowCount ( topIndex );
147
Q_ASSERT ( rows >= 0 );
149
Q_ASSERT ( model->hasChildren ( topIndex ) == true );
151
QModelIndex secondLevelIndex = model->index ( 0, 0, topIndex );
152
if ( secondLevelIndex.isValid() ) { // not the top level
153
// check a row count where parent is valid
154
rows = model->rowCount ( secondLevelIndex );
155
Q_ASSERT ( rows >= 0 );
157
Q_ASSERT ( model->hasChildren ( secondLevelIndex ) == true );
160
// The models rowCount() is tested more extensively in checkChildren(),
161
// but this catches the big mistakes
165
Tests model's implementation of QAbstractItemModel::columnCount() and hasChildren()
167
void ModelTest::columnCount()
170
QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
171
Q_ASSERT ( model->columnCount ( topIndex ) >= 0 );
173
// check a column count where parent is valid
174
QModelIndex childIndex = model->index ( 0, 0, topIndex );
175
if ( childIndex.isValid() )
176
Q_ASSERT ( model->columnCount ( childIndex ) >= 0 );
178
// columnCount() is tested more extensively in checkChildren(),
179
// but this catches the big mistakes
183
Tests model's implementation of QAbstractItemModel::hasIndex()
185
void ModelTest::hasIndex()
188
// Make sure that invalid values returns an invalid index
189
Q_ASSERT ( model->hasIndex ( -2, -2 ) == false );
190
Q_ASSERT ( model->hasIndex ( -2, 0 ) == false );
191
Q_ASSERT ( model->hasIndex ( 0, -2 ) == false );
193
int rows = model->rowCount();
194
int columns = model->columnCount();
196
// check out of bounds
197
Q_ASSERT ( model->hasIndex ( rows, columns ) == false );
198
Q_ASSERT ( model->hasIndex ( rows + 1, columns + 1 ) == false );
201
Q_ASSERT ( model->hasIndex ( 0, 0 ) == true );
203
// hasIndex() is tested more extensively in checkChildren(),
204
// but this catches the big mistakes
208
Tests model's implementation of QAbstractItemModel::index()
210
void ModelTest::index()
213
// Make sure that invalid values returns an invalid index
214
Q_ASSERT ( model->index ( -2, -2 ) == QModelIndex() );
215
Q_ASSERT ( model->index ( -2, 0 ) == QModelIndex() );
216
Q_ASSERT ( model->index ( 0, -2 ) == QModelIndex() );
218
int rows = model->rowCount();
219
int columns = model->columnCount();
224
// Catch off by one errors
225
Q_ASSERT ( model->index ( rows, columns ) == QModelIndex() );
226
Q_ASSERT ( model->index ( 0, 0 ).isValid() == true );
228
// Make sure that the same index is *always* returned
229
QModelIndex a = model->index ( 0, 0 );
230
QModelIndex b = model->index ( 0, 0 );
233
// index() is tested more extensively in checkChildren(),
234
// but this catches the big mistakes
238
Tests model's implementation of QAbstractItemModel::parent()
240
void ModelTest::parent()
243
// Make sure the model wont crash and will return an invalid QModelIndex
244
// when asked for the parent of an invalid index.
245
Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() );
247
if ( model->rowCount() == 0 )
250
// Column 0 | Column 1 |
252
// \- topIndex | topIndex1 |
253
// \- childIndex | childIndex1 |
255
// Common error test #1, make sure that a top level index has a parent
256
// that is a invalid QModelIndex.
257
QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
258
Q_ASSERT ( model->parent ( topIndex ) == QModelIndex() );
260
// Common error test #2, make sure that a second level index has a parent
261
// that is the first level index.
262
if ( model->rowCount ( topIndex ) > 0 ) {
263
QModelIndex childIndex = model->index ( 0, 0, topIndex );
264
Q_ASSERT ( model->parent ( childIndex ) == topIndex );
267
// Common error test #3, the second column should NOT have the same children
268
// as the first column in a row.
269
// Usually the second column shouldn't have children.
270
QModelIndex topIndex1 = model->index ( 0, 1, QModelIndex() );
271
if ( model->rowCount ( topIndex1 ) > 0 ) {
272
QModelIndex childIndex = model->index ( 0, 0, topIndex );
273
QModelIndex childIndex1 = model->index ( 0, 0, topIndex1 );
274
Q_ASSERT ( childIndex != childIndex1 );
277
// Full test, walk n levels deep through the model making sure that all
278
// parent's children correctly specify their parent.
279
checkChildren ( QModelIndex() );
283
Called from the parent() test.
285
A model that returns an index of parent X should also return X when asking
286
for the parent of the index.
288
This recursive function does pretty extensive testing on the whole model in an
289
effort to catch edge cases.
291
This function assumes that rowCount(), columnCount() and index() already work.
292
If they have a bug it will point it out, but the above tests should have already
293
found the basic bugs because it is easier to figure out the problem in
294
those tests then this one.
296
void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth )
298
// First just try walking back up the tree.
299
QModelIndex p = parent;
300
while ( p.isValid() )
303
// For models that are dynamically populated
304
// if ( model->canFetchMore ( parent ) ) {
305
// fetchingMore = true;
306
// model->fetchMore ( parent );
307
// fetchingMore = false;
310
int rows = model->rowCount ( parent );
311
int columns = model->columnCount ( parent );
316
Q_ASSERT(parent.column() <= 0);
317
Q_ASSERT ( model->hasChildren ( parent ) );
320
// Some further testing against rows(), columns(), and hasChildren()
321
Q_ASSERT ( rows >= 0 );
322
Q_ASSERT ( columns >= 0 );
324
Q_ASSERT ( model->hasChildren ( parent ) == true );
326
//qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows
327
// << "columns:" << columns << "parent column:" << parent.column();
329
Q_ASSERT ( model->hasIndex ( rows, 0, parent ) == false );
330
Q_ASSERT ( model->index(rows, 0, parent).isValid() == false );
331
for ( int r = 0; r < rows; ++r ) {
332
// if ( model->canFetchMore ( parent ) ) {
333
// fetchingMore = true;
334
// model->fetchMore ( parent );
335
// fetchingMore = false;
337
Q_ASSERT ( model->hasIndex ( r, columns, parent ) == false );
338
Q_ASSERT ( model->index(r, columns, parent).isValid() == false );
339
for ( int c = 0; c < columns; ++c ) {
340
Q_ASSERT ( model->hasIndex ( r, c, parent ) == true );
341
QModelIndex index = model->index ( r, c, parent );
342
// rowCount() and columnCount() said that it existed...
343
Q_ASSERT ( index.isValid() == true );
345
// index() should always return the same index when called twice in a row
346
QModelIndex modifiedIndex = model->index ( r, c, parent );
347
Q_ASSERT ( index == modifiedIndex );
349
// Make sure we get the same index if we request it twice in a row
350
QModelIndex a = model->index ( r, c, parent );
351
QModelIndex b = model->index ( r, c, parent );
354
// Some basic checking on the index that is returned
355
Q_ASSERT ( index.model() == model );
356
Q_ASSERT ( index.row() == r );
357
Q_ASSERT ( index.column() == c );
358
// While you can technically return a QVariant usually this is a sign
359
// of an bug in data() Disable if this really is ok in your model.
360
// qDebug() << index << index.data() << index.parent();
361
Q_ASSERT ( model->data ( index, Qt::DisplayRole ).isValid() == true );
363
// If the next test fails here is some somewhat useful debug you play with.
365
if (model->parent(index) != parent) {
366
qDebug() << r << c << currentDepth << model->data(index).toString()
367
<< model->data(parent).toString();
368
qDebug() << index << parent << model->parent(index);
369
// And a view that you can even use to show the model.
371
//view.setModel(model);
375
// Check that we can get back our real parent.
376
Q_ASSERT ( model->parent ( index ) == parent );
378
// recursively go down the children
379
if ( model->hasChildren ( index ) && currentDepth < 10 ) {
380
//qDebug() << r << c << "has children" << model->rowCount(index);
381
checkChildren ( index, ++currentDepth );
382
}/* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/
384
// make sure that after testing the children that the index doesn't change.
385
QModelIndex newerIndex = model->index ( r, c, parent );
386
Q_ASSERT ( index == newerIndex );
392
Tests model's implementation of QAbstractItemModel::data()
394
void ModelTest::data()
396
// Invalid index should return an invalid qvariant
397
Q_ASSERT ( !model->data ( QModelIndex() ).isValid() );
399
if ( model->rowCount() == 0 )
402
// A valid index should have a valid QVariant data
403
Q_ASSERT ( model->index ( 0, 0 ).isValid() );
405
// shouldn't be able to set data on an invalid index
406
Q_ASSERT ( model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) == false );
408
// General Purpose roles that should return a QString
409
QVariant variant = model->data ( model->index ( 0, 0 ), Qt::ToolTipRole );
410
if ( variant.isValid() ) {
411
Q_ASSERT ( qVariantCanConvert<QString> ( variant ) );
413
variant = model->data ( model->index ( 0, 0 ), Qt::StatusTipRole );
414
if ( variant.isValid() ) {
415
Q_ASSERT ( qVariantCanConvert<QString> ( variant ) );
417
variant = model->data ( model->index ( 0, 0 ), Qt::WhatsThisRole );
418
if ( variant.isValid() ) {
419
Q_ASSERT ( qVariantCanConvert<QString> ( variant ) );
422
// General Purpose roles that should return a QSize
423
variant = model->data ( model->index ( 0, 0 ), Qt::SizeHintRole );
424
if ( variant.isValid() ) {
425
Q_ASSERT ( qVariantCanConvert<QSize> ( variant ) );
428
// General Purpose roles that should return a QFont
429
QVariant fontVariant = model->data ( model->index ( 0, 0 ), Qt::FontRole );
430
if ( fontVariant.isValid() ) {
431
Q_ASSERT ( qVariantCanConvert<QFont> ( fontVariant ) );
434
// Check that the alignment is one we know about
435
QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole );
436
if ( textAlignmentVariant.isValid() ) {
437
int alignment = textAlignmentVariant.toInt();
438
Q_ASSERT ( alignment == ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) );
441
// General Purpose roles that should return a QColor
442
QVariant colorVariant = model->data ( model->index ( 0, 0 ), Qt::BackgroundColorRole );
443
if ( colorVariant.isValid() ) {
444
Q_ASSERT ( qVariantCanConvert<QColor> ( colorVariant ) );
447
colorVariant = model->data ( model->index ( 0, 0 ), Qt::TextColorRole );
448
if ( colorVariant.isValid() ) {
449
Q_ASSERT ( qVariantCanConvert<QColor> ( colorVariant ) );
452
// Check that the "check state" is one we know about.
453
QVariant checkStateVariant = model->data ( model->index ( 0, 0 ), Qt::CheckStateRole );
454
if ( checkStateVariant.isValid() ) {
455
int state = checkStateVariant.toInt();
456
Q_ASSERT ( state == Qt::Unchecked ||
457
state == Qt::PartiallyChecked ||
458
state == Qt::Checked );
463
Store what is about to be inserted to make sure it actually happens
467
void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, int end )
470
qDebug() << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data ( parent ).value<QString>()
471
<< "current count of parent=" << model->rowCount ( parent ); // << "display of last=" << model->data( model->index(start-1, 0, parent) );
472
// qDebug() << model->index(start-1, 0, parent) << model->data( model->index(start-1, 0, parent) );
475
c.oldSize = model->rowCount ( parent );
476
c.last = model->data ( model->index ( start - 1, 0, parent ) );
477
c.next = model->data ( model->index ( start, 0, parent ) );
482
Confirm that what was said was going to happen actually did
484
\sa rowsAboutToBeInserted()
486
void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end )
488
Changing c = insert.pop();
489
Q_ASSERT ( c.parent == parent );
490
qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize
491
<< "parent=" << model->data ( parent ).value<QString>() << "current rowcount=" << model->rowCount ( parent );
493
for (int ii=start; ii <= end; ii++)
495
qDebug() << "itemWasInserted:" << model->data ( model->index ( ii, 0, parent ));
499
Q_ASSERT ( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) );
500
Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) );
502
if (c.next != model->data(model->index(end + 1, 0, c.parent))) {
503
qDebug() << start << end;
504
for (int i=0; i < model->rowCount(); ++i)
505
qDebug() << model->index(i, 0).data().toString();
506
qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent));
509
Q_ASSERT ( c.next == model->data ( model->index ( end + 1, 0, c.parent ) ) );
513
void ModelTest::modelAboutToBeReset()
515
qDebug() << "@@@@@@@@@@@" << "modelAboutToBeReset";
518
void ModelTest::modelReset()
520
qDebug() << "@@@@@@@@@@@" << "modelReset";
523
void ModelTest::layoutAboutToBeChanged()
525
for ( int i = 0; i < qBound ( 0, model->rowCount(), 100 ); ++i )
526
changing.append ( QPersistentModelIndex ( model->index ( i, 0 ) ) );
529
void ModelTest::layoutChanged()
531
for ( int i = 0; i < changing.count(); ++i ) {
532
QPersistentModelIndex p = changing[i];
533
Q_ASSERT ( p == model->index ( p.row(), p.column(), p.parent() ) );
538
void ModelTest::rowsAboutToBeMoved(const QModelIndex &srcParent, int start, int end, const QModelIndex &destParent, int destinationRow )
540
qDebug() << "rowsAboutToBeMoved" << srcParent << start << end << destParent << destinationRow;
542
cs.parent = srcParent;
543
cs.oldSize = model->rowCount ( srcParent );
544
cs.last = model->data ( model->index ( start - 1, 0, srcParent ) );
545
cs.next = model->data ( model->index ( end + 1, 0, srcParent ) );
548
cd.parent = destParent;
549
cd.oldSize = model->rowCount ( destParent );
550
cd.last = model->data ( model->index ( destinationRow - 1, 0, destParent ) );
551
cd.next = model->data ( model->index ( destinationRow, 0, destParent ) );
555
void ModelTest::rowsMoved(const QModelIndex &srcParent, int start, int end, const QModelIndex &destParent, int destinationRow )
557
qDebug() << "rowsMoved" << srcParent << start << end << destParent << destinationRow;
559
Changing cd = insert.pop();
560
Q_ASSERT ( cd.parent == destParent );
561
if (srcParent == destParent)
563
Q_ASSERT ( cd.oldSize == model->rowCount ( destParent ) );
565
// TODO: Find out what I can assert here about last and next.
566
// Q_ASSERT ( cd.last == model->data ( model->index ( destinationRow - 1, 0, cd.parent ) ) );
567
// Q_ASSERT ( cd.next == model->data ( model->index ( destinationRow + (end - start + 1), 0, cd.parent ) ) );
573
Q_ASSERT ( cd.oldSize + ( end - start + 1 ) == model->rowCount ( destParent ) );
575
Q_ASSERT ( cd.last == model->data ( model->index ( destinationRow - 1, 0, cd.parent ) ) );
576
Q_ASSERT ( cd.next == model->data ( model->index ( destinationRow + (end - start + 1), 0, cd.parent ) ) );
578
Changing cs = remove.pop();
580
Q_ASSERT ( cs.parent == srcParent );
581
if (srcParent == destParent)
583
Q_ASSERT ( cs.oldSize == model->rowCount ( srcParent ) );
587
Q_ASSERT ( cs.oldSize - ( end - start + 1 ) == model->rowCount ( srcParent ) );
589
Q_ASSERT ( cs.last == model->data ( model->index ( start - 1, 0, srcParent ) ) );
590
qDebug() << cs.next << model->data ( model->index ( start, 0, srcParent ) );
591
Q_ASSERT ( cs.next == model->data ( model->index ( start, 0, srcParent ) ) );
597
Store what is about to be inserted to make sure it actually happens
601
void ModelTest::rowsAboutToBeRemoved ( const QModelIndex &parent, int start, int end )
603
qDebug() << "ratbr" << parent << start << end;
604
for (int ii=start; ii <= end; ii++)
606
qDebug() << "itemwillbe removed:" << model->data ( model->index ( ii, 0, parent ));
612
c.oldSize = model->rowCount ( parent );
613
c.last = model->data ( model->index ( start - 1, 0, parent ) );
614
c.next = model->data ( model->index ( end + 1, 0, parent ) );
619
Confirm that what was said was going to happen actually did
621
\sa rowsAboutToBeRemoved()
623
void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end )
625
qDebug() << "rr" << parent << start << end;
626
Changing c = remove.pop();
627
Q_ASSERT ( c.parent == parent );
628
Q_ASSERT ( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) );
629
Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) );
630
Q_ASSERT ( c.next == model->data ( model->index ( start, 0, c.parent ) ) );