Remove usage of deprecated qWaitForWindowShown(QWidget *) method.
[profile/ivi/qtbase.git] / tests / auto / widgets / itemviews / qheaderview / tst_qheaderview.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 **
39 ** $QT_END_LICENSE$
40 **
41 ****************************************************************************/
42
43
44 #include <QtTest/QtTest>
45 #include <QStandardItemModel>
46 #include <QStringListModel>
47 #include <QSortFilterProxyModel>
48 #include <QTableView>
49
50 #include <qabstractitemmodel.h>
51 #include <qapplication.h>
52 #include <qheaderview.h>
53 #include <private/qheaderview_p.h>
54 #include <qitemdelegate.h>
55 #include <qtreewidget.h>
56 #include <qdebug.h>
57
58 typedef QList<int> IntList;
59 Q_DECLARE_METATYPE(IntList)
60
61 typedef QList<bool> BoolList;
62 Q_DECLARE_METATYPE(BoolList)
63
64 class protected_QHeaderView : public QHeaderView
65 {
66     Q_OBJECT
67 public:
68     protected_QHeaderView(Qt::Orientation orientation) : QHeaderView(orientation) {
69         resizeSections();
70     };
71
72     void testEvent();
73     void testhorizontalOffset();
74     void testverticalOffset();
75     friend class tst_QHeaderView;
76 };
77
78 class XResetModel : public QStandardItemModel
79 {
80     virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex())
81     {
82         blockSignals(true);
83         bool r = QStandardItemModel::removeRows(row, count, parent);
84         blockSignals(false);
85         emit reset();
86         return r;
87     }
88     virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex())
89     {
90         blockSignals(true);
91         bool r = QStandardItemModel::insertRows(row, count, parent);
92         blockSignals(false);
93         emit reset();
94         return r;
95     }
96 };
97
98 class tst_QHeaderView : public QObject
99 {
100     Q_OBJECT
101
102 public:
103     tst_QHeaderView();
104     virtual ~tst_QHeaderView();
105
106 public slots:
107     void initTestCase();
108     void cleanupTestCase();
109     void init();
110     void cleanup();
111
112 private slots:
113     void getSetCheck();
114     void visualIndex();
115
116     void visualIndexAt_data();
117     void visualIndexAt();
118
119     void noModel();
120     void emptyModel();
121     void removeRows();
122     void removeCols();
123
124     void clickable();
125     void movable();
126     void hidden();
127     void stretch();
128
129     void sectionSize_data();
130     void sectionSize();
131
132     void length();
133     void offset();
134     void sectionSizeHint();
135     void logicalIndex();
136     void logicalIndexAt();
137     void swapSections();
138
139     void moveSection_data();
140     void moveSection();
141
142     void resizeMode();
143
144     void resizeSection_data();
145     void resizeSection();
146
147     void resizeAndMoveSection_data();
148     void resizeAndMoveSection();
149     void resizeHiddenSection_data();
150     void resizeHiddenSection();
151     void resizeAndInsertSection_data();
152     void resizeAndInsertSection();
153     void resizeWithResizeModes_data();
154     void resizeWithResizeModes();
155     void moveAndInsertSection_data();
156     void moveAndInsertSection();
157     void highlightSections();
158     void showSortIndicator();
159     void sortIndicatorTracking();
160     void removeAndInsertRow();
161     void unhideSection();
162     void event();
163     void headerDataChanged();
164     void currentChanged();
165     void horizontalOffset();
166     void verticalOffset();
167     void stretchSectionCount();
168     void hiddenSectionCount();
169     void focusPolicy();
170     void moveSectionAndReset();
171     void moveSectionAndRemove();
172     void saveRestore();
173     void defaultSectionSizeTest();
174
175     void defaultAlignment_data();
176     void defaultAlignment();
177
178     void globalResizeMode_data();
179     void globalResizeMode();
180
181     void sectionPressedSignal_data();
182     void sectionPressedSignal();
183     void sectionClickedSignal_data() { sectionPressedSignal_data(); }
184     void sectionClickedSignal();
185
186     void defaultSectionSize_data();
187     void defaultSectionSize();
188
189     void oneSectionSize();
190
191     void hideAndInsert_data();
192     void hideAndInsert();
193
194     void removeSection();
195     void preserveHiddenSectionWidth();
196     void invisibleStretchLastSection();
197     void noSectionsWithNegativeSize();
198
199     void emptySectionSpan();
200     void task236450_hidden_data();
201     void task236450_hidden();
202     void task248050_hideRow();
203     void QTBUG6058_reset();
204     void QTBUG7833_sectionClicked();
205     void QTBUG8650_crashOnInsertSections();
206     void QTBUG12268_hiddenMovedSectionSorting();
207     void QTBUG14242_hideSectionAutoSize();
208     void ensureNoIndexAtLength();
209     void offsetConsistent();
210
211     void initialSortOrderRole();
212
213     void logicalIndexAtTest_data()   { setupTestData(); }
214     void visualIndexAtTest_data()    { setupTestData(); }
215     void hideShowTest_data()         { setupTestData(); }
216     void swapSectionsTest_data()     { setupTestData(); }
217     void moveSectionTest_data()      { setupTestData(); }
218     void defaultSizeTest_data()      { setupTestData(); }
219     void removeTest_data()           { setupTestData(true); }
220     void insertTest_data()           { setupTestData(true); }
221     void mixedTests_data()           { setupTestData(true); }
222     void resizeToContentTest_data()  { setupTestData(); }
223     void logicalIndexAtTest();
224     void visualIndexAtTest();
225     void hideShowTest();
226     void swapSectionsTest();
227     void moveSectionTest();
228     void defaultSizeTest();
229     void removeTest();
230     void insertTest();
231     void mixedTests();
232     void resizeToContentTest();
233     void testStreamWithHide();
234
235 protected:
236     void setupTestData(bool use_reset_model = false);
237     void additionalInit();
238     void calculateAndCheck(int cppline, const int precalced_comparedata[]);
239
240     QWidget *topLevel;
241     QHeaderView *view;
242     QStandardItemModel *model;
243     QTableView *m_tableview;
244     bool m_using_reset_model;
245     QElapsedTimer timer;
246 };
247
248 class QtTestModel: public QAbstractTableModel
249 {
250
251 Q_OBJECT
252
253 public:
254     QtTestModel(QObject *parent = 0): QAbstractTableModel(parent),
255        cols(0), rows(0), wrongIndex(false) {}
256     int rowCount(const QModelIndex&) const { return rows; }
257     int columnCount(const QModelIndex&) const { return cols; }
258     bool isEditable(const QModelIndex &) const { return true; }
259
260     QVariant data(const QModelIndex &idx, int) const
261     {
262         if (idx.row() < 0 || idx.column() < 0 || idx.column() >= cols || idx.row() >= rows) {
263             wrongIndex = true;
264             qWarning("Invalid modelIndex [%d,%d,%p]", idx.row(), idx.column(), idx.internalPointer());
265         }
266         return QString("[%1,%2,%3]").arg(idx.row()).arg(idx.column()).arg(0);//idx.data());
267     }
268
269     void insertOneColumn(int col)
270     {
271         beginInsertColumns(QModelIndex(), col, col);
272         --cols;
273         endInsertColumns();
274     }
275
276     void removeLastRow()
277     {
278         beginRemoveRows(QModelIndex(), rows - 1, rows - 1);
279         --rows;
280         endRemoveRows();
281     }
282
283     void removeAllRows()
284     {
285         beginRemoveRows(QModelIndex(), 0, rows - 1);
286         rows = 0;
287         endRemoveRows();
288     }
289
290     void removeOneColumn(int col)
291     {
292         beginRemoveColumns(QModelIndex(), col, col);
293         --cols;
294         endRemoveColumns();
295     }
296
297     void removeLastColumn()
298     {
299         beginRemoveColumns(QModelIndex(), cols - 1, cols - 1);
300         --cols;
301         endRemoveColumns();
302     }
303
304     void removeAllColumns()
305     {
306         beginRemoveColumns(QModelIndex(), 0, cols - 1);
307         cols = 0;
308         endRemoveColumns();
309     }
310
311     void cleanup()
312     {
313         cols = 3;
314         rows = 3;
315         emit layoutChanged();
316     }
317
318     int cols, rows;
319     mutable bool wrongIndex;
320 };
321
322 // Testing get/set functions
323 void tst_QHeaderView::getSetCheck()
324 {
325     protected_QHeaderView obj1(Qt::Horizontal);
326     // bool QHeaderView::highlightSections()
327     // void QHeaderView::setHighlightSections(bool)
328     obj1.setHighlightSections(false);
329     QCOMPARE(false, obj1.highlightSections());
330     obj1.setHighlightSections(true);
331     QCOMPARE(true, obj1.highlightSections());
332
333     // bool QHeaderView::stretchLastSection()
334     // void QHeaderView::setStretchLastSection(bool)
335     obj1.setStretchLastSection(false);
336     QCOMPARE(false, obj1.stretchLastSection());
337     obj1.setStretchLastSection(true);
338     QCOMPARE(true, obj1.stretchLastSection());
339
340     // int QHeaderView::defaultSectionSize()
341     // void QHeaderView::setDefaultSectionSize(int)
342     obj1.setDefaultSectionSize(-1);
343     QVERIFY(obj1.defaultSectionSize() >= 0);
344     obj1.setDefaultSectionSize(0);
345     QCOMPARE(0, obj1.defaultSectionSize());
346     obj1.setDefaultSectionSize(INT_MAX);
347     QCOMPARE(INT_MAX, obj1.defaultSectionSize());
348
349     // int QHeaderView::minimumSectionSize()
350     // void QHeaderView::setMinimumSectionSize(int)
351     obj1.setMinimumSectionSize(-1);
352     QVERIFY(obj1.minimumSectionSize() >= 0);
353     obj1.setMinimumSectionSize(0);
354     QCOMPARE(0, obj1.minimumSectionSize());
355     obj1.setMinimumSectionSize(INT_MAX);
356     QCOMPARE(INT_MAX, obj1.minimumSectionSize());
357
358     // int QHeaderView::offset()
359     // void QHeaderView::setOffset(int)
360     obj1.setOffset(0);
361     QCOMPARE(0, obj1.offset());
362     obj1.setOffset(INT_MIN);
363     QCOMPARE(INT_MIN, obj1.offset());
364     obj1.setOffset(INT_MAX);
365     QCOMPARE(INT_MAX, obj1.offset());
366
367 }
368
369 tst_QHeaderView::tst_QHeaderView()
370 {
371     qRegisterMetaType<int>("Qt::SortOrder");
372 }
373
374 tst_QHeaderView::~tst_QHeaderView()
375 {
376 }
377
378 void tst_QHeaderView::initTestCase()
379 {
380 #ifdef Q_OS_WINCE //disable magic for WindowsCE
381     qApp->setAutoMaximizeThreshold(-1);
382 #endif
383     m_tableview = new QTableView();
384 }
385
386 void tst_QHeaderView::cleanupTestCase()
387 {
388     delete m_tableview;
389 }
390
391 void tst_QHeaderView::init()
392 {
393     topLevel = new QWidget();
394     view = new QHeaderView(Qt::Vertical,topLevel);
395     // Some initial value tests before a model is added
396     QCOMPARE(view->length(), 0);
397     QVERIFY(view->sizeHint() == QSize(0,0));
398     QCOMPARE(view->sectionSizeHint(0), -1);
399
400     /*
401     model = new QStandardItemModel(1, 1);
402     view->setModel(model);
403     //qDebug() << view->count();
404     view->sizeHint();
405     */
406
407     int rows = 4;
408     int columns = 4;
409     model = new QStandardItemModel(rows, columns);
410     /*
411     for (int row = 0; row < rows; ++row) {
412         for (int column = 0; column < columns; ++column) {
413             QModelIndex index = model->index(row, column, QModelIndex());
414             model->setData(index, QVariant((row+1) * (column+1)));
415         }
416     }
417     */
418
419     QSignalSpy spy(view, SIGNAL(sectionCountChanged(int, int)));
420     view->setModel(model);
421     QCOMPARE(spy.count(), 1);
422     view->resize(200,200);
423     topLevel->show();
424 }
425
426 void tst_QHeaderView::cleanup()
427 {
428     m_tableview->setUpdatesEnabled(true);
429     if (view && view->parent() != m_tableview)
430         delete view;
431     view = 0;
432     delete model;
433     model = 0;
434 }
435
436 void tst_QHeaderView::noModel()
437 {
438     QHeaderView emptyView(Qt::Vertical);
439     QCOMPARE(emptyView.count(), 0);
440 }
441
442 void tst_QHeaderView::emptyModel()
443 {
444     QtTestModel testmodel;
445     view->setModel(&testmodel);
446     QVERIFY(!testmodel.wrongIndex);
447     QCOMPARE(view->count(), testmodel.rows);
448     view->setModel(model);
449 }
450
451 void tst_QHeaderView::removeRows()
452 {
453     QtTestModel model;
454     model.rows = model.cols = 10;
455
456     QHeaderView vertical(Qt::Vertical);
457     QHeaderView horizontal(Qt::Horizontal);
458
459     vertical.setModel(&model);
460     horizontal.setModel(&model);
461     vertical.show();
462     horizontal.show();
463     QCOMPARE(vertical.count(), model.rows);
464     QCOMPARE(horizontal.count(), model.cols);
465
466     model.removeLastRow();
467     QVERIFY(!model.wrongIndex);
468     QCOMPARE(vertical.count(), model.rows);
469     QCOMPARE(horizontal.count(), model.cols);
470
471     model.removeAllRows();
472     QVERIFY(!model.wrongIndex);
473     QCOMPARE(vertical.count(), model.rows);
474     QCOMPARE(horizontal.count(), model.cols);
475 }
476
477
478 void tst_QHeaderView::removeCols()
479 {
480     QtTestModel model;
481     model.rows = model.cols = 10;
482
483     QHeaderView vertical(Qt::Vertical);
484     QHeaderView horizontal(Qt::Horizontal);
485     vertical.setModel(&model);
486     horizontal.setModel(&model);
487     vertical.show();
488     horizontal.show();
489     QCOMPARE(vertical.count(), model.rows);
490     QCOMPARE(horizontal.count(), model.cols);
491
492     model.removeLastColumn();
493     QVERIFY(!model.wrongIndex);
494     QCOMPARE(vertical.count(), model.rows);
495     QCOMPARE(horizontal.count(), model.cols);
496
497     model.removeAllColumns();
498     QVERIFY(!model.wrongIndex);
499     QCOMPARE(vertical.count(), model.rows);
500     QCOMPARE(horizontal.count(), model.cols);
501 }
502
503 void tst_QHeaderView::movable()
504 {
505     QCOMPARE(view->sectionsMovable(), false);
506     view->setSectionsMovable(false);
507     QCOMPARE(view->sectionsMovable(), false);
508     view->setSectionsMovable(true);
509     QCOMPARE(view->sectionsMovable(), true);
510 }
511
512 void tst_QHeaderView::clickable()
513 {
514     QCOMPARE(view->sectionsClickable(), false);
515     view->setSectionsClickable(false);
516     QCOMPARE(view->sectionsClickable(), false);
517     view->setSectionsClickable(true);
518     QCOMPARE(view->sectionsClickable(), true);
519 }
520
521 void tst_QHeaderView::hidden()
522 {
523     //hideSection() & showSection call setSectionHidden
524     // Test bad arguments
525     QCOMPARE(view->isSectionHidden(-1), false);
526     QCOMPARE(view->isSectionHidden(view->count()), false);
527     QCOMPARE(view->isSectionHidden(999999), false);
528
529     view->setSectionHidden(-1, true);
530     view->setSectionHidden(view->count(), true);
531     view->setSectionHidden(999999, true);
532     view->setSectionHidden(-1, false);
533     view->setSectionHidden(view->count(), false);
534     view->setSectionHidden(999999, false);
535
536     // Hidden sections shouldn't have visual properties (except position)
537     int pos = view->defaultSectionSize();
538     view->setSectionHidden(1, true);
539     QCOMPARE(view->sectionSize(1), 0);
540     QCOMPARE(view->sectionPosition(1), pos);
541     view->resizeSection(1, 100);
542     QCOMPARE(view->sectionViewportPosition(1), pos);
543     QCOMPARE(view->sectionSize(1), 0);
544     view->setSectionHidden(1, false);
545     QCOMPARE(view->isSectionHidden(0), false);
546     QCOMPARE(view->sectionSize(0), view->defaultSectionSize());
547 }
548
549 void tst_QHeaderView::stretch()
550 {
551     // Show before resize and setStrechLastSection
552 #if defined(Q_OS_WINCE)
553     QSize viewSize(200,300);
554 #else
555     QSize viewSize(500, 500);
556 #endif
557     view->resize(viewSize);
558     view->setStretchLastSection(true);
559     QCOMPARE(view->stretchLastSection(), true);
560     topLevel->show();
561     QCOMPARE(view->width(), viewSize.width());
562     QCOMPARE(view->visualIndexAt(view->viewport()->height() - 5), 3);
563
564     view->setSectionHidden(3, true);
565     QCOMPARE(view->visualIndexAt(view->viewport()->height() - 5), 2);
566
567     view->setStretchLastSection(false);
568     QCOMPARE(view->stretchLastSection(), false);
569 }
570
571 void tst_QHeaderView::oneSectionSize()
572 {
573     //this ensures that if there is only one section, it gets a correct width (more than 0)
574     QHeaderView view (Qt::Vertical);
575     QtTestModel model;
576     model.cols = 1;
577     model.rows = 1;
578
579     view.setSectionResizeMode(QHeaderView::Interactive);
580     view.setModel(&model);
581
582     view.show();
583
584     QVERIFY(view.sectionSize(0) > 0);
585 }
586
587
588 void tst_QHeaderView::sectionSize_data()
589 {
590     QTest::addColumn<QList<int> >("boundsCheck");
591     QTest::addColumn<QList<int> >("defaultSizes");
592     QTest::addColumn<int>("initialDefaultSize");
593     QTest::addColumn<int>("lastVisibleSectionSize");
594     QTest::addColumn<int>("persistentSectionSize");
595
596     QTest::newRow("data set one")
597         << (QList<int>() << -1 << 0 << 4 << 9999)
598         << (QList<int>() << 10 << 30 << 30)
599         << 30
600         << 300
601         << 20;
602 }
603
604 void tst_QHeaderView::sectionSize()
605 {
606     QFETCH(QList<int>, boundsCheck);
607     QFETCH(QList<int>, defaultSizes);
608     QFETCH(int, initialDefaultSize);
609     QFETCH(int, lastVisibleSectionSize);
610     QFETCH(int, persistentSectionSize);
611
612 #ifdef Q_OS_WINCE
613     // We test on a device with doubled pixels. Therefore we need to specify
614     // different boundaries.
615     initialDefaultSize = qMax(view->minimumSectionSize(), 30);
616 #endif
617
618     // bounds check
619     foreach (int val, boundsCheck)
620         view->sectionSize(val);
621
622     // default size
623     QCOMPARE(view->defaultSectionSize(), initialDefaultSize);
624     foreach (int def, defaultSizes) {
625         view->setDefaultSectionSize(def);
626         QCOMPARE(view->defaultSectionSize(), def);
627     }
628
629     view->setDefaultSectionSize(initialDefaultSize);
630     for (int s = 0; s < view->count(); ++s)
631         QCOMPARE(view->sectionSize(s), initialDefaultSize);
632     view->doItemsLayout();
633
634     // stretch last section
635     view->setStretchLastSection(true);
636     int lastSection = view->count() - 1;
637
638     //test that when hiding the last column,
639     //resizing the new last visible columns still works
640     view->hideSection(lastSection);
641     view->resizeSection(lastSection - 1, lastVisibleSectionSize);
642     QCOMPARE(view->sectionSize(lastSection - 1), lastVisibleSectionSize);
643     view->showSection(lastSection);
644
645     // turn off stretching
646     view->setStretchLastSection(false);
647     QCOMPARE(view->sectionSize(lastSection), initialDefaultSize);
648
649     // test persistence
650     int sectionCount = view->count();
651     for (int i = 0; i < sectionCount; ++i)
652         view->resizeSection(i, persistentSectionSize);
653     QtTestModel model;
654     model.cols = sectionCount * 2;
655     model.rows = sectionCount * 2;
656     view->setModel(&model);
657     for (int j = 0; j < sectionCount; ++j)
658         QCOMPARE(view->sectionSize(j), persistentSectionSize);
659     for (int k = sectionCount; k < view->count(); ++k)
660         QCOMPARE(view->sectionSize(k), initialDefaultSize);
661 }
662
663 void tst_QHeaderView::visualIndex()
664 {
665     // Test bad arguments
666     QCOMPARE(view->visualIndex(999999), -1);
667     QCOMPARE(view->visualIndex(-1), -1);
668     QCOMPARE(view->visualIndex(1), 1);
669     view->setSectionHidden(1, true);
670     QCOMPARE(view->visualIndex(1), 1);
671     QCOMPARE(view->visualIndex(2), 2);
672
673     view->setSectionHidden(1, false);
674     QCOMPARE(view->visualIndex(1), 1);
675     QCOMPARE(view->visualIndex(2), 2);
676 }
677
678 void tst_QHeaderView::visualIndexAt_data()
679 {
680     QTest::addColumn<QList<int> >("hidden");
681     QTest::addColumn<QList<int> >("from");
682     QTest::addColumn<QList<int> >("to");
683     QTest::addColumn<QList<int> >("coordinate");
684     QTest::addColumn<QList<int> >("visual");
685
686     QList<int> coordinateList;
687 #ifndef Q_OS_WINCE
688     coordinateList << -1 << 0 << 31 << 91 << 99999;
689 #else
690     // We test on a device with doubled pixels. Therefore we need to specify
691     // different boundaries.
692     coordinateList << -1 << 0 << 33 << 97 << 99999;
693 #endif
694
695     QTest::newRow("no hidden, no moved sections")
696         << QList<int>()
697         << QList<int>()
698         << QList<int>()
699         << coordinateList
700         << (QList<int>() << -1 << 0 << 1 << 3 << -1);
701
702     QTest::newRow("no hidden, moved sections")
703         << QList<int>()
704         << (QList<int>() << 0)
705         << (QList<int>() << 1)
706         << coordinateList
707         << (QList<int>() << -1 << 0 << 1 << 3 << -1);
708
709     QTest::newRow("hidden, no moved sections")
710         << (QList<int>() << 0)
711         << QList<int>()
712         << QList<int>()
713         << coordinateList
714         << (QList<int>() << -1 << 1 << 2 << 3 << -1);
715 }
716
717 void tst_QHeaderView::visualIndexAt()
718 {
719     QFETCH(QList<int>, hidden);
720     QFETCH(QList<int>, from);
721     QFETCH(QList<int>, to);
722     QFETCH(QList<int>, coordinate);
723     QFETCH(QList<int>, visual);
724
725     view->setStretchLastSection(true);
726     topLevel->show();
727
728     for (int i = 0; i < hidden.count(); ++i)
729         view->setSectionHidden(hidden.at(i), true);
730
731     for (int j = 0; j < from.count(); ++j)
732         view->moveSection(from.at(j), to.at(j));
733
734     QTest::qWait(100);
735
736     for (int k = 0; k < coordinate.count(); ++k)
737         QCOMPARE(view->visualIndexAt(coordinate.at(k)), visual.at(k));
738 }
739
740 void tst_QHeaderView::length()
741 {
742 #if defined(Q_OS_WINCE)
743     QFont font(QLatin1String("Tahoma"), 7);
744     view->setFont(font);
745 #endif
746     view->setStretchLastSection(true);
747     topLevel->show();
748
749     //minimumSectionSize should be the size of the last section of the widget is not tall enough
750     int length = view->minimumSectionSize();
751     for (int i=0; i < view->count()-1; i++) {
752         length += view->sectionSize(i);
753     }
754
755     length = qMax(length, view->viewport()->height());
756     QCOMPARE(length, view->length());
757
758     view->setStretchLastSection(false);
759     topLevel->show();
760
761     QVERIFY(length != view->length());
762
763     // layoutChanged might mean rows have been removed
764     QtTestModel model;
765     model.cols = 10;
766     model.rows = 10;
767     view->setModel(&model);
768     int oldLength = view->length();
769     model.cleanup();
770     QCOMPARE(model.rows, view->count());
771     QVERIFY(oldLength != view->length());
772 }
773
774 void tst_QHeaderView::offset()
775 {
776     QCOMPARE(view->offset(), 0);
777     view->setOffset(10);
778     QCOMPARE(view->offset(), 10);
779     view->setOffset(0);
780     QCOMPARE(view->offset(), 0);
781
782     // Test odd arguments
783     view->setOffset(-1);
784 }
785
786 void tst_QHeaderView::sectionSizeHint()
787 {
788     // Test bad arguments
789     view->sectionSizeHint(-1);
790     view->sectionSizeHint(99999);
791
792     // TODO how to test the return value?
793 }
794
795 void tst_QHeaderView::logicalIndex()
796 {
797     // Test bad arguments
798     QCOMPARE(view->logicalIndex(-1), -1);
799     QCOMPARE(view->logicalIndex(99999), -1);
800 }
801
802 void tst_QHeaderView::logicalIndexAt()
803 {
804     // Test bad arguments
805     view->logicalIndexAt(-1);
806     view->logicalIndexAt(99999);
807     QCOMPARE(view->logicalIndexAt(0), 0);
808     QCOMPARE(view->logicalIndexAt(1), 0);
809
810     topLevel->show();
811     view->setStretchLastSection(true);
812     // First item
813     QCOMPARE(view->logicalIndexAt(0), 0);
814     QCOMPARE(view->logicalIndexAt(view->sectionSize(0)-1), 0);
815     QCOMPARE(view->logicalIndexAt(view->sectionSize(0)+1), 1);
816     // Last item
817     int last = view->length() - 1;//view->viewport()->height() - 10;
818     QCOMPARE(view->logicalIndexAt(last), 3);
819     // Not in widget
820     int outofbounds = view->length() + 1;//view->viewport()->height() + 1;
821     QCOMPARE(view->logicalIndexAt(outofbounds), -1);
822
823     view->moveSection(0,1);
824     // First item
825     QCOMPARE(view->logicalIndexAt(0), 1);
826     QCOMPARE(view->logicalIndexAt(view->sectionSize(0)-1), 1);
827     QCOMPARE(view->logicalIndexAt(view->sectionSize(0)+1), 0);
828     // Last item
829     QCOMPARE(view->logicalIndexAt(last), 3);
830     view->moveSection(1,0);
831
832 }
833
834 void tst_QHeaderView::swapSections()
835 {
836     view->swapSections(-1, 1);
837     view->swapSections(99999, 1);
838     view->swapSections(1, -1);
839     view->swapSections(1, 99999);
840
841     QVector<int> logical = (QVector<int>() << 0 << 1 << 2 << 3);
842
843     QSignalSpy spy1(view, SIGNAL(sectionMoved(int, int, int)));
844
845     QCOMPARE(view->sectionsMoved(), false);
846     view->swapSections(1, 1);
847     QCOMPARE(view->sectionsMoved(), false);
848     view->swapSections(1, 2);
849     QCOMPARE(view->sectionsMoved(), true);
850     view->swapSections(2, 1);
851     QCOMPARE(view->sectionsMoved(), true);
852     for (int i = 0; i < view->count(); ++i)
853         QCOMPARE(view->logicalIndex(i), logical.at(i));
854     QCOMPARE(spy1.count(), 4);
855
856     logical = (QVector<int>()  << 3 << 1 << 2 << 0);
857     view->swapSections(3, 0);
858     QCOMPARE(view->sectionsMoved(), true);
859     for (int j = 0; j < view->count(); ++j)
860         QCOMPARE(view->logicalIndex(j), logical.at(j));
861     QCOMPARE(spy1.count(), 6);
862 }
863
864 void tst_QHeaderView::moveSection_data()
865 {
866     QTest::addColumn<QList<int> >("hidden");
867     QTest::addColumn<QList<int> >("from");
868     QTest::addColumn<QList<int> >("to");
869     QTest::addColumn<QList<bool> >("moved");
870     QTest::addColumn<QList<int> >("logical");
871     QTest::addColumn<int>("count");
872
873     QTest::newRow("bad args, no hidden")
874         << QList<int>()
875         << (QList<int>() << -1 << 1 << 99999 << 1)
876         << (QList<int>() << 1 << -1 << 1 << 99999)
877         << (QList<bool>() << false << false << false << false)
878         << (QList<int>() << 0 << 1 << 2 << 3)
879         << 0;
880
881     QTest::newRow("good args, no hidden")
882         << QList<int>()
883         << (QList<int>() << 1 << 1 << 2 << 1)
884         << (QList<int>() << 1 << 2 << 1 << 2)
885         << (QList<bool>() << false << true << true << true)
886         << (QList<int>() << 0 << 2 << 1 << 3)
887         << 3;
888
889     QTest::newRow("hidden sections")
890         << (QList<int>() << 0 << 3)
891         << (QList<int>() << 1 << 1 << 2 << 1)
892         << (QList<int>() << 1 << 2 << 1 << 2)
893         << (QList<bool>() << false << true << true << true)
894         << (QList<int>() << 0 << 2 << 1 << 3)
895         << 3;
896 }
897
898 void tst_QHeaderView::moveSection()
899 {
900     QFETCH(QList<int>, hidden);
901     QFETCH(QList<int>, from);
902     QFETCH(QList<int>, to);
903     QFETCH(QList<bool>, moved);
904     QFETCH(QList<int>, logical);
905     QFETCH(int, count);
906
907     QVERIFY(from.count() == to.count());
908     QVERIFY(from.count() == moved.count());
909     QVERIFY(view->count() == logical.count());
910
911     QSignalSpy spy1(view, SIGNAL(sectionMoved(int, int, int)));
912     QCOMPARE(view->sectionsMoved(), false);
913
914     for (int h = 0; h < hidden.count(); ++h)
915         view->setSectionHidden(hidden.at(h), true);
916
917     for (int i = 0; i < from.count(); ++i) {
918         view->moveSection(from.at(i), to.at(i));
919         QCOMPARE(view->sectionsMoved(), moved.at(i));
920     }
921
922     for (int j = 0; j < view->count(); ++j)
923         QCOMPARE(view->logicalIndex(j), logical.at(j));
924
925     QCOMPARE(spy1.count(), count);
926 }
927
928 void tst_QHeaderView::resizeAndMoveSection_data()
929 {
930     QTest::addColumn<IntList>("logicalIndexes");
931     QTest::addColumn<IntList>("sizes");
932     QTest::addColumn<int>("logicalFrom");
933     QTest::addColumn<int>("logicalTo");
934
935     QTest::newRow("resizeAndMove-1")
936         << (IntList() << 0 << 1)
937         << (IntList() << 20 << 40)
938         << 0 << 1;
939
940     QTest::newRow("resizeAndMove-2")
941         << (IntList() << 0 << 1 << 2 << 3)
942         << (IntList() << 20 << 60 << 10 << 80)
943         << 0 << 2;
944
945     QTest::newRow("resizeAndMove-3")
946         << (IntList() << 0 << 1 << 2 << 3)
947         << (IntList() << 100 << 60 << 40 << 10)
948         << 0 << 3;
949
950     QTest::newRow("resizeAndMove-4")
951         << (IntList() << 0 << 1 << 2 << 3)
952         << (IntList() << 10 << 40 << 80 << 30)
953         << 1 << 2;
954
955     QTest::newRow("resizeAndMove-5")
956         << (IntList() << 2 << 3)
957         << (IntList() << 100 << 200)
958         << 3 << 2;
959 }
960
961 void tst_QHeaderView::resizeAndMoveSection()
962 {
963     QFETCH(IntList, logicalIndexes);
964     QFETCH(IntList, sizes);
965     QFETCH(int, logicalFrom);
966     QFETCH(int, logicalTo);
967
968     // Save old visual indexes and sizes
969     IntList oldVisualIndexes;
970     IntList oldSizes;
971     foreach (int logical, logicalIndexes) {
972         oldVisualIndexes.append(view->visualIndex(logical));
973         oldSizes.append(view->sectionSize(logical));
974     }
975
976     // Resize sections
977     for (int i = 0; i < logicalIndexes.size(); ++i) {
978         int logical = logicalIndexes.at(i);
979         view->resizeSection(logical, sizes.at(i));
980     }
981
982     // Move sections
983     int visualFrom = view->visualIndex(logicalFrom);
984     int visualTo = view->visualIndex(logicalTo);
985     view->moveSection(visualFrom, visualTo);
986     QCOMPARE(view->visualIndex(logicalFrom), visualTo);
987
988     // Check that sizes are still correct
989     for (int i = 0; i < logicalIndexes.size(); ++i) {
990         int logical = logicalIndexes.at(i);
991         QCOMPARE(view->sectionSize(logical), sizes.at(i));
992     }
993
994     // Move sections back
995     view->moveSection(visualTo, visualFrom);
996
997     // Check that sizes are still correct
998     for (int i = 0; i < logicalIndexes.size(); ++i) {
999         int logical = logicalIndexes.at(i);
1000         QCOMPARE(view->sectionSize(logical), sizes.at(i));
1001     }
1002
1003     // Put everything back as it was
1004     for (int i = 0; i < logicalIndexes.size(); ++i) {
1005         int logical = logicalIndexes.at(i);
1006         view->resizeSection(logical, oldSizes.at(i));
1007         QCOMPARE(view->visualIndex(logical), oldVisualIndexes.at(i));
1008     }
1009 }
1010
1011 void tst_QHeaderView::resizeHiddenSection_data()
1012 {
1013     QTest::addColumn<int>("section");
1014     QTest::addColumn<int>("initialSize");
1015     QTest::addColumn<int>("finalSize");
1016
1017     QTest::newRow("section 0 resize 50 to 20")
1018         << 0 << 50 << 20;
1019
1020     QTest::newRow("section 1 resize 50 to 20")
1021         << 1 << 50 << 20;
1022
1023     QTest::newRow("section 2 resize 50 to 20")
1024         << 2 << 50 << 20;
1025
1026     QTest::newRow("section 3 resize 50 to 20")
1027         << 3 << 50 << 20;
1028 }
1029
1030 void tst_QHeaderView::resizeHiddenSection()
1031 {
1032     QFETCH(int, section);
1033     QFETCH(int, initialSize);
1034     QFETCH(int, finalSize);
1035
1036     view->resizeSection(section, initialSize);
1037     view->setSectionHidden(section, true);
1038     QCOMPARE(view->sectionSize(section), 0);
1039
1040     view->resizeSection(section, finalSize);
1041     QCOMPARE(view->sectionSize(section), 0);
1042
1043     view->setSectionHidden(section, false);
1044     QCOMPARE(view->sectionSize(section), finalSize);
1045 }
1046
1047 void tst_QHeaderView::resizeAndInsertSection_data()
1048 {
1049     QTest::addColumn<int>("section");
1050     QTest::addColumn<int>("size");
1051     QTest::addColumn<int>("insert");
1052     QTest::addColumn<int>("compare");
1053     QTest::addColumn<int>("expected");
1054
1055     QTest::newRow("section 0 size 50 insert 0")
1056         << 0 << 50 << 0 << 1 << 50;
1057
1058     QTest::newRow("section 1 size 50 insert 1")
1059         << 0 << 50 << 1 << 0 << 50;
1060
1061     QTest::newRow("section 1 size 50 insert 0")
1062         << 1 << 50 << 0 << 2 << 50;
1063
1064 }
1065
1066 void tst_QHeaderView::resizeAndInsertSection()
1067 {
1068     QFETCH(int, section);
1069     QFETCH(int, size);
1070     QFETCH(int, insert);
1071     QFETCH(int, compare);
1072     QFETCH(int, expected);
1073
1074     view->setStretchLastSection(false);
1075
1076     view->resizeSection(section, size);
1077     QCOMPARE(view->sectionSize(section), size);
1078
1079     model->insertRow(insert);
1080
1081     QCOMPARE(view->sectionSize(compare), expected);
1082 }
1083
1084 void tst_QHeaderView::resizeWithResizeModes_data()
1085 {
1086     QTest::addColumn<int>("size");
1087     QTest::addColumn<QList<int> >("sections");
1088     QTest::addColumn<QList<int> >("modes");
1089     QTest::addColumn<QList<int> >("expected");
1090
1091     QTest::newRow("stretch first section")
1092         << 600
1093         << (QList<int>() << 100 << 100 << 100 << 100)
1094         << (QList<int>() << ((int)QHeaderView::Stretch)
1095                          << ((int)QHeaderView::Interactive)
1096                          << ((int)QHeaderView::Interactive)
1097                          << ((int)QHeaderView::Interactive))
1098         << (QList<int>() << 300 << 100 << 100 << 100);
1099 }
1100
1101 void  tst_QHeaderView::resizeWithResizeModes()
1102 {
1103     QFETCH(int, size);
1104     QFETCH(QList<int>, sections);
1105     QFETCH(QList<int>, modes);
1106     QFETCH(QList<int>, expected);
1107
1108     view->setStretchLastSection(false);
1109     for (int i = 0; i < sections.count(); ++i) {
1110         view->resizeSection(i, sections.at(i));
1111         view->setSectionResizeMode(i, (QHeaderView::ResizeMode)modes.at(i));
1112     }
1113     topLevel->show();
1114     view->resize(size, size);
1115     for (int j = 0; j < expected.count(); ++j)
1116         QCOMPARE(view->sectionSize(j), expected.at(j));
1117 }
1118
1119 void tst_QHeaderView::moveAndInsertSection_data()
1120 {
1121     QTest::addColumn<int>("from");
1122     QTest::addColumn<int>("to");
1123     QTest::addColumn<int>("insert");
1124     QTest::addColumn<QList<int> >("mapping");
1125
1126     QTest::newRow("move from 1 to 3, insert 0")
1127         << 1 << 3 << 0 <<(QList<int>() << 0 << 1 << 3 << 4 << 2);
1128
1129 }
1130
1131 void tst_QHeaderView::moveAndInsertSection()
1132 {
1133     QFETCH(int, from);
1134     QFETCH(int, to);
1135     QFETCH(int, insert);
1136     QFETCH(QList<int>, mapping);
1137
1138     view->setStretchLastSection(false);
1139
1140     view->moveSection(from, to);
1141
1142     model->insertRow(insert);
1143
1144     for (int i = 0; i < mapping.count(); ++i)
1145         QCOMPARE(view->logicalIndex(i), mapping.at(i));
1146 }
1147
1148 void tst_QHeaderView::resizeMode()
1149 {
1150     // resizeMode must not be called with an invalid index
1151     int last = view->count() - 1;
1152     view->setSectionResizeMode(QHeaderView::Interactive);
1153     QCOMPARE(view->sectionResizeMode(last), QHeaderView::Interactive);
1154     QCOMPARE(view->sectionResizeMode(1), QHeaderView::Interactive);
1155     view->setSectionResizeMode(QHeaderView::Stretch);
1156     QCOMPARE(view->sectionResizeMode(last), QHeaderView::Stretch);
1157     QCOMPARE(view->sectionResizeMode(1), QHeaderView::Stretch);
1158     view->setSectionResizeMode(QHeaderView::Custom);
1159     QCOMPARE(view->sectionResizeMode(last), QHeaderView::Custom);
1160     QCOMPARE(view->sectionResizeMode(1), QHeaderView::Custom);
1161
1162     // test when sections have been moved
1163     view->setStretchLastSection(false);
1164     for (int i=0; i < (view->count() - 1); ++i)
1165         view->setSectionResizeMode(i, QHeaderView::Interactive);
1166     int logicalIndex = view->count() / 2;
1167     view->setSectionResizeMode(logicalIndex, QHeaderView::Stretch);
1168     view->moveSection(view->visualIndex(logicalIndex), 0);
1169     for (int i=0; i < (view->count() - 1); ++i) {
1170         if (i == logicalIndex)
1171             QCOMPARE(view->sectionResizeMode(i), QHeaderView::Stretch);
1172         else
1173             QCOMPARE(view->sectionResizeMode(i), QHeaderView::Interactive);
1174     }
1175 }
1176
1177 void tst_QHeaderView::resizeSection_data()
1178 {
1179     QTest::addColumn<int>("initial");
1180     QTest::addColumn<QList<int> >("logical");
1181     QTest::addColumn<QList<int> >("size");
1182     QTest::addColumn<QList<int> >("mode");
1183     QTest::addColumn<int>("resized");
1184     QTest::addColumn<QList<int> >("expected");
1185
1186     QTest::newRow("bad args")
1187         << 100
1188         << (QList<int>() << -1 << -1 << 99999 << 99999 << 4)
1189         << (QList<int>() << -1 << 0 << 99999 << -1 << -1)
1190         << (QList<int>()
1191             << int(QHeaderView::Interactive)
1192             << int(QHeaderView::Interactive)
1193             << int(QHeaderView::Interactive)
1194             << int(QHeaderView::Interactive))
1195         << 0
1196         << (QList<int>() << 0 << 0 << 0 << 0 << 0);
1197 }
1198
1199 void tst_QHeaderView::resizeSection()
1200 {
1201
1202     QFETCH(int, initial);
1203     QFETCH(QList<int>, logical);
1204     QFETCH(QList<int>, size);
1205     QFETCH(QList<int>, mode);
1206     QFETCH(int, resized);
1207     QFETCH(QList<int>, expected);
1208
1209     view->resize(400, 400);
1210
1211     topLevel->show();
1212     view->setSectionsMovable(true);
1213     view->setStretchLastSection(false);
1214
1215     for (int i = 0; i < logical.count(); ++i)
1216         if (logical.at(i) > -1 && logical.at(i) < view->count()) // for now
1217             view->setSectionResizeMode(logical.at(i), (QHeaderView::ResizeMode)mode.at(i));
1218
1219     for (int j = 0; j < logical.count(); ++j)
1220         view->resizeSection(logical.at(j), initial);
1221
1222     QSignalSpy spy(view, SIGNAL(sectionResized(int, int, int)));
1223
1224     for (int k = 0; k < logical.count(); ++k)
1225         view->resizeSection(logical.at(k), size.at(k));
1226
1227     QCOMPARE(spy.count(), resized);
1228
1229     for (int l = 0; l < logical.count(); ++l)
1230         QCOMPARE(view->sectionSize(logical.at(l)), expected.at(l));
1231 }
1232
1233 void tst_QHeaderView::highlightSections()
1234 {
1235     view->setHighlightSections(true);
1236     QCOMPARE(view->highlightSections(), true);
1237     view->setHighlightSections(false);
1238     QCOMPARE(view->highlightSections(), false);
1239 }
1240
1241 void tst_QHeaderView::showSortIndicator()
1242 {
1243     view->setSortIndicatorShown(true);
1244     QCOMPARE(view->isSortIndicatorShown(), true);
1245     QCOMPARE(view->sortIndicatorOrder(), Qt::DescendingOrder);
1246     view->setSortIndicator(1, Qt::AscendingOrder);
1247     QCOMPARE(view->sortIndicatorOrder(), Qt::AscendingOrder);
1248     view->setSortIndicator(1, Qt::DescendingOrder);
1249     QCOMPARE(view->sortIndicatorOrder(), Qt::DescendingOrder);
1250     view->setSortIndicatorShown(false);
1251     QCOMPARE(view->isSortIndicatorShown(), false);
1252
1253     view->setSortIndicator(999999, Qt::DescendingOrder);
1254     // Don't segfault baby :)
1255     view->setSortIndicatorShown(true);
1256
1257     view->setSortIndicator(0, Qt::DescendingOrder);
1258     // Don't assert baby :)
1259 }
1260
1261 void tst_QHeaderView::sortIndicatorTracking()
1262 {
1263     QtTestModel model;
1264     model.rows = model.cols = 10;
1265
1266     QHeaderView hv(Qt::Horizontal);
1267
1268     hv.setModel(&model);
1269     hv.show();
1270     hv.setSortIndicatorShown(true);
1271     hv.setSortIndicator(1, Qt::DescendingOrder);
1272
1273     model.removeOneColumn(8);
1274     QCOMPARE(hv.sortIndicatorSection(), 1);
1275
1276     model.removeOneColumn(2);
1277     QCOMPARE(hv.sortIndicatorSection(), 1);
1278
1279     model.insertOneColumn(2);
1280     QCOMPARE(hv.sortIndicatorSection(), 1);
1281
1282     model.insertOneColumn(1);
1283     QCOMPARE(hv.sortIndicatorSection(), 2);
1284
1285     model.removeOneColumn(0);
1286     QCOMPARE(hv.sortIndicatorSection(), 1);
1287
1288     model.removeOneColumn(1);
1289     QCOMPARE(hv.sortIndicatorSection(), -1);
1290 }
1291
1292 void tst_QHeaderView::removeAndInsertRow()
1293 {
1294     // Check if logicalIndex returns the correct value after we have removed a row
1295     // we might as well te
1296     for (int i = 0; i < model->rowCount(); ++i) {
1297         QCOMPARE(i, view->logicalIndex(i));
1298     }
1299
1300     while (model->removeRow(0)) {
1301         for (int i = 0; i < model->rowCount(); ++i) {
1302             QCOMPARE(i, view->logicalIndex(i));
1303         }
1304     }
1305
1306     int pass = 0;
1307     for (pass = 0; pass < 5; pass++) {
1308         for (int i = 0; i < model->rowCount(); ++i) {
1309             QCOMPARE(i, view->logicalIndex(i));
1310         }
1311         model->insertRow(0);
1312     }
1313
1314     while (model->removeRows(0, 2)) {
1315         for (int i = 0; i < model->rowCount(); ++i) {
1316             QCOMPARE(i, view->logicalIndex(i));
1317         }
1318     }
1319
1320     for (pass = 0; pass < 3; pass++) {
1321         model->insertRows(0, 2);
1322         for (int i = 0; i < model->rowCount(); ++i) {
1323             QCOMPARE(i, view->logicalIndex(i));
1324         }
1325     }
1326
1327     for (pass = 0; pass < 3; pass++) {
1328         model->insertRows(3, 2);
1329         for (int i = 0; i < model->rowCount(); ++i) {
1330             QCOMPARE(i, view->logicalIndex(i));
1331         }
1332     }
1333
1334     // Insert at end
1335     for (pass = 0; pass < 3; pass++) {
1336         int rowCount = model->rowCount();
1337         model->insertRows(rowCount, 1);
1338         for (int i = 0; i < rowCount; ++i) {
1339             QCOMPARE(i, view->logicalIndex(i));
1340         }
1341     }
1342
1343 }
1344 void tst_QHeaderView::unhideSection()
1345 {
1346     // You should not necessarily expect the same size back again, so the best test we can do is to test if it is larger than 0 after a unhide.
1347     QCOMPARE(view->sectionsHidden(), false);
1348     view->setSectionHidden(0, true);
1349     QCOMPARE(view->sectionsHidden(), true);
1350     QVERIFY(view->sectionSize(0) == 0);
1351     view->setSectionResizeMode(QHeaderView::Interactive);
1352     view->setSectionHidden(0, false);
1353     QVERIFY(view->sectionSize(0) > 0);
1354
1355     view->setSectionHidden(0, true);
1356     QVERIFY(view->sectionSize(0) == 0);
1357     view->setSectionHidden(0, true);
1358     QVERIFY(view->sectionSize(0) == 0);
1359     view->setSectionResizeMode(QHeaderView::Stretch);
1360     view->setSectionHidden(0, false);
1361     QVERIFY(view->sectionSize(0) > 0);
1362
1363 }
1364
1365 void tst_QHeaderView::event()
1366 {
1367     protected_QHeaderView x(Qt::Vertical);
1368     x.testEvent();
1369     protected_QHeaderView y(Qt::Horizontal);
1370     y.testEvent();
1371 }
1372
1373
1374 void protected_QHeaderView::testEvent()
1375 {
1376     // No crashy please
1377     QHoverEvent enterEvent(QEvent::HoverEnter, QPoint(), QPoint());
1378     event(&enterEvent);
1379     QHoverEvent eventLeave(QEvent::HoverLeave, QPoint(), QPoint());
1380     event(&eventLeave);
1381     QHoverEvent eventMove(QEvent::HoverMove, QPoint(), QPoint());
1382     event(&eventMove);
1383 }
1384
1385 void tst_QHeaderView::headerDataChanged()
1386 {
1387     // This shouldn't asserver because view is Vertical
1388     view->headerDataChanged(Qt::Horizontal, -1, -1);
1389 #if 0
1390     // This will assert
1391     view->headerDataChanged(Qt::Vertical, -1, -1);
1392 #endif
1393
1394     // No crashing please
1395     view->headerDataChanged(Qt::Horizontal, 0, 1);
1396     view->headerDataChanged(Qt::Vertical, 0, 1);
1397 }
1398
1399 void tst_QHeaderView::currentChanged()
1400 {
1401     view->setCurrentIndex(QModelIndex());
1402 }
1403
1404 void tst_QHeaderView::horizontalOffset()
1405 {
1406     protected_QHeaderView x(Qt::Vertical);
1407     x.testhorizontalOffset();
1408     protected_QHeaderView y(Qt::Horizontal);
1409     y.testhorizontalOffset();
1410 }
1411
1412 void tst_QHeaderView::verticalOffset()
1413 {
1414     protected_QHeaderView x(Qt::Vertical);
1415     x.testverticalOffset();
1416     protected_QHeaderView y(Qt::Horizontal);
1417     y.testverticalOffset();
1418 }
1419
1420 void  protected_QHeaderView::testhorizontalOffset()
1421 {
1422     if(orientation() == Qt::Horizontal){
1423         QCOMPARE(horizontalOffset(), 0);
1424         setOffset(10);
1425         QCOMPARE(horizontalOffset(), 10);
1426     }
1427     else
1428         QCOMPARE(horizontalOffset(), 0);
1429
1430 }
1431
1432 void  protected_QHeaderView::testverticalOffset()
1433 {
1434     if(orientation() == Qt::Vertical){
1435         QCOMPARE(verticalOffset(), 0);
1436         setOffset(10);
1437         QCOMPARE(verticalOffset(), 10);
1438     }
1439     else
1440         QCOMPARE(verticalOffset(), 0);
1441 }
1442
1443 void tst_QHeaderView::stretchSectionCount()
1444 {
1445     view->setStretchLastSection(false);
1446     QCOMPARE(view->stretchSectionCount(), 0);
1447     view->setStretchLastSection(true);
1448     QCOMPARE(view->stretchSectionCount(), 0);
1449
1450     view->setSectionResizeMode(0, QHeaderView::Stretch);
1451     QCOMPARE(view->stretchSectionCount(), 1);
1452 }
1453
1454 void tst_QHeaderView::hiddenSectionCount()
1455 {
1456     model->clear();
1457     model->insertRows(0, 10);
1458     // Hide every other one
1459     for (int i=0; i<10; i++)
1460         view->setSectionHidden(i, (i & 1) == 0);
1461
1462     QCOMPARE(view->hiddenSectionCount(), 5);
1463
1464     view->setSectionResizeMode(QHeaderView::Stretch);
1465     QCOMPARE(view->hiddenSectionCount(), 5);
1466
1467     // Remove some rows and make sure they are now still counted
1468     model->removeRow(9);
1469     model->removeRow(8);
1470     model->removeRow(7);
1471     model->removeRow(6);
1472     QCOMPARE(view->count(), 6);
1473     QCOMPARE(view->hiddenSectionCount(), 3);
1474     model->removeRows(0,5);
1475     QCOMPARE(view->count(), 1);
1476     QCOMPARE(view->hiddenSectionCount(), 0);
1477     QVERIFY(view->count() >=  view->hiddenSectionCount());
1478 }
1479
1480 void tst_QHeaderView::focusPolicy()
1481 {
1482     QHeaderView view(Qt::Horizontal);
1483     QCOMPARE(view.focusPolicy(), Qt::NoFocus);
1484
1485     QTreeWidget widget;
1486     QCOMPARE(widget.header()->focusPolicy(), Qt::NoFocus);
1487     QVERIFY(!widget.focusProxy());
1488     QVERIFY(!widget.hasFocus());
1489     QVERIFY(!widget.header()->focusProxy());
1490     QVERIFY(!widget.header()->hasFocus());
1491
1492     widget.show();
1493     widget.setFocus(Qt::OtherFocusReason);
1494     QApplication::setActiveWindow(&widget);
1495     widget.activateWindow();
1496     QVERIFY(QTest::qWaitForWindowActive(&widget));
1497     QVERIFY(widget.hasFocus());
1498     QVERIFY(!widget.header()->hasFocus());
1499
1500     widget.setFocusPolicy(Qt::NoFocus);
1501     widget.clearFocus();
1502     QTRY_VERIFY(!widget.hasFocus());
1503     QVERIFY(!widget.header()->hasFocus());
1504
1505     QTest::keyPress(&widget, Qt::Key_Tab);
1506
1507     qApp->processEvents();
1508     qApp->processEvents();
1509
1510     QVERIFY(!widget.hasFocus());
1511     QVERIFY(!widget.header()->hasFocus());
1512 }
1513
1514 class SimpleModel : public QAbstractItemModel
1515 {
1516     Q_OBJECT
1517 public:
1518
1519     SimpleModel( QObject* parent=0)
1520         : QAbstractItemModel(parent),
1521         m_col_count(3) {}
1522
1523     QModelIndex parent(const QModelIndex &/*child*/) const
1524     {
1525         return QModelIndex();
1526     }
1527     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
1528     {
1529         return hasIndex(row, column, parent) ? createIndex(row, column, 0) : QModelIndex();
1530     }
1531     int rowCount(const QModelIndex & /* parent */) const
1532     {
1533         return 8;
1534     }
1535     int columnCount(const QModelIndex &/*parent= QModelIndex()*/) const
1536     {
1537         return m_col_count;
1538     }
1539
1540     QVariant data(const QModelIndex &index, int role) const
1541     {
1542         if (!index.isValid())
1543         {
1544             return QVariant();
1545         }
1546         if (role == Qt::DisplayRole) {
1547             return QString::fromLatin1("%1,%2").arg(index.row()).arg(index.column());
1548         }
1549         return QVariant();
1550     }
1551
1552     void setColumnCount( int c )
1553     {
1554         m_col_count = c;
1555     }
1556
1557 private:
1558     int m_col_count;
1559 };
1560
1561 void tst_QHeaderView::moveSectionAndReset()
1562 {
1563     SimpleModel m;
1564     QHeaderView v(Qt::Horizontal);
1565     v.setModel(&m);
1566     int cc = 2;
1567     for (cc = 2; cc < 4; ++cc) {
1568         m.setColumnCount(cc);
1569         int movefrom = 0;
1570         int moveto;
1571         for (moveto = 1; moveto < cc; ++moveto) {
1572             v.moveSection(movefrom, moveto);
1573             m.setColumnCount(cc - 1);
1574             v.reset();
1575             for (int i = 0; i < cc - 1; ++i) {
1576                 QCOMPARE(v.logicalIndex(v.visualIndex(i)), i);
1577             }
1578         }
1579     }
1580 }
1581
1582 void tst_QHeaderView::moveSectionAndRemove()
1583 {
1584     QStandardItemModel m;
1585     QHeaderView v(Qt::Horizontal);
1586
1587     v.setModel(&m);
1588     v.model()->insertColumns(0, 3);
1589     v.moveSection(0, 1);
1590
1591     QCOMPARE(v.count(), 3);
1592     v.model()->removeColumns(0, v.model()->columnCount());
1593     QCOMPARE(v.count(), 0);
1594 }
1595
1596 void tst_QHeaderView::saveRestore()
1597 {
1598     SimpleModel m;
1599     QHeaderView h1(Qt::Horizontal);
1600     h1.setModel(&m);
1601     h1.swapSections(0, 2);
1602     h1.resizeSection(1, 10);
1603     h1.setSortIndicatorShown(true);
1604     h1.setSortIndicator(1,Qt::DescendingOrder);
1605     QByteArray s1 = h1.saveState();
1606
1607     QHeaderView h2(Qt::Vertical);
1608     QSignalSpy spy(&h2, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)));
1609
1610     h2.setModel(&m);
1611     h2.restoreState(s1);
1612
1613     QCOMPARE(spy.count(), 1);
1614     QCOMPARE(spy.at(0).at(0).toInt(), 1);
1615
1616     QCOMPARE(h2.logicalIndex(0), 2);
1617     QCOMPARE(h2.logicalIndex(2), 0);
1618     QCOMPARE(h2.sectionSize(1), 10);
1619     QCOMPARE(h2.sortIndicatorSection(), 1);
1620     QCOMPARE(h2.sortIndicatorOrder(), Qt::DescendingOrder);
1621     QCOMPARE(h2.isSortIndicatorShown(), true);
1622
1623     QByteArray s2 = h2.saveState();
1624
1625     QVERIFY(s1 == s2);
1626 }
1627
1628 void tst_QHeaderView::defaultSectionSizeTest()
1629 {
1630     // Setup
1631     QTableView qtv;
1632     QStandardItemModel amodel(4, 4);
1633     qtv.setModel(&amodel);
1634     QHeaderView *hv = qtv.verticalHeader();
1635     const int defaultSize = 26;
1636     hv->setDefaultSectionSize(defaultSize + 1); // Set it to a value different from defaultSize.
1637
1638     // no hidden Sections
1639     hv->resizeSection(1, 0);
1640     hv->setDefaultSectionSize(defaultSize);
1641     QVERIFY(hv->sectionSize(1) == defaultSize);
1642
1643     // with hidden sections
1644     hv->resizeSection(1, 0);
1645     hv->hideSection(2);
1646     hv->setDefaultSectionSize(defaultSize);
1647
1648     QVERIFY(hv->sectionSize(0) == defaultSize); // trivial case.
1649     QVERIFY(hv->sectionSize(1) == defaultSize); // just sized 0. Now it should be 10
1650     QVERIFY(hv->sectionSize(2) == 0); // section is hidden. It should not be resized.
1651 }
1652
1653
1654 void tst_QHeaderView::defaultAlignment_data()
1655 {
1656     QTest::addColumn<int>("direction");
1657     QTest::addColumn<int>("initial");
1658     QTest::addColumn<int>("alignment");
1659
1660     QTest::newRow("horizontal right aligned")
1661         << int(Qt::Horizontal)
1662         << int(Qt::AlignCenter)
1663         << int(Qt::AlignRight);
1664
1665     QTest::newRow("horizontal left aligned")
1666         << int(Qt::Horizontal)
1667         << int(Qt::AlignCenter)
1668         << int(Qt::AlignLeft);
1669
1670     QTest::newRow("vertical right aligned")
1671         << int(Qt::Vertical)
1672         << int(Qt::AlignLeft|Qt::AlignVCenter)
1673         << int(Qt::AlignRight);
1674
1675     QTest::newRow("vertical left aligned")
1676         << int(Qt::Vertical)
1677         << int(Qt::AlignLeft|Qt::AlignVCenter)
1678         << int(Qt::AlignLeft);
1679 }
1680
1681 void tst_QHeaderView::defaultAlignment()
1682 {
1683     QFETCH(int, direction);
1684     QFETCH(int, initial);
1685     QFETCH(int, alignment);
1686
1687     SimpleModel m;
1688
1689     QHeaderView header((Qt::Orientation)direction);
1690     header.setModel(&m);
1691
1692     QCOMPARE(header.defaultAlignment(), (Qt::Alignment)initial);
1693     header.setDefaultAlignment((Qt::Alignment)alignment);
1694     QCOMPARE(header.defaultAlignment(), (Qt::Alignment)alignment);
1695 }
1696
1697 void tst_QHeaderView::globalResizeMode_data()
1698 {
1699     QTest::addColumn<int>("direction");
1700     QTest::addColumn<int>("mode");
1701     QTest::addColumn<int>("insert");
1702
1703     QTest::newRow("horizontal ResizeToContents 0")
1704         << int(Qt::Horizontal)
1705         << int(QHeaderView::ResizeToContents)
1706         << 0;
1707 }
1708
1709 void tst_QHeaderView::globalResizeMode()
1710 {
1711     QFETCH(int, direction);
1712     QFETCH(int, mode);
1713     QFETCH(int, insert);
1714
1715     QStandardItemModel m(4, 4);
1716     QHeaderView h((Qt::Orientation)direction);
1717     h.setModel(&m);
1718
1719     h.setSectionResizeMode((QHeaderView::ResizeMode)mode);
1720     m.insertRow(insert);
1721     for (int i = 0; i < h.count(); ++i)
1722         QCOMPARE(h.sectionResizeMode(i), (QHeaderView::ResizeMode)mode);
1723 }
1724
1725
1726 void tst_QHeaderView::sectionPressedSignal_data()
1727 {
1728     QTest::addColumn<int>("direction");
1729     QTest::addColumn<bool>("clickable");
1730     QTest::addColumn<int>("count");
1731
1732     QTest::newRow("horizontal unclickable 0")
1733         << int(Qt::Horizontal)
1734         << false
1735         << 0;
1736
1737     QTest::newRow("horizontal clickable 1")
1738         << int(Qt::Horizontal)
1739         << true
1740         << 1;
1741 }
1742
1743 void tst_QHeaderView::sectionPressedSignal()
1744 {
1745     QFETCH(int, direction);
1746     QFETCH(bool, clickable);
1747     QFETCH(int, count);
1748
1749     QStandardItemModel m(4, 4);
1750     QHeaderView h((Qt::Orientation)direction);
1751
1752     h.setModel(&m);
1753     h.show();
1754     h.setSectionsClickable(clickable);
1755
1756     QSignalSpy spy(&h, SIGNAL(sectionPressed(int)));
1757
1758     QCOMPARE(spy.count(), 0);
1759     QTest::mousePress(h.viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
1760     QCOMPARE(spy.count(), count);
1761 }
1762
1763 void tst_QHeaderView::sectionClickedSignal()
1764 {
1765     QFETCH(int, direction);
1766     QFETCH(bool, clickable);
1767     QFETCH(int, count);
1768
1769     QStandardItemModel m(4, 4);
1770     QHeaderView h((Qt::Orientation)direction);
1771
1772     h.setModel(&m);
1773     h.show();
1774     h.setSectionsClickable(clickable);
1775     h.setSortIndicatorShown(true);
1776
1777     QSignalSpy spy(&h, SIGNAL(sectionClicked(int)));
1778     QSignalSpy spy2(&h, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)));
1779
1780     QCOMPARE(spy.count(), 0);
1781     QCOMPARE(spy2.count(), 0);
1782     QTest::mouseClick(h.viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
1783     QCOMPARE(spy.count(), count);
1784     QCOMPARE(spy2.count(), count);
1785
1786     //now let's try with the sort indicator hidden (the result should be the same
1787     spy.clear();
1788     spy2.clear();
1789     h.setSortIndicatorShown(false);
1790     QTest::mouseClick(h.viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
1791     QCOMPARE(spy.count(), count);
1792     QCOMPARE(spy2.count(), count);
1793 }
1794
1795 void tst_QHeaderView::defaultSectionSize_data()
1796 {
1797     QTest::addColumn<int>("direction");
1798     QTest::addColumn<int>("oldDefaultSize");
1799     QTest::addColumn<int>("newDefaultSize");
1800
1801     //QTest::newRow("horizontal,-5") << int(Qt::Horizontal) << 100 << -5;
1802     QTest::newRow("horizontal, 0") << int(Qt::Horizontal) << 100 << 0;
1803     QTest::newRow("horizontal, 5") << int(Qt::Horizontal) << 100 << 5;
1804     QTest::newRow("horizontal,25") << int(Qt::Horizontal) << 100 << 5;
1805 }
1806
1807 void tst_QHeaderView::defaultSectionSize()
1808 {
1809     QFETCH(int, direction);
1810     QFETCH(int, oldDefaultSize);
1811     QFETCH(int, newDefaultSize);
1812
1813     QStandardItemModel m(4, 4);
1814     QHeaderView h((Qt::Orientation)direction);
1815
1816     h.setModel(&m);
1817
1818     QCOMPARE(h.defaultSectionSize(), oldDefaultSize);
1819     h.setDefaultSectionSize(newDefaultSize);
1820     QCOMPARE(h.defaultSectionSize(), newDefaultSize);
1821     h.reset();
1822     for (int i = 0; i < h.count(); ++i)
1823         QCOMPARE(h.sectionSize(i), newDefaultSize);
1824 }
1825
1826 void tst_QHeaderView::hideAndInsert_data()
1827 {
1828     QTest::addColumn<int>("direction");
1829     QTest::addColumn<int>("hide");
1830     QTest::addColumn<int>("insert");
1831     QTest::addColumn<int>("hidden");
1832
1833     QTest::newRow("horizontal, 0, 0") << int(Qt::Horizontal) << 0 << 0 << 1;
1834 }
1835
1836 void tst_QHeaderView::hideAndInsert()
1837 {
1838     QFETCH(int, direction);
1839     QFETCH(int, hide);
1840     QFETCH(int, insert);
1841     QFETCH(int, hidden);
1842
1843     QStandardItemModel m(4, 4);
1844     QHeaderView h((Qt::Orientation)direction);
1845
1846     h.setModel(&m);
1847
1848     h.setSectionHidden(hide, true);
1849
1850     if (direction == Qt::Vertical)
1851         m.insertRow(insert);
1852     else
1853         m.insertColumn(insert);
1854
1855     for (int i = 0; i < h.count(); ++i)
1856         if (i != hidden)
1857             QCOMPARE(h.isSectionHidden(i), false);
1858         else
1859             QCOMPARE(h.isSectionHidden(i), true);
1860 }
1861
1862 void tst_QHeaderView::removeSection()
1863 {
1864 //test that removing a hidden section gives the expected result: the next row should be hidden
1865 //(see task
1866     const int hidden = 3; //section that will be hidden
1867     const QStringList list = QStringList() << "0" << "1" << "2" << "3" << "4" << "5" << "6";
1868
1869     QStringListModel model( list );
1870     QHeaderView view(Qt::Vertical);
1871     view.setModel(&model);
1872     view.hideSection(hidden);
1873     view.hideSection(1);
1874     model.removeRow(1);
1875     view.show();
1876
1877     for(int i = 0; i < view.count(); i++) {
1878         if (i == (hidden-1)) { //-1 because we removed a row in the meantime
1879             QCOMPARE(view.sectionSize(i), 0);
1880             QVERIFY(view.isSectionHidden(i));
1881         } else {
1882             QCOMPARE(view.sectionSize(i), view.defaultSectionSize() );
1883             QVERIFY(!view.isSectionHidden(i));
1884         }
1885     }
1886 }
1887
1888 void tst_QHeaderView::preserveHiddenSectionWidth()
1889 {
1890     const QStringList list = QStringList() << "0" << "1" << "2" << "3";
1891
1892     QStringListModel model( list );
1893     QHeaderView view(Qt::Vertical);
1894     view.setModel(&model);
1895     view.resizeSection(0, 100);
1896     view.resizeSection(1, 10);
1897     view.resizeSection(2, 50);
1898     view.setSectionResizeMode(3, QHeaderView::Stretch);
1899     view.show();
1900
1901     view.hideSection(2);
1902     model.removeRow(1);
1903     view.showSection(1);
1904     QCOMPARE(view.sectionSize(0), 100);
1905     QCOMPARE(view.sectionSize(1), 50);
1906
1907     view.hideSection(1);
1908     model.insertRow(1);
1909     view.showSection(2);
1910     QCOMPARE(view.sectionSize(0), 100);
1911     QCOMPARE(view.sectionSize(1), view.defaultSectionSize());
1912     QCOMPARE(view.sectionSize(2), 50);
1913 }
1914
1915 void tst_QHeaderView::invisibleStretchLastSection()
1916 {
1917     int count = 6;
1918     QStandardItemModel model(1, count);
1919     QHeaderView view(Qt::Horizontal);
1920     view.setModel(&model);
1921     int height = view.height();
1922
1923     view.resize(view.defaultSectionSize() * (count / 2), height); // don't show all sections
1924     view.show();
1925     view.setStretchLastSection(true);
1926     // stretch section is not visible; it should not be stretched
1927     for (int i = 0; i < count; ++i)
1928         QCOMPARE(view.sectionSize(i), view.defaultSectionSize());
1929
1930     view.resize(view.defaultSectionSize() * (count + 1), height); // give room to stretch
1931
1932     // stretch section is visible; it should be stretched
1933     for (int i = 0; i < count - 1; ++i)
1934         QCOMPARE(view.sectionSize(i), view.defaultSectionSize());
1935     QCOMPARE(view.sectionSize(count - 1), view.defaultSectionSize() * 2);
1936 }
1937
1938 void tst_QHeaderView::noSectionsWithNegativeSize()
1939 {
1940     QStandardItemModel m(4, 4);
1941     QHeaderView h(Qt::Horizontal);
1942     h.setModel(&m);
1943     h.resizeSection(1, -5);
1944     QVERIFY(h.sectionSize(1) >= 0); // Sections with negative sizes not well defined.
1945 }
1946
1947 void tst_QHeaderView::emptySectionSpan()
1948 {
1949     QHeaderViewPrivate::SectionItem section;
1950     QCOMPARE(section.sectionSize(), 0);
1951 }
1952
1953 void tst_QHeaderView::task236450_hidden_data()
1954 {
1955     QTest::addColumn<QList<int> >("hide1");
1956     QTest::addColumn<QList<int> >("hide2");
1957
1958     QTest::newRow("set 1") << (QList<int>() << 1 << 3)
1959                            << (QList<int>() << 1 << 5);
1960
1961     QTest::newRow("set 2") << (QList<int>() << 2 << 3)
1962                            << (QList<int>() << 1 << 5);
1963
1964     QTest::newRow("set 3") << (QList<int>() << 0 << 2 << 4)
1965                            << (QList<int>() << 2 << 3 << 5);
1966
1967 }
1968
1969 void tst_QHeaderView::task236450_hidden()
1970 {
1971     QFETCH(QList<int>, hide1);
1972     QFETCH(QList<int>, hide2);
1973     const QStringList list = QStringList() << "0" << "1" << "2" << "3" << "4" << "5";
1974
1975     QStringListModel model( list );
1976     protected_QHeaderView view(Qt::Vertical);
1977     view.setModel(&model);
1978     view.show();
1979
1980     foreach (int i, hide1)
1981         view.hideSection(i);
1982
1983     QCOMPARE(view.hiddenSectionCount(), hide1.count());
1984     for (int i = 0; i < 6; i++) {
1985         QCOMPARE(!view.isSectionHidden(i), !hide1.contains(i));
1986     }
1987
1988     view.setDefaultSectionSize(2);
1989     view.scheduleDelayedItemsLayout();
1990     view.executeDelayedItemsLayout(); //force to do a relayout
1991
1992     QCOMPARE(view.hiddenSectionCount(), hide1.count());
1993     for (int i = 0; i < 6; i++) {
1994         QCOMPARE(!view.isSectionHidden(i), !hide1.contains(i));
1995         view.setSectionHidden(i, hide2.contains(i));
1996     }
1997
1998     QCOMPARE(view.hiddenSectionCount(), hide2.count());
1999     for (int i = 0; i < 6; i++) {
2000         QCOMPARE(!view.isSectionHidden(i), !hide2.contains(i));
2001     }
2002
2003 }
2004
2005 void tst_QHeaderView::task248050_hideRow()
2006 {
2007     //this is the sequence of events that make the task fail
2008     protected_QHeaderView header(Qt::Vertical);
2009     QStandardItemModel model(0, 1);
2010     header.setStretchLastSection(false);
2011     header.setDefaultSectionSize(17);
2012     header.setModel(&model);
2013     header.doItemsLayout();
2014
2015     model.setRowCount(3);
2016
2017     QCOMPARE(header.sectionPosition(2), 17*2);
2018
2019     header.hideSection(1);
2020     QCOMPARE(header.sectionPosition(2), 17);
2021
2022     QTest::qWait(100);
2023     //the size of the section shouldn't have changed
2024     QCOMPARE(header.sectionPosition(2), 17);
2025 }
2026
2027
2028 //returns 0 if everything is fine.
2029 static int checkHeaderViewOrder(QHeaderView *view, const QVector<int> &expected)
2030 {
2031     if (view->count() != expected.count())
2032         return 1;
2033
2034     for (int i = 0; i < expected.count(); i++) {
2035         if (view->logicalIndex(i) != expected.at(i))
2036             return i + 10;
2037         if (view->visualIndex(expected.at(i)) != i)
2038             return i + 100;
2039     }
2040     return 0;
2041 }
2042
2043
2044 void tst_QHeaderView::QTBUG6058_reset()
2045 {
2046     QStringListModel model1( QStringList() << "0" << "1" << "2" << "3" << "4" << "5" );
2047     QStringListModel model2( QStringList() << "a" << "b" << "c" );
2048     QSortFilterProxyModel proxy;
2049
2050     QHeaderView view(Qt::Vertical);
2051     view.setModel(&proxy);
2052     view.show();
2053     QTest::qWait(20);
2054
2055     proxy.setSourceModel(&model1);
2056     QApplication::processEvents();
2057     view.swapSections(0,2);
2058     view.swapSections(1,4);
2059     QApplication::processEvents();
2060     QCOMPARE(checkHeaderViewOrder(&view, QVector<int>() << 2 << 4 << 0 << 3 << 1 << 5) , 0);
2061
2062     proxy.setSourceModel(&model2);
2063     QApplication::processEvents();
2064     QCOMPARE(checkHeaderViewOrder(&view, QVector<int>() << 2 << 0 << 1 ) , 0);
2065
2066     proxy.setSourceModel(&model1);
2067     QApplication::processEvents();
2068     QCOMPARE(checkHeaderViewOrder(&view, QVector<int>() << 2 << 0 << 1 << 3 << 4 << 5 ) , 0);
2069 }
2070
2071 void tst_QHeaderView::QTBUG7833_sectionClicked()
2072 {
2073
2074
2075
2076
2077     QTableView tv;
2078     QStandardItemModel *sim = new QStandardItemModel(&tv);
2079     QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(&tv);
2080     proxyModel->setSourceModel(sim);
2081     proxyModel->setDynamicSortFilter(true);
2082     proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
2083
2084     QList<QStandardItem *> row;
2085     for (int i = 0; i < 12; i++)
2086         row.append(new QStandardItem(QString(QLatin1Char('A' + i))));
2087     sim->appendRow(row);
2088     row.clear();
2089     for (int i = 12; i > 0; i--)
2090         row.append(new QStandardItem(QString(QLatin1Char('A' + i))));
2091     sim->appendRow(row);
2092
2093     tv.setSortingEnabled(true);
2094     tv.horizontalHeader()->setSortIndicatorShown(true);
2095     tv.horizontalHeader()->setSectionsClickable(true);
2096     tv.horizontalHeader()->setStretchLastSection(true);
2097     tv.horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
2098
2099     tv.setModel(proxyModel);
2100     tv.setColumnHidden(5, true);
2101     tv.setColumnHidden(6, true);
2102     tv.horizontalHeader()->swapSections(8, 10);
2103     tv.sortByColumn(1, Qt::AscendingOrder);
2104
2105     QSignalSpy clickedSpy(tv.horizontalHeader(), SIGNAL(sectionClicked(int)));
2106     QSignalSpy pressedSpy(tv.horizontalHeader(), SIGNAL(sectionPressed(int)));
2107
2108
2109     QTest::mouseClick(tv.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier,
2110                       QPoint(tv.horizontalHeader()->sectionViewportPosition(11) + tv.horizontalHeader()->sectionSize(11)/2, 5));
2111     QCOMPARE(clickedSpy.count(), 1);
2112     QCOMPARE(pressedSpy.count(), 1);
2113     QCOMPARE(clickedSpy.at(0).at(0).toInt(), 11);
2114     QCOMPARE(pressedSpy.at(0).at(0).toInt(), 11);
2115
2116     QTest::mouseClick(tv.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier,
2117                       QPoint(tv.horizontalHeader()->sectionViewportPosition(8) + tv.horizontalHeader()->sectionSize(0)/2, 5));
2118
2119     QCOMPARE(clickedSpy.count(), 2);
2120     QCOMPARE(pressedSpy.count(), 2);
2121     QCOMPARE(clickedSpy.at(1).at(0).toInt(), 8);
2122     QCOMPARE(pressedSpy.at(1).at(0).toInt(), 8);
2123
2124     QTest::mouseClick(tv.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier,
2125                       QPoint(tv.horizontalHeader()->sectionViewportPosition(0) + tv.horizontalHeader()->sectionSize(0)/2, 5));
2126
2127     QCOMPARE(clickedSpy.count(), 3);
2128     QCOMPARE(pressedSpy.count(), 3);
2129     QCOMPARE(clickedSpy.at(2).at(0).toInt(), 0);
2130     QCOMPARE(pressedSpy.at(2).at(0).toInt(), 0);
2131 }
2132
2133 void tst_QHeaderView::QTBUG8650_crashOnInsertSections()
2134 {
2135     QStringList headerLabels;
2136     QHeaderView view(Qt::Horizontal);
2137     QStandardItemModel model(2,2);
2138     view.setModel(&model);
2139     view.moveSection(1, 0);
2140     view.hideSection(0);
2141
2142     QList<QStandardItem *> items;
2143     items << new QStandardItem("c");
2144     model.insertColumn(0, items);
2145 }
2146
2147 void tst_QHeaderView::QTBUG12268_hiddenMovedSectionSorting()
2148 {
2149     QTableView view; // ### this test fails on QTableView &view = *m_tableview; !? + shadowing view member
2150     QStandardItemModel *model = new QStandardItemModel(4,3, &view);
2151     for (int i = 0; i< model->rowCount(); ++i)
2152         for (int j = 0; j< model->columnCount(); ++j)
2153             model->setData(model->index(i,j), QString("item [%1,%2]").arg(i).arg(j));
2154     view.setModel(model);
2155     view.horizontalHeader()->setSectionsMovable(true);
2156     view.setSortingEnabled(true);
2157     view.sortByColumn(1, Qt::AscendingOrder);
2158     view.horizontalHeader()->moveSection(0,2);
2159     view.setColumnHidden(1, true);
2160     view.show();
2161     QVERIFY(QTest::qWaitForWindowExposed(&view));
2162     QCOMPARE(view.horizontalHeader()->hiddenSectionCount(), 1);
2163     QTest::mouseClick(view.horizontalHeader()->viewport(), Qt::LeftButton);
2164     QCOMPARE(view.horizontalHeader()->hiddenSectionCount(), 1);
2165 }
2166
2167 void tst_QHeaderView::QTBUG14242_hideSectionAutoSize()
2168 {
2169     QTableView qtv;
2170     QStandardItemModel amodel(4, 4);
2171     qtv.setModel(&amodel);
2172     QHeaderView *hv = qtv.verticalHeader();
2173     hv->setDefaultSectionSize(25);
2174     hv->setSectionResizeMode(QHeaderView::ResizeToContents);
2175     qtv.show();
2176
2177     hv->hideSection(0);
2178     int afterlength = hv->length();
2179
2180     int calced_length = 0;
2181     for (int u = 0; u < hv->count(); ++u)
2182         calced_length += hv->sectionSize(u);
2183
2184     QVERIFY(calced_length == afterlength);
2185 }
2186
2187 void tst_QHeaderView::ensureNoIndexAtLength()
2188 {
2189     QTableView qtv;
2190     QStandardItemModel amodel(4, 4);
2191     qtv.setModel(&amodel);
2192     QHeaderView *hv = qtv.verticalHeader();
2193     QVERIFY(hv->visualIndexAt(hv->length()) == -1);
2194     hv->resizeSection(hv->count() - 1, 0);
2195     QVERIFY(hv->visualIndexAt(hv->length()) == -1);
2196 }
2197
2198 void tst_QHeaderView::offsetConsistent()
2199 {
2200     // Ensure that a hidden section 'far away'
2201     // does not affect setOffsetToSectionPosition ..
2202     const int sectionToHide = 513;
2203     QTableView qtv;
2204     QStandardItemModel amodel(1000, 4);
2205     qtv.setModel(&amodel);
2206     QHeaderView *hv = qtv.verticalHeader();
2207     for (int u = 0; u < 100; u += 2)
2208         hv->resizeSection(u, 0);
2209     hv->setOffsetToSectionPosition(150);
2210     int offset1 = hv->offset();
2211     hv->hideSection(sectionToHide);
2212     hv->setOffsetToSectionPosition(150);
2213     int offset2 = hv->offset();
2214     QVERIFY(offset1 == offset2);
2215     // Ensure that hidden indexes (still) is considered.
2216     hv->resizeSection(sectionToHide, hv->sectionSize(200) * 2);
2217     hv->setOffsetToSectionPosition(800);
2218     offset1 = hv->offset();
2219     hv->showSection(sectionToHide);
2220     hv->setOffsetToSectionPosition(800);
2221     offset2 = hv->offset();
2222     QVERIFY(offset2 > offset1);
2223 }
2224
2225 void tst_QHeaderView::initialSortOrderRole()
2226 {
2227     QTableView view; // ### Shadowing member view (of type QHeaderView)
2228     QStandardItemModel *model = new QStandardItemModel(4, 3, &view);
2229     for (int i = 0; i< model->rowCount(); ++i)
2230         for (int j = 0; j< model->columnCount(); ++j)
2231             model->setData(model->index(i,j), QString("item [%1,%2]").arg(i).arg(j));
2232     QStandardItem *ascendingItem = new QStandardItem();
2233     QStandardItem *descendingItem = new QStandardItem();
2234     ascendingItem->setData(Qt::AscendingOrder, Qt::InitialSortOrderRole);
2235     descendingItem->setData(Qt::DescendingOrder, Qt::InitialSortOrderRole);
2236     model->setHorizontalHeaderItem(1, ascendingItem);
2237     model->setHorizontalHeaderItem(2, descendingItem);
2238     view.setModel(model);
2239     view.setSortingEnabled(true);
2240     view.sortByColumn(0, Qt::AscendingOrder);
2241     view.show();
2242     QVERIFY(QTest::qWaitForWindowExposed(&view));
2243
2244     const int column1Pos = view.horizontalHeader()->sectionViewportPosition(1) + 5; // +5 not to be on the handle
2245     QTest::mouseClick(view.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(column1Pos, 0));
2246     QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), 1);
2247     QCOMPARE(view.horizontalHeader()->sortIndicatorOrder(), Qt::AscendingOrder);
2248
2249     const int column2Pos = view.horizontalHeader()->sectionViewportPosition(2) + 5; // +5 not to be on the handle
2250     QTest::mouseClick(view.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(column2Pos, 0));
2251     QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), 2);
2252     QCOMPARE(view.horizontalHeader()->sortIndicatorOrder(), Qt::DescendingOrder);
2253
2254     const int column0Pos = view.horizontalHeader()->sectionViewportPosition(0) + 5; // +5 not to be on the handle
2255     QTest::mouseClick(view.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(column0Pos, 0));
2256     QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), 0);
2257     QCOMPARE(view.horizontalHeader()->sortIndicatorOrder(), Qt::AscendingOrder);
2258 }
2259
2260 const bool block_some_signals = true; // The test should also work with this set to false
2261 const int rowcount = 500;
2262 const int colcount = 10;
2263
2264 QString istr(int n, bool comma = true)
2265 {
2266     QString s;
2267     s.setNum(n);
2268     if (comma)
2269         s += ", ";
2270     return s;
2271 }
2272
2273 void tst_QHeaderView::calculateAndCheck(int cppline, const int precalced_comparedata[])
2274 {
2275     qint64 endtimer = timer.elapsed();
2276     const bool silentmode = true;
2277     if (!silentmode)
2278         qDebug().nospace() << "(Time:" << endtimer << ")";
2279
2280     QString sline;
2281     sline.setNum(cppline - 1);
2282
2283     const int p1 = 3133777;      // just a prime (maybe not that random ;) )
2284     const int p2 = 135928393;    // just a random large prime - a bit less than signed 32-bit
2285
2286     int sum_visual = 0;
2287     int sum_logical = 0;
2288     int sum_size = 0;
2289     int sum_hidden_size = 0;
2290     int sum_lookup_visual = 0;
2291     int sum_lookup_logical = 0;
2292
2293     int chk_visual = 1;
2294     int chk_logical = 1;
2295     int chk_sizes = 1;
2296     int chk_hidden_size = 1;
2297     int chk_lookup_visual = 1;
2298     int chk_lookup_logical = 1;
2299
2300     int header_lenght = 0;
2301     int lastindex = view->count() - 1;
2302
2303     // calculate information based on index
2304     for (int i = 0; i <= lastindex; ++i) {
2305         int visual = view->visualIndex(i);
2306         int logical = view->logicalIndex(i);
2307         int ssize = view->sectionSize(i);
2308
2309         sum_visual += visual;
2310         sum_logical += logical;
2311         sum_size += ssize;
2312
2313         if (visual >= 0) {
2314             chk_visual %= p2;
2315             chk_visual *= (visual + 1) * (i + 1) * p1;
2316         }
2317
2318         if (logical >= 0) {
2319             chk_logical %= p2;
2320             chk_logical *= (logical + 1) * (i + 1 + (logical != i) ) * p1;
2321         }
2322
2323         if (ssize >= 0) {
2324             chk_sizes %= p2;
2325             chk_sizes *= ( (ssize + 2) * (i + 1) * p1);
2326         }
2327
2328         if (view->isSectionHidden(i)) {
2329             view->showSection(i);
2330             int hiddensize = view->sectionSize(i);
2331             sum_hidden_size += hiddensize;
2332             chk_hidden_size %= p2;
2333             chk_hidden_size += ( (hiddensize + 1) * (i + 1) * p1);
2334             // (hiddensize + 1) in the above to differ between hidden and size 0
2335             // Though it can be changed (why isn't sections with size 0 hidden?)
2336
2337             view->hideSection(i);
2338         }
2339     }
2340
2341     // lookup indexes by pixel position
2342     const int max_lookup_count = 500;
2343     int lookup_to = view->height() + 1;
2344     if (lookup_to > max_lookup_count)
2345         lookup_to = max_lookup_count; // We limit this lookup - not to spend years when testing.
2346                                       // Notice that lookupTest also has its own extra test
2347     for (int u = 0; u < max_lookup_count; ++u) {
2348         int visu = view->visualIndexAt(u);
2349         int logi = view->logicalIndexAt(u);
2350         sum_lookup_visual += logi;
2351         sum_lookup_logical += visu;
2352         chk_lookup_visual %= p2;
2353         chk_lookup_visual *= ( (u + 1) * p1 * (visu + 2));
2354         chk_lookup_logical %= p2;
2355         chk_lookup_logical *=  ( (u + 1) * p1 * (logi + 2));
2356     }
2357     header_lenght = view->length();
2358
2359     // visual and logical indexes.
2360     int sum_to_last_index = (lastindex * (lastindex + 1)) / 2; // == 0 + 1 + 2 + 3 + ... + lastindex
2361
2362     const bool write_calced_data = false;  // Do not write calculated output (unless the test fails)
2363     if (write_calced_data) {
2364         qDebug().nospace() << "(" << cppline - 1 << ")"  // << " const int precalced[] = "
2365                            << " {" << chk_visual << ", " << chk_logical << ", " << chk_sizes << ", " << chk_hidden_size
2366                            << ", " << chk_lookup_visual << ", " << chk_lookup_logical << ", " << header_lenght << "};";
2367     }
2368
2369     const bool sanity_checks = true;
2370     if (sanity_checks) {
2371         QString msg = QString("sanity problem at ") + sline;
2372         char *verifytext = QTest::toString(msg);
2373
2374         QVERIFY2(m_tableview->model()->rowCount() == view->count() , verifytext);
2375         QVERIFY2(view->visualIndex(lastindex + 1) <= 0, verifytext);       // there is no such index in model
2376         QVERIFY2(view->logicalIndex(lastindex + 1) <= 0, verifytext);      // there is no such index in model.
2377         QVERIFY2(view->logicalIndex(lastindex + 1) <= 0, verifytext);      // there is no such index in model.
2378         QVERIFY2(lastindex < 0 || view->visualIndex(0) >= 0, verifytext);   // no rows or legal index
2379         QVERIFY2(lastindex < 0 || view->logicalIndex(0) >= 0, verifytext);  // no rows or legal index
2380         QVERIFY2(lastindex < 0 || view->visualIndex(lastindex) >= 0, verifytext);  // no rows or legal index
2381         QVERIFY2(lastindex < 0 || view->logicalIndex(lastindex) >= 0, verifytext); // no rows or legal index
2382         QVERIFY2(view->visualIndexAt(-1) == -1, verifytext);
2383         QVERIFY2(view->logicalIndexAt(-1) == -1, verifytext);
2384         QVERIFY2(view->visualIndexAt(view->length()) == -1, verifytext);
2385         QVERIFY2(view->logicalIndexAt(view->length()) == -1, verifytext);
2386         QVERIFY2(sum_visual == sum_logical, verifytext);
2387         QVERIFY2(sum_to_last_index == sum_logical, verifytext);
2388     }
2389
2390     // Semantic test
2391     const bool check_semantics = true; // Otherwise there is no 'real' test
2392     if (!check_semantics)
2393         return;
2394
2395     const int *x = precalced_comparedata;
2396
2397     QString msg = "semantic problem at " + QString(__FILE__) + " (" + sline + ")";
2398     msg += "\nThe *expected* result was : {" + istr(x[0]) + istr(x[1]) + istr(x[2]) + istr(x[3])
2399         + istr(x[4]) + istr(x[5]) + istr(x[6], false) + "}";
2400     msg += "\nThe calculated result was : {";
2401     msg += istr(chk_visual) + istr(chk_logical) + istr(chk_sizes) + istr(chk_hidden_size)
2402         + istr(chk_lookup_visual) + istr(chk_lookup_logical) + istr(header_lenght, false) + "};";
2403
2404     char *verifytext = QTest::toString(msg);
2405
2406     QVERIFY2(chk_visual            == x[0], verifytext);
2407     QVERIFY2(chk_logical           == x[1], verifytext);
2408     QVERIFY2(chk_sizes             == x[2], verifytext);
2409     QVERIFY2(chk_hidden_size       == x[3], verifytext);
2410     QVERIFY2(chk_lookup_visual     == x[4], verifytext);
2411     QVERIFY2(chk_lookup_logical    == x[5], verifytext);
2412     QVERIFY2(header_lenght         == x[6], verifytext);
2413 }
2414
2415 void tst_QHeaderView::setupTestData(bool also_use_reset_model)
2416 {
2417     QTest::addColumn<bool>("updates_enabled");
2418     QTest::addColumn<bool>("special_prepare");
2419     QTest::addColumn<bool>("reset_model");
2420
2421     if (also_use_reset_model) {
2422         QTest::newRow("no_updates+normal+reset")  << false << false << true;
2423         QTest::newRow("hasupdates+normal+reset")  << true << false << true;
2424         QTest::newRow("no_updates+special+reset") << false << true << true;
2425         QTest::newRow("hasupdates+special+reset") << true << true << true;
2426     }
2427
2428     QTest::newRow("no_updates+normal")  << false << false << false;
2429     QTest::newRow("hasupdates+normal")  << true << false << false;
2430     QTest::newRow("no_updates+special") << false << true << false;
2431     QTest::newRow("hasupdates+special") << true << true << false;
2432 }
2433
2434 void tst_QHeaderView::additionalInit()
2435 {
2436     m_tableview->setVerticalHeader(view);
2437
2438     QFETCH(bool, updates_enabled);
2439     QFETCH(bool, special_prepare);
2440     QFETCH(bool, reset_model);
2441
2442     m_using_reset_model = reset_model;
2443
2444     if (m_using_reset_model) {
2445         XResetModel *m = new XResetModel();
2446         m_tableview->setModel(m);
2447         delete model;
2448         model = m;
2449     } else {
2450         m_tableview->setModel(model);
2451     }
2452
2453     const int default_section_size = 25;
2454     view->setDefaultSectionSize(default_section_size); // Important - otherwise there will be semantic changes
2455
2456     model->clear();
2457
2458     if (special_prepare) {
2459
2460         for (int u = 0; u <= rowcount; ++u) // ensures fragmented spans in e.g Qt 4.7
2461             model->setRowCount(u);
2462
2463         model->setColumnCount(colcount);
2464         view->swapSections(0, rowcount - 1);
2465         view->swapSections(0, rowcount - 1); // No real change - setup visual and log-indexes
2466         view->hideSection(rowcount - 1);
2467         view->showSection(rowcount - 1);  // No real change - (maybe init hidden vector)
2468     } else {
2469         model->setColumnCount(colcount);
2470         model->setRowCount(rowcount);
2471     }
2472
2473     QString s;
2474     for (int i = 0; i < model->rowCount(); ++i) {
2475         model->setData(model->index(i, 0), QVariant(i));
2476         s.setNum(i);
2477         s += ".";
2478         s += 'a' + (i % 25);
2479         model->setData(model->index(i, 1), QVariant(s));
2480     }
2481     m_tableview->setUpdatesEnabled(updates_enabled);
2482     view->blockSignals(block_some_signals);
2483     timer.start();
2484 }
2485
2486 void tst_QHeaderView::logicalIndexAtTest()
2487 {
2488     additionalInit();
2489
2490     view->swapSections(4, 9); // Make sure that visual and logical Indexes are not just the same.
2491
2492     int check1 = 0;
2493     int check2 = 0;
2494     for (int u = 0; u < model->rowCount(); ++u) {
2495         view->resizeSection(u, 10 + u % 30);
2496         int v = view->visualIndexAt(u * 29);
2497         view->visualIndexAt(u * 29);
2498         check1 += v;
2499         check2 += u * v;
2500     }
2501     view->resizeSection(0, 0); // Make sure that we have a 0 size section - before the result set
2502     view->setSectionHidden(6, true); // Make sure we have a real hidden section before result set
2503
2504     //qDebug() << "logicalIndexAtTest" << check1 << check2;
2505     const int precalced_check1 = 106327;
2506     const int precalced_check2 = 29856418;
2507     QVERIFY(precalced_check1 == check1);
2508     QVERIFY(precalced_check2 == check2);
2509
2510     const int precalced_results[] = { 1145298384, -1710423344, -650981936, 372919464, -1544372176, -426463328, 12124 };
2511     calculateAndCheck(__LINE__, precalced_results);
2512 }
2513
2514 void tst_QHeaderView::visualIndexAtTest()
2515 {
2516     additionalInit();
2517
2518     view->swapSections(4, 9); // Make sure that visual and logical Indexes are not just the same.
2519     int check1 = 0;
2520     int check2 = 0;
2521
2522     for (int u = 0; u < model->rowCount(); ++u) {
2523         view->resizeSection(u, 3 + u % 17);
2524         int v = view->visualIndexAt(u * 29);
2525         check1 += v;
2526         check2 += u * v;
2527     }
2528
2529     view->resizeSection(1, 0); // Make sure that we have a 0 size section - before the result set
2530     view->setSectionHidden(5, true); // Make sure we have a real hidden section before result set
2531
2532     //qDebug() << "visualIndexAtTest" << check1 << check2;
2533     const int precalced_check1 = 72665;
2534     const int precalced_check2 = 14015890;
2535     QVERIFY(precalced_check1 == check1);
2536     QVERIFY(precalced_check2 == check2);
2537
2538     const int precalced_results[] = { 1145298384, -1710423344, -1457520212, 169223959, 557466160, -324939600, 5453 };
2539     calculateAndCheck(__LINE__, precalced_results);
2540 }
2541
2542 void tst_QHeaderView::hideShowTest()
2543 {
2544     additionalInit();
2545
2546     for (int u = model->rowCount(); u >= 0; --u)
2547         if (u % 8 != 0)
2548             view->hideSection(u);
2549
2550     for (int u = model->rowCount(); u >= 0; --u)
2551         if (u % 3 == 0)
2552             view->showSection(u);
2553
2554     view->setSectionHidden(model->rowCount(), true); // invalid hide (should be ignored)
2555     view->setSectionHidden(-1, true); // invalid hide (should be ignored)
2556
2557     const int precalced_results[] = { -1523279360, -1523279360, -1321506816, 2105322423, 1879611280, 1879611280, 5225 };
2558     calculateAndCheck(__LINE__, precalced_results);
2559 }
2560
2561 void tst_QHeaderView::swapSectionsTest()
2562 {
2563     additionalInit();
2564
2565     for (int u = 0; u < rowcount / 2; ++u)
2566         view->swapSections(u, rowcount - u - 1);
2567
2568     for (int u = 0; u < rowcount; u += 2)
2569         view->swapSections(u, u + 1);
2570
2571     view->swapSections(0, model->rowCount()); // invalid swapsection (should be ignored)
2572
2573     const int precalced_results[] = { -1536450048, -1774641430, -1347156568, 1, 1719705216, -240077576, 12500 };
2574     calculateAndCheck(__LINE__, precalced_results);
2575 }
2576
2577 void tst_QHeaderView::moveSectionTest()
2578 {
2579     additionalInit();
2580
2581     for (int u = 1; u < 5; ++u)
2582         view->moveSection(u, model->rowCount() - u);
2583
2584     view->moveSection(2, model->rowCount() / 2);
2585     view->moveSection(0, 10);
2586     view->moveSection(0, model->rowCount() - 10);
2587
2588     view->moveSection(0, model->rowCount()); // invalid move (should be ignored)
2589
2590     const int precalced_results[] = { 645125952, 577086896, -1347156568, 1, 1719705216, 709383416, 12500 };
2591     calculateAndCheck(__LINE__, precalced_results);
2592 }
2593
2594 void tst_QHeaderView::defaultSizeTest()
2595 {
2596     additionalInit();
2597
2598     view->hideSection(rowcount / 2);
2599     int restore_to = view->defaultSectionSize();
2600     view->setDefaultSectionSize(restore_to + 5);
2601
2602     const int precalced_results[] = { -1523279360, -1523279360, -1739688320, -1023807777, 997629696, 997629696, 14970 };
2603     calculateAndCheck(__LINE__, precalced_results);
2604
2605     view->setDefaultSectionSize(restore_to);
2606 }
2607
2608 void tst_QHeaderView::removeTest()
2609 {
2610     additionalInit();
2611
2612     view->swapSections(0, 5);
2613     model->removeRows(0, 1);   // remove one row
2614     model->removeRows(4, 10);
2615     model->setRowCount(model->rowCount() / 2 - 1);
2616
2617     if (m_using_reset_model) {
2618         const int precalced_results[] = { 1741224292, -135269187, -569519837, 1, 1719705216, -1184395000, 6075 };
2619         calculateAndCheck(__LINE__, precalced_results);
2620     } else {
2621         const int precalced_results[] = { 289162397, 289162397, -569519837, 1, 1719705216, 1719705216, 6075 };
2622         calculateAndCheck(__LINE__, precalced_results);
2623     }
2624 }
2625
2626 void tst_QHeaderView::insertTest()
2627 {
2628     additionalInit();
2629
2630     view->swapSections(0, model->rowCount() - 1);
2631     model->insertRows(0, 1);   // insert one row
2632     model->insertRows(4, 10);
2633     model->setRowCount(model->rowCount() * 2 - 1);
2634
2635     if (m_using_reset_model) {
2636         const int precalced_results[] = { 2040508069, -1280266538, -150350734, 1, 1719705216, 1331312784, 25525 };
2637         calculateAndCheck(__LINE__, precalced_results);
2638     } else {
2639         const int precalced_results[] = { -1909447021, 339092083, -150350734, 1, 1719705216, -969712728, 25525 };
2640         calculateAndCheck(__LINE__, precalced_results);
2641     }
2642 }
2643
2644 void tst_QHeaderView::mixedTests()
2645 {
2646     additionalInit();
2647
2648     model->setRowCount(model->rowCount() + 10);
2649
2650     for (int u = 0; u < model->rowCount(); u += 2)
2651         view->swapSections(u, u + 1);
2652
2653     view->moveSection(0, 5);
2654
2655     for (int u = model->rowCount(); u >= 0; --u) {
2656         if (u % 5 != 0)
2657             view->hideSection(u);
2658         if (u % 3 != 0)
2659             view->showSection(u);
2660     }
2661
2662     model->insertRows(3, 7);
2663     model->removeRows(8, 3);
2664     model->setRowCount(model->rowCount() - 10);
2665
2666     if (m_using_reset_model) {
2667         const int precalced_results[] = { 898296472, 337096378, -543340640, 1, -1251526424, -568618976, 9250 };
2668         calculateAndCheck(__LINE__, precalced_results);
2669     } else {
2670         const int precalced_results[] = { 1911338224, 1693514365, -613398968, -1912534953, 1582159424, -1851079000, 9300 };
2671         calculateAndCheck(__LINE__, precalced_results);
2672     }
2673 }
2674
2675 void tst_QHeaderView::resizeToContentTest()
2676 {
2677     additionalInit();
2678
2679     QModelIndex idx = model->index(2, 2);
2680     model->setData(idx, QVariant("A normal string"));
2681
2682     idx = model->index(1, 3);
2683     model->setData(idx, QVariant("A normal longer string to test resize"));
2684
2685     QHeaderView *hh = m_tableview->horizontalHeader();
2686     hh->resizeSections(QHeaderView::ResizeToContents);
2687     QVERIFY(hh->sectionSize(3) > hh->sectionSize(2));
2688
2689     for (int u = 0; u < 10; ++u)
2690         view->resizeSection(u, 1);
2691
2692     view->resizeSections(QHeaderView::ResizeToContents);
2693     QVERIFY(view->sectionSize(1) > 1);
2694     QVERIFY(view->sectionSize(2) > 1);
2695
2696     view->setDefaultSectionSize(25); // To make sure our precalced data are correct. We do not know font height etc.
2697
2698     const int precalced_results[] =  { -1523279360, -1523279360, -1347156568, 1, 1719705216, 1719705216, 12500 };
2699     calculateAndCheck(__LINE__, precalced_results);
2700 }
2701
2702 void tst_QHeaderView::testStreamWithHide()
2703 {
2704 #ifndef QT_NO_DATASTREAM
2705     m_tableview->setVerticalHeader(view);
2706     m_tableview->setModel(model);
2707     view->setDefaultSectionSize(25);
2708     view->hideSection(2);
2709     view->swapSections(1, 2);
2710
2711     QByteArray s = view->saveState();
2712     view->swapSections(1, 2);
2713     view->setDefaultSectionSize(30); // To make sure our precalced data are correct.
2714     view->restoreState(s);
2715
2716     const int precalced_results[] =  { -1116614432, -1528653200, -1914165644, 244434607, -1111214068, 750357900, 75};
2717     calculateAndCheck(__LINE__, precalced_results);
2718 #else
2719     QSKIP("Datastream required for testStreamWithHide. Skipping this test.");
2720 #endif
2721 }
2722
2723 QTEST_MAIN(tst_QHeaderView)
2724 #include "tst_qheaderview.moc"