diff options
-rw-r--r-- | src/widgets/itemviews/qlistview.cpp | 42 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp | 42 |
2 files changed, 83 insertions, 1 deletions
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 9b3221f84e..68d5d7612f 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -3487,7 +3487,47 @@ int QListView::visualIndex(const QModelIndex &index) const */ QSize QListView::viewportSizeHint() const { - return QAbstractItemView::viewportSizeHint(); + Q_D(const QListView); + // We don't have a nice simple size hint for invalid or wrapping list views. + if (!d->model) + return QAbstractItemView::viewportSizeHint(); + const int rc = d->model->rowCount(); + if (rc == 0 || isWrapping()) + return QAbstractItemView::viewportSizeHint(); + + QStyleOptionViewItem option; + initViewItemOption(&option); + + if (uniformItemSizes()) { + QSize sz = d->cachedItemSize; + if (!sz.isValid()) { + QModelIndex idx = d->model->index(0, d->column, d->root); + sz = d->itemSize(option, idx); + } + sz.setHeight(rc * sz.height()); + return sz; + } + + // Using AdjustToContents with a high number of rows will normally not make sense, so we limit + // this to default 1000 (that is btw the default for QHeaderView::resizeContentsPrecision()) + // (By setting the property _q_resizeContentPrecision the user can however override this). + int maximumRows = 1000; + const QVariant userOverrideValue = property("_q_resizeContentPrecision"); + if (userOverrideValue.isValid() && userOverrideValue.toInt() > 0) { + maximumRows = userOverrideValue.toInt(); + } + const int rowCount = qMin(rc, maximumRows); + + int h = 0; + int w = 0; + + for (int row = 0; row < rowCount; ++row) { + QModelIndex idx = d->model->index(row, d->column, d->root); + QSize itemSize = d->itemSize(option, idx); + h += itemSize.height(); + w = qMax(w, itemSize.width()); + } + return QSize(w, h); } QT_END_NAMESPACE diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index 7bd14729d8..74198d1cc4 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -38,6 +38,8 @@ #include <QTimer> #include <QtMath> #include <QProxyStyle> +#include <QVBoxLayout> +#include <QDialog> #include <QtTest/private/qtesthelpers_p.h> #include <QtWidgets/private/qlistview_p.h> @@ -166,6 +168,7 @@ private slots: void taskQTBUG_39902_mutualScrollBars(); void horizontalScrollingByVerticalWheelEvents(); void taskQTBUG_7232_AllowUserToControlSingleStep(); + void taskQTBUG_58749_adjustToContent(); void taskQTBUG_51086_skippingIndexesInSelectedIndexes(); void taskQTBUG_47694_indexOutOfBoundBatchLayout(); void itemAlignment(); @@ -2527,6 +2530,45 @@ void tst_QListView::taskQTBUG_7232_AllowUserToControlSingleStep() QCOMPARE(hStep1, lv.horizontalScrollBar()->singleStep()); } +void tst_QListView::taskQTBUG_58749_adjustToContent() +{ + QStandardItemModel model; + model.setRowCount(20); + model.setColumnCount(1); + const QString rowStr = QStringLiteral("Row number txt:"); + for (int u = 0; u < model.rowCount(); ++u) + model.setData(model.index(u, 0), rowStr + QString::number(u)); + + QDialog w; // It really should work for QWidget, too, but sometimes an event (like move) + // is needed to get the resize triggered. + QVBoxLayout *l = new QVBoxLayout(&w); + l->setSizeConstraint(QLayout::SetFixedSize); + auto *view = new QListView; + view->setModel(&model); + view->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); + l->addWidget(view); + l->setSizeConstraint(QLayout::SetFixedSize); + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); + + const QString longText = "Here we have a row text that is somewhat longer ..."; + + QFontMetrics fm(w.font(), &w); + QRect r = fm.boundingRect(model.data(model.index(0, 0)).toString()); + const int longTextWidth = fm.horizontalAdvance(longText); + QVERIFY(w.height() > r.height() * model.rowCount()); + // We have a width longer than the width for the given index data. + QVERIFY(w.width() > r.width()); + // but ... the width should not have a width matching the much longer text. + QVERIFY(w.width() < longTextWidth); + + // use the long text and make sure the width is adjusted. + model.setData(model.index(0, 0), longText); + QApplication::processEvents(); + QVERIFY(w.width() > longTextWidth); + QVERIFY(view->width() >= longTextWidth); +} + void tst_QListView::taskQTBUG_51086_skippingIndexesInSelectedIndexes() { QStandardItemModel data(10, 1); |