Remove usage of deprecated qWaitForWindowShown(QWidget *) method.
[profile/ivi/qtbase.git] / tests / auto / widgets / itemviews / qtableview / tst_qtableview.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43 #include <QtGui/QtGui>
44 #include <QtWidgets/QtWidgets>
45 #include <private/qtablewidget_p.h>
46 #include <QtTest/QtTest>
47 #include "private/qapplication_p.h"
48
49 #ifdef QT_BUILD_INTERNAL
50 #define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) \
51     QVERIFY(static_cast<QTableViewPrivate*>(QObjectPrivate::get(TEST_VIEW_))->spans.checkConsistency())
52 #else
53 #define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) (void)false
54 #endif
55
56 typedef QList<int> IntList;
57 Q_DECLARE_METATYPE(IntList)
58
59 typedef QList<bool> BoolList;
60 Q_DECLARE_METATYPE(BoolList)
61
62 class tst_QTableView : public QObject
63 {
64     Q_OBJECT
65
66 public:
67     tst_QTableView();
68     virtual ~tst_QTableView();
69
70 public slots:
71     void initTestCase();
72     void cleanupTestCase();
73     void init();
74     void cleanup();
75
76 private slots:
77     void getSetCheck();
78
79     void noDelegate();
80     void noModel();
81     void emptyModel();
82
83     void removeRows_data();
84     void removeRows();
85
86     void removeColumns_data();
87     void removeColumns();
88
89     void keyboardNavigation_data();
90     void keyboardNavigation();
91
92     void headerSections_data();
93     void headerSections();
94
95     void moveCursor_data();
96     void moveCursor();
97
98     void moveCursorStrikesBack_data();
99     void moveCursorStrikesBack();
100
101     void hideRows_data();
102     void hideRows();
103
104     void hideColumns_data();
105     void hideColumns();
106
107     void selection_data();
108     void selection();
109
110     void selectRow_data();
111     void selectRow();
112
113     void selectColumn_data();
114     void selectColumn();
115
116     void visualRect_data();
117     void visualRect();
118
119     void fetchMore();
120     void setHeaders();
121
122     void resizeRowsToContents_data();
123     void resizeRowsToContents();
124
125     void resizeColumnsToContents_data();
126     void resizeColumnsToContents();
127
128     void rowViewportPosition_data();
129     void rowViewportPosition();
130
131     void rowAt_data();
132     void rowAt();
133
134     void rowHeight_data();
135     void rowHeight();
136
137     void columnViewportPosition_data();
138     void columnViewportPosition();
139
140     void columnAt_data();
141     void columnAt();
142
143     void columnWidth_data();
144     void columnWidth();
145
146     void hiddenRow_data();
147     void hiddenRow();
148
149     void hiddenColumn_data();
150     void hiddenColumn();
151
152     void sortingEnabled_data();
153     void sortingEnabled();
154
155     void scrollTo_data();
156     void scrollTo();
157
158     void indexAt_data();
159     void indexAt();
160
161     void span_data();
162     void span();
163     void spans();
164     void spans_data();
165     void spansAfterRowInsertion();
166     void spansAfterColumnInsertion();
167     void spansAfterRowRemoval();
168     void spansAfterColumnRemoval();
169
170     void checkHeaderReset();
171     void checkHeaderMinSize();
172
173     void resizeToContents();
174
175     void tabFocus();
176     void bigModel();
177     void selectionSignal();
178     void setCurrentIndex();
179
180     // task-specific tests:
181     void task173773_updateVerticalHeader();
182     void task227953_setRootIndex();
183     void task240266_veryBigColumn();
184     void task248688_autoScrollNavigation();
185     void task259308_scrollVerticalHeaderSwappedSections();
186     void task191545_dragSelectRows();
187     void taskQTBUG_5062_spansInconsistency();
188     void taskQTBUG_4516_clickOnRichTextLabel();
189     void taskQTBUG_5237_wheelEventOnHeader();
190     void taskQTBUG_8585_crashForNoGoodReason();
191     void taskQTBUG_7774_RtoLVisualRegionForSelection();
192     void taskQTBUG_8777_scrollToSpans();
193     void taskQTBUG_10169_sizeHintForRow();
194
195     void mouseWheel_data();
196     void mouseWheel();
197
198     void addColumnWhileEditing();
199     void task234926_setHeaderSorting();
200
201     void changeHeaderData();
202 };
203
204 // Testing get/set functions
205 void tst_QTableView::getSetCheck()
206 {
207     QTableView obj1;
208
209     obj1.setSortingEnabled(false);
210     QCOMPARE(false, obj1.isSortingEnabled());
211     obj1.setSortingEnabled(true);
212     QCOMPARE(true, obj1.isSortingEnabled());
213
214     obj1.setShowGrid(false);
215     QCOMPARE(false, obj1.showGrid());
216     obj1.setShowGrid(true);
217     QCOMPARE(true, obj1.showGrid());
218
219     obj1.setGridStyle(Qt::NoPen);
220     QCOMPARE(Qt::NoPen, obj1.gridStyle());
221     obj1.setGridStyle(Qt::SolidLine);
222     QCOMPARE(Qt::SolidLine, obj1.gridStyle());
223
224     obj1.setRootIndex(QModelIndex());
225     QCOMPARE(QModelIndex(), obj1.rootIndex());
226     QStandardItemModel model(10, 10);
227     obj1.setModel(&model);
228     QModelIndex index = model.index(0, 0);
229     obj1.setRootIndex(index);
230     QCOMPARE(index, obj1.rootIndex());
231
232     QHeaderView *var1 = new QHeaderView(Qt::Horizontal);
233     obj1.setHorizontalHeader(var1);
234     QCOMPARE(var1, obj1.horizontalHeader());
235     obj1.setHorizontalHeader((QHeaderView *)0);
236     QCOMPARE(var1, obj1.horizontalHeader());
237     delete var1;
238
239     QHeaderView *var2 = new QHeaderView(Qt::Vertical);
240     obj1.setVerticalHeader(var2);
241     QCOMPARE(var2, obj1.verticalHeader());
242     obj1.setVerticalHeader((QHeaderView *)0);
243     QCOMPARE(var2, obj1.verticalHeader());
244     delete var2;
245
246     QCOMPARE(obj1.isCornerButtonEnabled(), true);
247     obj1.setCornerButtonEnabled(false);
248     QCOMPARE(obj1.isCornerButtonEnabled(), false);
249 }
250
251 class QtTestTableModel: public QAbstractTableModel
252 {
253     Q_OBJECT
254
255 signals:
256     void invalidIndexEncountered() const;
257
258 public slots:
259     bool submit() { ++submit_count; return QAbstractTableModel::submit(); }
260
261 public:
262     QtTestTableModel(int rows = 0, int columns = 0, QObject *parent = 0)
263         : QAbstractTableModel(parent),
264           row_count(rows),
265           column_count(columns),
266           submit_count(0),
267           can_fetch_more(false),
268           fetch_more_count(0),
269           disabled_rows(),
270           disabled_columns() {}
271
272     int rowCount(const QModelIndex& = QModelIndex()) const { return row_count; }
273     int columnCount(const QModelIndex& = QModelIndex()) const { return column_count; }
274     bool isEditable(const QModelIndex &) const { return true; }
275
276     Qt::ItemFlags flags(const QModelIndex &index) const
277     {
278         Qt::ItemFlags index_flags = QAbstractTableModel::flags(index);
279         if (disabled_rows.contains(index.row())
280             || disabled_columns.contains(index.column()))
281             index_flags &= ~Qt::ItemIsEnabled;
282         return index_flags;
283     }
284
285     void disableRow(int row)
286     {
287         disabled_rows.insert(row);
288     }
289
290     void enableRow(int row)
291     {
292         disabled_rows.remove(row);
293     }
294
295     void disableColumn(int column)
296     {
297         disabled_columns.insert(column);
298     }
299
300     void enableColumn(int column)
301     {
302         disabled_columns.remove(column);
303     }
304
305     QVariant data(const QModelIndex &idx, int role) const
306     {
307         if (!idx.isValid() || idx.row() >= row_count || idx.column() >= column_count) {
308             qWarning() << "Invalid modelIndex [%d,%d,%p]" << idx;
309             emit invalidIndexEncountered();
310             return QVariant();
311         }
312
313         if (role == Qt::DisplayRole || role == Qt::EditRole)
314             return QString("[%1,%2,%3]").arg(idx.row()).arg(idx.column()).arg(0);
315
316         return QVariant();
317     }
318
319     bool insertRows(int start, int count, const QModelIndex &parent = QModelIndex())
320     {
321         if (start < 0 || start > row_count)
322             return false;
323
324         beginInsertRows(parent, start, start + count - 1);
325         row_count += count;
326         endInsertRows();
327         return true;
328     }
329
330     bool removeRows(int start, int count, const QModelIndex &parent = QModelIndex())
331     {
332         if (start < 0 || start >= row_count || row_count < count)
333             return false;
334
335         beginRemoveRows(parent, start, start + count - 1);
336         row_count -= count;
337         endRemoveRows();
338         return true;
339     }
340
341     void removeLastRow()
342     {
343         beginRemoveRows(QModelIndex(), row_count - 1, row_count - 1);
344         --row_count;
345         endRemoveRows();
346     }
347
348     void removeAllRows()
349     {
350         beginRemoveRows(QModelIndex(), 0, row_count - 1);
351         row_count = 0;
352         endRemoveRows();
353     }
354
355     bool insertColumns(int start, int count, const QModelIndex &parent = QModelIndex())
356     {
357         if (start < 0 || start > column_count)
358             return false;
359
360         beginInsertColumns(parent, start, start + count - 1);
361         column_count += count;
362         endInsertColumns();
363         return true;
364     }
365
366     bool removeColumns(int start, int count, const QModelIndex &parent = QModelIndex())
367     {
368         if (start < 0 || start >= column_count || column_count < count)
369             return false;
370
371         beginRemoveColumns(parent, start, start + count - 1);
372         column_count -= count;
373         endRemoveColumns();
374         return true;
375     }
376
377     void removeLastColumn()
378     {
379         beginRemoveColumns(QModelIndex(), column_count - 1, column_count - 1);
380         --column_count;
381         endRemoveColumns();
382     }
383
384     void removeAllColumns()
385     {
386         beginRemoveColumns(QModelIndex(), 0, column_count - 1);
387         column_count = 0;
388         endRemoveColumns();
389     }
390
391     bool canFetchMore(const QModelIndex &) const
392     {
393         return can_fetch_more;
394     }
395
396     void fetchMore(const QModelIndex &)
397     {
398         ++fetch_more_count;
399     }
400
401     void reset()
402     {
403         QAbstractTableModel::reset();
404     }
405
406     int row_count;
407     int column_count;
408     int submit_count;
409     bool can_fetch_more;
410     int fetch_more_count;
411     QSet<int> disabled_rows;
412     QSet<int> disabled_columns;
413 };
414
415 class QtTestTableView : public QTableView
416 {
417 Q_OBJECT
418
419 public:
420     QtTestTableView(QWidget *parent = 0) : QTableView(parent), checkSignalOrder(false), hasCurrentChanged(0), hasSelectionChanged(0) {}
421
422     void setModel(QAbstractItemModel *model)
423     {
424         QTableView::setModel(model);
425         connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
426                      this, SLOT(currentChanged(QModelIndex,QModelIndex)));
427         connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
428                      this, SLOT(itemSelectionChanged(QItemSelection,QItemSelection)));
429     }
430
431     enum CursorAction {
432         MoveUp       = QAbstractItemView::MoveUp,
433         MoveDown     = QAbstractItemView::MoveDown,
434         MoveLeft     = QAbstractItemView::MoveLeft,
435         MoveRight    = QAbstractItemView::MoveRight,
436         MoveHome     = QAbstractItemView::MoveHome,
437         MoveEnd      = QAbstractItemView::MoveEnd,
438         MovePageUp   = QAbstractItemView::MovePageUp,
439         MovePageDown = QAbstractItemView::MovePageDown,
440         MoveNext     = QAbstractItemView::MoveNext,
441         MovePrevious = QAbstractItemView::MovePrevious
442     };
443
444     QModelIndex moveCursor(QtTestTableView::CursorAction cursorAction,
445                            Qt::KeyboardModifiers modifiers)
446     {
447         return QTableView::moveCursor((QAbstractItemView::CursorAction)cursorAction, modifiers);
448     }
449
450     int columnWidthHint(int column) const
451     {
452         return sizeHintForColumn(column);
453     }
454
455     int rowHeightHint(int row) const
456     {
457         return sizeHintForRow(row);
458     }
459
460     bool isIndexHidden(const QModelIndex &index) const
461     {
462         return QTableView::isIndexHidden(index);
463     }
464
465     void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
466     {
467         QTableView::setSelection(rect, command);
468     }
469
470     QModelIndexList selectedIndexes() const
471     {
472         return QTableView::selectedIndexes();
473     }
474
475     int sizeHintForRow(int row) const
476     {
477         return QTableView::sizeHintForRow(row);
478     }
479
480     bool checkSignalOrder;
481 public slots:
482     void currentChanged(QModelIndex , QModelIndex ) {
483         hasCurrentChanged++;
484         if (checkSignalOrder)
485             QVERIFY(hasCurrentChanged > hasSelectionChanged);
486     }
487
488     void itemSelectionChanged(QItemSelection , QItemSelection ) {
489         hasSelectionChanged++;
490         if (checkSignalOrder)
491             QVERIFY(hasCurrentChanged >= hasSelectionChanged);
492     }
493 private:
494     int hasCurrentChanged;
495     int hasSelectionChanged;
496
497 };
498
499 class QtTestItemDelegate : public QItemDelegate
500 {
501 public:
502     QSize sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
503     {
504         return hint;
505     }
506
507     QSize hint;
508 };
509
510 tst_QTableView::tst_QTableView()
511 {
512 }
513
514 tst_QTableView::~tst_QTableView()
515 {
516 }
517
518 void tst_QTableView::initTestCase()
519 {
520 #ifdef Q_OS_WINCE //disable magic for WindowsCE
521     qApp->setAutoMaximizeThreshold(-1);
522 #endif
523 }
524
525 void tst_QTableView::cleanupTestCase()
526 {
527 }
528
529 void tst_QTableView::init()
530 {
531 }
532
533 void tst_QTableView::cleanup()
534 {
535 }
536
537 void tst_QTableView::noDelegate()
538 {
539     QtTestTableModel model(3, 3);
540     QTableView view;
541     view.setModel(&model);
542     view.setItemDelegate(0);
543     view.show();
544 }
545
546 void tst_QTableView::noModel()
547 {
548     QTableView view;
549     view.show();
550 }
551
552 void tst_QTableView::emptyModel()
553 {
554     QtTestTableModel model;
555     QTableView view;
556     QSignalSpy spy(&model, SIGNAL(invalidIndexEncountered()));
557     view.setModel(&model);
558     view.show();
559     QCOMPARE(spy.count(), 0);
560 }
561
562 void tst_QTableView::removeRows_data()
563 {
564     QTest::addColumn<int>("rowCount");
565     QTest::addColumn<int>("columnCount");
566
567     QTest::newRow("2x2") << 2 << 2;
568     QTest::newRow("10x10") << 10  << 10;
569 }
570
571 void tst_QTableView::removeRows()
572 {
573     QFETCH(int, rowCount);
574     QFETCH(int, columnCount);
575
576     QtTestTableModel model(rowCount, columnCount);
577     QSignalSpy spy(&model, SIGNAL(invalidIndexEncountered()));
578
579     QTableView view;
580     view.setModel(&model);
581     view.show();
582
583     model.removeLastRow();
584     QCOMPARE(spy.count(), 0);
585
586     model.removeAllRows();
587     QCOMPARE(spy.count(), 0);
588 }
589
590 void tst_QTableView::removeColumns_data()
591 {
592     QTest::addColumn<int>("rowCount");
593     QTest::addColumn<int>("columnCount");
594
595     QTest::newRow("2x2") << 2 << 2;
596     QTest::newRow("10x10") << 10  << 10;
597 }
598
599 void tst_QTableView::removeColumns()
600 {
601     QFETCH(int, rowCount);
602     QFETCH(int, columnCount);
603
604     QtTestTableModel model(rowCount, columnCount);
605     QSignalSpy spy(&model, SIGNAL(invalidIndexEncountered()));
606
607     QTableView view;
608     view.setModel(&model);
609     view.show();
610
611     model.removeLastColumn();
612     QCOMPARE(spy.count(), 0);
613
614     model.removeAllColumns();
615     QCOMPARE(spy.count(), 0);
616 }
617
618 void tst_QTableView::keyboardNavigation_data()
619 {
620     QTest::addColumn<int>("rowCount");
621     QTest::addColumn<int>("columnCount");
622     QTest::addColumn<bool>("tabKeyNavigation");
623     QTest::addColumn<IntList>("keyPresses");
624
625     QTest::newRow("16x16 model") << 16  << 16 << true
626                                  << (IntList()
627                                      << Qt::Key_Up
628                                      << Qt::Key_Up
629                                      << Qt::Key_Right
630                                      << Qt::Key_Right
631                                      << Qt::Key_Up
632                                      << Qt::Key_Left
633                                      << Qt::Key_Left
634                                      << Qt::Key_Up
635                                      << Qt::Key_Down
636                                      << Qt::Key_Up
637                                      << Qt::Key_Up
638                                      << Qt::Key_Up
639                                      << Qt::Key_Up
640                                      << Qt::Key_Up
641                                      << Qt::Key_Up
642                                      << Qt::Key_Left
643                                      << Qt::Key_Left
644                                      << Qt::Key_Up
645                                      << Qt::Key_Down
646                                      << Qt::Key_Down
647                                      << Qt::Key_Tab
648                                      << Qt::Key_Backtab);
649
650
651     QTest::newRow("no tab") << 8  << 8 <<  false
652                                  << (IntList()
653                                      << Qt::Key_Up
654                                      << Qt::Key_Up
655                                      << Qt::Key_Right
656                                      << Qt::Key_Right
657                                      << Qt::Key_Up
658                                      << Qt::Key_Left
659                                      << Qt::Key_Left
660                                      << Qt::Key_Up
661                                      << Qt::Key_Down
662                                      << Qt::Key_Up
663                                      << Qt::Key_Up
664                                      << Qt::Key_Up
665                                      << Qt::Key_Up
666                                      << Qt::Key_Up
667                                      << Qt::Key_Up
668                                      << Qt::Key_Left
669                                      << Qt::Key_Left
670                                      << Qt::Key_Up
671                                      << Qt::Key_Down
672                                      << Qt::Key_Down
673                                      << Qt::Key_Tab
674                                      << Qt::Key_Backtab);
675 }
676
677 void tst_QTableView::keyboardNavigation()
678 {
679     QFETCH(int, rowCount);
680     QFETCH(int, columnCount);
681     QFETCH(bool, tabKeyNavigation);
682     QFETCH(IntList, keyPresses);
683
684     QtTestTableModel model(rowCount, columnCount);
685     QTableView view;
686     view.setModel(&model);
687
688     view.setTabKeyNavigation(tabKeyNavigation);
689     QModelIndex index = model.index(rowCount - 1, columnCount - 1);
690     view.setCurrentIndex(index);
691
692     view.show();
693     qApp->setActiveWindow(&view);
694     QVERIFY(QTest::qWaitForWindowActive(&view));
695
696     int row = rowCount - 1;
697     int column = columnCount - 1;
698     for (int i = 0; i < keyPresses.count(); ++i) {
699
700         Qt::Key key = (Qt::Key)keyPresses.at(i);
701
702         switch (key) {
703         case Qt::Key_Up:
704             row = qMax(0, row - 1);
705             break;
706         case Qt::Key_Down:
707             row = qMin(rowCount - 1, row + 1);
708             break;
709         case Qt::Key_Backtab:
710             if (!tabKeyNavigation)
711                 break;
712         case Qt::Key_Left:
713             column = qMax(0, column - 1);
714             break;
715         case Qt::Key_Tab:
716             if (!tabKeyNavigation)
717                 break;
718         case Qt::Key_Right:
719             column = qMin(columnCount - 1, column + 1);
720             break;
721         default:
722             break;
723         }
724
725         QTest::keyClick(&view, key);
726         QApplication::processEvents();
727
728         QModelIndex index = model.index(row, column);
729         QCOMPARE(view.currentIndex(), index);
730     }
731 }
732
733 void tst_QTableView::headerSections_data()
734 {
735     QTest::addColumn<int>("rowCount");
736     QTest::addColumn<int>("columnCount");
737     QTest::addColumn<int>("row");
738     QTest::addColumn<int>("column");
739     QTest::addColumn<int>("rowHeight");
740     QTest::addColumn<int>("columnWidth");
741
742     QTest::newRow("") << 10 << 10 << 5 << 5 << 30 << 30;
743 }
744
745 void tst_QTableView::headerSections()
746 {
747     QFETCH(int, rowCount);
748     QFETCH(int, columnCount);
749     QFETCH(int, row);
750     QFETCH(int, column);
751     QFETCH(int, rowHeight);
752     QFETCH(int, columnWidth);
753
754     QtTestTableModel model(rowCount, columnCount);
755
756     QTableView view;
757     QHeaderView *hheader = view.horizontalHeader();
758     QHeaderView *vheader = view.verticalHeader();
759
760     view.setModel(&model);
761     view.show();
762
763     hheader->doItemsLayout();
764     vheader->doItemsLayout();
765
766     QCOMPARE(hheader->count(), model.columnCount());
767     QCOMPARE(vheader->count(), model.rowCount());
768
769     view.setRowHeight(row, rowHeight);
770     QCOMPARE(view.rowHeight(row), rowHeight);
771     view.hideRow(row);
772     QCOMPARE(view.rowHeight(row), 0);
773     view.showRow(row);
774     QCOMPARE(view.rowHeight(row), rowHeight);
775
776     view.setColumnWidth(column, columnWidth);
777     QCOMPARE(view.columnWidth(column), columnWidth);
778     view.hideColumn(column);
779     QCOMPARE(view.columnWidth(column), 0);
780     view.showColumn(column);
781     QCOMPARE(view.columnWidth(column), columnWidth);
782 }
783
784 typedef QPair<int,int> IntPair;
785 Q_DECLARE_METATYPE(IntPair)
786
787 void tst_QTableView::moveCursor_data()
788 {
789     QTest::addColumn<int>("rowCount");
790     QTest::addColumn<int>("columnCount");
791     QTest::addColumn<int>("hideRow");
792     QTest::addColumn<int>("hideColumn");
793
794     QTest::addColumn<int>("startRow");
795     QTest::addColumn<int>("startColumn");
796
797     QTest::addColumn<int>("cursorMoveAction");
798     QTest::addColumn<int>("modifier");
799
800     QTest::addColumn<int>("expectedRow");
801     QTest::addColumn<int>("expectedColumn");
802     QTest::addColumn<IntPair>("moveRow");
803     QTest::addColumn<IntPair>("moveColumn");
804
805     // MoveRight
806     QTest::newRow("MoveRight (0,0)")
807         << 4 << 4 << -1 << -1
808         << 0 << 0
809         << int(QtTestTableView::MoveRight) << int(Qt::NoModifier)
810         << 0 << 1 << IntPair(0,0) << IntPair(0,0);
811
812     QTest::newRow("MoveRight (3,0)")
813         << 4 << 4 << -1 << -1
814         << 3 << 0
815         << int(QtTestTableView::MoveRight) << int(Qt::NoModifier)
816         << 3 << 1 << IntPair(0,0) << IntPair(0,0);
817
818     QTest::newRow("MoveRight (3,3)")
819         << 4 << 4 << -1 << -1
820         << 3 << 3
821         << int(QtTestTableView::MoveRight) << int(Qt::NoModifier)
822         << 3 << 3 << IntPair(0,0) << IntPair(0,0); // ###
823
824     QTest::newRow("MoveRight, hidden column 1 (0,0)")
825         << 4 << 4 << -1 << 1
826         << 0 << 0
827         << int(QtTestTableView::MoveRight) << int(Qt::NoModifier)
828         << 0 << 2 << IntPair(0,0) << IntPair(0,0);
829
830     QTest::newRow("MoveRight, hidden column 3 (0,2)")
831         << 4 << 4 << -1 << 3
832         << 0 << 2
833         << int(QtTestTableView::MoveRight) << int(Qt::NoModifier)
834         << 0 << 2 << IntPair(0,0) << IntPair(0,0); // ###
835
836     // MoveNext should in addition wrap
837     QTest::newRow("MoveNext (0,0)")
838         << 4 << 4 << -1 << -1
839         << 0 << 0
840         << int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
841         << 0 << 1 << IntPair(0,0) << IntPair(0,0);
842
843     QTest::newRow("MoveNext (0,2)")
844         << 4 << 4 << -1 << -1
845         << 0 << 2
846         << int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
847         << 0 << 3 << IntPair(0,0) << IntPair(0,0);
848
849     QTest::newRow("MoveNext, wrap (0,3)")
850         << 4 << 4 << -1 << -1
851         << 0 << 3
852         << int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
853         << 1 << 0 << IntPair(0,0) << IntPair(0,0);
854
855     QTest::newRow("MoveNext, wrap (3,3)")
856         << 4 << 4 << -1 << -1
857         << 3 << 3
858         << int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
859         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
860
861     QTest::newRow("MoveNext, hidden column 1 (0,0)")
862         << 4 << 4 << -1 << 1
863         << 0 << 0
864         << int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
865         << 0 << 2 << IntPair(0,0) << IntPair(0,0);
866
867     QTest::newRow("MoveNext, wrap, hidden column 3 (0,2)")
868         << 4 << 4 << -1 << 3
869         << 0 << 2
870         << int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
871         << 1 << 0 << IntPair(0,0) << IntPair(0,0);
872
873     QTest::newRow("MoveNext, wrap, hidden column 3 (3,2)")
874         << 4 << 4 << -1 << 3
875         << 3 << 2
876         << int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
877         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
878
879     QTest::newRow("MoveNext, wrapy, wrapx, hidden column 3, hidden row 3 (2,2)")
880         << 4 << 4 << 3 << 3
881         << 2 << 2
882         << int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
883         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
884
885     QTest::newRow("MoveNext, wrap, hidden column 2, moved column from 3 to 0. (0,2)")
886         << 4 << 4 << -1 << 2
887         << 0 << 2
888         << int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
889         << 1 << 3 << IntPair(0,0) << IntPair(3,0);
890
891     // MoveLeft
892     QTest::newRow("MoveLeft (0,0)")
893         << 4 << 4 << -1 << -1
894         << 0 << 0
895         << int(QtTestTableView::MoveLeft) << int(Qt::NoModifier)
896         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
897
898     QTest::newRow("MoveLeft (0,3)")
899         << 4 << 4 << -1 << -1
900         << 0 << 3
901         << int(QtTestTableView::MoveLeft) << int(Qt::NoModifier)
902         << 0 << 2 << IntPair(0,0) << IntPair(0,0);
903
904     QTest::newRow("MoveLeft (1,0)")
905         << 4 << 4 << -1 << -1
906         << 1 << 0
907         << int(QtTestTableView::MoveLeft) << int(Qt::NoModifier)
908         << 1 << 0 << IntPair(0,0) << IntPair(0,0);
909
910     QTest::newRow("MoveLeft, hidden column 0 (0,2)")
911         << 4 << 4 << -1 << 1
912         << 0 << 2
913         << int(QtTestTableView::MoveLeft) << int(Qt::NoModifier)
914         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
915
916     QTest::newRow("MoveLeft, hidden column 0 (0,1)")
917         << 4 << 4 << -1 << 0
918         << 0 << 1
919         << int(QtTestTableView::MoveLeft) << int(Qt::NoModifier)
920         << 0 << 1 << IntPair(0,0) << IntPair(0,0);
921
922     // MovePrevious should in addition wrap
923     QTest::newRow("MovePrevious (0,3)")
924         << 4 << 4 << -1 << -1
925         << 0 << 3
926         << int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
927         << 0 << 2 << IntPair(0,0) << IntPair(0,0);
928
929     QTest::newRow("MovePrevious (0,1)")
930         << 4 << 4 << -1 << -1
931         << 0 << 1
932         << int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
933         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
934
935     QTest::newRow("MovePrevious, wrap (1,0)")
936         << 4 << 4 << -1 << -1
937         << 1 << 0
938         << int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
939         << 0 << 3 << IntPair(0,0) << IntPair(0,0);
940
941     QTest::newRow("MovePrevious, wrap, (0,0)")
942         << 4 << 4 << -1 << -1
943         << 0 << 0
944         << int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
945         << 3 << 3 << IntPair(0,0) << IntPair(0,0);
946
947     QTest::newRow("MovePrevious, hidden column 1 (0,2)")
948         << 4 << 4 << -1 << 1
949         << 0 << 2
950         << int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
951         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
952
953     QTest::newRow("MovePrevious, wrap, hidden column 3 (0,2)")
954         << 4 << 4 << -1 << 3
955         << 0 << 2
956         << int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
957         << 0 << 1 << IntPair(0,0) << IntPair(0,0);
958
959     QTest::newRow("MovePrevious, wrapy, hidden column 0 (0,1)")
960         << 4 << 4 << -1 << 0
961         << 0 << 1
962         << int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
963         << 3 << 3 << IntPair(0,0) << IntPair(0,0);
964
965     QTest::newRow("MovePrevious, wrap, hidden column 0, hidden row 0 (1,1)")
966         << 4 << 4 << 0 << 0
967         << 1 << 1
968         << int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
969         << 3 << 3 << IntPair(0,0) << IntPair(0,0);
970
971     QTest::newRow("MovePrevious, wrap, hidden column 1, moved column from 0 to 3. (1,2)")
972         << 4 << 4 << -1 << 1
973         << 1 << 2
974         << int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
975         << 0 << 0 << IntPair(0,0) << IntPair(0,3);
976
977     // MoveDown
978     QTest::newRow("MoveDown (0,0)")
979         << 4 << 4 << -1 << -1
980         << 0 << 0
981         << int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
982         << 1 << 0 << IntPair(0,0) << IntPair(0,0);
983
984     QTest::newRow("MoveDown (3,0)")
985         << 4 << 4 << -1 << -1
986         << 3 << 0
987         << int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
988         << 3 << 0 << IntPair(0,0) << IntPair(0,0);
989
990     QTest::newRow("MoveDown (3,3)")
991         << 4 << 4 << -1 << -1
992         << 3 << 3
993         << int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
994         << 3 << 3 << IntPair(0,0) << IntPair(0,0);
995
996     QTest::newRow("MoveDown, hidden row 1 (0,0)")
997         << 4 << 4 << 1 << -1
998         << 0 << 0
999         << int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
1000         << 2 << 0 << IntPair(0,0) << IntPair(0,0);
1001
1002     QTest::newRow("MoveDown, hidden row 3 (2,0)")
1003         << 4 << 4 << 3 << -1
1004         << 2 << 0
1005         << int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
1006         << 2 << 0 << IntPair(0,0) << IntPair(0,0);
1007
1008     QTest::newRow("MoveDown, hidden row 0 hidden column 0 (0,0)")
1009         << 4 << 4 << 0 << 0
1010         << 0 << 0
1011         << int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
1012         << 1 << 1 << IntPair(0,0) << IntPair(0,0);
1013
1014     // MoveUp
1015     QTest::newRow("MoveUp (0,0)")
1016         << 4 << 4 << -1 << -1
1017         << 0 << 0
1018         << int(QtTestTableView::MoveUp) << int(Qt::NoModifier)
1019         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
1020
1021     QTest::newRow("MoveUp (3, 0)")
1022         << 4 << 4 << -1 << -1
1023         << 3 << 0
1024         << int(QtTestTableView::MoveUp) << int(Qt::NoModifier)
1025         << 2 << 0 << IntPair(0,0) << IntPair(0,0);
1026
1027     QTest::newRow("MoveUp (0,1)")
1028         << 4 << 4 << -1 << -1
1029         << 0 << 1
1030         << int(QtTestTableView::MoveUp) << int(Qt::NoModifier)
1031         << 0 << 1 << IntPair(0,0) << IntPair(0,0);
1032
1033     QTest::newRow("MoveUp, hidden row 1 (2,0)")
1034         << 4 << 4 << 1 << -1
1035         << 2 << 0
1036         << int(QtTestTableView::MoveUp) << int(Qt::NoModifier)
1037         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
1038
1039     QTest::newRow("MoveUp, hidden row (1,0)")
1040         << 4 << 4 << 0 << -1
1041         << 1 << 0
1042         << int(QtTestTableView::MoveUp) << int(Qt::NoModifier)
1043         << 1 << 0 << IntPair(0,0) << IntPair(0,0);
1044
1045     // MoveHome
1046     QTest::newRow("MoveHome (0,0)")
1047         << 4 << 4 << -1 << -1
1048         << 0 << 0
1049         << int(QtTestTableView::MoveHome) << int(Qt::NoModifier)
1050         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
1051
1052     QTest::newRow("MoveHome (3,3)")
1053         << 4 << 4 << -1 << -1
1054         << 3 << 3
1055         << int(QtTestTableView::MoveHome) << int(Qt::NoModifier)
1056         << 3 << 0 << IntPair(0,0) << IntPair(0,0);
1057
1058     QTest::newRow("MoveHome, hidden column 0 (3,3)")
1059         << 4 << 4 << -1 << 0
1060         << 3 << 3
1061         << int(QtTestTableView::MoveHome) << int(Qt::NoModifier)
1062         << 3 << 1 << IntPair(0,0) << IntPair(0,0);
1063
1064     // Use Ctrl modifier
1065     QTest::newRow("MoveHome + Ctrl (0,0)")
1066         << 4 << 4 << -1 << -1
1067         << 0 << 0
1068         << int(QtTestTableView::MoveHome) << int(Qt::ControlModifier)
1069         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
1070
1071     QTest::newRow("MoveHome + Ctrl (3,3)")
1072         << 4 << 4 << -1 << -1
1073         << 3 << 3
1074         << int(QtTestTableView::MoveHome) << int(Qt::ControlModifier)
1075         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
1076
1077     QTest::newRow("MoveHome + Ctrl, hidden column 0, hidden row 0 (3,3)")
1078         << 4 << 4 << 0 << 0
1079         << 3 << 3
1080         << int(QtTestTableView::MoveHome) << int(Qt::ControlModifier)
1081         << 1 << 1 << IntPair(0,0) << IntPair(0,0);
1082
1083     // MoveEnd
1084     QTest::newRow("MoveEnd (0,0)")
1085         << 4 << 4 << -1 << -1
1086         << 0 << 0
1087         << int(QtTestTableView::MoveEnd) << int(Qt::NoModifier)
1088         << 0 << 3 << IntPair(0,0) << IntPair(0,0);
1089
1090     QTest::newRow("MoveEnd (3,3)")
1091         << 4 << 4 << -1 << -1
1092         << 3 << 3
1093         << int(QtTestTableView::MoveEnd) << int(Qt::NoModifier)
1094         << 3 << 3 << IntPair(0,0) << IntPair(0,0);
1095
1096     QTest::newRow("MoveEnd, hidden column (0,0)")
1097         << 4 << 4 << -1 << 3
1098         << 0 << 0
1099         << int(QtTestTableView::MoveEnd) << int(Qt::NoModifier)
1100         << 0<< 2 << IntPair(0,0) << IntPair(0,0);
1101
1102     // Use Ctrl modifier
1103     QTest::newRow("MoveEnd + Ctrl (0,0)")
1104         << 4 << 4 << -1 << -1
1105         << 0 << 0
1106         << int(QtTestTableView::MoveEnd) << int(Qt::ControlModifier)
1107         << 3 << 3 << IntPair(0,0) << IntPair(0,0);
1108
1109     QTest::newRow("MoveEnd + Ctrl (3,3)")
1110         << 4 << 4 << -1 << -1
1111         << 3 << 3
1112         << int(QtTestTableView::MoveEnd) << int(Qt::ControlModifier)
1113         << 3 << 3 << IntPair(0,0) << IntPair(0,0);
1114
1115     QTest::newRow("MoveEnd + Ctrl, hidden column 3 (0,0)")
1116         << 4 << 4 << -1 << 3
1117         << 0 << 0
1118         << int(QtTestTableView::MoveEnd) << int(Qt::ControlModifier)
1119         << 3 << 2 << IntPair(0,0) << IntPair(0,0);
1120
1121     QTest::newRow("MoveEnd + Ctrl, hidden column 3, hidden row 3 (0,0)")
1122         << 4 << 4 << 3 << 3
1123         << 0 << 0
1124         << int(QtTestTableView::MoveEnd) << int(Qt::ControlModifier)
1125         << 2 << 2 << IntPair(0,0) << IntPair(0,0);
1126
1127     QTest::newRow("MovePageUp (0,0)")
1128         << 4 << 4 << -1 << -1
1129         << 0 << 0
1130         << int(QtTestTableView::MovePageUp) << 0
1131         << 0 << 0 << IntPair(0,0) << IntPair(0,0);
1132
1133     QTest::newRow("MovePageUp (3,3)")
1134         << 4 << 4 << -1 << -1
1135         << 3 << 3
1136         << int(QtTestTableView::MovePageUp) << 0
1137         << 0 << 3 << IntPair(0,0) << IntPair(0,0);
1138
1139     QTest::newRow("MovePageDown (3, 3)")
1140         << 4 << 4 << -1 << -1
1141         << 3 << 3
1142         << int(QtTestTableView::MovePageDown) << 0
1143         << 3 << 3 << IntPair(0,0) << IntPair(0,0);
1144
1145     QTest::newRow("MovePageDown (0, 3)")
1146         << 4 << 4 << -1 << -1
1147         << 0 << 3
1148         << int(QtTestTableView::MovePageDown) << 0
1149         << 3 << 3 << IntPair(0,0) << IntPair(0,0);
1150 }
1151
1152 void tst_QTableView::moveCursor()
1153 {
1154     QFETCH(int, rowCount);
1155     QFETCH(int, columnCount);
1156     QFETCH(int, hideRow);
1157     QFETCH(int, hideColumn);
1158     QFETCH(int, startRow);
1159     QFETCH(int, startColumn);
1160     QFETCH(int, cursorMoveAction);
1161     QFETCH(int, modifier);
1162     QFETCH(int, expectedRow);
1163     QFETCH(int, expectedColumn);
1164     QFETCH(IntPair, moveRow);
1165     QFETCH(IntPair, moveColumn);
1166
1167     QtTestTableModel model(rowCount, columnCount);
1168     QtTestTableView view;
1169
1170     view.setModel(&model);
1171     view.hideRow(hideRow);
1172     view.hideColumn(hideColumn);
1173     if (moveColumn.first != moveColumn.second)
1174         view.horizontalHeader()->moveSection(moveColumn.first, moveColumn.second);
1175     if (moveRow.first != moveRow.second)
1176         view.verticalHeader()->moveSection(moveRow.first, moveRow.second);
1177
1178     view.show();
1179
1180     QModelIndex index = model.index(startRow, startColumn);
1181     view.setCurrentIndex(index);
1182
1183     QModelIndex newIndex = view.moveCursor((QtTestTableView::CursorAction)cursorMoveAction,
1184                                            (Qt::KeyboardModifiers)modifier);
1185     // expected fails, task 119433
1186     if(newIndex.row() == -1)
1187         return;
1188     QCOMPARE(newIndex.row(), expectedRow);
1189     QCOMPARE(newIndex.column(), expectedColumn);
1190 }
1191
1192 void tst_QTableView::moveCursorStrikesBack_data()
1193 {
1194     QTest::addColumn<int>("hideRow");
1195     QTest::addColumn<int>("hideColumn");
1196     QTest::addColumn<IntList>("disableRows");
1197     QTest::addColumn<IntList>("disableColumns");
1198     QTest::addColumn<QRect>("span");
1199
1200     QTest::addColumn<int>("startRow");
1201     QTest::addColumn<int>("startColumn");
1202     QTest::addColumn<IntList>("cursorMoveActions");
1203     QTest::addColumn<int>("expectedRow");
1204     QTest::addColumn<int>("expectedColumn");
1205
1206     QTest::newRow("Last column disabled. Task QTBUG-3878") << -1 << -1
1207             << IntList()
1208             << (IntList() << 6)
1209             << QRect()
1210             << 0 << 5 << (IntList() << int(QtTestTableView::MoveNext))
1211             << 1 << 0;
1212
1213     QTest::newRow("Last column disabled 2. Task QTBUG-3878") << -1 << -1
1214             << IntList()
1215             << (IntList() << 6)
1216             << QRect()
1217             << 1 << 0 << (IntList() << int(QtTestTableView::MovePrevious))
1218             << 0 << 5;
1219
1220     QTest::newRow("Span, anchor column hidden") << -1 << 1
1221             << IntList()
1222             << IntList()
1223             << QRect(1, 2, 2, 3)
1224             << 2 << 0 << (IntList() << int(QtTestTableView::MoveNext))
1225             << 2 << 2;
1226
1227     QTest::newRow("Span, anchor column disabled") << -1 << -1
1228             << IntList()
1229             << (IntList() << 1)
1230             << QRect(1, 2, 2, 3)
1231             << 2 << 0 << (IntList() << int(QtTestTableView::MoveNext))
1232             << 2 << 2;
1233
1234     QTest::newRow("Span, anchor row hidden") << 2 << -1
1235             << IntList()
1236             << IntList()
1237             << QRect(1, 2, 2, 3)
1238             << 1 << 2 << (IntList() << int(QtTestTableView::MoveDown))
1239             << 3 << 2;
1240
1241     QTest::newRow("Span, anchor row disabled") << -1 << -1
1242             << (IntList() << 2)
1243             << IntList()
1244             << QRect(1, 2, 2, 3)
1245             << 1 << 2 << (IntList() << int(QtTestTableView::MoveDown))
1246             << 3 << 2;
1247
1248     QTest::newRow("Move through span right") << -1 << -1
1249             << IntList()
1250             << IntList()
1251             << QRect(1, 2, 2, 3)
1252             << 3 << 0 << (IntList() << int(QtTestTableView::MoveRight) << int(QtTestTableView::MoveRight))
1253             << 3 << 3;
1254
1255     QTest::newRow("Move through span left") << -1 << -1
1256             << IntList()
1257             << IntList()
1258             << QRect(1, 2, 2, 3)
1259             << 3 << 3 << (IntList() << int(QtTestTableView::MoveLeft) << int(QtTestTableView::MoveLeft))
1260             << 3 << 0;
1261
1262     QTest::newRow("Move through span down") << -1 << -1
1263             << IntList()
1264             << IntList()
1265             << QRect(1, 2, 2, 3)
1266             << 1 << 2 << (IntList() << int(QtTestTableView::MoveDown) << int(QtTestTableView::MoveDown))
1267             << 5 << 2;
1268
1269     QTest::newRow("Move through span up") << -1 << -1
1270             << IntList()
1271             << IntList()
1272             << QRect(1, 2, 2, 3)
1273             << 5 << 2 << (IntList() << int(QtTestTableView::MoveUp) << int(QtTestTableView::MoveUp))
1274             << 1 << 2;
1275
1276     IntList fullList;
1277     for (int i = 0; i < 7; ++i)
1278         fullList << i;
1279
1280     QTest::newRow("All disabled, wrap forward. Timeout => FAIL") << -1 << -1
1281             << fullList
1282             << fullList
1283             << QRect()
1284             << 1 << 0 << (IntList() << int(QtTestTableView::MoveNext))
1285             << 1 << 0;
1286
1287     QTest::newRow("All disabled, wrap backwards. Timeout => FAIL") << -1 << -1
1288             << fullList
1289             << fullList
1290             << QRect()
1291             << 1 << 0 << (IntList() << int(QtTestTableView::MovePrevious))
1292             << 1 << 0;
1293 }
1294
1295 void tst_QTableView::moveCursorStrikesBack()
1296 {
1297     QFETCH(int, hideRow);
1298     QFETCH(int, hideColumn);
1299     QFETCH(IntList, disableRows);
1300     QFETCH(IntList, disableColumns);
1301     QFETCH(QRect, span);
1302
1303     QFETCH(int, startRow);
1304     QFETCH(int, startColumn);
1305     QFETCH(IntList, cursorMoveActions);
1306     QFETCH(int, expectedRow);
1307     QFETCH(int, expectedColumn);
1308
1309     QtTestTableModel model(7, 7);
1310     QtTestTableView view;
1311     view.setModel(&model);
1312     view.hideRow(hideRow);
1313     view.hideColumn(hideColumn);
1314
1315     if (span.height() && span.width())
1316         view.setSpan(span.top(), span.left(), span.height(), span.width());
1317     view.show();
1318
1319     QModelIndex index = model.index(startRow, startColumn);
1320     view.setCurrentIndex(index);
1321
1322     foreach (int row, disableRows)
1323         model.disableRow(row);
1324     foreach (int column, disableColumns)
1325         model.disableColumn(column);
1326
1327     int newRow = -1;
1328     int newColumn = -1;
1329     foreach (int cursorMoveAction, cursorMoveActions) {
1330         QModelIndex newIndex = view.moveCursor((QtTestTableView::CursorAction)cursorMoveAction, 0);
1331         view.setCurrentIndex(newIndex);
1332         newRow = newIndex.row();
1333         newColumn = newIndex.column();
1334     }
1335
1336     // expected fails, task 119433
1337     if(newRow == -1)
1338         return;
1339     QCOMPARE(newRow, expectedRow);
1340     QCOMPARE(newColumn, expectedColumn);
1341 }
1342
1343 void tst_QTableView::hideRows_data()
1344 {
1345     QTest::addColumn<int>("rowCount");
1346     QTest::addColumn<int>("columnCount");
1347     QTest::addColumn<int>("showRow"); // hide, then show
1348     QTest::addColumn<int>("hideRow"); // hide only
1349     QTest::addColumn<int>("row");
1350     QTest::addColumn<int>("column");
1351     QTest::addColumn<int>("rowSpan");
1352     QTest::addColumn<int>("columnSpan");
1353
1354     QTest::newRow("show row 0, hide row 3, no span")
1355       << 10 << 10
1356       << 0
1357       << 3
1358       << -1 << -1
1359       << 1 << 1;
1360
1361     QTest::newRow("show row 0, hide row 3, span")
1362       << 10 << 10
1363       << 0
1364       << 3
1365       << 0 << 0
1366       << 3 << 2;
1367 }
1368
1369 void tst_QTableView::hideRows()
1370 {
1371     QFETCH(int, rowCount);
1372     QFETCH(int, columnCount);
1373     QFETCH(int, showRow);
1374     QFETCH(int, hideRow);
1375     QFETCH(int, row);
1376     QFETCH(int, column);
1377     QFETCH(int, rowSpan);
1378     QFETCH(int, columnSpan);
1379
1380     QtTestTableModel model(rowCount, columnCount);
1381     QTableView view;
1382
1383     view.setModel(&model);
1384     view.setSpan(row, column, rowSpan, columnSpan);
1385
1386     view.hideRow(showRow);
1387     QVERIFY(view.isRowHidden(showRow));
1388
1389     view.hideRow(hideRow);
1390     QVERIFY(view.isRowHidden(hideRow));
1391
1392     view.showRow(showRow);
1393     QVERIFY(!view.isRowHidden(showRow));
1394     QVERIFY(view.isRowHidden(hideRow));
1395 }
1396
1397 void tst_QTableView::hideColumns_data()
1398 {
1399     QTest::addColumn<int>("rowCount");
1400     QTest::addColumn<int>("columnCount");
1401     QTest::addColumn<int>("showColumn"); // hide, then show
1402     QTest::addColumn<int>("hideColumn"); // hide only
1403     QTest::addColumn<int>("row");
1404     QTest::addColumn<int>("column");
1405     QTest::addColumn<int>("rowSpan");
1406     QTest::addColumn<int>("columnSpan");
1407
1408     QTest::newRow("show col 0, hide col 3, no span")
1409       << 10 << 10
1410       << 0
1411       << 3
1412       << -1 << -1
1413       << 1 << 1;
1414
1415     QTest::newRow("show col 0, hide col 3, span")
1416       << 10 << 10
1417       << 0
1418       << 3
1419       << 0 << 0
1420       << 3 << 2;
1421 }
1422
1423 void tst_QTableView::hideColumns()
1424 {
1425     QFETCH(int, rowCount);
1426     QFETCH(int, columnCount);
1427     QFETCH(int, showColumn);
1428     QFETCH(int, hideColumn);
1429     QFETCH(int, row);
1430     QFETCH(int, column);
1431     QFETCH(int, rowSpan);
1432     QFETCH(int, columnSpan);
1433
1434     QtTestTableModel model(rowCount, columnCount);
1435
1436     QTableView view;
1437     view.setModel(&model);
1438     view.setSpan(row, column, rowSpan, columnSpan);
1439
1440     view.hideColumn(showColumn);
1441     QVERIFY(view.isColumnHidden(showColumn));
1442
1443     view.hideColumn(hideColumn);
1444     QVERIFY(view.isColumnHidden(hideColumn));
1445
1446     view.showColumn(showColumn);
1447     QVERIFY(!view.isColumnHidden(showColumn));
1448     QVERIFY(view.isColumnHidden(hideColumn));
1449 }
1450
1451 void tst_QTableView::selection_data()
1452 {
1453     QTest::addColumn<int>("rowCount");
1454     QTest::addColumn<int>("columnCount");
1455     QTest::addColumn<int>("row");
1456     QTest::addColumn<int>("column");
1457     QTest::addColumn<int>("rowSpan");
1458     QTest::addColumn<int>("columnSpan");
1459     QTest::addColumn<int>("hideRow");
1460     QTest::addColumn<int>("hideColumn");
1461     QTest::addColumn<int>("moveRowFrom");
1462     QTest::addColumn<int>("moveRowTo");
1463     QTest::addColumn<int>("moveColumnFrom");
1464     QTest::addColumn<int>("moveColumnTo");
1465     QTest::addColumn<int>("rowHeight");
1466     QTest::addColumn<int>("columnWidth");
1467     QTest::addColumn<int>("x");
1468     QTest::addColumn<int>("y");
1469     QTest::addColumn<int>("width");
1470     QTest::addColumn<int>("height");
1471     QTest::addColumn<int>("command");
1472     QTest::addColumn<int>("selectedCount"); // ### make this more detailed
1473
1474     QTest::newRow("no span, no hidden, no moved, 3x3 select")
1475       << 10 << 10                          // dim
1476       << -1 << -1                          // pos
1477       << 1 << 1                            // span
1478       << -1 << -1                          // hide
1479       << -1 << -1                          // move row
1480       << -1 << -1                          // move col
1481       << 40 << 40                          // cell size
1482       << 20 << 20 << 80 << 80              // rect
1483       << int(QItemSelectionModel::Select)  // command
1484       << 9;                                // selected count
1485
1486     QTest::newRow("row span, no hidden, no moved, 3x3 select")
1487       << 10 << 10                          // dim
1488       << 1 << 1                            // pos
1489       << 2 << 1                            // span
1490       << -1 << -1                          // hide
1491       << -1 << -1                          // move row
1492       << -1 << -1                          // move col
1493       << 40 << 40                          // cell size
1494       << 20 << 20 << 80 << 80              // rect
1495       << int(QItemSelectionModel::Select)  // command
1496       << 8;                                // selected count
1497
1498     QTest::newRow("col span, no hidden, no moved, 3x3 select")
1499       << 10 << 10                          // dim
1500       << 1 << 1                            // pos
1501       << 1 << 2                            // span
1502       << -1 << -1                          // hide
1503       << -1 << -1                          // move row
1504       << -1 << -1                          // move col
1505       << 40 << 40                          // cell size
1506       << 20 << 20 << 80 << 80              // rect
1507       << int(QItemSelectionModel::Select)  // command
1508       << 8;                                // selected count
1509
1510     QTest::newRow("no span, row hidden, no moved, 3x3 select")
1511       << 10 << 10                          // dim
1512       << -1 << -1                          // pos
1513       << 1 << 1                            // span
1514       << 1 << -1                           // hide
1515       << -1 << -1                          // move row
1516       << -1 << -1                          // move col
1517       << 40 << 40                          // cell size
1518       << 20 << 20 << 80 << 80              // rect
1519       << int(QItemSelectionModel::Select)  // command
1520       << 9;                                // selected count
1521
1522     QTest::newRow("no span, col hidden, no moved, 3x3 select")
1523       << 10 << 10                          // dim
1524       << -1 << -1                          // pos
1525       << 1 << 1                            // span
1526       << -1 << 1                           // hide
1527       << -1 << -1                          // move row
1528       << -1 << -1                          // move col
1529       << 40 << 40                          // cell size
1530       << 20 << 20 << 80 << 80              // rect
1531       << int(QItemSelectionModel::Select)  // command
1532       << 9;                                // selected count
1533
1534     QTest::newRow("no span, no hidden, row moved, 3x3 select")
1535       << 10 << 10                          // dim
1536       << -1 << -1                          // pos
1537       << 1 << 1                            // span
1538       << -1 << -1                          // hide
1539       << 1 << 3                            // move row
1540       << -1 << -1                          // move col
1541       << 40 << 40                          // cell size
1542       << 20 << 20 << 80 << 80              // rect
1543       << int(QItemSelectionModel::Select)  // command
1544       << 9;                                // selected count
1545
1546     QTest::newRow("no span, no hidden, col moved, 3x3 select")
1547       << 10 << 10                          // dim
1548       << -1 << -1                          // pos
1549       << 1 << 1                            // span
1550       << -1 << -1                          // hide
1551       << -1 << -1                          // move row
1552       << 1 << 3                            // move col
1553       << 40 << 40                          // cell size
1554       << 20 << 20 << 80 << 80              // rect
1555       << int(QItemSelectionModel::Select)  // command
1556       << 9;                                // selected count
1557 }
1558
1559 void tst_QTableView::selection()
1560 {
1561     QFETCH(int, rowCount);
1562     QFETCH(int, columnCount);
1563     QFETCH(int, row);
1564     QFETCH(int, column);
1565     QFETCH(int, rowSpan);
1566     QFETCH(int, columnSpan);
1567     QFETCH(int, hideRow);
1568     QFETCH(int, hideColumn);
1569     QFETCH(int, moveRowFrom);
1570     QFETCH(int, moveRowTo);
1571     QFETCH(int, moveColumnFrom);
1572     QFETCH(int, moveColumnTo);
1573     QFETCH(int, rowHeight);
1574     QFETCH(int, columnWidth);
1575     QFETCH(int, x);
1576     QFETCH(int, y);
1577     QFETCH(int, width);
1578     QFETCH(int, height);
1579     QFETCH(int, command);
1580     QFETCH(int, selectedCount);
1581
1582     QtTestTableModel model(rowCount, columnCount);
1583
1584     QtTestTableView view;
1585     view.show();
1586     view.setModel(&model);
1587
1588     view.setSpan(row, column, rowSpan, columnSpan);
1589
1590     view.hideRow(hideRow);
1591     view.hideColumn(hideColumn);
1592
1593     view.verticalHeader()->moveSection(moveRowFrom, moveRowTo);
1594     view.horizontalHeader()->moveSection(moveColumnFrom, moveColumnTo);
1595
1596     for (int r = 0; r < rowCount; ++r)
1597         view.setRowHeight(r, rowHeight);
1598     for (int c = 0; c < columnCount; ++c)
1599         view.setColumnWidth(c, columnWidth);
1600
1601     view.setSelection(QRect(x, y, width, height),
1602                       QItemSelectionModel::SelectionFlags(command));
1603
1604     QCOMPARE(view.selectedIndexes().count(), selectedCount);
1605 }
1606
1607 void tst_QTableView::selectRow_data()
1608 {
1609     QTest::addColumn<int>("rowCount");
1610     QTest::addColumn<int>("columnCount");
1611     QTest::addColumn<int>("row");
1612     QTest::addColumn<int>("mode");
1613     QTest::addColumn<int>("behavior");
1614     QTest::addColumn<int>("selectedItems");
1615
1616     QTest::newRow("SingleSelection and SelectItems")
1617         << 10 << 10
1618         << 0
1619         << (int)QAbstractItemView::SingleSelection
1620         << (int)QAbstractItemView::SelectItems
1621         << 0;
1622
1623     QTest::newRow("SingleSelection and SelectRows")
1624         << 10 << 10
1625         << 0
1626         << (int)QAbstractItemView::SingleSelection
1627         << (int)QAbstractItemView::SelectRows
1628         << 10;
1629
1630     QTest::newRow("SingleSelection and SelectColumns")
1631         << 10 << 10
1632         << 0
1633         << (int)QAbstractItemView::SingleSelection
1634         << (int)QAbstractItemView::SelectColumns
1635         << 0;
1636
1637     QTest::newRow("MultiSelection and SelectItems")
1638         << 10 << 10
1639         << 0
1640         << (int)QAbstractItemView::MultiSelection
1641         << (int)QAbstractItemView::SelectItems
1642         << 10;
1643
1644     QTest::newRow("MultiSelection and SelectRows")
1645         << 10 << 10
1646         << 0
1647         << (int)QAbstractItemView::MultiSelection
1648         << (int)QAbstractItemView::SelectRows
1649         << 10;
1650
1651     QTest::newRow("MultiSelection and SelectColumns")
1652         << 10 << 10
1653         << 0
1654         << (int)QAbstractItemView::MultiSelection
1655         << (int)QAbstractItemView::SelectColumns
1656         << 0;
1657
1658     QTest::newRow("ExtendedSelection and SelectItems")
1659         << 10 << 10
1660         << 0
1661         << (int)QAbstractItemView::ExtendedSelection
1662         << (int)QAbstractItemView::SelectItems
1663         << 10;
1664
1665     QTest::newRow("ExtendedSelection and SelectRows")
1666         << 10 << 10
1667         << 0
1668         << (int)QAbstractItemView::ExtendedSelection
1669         << (int)QAbstractItemView::SelectRows
1670         << 10;
1671
1672     QTest::newRow("ExtendedSelection and SelectColumns")
1673         << 10 << 10
1674         << 0
1675         << (int)QAbstractItemView::ExtendedSelection
1676         << (int)QAbstractItemView::SelectColumns
1677         << 0;
1678
1679     QTest::newRow("ContiguousSelection and SelectItems")
1680         << 10 << 10
1681         << 0
1682         << (int)QAbstractItemView::ContiguousSelection
1683         << (int)QAbstractItemView::SelectItems
1684         << 10;
1685
1686     QTest::newRow("ContiguousSelection and SelectRows")
1687         << 10 << 10
1688         << 0
1689         << (int)QAbstractItemView::ContiguousSelection
1690         << (int)QAbstractItemView::SelectRows
1691         << 10;
1692
1693     QTest::newRow("ContiguousSelection and SelectColumns")
1694         << 10 << 10
1695         << 0
1696         << (int)QAbstractItemView::ContiguousSelection
1697         << (int)QAbstractItemView::SelectColumns
1698         << 0;
1699 }
1700
1701 void tst_QTableView::selectRow()
1702 {
1703     QFETCH(int, rowCount);
1704     QFETCH(int, columnCount);
1705     QFETCH(int, row);
1706     QFETCH(int, mode);
1707     QFETCH(int, behavior);
1708     QFETCH(int, selectedItems);
1709
1710     QtTestTableModel model(rowCount, columnCount);
1711     QTableView view;
1712
1713     view.setModel(&model);
1714     view.setSelectionMode((QAbstractItemView::SelectionMode)mode);
1715     view.setSelectionBehavior((QAbstractItemView::SelectionBehavior)behavior);
1716
1717     QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0);
1718
1719     view.selectRow(row);
1720
1721     //test we have 10 items selected
1722     QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedItems);
1723     //test that all 10 items are in the same row
1724     for (int i = 0; selectedItems > 0 && i < rowCount; ++i)
1725         QCOMPARE(view.selectionModel()->selectedIndexes().at(i).row(), row);
1726 }
1727
1728 void tst_QTableView::selectColumn_data()
1729 {
1730     QTest::addColumn<int>("rowCount");
1731     QTest::addColumn<int>("columnCount");
1732     QTest::addColumn<int>("column");
1733     QTest::addColumn<int>("mode");
1734     QTest::addColumn<int>("behavior");
1735     QTest::addColumn<int>("selectedItems");
1736
1737         QTest::newRow("SingleSelection and SelectItems")
1738             << 10 << 10
1739             << 0
1740             << (int)QAbstractItemView::SingleSelection
1741             << (int)QAbstractItemView::SelectItems
1742             << 0;
1743
1744         QTest::newRow("SingleSelection and SelectRows")
1745             << 10 << 10
1746             << 0
1747             << (int)QAbstractItemView::SingleSelection
1748             << (int)QAbstractItemView::SelectRows
1749             << 0;
1750
1751         QTest::newRow("SingleSelection and SelectColumns")
1752             << 10 << 10
1753             << 0
1754             << (int)QAbstractItemView::SingleSelection
1755             << (int)QAbstractItemView::SelectColumns
1756             << 10;
1757
1758         QTest::newRow("MultiSelection and SelectItems")
1759             << 10 << 10
1760             << 0
1761             << (int)QAbstractItemView::MultiSelection
1762             << (int)QAbstractItemView::SelectItems
1763             << 10;
1764
1765         QTest::newRow("MultiSelection and SelectRows")
1766             << 10 << 10
1767             << 0
1768             << (int)QAbstractItemView::MultiSelection
1769             << (int)QAbstractItemView::SelectRows
1770             << 0;
1771
1772         QTest::newRow("MultiSelection and SelectColumns")
1773             << 10 << 10
1774             << 0
1775             << (int)QAbstractItemView::MultiSelection
1776             << (int)QAbstractItemView::SelectColumns
1777             << 10;
1778
1779         QTest::newRow("ExtendedSelection and SelectItems")
1780             << 10 << 10
1781             << 0
1782             << (int)QAbstractItemView::ExtendedSelection
1783             << (int)QAbstractItemView::SelectItems
1784             << 10;
1785
1786         QTest::newRow("ExtendedSelection and SelectRows")
1787             << 10 << 10
1788             << 0
1789             << (int)QAbstractItemView::ExtendedSelection
1790             << (int)QAbstractItemView::SelectRows
1791             << 0;
1792
1793         QTest::newRow("ExtendedSelection and SelectColumns")
1794             << 10 << 10
1795             << 0
1796             << (int)QAbstractItemView::ExtendedSelection
1797             << (int)QAbstractItemView::SelectColumns
1798             << 10;
1799
1800         QTest::newRow("ContiguousSelection and SelectItems")
1801             << 10 << 10
1802             << 0
1803             << (int)QAbstractItemView::ContiguousSelection
1804             << (int)QAbstractItemView::SelectItems
1805             << 10;
1806
1807         QTest::newRow("ContiguousSelection and SelectRows")
1808             << 10 << 10
1809             << 0
1810             << (int)QAbstractItemView::ContiguousSelection
1811             << (int)QAbstractItemView::SelectRows
1812             << 0;
1813
1814         QTest::newRow("ContiguousSelection and SelectColumns")
1815             << 10 << 10
1816             << 0
1817             << (int)QAbstractItemView::ContiguousSelection
1818             << (int)QAbstractItemView::SelectColumns
1819             << 10;
1820 }
1821
1822 void tst_QTableView::selectColumn()
1823 {
1824     QFETCH(int, rowCount);
1825     QFETCH(int, columnCount);
1826     QFETCH(int, column);
1827     QFETCH(int, mode);
1828     QFETCH(int, behavior);
1829     QFETCH(int, selectedItems);
1830
1831     QtTestTableModel model(rowCount, columnCount);
1832
1833     QTableView view;
1834     view.setModel(&model);
1835     view.setSelectionMode((QAbstractItemView::SelectionMode)mode);
1836     view.setSelectionBehavior((QAbstractItemView::SelectionBehavior)behavior);
1837
1838     QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0);
1839
1840     view.selectColumn(column);
1841
1842     QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedItems);
1843     for (int i = 0; selectedItems > 0 && i < columnCount; ++i)
1844         QCOMPARE(view.selectionModel()->selectedIndexes().at(i).column(), column);
1845 }
1846
1847 Q_DECLARE_METATYPE(QRect)
1848 void tst_QTableView::visualRect_data()
1849 {
1850     QTest::addColumn<int>("rowCount");
1851     QTest::addColumn<int>("columnCount");
1852     QTest::addColumn<int>("hideRow");
1853     QTest::addColumn<int>("hideColumn");
1854     QTest::addColumn<int>("row");
1855     QTest::addColumn<int>("column");
1856     QTest::addColumn<int>("rowHeight");
1857     QTest::addColumn<int>("columnWidth");
1858     QTest::addColumn<QRect>("expectedRect");
1859
1860     QTest::newRow("(0,0)")
1861         << 10 << 10
1862         << -1 << -1
1863         << 0 << 0
1864         << 20 << 30
1865         << QRect(0, 0, 29, 19);
1866
1867     QTest::newRow("(0,0) hidden row")
1868         << 10 << 10
1869         << 0 << -1
1870         << 0 << 0
1871         << 20 << 30
1872         << QRect();
1873
1874     QTest::newRow("(0,0) hidden column")
1875         << 10 << 10
1876         << -1 << 0
1877         << 0 << 0
1878         << 20 << 30
1879         << QRect();
1880
1881     QTest::newRow("(0,0) hidden row and column")
1882         << 10 << 10
1883         << 0 << 0
1884         << 0 << 0
1885         << 20 << 30
1886         << QRect();
1887
1888     QTest::newRow("(0,0) out of bounds")
1889         << 10 << 10
1890         << -1 << -1
1891         << 20 << 20
1892         << 20 << 30
1893         << QRect();
1894
1895     QTest::newRow("(5,5), hidden row")
1896         << 10 << 10
1897         << 5 << -1
1898         << 5 << 5
1899         << 20 << 30
1900         << QRect();
1901
1902     QTest::newRow("(9,9)")
1903         << 10 << 10
1904         << -1 << -1
1905         << 9 << 9
1906         << 20 << 30
1907         << QRect(30*9, 20*9, 29, 19);
1908 }
1909
1910 void tst_QTableView::visualRect()
1911 {
1912     QFETCH(int, rowCount);
1913     QFETCH(int, columnCount);
1914     QFETCH(int, hideRow);
1915     QFETCH(int, hideColumn);
1916     QFETCH(int, row);
1917     QFETCH(int, column);
1918     QFETCH(int, rowHeight);
1919     QFETCH(int, columnWidth);
1920     QFETCH(QRect, expectedRect);
1921
1922     QtTestTableModel model(rowCount, columnCount);
1923
1924     QTableView view;
1925     view.setModel(&model);
1926     // Make sure that it has 1 pixel between each cell.
1927     view.setGridStyle(Qt::SolidLine);
1928     for (int i = 0; i < view.verticalHeader()->count(); ++i)
1929         view.verticalHeader()->resizeSection(i, rowHeight);
1930     for (int i = 0; i < view.horizontalHeader()->count(); ++i)
1931         view.horizontalHeader()->resizeSection(i, columnWidth);
1932
1933     view.hideRow(hideRow);
1934     view.hideColumn(hideColumn);
1935
1936     QRect rect = view.visualRect(model.index(row, column));
1937     QCOMPARE(rect, expectedRect);
1938 }
1939
1940 void tst_QTableView::fetchMore()
1941 {
1942     QtTestTableModel model(64, 64);
1943
1944     model.can_fetch_more = true;
1945
1946     QTableView view;
1947     view.setModel(&model);
1948     view.show();
1949
1950     QCOMPARE(model.fetch_more_count, 0);
1951     view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum());
1952     QVERIFY(model.fetch_more_count > 0);
1953
1954     model.fetch_more_count = 0; //reset
1955     view.scrollToTop();
1956     QCOMPARE(model.fetch_more_count, 0);
1957
1958     view.scrollToBottom();
1959     QVERIFY(model.fetch_more_count > 0);
1960
1961     model.fetch_more_count = 0; //reset
1962     view.scrollToTop();
1963     view.setCurrentIndex(model.index(0, 0));
1964     QCOMPARE(model.fetch_more_count, 0);
1965
1966     for (int i = 0; i < 64; ++i)
1967         QTest::keyClick(&view, Qt::Key_Down);
1968     QCOMPARE(view.currentIndex(), model.index(63, 0));
1969     QVERIFY(model.fetch_more_count > 0);
1970 }
1971
1972 void tst_QTableView::setHeaders()
1973 {
1974     QTableView view;
1975
1976     // Make sure we don't delete ourselves
1977     view.setVerticalHeader(view.verticalHeader());
1978     view.verticalHeader()->count();
1979     view.setHorizontalHeader(view.horizontalHeader());
1980     view.horizontalHeader()->count();
1981
1982     // Try passing around a header without it being deleted
1983     QTableView view2;
1984     view2.setVerticalHeader(view.verticalHeader());
1985     view2.setHorizontalHeader(view.horizontalHeader());
1986     view.setHorizontalHeader(new QHeaderView(Qt::Horizontal));
1987     view.setVerticalHeader(new QHeaderView(Qt::Vertical));
1988     view2.verticalHeader()->count();
1989     view2.horizontalHeader()->count();
1990
1991 }
1992
1993 void tst_QTableView::resizeRowsToContents_data()
1994 {
1995     QTest::addColumn<int>("rowCount");
1996     QTest::addColumn<int>("columnCount");
1997     QTest::addColumn<bool>("showGrid");
1998     QTest::addColumn<int>("cellWidth");
1999     QTest::addColumn<int>("cellHeight");
2000     QTest::addColumn<int>("rowHeight");
2001     QTest::addColumn<int>("columnWidth");
2002
2003     QTest::newRow("10x10 grid shown 40x40")
2004         << 10 << 10 << false << 40 << 40 << 40 << 40;
2005
2006     QTest::newRow("10x10 grid not shown 40x40")
2007         << 10 << 10 << true << 40 << 40 << 41 << 41;
2008 }
2009
2010 void tst_QTableView::resizeRowsToContents()
2011 {
2012     QFETCH(int, rowCount);
2013     QFETCH(int, columnCount);
2014     QFETCH(bool, showGrid);
2015     QFETCH(int, cellWidth);
2016     QFETCH(int, cellHeight);
2017     QFETCH(int, rowHeight);
2018     QFETCH(int, columnWidth);
2019     Q_UNUSED(columnWidth);
2020
2021     QtTestTableModel model(rowCount, columnCount);
2022     QtTestTableView view;
2023     QtTestItemDelegate delegate;
2024
2025     view.setModel(&model);
2026     view.setItemDelegate(&delegate);
2027     view.setShowGrid(showGrid); // the grid will add to the row height
2028
2029     delegate.hint = QSize(cellWidth, cellHeight);
2030
2031     QSignalSpy resizedSpy(view.verticalHeader(), SIGNAL(sectionResized(int, int, int)));
2032     view.resizeRowsToContents();
2033
2034     QCOMPARE(resizedSpy.count(), model.rowCount());
2035     for (int r = 0; r < model.rowCount(); ++r) {
2036         QCOMPARE(view.rowHeight(r), rowHeight);
2037     }
2038 }
2039
2040 void tst_QTableView::resizeColumnsToContents_data()
2041 {
2042     QTest::addColumn<int>("rowCount");
2043     QTest::addColumn<int>("columnCount");
2044     QTest::addColumn<bool>("showGrid");
2045     QTest::addColumn<int>("cellWidth");
2046     QTest::addColumn<int>("cellHeight");
2047     QTest::addColumn<int>("rowHeight");
2048     QTest::addColumn<int>("columnWidth");
2049
2050     QTest::newRow("10x10 grid shown 40x40")
2051         << 10 << 10 << false << 40 << 40 << 40 << 40;
2052
2053     QTest::newRow("10x10 grid not shown 40x40")
2054         << 10 << 10 << true << 40 << 40 << 41 << 41;
2055 }
2056
2057 void tst_QTableView::resizeColumnsToContents()
2058 {
2059     QFETCH(int, rowCount);
2060     QFETCH(int, columnCount);
2061     QFETCH(bool, showGrid);
2062     QFETCH(int, cellWidth);
2063     QFETCH(int, cellHeight);
2064     QFETCH(int, rowHeight);
2065     QFETCH(int, columnWidth);
2066     Q_UNUSED(rowHeight);
2067
2068     QtTestTableModel model(rowCount, columnCount);
2069     QtTestTableView view;
2070     QtTestItemDelegate delegate;
2071
2072     view.setModel(&model);
2073     view.setItemDelegate(&delegate);
2074     view.setShowGrid(showGrid); // the grid will add to the row height
2075
2076     delegate.hint = QSize(cellWidth, cellHeight);
2077
2078     QSignalSpy resizedSpy(view.horizontalHeader(), SIGNAL(sectionResized(int, int, int)));
2079     view.resizeColumnsToContents();
2080
2081     QCOMPARE(resizedSpy.count(), model.columnCount());
2082     for (int c = 0; c < model.columnCount(); ++c)
2083         QCOMPARE(view.columnWidth(c), columnWidth);
2084 }
2085
2086 void tst_QTableView::rowViewportPosition_data()
2087 {
2088     QTest::addColumn<int>("rowCount");
2089     QTest::addColumn<int>("rowHeight");
2090     QTest::addColumn<int>("row");
2091     QTest::addColumn<int>("verticalScrollMode");
2092     QTest::addColumn<int>("verticalScrollValue");
2093     QTest::addColumn<int>("rowViewportPosition");
2094
2095     QTest::newRow("row 0, scroll per item 0")
2096         << 10 << 40 << 0 << int(QAbstractItemView::ScrollPerItem) << 0 << 0;
2097
2098     QTest::newRow("row 1, scroll per item, 0")
2099         << 10 << 40 << 1 << int(QAbstractItemView::ScrollPerItem) << 0 << 1 * 40;
2100
2101     QTest::newRow("row 1, scroll per item, 1")
2102         << 10 << 40 << 1 << int(QAbstractItemView::ScrollPerItem) << 1 << 0;
2103
2104     QTest::newRow("row 5, scroll per item, 0")
2105         << 10 << 40 << 5 << int(QAbstractItemView::ScrollPerItem) << 0 << 5 * 40;
2106
2107     QTest::newRow("row 5, scroll per item, 5")
2108         << 10 << 40 << 5 << int(QAbstractItemView::ScrollPerItem) << 5 << 0;
2109
2110     QTest::newRow("row 9, scroll per item, 0")
2111         << 10 << 40 << 9 << int(QAbstractItemView::ScrollPerItem) << 0 << 9 * 40;
2112
2113     QTest::newRow("row 9, scroll per item, 5")
2114         << 10 << 40 << 9 << int(QAbstractItemView::ScrollPerItem) << 5 << 4 * 40;
2115
2116     QTest::newRow("row 0, scroll per pixel 0")
2117         << 10 << 40 << 0 << int(QAbstractItemView::ScrollPerPixel) << 0 << 0;
2118
2119     QTest::newRow("row 1, scroll per pixel, 0")
2120         << 10 << 40 << 1 << int(QAbstractItemView::ScrollPerPixel) << 0 << 1 * 40;
2121
2122     QTest::newRow("row 1, scroll per pixel, 1")
2123         << 10 << 40 << 1 << int(QAbstractItemView::ScrollPerPixel) << 1 * 40 << 0;
2124
2125     QTest::newRow("row 5, scroll per pixel, 0")
2126         << 10 << 40 << 5 << int(QAbstractItemView::ScrollPerPixel) << 0 << 5 * 40;
2127
2128     QTest::newRow("row 5, scroll per pixel, 5")
2129         << 10 << 40 << 5 << int(QAbstractItemView::ScrollPerPixel) << 5 * 40 << 0;
2130
2131     QTest::newRow("row 9, scroll per pixel, 0")
2132         << 10 << 40 << 9 << int(QAbstractItemView::ScrollPerPixel) << 0 << 9 * 40;
2133
2134     QTest::newRow("row 9, scroll per pixel, 5")
2135         << 10 << 40 << 9 << int(QAbstractItemView::ScrollPerPixel) << 5 * 40 << 4 * 40;
2136 }
2137
2138 void tst_QTableView::rowViewportPosition()
2139 {
2140     QFETCH(int, rowCount);
2141     QFETCH(int, rowHeight);
2142     QFETCH(int, row);
2143     QFETCH(int, verticalScrollMode);
2144     QFETCH(int, verticalScrollValue);
2145     QFETCH(int, rowViewportPosition);
2146
2147     QtTestTableModel model(rowCount, 1);
2148     QtTestTableView view;
2149     view.resize(100, 2 * rowHeight);
2150     view.show();
2151
2152     view.setModel(&model);
2153     for (int r = 0; r < rowCount; ++r)
2154         view.setRowHeight(r, rowHeight);
2155
2156     view.setVerticalScrollMode((QAbstractItemView::ScrollMode)verticalScrollMode);
2157     view.verticalScrollBar()->setValue(verticalScrollValue);
2158
2159     QCOMPARE(view.rowViewportPosition(row), rowViewportPosition);
2160 }
2161
2162 void tst_QTableView::rowAt_data()
2163 {
2164     QTest::addColumn<int>("rowCount");
2165     QTest::addColumn<int>("rowHeight");
2166     QTest::addColumn<IntList>("hiddenRows");
2167     QTest::addColumn<int>("coordinate");
2168     QTest::addColumn<int>("row");
2169
2170     QTest::newRow("row at 100") << 5 << 40 << IntList() << 100 << 2;
2171     QTest::newRow("row at 180") << 5 << 40 << IntList() << 180 << 4;
2172     QTest::newRow("row at 20")  << 5 << 40 << IntList() <<  20 << 0;
2173
2174     // ### expand the dataset to include hidden rows
2175 }
2176
2177 void tst_QTableView::rowAt()
2178 {
2179     QFETCH(int, rowCount);
2180     QFETCH(int, rowHeight);
2181     QFETCH(IntList, hiddenRows);
2182     QFETCH(int, coordinate);
2183     QFETCH(int, row);
2184
2185     QtTestTableModel model(rowCount, 1);
2186     QtTestTableView view;
2187     view.resize(100, 2 * rowHeight);
2188
2189     view.setModel(&model);
2190
2191     for (int r = 0; r < rowCount; ++r)
2192         view.setRowHeight(r, rowHeight);
2193
2194     for (int i = 0; i < hiddenRows.count(); ++i)
2195         view.hideRow(hiddenRows.at(i));
2196
2197     QCOMPARE(view.rowAt(coordinate), row);
2198 }
2199
2200 void tst_QTableView::rowHeight_data()
2201 {
2202     QTest::addColumn<int>("rowCount");
2203     QTest::addColumn<IntList>("rowHeights");
2204     QTest::addColumn<BoolList>("hiddenRows");
2205
2206     QTest::newRow("increasing")
2207       << 5
2208       << (IntList() << 20 << 30 << 40 << 50 << 60)
2209       << (BoolList() << false << false << false << false << false);
2210
2211     QTest::newRow("decreasing")
2212       << 5
2213       << (IntList() << 60 << 50 << 40 << 30 << 20)
2214       << (BoolList() << false << false << false << false << false);
2215
2216     QTest::newRow("random")
2217       << 5
2218       << (IntList() << 87 << 34 << 68 << 91 << 27)
2219       << (BoolList() << false << false << false << false << false);
2220
2221     // ### expand the dataset to include hidden rows
2222 }
2223
2224 void tst_QTableView::rowHeight()
2225 {
2226     QFETCH(int, rowCount);
2227     QFETCH(IntList, rowHeights);
2228     QFETCH(BoolList, hiddenRows);
2229
2230     QtTestTableModel model(rowCount, 1);
2231     QtTestTableView view;
2232
2233     view.setModel(&model);
2234
2235     for (int r = 0; r < rowCount; ++r) {
2236         view.setRowHeight(r, rowHeights.at(r));
2237         view.setRowHidden(r, hiddenRows.at(r));
2238     }
2239
2240     for (int r = 0; r < rowCount; ++r) {
2241         if (hiddenRows.at(r))
2242             QCOMPARE(view.rowHeight(r), 0);
2243         else
2244             QCOMPARE(view.rowHeight(r), rowHeights.at(r));
2245     }
2246 }
2247
2248 void tst_QTableView::columnViewportPosition_data()
2249 {
2250     QTest::addColumn<int>("columnCount");
2251     QTest::addColumn<int>("columnWidth");
2252     QTest::addColumn<int>("column");
2253     QTest::addColumn<int>("horizontalScrollMode");
2254     QTest::addColumn<int>("horizontalScrollValue");
2255     QTest::addColumn<int>("columnViewportPosition");
2256
2257     QTest::newRow("column 0, scroll per item 0")
2258         << 10 << 40 << 0 << int(QAbstractItemView::ScrollPerItem) << 0 << 0;
2259
2260     QTest::newRow("column 1, scroll per item, 0")
2261         << 10 << 40 << 1 << int(QAbstractItemView::ScrollPerItem) << 0 << 1 * 40;
2262
2263     QTest::newRow("column 1, scroll per item, 1")
2264         << 10 << 40 << 1 << int(QAbstractItemView::ScrollPerItem) << 1 << 0;
2265
2266     QTest::newRow("column 5, scroll per item, 0")
2267         << 10 << 40 << 5 << int(QAbstractItemView::ScrollPerItem) << 0 << 5 * 40;
2268
2269     QTest::newRow("column 5, scroll per item, 5")
2270         << 10 << 40 << 5 << int(QAbstractItemView::ScrollPerItem) << 5 << 0;
2271
2272     QTest::newRow("column 9, scroll per item, 0")
2273         << 10 << 40 << 9 << int(QAbstractItemView::ScrollPerItem) << 0 << 9 * 40;
2274
2275     QTest::newRow("column 9, scroll per item, 5")
2276         << 10 << 40 << 9 << int(QAbstractItemView::ScrollPerItem) << 5 << 4 * 40;
2277
2278     QTest::newRow("column 0, scroll per pixel 0")
2279         << 10 << 40 << 0 << int(QAbstractItemView::ScrollPerPixel) << 0 << 0;
2280
2281     QTest::newRow("column 1, scroll per pixel 0")
2282         << 10 << 40 << 1 << int(QAbstractItemView::ScrollPerPixel) << 0 << 1 * 40;
2283
2284     QTest::newRow("column 1, scroll per pixel 1")
2285         << 10 << 40 << 1 << int(QAbstractItemView::ScrollPerPixel) << 1 * 40 << 0;
2286
2287     QTest::newRow("column 5, scroll per pixel 0")
2288         << 10 << 40 << 5 << int(QAbstractItemView::ScrollPerPixel) << 0 << 5 * 40;
2289
2290     QTest::newRow("column 5, scroll per pixel 5")
2291         << 10 << 40 << 5 << int(QAbstractItemView::ScrollPerPixel) << 5 * 40 << 0;
2292
2293     QTest::newRow("column 9, scroll per pixel 0")
2294         << 10 << 40 << 9 << int(QAbstractItemView::ScrollPerPixel) << 0 << 9 * 40;
2295
2296     QTest::newRow("column 9, scroll per pixel 5")
2297         << 10 << 40 << 9 << int(QAbstractItemView::ScrollPerPixel) << 5 * 40 << 4 * 40;
2298 }
2299
2300 void tst_QTableView::columnViewportPosition()
2301 {
2302     QFETCH(int, columnCount);
2303     QFETCH(int, columnWidth);
2304     QFETCH(int, column);
2305     QFETCH(int, horizontalScrollMode);
2306     QFETCH(int, horizontalScrollValue);
2307     QFETCH(int, columnViewportPosition);
2308
2309     QtTestTableModel model(1, columnCount);
2310     QtTestTableView view;
2311     view.resize(2 * columnWidth, 100);
2312     view.show();
2313
2314     view.setModel(&model);
2315     for (int c = 0; c < columnCount; ++c)
2316         view.setColumnWidth(c, columnWidth);
2317
2318     view.setHorizontalScrollMode((QAbstractItemView::ScrollMode)horizontalScrollMode);
2319     view.horizontalScrollBar()->setValue(horizontalScrollValue);
2320
2321     QCOMPARE(view.columnViewportPosition(column), columnViewportPosition);
2322 }
2323
2324 void tst_QTableView::columnAt_data()
2325 {
2326     QTest::addColumn<int>("columnCount");
2327     QTest::addColumn<int>("columnWidth");
2328     QTest::addColumn<IntList>("hiddenColumns");
2329     QTest::addColumn<int>("coordinate");
2330     QTest::addColumn<int>("column");
2331
2332     QTest::newRow("column at 100") << 5 << 40 << IntList() << 100 << 2;
2333     QTest::newRow("column at 180") << 5 << 40 << IntList() << 180 << 4;
2334     QTest::newRow("column at 20")  << 5 << 40 << IntList() <<  20 << 0;
2335
2336     // ### expand the dataset to include hidden coumns
2337 }
2338
2339 void tst_QTableView::columnAt()
2340 {
2341     QFETCH(int, columnCount);
2342     QFETCH(int, columnWidth);
2343     QFETCH(IntList, hiddenColumns);
2344     QFETCH(int, coordinate);
2345     QFETCH(int, column);
2346
2347     QtTestTableModel model(1, columnCount);
2348     QtTestTableView view;
2349     view.resize(2 * columnWidth, 100);
2350
2351     view.setModel(&model);
2352
2353     for (int c = 0; c < columnCount; ++c)
2354         view.setColumnWidth(c, columnWidth);
2355
2356     for (int i = 0; i < hiddenColumns.count(); ++i)
2357         view.hideColumn(hiddenColumns.at(i));
2358
2359     QCOMPARE(view.columnAt(coordinate), column);
2360 }
2361
2362 void tst_QTableView::columnWidth_data()
2363 {
2364     QTest::addColumn<int>("columnCount");
2365     QTest::addColumn<IntList>("columnWidths");
2366     QTest::addColumn<BoolList>("hiddenColumns");
2367
2368     QTest::newRow("increasing")
2369       << 5
2370       << (IntList() << 20 << 30 << 40 << 50 << 60)
2371       << (BoolList() << false << false << false << false << false);
2372
2373     QTest::newRow("decreasing")
2374       << 5
2375       << (IntList() << 60 << 50 << 40 << 30 << 20)
2376       << (BoolList() << false << false << false << false << false);
2377
2378     QTest::newRow("random")
2379       << 5
2380       << (IntList() << 87 << 34 << 68 << 91 << 27)
2381       << (BoolList() << false << false << false << false << false);
2382
2383     // ### expand the dataset to include hidden columns
2384 }
2385
2386 void tst_QTableView::columnWidth()
2387 {
2388     QFETCH(int, columnCount);
2389     QFETCH(IntList, columnWidths);
2390     QFETCH(BoolList, hiddenColumns);
2391
2392     QtTestTableModel model(1, columnCount);
2393     QtTestTableView view;
2394
2395     view.setModel(&model);
2396
2397     for (int c = 0; c < columnCount; ++c) {
2398         view.setColumnWidth(c, columnWidths.at(c));
2399         view.setColumnHidden(c, hiddenColumns.at(c));
2400     }
2401
2402     for (int c = 0; c < columnCount; ++c) {
2403         if (hiddenColumns.at(c))
2404             QCOMPARE(view.columnWidth(c), 0);
2405         else
2406             QCOMPARE(view.columnWidth(c), columnWidths.at(c));
2407     }
2408 }
2409
2410 void tst_QTableView::hiddenRow_data()
2411 {
2412     QTest::addColumn<int>("rowCount");
2413     QTest::addColumn<BoolList>("hiddenRows");
2414
2415     QTest::newRow("first hidden")
2416       << 5 << (BoolList() << true << false << false << false << false);
2417
2418     QTest::newRow("last hidden")
2419       << 5 << (BoolList() << false << false << false << false << true);
2420
2421     QTest::newRow("none hidden")
2422       << 5 << (BoolList() << false << false << false << false << false);
2423
2424     QTest::newRow("all hidden")
2425       << 5 << (BoolList() << true << true << true << true << true);
2426  }
2427
2428 void tst_QTableView::hiddenRow()
2429 {
2430     QFETCH(int, rowCount);
2431     QFETCH(BoolList, hiddenRows);
2432
2433
2434     QtTestTableModel model(rowCount, 1);
2435     QtTestTableView view;
2436
2437     view.setModel(&model);
2438
2439     for (int r = 0; r < rowCount; ++r)
2440         QVERIFY(!view.isRowHidden(r));
2441
2442     for (int r = 0; r < rowCount; ++r)
2443         view.setRowHidden(r, hiddenRows.at(r));
2444
2445     for (int r = 0; r < rowCount; ++r)
2446         QCOMPARE(view.isRowHidden(r), hiddenRows.at(r));
2447
2448     for (int r = 0; r < rowCount; ++r)
2449         view.setRowHidden(r, false);
2450
2451     for (int r = 0; r < rowCount; ++r)
2452         QVERIFY(!view.isRowHidden(r));
2453 }
2454
2455 void tst_QTableView::hiddenColumn_data()
2456 {
2457     QTest::addColumn<int>("columnCount");
2458     QTest::addColumn<BoolList>("hiddenColumns");
2459
2460     QTest::newRow("first hidden")
2461       << 5 << (BoolList() << true << false << false << false << false);
2462
2463     QTest::newRow("last hidden")
2464       << 5 << (BoolList() << false << false << false << false << true);
2465
2466     QTest::newRow("none hidden")
2467       << 5 << (BoolList() << false << false << false << false << false);
2468
2469     QTest::newRow("all hidden")
2470       << 5 << (BoolList() << true << true << true << true << true);
2471 }
2472
2473 void tst_QTableView::hiddenColumn()
2474 {
2475     QFETCH(int, columnCount);
2476     QFETCH(BoolList, hiddenColumns);
2477
2478     QtTestTableModel model(1, columnCount);
2479     QtTestTableView view;
2480
2481     view.setModel(&model);
2482
2483     for (int c = 0; c < columnCount; ++c)
2484         QVERIFY(!view.isColumnHidden(c));
2485
2486     for (int c = 0; c < columnCount; ++c)
2487         view.setColumnHidden(c, hiddenColumns.at(c));
2488
2489     for (int c = 0; c < columnCount; ++c)
2490         QCOMPARE(view.isColumnHidden(c), hiddenColumns.at(c));
2491
2492     for (int c = 0; c < columnCount; ++c)
2493         view.setColumnHidden(c, false);
2494
2495     for (int c = 0; c < columnCount; ++c)
2496         QVERIFY(!view.isColumnHidden(c));
2497 }
2498
2499 void tst_QTableView::sortingEnabled_data()
2500 {
2501 //    QTest::addColumn<int>("columnCount");
2502 }
2503
2504 void tst_QTableView::sortingEnabled()
2505 {
2506 //    QFETCH(int, columnCount);
2507 }
2508
2509 void tst_QTableView::scrollTo_data()
2510 {
2511     QTest::addColumn<int>("verticalScrollMode");
2512     QTest::addColumn<int>("horizontalScrollMode");
2513     QTest::addColumn<int>("rowCount");
2514     QTest::addColumn<int>("columnCount");
2515     QTest::addColumn<int>("rowHeight");
2516     QTest::addColumn<int>("columnWidth");
2517     QTest::addColumn<int>("hiddenRow");
2518     QTest::addColumn<int>("hiddenColumn");
2519     QTest::addColumn<int>("row");
2520     QTest::addColumn<int>("column");
2521     QTest::addColumn<int>("rowSpan");
2522     QTest::addColumn<int>("columnSpan");
2523     QTest::addColumn<int>("horizontalScroll");
2524     QTest::addColumn<int>("verticalScroll");
2525     QTest::addColumn<int>("scrollHint");
2526     QTest::addColumn<int>("expectedHorizontalScroll");
2527     QTest::addColumn<int>("expectedVerticalScroll");
2528
2529     QTest::newRow("no hidden, no span, no scroll, per item")
2530         << (int)QAbstractItemView::ScrollPerItem
2531         << (int)QAbstractItemView::ScrollPerItem
2532         << 10 << 10  // table
2533         << 80 << 80  // size
2534         << -1 << -1  // hide
2535         << 0 << 0    // cell
2536         << 1 << 1    // span
2537         << 0 << 0    // scroll
2538         << (int)QAbstractItemView::PositionAtTop
2539         << 0 << 0;   // expected
2540
2541     QTest::newRow("no hidden, no span, no scroll, per pixel")
2542         << (int)QAbstractItemView::ScrollPerPixel
2543         << (int)QAbstractItemView::ScrollPerPixel
2544         << 10 << 10  // table
2545         << 80 << 80  // size
2546         << -1 << -1  // hide
2547         << 0 << 0    // cell
2548         << 1 << 1    // span
2549         << 0 << 0    // scroll
2550         << (int)QAbstractItemView::PositionAtTop
2551         << 0 << 0;   // expected
2552
2553     QTest::newRow("hidden, no span, no scroll, per item")
2554         << (int)QAbstractItemView::ScrollPerItem
2555         << (int)QAbstractItemView::ScrollPerItem
2556         << 10 << 10  // table
2557         << 80 << 80  // size
2558         << 3 << 3    // hide
2559         << 5 << 5    // cell
2560         << 1 << 1    // span
2561         << 0 << 0    // scroll
2562         << (int)QAbstractItemView::PositionAtTop
2563         << 4 << 4;   // expected
2564 }
2565
2566 void tst_QTableView::scrollTo()
2567 {
2568     QFETCH(int, horizontalScrollMode);
2569     QFETCH(int, verticalScrollMode);
2570     QFETCH(int, rowCount);
2571     QFETCH(int, columnCount);
2572     QFETCH(int, rowHeight);
2573     QFETCH(int, columnWidth);
2574     QFETCH(int, hiddenRow);
2575     QFETCH(int, hiddenColumn);
2576     QFETCH(int, row);
2577     QFETCH(int, column);
2578     QFETCH(int, rowSpan);
2579     QFETCH(int, columnSpan);
2580     QFETCH(int, horizontalScroll);
2581     QFETCH(int, verticalScroll);
2582     QFETCH(int, scrollHint);
2583     QFETCH(int, expectedHorizontalScroll);
2584     QFETCH(int, expectedVerticalScroll);
2585
2586     QtTestTableModel model(rowCount, columnCount);
2587     QWidget toplevel;
2588     QtTestTableView view(&toplevel);
2589
2590     toplevel.show();
2591     // resizing to this size will ensure that there can ONLY_BE_ONE_CELL inside the view.
2592     QSize forcedSize(columnWidth * 2, rowHeight * 2);
2593     view.resize(forcedSize);
2594     QVERIFY(QTest::qWaitForWindowExposed(&toplevel));
2595     QTRY_COMPARE(view.size(), forcedSize);
2596
2597     view.setModel(&model);
2598     view.setSpan(row, column, rowSpan, columnSpan);
2599     view.hideRow(hiddenRow);
2600     view.hideColumn(hiddenColumn);
2601     view.setHorizontalScrollMode((QAbstractItemView::ScrollMode)horizontalScrollMode);
2602     view.setVerticalScrollMode((QAbstractItemView::ScrollMode)verticalScrollMode);
2603
2604     for (int r = 0; r < rowCount; ++r)
2605         view.setRowHeight(r, rowHeight);
2606     for (int c = 0; c < columnCount; ++c)
2607         view.setColumnWidth(c, columnWidth);
2608
2609     QTest::qWait(150); // ### needed to pass the test
2610     view.horizontalScrollBar()->setValue(horizontalScroll);
2611     view.verticalScrollBar()->setValue(verticalScroll);
2612
2613     QModelIndex index = model.index(row, column);
2614     QVERIFY(index.isValid());
2615     view.scrollTo(index, (QAbstractItemView::ScrollHint)scrollHint);
2616     QCOMPARE(view.verticalScrollBar()->value(), expectedVerticalScroll);
2617     QCOMPARE(view.horizontalScrollBar()->value(), expectedHorizontalScroll);
2618 }
2619
2620 void tst_QTableView::indexAt_data()
2621 {
2622     QTest::addColumn<int>("rowCount");
2623     QTest::addColumn<int>("columnCount");
2624
2625     QTest::addColumn<int>("rowHeight");
2626     QTest::addColumn<int>("columnWidth");
2627
2628     QTest::addColumn<int>("hiddenRow");
2629     QTest::addColumn<int>("hiddenColumn");
2630
2631     QTest::addColumn<int>("row");
2632     QTest::addColumn<int>("column");
2633     QTest::addColumn<int>("rowSpan");
2634     QTest::addColumn<int>("columnSpan");
2635     QTest::addColumn<int>("horizontalScroll");
2636     QTest::addColumn<int>("verticalScroll");
2637     QTest::addColumn<int>("x");
2638     QTest::addColumn<int>("y");
2639     QTest::addColumn<int>("expectedRow");
2640     QTest::addColumn<int>("expectedColumn");
2641
2642     QTest::newRow("no hidden, no span, no scroll, (20,20)")
2643       << 10 << 10  // dim
2644       << 40 << 40  // size
2645       << -1 << -1  // hide
2646       << -1 << -1  // pos
2647       << 1 << 1    // span
2648       << 0 << 0    // scroll
2649       << 20 << 20  // point
2650       << 0 << 0;   // expected
2651
2652     QTest::newRow("row hidden, no span, no scroll, at (20,20)")
2653       << 10 << 10  // dim
2654       << 40 << 40  // size
2655       << 0 << -1   // hide
2656       << -1 << -1  // pos
2657       << 1 << 1    // span
2658       << 0 << 0    // scroll
2659       << 20 << 20  // point
2660       << 1 << 0;   // expected
2661
2662     QTest::newRow("col hidden, no span, no scroll, at (20,20)")
2663       << 10 << 10  // dim
2664       << 40 << 40  // size
2665       << -1 << 0   // hide
2666       << -1 << -1  // pos
2667       << 1 << 1    // span
2668       << 0 << 0    // scroll
2669       << 20 << 20  // point
2670       << 0 << 1;   // expected
2671
2672     QTest::newRow("no hidden, row span, no scroll, at (60,20)")
2673       << 10 << 10  // dim
2674       << 40 << 40  // size
2675       << -1 << -1  // hide
2676       << 0 << 0    // pos
2677       << 2 << 1    // span
2678       << 0 << 0    // scroll
2679       << 20 << 60  // point
2680       << 0 << 0;   // expected
2681
2682
2683     QTest::newRow("no hidden, col span, no scroll, at (60,20)")
2684       << 10 << 10  // dim
2685       << 40 << 40  // size
2686       << -1 << -1  // hide
2687       << 0 << 0    // pos
2688       << 1 << 2    // span
2689       << 0 << 0    // scroll
2690       << 60 << 20  // point
2691       << 0 << 0;   // expected
2692
2693     QTest::newRow("no hidden, no span, scroll (5,0), at (20,20)")
2694       << 10 << 10  // dim
2695       << 40 << 40  // size
2696       << -1 << -1  // hide
2697       << -1 << -1  // pos
2698       << 1 << 1    // span
2699       << 5 << 0    // scroll
2700       << 20 << 20  // point
2701       << 0 << 5;   // expected
2702
2703     QTest::newRow("no hidden, no span, scroll (0,5), at (20,20)")
2704       << 10 << 10  // dim
2705       << 40 << 40  // size
2706       << -1 << -1  // hide
2707       << -1 << -1  // pos
2708       << 1 << 1    // span
2709       << 0 << 5    // scroll
2710       << 20 << 20  // point
2711       << 5 << 0;   // expected
2712
2713     QTest::newRow("no hidden, no span, scroll (5,5), at (20,20)")
2714       << 10 << 10  // dim
2715       << 40 << 40  // size
2716       << -1 << -1  // hide
2717       << -1 << -1  // pos
2718       << 1 << 1    // span
2719       << 5 << 5    // scroll
2720       << 20 << 20  // point
2721       << 5 << 5;   // expected
2722 }
2723
2724 void tst_QTableView::indexAt()
2725 {
2726     QFETCH(int, rowCount);
2727     QFETCH(int, columnCount);
2728     QFETCH(int, rowHeight);
2729     QFETCH(int, columnWidth);
2730     QFETCH(int, hiddenRow);
2731     QFETCH(int, hiddenColumn);
2732     QFETCH(int, row);
2733     QFETCH(int, column);
2734     QFETCH(int, rowSpan);
2735     QFETCH(int, columnSpan);
2736     QFETCH(int, horizontalScroll);
2737     QFETCH(int, verticalScroll);
2738     QFETCH(int, x);
2739     QFETCH(int, y);
2740     QFETCH(int, expectedRow);
2741     QFETCH(int, expectedColumn);
2742
2743     QtTestTableModel model(rowCount, columnCount);
2744     QWidget toplevel;
2745     QtTestTableView view(&toplevel);
2746
2747     toplevel.show();
2748     QVERIFY(QTest::qWaitForWindowExposed(&toplevel));
2749
2750     //some styles change the scroll mode in their polish
2751     view.setHorizontalScrollMode(QAbstractItemView::ScrollPerItem);
2752     view.setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
2753
2754     view.setModel(&model);
2755     view.setSpan(row, column, rowSpan, columnSpan);
2756     view.hideRow(hiddenRow);
2757     view.hideColumn(hiddenColumn);
2758
2759     for (int r = 0; r < rowCount; ++r)
2760         view.setRowHeight(r, rowHeight);
2761     for (int c = 0; c < columnCount; ++c)
2762         view.setColumnWidth(c, columnWidth);
2763
2764     QTest::qWait(20);
2765     view.horizontalScrollBar()->setValue(horizontalScroll);
2766     view.verticalScrollBar()->setValue(verticalScroll);
2767     QTest::qWait(20);
2768
2769     QModelIndex index = view.indexAt(QPoint(x, y));
2770     QCOMPARE(index.row(), expectedRow);
2771     QCOMPARE(index.column(), expectedColumn);
2772 }
2773
2774 void tst_QTableView::span_data()
2775 {
2776     QTest::addColumn<int>("rowCount");
2777     QTest::addColumn<int>("columnCount");
2778     QTest::addColumn<int>("hiddenRow");
2779     QTest::addColumn<int>("hiddenColumn");
2780     QTest::addColumn<int>("row");
2781     QTest::addColumn<int>("column");
2782     QTest::addColumn<int>("rowSpan");
2783     QTest::addColumn<int>("columnSpan");
2784     QTest::addColumn<int>("expectedRowSpan");
2785     QTest::addColumn<int>("expectedColumnSpan");
2786     QTest::addColumn<bool>("clear");
2787
2788     QTest::newRow("top left 2x2")
2789       << 10 << 10
2790       << -1 << -1
2791       << 0 << 0
2792       << 2 << 2
2793       << 2 << 2
2794       << false;
2795
2796     QTest::newRow("top left 1x2")
2797       << 10 << 10
2798       << 3 << 3
2799       << 0 << 0
2800       << 1 << 2
2801       << 1 << 2
2802       << false;
2803
2804     QTest::newRow("top left 2x1")
2805       << 10 << 10
2806       << -1 << -1
2807       << 0 << 0
2808       << 2 << 1
2809       << 2 << 1
2810       << false;
2811
2812   /* This makes no sens.
2813     QTest::newRow("top left 2x0")
2814       << 10 << 10
2815       << -1 << -1
2816       << 0 << 0
2817       << 2 << 0
2818       << 2 << 0
2819       << false;
2820
2821     QTest::newRow("top left 0x2")
2822       << 10 << 10
2823       << -1 << -1
2824       << 0 << 0
2825       << 0 << 2
2826       << 0 << 2
2827       << false;*/
2828
2829     QTest::newRow("invalid 2x2")
2830       << 10 << 10
2831       << -1 << -1
2832       << -1 << -1
2833       << 2 << 2
2834       << 1 << 1
2835       << false;
2836
2837     QTest::newRow("top left 2x2")
2838       << 10 << 10
2839       << -1 << -1
2840       << 0 << 0
2841       << 2 << 2
2842       << 2 << 2
2843       << false;
2844
2845     QTest::newRow("bottom right 2x2")
2846       << 10 << 10
2847       << -1 << -1
2848       << 8 << 8
2849       << 2 << 2
2850       << 2 << 2
2851       << false;
2852
2853     QTest::newRow("invalid span 2x2")
2854       << 10 << 10
2855       << -1 << -1
2856       << 8 << 8
2857       << 2 << 2
2858       << 2 << 2
2859       << false;
2860
2861     QTest::newRow("invalid span 3x3")
2862       << 10 << 10
2863       << -1 << -1
2864       << 6 << 6
2865       << 3 << 3
2866       << 2 << 3
2867       << true;
2868
2869 }
2870
2871 void tst_QTableView::span()
2872 {
2873     QFETCH(int, rowCount);
2874     QFETCH(int, columnCount);
2875     QFETCH(int, hiddenRow);
2876     QFETCH(int, hiddenColumn);
2877     QFETCH(int, row);
2878     QFETCH(int, column);
2879     QFETCH(int, rowSpan);
2880     QFETCH(int, columnSpan);
2881     QFETCH(int, expectedRowSpan);
2882     QFETCH(int, expectedColumnSpan);
2883     QFETCH(bool, clear);
2884
2885     QtTestTableModel model(rowCount, columnCount);
2886     QtTestTableView view;
2887
2888     view.setModel(&model);
2889     view.show();
2890
2891     view.setSpan(row, column, rowSpan, columnSpan);
2892     if (clear) {
2893         model.removeLastRow();
2894         model.removeLastRow();
2895         view.update();
2896     }
2897
2898     view.hideRow(hiddenRow);
2899     view.hideColumn(hiddenColumn);
2900     view.show();
2901
2902     QCOMPARE(view.rowSpan(row, column), expectedRowSpan);
2903     QCOMPARE(view.columnSpan(row, column), expectedColumnSpan);
2904
2905     if (hiddenRow > -1) {
2906         QModelIndex hidden = model.index(hiddenRow, columnCount - 1);
2907         QVERIFY(view.isIndexHidden(hidden));
2908     }
2909
2910     if (hiddenColumn > -1) {
2911         QModelIndex hidden = model.index(rowCount - 1, hiddenColumn);
2912         QVERIFY(view.isIndexHidden(hidden));
2913     }
2914
2915     view.clearSpans();
2916     QCOMPARE(view.rowSpan(row, column), 1);
2917     QCOMPARE(view.columnSpan(row, column), 1);
2918
2919     VERIFY_SPANS_CONSISTENCY(&view);
2920 }
2921
2922 typedef QVector<QRect> SpanList;
2923 Q_DECLARE_METATYPE(SpanList)
2924
2925 void tst_QTableView::spans_data()
2926 {
2927     QTest::addColumn<int>("rows");
2928     QTest::addColumn<int>("columns");
2929     QTest::addColumn<SpanList>("spans");
2930     QTest::addColumn<bool>("hideRowLastRowOfFirstSpan");
2931     QTest::addColumn<QPoint>("pos");
2932     QTest::addColumn<int>("expectedRowSpan");
2933     QTest::addColumn<int>("expectedColumnSpan");
2934
2935     QTest::newRow("1x3 span, query 3,0")
2936       << 5 << 5
2937       << (SpanList() << QRect(3, 0, 1, 3))
2938       << false //no hidden row
2939       << QPoint(3, 0)
2940       << 1
2941       << 3;
2942
2943     QTest::newRow("1x3 span, query 3,1")
2944       << 5 << 5
2945       << (SpanList() << QRect(3, 0, 1, 3))
2946       << false //no hidden row
2947       << QPoint(3, 1)
2948       << 1
2949       << 3;
2950
2951     QTest::newRow("1x3 span, query 3,2")
2952       << 5 << 5
2953       << (SpanList() << QRect(3, 0, 1, 3))
2954       << false //no hidden row
2955       << QPoint(3, 2)
2956       << 1
2957       << 3;
2958
2959     QTest::newRow("two 1x2 spans at the same column, query at 3,0")
2960       << 5 << 5
2961       << (SpanList() << QRect(3, 0, 1, 2) << QRect(4, 0, 1, 2))
2962       << false //no hidden row
2963       << QPoint(3, 0)
2964       << 1
2965       << 2;
2966
2967     QTest::newRow("two 1x2 spans at the same column, query at 4,0")
2968       << 5 << 5
2969       << (SpanList() << QRect(3, 0, 1, 2) << QRect(4, 0, 1, 2))
2970       << false //no hidden row
2971       << QPoint(4, 0)
2972       << 1
2973       << 2;
2974
2975     QTest::newRow("how to order spans (1,1)")
2976       << 5 << 5
2977       << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1))
2978       << false //no hidden row
2979       << QPoint(1, 1)
2980       << 3
2981       << 1;
2982
2983     QTest::newRow("how to order spans (2,1)")
2984       << 5 << 5
2985       << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1))
2986       << false //no hidden row
2987       << QPoint(2, 1)
2988       << 3
2989       << 1;
2990
2991     QTest::newRow("how to order spans (3,1)")
2992       << 5 << 5
2993       << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1))
2994       << false //no hidden row
2995       << QPoint(3, 1)
2996       << 3
2997       << 1;
2998
2999     QTest::newRow("how to order spans (1,2)")
3000       << 5 << 5
3001       << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1))
3002       << false //no hidden row
3003       << QPoint(1, 2)
3004       << 2
3005       << 1;
3006
3007     QTest::newRow("how to order spans (2,2)")
3008       << 5 << 5
3009       << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1))
3010       << false //no hidden row
3011       << QPoint(2, 2)
3012       << 2
3013       << 1;
3014
3015     QTest::newRow("spans with hidden rows")
3016       << 3 << 2
3017       << (SpanList() << QRect(0, 0, 2, 2) << QRect(2, 0, 1, 2))
3018       << true //we hide the last row of the first span
3019       << QPoint(2, 0)
3020       << 1
3021       << 2;
3022
3023     QTest::newRow("QTBUG-6004: No failing assertion, then it passes.")
3024       << 5 << 5
3025       << (SpanList() << QRect(0, 0, 2, 2) << QRect(0, 0, 1, 1))
3026       << false
3027       << QPoint(0, 0)
3028       << 1
3029       << 1;
3030
3031     QTest::newRow("QTBUG-6004 (follow-up): No failing assertion, then it passes.")
3032       << 10 << 10
3033       << (SpanList() << QRect(2, 2, 1, 3) << QRect(2, 2, 1, 1))
3034       << false
3035       << QPoint(0, 0)
3036       << 1
3037       << 1;
3038
3039     QTest::newRow("QTBUG-9631: remove one span")
3040       << 10 << 10
3041       << (SpanList() << QRect(1, 1, 2, 1) << QRect(2, 2, 2, 2) << QRect(1, 1, 1, 1))
3042       << false
3043       << QPoint(1, 1)
3044       << 1
3045       << 1;
3046 }
3047
3048 void tst_QTableView::spans()
3049 {
3050     QFETCH(int, rows);
3051     QFETCH(int, columns);
3052     QFETCH(SpanList, spans);
3053     QFETCH(bool, hideRowLastRowOfFirstSpan);
3054     QFETCH(QPoint, pos);
3055     QFETCH(int, expectedRowSpan);
3056     QFETCH(int, expectedColumnSpan);
3057
3058     QtTestTableModel model(rows, columns);
3059     QtTestTableView view;
3060
3061     view.setModel(&model);
3062     view.show();
3063
3064     for (int i = 0; i < spans.count(); ++i) {
3065         QRect sp = spans.at(i);
3066         view.setSpan(sp.x(), sp.y(), sp.width(), sp.height());
3067     }
3068
3069     if (hideRowLastRowOfFirstSpan) {
3070         view.setRowHidden(spans.at(0).bottom(), true);
3071         //we check that the span didn't break the visual rects of the model indexes
3072         QRect first = view.visualRect( model.index(spans.at(0).top(), 0));
3073         QRect next = view.visualRect( model.index(spans.at(0).bottom() + 1, 0));
3074         QVERIFY(first.intersected(next).isEmpty());
3075     }
3076
3077     QCOMPARE(view.columnSpan(pos.x(), pos.y()), expectedColumnSpan);
3078     QCOMPARE(view.rowSpan(pos.x(), pos.y()), expectedRowSpan);
3079
3080     VERIFY_SPANS_CONSISTENCY(&view);
3081 }
3082
3083 void tst_QTableView::spansAfterRowInsertion()
3084 {
3085     QtTestTableModel model(10, 10);
3086     QtTestTableView view;
3087     view.setModel(&model);
3088     view.setSpan(3, 3, 3, 3);
3089     view.show();
3090     QTest::qWait(50);
3091
3092     // Insertion before the span only shifts the span.
3093     view.model()->insertRows(0, 2);
3094     QCOMPARE(view.rowSpan(3, 3), 1);
3095     QCOMPARE(view.columnSpan(3, 3), 1);
3096     QCOMPARE(view.rowSpan(5, 3), 3);
3097     QCOMPARE(view.columnSpan(5, 3), 3);
3098
3099     // Insertion happens before the given row, so it only shifts the span also.
3100     view.model()->insertRows(5, 2);
3101     QCOMPARE(view.rowSpan(5, 3), 1);
3102     QCOMPARE(view.columnSpan(5, 3), 1);
3103     QCOMPARE(view.rowSpan(7, 3), 3);
3104     QCOMPARE(view.columnSpan(7, 3), 3);
3105
3106     // Insertion inside the span expands it.
3107     view.model()->insertRows(8, 2);
3108     QCOMPARE(view.rowSpan(7, 3), 5);
3109     QCOMPARE(view.columnSpan(7, 3), 3);
3110
3111     // Insertion after the span does nothing to it.
3112     view.model()->insertRows(12, 2);
3113     QCOMPARE(view.rowSpan(7, 3), 5);
3114     QCOMPARE(view.columnSpan(7, 3), 3);
3115
3116     VERIFY_SPANS_CONSISTENCY(&view);
3117 }
3118
3119 void tst_QTableView::spansAfterColumnInsertion()
3120 {
3121     QtTestTableModel model(10, 10);
3122     QtTestTableView view;
3123     view.setModel(&model);
3124     view.setSpan(3, 3, 3, 3);
3125     view.show();
3126     QTest::qWait(50);
3127
3128     // Insertion before the span only shifts the span.
3129     view.model()->insertColumns(0, 2);
3130     QCOMPARE(view.rowSpan(3, 3), 1);
3131     QCOMPARE(view.columnSpan(3, 3), 1);
3132     QCOMPARE(view.rowSpan(3, 5), 3);
3133     QCOMPARE(view.columnSpan(3, 5), 3);
3134
3135     // Insertion happens before the given column, so it only shifts the span also.
3136     view.model()->insertColumns(5, 2);
3137     QCOMPARE(view.rowSpan(3, 5), 1);
3138     QCOMPARE(view.columnSpan(3, 5), 1);
3139     QCOMPARE(view.rowSpan(3, 7), 3);
3140     QCOMPARE(view.columnSpan(3, 7), 3);
3141
3142     // Insertion inside the span expands it.
3143     view.model()->insertColumns(8, 2);
3144     QCOMPARE(view.rowSpan(3, 7), 3);
3145     QCOMPARE(view.columnSpan(3, 7), 5);
3146
3147     // Insertion after the span does nothing to it.
3148     view.model()->insertColumns(12, 2);
3149     QCOMPARE(view.rowSpan(3, 7), 3);
3150     QCOMPARE(view.columnSpan(3, 7), 5);
3151
3152     VERIFY_SPANS_CONSISTENCY(&view);
3153 }
3154
3155 void tst_QTableView::spansAfterRowRemoval()
3156 {
3157     QtTestTableModel model(10, 10);
3158     QtTestTableView view;
3159     view.setModel(&model);
3160
3161     QList<QRect> spans;
3162     spans << QRect(0, 1, 1, 2)
3163           << QRect(1, 2, 1, 2)
3164           << QRect(2, 2, 1, 5)
3165           << QRect(2, 8, 1, 2)
3166           << QRect(3, 4, 1, 2)
3167           << QRect(4, 4, 1, 4)
3168           << QRect(5, 6, 1, 3)
3169           << QRect(6, 7, 1, 3);
3170     foreach (QRect span, spans)
3171         view.setSpan(span.top(), span.left(), span.height(), span.width());
3172
3173     view.show();
3174     QTest::qWait(100);
3175     view.model()->removeRows(3, 3);
3176
3177     QList<QRect> expectedSpans;
3178     expectedSpans << QRect(0, 1, 1, 2)
3179           << QRect(1, 2, 1, 1)
3180           << QRect(2, 2, 1, 2)
3181           << QRect(2, 5, 1, 2)
3182           << QRect(3, 4, 1, 1)
3183           << QRect(4, 3, 1, 2)
3184           << QRect(5, 3, 1, 3)
3185           << QRect(6, 4, 1, 3);
3186     foreach (QRect span, expectedSpans) {
3187         QCOMPARE(view.columnSpan(span.top(), span.left()), span.width());
3188         QCOMPARE(view.rowSpan(span.top(), span.left()), span.height());
3189     }
3190
3191     VERIFY_SPANS_CONSISTENCY(&view);
3192 }
3193
3194 void tst_QTableView::spansAfterColumnRemoval()
3195 {
3196     QtTestTableModel model(10, 10);
3197     QtTestTableView view;
3198     view.setModel(&model);
3199
3200     // Same set as above just swapping columns and rows.
3201     QList<QRect> spans;
3202     spans << QRect(0, 1, 1, 2)
3203           << QRect(1, 2, 1, 2)
3204           << QRect(2, 2, 1, 5)
3205           << QRect(2, 8, 1, 2)
3206           << QRect(3, 4, 1, 2)
3207           << QRect(4, 4, 1, 4)
3208           << QRect(5, 6, 1, 3)
3209           << QRect(6, 7, 1, 3);
3210     foreach (QRect span, spans)
3211         view.setSpan(span.left(), span.top(), span.width(), span.height());
3212
3213     view.show();
3214     QTest::qWait(100);
3215     view.model()->removeColumns(3, 3);
3216
3217     QList<QRect> expectedSpans;
3218     expectedSpans << QRect(0, 1, 1, 2)
3219           << QRect(1, 2, 1, 1)
3220           << QRect(2, 2, 1, 2)
3221           << QRect(2, 5, 1, 2)
3222           << QRect(3, 4, 1, 1)
3223           << QRect(4, 3, 1, 2)
3224           << QRect(5, 3, 1, 3)
3225           << QRect(6, 4, 1, 3);
3226     foreach (QRect span, expectedSpans) {
3227         QCOMPARE(view.columnSpan(span.left(), span.top()), span.height());
3228         QCOMPARE(view.rowSpan(span.left(), span.top()), span.width());
3229     }
3230
3231     VERIFY_SPANS_CONSISTENCY(&view);
3232 }
3233
3234 class Model : public QAbstractTableModel {
3235
3236 Q_OBJECT
3237
3238 public:
3239     Model(QObject * parent = 0) : QAbstractTableModel(parent) {
3240     }
3241
3242     int rowCount(const QModelIndex &) const {
3243         return rows;
3244     }
3245     int columnCount(const QModelIndex &) const {
3246         return columns;
3247     }
3248     QVariant data(const QModelIndex &, int) const
3249     {
3250         return QVariant();
3251     }
3252     void res() { reset(); }
3253
3254     int rows;
3255     int columns;
3256 };
3257
3258 void tst_QTableView::checkHeaderReset()
3259 {
3260     QTableView view;
3261     Model m;
3262     m.rows = 3;
3263     m.columns = 3;
3264     view.setModel(&m);
3265
3266     m.rows = 4;
3267     m.columns = 4;
3268     m.res();
3269     QCOMPARE(view.horizontalHeader()->count(), 4);
3270 }
3271
3272 void tst_QTableView::checkHeaderMinSize()
3273 {
3274     //tests if the minimumsize is of a header is taken into account
3275     //while computing QTableView geometry. For that we test the position of the
3276     //viewport.
3277     QTableView view;
3278     QStringListModel m;
3279     m.setStringList( QStringList() << QLatin1String("one cell is enough"));
3280     view.setModel(&m);
3281
3282     //setting the minimum height on the horizontal header
3283     //and the minimum width on the vertical header
3284     view.horizontalHeader()->setMinimumHeight(50);
3285     view.verticalHeader()->setMinimumWidth(100);
3286
3287     view.show();
3288
3289     QVERIFY( view.verticalHeader()->y() >= view.horizontalHeader()->minimumHeight());
3290     QVERIFY( view.horizontalHeader()->x() >= view.verticalHeader()->minimumWidth());
3291 }
3292
3293 void tst_QTableView::resizeToContents()
3294 {
3295     //checks that the resize to contents is consistent
3296     QTableWidget table(2,3);
3297     QTableWidget table2(2,3);
3298     QTableWidget table3(2,3);
3299
3300
3301     table.setHorizontalHeaderItem(0, new QTableWidgetItem("A Lot of text here: BLA BLA BLA"));
3302     table2.setHorizontalHeaderItem(0, new QTableWidgetItem("A Lot of text here: BLA BLA BLA"));
3303     table3.setHorizontalHeaderItem(0, new QTableWidgetItem("A Lot of text here: BLA BLA BLA"));
3304     table.horizontalHeader()->setVisible(false);
3305     table2.horizontalHeader()->setVisible(false);
3306     table.verticalHeader()->setVisible(false);
3307     table2.verticalHeader()->setVisible(false);
3308
3309
3310     for(int i = 0;i<table.columnCount();i++) {
3311         table.resizeColumnToContents(i);
3312     }
3313     for(int i = 0;i<table.rowCount();i++) {
3314         table.resizeRowToContents(i);
3315     }
3316     table2.resizeColumnsToContents();
3317     table2.resizeRowsToContents();
3318     table3.resizeColumnsToContents();
3319     table3.resizeRowsToContents();
3320
3321     //now let's check the row/col sizes
3322     for(int i = 0;i<table.columnCount();i++) {
3323         QCOMPARE( table.columnWidth(i), table2.columnWidth(i));
3324         QCOMPARE( table2.columnWidth(i), table3.columnWidth(i));
3325     }
3326     for(int i = 0;i<table.rowCount();i++) {
3327         QCOMPARE( table.rowHeight(i), table2.rowHeight(i));
3328         QCOMPARE( table2.rowHeight(i), table3.rowHeight(i));
3329     }
3330
3331 }
3332
3333 QT_BEGIN_NAMESPACE
3334 extern bool Q_GUI_EXPORT qt_tab_all_widgets; // qapplication.cpp
3335 QT_END_NAMESPACE
3336
3337 void tst_QTableView::tabFocus()
3338 {
3339     if (!qt_tab_all_widgets)
3340         QSKIP("This test requires full keyboard control to be enabled.");
3341
3342     // QTableView enables tabKeyNavigation by default, but you should be able
3343     // to change focus on an empty table view, or on a table view that doesn't
3344     // have this property set.
3345     QWidget window;
3346
3347     QTableView *view = new QTableView(&window);
3348     QLineEdit *edit = new QLineEdit(&window);
3349
3350     window.show();
3351     QApplication::setActiveWindow(&window);
3352     window.setFocus();
3353     window.activateWindow();
3354     QVERIFY(QTest::qWaitForWindowActive(&window));
3355
3356     // window
3357     QVERIFY(window.hasFocus());
3358     QVERIFY(!view->hasFocus());
3359     QVERIFY(!edit->hasFocus());
3360
3361     for (int i = 0; i < 2; ++i) {
3362         // tab to view
3363         QTest::keyPress(qApp->focusWidget(), Qt::Key_Tab);
3364         QTRY_VERIFY(!window.hasFocus());
3365         QVERIFY(view->hasFocus());
3366         QVERIFY(!edit->hasFocus());
3367
3368         // tab to edit
3369         QTest::keyPress(qApp->focusWidget(), Qt::Key_Tab);
3370         QTRY_VERIFY(edit->hasFocus());
3371         QVERIFY(!window.hasFocus());
3372         QVERIFY(!view->hasFocus());
3373     }
3374
3375     // backtab to view
3376     QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
3377     QTRY_VERIFY(view->hasFocus());
3378     QVERIFY(!window.hasFocus());
3379     QVERIFY(!edit->hasFocus());
3380
3381     // backtab to edit
3382     QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
3383     QTRY_VERIFY(edit->hasFocus());
3384     QVERIFY(!window.hasFocus());
3385     QVERIFY(!view->hasFocus());
3386
3387     QStandardItemModel *model = new QStandardItemModel;
3388     view->setModel(model);
3389
3390     // backtab to view
3391     QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
3392     QTRY_VERIFY(view->hasFocus());
3393     QVERIFY(!window.hasFocus());
3394     QVERIFY(!edit->hasFocus());
3395
3396     // backtab to edit
3397     QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
3398     QTRY_VERIFY(edit->hasFocus());
3399     QVERIFY(!window.hasFocus());
3400     QVERIFY(!view->hasFocus());
3401
3402     model->insertRow(0, new QStandardItem("Hei"));
3403     model->insertRow(0, new QStandardItem("Hei"));
3404     model->insertRow(0, new QStandardItem("Hei"));
3405
3406     // backtab to view
3407     QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
3408     QTRY_VERIFY(view->hasFocus());
3409     QVERIFY(!window.hasFocus());
3410     QVERIFY(!edit->hasFocus());
3411
3412     // backtab to edit doesn't work
3413     QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
3414     QVERIFY(!window.hasFocus());
3415     QVERIFY(view->hasFocus());
3416     QVERIFY(!edit->hasFocus());
3417
3418     view->setTabKeyNavigation(false);
3419
3420     // backtab to edit
3421     QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
3422     QTRY_VERIFY(edit->hasFocus());
3423     QVERIFY(!window.hasFocus());
3424     QVERIFY(!view->hasFocus());
3425
3426     QTest::keyPress(qApp->focusWidget(), Qt::Key_Tab);
3427     QTRY_VERIFY(view->hasFocus());
3428     QTest::keyPress(qApp->focusWidget(), Qt::Key_Tab);
3429     QTRY_VERIFY(edit->hasFocus());
3430
3431     delete model;
3432 }
3433
3434 class BigModel : public QAbstractTableModel
3435 {
3436     Q_OBJECT
3437 public:
3438     virtual QVariant data(const QModelIndex &index,
3439                           int role = Qt::DisplayRole) const
3440     {
3441         if (role == Qt::DisplayRole)
3442             return QString("%1 - %2").arg(index.column()).arg(index.row());
3443         return QVariant();
3444     }
3445
3446
3447     int rowCount(const QModelIndex & parent = QModelIndex()) const
3448     {
3449         Q_UNUSED(parent);
3450         return 10000000;
3451     }
3452
3453     int columnCount(const QModelIndex & parent = QModelIndex()) const
3454     {
3455         Q_UNUSED(parent);
3456         return 20000000;
3457     }
3458 };
3459
3460 void tst_QTableView::bigModel()
3461 {
3462     //should not crash
3463     QTableView view;
3464     BigModel model;
3465     view.setModel(&model);
3466     view.show();
3467     view.setSpan(10002,10002,6,6);
3468     QTest::qWait(100);
3469     view.resize(1000,1000);
3470     QTest::qWait(100);
3471     view.scrollTo(model.index(10010,10010));
3472     QTest::qWait(100);
3473 }
3474
3475 void tst_QTableView::selectionSignal()
3476 {
3477     QtTestTableModel model(10, 10);
3478     QtTestTableView view;
3479     view.checkSignalOrder = true;
3480     view.setModel(&model);
3481     view.resize(200, 200);
3482     view.show();
3483     QVERIFY(QTest::qWaitForWindowExposed(&view));
3484     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.visualRect(model.index(2, 0)).center());
3485 }
3486
3487 void tst_QTableView::setCurrentIndex()
3488 {
3489     QtTestTableModel model(4, 4);
3490     QtTestTableView view;
3491     view.setModel(&model);
3492
3493     // submit() slot should be called in model when current row changes
3494     view.setCurrentIndex(model.index(0,0));
3495     QCOMPARE(model.submit_count, 1);
3496     view.setCurrentIndex(model.index(0,2));
3497     QCOMPARE(model.submit_count, 1);
3498     view.setCurrentIndex(model.index(1,0));
3499     QCOMPARE(model.submit_count, 2);
3500     view.setCurrentIndex(model.index(3,3));
3501     QCOMPARE(model.submit_count, 3);
3502     view.setCurrentIndex(model.index(0,1));
3503     QCOMPARE(model.submit_count, 4);
3504     view.setCurrentIndex(model.index(0,0));
3505     QCOMPARE(model.submit_count, 4);
3506 }
3507
3508 class task173773_EventFilter : public QObject
3509 {
3510     int paintEventCount_;
3511 public:
3512     task173773_EventFilter() : paintEventCount_(0) {}
3513     int paintEventCount() const { return paintEventCount_; }
3514 private:
3515     bool eventFilter(QObject *obj, QEvent *e)
3516     {
3517         Q_UNUSED(obj);
3518         if (e->type() == QEvent::Paint)
3519             ++paintEventCount_;
3520         return false;
3521     }
3522 };
3523
3524 void tst_QTableView::task173773_updateVerticalHeader()
3525 {
3526     QStandardItemModel model(2, 1);
3527     model.setData(model.index(0, 0), 0);
3528     model.setData(model.index(1, 0), 1);
3529
3530     QSortFilterProxyModel proxyModel;
3531     proxyModel.setSourceModel(&model);
3532
3533     QTableView view;
3534     view.setModel(&proxyModel);
3535     view.setSortingEnabled(true);
3536     view.show();
3537     QVERIFY(QTest::qWaitForWindowExposed(&view));
3538
3539     view.sortByColumn(0, Qt::AscendingOrder);
3540     QTest::qWait(100);
3541
3542     task173773_EventFilter eventFilter;
3543     view.verticalHeader()->viewport()->installEventFilter(&eventFilter);
3544
3545     view.sortByColumn(0, Qt::DescendingOrder);
3546     QTest::qWait(100);
3547
3548     // ### note: this test may occasionally pass even if the bug is present!
3549     QVERIFY(eventFilter.paintEventCount() > 0);
3550 }
3551
3552 void tst_QTableView::task227953_setRootIndex()
3553 {
3554         QTableView tableView;
3555
3556     //model = tree with two items with tables as children
3557     QStandardItemModel model;
3558     QStandardItem item1, item2;
3559     model.appendColumn(QList<QStandardItem*>() << &item1 << &item2);
3560
3561
3562     //setup the first table as a child of the first item
3563     for ( int row = 0; row < 40; ++row ) {
3564         item1.appendRow(QList<QStandardItem*>() << new QStandardItem(QString("row %0").arg(row)));
3565     }
3566
3567     //setup the second table as a child of the second item
3568     for ( int row = 0; row < 10; ++row ) {
3569         item2.appendRow(QList<QStandardItem*>() << new QStandardItem(QString("row %0").arg(row)));
3570     }
3571
3572     tableView.setModel(&model);
3573
3574     //show the first 10 rows of the first table
3575     QModelIndex root = model.indexFromItem(&item1);
3576         tableView.setRootIndex(root);
3577         for (int i = 10; i != 40; ++i) {
3578                 tableView.setRowHidden(i, true);
3579         }
3580
3581     QCOMPARE(tableView.verticalHeader()->count(), 40);
3582     QCOMPARE(tableView.verticalHeader()->hiddenSectionCount(), 30);
3583
3584         //show the first 10 rows of the second table
3585         tableView.setRootIndex(model.indexFromItem(&item2));
3586
3587     QCOMPARE(tableView.verticalHeader()->count(), 10);
3588     QCOMPARE(tableView.verticalHeader()->hiddenSectionCount(), 0);
3589     QVERIFY(!tableView.verticalHeader()->isHidden());
3590 }
3591
3592 void tst_QTableView::task240266_veryBigColumn()
3593 {
3594     QTableView table;
3595     table.setFixedSize(500, 300); //just to make sure we have the 2 first columns visible
3596     QStandardItemModel model(1, 3);
3597     table.setModel(&model);
3598     table.setColumnWidth(0, 100); //normal column
3599     table.setColumnWidth(1, 100); //normal column
3600     table.setColumnWidth(2, 9000); //very big column
3601     table.show();
3602     QVERIFY(QTest::qWaitForWindowExposed(&table));
3603
3604     //some styles change the scroll mode in their polish
3605     table.setHorizontalScrollMode(QAbstractItemView::ScrollPerItem);
3606     table.setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
3607
3608     QScrollBar *scroll = table.horizontalScrollBar();
3609     QCOMPARE(scroll->minimum(), 0);
3610     QCOMPARE(scroll->maximum(), model.columnCount() - 1);
3611     QCOMPARE(scroll->singleStep(), 1);
3612
3613     //1 is not always a very correct value for pageStep. Ideally this should be dynamic.
3614     //Maybe something for Qt 5 ;-)
3615     QCOMPARE(scroll->pageStep(), 1);
3616
3617 }
3618
3619 void tst_QTableView::task248688_autoScrollNavigation()
3620 {
3621     //we make sure that when navigating with the keyboard the view is correctly scrolled
3622     //to the current item
3623     QStandardItemModel model(16, 16);
3624     QTableView view;
3625     view.setModel(&model);
3626
3627         view.hideColumn(8);
3628         view.hideRow(8);
3629     view.show();
3630     for (int r = 0; r < model.rowCount(); ++r) {
3631         if (view.isRowHidden(r))
3632             continue;
3633         for (int c = 0; c < model.columnCount(); ++c) {
3634             if (view.isColumnHidden(c))
3635                 continue;
3636             QModelIndex index = model.index(r, c);
3637             view.setCurrentIndex(index);
3638             QVERIFY(view.viewport()->rect().contains(view.visualRect(index)));
3639         }
3640     }
3641 }
3642
3643
3644 void tst_QTableView::mouseWheel_data()
3645 {
3646     QTest::addColumn<int>("scrollMode");
3647     QTest::addColumn<int>("delta");
3648     QTest::addColumn<int>("horizontalPositon");
3649     QTest::addColumn<int>("verticalPosition");
3650
3651     QTest::newRow("scroll up per item")
3652             << int(QAbstractItemView::ScrollPerItem) << 120
3653             << 10 - qApp->wheelScrollLines() << 10 - qApp->wheelScrollLines();
3654     QTest::newRow("scroll down per item")
3655             << int(QAbstractItemView::ScrollPerItem) << -120
3656             << 10 + qApp->wheelScrollLines() << 10 + qApp->wheelScrollLines();
3657     QTest::newRow("scroll down per pixel")
3658             << int(QAbstractItemView::ScrollPerPixel) << -120
3659             << 10 + qApp->wheelScrollLines() * 89 << 10 + qApp->wheelScrollLines() * 28;
3660 }
3661
3662 void tst_QTableView::mouseWheel()
3663 {
3664 #ifdef Q_OS_WINCE
3665     QSKIP("Since different Windows CE versions sport different taskbars, we skip this test");
3666 #endif
3667
3668     QFETCH(int, scrollMode);
3669     QFETCH(int, delta);
3670     QFETCH(int, horizontalPositon);
3671     QFETCH(int, verticalPosition);
3672
3673     QtTestTableModel model(100, 100);
3674     QWidget topLevel;
3675     QtTestTableView view(&topLevel);
3676     view.resize(500, 500);
3677     for (int r = 0; r < 100; ++r)
3678         view.setRowHeight(r, 50);
3679     for (int c = 0; c < 100; ++c)
3680         view.setColumnWidth(c, 100);
3681     topLevel.show();
3682
3683     QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
3684
3685     view.setModel(&model);
3686
3687     view.setHorizontalScrollMode((QAbstractItemView::ScrollMode)scrollMode);
3688     view.setVerticalScrollMode((QAbstractItemView::ScrollMode)scrollMode);
3689     view.horizontalScrollBar()->setValue(10);
3690     view.verticalScrollBar()->setValue(10);
3691
3692     QPoint pos = view.viewport()->geometry().center();
3693     QWheelEvent verticalEvent(pos, delta, 0, 0, Qt::Vertical);
3694     QWheelEvent horizontalEvent(pos, delta, 0, 0, Qt::Horizontal);
3695     QApplication::sendEvent(view.viewport(), &horizontalEvent);
3696     QVERIFY(qAbs(view.horizontalScrollBar()->value() - horizontalPositon) < 10);
3697     QApplication::sendEvent(view.viewport(), &verticalEvent);
3698     QVERIFY(qAbs(view.verticalScrollBar()->value() - verticalPosition) < 10);
3699 }
3700
3701 void tst_QTableView::addColumnWhileEditing()
3702 {
3703     QTableView view;
3704     QStandardItemModel model(1, 10);
3705     view.setModel(&model);
3706     QModelIndex last = model.index(0,9);
3707     view.show();
3708
3709     view.openPersistentEditor(last);
3710     view.scrollTo(last);
3711
3712     //let's see if the editor is moved to the right location
3713     //after adding a column
3714     model.setColumnCount(model.columnCount() + 1);
3715     QPointer<QLineEdit> editor = qFindChild<QLineEdit*>(&view);
3716     QVERIFY(editor);
3717     QCOMPARE(editor->geometry(), view.visualRect(last));
3718
3719     //let's see if the editor is moved to the right location
3720     //after removing a column
3721     view.scrollTo(model.index(0, model.columnCount()-1));
3722     model.setColumnCount(model.columnCount() - 1);
3723     QVERIFY(editor);
3724     QCOMPARE(editor->geometry(), view.visualRect(last));
3725 }
3726
3727 void tst_QTableView::task259308_scrollVerticalHeaderSwappedSections()
3728 {
3729     QStandardItemModel model;
3730     model.setRowCount(50);
3731     model.setColumnCount(2);
3732     for (int row = 0; row < model.rowCount(); ++row)
3733         for (int col = 0; col < model.columnCount(); ++col) {
3734             const QModelIndex &idx = model.index(row, col);
3735             model.setData(idx, QVariant(row), Qt::EditRole);
3736         }
3737
3738     QTableView tv;
3739     tv.setModel(&model);
3740     tv.show();
3741     tv.verticalHeader()->swapSections(0, model.rowCount() - 1);
3742     tv.setCurrentIndex(model.index(model.rowCount() - 1, 0));
3743
3744     QVERIFY(QTest::qWaitForWindowExposed(&tv));
3745     QTest::keyClick(&tv, Qt::Key_PageUp);   // PageUp won't scroll when at top
3746     QTRY_COMPARE(tv.rowAt(0), tv.verticalHeader()->logicalIndex(0));
3747
3748     int newRow = tv.rowAt(tv.viewport()->height());
3749     if (newRow == tv.rowAt(tv.viewport()->height() - 1)) // Overlapping row
3750         newRow++;
3751     QTest::keyClick(&tv, Qt::Key_PageDown); // Scroll down and check current
3752     QTRY_COMPARE(tv.currentIndex().row(), newRow);
3753
3754     tv.setCurrentIndex(model.index(0, 0));
3755     QTest::qWait(60);
3756     QTest::keyClick(&tv, Qt::Key_PageDown); // PageDown won't scroll when at the bottom
3757     QTRY_COMPARE(tv.rowAt(tv.viewport()->height() - 1), tv.verticalHeader()->logicalIndex(model.rowCount() - 1));
3758 }
3759
3760 template <typename T>
3761 struct ValueSaver {
3762     T &var, value;
3763     ValueSaver(T &v) : var(v), value(v) { }
3764     ~ValueSaver() { var = value; }
3765 };
3766
3767 void tst_QTableView::task191545_dragSelectRows()
3768 {
3769     QStandardItemModel model(10, 10);
3770     QTableView table;
3771     table.setModel(&model);
3772     table.setSelectionBehavior(QAbstractItemView::SelectItems);
3773     table.setSelectionMode(QAbstractItemView::ExtendedSelection);
3774     table.setMinimumSize(1000, 400);
3775     table.show();
3776     QTest::qWait(200);
3777
3778     ValueSaver<Qt::KeyboardModifiers> saver(QApplicationPrivate::modifier_buttons);
3779     QApplicationPrivate::modifier_buttons = Qt::ControlModifier;
3780
3781     {
3782         QRect cellRect = table.visualRect(model.index(3, 0));
3783         QHeaderView *vHeader = table.verticalHeader();
3784         QWidget *vHeaderVp = vHeader->viewport();
3785         QPoint rowPos(cellRect.center());
3786         QMouseEvent rowPressEvent(QEvent::MouseButtonPress, rowPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
3787         qApp->sendEvent(vHeaderVp, &rowPressEvent);
3788
3789         for (int i = 0; i < 4; ++i) {
3790             rowPos.setY(rowPos.y() + cellRect.height());
3791             QMouseEvent moveEvent(QEvent::MouseMove, rowPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
3792             qApp->sendEvent(vHeaderVp, &moveEvent);
3793         }
3794         QMouseEvent rowReleaseEvent(QEvent::MouseButtonRelease, rowPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
3795         qApp->sendEvent(vHeaderVp, &rowReleaseEvent);
3796
3797         for (int i = 0; i < 4; ++i) {
3798             QModelIndex index = model.index(3 + i, 0, table.rootIndex());
3799             QVERIFY(vHeader->selectionModel()->selectedRows().contains(index));
3800         }
3801     }
3802
3803     {
3804         QRect cellRect = table.visualRect(model.index(0, 3));
3805         QHeaderView *hHeader = table.horizontalHeader();
3806         QWidget *hHeaderVp = hHeader->viewport();
3807         QPoint colPos((cellRect.left() + cellRect.right()) / 2, 5);
3808         QMouseEvent colPressEvent(QEvent::MouseButtonPress, colPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
3809         qApp->sendEvent(hHeaderVp, &colPressEvent);
3810
3811         for (int i = 0; i < 4; ++i) {
3812             colPos.setX(colPos.x() + cellRect.width());
3813             QMouseEvent moveEvent(QEvent::MouseMove, colPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
3814             qApp->sendEvent(hHeaderVp, &moveEvent);
3815         }
3816         QMouseEvent colReleaseEvent(QEvent::MouseButtonRelease, colPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
3817         qApp->sendEvent(hHeaderVp, &colReleaseEvent);
3818
3819         for (int i = 0; i < 4; ++i) {
3820             QModelIndex index = model.index(0, 3 + i, table.rootIndex());
3821             QVERIFY(hHeader->selectionModel()->selectedColumns().contains(index));
3822         }
3823     }
3824
3825     {
3826         QRect cellRect = table.visualRect(model.index(2, 2));
3827         QWidget *tableVp = table.viewport();
3828         QPoint cellPos = cellRect.center();
3829         QMouseEvent cellPressEvent(QEvent::MouseButtonPress, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
3830         qApp->sendEvent(tableVp, &cellPressEvent);
3831
3832         for (int i = 0; i < 6; ++i) {
3833             cellPos.setX(cellPos.x() + cellRect.width());
3834             cellPos.setY(cellPos.y() + cellRect.height());
3835             QMouseEvent moveEvent(QEvent::MouseMove, cellPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
3836             qApp->sendEvent(tableVp, &moveEvent);
3837         }
3838         QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
3839         qApp->sendEvent(tableVp, &cellReleaseEvent);
3840
3841         for (int i = 0; i < 6; ++i)
3842             for (int j = 0; j < 6; ++j) {
3843                 QModelIndex index = model.index(2 + i, 2 + j, table.rootIndex());
3844                 QVERIFY(table.selectionModel()->isSelected(index));
3845             }
3846     }
3847
3848     {
3849         QRect cellRect = table.visualRect(model.index(3, 3));
3850         QWidget *tableVp = table.viewport();
3851         QPoint cellPos = cellRect.center();
3852         QMouseEvent cellPressEvent(QEvent::MouseButtonPress, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
3853         qApp->sendEvent(tableVp, &cellPressEvent);
3854
3855         for (int i = 0; i < 6; ++i) {
3856             cellPos.setX(cellPos.x() + cellRect.width());
3857             cellPos.setY(cellPos.y() + cellRect.height());
3858             QMouseEvent moveEvent(QEvent::MouseMove, cellPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
3859             qApp->sendEvent(tableVp, &moveEvent);
3860         }
3861         QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
3862         qApp->sendEvent(tableVp, &cellReleaseEvent);
3863
3864         QTest::qWait(200);
3865         for (int i = 0; i < 6; ++i)
3866             for (int j = 0; j < 6; ++j) {
3867                 QModelIndex index = model.index(3 + i, 3 + j, table.rootIndex());
3868                 QVERIFY(!table.selectionModel()->isSelected(index));
3869             }
3870     }
3871 }
3872
3873 void tst_QTableView::task234926_setHeaderSorting()
3874 {
3875     QStringListModel model;
3876     QStringList data;
3877     data << "orange" << "apple" << "banana" << "lemon" << "pumpkin";
3878     QStringList sortedDataA = data;
3879     QStringList sortedDataD = data;
3880     qSort(sortedDataA);
3881     qSort(sortedDataD.begin(), sortedDataD.end(), qGreater<QString>());
3882     model.setStringList(data);
3883     QTableView view;
3884     view.setModel(&model);
3885 //    view.show();
3886     QTest::qWait(20);
3887     QCOMPARE(model.stringList(), data);
3888     view.setSortingEnabled(true);
3889     view.sortByColumn(0, Qt::AscendingOrder);
3890     QApplication::processEvents();
3891     QCOMPARE(model.stringList() , sortedDataA);
3892
3893     view.horizontalHeader()->setSortIndicator(0, Qt::DescendingOrder);
3894     QApplication::processEvents();
3895     QCOMPARE(model.stringList() , sortedDataD);
3896
3897     QHeaderView *h = new QHeaderView(Qt::Horizontal);
3898     h->setModel(&model);
3899     view.setHorizontalHeader(h);
3900     h->setSortIndicator(0, Qt::AscendingOrder);
3901     QApplication::processEvents();
3902     QCOMPARE(model.stringList() , sortedDataA);
3903
3904     h->setSortIndicator(0, Qt::DescendingOrder);
3905     QApplication::processEvents();
3906     QCOMPARE(model.stringList() , sortedDataD);
3907 }
3908
3909 void tst_QTableView::taskQTBUG_5062_spansInconsistency()
3910 {
3911     const int nRows = 5;
3912     const int nColumns = 5;
3913
3914     QtTestTableModel model(nRows, nColumns);
3915     QtTestTableView view;
3916     view.setModel(&model);
3917
3918     for (int i = 0; i < nRows; ++i)
3919        view.setSpan(i, 0, 1, nColumns);
3920     view.setSpan(2, 0, 1, 1);
3921     view.setSpan(3, 0, 1, 1);
3922
3923     VERIFY_SPANS_CONSISTENCY(&view);
3924 }
3925
3926 void tst_QTableView::taskQTBUG_4516_clickOnRichTextLabel()
3927 {
3928     QTableView view;
3929     QStandardItemModel model(5,5);
3930     view.setModel(&model);
3931     QLabel label("rich text");
3932     label.setTextFormat(Qt::RichText);
3933     view.setIndexWidget(model.index(1,1), &label);
3934     view.setCurrentIndex(model.index(0,0));
3935     QCOMPARE(view.currentIndex(), model.index(0,0));
3936
3937     QTest::mouseClick(&label, Qt::LeftButton);
3938     QCOMPARE(view.currentIndex(), model.index(1,1));
3939
3940
3941 }
3942
3943
3944 void tst_QTableView::changeHeaderData()
3945 {
3946     QTableView view;
3947     QStandardItemModel model(5,5);
3948     view.setModel(&model);
3949     view.show();
3950     QVERIFY(QTest::qWaitForWindowExposed(&view));
3951
3952     QString text = "long long long text";
3953     const int textWidth = view.verticalHeader()->fontMetrics().width(text);
3954     QVERIFY(view.verticalHeader()->width() < textWidth);
3955
3956     model.setHeaderData(2, Qt::Vertical, text);
3957     QTest::qWait(100); //leave time for layout
3958
3959     QVERIFY(view.verticalHeader()->width() > textWidth);
3960 }
3961
3962 void tst_QTableView::taskQTBUG_5237_wheelEventOnHeader()
3963 {
3964     QTableView view;
3965     QStandardItemModel model(500,5);
3966     view.setModel(&model);
3967     view.show();
3968     QVERIFY(QTest::qWaitForWindowExposed(&view));
3969
3970     int sbValueBefore = view.verticalScrollBar()->value();
3971     QHeaderView *header = view.verticalHeader();
3972     QTest::mouseMove(header);
3973     QWheelEvent wheelEvent(header->geometry().center(), -720, 0, 0);
3974     QApplication::sendEvent(header->viewport(), &wheelEvent);
3975     int sbValueAfter = view.verticalScrollBar()->value();
3976     QVERIFY(sbValueBefore != sbValueAfter);
3977 }
3978
3979 class TestTableView : public QTableView {
3980 Q_OBJECT
3981 public:
3982     TestTableView(QWidget *parent = 0) : QTableView(parent)
3983     {
3984         connect(this, SIGNAL(entered(const QModelIndex&)), this, SLOT(openEditor(const QModelIndex&)));
3985     }
3986     ~TestTableView(){}
3987 public slots:
3988     void onDataChanged()
3989     {
3990         for (int i = 0; i < model()->rowCount(); i++) {
3991             setRowHidden(i, model()->data(model()->index(i, 0)).toBool());
3992         }
3993     }
3994
3995     void openEditor(const QModelIndex& index)
3996     { openPersistentEditor(index); }
3997 };
3998
3999
4000 void tst_QTableView::taskQTBUG_8585_crashForNoGoodReason()
4001 {
4002     QStandardItemModel model;
4003     model.insertColumn(0, QModelIndex());
4004     for(int i = 0; i < 20; i++)
4005     {
4006         model.insertRow(i);
4007     }
4008
4009     TestTableView w;
4010     w.setMouseTracking(true);
4011     w.setModel(&model);
4012     connect(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), &w, SLOT(onDataChanged()));
4013     w.show();
4014     QVERIFY(QTest::qWaitForWindowExposed(&w));
4015     for (int i = 0; i < 10; i++)
4016     {
4017         QTest::mouseMove(w.viewport(), QPoint(50, 20));
4018         w.model()->setData(w.indexAt(QPoint(50, 20)), true);
4019         QTest::mouseMove(w.viewport(), QPoint(50, 25));
4020     }
4021 }
4022
4023 class TableView7774 : public QTableView
4024 {
4025 public:
4026     QRegion visualRegionForSelection(const QItemSelection &selection) const
4027     {
4028         return QTableView::visualRegionForSelection(selection);
4029     }
4030 };
4031
4032 void tst_QTableView::taskQTBUG_7774_RtoLVisualRegionForSelection()
4033 {
4034     TableView7774 view;
4035     QStandardItemModel model(5,5);
4036     view.setModel(&model);
4037     view.setLayoutDirection(Qt::RightToLeft);
4038     view.show();
4039     QVERIFY(QTest::qWaitForWindowExposed(&view));
4040
4041     QItemSelectionRange range(model.index(2, 0), model.index(2, model.columnCount() - 1));
4042     QItemSelection selection;
4043     selection << range;
4044     QRegion region = view.visualRegionForSelection(selection);
4045     QCOMPARE(region.rects().at(0), view.visualRect(range.topLeft()) | view.visualRect(range.bottomRight()));
4046 }
4047
4048 void tst_QTableView::taskQTBUG_8777_scrollToSpans()
4049 {
4050     QTableWidget table(75,5);
4051     for (int i=0; i<50; i++)
4052         table.setSpan(2+i, 0, 1, 5);
4053     table.setCurrentCell(0,2);
4054     table.show();
4055
4056     for (int i = 0; i < 45; ++i)
4057         QTest::keyClick(&table, Qt::Key_Down);
4058
4059     QVERIFY(table.verticalScrollBar()->value() > 10);
4060 }
4061
4062 void tst_QTableView::taskQTBUG_10169_sizeHintForRow()
4063
4064     QtTestTableView tableView; 
4065     QStandardItemModel model(1, 3); 
4066     model.setData(model.index(0, 0), "Word wrapping text goes here.");
4067     tableView.setModel(&model);
4068     tableView.verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
4069     const int orderedHeight = tableView.sizeHintForRow(0);
4070     tableView.horizontalHeader()->moveSection(2, 0);
4071     const int reorderedHeight = tableView.sizeHintForRow(0);
4072
4073     //the order of the columns shouldn't matter.
4074     QCOMPARE(orderedHeight, reorderedHeight);
4075 }
4076
4077 QTEST_MAIN(tst_QTableView)
4078 #include "tst_qtableview.moc"