From a4c25c020554527aa9ff9b533afabffef46be131 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Tue, 18 Oct 2016 16:35:16 +0300 Subject: [PATCH] Add expandingListItems property to QListView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This property allows to change the default behavior in which list items occupy the entire width of the column. Setting it to false will reduce their widths to the minimum values, thus allowing to have intermediate free space. Then the user will be able to begin selections by mouse from this space. [ChangeLog][QtWidgets][QListView] Added expandingListItems property. Change-Id: I6bd1b147fd0335324310a165104c36f6b0d6ac9f Task-number: QTBUG-56606 Reviewed-by: Anton Kudryavtsev Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qlistview.cpp | 44 +++++++++++++++++-- src/widgets/itemviews/qlistview.h | 4 ++ src/widgets/itemviews/qlistview_p.h | 2 + .../itemviews/qlistview/tst_qlistview.cpp | 24 ++++++++++ 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index d19e5d9a9f4..5224a13456c 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1624,6 +1624,33 @@ bool QListView::isSelectionRectVisible() const return d->isSelectionRectVisible(); } +/*! + \property QListView::expandingListItems + \brief if items occupy the entire width of the column + \since 5.9 + + If this property is \c true then all items in the column + will have the width of the column; otherwise the width of + each item will be determined by it's size hint. + + By default, this property is \c true. +*/ +void QListView::setExpandingListItems(bool enable) +{ + Q_D(QListView); + if (d->expandingListItems == enable) + return; + d->expandingListItems = enable; + if (viewMode() == ListMode && flow() == QListView::TopToBottom && isWrapping()) + d->doDelayedItemsLayout(); +} + +bool QListView::isExpandingListItems() const +{ + Q_D(const QListView); + return d->expandingListItems; +} + /*! \reimp */ @@ -1650,7 +1677,8 @@ QListViewPrivate::QListViewPrivate() column(0), uniformItemSizes(false), batchSize(100), - showElasticBand(false) + showElasticBand(false), + expandingListItems(true) { } @@ -2365,7 +2393,8 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c int right = (segment + 1 >= segmentPositions.count() ? contentsSize.width() : segmentPositions.at(segment + 1)); - size.setWidth(right - pos.x()); + size.setWidth(dd->expandingListItems ? right - pos.x() + : qMin(size.width(), right - pos.x())); } else { // make the items as wide as the viewport size.setWidth(qMax(size.width(), viewport()->width() - 2 * spacing())); } @@ -2551,8 +2580,15 @@ QVector QListModeViewBase::intersectingSet(const QRect &area) const if (isHidden(row)) continue; QModelIndex index = modelIndex(row); - if (index.isValid()) - ret += index; + if (index.isValid()) { + if (flow() == QListView::LeftToRight || dd->expandingListItems) { + ret += index; + } else { + const int iw = indexToListViewItem(index).width(); // item width + if (iw > 0 && segStartPosition - segmentPositions.at(seg) < iw) + ret += index; + } + } #if 0 // for debugging else qWarning("intersectingSet: row %d was invalid", row); diff --git a/src/widgets/itemviews/qlistview.h b/src/widgets/itemviews/qlistview.h index e918e66d383..4cf53f9bab1 100644 --- a/src/widgets/itemviews/qlistview.h +++ b/src/widgets/itemviews/qlistview.h @@ -66,6 +66,7 @@ class Q_WIDGETS_EXPORT QListView : public QAbstractItemView Q_PROPERTY(int batchSize READ batchSize WRITE setBatchSize) Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap) Q_PROPERTY(bool selectionRectVisible READ isSelectionRectVisible WRITE setSelectionRectVisible) + Q_PROPERTY(bool expandingListItems READ isExpandingListItems WRITE setExpandingListItems) public: enum Movement { Static, Free, Snap }; @@ -126,6 +127,9 @@ public: void setSelectionRectVisible(bool show); bool isSelectionRectVisible() const; + void setExpandingListItems(bool enable); + bool isExpandingListItems() const; + QRect visualRect(const QModelIndex &index) const Q_DECL_OVERRIDE; void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) Q_DECL_OVERRIDE; QModelIndex indexAt(const QPoint &p) const Q_DECL_OVERRIDE; diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h index 47effcdfd99..a66e0071950 100644 --- a/src/widgets/itemviews/qlistview_p.h +++ b/src/widgets/itemviews/qlistview_p.h @@ -431,6 +431,8 @@ public: QRect elasticBand; bool showElasticBand; + + bool expandingListItems; }; // inline implementations diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index 0f1c5723d55..e5e9b87df4b 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -150,6 +150,7 @@ private slots: void horizontalScrollingByVerticalWheelEvents(); void taskQTBUG_7232_AllowUserToControlSingleStep(); void taskQTBUG_51086_skippingIndexesInSelectedIndexes(); + void expandingListItems(); }; // Testing get/set functions @@ -2486,5 +2487,28 @@ void tst_QListView::taskQTBUG_51086_skippingIndexesInSelectedIndexes() QVERIFY(!indexes.contains(data.index(8, 0))); } +void tst_QListView::expandingListItems() +{ + auto item1 = new QStandardItem("111"); + auto item2 = new QStandardItem("111111"); + QStandardItemModel model; + model.appendRow(item1); + model.appendRow(item2); + + QListView w; + w.setModel(&model); + w.setWrapping(true); + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); + + QVERIFY(w.visualRect(item1->index()).width() > 0); + QVERIFY(w.visualRect(item1->index()).width() == w.visualRect(item2->index()).width()); + + w.setExpandingListItems(false); + QApplication::processEvents(); + + QVERIFY(w.visualRect(item1->index()).width() < w.visualRect(item2->index()).width()); +} + QTEST_MAIN(tst_QListView) #include "tst_qlistview.moc"