summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Ehrlicher <ch.ehrlicher@gmx.de>2017-10-31 16:05:58 +0100
committerChristian Ehrlicher <ch.ehrlicher@gmx.de>2018-01-06 05:17:00 +0000
commit20604ea554b282efa80502c68a499824f8692e7a (patch)
treeed1c27e6e482913d65c687c2a77ba68aa72c4df6
parent1c0ac8c4b8646e898aa1636f93dcfd34949611cf (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.cpp43
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp78
-rw-r--r--tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp24
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);