diff options
| -rw-r--r-- | src/kitemviews/kitemlistcontainer.cpp | 34 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistcontainer.h | 7 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistview.cpp | 13 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistview.h | 8 |
4 files changed, 62 insertions, 0 deletions
diff --git a/src/kitemviews/kitemlistcontainer.cpp b/src/kitemviews/kitemlistcontainer.cpp index 58f2e3cd6..b480b4494 100644 --- a/src/kitemviews/kitemlistcontainer.cpp +++ b/src/kitemviews/kitemlistcontainer.cpp @@ -234,11 +234,19 @@ void KItemListContainer::updateScrollOffsetScrollBar() const int value = view->scrollOffset(); const int maximum = qMax(0, int(view->maximumScrollOffset() - pageStep)); if (smoothScroller->requestScrollBarUpdate(maximum)) { + const bool updatePolicy = (scrollOffsetScrollBar->maximum() > 0 && maximum == 0) + || horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOn; + scrollOffsetScrollBar->setSingleStep(singleStep); scrollOffsetScrollBar->setPageStep(pageStep); scrollOffsetScrollBar->setMinimum(0); scrollOffsetScrollBar->setMaximum(maximum); scrollOffsetScrollBar->setValue(value); + + if (updatePolicy) { + // Prevent a potential endless layout loop (see bug #293318). + updateScrollOffsetScrollBarPolicy(); + } } } @@ -320,6 +328,32 @@ void KItemListContainer::updateSmoothScrollers(Qt::Orientation orientation) } } +void KItemListContainer::updateScrollOffsetScrollBarPolicy() +{ + const KItemListView* view = m_controller->view(); + Q_ASSERT(view); + const bool vertical = (view->scrollOrientation() == Qt::Vertical); + + QStyleOption option; + option.initFrom(this); + const int scrollBarInc = style()->pixelMetric(QStyle::PM_ScrollBarExtent, &option, this); + + QSizeF newViewSize = m_controller->view()->size(); + if (vertical) { + newViewSize.rwidth() += scrollBarInc; + } else { + newViewSize.rheight() += scrollBarInc; + } + + const Qt::ScrollBarPolicy policy = view->scrollBarRequired(newViewSize) + ? Qt::ScrollBarAlwaysOn : Qt::ScrollBarAsNeeded; + if (vertical) { + setVerticalScrollBarPolicy(policy); + } else { + setHorizontalScrollBarPolicy(policy); + } +} + void KItemListContainer::initialize() { if (m_controller) { diff --git a/src/kitemviews/kitemlistcontainer.h b/src/kitemviews/kitemlistcontainer.h index 4d6eadbbb..b41f48a7f 100644 --- a/src/kitemviews/kitemlistcontainer.h +++ b/src/kitemviews/kitemlistcontainer.h @@ -70,6 +70,13 @@ private: void updateGeometries(); void updateSmoothScrollers(Qt::Orientation orientation); + /** + * Helper method for updateScrollOffsetScrollBar(). Updates the scrollbar-policy + * to Qt::ScrollBarAlwaysOn for cases where turning off the scrollbar might lead + * to an endless layout loop (see bug #293318). + */ + void updateScrollOffsetScrollBarPolicy(); + private: KItemListController* m_controller; diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index c671a2e6e..52d857705 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -1880,6 +1880,19 @@ bool KItemListView::animateChangedItemCount(int changedItemCount) const return changedItemCount <= maximum * 2 / 3; } + +bool KItemListView::scrollBarRequired(const QSizeF& size) const +{ + const QSizeF oldSize = m_layouter->size(); + + m_layouter->setSize(size); + const qreal maxOffset = m_layouter->maximumScrollOffset(); + m_layouter->setSize(oldSize); + + return m_layouter->scrollOrientation() == Qt::Vertical ? maxOffset > size.height() + : maxOffset > size.width(); +} + int KItemListView::calculateAutoScrollingIncrement(int pos, int range, int oldInc) { int inc = 0; diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 9c34daba3..e675df221 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -462,6 +462,13 @@ private: bool animateChangedItemCount(int changedItemCount) const; /** + * @return True if a scrollbar for the given scroll-orientation is required + * when using a size of \p size for the view. Calling the method is rather + * expansive as a temporary relayout needs to be done. + */ + bool scrollBarRequired(const QSizeF& size) const; + + /** * Helper function for triggerAutoScrolling(). * @param pos Logical position of the mouse relative to the range. * @param range Range of the visible area. @@ -512,6 +519,7 @@ private: KItemListHeader* m_header; bool m_useHeaderWidths; + friend class KItemListContainer; // Accesses scrollBarRequired() friend class KItemListController; friend class KItemListControllerTest; }; |
