diff options
author | Christian Ehrlicher <ch.ehrlicher@gmx.de> | 2017-10-31 16:05:58 +0100 |
---|---|---|
committer | Christian Ehrlicher <ch.ehrlicher@gmx.de> | 2018-01-06 05:17:00 +0000 |
commit | 20604ea554b282efa80502c68a499824f8692e7a (patch) | |
tree | ed1c27e6e482913d65c687c2a77ba68aa72c4df6 | |
parent | 1c0ac8c4b8646e898aa1636f93dcfd34949611cf (diff) |
QHeaderView: respect min/maximumSectionSize property
QHeaderView::resizeSection() did not check if the given section size is
inside the min/max property bounds.
Also on calling setMin/MaximumSectionSize() the current section sizes
were not checked if they are inside the new given bounds.
This is a small behavior change when a user is setting the section size
via resizeSection() without respecting the min/maxSectionSizes.
Task-number: QTBUG-64173
Change-Id: Ia9c9eebf058d60c776ab5f8f8336642013ec553f
Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
-rw-r--r-- | src/widgets/itemviews/qheaderview.cpp | 43 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp | 78 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp | 24 |
3 files changed, 136 insertions, 9 deletions
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 6ee3f0cfca..a21b8feeb1 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -886,6 +886,10 @@ void QHeaderView::resizeSection(int logical, int size) if (logical < 0 || logical >= count() || size < 0 || size > maxSizeSection) return; + // make sure to not exceed bounds when setting size programmatically + if (size > 0) + size = qBound(minimumSectionSize(), size, maximumSectionSize()); + if (isSectionHidden(logical)) { d->hiddenSectionSize.insert(logical, size); return; @@ -1661,9 +1665,25 @@ void QHeaderView::setMinimumSectionSize(int size) Q_D(QHeaderView); if (size < -1 || size > maxSizeSection) return; + // larger new min size - check current section sizes + const bool needSizeCheck = size > d->minimumSectionSize; d->minimumSectionSize = size; if (d->minimumSectionSize > maximumSectionSize()) - d->maximumSectionSize = size; + setMaximumSectionSize(size); + + if (needSizeCheck) { + if (d->hasAutoResizeSections()) { + d->doDelayedResizeSections(); + } else { + for (int visual = 0; visual < d->sectionCount(); ++visual) { + if (d->isVisualIndexHidden(visual)) + continue; + if (d->headerSectionSize(visual) < d->minimumSectionSize) + resizeSection(logicalIndex(visual), size); + } + } + } + } /*! @@ -1700,7 +1720,22 @@ void QHeaderView::setMaximumSectionSize(int size) if (minimumSectionSize() > size) d->minimumSectionSize = size; + // smaller new max size - check current section sizes + const bool needSizeCheck = size < d->maximumSectionSize; d->maximumSectionSize = size; + + if (needSizeCheck) { + if (d->hasAutoResizeSections()) { + d->doDelayedResizeSections(); + } else { + for (int visual = 0; visual < d->sectionCount(); ++visual) { + if (d->isVisualIndexHidden(visual)) + continue; + if (d->headerSectionSize(visual) > d->maximumSectionSize) + resizeSection(logicalIndex(visual), size); + } + } + } } @@ -3431,9 +3466,11 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool int logicalIndex = q->logicalIndex(i); sectionSize = qMax(viewSectionSizeHint(logicalIndex), q->sectionSizeHint(logicalIndex)); - if (sectionSize > q->maximumSectionSize()) - sectionSize = q->maximumSectionSize(); } + sectionSize = qBound(q->minimumSectionSize(), + sectionSize, + q->maximumSectionSize()); + section_sizes.append(sectionSize); lengthToStretch -= sectionSize; } diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index 8d90f9e59f..a5d131a436 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -239,13 +239,15 @@ private slots: void testStreamWithHide(); void testStylePosition(); void stretchAndRestoreLastSection(); - + void testMinMaxSectionSizeStretched(); + void testMinMaxSectionSizeNotStretched(); void sizeHintCrash(); protected: void setupTestData(bool use_reset_model = false); void additionalInit(); void calculateAndCheck(int cppline, const int precalced_comparedata[]); + void testMinMaxSectionSize(bool stretchLastSection); QWidget *topLevel; QHeaderView *view; @@ -402,6 +404,7 @@ void tst_QHeaderView::init() QCOMPARE(view->length(), 0); QCOMPARE(view->sizeHint(), QSize(0,0)); QCOMPARE(view->sectionSizeHint(0), -1); + view->setMinimumSectionSize(0); // system default min size can be to large /* model = new QStandardItemModel(1, 1); @@ -1604,6 +1607,7 @@ static QByteArray savedState() QStandardItemModel m(4, 4); QHeaderView h1(Qt::Horizontal); h1.setModel(&m); + h1.setMinimumSectionSize(0); // system default min size can be to large h1.swapSections(0, 2); h1.resizeSection(1, 10); h1.setSortIndicatorShown(true); @@ -2194,6 +2198,7 @@ void tst_QHeaderView::task248050_hideRow() //this is the sequence of events that make the task fail protected_QHeaderView header(Qt::Vertical); QStandardItemModel model(0, 1); + header.setMinimumSectionSize(0); // system default min size can be to large header.setStretchLastSection(false); header.setDefaultSectionSize(17); header.setModel(&model); @@ -3182,5 +3187,76 @@ void tst_QHeaderView::stretchAndRestoreLastSection() QCOMPARE(header.sectionSize(9), someOtherSectionSize); } +void tst_QHeaderView::testMinMaxSectionSizeStretched() +{ + testMinMaxSectionSize(true); +} + +void tst_QHeaderView::testMinMaxSectionSizeNotStretched() +{ + testMinMaxSectionSize(false); +} + +static void waitFor(const std::function<bool()> &func) +{ + for (int i = 0; i < 100; i++) + { + if (func()) + return; + QTest::qWait(10); + } +} + +void tst_QHeaderView::testMinMaxSectionSize(bool stretchLastSection) +{ + QStandardItemModel m(5, 5); + QTableView tv; + tv.setModel(&m); + tv.show(); + + const int sectionSizeMin = 20; + const int sectionSizeMax = 40; + const int defaultSectionSize = 30; + + QVERIFY(QTest::qWaitForWindowExposed(&tv)); + + QHeaderView &header = *tv.horizontalHeader(); + header.setMinimumSectionSize(sectionSizeMin); + header.setMaximumSectionSize(sectionSizeMax); + header.setDefaultSectionSize(defaultSectionSize); + header.setStretchLastSection(stretchLastSection); + + // check defaults + QCOMPARE(header.sectionSize(0), defaultSectionSize); + QCOMPARE(header.sectionSize(3), defaultSectionSize); + + // do not go above maxSectionSize + header.resizeSection(0, sectionSizeMax + 1); + QCOMPARE(header.sectionSize(0), sectionSizeMax); + + // do not go below minSectionSize + header.resizeSection(0, sectionSizeMin - 1); + QCOMPARE(header.sectionSize(0), sectionSizeMin); + + // change section size on max change + header.setMinimumSectionSize(sectionSizeMin); + header.setMaximumSectionSize(sectionSizeMax); + header.resizeSection(0, sectionSizeMax); + QCOMPARE(header.sectionSize(0), sectionSizeMax); + header.setMaximumSectionSize(defaultSectionSize); + waitFor([this, &header, defaultSectionSize]() { return header.sectionSize(0) == defaultSectionSize; }); + QCOMPARE(header.sectionSize(0), defaultSectionSize); + + // change section size on min change + header.setMinimumSectionSize(sectionSizeMin); + header.setMaximumSectionSize(sectionSizeMax); + header.resizeSection(0, sectionSizeMin); + QCOMPARE(header.sectionSize(0), sectionSizeMin); + header.setMinimumSectionSize(defaultSectionSize); + waitFor([this, &header, defaultSectionSize]() { return header.sectionSize(0) == defaultSectionSize; }); + QCOMPARE(header.sectionSize(0), defaultSectionSize); +} + + QTEST_MAIN(tst_QHeaderView) #include "tst_qheaderview.moc" diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index b558bd9b4e..06c80bf8d2 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -426,6 +426,9 @@ public: this, SLOT(slotCurrentChanged(QModelIndex,QModelIndex))); connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(itemSelectionChanged(QItemSelection,QItemSelection))); + // Allow small sections in this test, since this test was made before we correctly enforced minimum sizes. + horizontalHeader()->setMinimumSectionSize(0); + verticalHeader()->setMinimumSectionSize(0); } // enum CursorAction and moveCursor() are protected in QTableView. @@ -738,6 +741,8 @@ void tst_QTableView::headerSections() QHeaderView *vheader = view.verticalHeader(); view.setModel(&model); + hheader->setMinimumSectionSize(columnWidth); + vheader->setMinimumSectionSize(rowHeight); view.show(); hheader->doItemsLayout(); @@ -1147,6 +1152,9 @@ void tst_QTableView::moveCursor() QtTestTableView view; view.setModel(&model); + // we have to make sure that PgUp/PgDown can scroll to the bottom/top + view.resize(view.horizontalHeader()->length() + 50, + view.verticalHeader()->length() + 50); view.hideRow(hideRow); view.hideColumn(hideColumn); if (moveColumn.first != moveColumn.second) @@ -2085,6 +2093,8 @@ void tst_QTableView::visualRect() QTableView view; view.setModel(&model); + view.horizontalHeader()->setMinimumSectionSize(0); + view.verticalHeader()->setMinimumSectionSize(0); // Make sure that it has 1 pixel between each cell. view.setGridStyle(Qt::SolidLine); for (int i = 0; i < view.verticalHeader()->count(); ++i) @@ -3533,6 +3543,9 @@ void tst_QTableView::editSpanFromDirections() TableViewWithCursorExposed view; view.setModel(model.data()); + // we have to make sure that PgUp/PgDown can scroll to the bottom/top + view.resize(view.horizontalHeader()->length() + 50, + view.verticalHeader()->length() + 50); view.setSpan(row, column, rowSpan, columnSpan); view.show(); QVERIFY(QTest::qWaitForWindowActive(&view)); @@ -3978,7 +3991,7 @@ void tst_QTableView::mouseWheel_data() << 10 + qApp->wheelScrollLines() << 10 + qApp->wheelScrollLines(); QTest::newRow("scroll down per pixel") << int(QAbstractItemView::ScrollPerPixel) << -120 - << 10 + qApp->wheelScrollLines() * 89 << 10 + qApp->wheelScrollLines() * 28; + << 10 + qApp->wheelScrollLines() * 91 << 10 + qApp->wheelScrollLines() * 46; } void tst_QTableView::mouseWheel() @@ -3992,16 +4005,17 @@ void tst_QTableView::mouseWheel() QWidget topLevel; QtTestTableView view(&topLevel); view.resize(500, 500); - for (int r = 0; r < 100; ++r) - view.setRowHeight(r, 50); - for (int c = 0; c < 100; ++c) - view.setColumnWidth(c, 100); topLevel.show(); QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); view.setModel(&model); + for (int r = 0; r < 100; ++r) + view.setRowHeight(r, 50); + for (int c = 0; c < 100; ++c) + view.setColumnWidth(c, 100); + view.setHorizontalScrollMode((QAbstractItemView::ScrollMode)scrollMode); view.setVerticalScrollMode((QAbstractItemView::ScrollMode)scrollMode); view.horizontalScrollBar()->setValue(10); |