diff options
author | Christian Ehrlicher <ch.ehrlicher@gmx.de> | 2020-12-04 23:13:15 +0100 |
---|---|---|
committer | Christian Ehrlicher <ch.ehrlicher@gmx.de> | 2020-12-10 19:41:26 +0100 |
commit | 0e4cc2aca7eb77879d20142e761773a891b33f10 (patch) | |
tree | 0663a742a570237032df751b0609b9a8999dd43a | |
parent | 6fa1038a85f8e0da7c91b510cf01fe1bbcf37c0f (diff) |
QTableView: honor spans when calculating height/width hint
QTableViewPrivate::heightHintForIndex()/widthHintForIndex() did not
honor spans and therefore returned too big values.
Fixes: QTBUG-89116
Change-Id: I52948902b7eaaa27c092ed39da68950c3840e8e4
Pick-to: 5.15
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
-rw-r--r-- | src/widgets/itemviews/qtableview.cpp | 17 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp | 65 |
2 files changed, 82 insertions, 0 deletions
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 91afd3c7ed..544709d811 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -1060,6 +1060,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem & int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const { Q_Q(const QTableView); + const int oldHint = hint; QWidget *editor = editorForIndex(index).widget.data(); if (editor && persistent.contains(editor)) { hint = qMax(hint, editor->sizeHint().width()); @@ -1068,6 +1069,17 @@ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, con hint = qBound(min, hint, max); } hint = qMax(hint, q->itemDelegateForIndex(index)->sizeHint(option, index).width()); + + if (hasSpans()) { + auto span = spans.spanAt(index.column(), index.row()); + if (span && span->m_left == index.column() && span->m_top == index.row()) { + // spans are screwed up when sections are moved + const auto left = logicalColumn(span->m_left); + for (int i = 1; i <= span->width(); ++i) + hint -= q->columnWidth(visualColumn(left + i)); + } + hint = std::max(hint, oldHint); + } return hint; } @@ -1100,6 +1112,11 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS option.rect.setHeight(height); option.rect.setX(q->columnViewportPosition(index.column())); option.rect.setWidth(q->columnWidth(index.column())); + if (hasSpans()) { + auto span = spans.spanAt(index.column(), index.row()); + if (span && span->m_left == index.column() && span->m_top == index.row()) + option.rect.setWidth(std::max(option.rect.width(), visualSpanRect(*span).width())); + } // 1px less space when grid is shown (see drawCell) if (showGrid) option.rect.setWidth(option.rect.width() - 1); diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index 4588a29a0f..92bc30380a 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -408,6 +408,7 @@ private slots: void checkHeaderMinSize(); void resizeToContents(); + void resizeToContentsSpans(); void tabFocus(); void bigModel(); @@ -3724,6 +3725,70 @@ void tst_QTableView::resizeToContents() } + +class SpanModel : public QAbstractTableModel +{ +public: + SpanModel(bool sectionsMoved) + : _sectionsMoved(sectionsMoved) + {} + int columnCount(const QModelIndex & = {}) const override { return 2; } + int rowCount(const QModelIndex & = {}) const override { return 1; } + QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override + { + if (role != Qt::DisplayRole) + return QVariant(); + const int col = _sectionsMoved ? 1 - idx.column() : idx.column(); + if (col == 0) + return "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + return QVariant(); + } +private: + bool _sectionsMoved; +}; + + +void tst_QTableView::resizeToContentsSpans() +{ + SpanModel model1(false); + SpanModel model2(true); + QTableView view1, view2, view3; + view1.setModel(&model1); + view2.setModel(&model2); + view2.horizontalHeader()->moveSection(0, 1); + view3.setModel(&model1); + + view1.setSpan(0, 0, 1, 2); + view2.setSpan(0, 1, 1, 2); + view1.show(); + view2.show(); + view3.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view1)); + QVERIFY(QTest::qWaitForWindowExposed(&view2)); + QVERIFY(QTest::qWaitForWindowExposed(&view3)); + view1.setColumnWidth(0, 100); + view1.setColumnWidth(1, 100); + view2.setColumnWidth(0, 100); + view2.setColumnWidth(1, 100); + view3.setColumnWidth(0, 200); + + view1.resizeRowToContents(0); + view2.resizeRowToContents(0); + view3.resizeRowToContents(0); + QCOMPARE(view1.rowHeight(0), view3.rowHeight(0)); + QCOMPARE(view2.rowHeight(0), view3.rowHeight(0)); + + view3.resizeColumnToContents(0); + view3.resizeRowToContents(0); + // height should be only 1 text line for easy testing + view1.setRowHeight(0, view3.verticalHeader()->sectionSize(0)); + view2.setRowHeight(0, view3.verticalHeader()->sectionSize(0)); + view1.resizeColumnToContents(0); + view2.resizeColumnToContents(1); + QCOMPARE(view1.columnWidth(0), view3.columnWidth(0) - view1.columnWidth(1)); + QCOMPARE(view2.columnWidth(0), view3.columnWidth(0) - view2.columnWidth(1)); +} + QT_BEGIN_NAMESPACE extern bool Q_WIDGETS_EXPORT qt_tab_all_widgets(); // qapplication.cpp QT_END_NAMESPACE |