1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43 #include <QtTest/QtTest>
44 #include <QStandardItemModel>
45 #include <QStringListModel>
46 #include <QSortFilterProxyModel>
47 #include <QTableView>
48
49 #include <qabstractitemmodel.h>
50 #include <qapplication.h>
51 #include <qheaderview.h>
52 #include <private/qheaderview_p.h>
53 #include <qitemdelegate.h>
54 #include <qtreewidget.h>
55 #include <qdebug.h>
56
57 typedef QList<int> IntList;
58 Q_DECLARE_METATYPE(IntList)
59
60 typedef QList<bool> BoolList;
61 Q_DECLARE_METATYPE(BoolList)
62
63 //TESTED_CLASS=
64 //TESTED_FILES=
65
66 // Will try to wait for the condition while allowing event processing
67 // for a maximum of 2 seconds.
68 #define WAIT_FOR_CONDITION(expr, expected) \
69 do { \
70 const int step = 100; \
71 for (int i = 0; i < 2000 && expr != expected; i+=step) { \
72 QTest::qWait(step); \
73 } \
74 } while(0)
75
76 class protected_QHeaderView : public QHeaderView
77 {
78 Q_OBJECT
79 public:
protected_QHeaderView(Qt::Orientation orientation)80 protected_QHeaderView(Qt::Orientation orientation) : QHeaderView(orientation) {
81 resizeSections();
82 };
83
84 void testEvent();
85 void testhorizontalOffset();
86 void testverticalOffset();
87 friend class tst_QHeaderView;
88 };
89
90 class tst_QHeaderView : public QObject
91 {
92 Q_OBJECT
93
94 public:
95 tst_QHeaderView();
96 virtual ~tst_QHeaderView();
97
98 public slots:
99 void initTestCase();
100 void cleanupTestCase();
101 void init();
102 void cleanup();
103
104 private slots:
105 void getSetCheck();
106 void visualIndex();
107
108 void visualIndexAt_data();
109 void visualIndexAt();
110
111 void noModel();
112 void emptyModel();
113 void removeRows();
114 void removeCols();
115
116 void clickable();
117 void movable();
118 void hidden();
119 void stretch();
120
121 void sectionSize_data();
122 void sectionSize();
123
124 void length();
125 void offset();
126 void sectionSizeHint();
127 void logicalIndex();
128 void logicalIndexAt();
129 void swapSections();
130
131 void moveSection_data();
132 void moveSection();
133
134 void resizeMode();
135
136 void resizeSection_data();
137 void resizeSection();
138
139 void resizeAndMoveSection_data();
140 void resizeAndMoveSection();
141 void resizeHiddenSection_data();
142 void resizeHiddenSection();
143 void resizeAndInsertSection_data();
144 void resizeAndInsertSection();
145 void resizeWithResizeModes_data();
146 void resizeWithResizeModes();
147 void moveAndInsertSection_data();
148 void moveAndInsertSection();
149 void highlightSections();
150 void showSortIndicator();
151 void sortIndicatorTracking();
152 void removeAndInsertRow();
153 void unhideSection();
154 void event();
155 void headerDataChanged();
156 void currentChanged();
157 void horizontalOffset();
158 void verticalOffset();
159 void stretchSectionCount();
160 void hiddenSectionCount();
161 void focusPolicy();
162 void moveSectionAndReset();
163 void moveSectionAndRemove();
164 void saveRestore();
165
166 void defaultAlignment_data();
167 void defaultAlignment();
168
169 void globalResizeMode_data();
170 void globalResizeMode();
171
172 void sectionPressedSignal_data();
173 void sectionPressedSignal();
sectionClickedSignal_data()174 void sectionClickedSignal_data() { sectionPressedSignal_data(); }
175 void sectionClickedSignal();
176
177 void defaultSectionSize_data();
178 void defaultSectionSize();
179
180 void oneSectionSize();
181
182 void hideAndInsert_data();
183 void hideAndInsert();
184
185 void removeSection();
186 void preserveHiddenSectionWidth();
187 void invisibleStretchLastSection();
188
189 void emptySectionSpan();
190 void task236450_hidden_data();
191 void task236450_hidden();
192 void task248050_hideRow();
193 void QTBUG6058_reset();
194 void QTBUG7833_sectionClicked();
195 void QTBUG8650_crashOnInsertSections();
196 void QTBUG12268_hiddenMovedSectionSorting();
197 void QTBUG14242_hideSectionAutoSize();
198
199 void initialSortOrderRole();
200 void ensureNoIndexAtLength();
201
202 protected:
203 QWidget *topLevel;
204 QHeaderView *view;
205 QStandardItemModel *model;
206 };
207
208 class QtTestModel: public QAbstractTableModel
209 {
210
211 Q_OBJECT
212
213 public:
QtTestModel(QObject * parent=0)214 QtTestModel(QObject *parent = 0): QAbstractTableModel(parent),
215 cols(0), rows(0), wrongIndex(false) {}
rowCount(const QModelIndex &) const216 int rowCount(const QModelIndex&) const { return rows; }
columnCount(const QModelIndex &) const217 int columnCount(const QModelIndex&) const { return cols; }
isEditable(const QModelIndex &) const218 bool isEditable(const QModelIndex &) const { return true; }
219
data(const QModelIndex & idx,int) const220 QVariant data(const QModelIndex &idx, int) const
221 {
222 if (idx.row() < 0 || idx.column() < 0 || idx.column() >= cols || idx.row() >= rows) {
223 wrongIndex = true;
224 qWarning("Invalid modelIndex [%d,%d,%p]", idx.row(), idx.column(), idx.internalPointer());
225 }
226 return QString("[%1,%2,%3]").arg(idx.row()).arg(idx.column()).arg(0);//idx.data());
227 }
228
insertOneColumn(int col)229 void insertOneColumn(int col)
230 {
231 beginInsertColumns(QModelIndex(), col, col);
232 --cols;
233 endInsertColumns();
234 }
235
removeLastRow()236 void removeLastRow()
237 {
238 beginRemoveRows(QModelIndex(), rows - 1, rows - 1);
239 --rows;
240 endRemoveRows();
241 }
242
removeAllRows()243 void removeAllRows()
244 {
245 beginRemoveRows(QModelIndex(), 0, rows - 1);
246 rows = 0;
247 endRemoveRows();
248 }
249
removeOneColumn(int col)250 void removeOneColumn(int col)
251 {
252 beginRemoveColumns(QModelIndex(), col, col);
253 --cols;
254 endRemoveColumns();
255 }
256
removeLastColumn()257 void removeLastColumn()
258 {
259 beginRemoveColumns(QModelIndex(), cols - 1, cols - 1);
260 --cols;
261 endRemoveColumns();
262 }
263
removeAllColumns()264 void removeAllColumns()
265 {
266 beginRemoveColumns(QModelIndex(), 0, cols - 1);
267 cols = 0;
268 endRemoveColumns();
269 }
270
cleanup()271 void cleanup()
272 {
273 cols = 3;
274 rows = 3;
275 emit layoutChanged();
276 }
277
278 int cols, rows;
279 mutable bool wrongIndex;
280 };
281
282 // Testing get/set functions
getSetCheck()283 void tst_QHeaderView::getSetCheck()
284 {
285 protected_QHeaderView obj1(Qt::Horizontal);
286 // bool QHeaderView::highlightSections()
287 // void QHeaderView::setHighlightSections(bool)
288 obj1.setHighlightSections(false);
289 QCOMPARE(false, obj1.highlightSections());
290 obj1.setHighlightSections(true);
291 QCOMPARE(true, obj1.highlightSections());
292
293 // bool QHeaderView::stretchLastSection()
294 // void QHeaderView::setStretchLastSection(bool)
295 obj1.setStretchLastSection(false);
296 QCOMPARE(false, obj1.stretchLastSection());
297 obj1.setStretchLastSection(true);
298 QCOMPARE(true, obj1.stretchLastSection());
299
300 // int QHeaderView::defaultSectionSize()
301 // void QHeaderView::setDefaultSectionSize(int)
302 obj1.setDefaultSectionSize(0);
303 QCOMPARE(0, obj1.defaultSectionSize());
304 obj1.setDefaultSectionSize(INT_MIN);
305 QCOMPARE(INT_MIN, obj1.defaultSectionSize());
306 obj1.setDefaultSectionSize(INT_MAX);
307 QCOMPARE(INT_MAX, obj1.defaultSectionSize());
308 // ### the test above does not make sense for values below 0
309
310 // int QHeaderView::minimumSectionSize()
311 // void QHeaderView::setMinimumSectionSize(int)
312 obj1.setMinimumSectionSize(0);
313 QCOMPARE(0, obj1.minimumSectionSize());
314 obj1.setMinimumSectionSize(INT_MIN);
315 QCOMPARE(INT_MIN, obj1.minimumSectionSize());
316 obj1.setMinimumSectionSize(INT_MAX);
317 QCOMPARE(INT_MAX, obj1.minimumSectionSize());
318 // ### the test above does not make sense for values below 0
319
320 // int QHeaderView::offset()
321 // void QHeaderView::setOffset(int)
322 obj1.setOffset(0);
323 QCOMPARE(0, obj1.offset());
324 obj1.setOffset(INT_MIN);
325 QCOMPARE(INT_MIN, obj1.offset());
326 obj1.setOffset(INT_MAX);
327 QCOMPARE(INT_MAX, obj1.offset());
328
329 }
330
tst_QHeaderView()331 tst_QHeaderView::tst_QHeaderView()
332 {
333 qRegisterMetaType<int>("Qt::SortOrder");
334 }
335
~tst_QHeaderView()336 tst_QHeaderView::~tst_QHeaderView()
337 {
338 }
339
initTestCase()340 void tst_QHeaderView::initTestCase()
341 {
342 #ifdef Q_OS_WINCE //disable magic for WindowsCE
343 qApp->setAutoMaximizeThreshold(-1);
344 #endif
345 }
346
cleanupTestCase()347 void tst_QHeaderView::cleanupTestCase()
348 {
349 }
350
init()351 void tst_QHeaderView::init()
352 {
353 topLevel = new QWidget();
354 view = new QHeaderView(Qt::Vertical,topLevel);
355 // Some initial value tests before a model is added
356 QCOMPARE(view->length(), 0);
357 QVERIFY(view->sizeHint() == QSize(0,0));
358 QCOMPARE(view->sectionSizeHint(0), -1);
359
360 /*
361 model = new QStandardItemModel(1, 1);
362 view->setModel(model);
363 //qDebug() << view->count();
364 view->sizeHint();
365 */
366
367 int rows = 4;
368 int columns = 4;
369 model = new QStandardItemModel(rows, columns);
370 /*
371 for (int row = 0; row < rows; ++row) {
372 for (int column = 0; column < columns; ++column) {
373 QModelIndex index = model->index(row, column, QModelIndex());
374 model->setData(index, QVariant((row+1) * (column+1)));
375 }
376 }
377 */
378
379 QSignalSpy spy(view, SIGNAL(sectionCountChanged(int, int)));
380 view->setModel(model);
381 QCOMPARE(spy.count(), 1);
382 view->resize(200,200);
383 topLevel->show();
384 }
385
cleanup()386 void tst_QHeaderView::cleanup()
387 {
388 delete view;
389 view = 0;
390 delete model;
391 model = 0;
392 }
393
noModel()394 void tst_QHeaderView::noModel()
395 {
396 QHeaderView emptyView(Qt::Vertical);
397 QCOMPARE(emptyView.count(), 0);
398 }
399
emptyModel()400 void tst_QHeaderView::emptyModel()
401 {
402 QtTestModel testmodel;
403 view->setModel(&testmodel);
404 QVERIFY(!testmodel.wrongIndex);
405 QCOMPARE(view->count(), testmodel.rows);
406 view->setModel(model);
407 }
408
removeRows()409 void tst_QHeaderView::removeRows()
410 {
411 QtTestModel model;
412 model.rows = model.cols = 10;
413
414 QHeaderView vertical(Qt::Vertical);
415 QHeaderView horizontal(Qt::Horizontal);
416
417 vertical.setModel(&model);
418 horizontal.setModel(&model);
419 vertical.show();
420 horizontal.show();
421 QCOMPARE(vertical.count(), model.rows);
422 QCOMPARE(horizontal.count(), model.cols);
423
424 model.removeLastRow();
425 QVERIFY(!model.wrongIndex);
426 QCOMPARE(vertical.count(), model.rows);
427 QCOMPARE(horizontal.count(), model.cols);
428
429 model.removeAllRows();
430 QVERIFY(!model.wrongIndex);
431 QCOMPARE(vertical.count(), model.rows);
432 QCOMPARE(horizontal.count(), model.cols);
433 }
434
435
removeCols()436 void tst_QHeaderView::removeCols()
437 {
438 QtTestModel model;
439 model.rows = model.cols = 10;
440
441 QHeaderView vertical(Qt::Vertical);
442 QHeaderView horizontal(Qt::Horizontal);
443 vertical.setModel(&model);
444 horizontal.setModel(&model);
445 vertical.show();
446 horizontal.show();
447 QCOMPARE(vertical.count(), model.rows);
448 QCOMPARE(horizontal.count(), model.cols);
449
450 model.removeLastColumn();
451 QVERIFY(!model.wrongIndex);
452 QCOMPARE(vertical.count(), model.rows);
453 QCOMPARE(horizontal.count(), model.cols);
454
455 model.removeAllColumns();
456 QVERIFY(!model.wrongIndex);
457 QCOMPARE(vertical.count(), model.rows);
458 QCOMPARE(horizontal.count(), model.cols);
459 }
460
movable()461 void tst_QHeaderView::movable()
462 {
463 QCOMPARE(view->isMovable(), false);
464 view->setMovable(false);
465 QCOMPARE(view->isMovable(), false);
466 view->setMovable(true);
467 QCOMPARE(view->isMovable(), true);
468 }
469
clickable()470 void tst_QHeaderView::clickable()
471 {
472 QCOMPARE(view->isClickable(), false);
473 view->setClickable(false);
474 QCOMPARE(view->isClickable(), false);
475 view->setClickable(true);
476 QCOMPARE(view->isClickable(), true);
477 }
478
hidden()479 void tst_QHeaderView::hidden()
480 {
481 //hideSection() & showSection call setSectionHidden
482 // Test bad arguments
483 QCOMPARE(view->isSectionHidden(-1), false);
484 QCOMPARE(view->isSectionHidden(view->count()), false);
485 QCOMPARE(view->isSectionHidden(999999), false);
486
487 view->setSectionHidden(-1, true);
488 view->setSectionHidden(view->count(), true);
489 view->setSectionHidden(999999, true);
490 view->setSectionHidden(-1, false);
491 view->setSectionHidden(view->count(), false);
492 view->setSectionHidden(999999, false);
493
494 // Hidden sections shouldn't have visual properties (except position)
495 int pos = view->defaultSectionSize();
496 view->setSectionHidden(1, true);
497 QCOMPARE(view->sectionSize(1), 0);
498 QCOMPARE(view->sectionPosition(1), pos);
499 view->resizeSection(1, 100);
500 QCOMPARE(view->sectionViewportPosition(1), pos);
501 QCOMPARE(view->sectionSize(1), 0);
502 view->setSectionHidden(1, false);
503 QCOMPARE(view->isSectionHidden(0), false);
504 QCOMPARE(view->sectionSize(0), view->defaultSectionSize());
505 }
506
stretch()507 void tst_QHeaderView::stretch()
508 {
509 // Show before resize and setStrechLastSection
510 #if defined(Q_OS_WINCE)
511 QSize viewSize(200,300);
512 #else
513 QSize viewSize(500, 500);
514 #endif
515 view->resize(viewSize);
516 view->setStretchLastSection(true);
517 QCOMPARE(view->stretchLastSection(), true);
518 topLevel->show();
519 QCOMPARE(view->width(), viewSize.width());
520 QCOMPARE(view->visualIndexAt(view->viewport()->height() - 5), 3);
521
522 view->setSectionHidden(3, true);
523 QCOMPARE(view->visualIndexAt(view->viewport()->height() - 5), 2);
524
525 view->setStretchLastSection(false);
526 QCOMPARE(view->stretchLastSection(), false);
527 }
528
oneSectionSize()529 void tst_QHeaderView::oneSectionSize()
530 {
531 //this ensures that if there is only one section, it gets a correct width (more than 0)
532 QHeaderView view (Qt::Vertical);
533 QtTestModel model;
534 model.cols = 1;
535 model.rows = 1;
536
537 view.setResizeMode(QHeaderView::Interactive);
538 view.setModel(&model);
539
540 view.show();
541
542 QVERIFY(view.sectionSize(0) > 0);
543 }
544
545
sectionSize_data()546 void tst_QHeaderView::sectionSize_data()
547 {
548 QTest::addColumn<QList<int> >("boundsCheck");
549 QTest::addColumn<QList<int> >("defaultSizes");
550 QTest::addColumn<int>("initialDefaultSize");
551 QTest::addColumn<int>("lastVisibleSectionSize");
552 QTest::addColumn<int>("persistentSectionSize");
553
554 QTest::newRow("data set one")
555 << (QList<int>() << -1 << 0 << 4 << 9999)
556 << (QList<int>() << 10 << 30 << 30)
557 << 30
558 << 300
559 << 20;
560 }
561
sectionSize()562 void tst_QHeaderView::sectionSize()
563 {
564 QFETCH(QList<int>, boundsCheck);
565 QFETCH(QList<int>, defaultSizes);
566 QFETCH(int, initialDefaultSize);
567 QFETCH(int, lastVisibleSectionSize);
568 QFETCH(int, persistentSectionSize);
569
570 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
571 // We test on a device with doubled pixels. Therefore we need to specify
572 // different boundaries.
573 initialDefaultSize = qMax(view->minimumSectionSize(), 30);
574 #endif
575
576 // bounds check
577 foreach (int val, boundsCheck)
578 view->sectionSize(val);
579
580 // default size
581 QCOMPARE(view->defaultSectionSize(), initialDefaultSize);
582 foreach (int def, defaultSizes) {
583 view->setDefaultSectionSize(def);
584 QCOMPARE(view->defaultSectionSize(), def);
585 }
586
587 view->setDefaultSectionSize(initialDefaultSize);
588 for (int s = 0; s < view->count(); ++s)
589 QCOMPARE(view->sectionSize(s), initialDefaultSize);
590 view->doItemsLayout();
591
592 // stretch last section
593 view->setStretchLastSection(true);
594 int lastSection = view->count() - 1;
595
596 //test that when hiding the last column,
597 //resizing the new last visible columns still works
598 view->hideSection(lastSection);
599 view->resizeSection(lastSection - 1, lastVisibleSectionSize);
600 QCOMPARE(view->sectionSize(lastSection - 1), lastVisibleSectionSize);
601 view->showSection(lastSection);
602
603 // turn off stretching
604 view->setStretchLastSection(false);
605 QCOMPARE(view->sectionSize(lastSection), initialDefaultSize);
606
607 // test persistence
608 int sectionCount = view->count();
609 for (int i = 0; i < sectionCount; ++i)
610 view->resizeSection(i, persistentSectionSize);
611 QtTestModel model;
612 model.cols = sectionCount * 2;
613 model.rows = sectionCount * 2;
614 view->setModel(&model);
615 for (int j = 0; j < sectionCount; ++j)
616 QCOMPARE(view->sectionSize(j), persistentSectionSize);
617 for (int k = sectionCount; k < view->count(); ++k)
618 QCOMPARE(view->sectionSize(k), initialDefaultSize);
619 }
620
visualIndex()621 void tst_QHeaderView::visualIndex()
622 {
623 // Test bad arguments
624 QCOMPARE(view->visualIndex(999999), -1);
625 QCOMPARE(view->visualIndex(-1), -1);
626 QCOMPARE(view->visualIndex(1), 1);
627 view->setSectionHidden(1, true);
628 QCOMPARE(view->visualIndex(1), 1);
629 QCOMPARE(view->visualIndex(2), 2);
630
631 view->setSectionHidden(1, false);
632 QCOMPARE(view->visualIndex(1), 1);
633 QCOMPARE(view->visualIndex(2), 2);
634 }
635
visualIndexAt_data()636 void tst_QHeaderView::visualIndexAt_data()
637 {
638 QTest::addColumn<QList<int> >("hidden");
639 QTest::addColumn<QList<int> >("from");
640 QTest::addColumn<QList<int> >("to");
641 QTest::addColumn<QList<int> >("coordinate");
642 QTest::addColumn<QList<int> >("visual");
643
644 QList<int> coordinateList;
645 #ifndef Q_OS_WINCE
646 coordinateList << -1 << 0 << 31 << 91 << 99999;
647 #else
648 // We test on a device with doubled pixels. Therefore we need to specify
649 // different boundaries.
650 coordinateList << -1 << 0 << 33 << 97 << 99999;
651 #endif
652
653 QTest::newRow("no hidden, no moved sections")
654 << QList<int>()
655 << QList<int>()
656 << QList<int>()
657 << coordinateList
658 << (QList<int>() << -1 << 0 << 1 << 3 << -1);
659
660 QTest::newRow("no hidden, moved sections")
661 << QList<int>()
662 << (QList<int>() << 0)
663 << (QList<int>() << 1)
664 << coordinateList
665 << (QList<int>() << -1 << 0 << 1 << 3 << -1);
666
667 QTest::newRow("hidden, no moved sections")
668 << (QList<int>() << 0)
669 << QList<int>()
670 << QList<int>()
671 << coordinateList
672 << (QList<int>() << -1 << 1 << 2 << 3 << -1);
673 }
674
visualIndexAt()675 void tst_QHeaderView::visualIndexAt()
676 {
677 QFETCH(QList<int>, hidden);
678 QFETCH(QList<int>, from);
679 QFETCH(QList<int>, to);
680 QFETCH(QList<int>, coordinate);
681 QFETCH(QList<int>, visual);
682
683 #ifdef Q_OS_SYMBIAN
684 // Some Symbian devices have larger minimum section size than what is expected.
685 // Need to do this here instead of visualIndexAt_data() as view pointer doesn't
686 // seem to be valid there.
687 int minSize = view->minimumSectionSize();
688 if (minSize > 30) {
689 coordinate.clear();
690 coordinate << -1 << 0 << minSize + 1 << (minSize * 3) + 1 << 99999;
691 }
692 #endif
693 view->setStretchLastSection(true);
694 topLevel->show();
695
696 for (int i = 0; i < hidden.count(); ++i)
697 view->setSectionHidden(hidden.at(i), true);
698
699 for (int j = 0; j < from.count(); ++j)
700 view->moveSection(from.at(j), to.at(j));
701
702 QTest::qWait(100);
703
704 for (int k = 0; k < coordinate.count(); ++k)
705 QCOMPARE(view->visualIndexAt(coordinate.at(k)), visual.at(k));
706 }
707
length()708 void tst_QHeaderView::length()
709 {
710 #if defined(Q_OS_WINCE)
711 QFont font(QLatin1String("Tahoma"), 7);
712 view->setFont(font);
713 #elif defined(Q_OS_SYMBIAN)
714 QFont font(QLatin1String("Series 60 Sans"), 6);
715 view->setFont(font);
716 #endif
717 view->setStretchLastSection(true);
718 topLevel->show();
719
720 //minimumSectionSize should be the size of the last section of the widget is not tall enough
721 int length = view->minimumSectionSize();
722 for (int i=0; i < view->count()-1; i++) {
723 length += view->sectionSize(i);
724 }
725
726 length = qMax(length, view->viewport()->height());
727 QCOMPARE(length, view->length());
728
729 view->setStretchLastSection(false);
730 topLevel->show();
731
732 QVERIFY(length != view->length());
733
734 // layoutChanged might mean rows have been removed
735 QtTestModel model;
736 model.cols = 10;
737 model.rows = 10;
738 view->setModel(&model);
739 int oldLength = view->length();
740 model.cleanup();
741 QCOMPARE(model.rows, view->count());
742 QVERIFY(oldLength != view->length());
743 }
744
offset()745 void tst_QHeaderView::offset()
746 {
747 QCOMPARE(view->offset(), 0);
748 view->setOffset(10);
749 QCOMPARE(view->offset(), 10);
750 view->setOffset(0);
751 QCOMPARE(view->offset(), 0);
752
753 // Test odd arguments
754 view->setOffset(-1);
755 }
756
sectionSizeHint()757 void tst_QHeaderView::sectionSizeHint()
758 {
759 // Test bad arguments
760 view->sectionSizeHint(-1);
761 view->sectionSizeHint(99999);
762
763 // TODO how to test the return value?
764 }
765
logicalIndex()766 void tst_QHeaderView::logicalIndex()
767 {
768 // Test bad arguments
769 QCOMPARE(view->logicalIndex(-1), -1);
770 QCOMPARE(view->logicalIndex(99999), -1);
771 }
772
logicalIndexAt()773 void tst_QHeaderView::logicalIndexAt()
774 {
775 // Test bad arguments
776 view->logicalIndexAt(-1);
777 view->logicalIndexAt(99999);
778 QCOMPARE(view->logicalIndexAt(0), 0);
779 QCOMPARE(view->logicalIndexAt(1), 0);
780
781 topLevel->show();
782 view->setStretchLastSection(true);
783 // First item
784 QCOMPARE(view->logicalIndexAt(0), 0);
785 QCOMPARE(view->logicalIndexAt(view->sectionSize(0)-1), 0);
786 QCOMPARE(view->logicalIndexAt(view->sectionSize(0)+1), 1);
787 // Last item
788 int last = view->length() - 1;//view->viewport()->height() - 10;
789 QCOMPARE(view->logicalIndexAt(last), 3);
790 // Not in widget
791 int outofbounds = view->length() + 1;//view->viewport()->height() + 1;
792 QCOMPARE(view->logicalIndexAt(outofbounds), -1);
793
794 view->moveSection(0,1);
795 // First item
796 QCOMPARE(view->logicalIndexAt(0), 1);
797 QCOMPARE(view->logicalIndexAt(view->sectionSize(0)-1), 1);
798 QCOMPARE(view->logicalIndexAt(view->sectionSize(0)+1), 0);
799 // Last item
800 QCOMPARE(view->logicalIndexAt(last), 3);
801 view->moveSection(1,0);
802
803 }
804
swapSections()805 void tst_QHeaderView::swapSections()
806 {
807 view->swapSections(-1, 1);
808 view->swapSections(99999, 1);
809 view->swapSections(1, -1);
810 view->swapSections(1, 99999);
811
812 QVector<int> logical = (QVector<int>() << 0 << 1 << 2 << 3);
813
814 QSignalSpy spy1(view, SIGNAL(sectionMoved(int, int, int)));
815
816 QCOMPARE(view->sectionsMoved(), false);
817 view->swapSections(1, 1);
818 QCOMPARE(view->sectionsMoved(), false);
819 view->swapSections(1, 2);
820 QCOMPARE(view->sectionsMoved(), true);
821 view->swapSections(2, 1);
822 QCOMPARE(view->sectionsMoved(), true);
823 for (int i = 0; i < view->count(); ++i)
824 QCOMPARE(view->logicalIndex(i), logical.at(i));
825 QCOMPARE(spy1.count(), 4);
826
827 logical = (QVector<int>() << 3 << 1 << 2 << 0);
828 view->swapSections(3, 0);
829 QCOMPARE(view->sectionsMoved(), true);
830 for (int j = 0; j < view->count(); ++j)
831 QCOMPARE(view->logicalIndex(j), logical.at(j));
832 QCOMPARE(spy1.count(), 6);
833 }
834
moveSection_data()835 void tst_QHeaderView::moveSection_data()
836 {
837 QTest::addColumn<QList<int> >("hidden");
838 QTest::addColumn<QList<int> >("from");
839 QTest::addColumn<QList<int> >("to");
840 QTest::addColumn<QList<bool> >("moved");
841 QTest::addColumn<QList<int> >("logical");
842 QTest::addColumn<int>("count");
843
844 QTest::newRow("bad args, no hidden")
845 << QList<int>()
846 << (QList<int>() << -1 << 1 << 99999 << 1)
847 << (QList<int>() << 1 << -1 << 1 << 99999)
848 << (QList<bool>() << false << false << false << false)
849 << (QList<int>() << 0 << 1 << 2 << 3)
850 << 0;
851
852 QTest::newRow("good args, no hidden")
853 << QList<int>()
854 << (QList<int>() << 1 << 1 << 2 << 1)
855 << (QList<int>() << 1 << 2 << 1 << 2)
856 << (QList<bool>() << false << true << true << true)
857 << (QList<int>() << 0 << 2 << 1 << 3)
858 << 3;
859
860 QTest::newRow("hidden sections")
861 << (QList<int>() << 0 << 3)
862 << (QList<int>() << 1 << 1 << 2 << 1)
863 << (QList<int>() << 1 << 2 << 1 << 2)
864 << (QList<bool>() << false << true << true << true)
865 << (QList<int>() << 0 << 2 << 1 << 3)
866 << 3;
867 }
868
moveSection()869 void tst_QHeaderView::moveSection()
870 {
871 QFETCH(QList<int>, hidden);
872 QFETCH(QList<int>, from);
873 QFETCH(QList<int>, to);
874 QFETCH(QList<bool>, moved);
875 QFETCH(QList<int>, logical);
876 QFETCH(int, count);
877
878 QVERIFY(from.count() == to.count());
879 QVERIFY(from.count() == moved.count());
880 QVERIFY(view->count() == logical.count());
881
882 QSignalSpy spy1(view, SIGNAL(sectionMoved(int, int, int)));
883 QCOMPARE(view->sectionsMoved(), false);
884
885 for (int h = 0; h < hidden.count(); ++h)
886 view->setSectionHidden(hidden.at(h), true);
887
888 for (int i = 0; i < from.count(); ++i) {
889 view->moveSection(from.at(i), to.at(i));
890 QCOMPARE(view->sectionsMoved(), moved.at(i));
891 }
892
893 for (int j = 0; j < view->count(); ++j)
894 QCOMPARE(view->logicalIndex(j), logical.at(j));
895
896 QCOMPARE(spy1.count(), count);
897 }
898
resizeAndMoveSection_data()899 void tst_QHeaderView::resizeAndMoveSection_data()
900 {
901 QTest::addColumn<IntList>("logicalIndexes");
902 QTest::addColumn<IntList>("sizes");
903 QTest::addColumn<int>("logicalFrom");
904 QTest::addColumn<int>("logicalTo");
905
906 QTest::newRow("resizeAndMove-1")
907 << (IntList() << 0 << 1)
908 << (IntList() << 20 << 40)
909 << 0 << 1;
910
911 QTest::newRow("resizeAndMove-2")
912 << (IntList() << 0 << 1 << 2 << 3)
913 << (IntList() << 20 << 60 << 10 << 80)
914 << 0 << 2;
915
916 QTest::newRow("resizeAndMove-3")
917 << (IntList() << 0 << 1 << 2 << 3)
918 << (IntList() << 100 << 60 << 40 << 10)
919 << 0 << 3;
920
921 QTest::newRow("resizeAndMove-4")
922 << (IntList() << 0 << 1 << 2 << 3)
923 << (IntList() << 10 << 40 << 80 << 30)
924 << 1 << 2;
925
926 QTest::newRow("resizeAndMove-5")
927 << (IntList() << 2 << 3)
928 << (IntList() << 100 << 200)
929 << 3 << 2;
930 }
931
resizeAndMoveSection()932 void tst_QHeaderView::resizeAndMoveSection()
933 {
934 QFETCH(IntList, logicalIndexes);
935 QFETCH(IntList, sizes);
936 QFETCH(int, logicalFrom);
937 QFETCH(int, logicalTo);
938
939 // Save old visual indexes and sizes
940 IntList oldVisualIndexes;
941 IntList oldSizes;
942 foreach (int logical, logicalIndexes) {
943 oldVisualIndexes.append(view->visualIndex(logical));
944 oldSizes.append(view->sectionSize(logical));
945 }
946
947 // Resize sections
948 for (int i = 0; i < logicalIndexes.size(); ++i) {
949 int logical = logicalIndexes.at(i);
950 view->resizeSection(logical, sizes.at(i));
951 }
952
953 // Move sections
954 int visualFrom = view->visualIndex(logicalFrom);
955 int visualTo = view->visualIndex(logicalTo);
956 view->moveSection(visualFrom, visualTo);
957 QCOMPARE(view->visualIndex(logicalFrom), visualTo);
958
959 // Check that sizes are still correct
960 for (int i = 0; i < logicalIndexes.size(); ++i) {
961 int logical = logicalIndexes.at(i);
962 QCOMPARE(view->sectionSize(logical), sizes.at(i));
963 }
964
965 // Move sections back
966 view->moveSection(visualTo, visualFrom);
967
968 // Check that sizes are still correct
969 for (int i = 0; i < logicalIndexes.size(); ++i) {
970 int logical = logicalIndexes.at(i);
971 QCOMPARE(view->sectionSize(logical), sizes.at(i));
972 }
973
974 // Put everything back as it was
975 for (int i = 0; i < logicalIndexes.size(); ++i) {
976 int logical = logicalIndexes.at(i);
977 view->resizeSection(logical, oldSizes.at(i));
978 QCOMPARE(view->visualIndex(logical), oldVisualIndexes.at(i));
979 }
980 }
981
resizeHiddenSection_data()982 void tst_QHeaderView::resizeHiddenSection_data()
983 {
984 QTest::addColumn<int>("section");
985 QTest::addColumn<int>("initialSize");
986 QTest::addColumn<int>("finalSize");
987
988 QTest::newRow("section 0 resize 50 to 20")
989 << 0 << 50 << 20;
990
991 QTest::newRow("section 1 resize 50 to 20")
992 << 1 << 50 << 20;
993
994 QTest::newRow("section 2 resize 50 to 20")
995 << 2 << 50 << 20;
996
997 QTest::newRow("section 3 resize 50 to 20")
998 << 3 << 50 << 20;
999 }
1000
resizeHiddenSection()1001 void tst_QHeaderView::resizeHiddenSection()
1002 {
1003 QFETCH(int, section);
1004 QFETCH(int, initialSize);
1005 QFETCH(int, finalSize);
1006
1007 view->resizeSection(section, initialSize);
1008 view->setSectionHidden(section, true);
1009 QCOMPARE(view->sectionSize(section), 0);
1010
1011 view->resizeSection(section, finalSize);
1012 QCOMPARE(view->sectionSize(section), 0);
1013
1014 view->setSectionHidden(section, false);
1015 QCOMPARE(view->sectionSize(section), finalSize);
1016 }
1017
resizeAndInsertSection_data()1018 void tst_QHeaderView::resizeAndInsertSection_data()
1019 {
1020 QTest::addColumn<int>("section");
1021 QTest::addColumn<int>("size");
1022 QTest::addColumn<int>("insert");
1023 QTest::addColumn<int>("compare");
1024 QTest::addColumn<int>("expected");
1025
1026 QTest::newRow("section 0 size 50 insert 0")
1027 << 0 << 50 << 0 << 1 << 50;
1028
1029 QTest::newRow("section 1 size 50 insert 1")
1030 << 0 << 50 << 1 << 0 << 50;
1031
1032 QTest::newRow("section 1 size 50 insert 0")
1033 << 1 << 50 << 0 << 2 << 50;
1034
1035 }
1036
resizeAndInsertSection()1037 void tst_QHeaderView::resizeAndInsertSection()
1038 {
1039 QFETCH(int, section);
1040 QFETCH(int, size);
1041 QFETCH(int, insert);
1042 QFETCH(int, compare);
1043 QFETCH(int, expected);
1044
1045 view->setStretchLastSection(false);
1046
1047 view->resizeSection(section, size);
1048 QCOMPARE(view->sectionSize(section), size);
1049
1050 model->insertRow(insert);
1051
1052 QCOMPARE(view->sectionSize(compare), expected);
1053 }
1054
resizeWithResizeModes_data()1055 void tst_QHeaderView::resizeWithResizeModes_data()
1056 {
1057 QTest::addColumn<int>("size");
1058 QTest::addColumn<QList<int> >("sections");
1059 QTest::addColumn<QList<int> >("modes");
1060 QTest::addColumn<QList<int> >("expected");
1061
1062 QTest::newRow("stretch first section")
1063 << 600
1064 << (QList<int>() << 100 << 100 << 100 << 100)
1065 << (QList<int>() << ((int)QHeaderView::Stretch)
1066 << ((int)QHeaderView::Interactive)
1067 << ((int)QHeaderView::Interactive)
1068 << ((int)QHeaderView::Interactive))
1069 << (QList<int>() << 300 << 100 << 100 << 100);
1070 }
1071
resizeWithResizeModes()1072 void tst_QHeaderView::resizeWithResizeModes()
1073 {
1074 QFETCH(int, size);
1075 QFETCH(QList<int>, sections);
1076 QFETCH(QList<int>, modes);
1077 QFETCH(QList<int>, expected);
1078
1079 view->setStretchLastSection(false);
1080 for (int i = 0; i < sections.count(); ++i) {
1081 view->resizeSection(i, sections.at(i));
1082 view->setResizeMode(i, (QHeaderView::ResizeMode)modes.at(i));
1083 }
1084 topLevel->show();
1085 view->resize(size, size);
1086 for (int j = 0; j < expected.count(); ++j)
1087 QCOMPARE(view->sectionSize(j), expected.at(j));
1088 }
1089
moveAndInsertSection_data()1090 void tst_QHeaderView::moveAndInsertSection_data()
1091 {
1092 QTest::addColumn<int>("from");
1093 QTest::addColumn<int>("to");
1094 QTest::addColumn<int>("insert");
1095 QTest::addColumn<QList<int> >("mapping");
1096
1097 QTest::newRow("move from 1 to 3, insert 0")
1098 << 1 << 3 << 0 <<(QList<int>() << 0 << 1 << 3 << 4 << 2);
1099
1100 }
1101
moveAndInsertSection()1102 void tst_QHeaderView::moveAndInsertSection()
1103 {
1104 QFETCH(int, from);
1105 QFETCH(int, to);
1106 QFETCH(int, insert);
1107 QFETCH(QList<int>, mapping);
1108
1109 view->setStretchLastSection(false);
1110
1111 view->moveSection(from, to);
1112
1113 model->insertRow(insert);
1114
1115 for (int i = 0; i < mapping.count(); ++i)
1116 QCOMPARE(view->logicalIndex(i), mapping.at(i));
1117 }
1118
resizeMode()1119 void tst_QHeaderView::resizeMode()
1120 {
1121 // resizeMode must not be called with an invalid index
1122 int last = view->count() - 1;
1123 view->setResizeMode(QHeaderView::Interactive);
1124 QCOMPARE(view->resizeMode(last), QHeaderView::Interactive);
1125 QCOMPARE(view->resizeMode(1), QHeaderView::Interactive);
1126 view->setResizeMode(QHeaderView::Stretch);
1127 QCOMPARE(view->resizeMode(last), QHeaderView::Stretch);
1128 QCOMPARE(view->resizeMode(1), QHeaderView::Stretch);
1129 view->setResizeMode(QHeaderView::Custom);
1130 QCOMPARE(view->resizeMode(last), QHeaderView::Custom);
1131 QCOMPARE(view->resizeMode(1), QHeaderView::Custom);
1132
1133 // test when sections have been moved
1134 view->setStretchLastSection(false);
1135 for (int i=0; i < (view->count() - 1); ++i)
1136 view->setResizeMode(i, QHeaderView::Interactive);
1137 int logicalIndex = view->count() / 2;
1138 view->setResizeMode(logicalIndex, QHeaderView::Stretch);
1139 view->moveSection(view->visualIndex(logicalIndex), 0);
1140 for (int i=0; i < (view->count() - 1); ++i) {
1141 if (i == logicalIndex)
1142 QCOMPARE(view->resizeMode(i), QHeaderView::Stretch);
1143 else
1144 QCOMPARE(view->resizeMode(i), QHeaderView::Interactive);
1145 }
1146 }
1147
resizeSection_data()1148 void tst_QHeaderView::resizeSection_data()
1149 {
1150 QTest::addColumn<int>("initial");
1151 QTest::addColumn<QList<int> >("logical");
1152 QTest::addColumn<QList<int> >("size");
1153 QTest::addColumn<QList<int> >("mode");
1154 QTest::addColumn<int>("resized");
1155 QTest::addColumn<QList<int> >("expected");
1156
1157 QTest::newRow("bad args")
1158 << 100
1159 << (QList<int>() << -1 << -1 << 99999 << 99999 << 4)
1160 << (QList<int>() << -1 << 0 << 99999 << -1 << -1)
1161 << (QList<int>()
1162 << int(QHeaderView::Interactive)
1163 << int(QHeaderView::Interactive)
1164 << int(QHeaderView::Interactive)
1165 << int(QHeaderView::Interactive))
1166 << 0
1167 << (QList<int>() << 0 << 0 << 0 << 0 << 0);
1168 }
1169
resizeSection()1170 void tst_QHeaderView::resizeSection()
1171 {
1172
1173 QFETCH(int, initial);
1174 QFETCH(QList<int>, logical);
1175 QFETCH(QList<int>, size);
1176 QFETCH(QList<int>, mode);
1177 QFETCH(int, resized);
1178 QFETCH(QList<int>, expected);
1179
1180 view->resize(400, 400);
1181
1182 topLevel->show();
1183 view->setMovable(true);
1184 view->setStretchLastSection(false);
1185
1186 for (int i = 0; i < logical.count(); ++i)
1187 if (logical.at(i) > -1 && logical.at(i) < view->count()) // for now
1188 view->setResizeMode(logical.at(i), (QHeaderView::ResizeMode)mode.at(i));
1189
1190 for (int j = 0; j < logical.count(); ++j)
1191 view->resizeSection(logical.at(j), initial);
1192
1193 QSignalSpy spy(view, SIGNAL(sectionResized(int, int, int)));
1194
1195 for (int k = 0; k < logical.count(); ++k)
1196 view->resizeSection(logical.at(k), size.at(k));
1197
1198 QCOMPARE(spy.count(), resized);
1199
1200 for (int l = 0; l < logical.count(); ++l)
1201 QCOMPARE(view->sectionSize(logical.at(l)), expected.at(l));
1202 }
1203
highlightSections()1204 void tst_QHeaderView::highlightSections()
1205 {
1206 view->setHighlightSections(true);
1207 QCOMPARE(view->highlightSections(), true);
1208 view->setHighlightSections(false);
1209 QCOMPARE(view->highlightSections(), false);
1210 }
1211
showSortIndicator()1212 void tst_QHeaderView::showSortIndicator()
1213 {
1214 view->setSortIndicatorShown(true);
1215 QCOMPARE(view->isSortIndicatorShown(), true);
1216 QCOMPARE(view->sortIndicatorOrder(), Qt::DescendingOrder);
1217 view->setSortIndicator(1, Qt::AscendingOrder);
1218 QCOMPARE(view->sortIndicatorOrder(), Qt::AscendingOrder);
1219 view->setSortIndicator(1, Qt::DescendingOrder);
1220 QCOMPARE(view->sortIndicatorOrder(), Qt::DescendingOrder);
1221 view->setSortIndicatorShown(false);
1222 QCOMPARE(view->isSortIndicatorShown(), false);
1223
1224 view->setSortIndicator(999999, Qt::DescendingOrder);
1225 // Don't segfault baby :)
1226 view->setSortIndicatorShown(true);
1227
1228 view->setSortIndicator(0, Qt::DescendingOrder);
1229 // Don't assert baby :)
1230 }
1231
sortIndicatorTracking()1232 void tst_QHeaderView::sortIndicatorTracking()
1233 {
1234 QtTestModel model;
1235 model.rows = model.cols = 10;
1236
1237 QHeaderView hv(Qt::Horizontal);
1238
1239 hv.setModel(&model);
1240 hv.show();
1241 hv.setSortIndicatorShown(true);
1242 hv.setSortIndicator(1, Qt::DescendingOrder);
1243
1244 model.removeOneColumn(8);
1245 QCOMPARE(hv.sortIndicatorSection(), 1);
1246
1247 model.removeOneColumn(2);
1248 QCOMPARE(hv.sortIndicatorSection(), 1);
1249
1250 model.insertOneColumn(2);
1251 QCOMPARE(hv.sortIndicatorSection(), 1);
1252
1253 model.insertOneColumn(1);
1254 QCOMPARE(hv.sortIndicatorSection(), 2);
1255
1256 model.removeOneColumn(0);
1257 QCOMPARE(hv.sortIndicatorSection(), 1);
1258
1259 model.removeOneColumn(1);
1260 QCOMPARE(hv.sortIndicatorSection(), -1);
1261 }
1262
removeAndInsertRow()1263 void tst_QHeaderView::removeAndInsertRow()
1264 {
1265 // Check if logicalIndex returns the correct value after we have removed a row
1266 // we might as well te
1267 for (int i = 0; i < model->rowCount(); ++i) {
1268 QCOMPARE(i, view->logicalIndex(i));
1269 }
1270
1271 while (model->removeRow(0)) {
1272 for (int i = 0; i < model->rowCount(); ++i) {
1273 QCOMPARE(i, view->logicalIndex(i));
1274 }
1275 }
1276
1277 int pass = 0;
1278 for (pass = 0; pass < 5; pass++) {
1279 for (int i = 0; i < model->rowCount(); ++i) {
1280 QCOMPARE(i, view->logicalIndex(i));
1281 }
1282 model->insertRow(0);
1283 }
1284
1285 while (model->removeRows(0, 2)) {
1286 for (int i = 0; i < model->rowCount(); ++i) {
1287 QCOMPARE(i, view->logicalIndex(i));
1288 }
1289 }
1290
1291 for (pass = 0; pass < 3; pass++) {
1292 model->insertRows(0, 2);
1293 for (int i = 0; i < model->rowCount(); ++i) {
1294 QCOMPARE(i, view->logicalIndex(i));
1295 }
1296 }
1297
1298 for (pass = 0; pass < 3; pass++) {
1299 model->insertRows(3, 2);
1300 for (int i = 0; i < model->rowCount(); ++i) {
1301 QCOMPARE(i, view->logicalIndex(i));
1302 }
1303 }
1304
1305 // Insert at end
1306 for (pass = 0; pass < 3; pass++) {
1307 int rowCount = model->rowCount();
1308 model->insertRows(rowCount, 1);
1309 for (int i = 0; i < rowCount; ++i) {
1310 QCOMPARE(i, view->logicalIndex(i));
1311 }
1312 }
1313
1314 }
unhideSection()1315 void tst_QHeaderView::unhideSection()
1316 {
1317 // 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.
1318 QCOMPARE(view->sectionsHidden(), false);
1319 view->setSectionHidden(0, true);
1320 QCOMPARE(view->sectionsHidden(), true);
1321 QVERIFY(view->sectionSize(0) == 0);
1322 view->setResizeMode(QHeaderView::Interactive);
1323 view->setSectionHidden(0, false);
1324 QVERIFY(view->sectionSize(0) > 0);
1325
1326 view->setSectionHidden(0, true);
1327 QVERIFY(view->sectionSize(0) == 0);
1328 view->setSectionHidden(0, true);
1329 QVERIFY(view->sectionSize(0) == 0);
1330 view->setResizeMode(QHeaderView::Stretch);
1331 view->setSectionHidden(0, false);
1332 QVERIFY(view->sectionSize(0) > 0);
1333
1334 }
1335
event()1336 void tst_QHeaderView::event()
1337 {
1338 protected_QHeaderView x(Qt::Vertical);
1339 x.testEvent();
1340 protected_QHeaderView y(Qt::Horizontal);
1341 y.testEvent();
1342 }
1343
1344
testEvent()1345 void protected_QHeaderView::testEvent()
1346 {
1347 // No crashy please
1348 QHoverEvent enterEvent(QEvent::HoverEnter, QPoint(), QPoint());
1349 event(&enterEvent);
1350 QHoverEvent eventLeave(QEvent::HoverLeave, QPoint(), QPoint());
1351 event(&eventLeave);
1352 QHoverEvent eventMove(QEvent::HoverMove, QPoint(), QPoint());
1353 event(&eventMove);
1354 }
1355
headerDataChanged()1356 void tst_QHeaderView::headerDataChanged()
1357 {
1358 // This shouldn't asserver because view is Vertical
1359 view->headerDataChanged(Qt::Horizontal, -1, -1);
1360 #if 0
1361 // This will assert
1362 view->headerDataChanged(Qt::Vertical, -1, -1);
1363 #endif
1364
1365 // No crashing please
1366 view->headerDataChanged(Qt::Horizontal, 0, 1);
1367 view->headerDataChanged(Qt::Vertical, 0, 1);
1368 }
1369
currentChanged()1370 void tst_QHeaderView::currentChanged()
1371 {
1372 view->setCurrentIndex(QModelIndex());
1373 }
1374
horizontalOffset()1375 void tst_QHeaderView::horizontalOffset()
1376 {
1377 protected_QHeaderView x(Qt::Vertical);
1378 x.testhorizontalOffset();
1379 protected_QHeaderView y(Qt::Horizontal);
1380 y.testhorizontalOffset();
1381 }
1382
verticalOffset()1383 void tst_QHeaderView::verticalOffset()
1384 {
1385 protected_QHeaderView x(Qt::Vertical);
1386 x.testverticalOffset();
1387 protected_QHeaderView y(Qt::Horizontal);
1388 y.testverticalOffset();
1389 }
1390
testhorizontalOffset()1391 void protected_QHeaderView::testhorizontalOffset()
1392 {
1393 if(orientation() == Qt::Horizontal){
1394 QCOMPARE(horizontalOffset(), 0);
1395 setOffset(10);
1396 QCOMPARE(horizontalOffset(), 10);
1397 }
1398 else
1399 QCOMPARE(horizontalOffset(), 0);
1400
1401 }
1402
testverticalOffset()1403 void protected_QHeaderView::testverticalOffset()
1404 {
1405 if(orientation() == Qt::Vertical){
1406 QCOMPARE(verticalOffset(), 0);
1407 setOffset(10);
1408 QCOMPARE(verticalOffset(), 10);
1409 }
1410 else
1411 QCOMPARE(verticalOffset(), 0);
1412 }
1413
stretchSectionCount()1414 void tst_QHeaderView::stretchSectionCount()
1415 {
1416 view->setStretchLastSection(false);
1417 QCOMPARE(view->stretchSectionCount(), 0);
1418 view->setStretchLastSection(true);
1419 QCOMPARE(view->stretchSectionCount(), 0);
1420
1421 view->setResizeMode(0, QHeaderView::Stretch);
1422 QCOMPARE(view->stretchSectionCount(), 1);
1423 }
1424
hiddenSectionCount()1425 void tst_QHeaderView::hiddenSectionCount()
1426 {
1427 model->clear();
1428 model->insertRows(0, 10);
1429 // Hide every other one
1430 for (int i=0; i<10; i++)
1431 view->setSectionHidden(i, (i & 1) == 0);
1432
1433 QCOMPARE(view->hiddenSectionCount(), 5);
1434
1435 view->setResizeMode(QHeaderView::Stretch);
1436 QCOMPARE(view->hiddenSectionCount(), 5);
1437
1438 // Remove some rows and make sure they are now still counted
1439 model->removeRow(9);
1440 model->removeRow(8);
1441 model->removeRow(7);
1442 model->removeRow(6);
1443 QCOMPARE(view->count(), 6);
1444 QCOMPARE(view->hiddenSectionCount(), 3);
1445 model->removeRows(0,5);
1446 QCOMPARE(view->count(), 1);
1447 QCOMPARE(view->hiddenSectionCount(), 0);
1448 QVERIFY(view->count() >= view->hiddenSectionCount());
1449 }
1450
focusPolicy()1451 void tst_QHeaderView::focusPolicy()
1452 {
1453 QHeaderView view(Qt::Horizontal);
1454 QCOMPARE(view.focusPolicy(), Qt::NoFocus);
1455
1456 QTreeWidget widget;
1457 QCOMPARE(widget.header()->focusPolicy(), Qt::NoFocus);
1458 QVERIFY(!widget.focusProxy());
1459 QVERIFY(!widget.hasFocus());
1460 QVERIFY(!widget.header()->focusProxy());
1461 QVERIFY(!widget.header()->hasFocus());
1462
1463 widget.show();
1464 widget.setFocus(Qt::OtherFocusReason);
1465 QApplication::setActiveWindow(&widget);
1466 QTest::qWaitForWindowShown(&widget);
1467 widget.activateWindow();
1468 QTest::qWait(100);
1469
1470 qApp->processEvents();
1471
1472 WAIT_FOR_CONDITION(widget.hasFocus(), true);
1473
1474 QVERIFY(widget.hasFocus());
1475 QVERIFY(!widget.header()->hasFocus());
1476
1477 widget.setFocusPolicy(Qt::NoFocus);
1478 widget.clearFocus();
1479
1480 qApp->processEvents();
1481 qApp->processEvents();
1482
1483 WAIT_FOR_CONDITION(widget.hasFocus(), false);
1484 QVERIFY(!widget.hasFocus());
1485 QVERIFY(!widget.header()->hasFocus());
1486
1487 QTest::keyPress(&widget, Qt::Key_Tab);
1488
1489 qApp->processEvents();
1490 qApp->processEvents();
1491
1492 QVERIFY(!widget.hasFocus());
1493 QVERIFY(!widget.header()->hasFocus());
1494 }
1495
1496 class SimpleModel : public QAbstractItemModel
1497 {
1498 Q_OBJECT
1499 public:
1500
SimpleModel(QObject * parent=0)1501 SimpleModel( QObject* parent=0)
1502 : QAbstractItemModel(parent),
1503 m_col_count(3) {}
1504
parent(const QModelIndex &) const1505 QModelIndex parent(const QModelIndex &/*child*/) const
1506 {
1507 return QModelIndex();
1508 }
index(int row,int column,const QModelIndex & parent=QModelIndex ()) const1509 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
1510 {
1511 return hasIndex(row, column, parent) ? createIndex(row, column, 0) : QModelIndex();
1512 }
rowCount(const QModelIndex &) const1513 int rowCount(const QModelIndex & /* parent */) const
1514 {
1515 return 8;
1516 }
columnCount(const QModelIndex &) const1517 int columnCount(const QModelIndex &/*parent= QModelIndex()*/) const
1518 {
1519 return m_col_count;
1520 }
1521
data(const QModelIndex & index,int role) const1522 QVariant data(const QModelIndex &index, int role) const
1523 {
1524 if (!index.isValid())
1525 {
1526 return QVariant();
1527 }
1528 if (role == Qt::DisplayRole) {
1529 return QString::fromAscii("%1,%2").arg(index.row()).arg(index.column());
1530 }
1531 return QVariant();
1532 }
1533
setColumnCount(int c)1534 void setColumnCount( int c )
1535 {
1536 m_col_count = c;
1537 }
1538
1539 private:
1540 int m_col_count;
1541 };
1542
moveSectionAndReset()1543 void tst_QHeaderView::moveSectionAndReset()
1544 {
1545 SimpleModel m;
1546 QHeaderView v(Qt::Horizontal);
1547 v.setModel(&m);
1548 int cc = 2;
1549 for (cc = 2; cc < 4; ++cc) {
1550 m.setColumnCount(cc);
1551 int movefrom = 0;
1552 int moveto;
1553 for (moveto = 1; moveto < cc; ++moveto) {
1554 v.moveSection(movefrom, moveto);
1555 m.setColumnCount(cc - 1);
1556 v.reset();
1557 for (int i = 0; i < cc - 1; ++i) {
1558 QCOMPARE(v.logicalIndex(v.visualIndex(i)), i);
1559 }
1560 }
1561 }
1562 }
1563
moveSectionAndRemove()1564 void tst_QHeaderView::moveSectionAndRemove()
1565 {
1566 QStandardItemModel m;
1567 QHeaderView v(Qt::Horizontal);
1568
1569 v.setModel(&m);
1570 v.model()->insertColumns(0, 3);
1571 v.moveSection(0, 1);
1572
1573 QCOMPARE(v.count(), 3);
1574 v.model()->removeColumns(0, v.model()->columnCount());
1575 QCOMPARE(v.count(), 0);
1576 }
1577
saveRestore()1578 void tst_QHeaderView::saveRestore()
1579 {
1580 SimpleModel m;
1581 QHeaderView h1(Qt::Horizontal);
1582 h1.setModel(&m);
1583 h1.swapSections(0, 2);
1584 h1.resizeSection(1, 10);
1585 h1.setSortIndicatorShown(true);
1586 h1.setSortIndicator(1,Qt::DescendingOrder);
1587 QByteArray s1 = h1.saveState();
1588
1589 QHeaderView h2(Qt::Vertical);
1590 QSignalSpy spy(&h2, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)));
1591
1592 h2.setModel(&m);
1593 h2.restoreState(s1);
1594
1595 QCOMPARE(spy.count(), 1);
1596 QCOMPARE(spy.at(0).at(0).toInt(), 1);
1597
1598 QCOMPARE(h2.logicalIndex(0), 2);
1599 QCOMPARE(h2.logicalIndex(2), 0);
1600 QCOMPARE(h2.sectionSize(1), 10);
1601 QCOMPARE(h2.sortIndicatorSection(), 1);
1602 QCOMPARE(h2.sortIndicatorOrder(), Qt::DescendingOrder);
1603 QCOMPARE(h2.isSortIndicatorShown(), true);
1604
1605 QByteArray s2 = h2.saveState();
1606
1607 QVERIFY(s1 == s2);
1608 }
1609
defaultAlignment_data()1610 void tst_QHeaderView::defaultAlignment_data()
1611 {
1612 QTest::addColumn<int>("direction");
1613 QTest::addColumn<int>("initial");
1614 QTest::addColumn<int>("alignment");
1615
1616 QTest::newRow("horizontal right aligned")
1617 << int(Qt::Horizontal)
1618 << int(Qt::AlignCenter)
1619 << int(Qt::AlignRight);
1620
1621 QTest::newRow("horizontal left aligned")
1622 << int(Qt::Horizontal)
1623 << int(Qt::AlignCenter)
1624 << int(Qt::AlignLeft);
1625
1626 QTest::newRow("vertical right aligned")
1627 << int(Qt::Vertical)
1628 << int(Qt::AlignLeft|Qt::AlignVCenter)
1629 << int(Qt::AlignRight);
1630
1631 QTest::newRow("vertical left aligned")
1632 << int(Qt::Vertical)
1633 << int(Qt::AlignLeft|Qt::AlignVCenter)
1634 << int(Qt::AlignLeft);
1635 }
1636
defaultAlignment()1637 void tst_QHeaderView::defaultAlignment()
1638 {
1639 QFETCH(int, direction);
1640 QFETCH(int, initial);
1641 QFETCH(int, alignment);
1642
1643 SimpleModel m;
1644
1645 QHeaderView header((Qt::Orientation)direction);
1646 header.setModel(&m);
1647
1648 QCOMPARE(header.defaultAlignment(), (Qt::Alignment)initial);
1649 header.setDefaultAlignment((Qt::Alignment)alignment);
1650 QCOMPARE(header.defaultAlignment(), (Qt::Alignment)alignment);
1651 }
1652
globalResizeMode_data()1653 void tst_QHeaderView::globalResizeMode_data()
1654 {
1655 QTest::addColumn<int>("direction");
1656 QTest::addColumn<int>("mode");
1657 QTest::addColumn<int>("insert");
1658
1659 QTest::newRow("horizontal ResizeToContents 0")
1660 << int(Qt::Horizontal)
1661 << int(QHeaderView::ResizeToContents)
1662 << 0;
1663 }
1664
globalResizeMode()1665 void tst_QHeaderView::globalResizeMode()
1666 {
1667 QFETCH(int, direction);
1668 QFETCH(int, mode);
1669 QFETCH(int, insert);
1670
1671 QStandardItemModel m(4, 4);
1672 QHeaderView h((Qt::Orientation)direction);
1673 h.setModel(&m);
1674
1675 h.setResizeMode((QHeaderView::ResizeMode)mode);
1676 m.insertRow(insert);
1677 for (int i = 0; i < h.count(); ++i)
1678 QCOMPARE(h.resizeMode(i), (QHeaderView::ResizeMode)mode);
1679 }
1680
1681
sectionPressedSignal_data()1682 void tst_QHeaderView::sectionPressedSignal_data()
1683 {
1684 QTest::addColumn<int>("direction");
1685 QTest::addColumn<bool>("clickable");
1686 QTest::addColumn<int>("count");
1687
1688 QTest::newRow("horizontal unclickable 0")
1689 << int(Qt::Horizontal)
1690 << false
1691 << 0;
1692
1693 QTest::newRow("horizontal clickable 1")
1694 << int(Qt::Horizontal)
1695 << true
1696 << 1;
1697 }
1698
sectionPressedSignal()1699 void tst_QHeaderView::sectionPressedSignal()
1700 {
1701 QFETCH(int, direction);
1702 QFETCH(bool, clickable);
1703 QFETCH(int, count);
1704
1705 QStandardItemModel m(4, 4);
1706 QHeaderView h((Qt::Orientation)direction);
1707
1708 h.setModel(&m);
1709 h.show();
1710 h.setClickable(clickable);
1711
1712 QSignalSpy spy(&h, SIGNAL(sectionPressed(int)));
1713
1714 QCOMPARE(spy.count(), 0);
1715 QTest::mousePress(h.viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
1716 QCOMPARE(spy.count(), count);
1717 }
1718
sectionClickedSignal()1719 void tst_QHeaderView::sectionClickedSignal()
1720 {
1721 QFETCH(int, direction);
1722 QFETCH(bool, clickable);
1723 QFETCH(int, count);
1724
1725 QStandardItemModel m(4, 4);
1726 QHeaderView h((Qt::Orientation)direction);
1727
1728 h.setModel(&m);
1729 h.show();
1730 h.setClickable(clickable);
1731 h.setSortIndicatorShown(true);
1732
1733 QSignalSpy spy(&h, SIGNAL(sectionClicked(int)));
1734 QSignalSpy spy2(&h, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)));
1735
1736 QCOMPARE(spy.count(), 0);
1737 QCOMPARE(spy2.count(), 0);
1738 QTest::mouseClick(h.viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
1739 QCOMPARE(spy.count(), count);
1740 QCOMPARE(spy2.count(), count);
1741
1742 //now let's try with the sort indicator hidden (the result should be the same
1743 spy.clear();
1744 spy2.clear();
1745 h.setSortIndicatorShown(false);
1746 QTest::mouseClick(h.viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
1747 QCOMPARE(spy.count(), count);
1748 QCOMPARE(spy2.count(), count);
1749 }
1750
defaultSectionSize_data()1751 void tst_QHeaderView::defaultSectionSize_data()
1752 {
1753 QTest::addColumn<int>("direction");
1754 QTest::addColumn<int>("oldDefaultSize");
1755 QTest::addColumn<int>("newDefaultSize");
1756
1757 //QTest::newRow("horizontal,-5") << int(Qt::Horizontal) << 100 << -5;
1758 QTest::newRow("horizontal, 0") << int(Qt::Horizontal) << 100 << 0;
1759 QTest::newRow("horizontal, 5") << int(Qt::Horizontal) << 100 << 5;
1760 QTest::newRow("horizontal,25") << int(Qt::Horizontal) << 100 << 5;
1761 }
1762
defaultSectionSize()1763 void tst_QHeaderView::defaultSectionSize()
1764 {
1765 QFETCH(int, direction);
1766 QFETCH(int, oldDefaultSize);
1767 QFETCH(int, newDefaultSize);
1768
1769 QStandardItemModel m(4, 4);
1770 QHeaderView h((Qt::Orientation)direction);
1771
1772 h.setModel(&m);
1773
1774 QCOMPARE(h.defaultSectionSize(), oldDefaultSize);
1775 h.setDefaultSectionSize(newDefaultSize);
1776 QCOMPARE(h.defaultSectionSize(), newDefaultSize);
1777 h.reset();
1778 for (int i = 0; i < h.count(); ++i)
1779 QCOMPARE(h.sectionSize(i), newDefaultSize);
1780 }
1781
hideAndInsert_data()1782 void tst_QHeaderView::hideAndInsert_data()
1783 {
1784 QTest::addColumn<int>("direction");
1785 QTest::addColumn<int>("hide");
1786 QTest::addColumn<int>("insert");
1787 QTest::addColumn<int>("hidden");
1788
1789 QTest::newRow("horizontal, 0, 0") << int(Qt::Horizontal) << 0 << 0 << 1;
1790 }
1791
hideAndInsert()1792 void tst_QHeaderView::hideAndInsert()
1793 {
1794 QFETCH(int, direction);
1795 QFETCH(int, hide);
1796 QFETCH(int, insert);
1797 QFETCH(int, hidden);
1798
1799 QStandardItemModel m(4, 4);
1800 QHeaderView h((Qt::Orientation)direction);
1801
1802 h.setModel(&m);
1803
1804 h.setSectionHidden(hide, true);
1805
1806 if (direction == Qt::Vertical)
1807 m.insertRow(insert);
1808 else
1809 m.insertColumn(insert);
1810
1811 for (int i = 0; i < h.count(); ++i)
1812 if (i != hidden)
1813 QCOMPARE(h.isSectionHidden(i), false);
1814 else
1815 QCOMPARE(h.isSectionHidden(i), true);
1816 }
1817
removeSection()1818 void tst_QHeaderView::removeSection()
1819 {
1820 //test that removing a hidden section gives the expected result: the next row should be hidden
1821 //(see task
1822 const int hidden = 3; //section that will be hidden
1823 const QStringList list = QStringList() << "0" << "1" << "2" << "3" << "4" << "5" << "6";
1824
1825 QStringListModel model( list );
1826 QHeaderView view(Qt::Vertical);
1827 view.setModel(&model);
1828 view.hideSection(hidden);
1829 view.hideSection(1);
1830 model.removeRow(1);
1831 view.show();
1832
1833 for(int i = 0; i < view.count(); i++) {
1834 if (i == (hidden-1)) { //-1 because we removed a row in the meantime
1835 QCOMPARE(view.sectionSize(i), 0);
1836 QVERIFY(view.isSectionHidden(i));
1837 } else {
1838 QCOMPARE(view.sectionSize(i), view.defaultSectionSize() );
1839 QVERIFY(!view.isSectionHidden(i));
1840 }
1841 }
1842 }
1843
preserveHiddenSectionWidth()1844 void tst_QHeaderView::preserveHiddenSectionWidth()
1845 {
1846 const QStringList list = QStringList() << "0" << "1" << "2" << "3";
1847
1848 QStringListModel model( list );
1849 QHeaderView view(Qt::Vertical);
1850 view.setModel(&model);
1851 view.resizeSection(0, 100);
1852 view.resizeSection(1, 10);
1853 view.resizeSection(2, 50);
1854 view.setResizeMode(3, QHeaderView::Stretch);
1855 view.show();
1856
1857 view.hideSection(2);
1858 model.removeRow(1);
1859 view.showSection(1);
1860 QCOMPARE(view.sectionSize(0), 100);
1861 QCOMPARE(view.sectionSize(1), 50);
1862
1863 view.hideSection(1);
1864 model.insertRow(1);
1865 view.showSection(2);
1866 QCOMPARE(view.sectionSize(0), 100);
1867 QCOMPARE(view.sectionSize(1), view.defaultSectionSize());
1868 QCOMPARE(view.sectionSize(2), 50);
1869 }
1870
invisibleStretchLastSection()1871 void tst_QHeaderView::invisibleStretchLastSection()
1872 {
1873 int count = 6;
1874 QStandardItemModel model(1, count);
1875 QHeaderView view(Qt::Horizontal);
1876 view.setModel(&model);
1877 int height = view.height();
1878
1879 view.resize(view.defaultSectionSize() * (count / 2), height); // don't show all sections
1880 view.show();
1881 view.setStretchLastSection(true);
1882 // stretch section is not visible; it should not be stretched
1883 for (int i = 0; i < count; ++i)
1884 QCOMPARE(view.sectionSize(i), view.defaultSectionSize());
1885
1886 view.resize(view.defaultSectionSize() * (count + 1), height); // give room to stretch
1887
1888 // stretch section is visible; it should be stretched
1889 for (int i = 0; i < count - 1; ++i)
1890 QCOMPARE(view.sectionSize(i), view.defaultSectionSize());
1891 QCOMPARE(view.sectionSize(count - 1), view.defaultSectionSize() * 2);
1892 }
1893
emptySectionSpan()1894 void tst_QHeaderView::emptySectionSpan()
1895 {
1896 QHeaderViewPrivate::SectionSpan span;
1897 QCOMPARE(span.sectionSize(), 0);
1898 }
1899
task236450_hidden_data()1900 void tst_QHeaderView::task236450_hidden_data()
1901 {
1902 QTest::addColumn<QList<int> >("hide1");
1903 QTest::addColumn<QList<int> >("hide2");
1904
1905 QTest::newRow("set 1") << (QList<int>() << 1 << 3)
1906 << (QList<int>() << 1 << 5);
1907
1908 QTest::newRow("set 2") << (QList<int>() << 2 << 3)
1909 << (QList<int>() << 1 << 5);
1910
1911 QTest::newRow("set 3") << (QList<int>() << 0 << 2 << 4)
1912 << (QList<int>() << 2 << 3 << 5);
1913
1914 }
1915
task236450_hidden()1916 void tst_QHeaderView::task236450_hidden()
1917 {
1918 QFETCH(QList<int>, hide1);
1919 QFETCH(QList<int>, hide2);
1920 const QStringList list = QStringList() << "0" << "1" << "2" << "3" << "4" << "5";
1921
1922 QStringListModel model( list );
1923 protected_QHeaderView view(Qt::Vertical);
1924 view.setModel(&model);
1925 view.show();
1926
1927 foreach (int i, hide1)
1928 view.hideSection(i);
1929
1930 QCOMPARE(view.hiddenSectionCount(), hide1.count());
1931 for (int i = 0; i < 6; i++) {
1932 QCOMPARE(!view.isSectionHidden(i), !hide1.contains(i));
1933 }
1934
1935 view.setDefaultSectionSize(2);
1936 view.scheduleDelayedItemsLayout();
1937 view.executeDelayedItemsLayout(); //force to do a relayout
1938
1939 QCOMPARE(view.hiddenSectionCount(), hide1.count());
1940 for (int i = 0; i < 6; i++) {
1941 QCOMPARE(!view.isSectionHidden(i), !hide1.contains(i));
1942 view.setSectionHidden(i, hide2.contains(i));
1943 }
1944
1945 QCOMPARE(view.hiddenSectionCount(), hide2.count());
1946 for (int i = 0; i < 6; i++) {
1947 QCOMPARE(!view.isSectionHidden(i), !hide2.contains(i));
1948 }
1949
1950 }
1951
task248050_hideRow()1952 void tst_QHeaderView::task248050_hideRow()
1953 {
1954 //this is the sequence of events that make the task fail
1955 protected_QHeaderView header(Qt::Vertical);
1956 QStandardItemModel model(0, 1);
1957 header.setStretchLastSection(false);
1958 header.setDefaultSectionSize(17);
1959 header.setModel(&model);
1960 header.doItemsLayout();
1961
1962 model.setRowCount(3);
1963
1964 QCOMPARE(header.sectionPosition(2), 17*2);
1965
1966 header.hideSection(1);
1967 QCOMPARE(header.sectionPosition(2), 17);
1968
1969 QTest::qWait(100);
1970 //the size of the section shouldn't have changed
1971 QCOMPARE(header.sectionPosition(2), 17);
1972 }
1973
1974
1975 //returns 0 if everything is fine.
checkHeaderViewOrder(QHeaderView * view,const QVector<int> & expected)1976 static int checkHeaderViewOrder(QHeaderView *view, const QVector<int> &expected)
1977 {
1978 if (view->count() != expected.count())
1979 return 1;
1980
1981 for (int i = 0; i < expected.count(); i++) {
1982 if (view->logicalIndex(i) != expected.at(i))
1983 return i + 10;
1984 if (view->visualIndex(expected.at(i)) != i)
1985 return i + 100;
1986 }
1987 return 0;
1988 }
1989
1990
QTBUG6058_reset()1991 void tst_QHeaderView::QTBUG6058_reset()
1992 {
1993 QStringListModel model1( QStringList() << "0" << "1" << "2" << "3" << "4" << "5" );
1994 QStringListModel model2( QStringList() << "a" << "b" << "c" );
1995 QSortFilterProxyModel proxy;
1996
1997 QHeaderView view(Qt::Vertical);
1998 view.setModel(&proxy);
1999 view.show();
2000 QTest::qWait(20);
2001
2002 proxy.setSourceModel(&model1);
2003 QApplication::processEvents();
2004 view.swapSections(0,2);
2005 view.swapSections(1,4);
2006 QApplication::processEvents();
2007 QCOMPARE(checkHeaderViewOrder(&view, QVector<int>() << 2 << 4 << 0 << 3 << 1 << 5) , 0);
2008
2009 proxy.setSourceModel(&model2);
2010 QApplication::processEvents();
2011 QCOMPARE(checkHeaderViewOrder(&view, QVector<int>() << 2 << 0 << 1 ) , 0);
2012
2013 proxy.setSourceModel(&model1);
2014 QApplication::processEvents();
2015 QCOMPARE(checkHeaderViewOrder(&view, QVector<int>() << 2 << 0 << 1 << 3 << 4 << 5 ) , 0);
2016 }
2017
QTBUG7833_sectionClicked()2018 void tst_QHeaderView::QTBUG7833_sectionClicked()
2019 {
2020
2021
2022
2023
2024 QTableView tv;
2025 QStandardItemModel *sim = new QStandardItemModel(&tv);
2026 QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(&tv);
2027 proxyModel->setSourceModel(sim);
2028 proxyModel->setDynamicSortFilter(true);
2029 proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
2030
2031 QList<QStandardItem *> row;
2032 for (int i = 0; i < 12; i++)
2033 row.append(new QStandardItem(QString(QLatin1Char('A' + i))));
2034 sim->appendRow(row);
2035 row.clear();
2036 for (int i = 12; i > 0; i--)
2037 row.append(new QStandardItem(QString(QLatin1Char('A' + i))));
2038 sim->appendRow(row);
2039
2040 tv.setSortingEnabled(true);
2041 tv.horizontalHeader()->setSortIndicatorShown(true);
2042 tv.horizontalHeader()->setClickable(true);
2043 tv.horizontalHeader()->setStretchLastSection(true);
2044 tv.horizontalHeader()->setResizeMode(QHeaderView::Interactive);
2045
2046 tv.setModel(proxyModel);
2047 tv.setColumnHidden(5, true);
2048 tv.setColumnHidden(6, true);
2049 tv.horizontalHeader()->swapSections(8, 10);
2050 tv.sortByColumn(1, Qt::AscendingOrder);
2051
2052 QSignalSpy clickedSpy(tv.horizontalHeader(), SIGNAL(sectionClicked(int)));
2053 QSignalSpy pressedSpy(tv.horizontalHeader(), SIGNAL(sectionPressed(int)));
2054
2055
2056 QTest::mouseClick(tv.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier,
2057 QPoint(tv.horizontalHeader()->sectionViewportPosition(11) + tv.horizontalHeader()->sectionSize(11)/2, 5));
2058 QCOMPARE(clickedSpy.count(), 1);
2059 QCOMPARE(pressedSpy.count(), 1);
2060 QCOMPARE(clickedSpy.at(0).at(0).toInt(), 11);
2061 QCOMPARE(pressedSpy.at(0).at(0).toInt(), 11);
2062
2063 QTest::mouseClick(tv.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier,
2064 QPoint(tv.horizontalHeader()->sectionViewportPosition(8) + tv.horizontalHeader()->sectionSize(0)/2, 5));
2065
2066 QCOMPARE(clickedSpy.count(), 2);
2067 QCOMPARE(pressedSpy.count(), 2);
2068 QCOMPARE(clickedSpy.at(1).at(0).toInt(), 8);
2069 QCOMPARE(pressedSpy.at(1).at(0).toInt(), 8);
2070
2071 QTest::mouseClick(tv.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier,
2072 QPoint(tv.horizontalHeader()->sectionViewportPosition(0) + tv.horizontalHeader()->sectionSize(0)/2, 5));
2073
2074 QCOMPARE(clickedSpy.count(), 3);
2075 QCOMPARE(pressedSpy.count(), 3);
2076 QCOMPARE(clickedSpy.at(2).at(0).toInt(), 0);
2077 QCOMPARE(pressedSpy.at(2).at(0).toInt(), 0);
2078 }
2079
QTBUG8650_crashOnInsertSections()2080 void tst_QHeaderView::QTBUG8650_crashOnInsertSections()
2081 {
2082 QStringList headerLabels;
2083 QHeaderView view(Qt::Horizontal);
2084 QStandardItemModel model(2,2);
2085 view.setModel(&model);
2086 view.moveSection(1, 0);
2087 view.hideSection(0);
2088
2089 QList<QStandardItem *> items;
2090 items << new QStandardItem("c");
2091 model.insertColumn(0, items);
2092 }
2093
QTBUG12268_hiddenMovedSectionSorting()2094 void tst_QHeaderView::QTBUG12268_hiddenMovedSectionSorting()
2095 {
2096 QTableView view;
2097 QStandardItemModel *model = new QStandardItemModel(4,3, &view);
2098 for (int i = 0; i< model->rowCount(); ++i)
2099 for (int j = 0; j< model->columnCount(); ++j)
2100 model->setData(model->index(i,j), QString("item [%1,%2]").arg(i).arg(j));
2101 view.setModel(model);
2102 view.horizontalHeader()->setMovable(true);
2103 view.setSortingEnabled(true);
2104 view.sortByColumn(1, Qt::AscendingOrder);
2105 view.horizontalHeader()->moveSection(0,2);
2106 view.setColumnHidden(1, true);
2107 view.show();
2108 QTest::qWaitForWindowShown(&view);
2109 QCOMPARE(view.horizontalHeader()->hiddenSectionCount(), 1);
2110 QTest::mouseClick(view.horizontalHeader()->viewport(), Qt::LeftButton);
2111 QCOMPARE(view.horizontalHeader()->hiddenSectionCount(), 1);
2112 }
2113
QTBUG14242_hideSectionAutoSize()2114 void tst_QHeaderView::QTBUG14242_hideSectionAutoSize()
2115 {
2116 QTableView qtv;
2117 QStandardItemModel amodel(4, 4);
2118 qtv.setModel(&amodel);
2119 QHeaderView *hv = qtv.verticalHeader();
2120 hv->setDefaultSectionSize(25);
2121 hv->setResizeMode(QHeaderView::ResizeToContents);
2122 qtv.show();
2123 hv->hideSection(0);
2124 int afterlength = hv->length();
2125 int calced_length = 0;
2126 for (int u = 0; u < hv->count(); ++u)
2127 calced_length += hv->sectionSize(u);
2128 QVERIFY(calced_length == afterlength);
2129 }
2130
initialSortOrderRole()2131 void tst_QHeaderView::initialSortOrderRole()
2132 {
2133 QTableView view;
2134 QStandardItemModel *model = new QStandardItemModel(4, 3, &view);
2135 for (int i = 0; i< model->rowCount(); ++i)
2136 for (int j = 0; j< model->columnCount(); ++j)
2137 model->setData(model->index(i,j), QString("item [%1,%2]").arg(i).arg(j));
2138 QStandardItem *ascendingItem = new QStandardItem();
2139 QStandardItem *descendingItem = new QStandardItem();
2140 ascendingItem->setData(Qt::AscendingOrder, Qt::InitialSortOrderRole);
2141 descendingItem->setData(Qt::DescendingOrder, Qt::InitialSortOrderRole);
2142 model->setHorizontalHeaderItem(1, ascendingItem);
2143 model->setHorizontalHeaderItem(2, descendingItem);
2144 view.setModel(model);
2145 view.setSortingEnabled(true);
2146 view.sortByColumn(0, Qt::AscendingOrder);
2147 view.show();
2148 QTest::qWaitForWindowShown(&view);
2149
2150 const int column1Pos = view.horizontalHeader()->sectionViewportPosition(1) + 5; // +5 not to be on the handle
2151 QTest::mouseClick(view.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(column1Pos, 0));
2152 QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), 1);
2153 QCOMPARE(view.horizontalHeader()->sortIndicatorOrder(), Qt::AscendingOrder);
2154
2155 const int column2Pos = view.horizontalHeader()->sectionViewportPosition(2) + 5; // +5 not to be on the handle
2156 QTest::mouseClick(view.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(column2Pos, 0));
2157 QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), 2);
2158 QCOMPARE(view.horizontalHeader()->sortIndicatorOrder(), Qt::DescendingOrder);
2159
2160 const int column0Pos = view.horizontalHeader()->sectionViewportPosition(0) + 5; // +5 not to be on the handle
2161 QTest::mouseClick(view.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(column0Pos, 0));
2162 QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), 0);
2163 QCOMPARE(view.horizontalHeader()->sortIndicatorOrder(), Qt::AscendingOrder);
2164 }
2165
ensureNoIndexAtLength()2166 void tst_QHeaderView::ensureNoIndexAtLength()
2167 {
2168 QTableView qtv;
2169 QStandardItemModel amodel(4, 4);
2170 qtv.setModel(&amodel);
2171 QHeaderView *hv = qtv.verticalHeader();
2172 QVERIFY(hv->visualIndexAt(hv->length()) == -1);
2173 hv->resizeSection(hv->count() - 1, 0);
2174 QVERIFY(hv->visualIndexAt(hv->length()) == -1);
2175 }
2176
2177
2178 QTEST_MAIN(tst_QHeaderView)
2179 #include "tst_qheaderview.moc"
2180