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>
This commit is contained in:
Christian Ehrlicher 2020-12-04 23:13:15 +01:00
parent 6fa1038a85
commit 0e4cc2aca7
2 changed files with 82 additions and 0 deletions

View File

@ -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);

View File

@ -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