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:
parent
6fa1038a85
commit
0e4cc2aca7
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user