diff options
-rw-r--r-- | src/widgets/itemviews/qabstractitemview.cpp | 33 | ||||
-rw-r--r-- | src/widgets/itemviews/qabstractitemview.h | 6 | ||||
-rw-r--r-- | src/widgets/itemviews/qabstractitemview_p.h | 4 | ||||
-rw-r--r-- | src/widgets/styles/qcommonstyle.cpp | 3 | ||||
-rw-r--r-- | src/widgets/styles/qmacstyle_mac.mm | 3 | ||||
-rw-r--r-- | src/widgets/styles/qstyle.cpp | 4 | ||||
-rw-r--r-- | src/widgets/styles/qstyle.h | 1 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp | 50 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp | 28 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp | 2 |
10 files changed, 121 insertions, 13 deletions
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index d98f61b990..9135d1a23c 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -108,7 +108,9 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate() currentIndexSet(false), wrapItemText(false), delayedPendingLayout(true), - moveCursorUpdatedView(false) + moveCursorUpdatedView(false), + verticalScrollModeSet(false), + horizontalScrollModeSet(false) { keyboardInputTime.invalidate(); } @@ -137,6 +139,9 @@ void QAbstractItemViewPrivate::init() viewport->setBackgroundRole(QPalette::Base); q->setAttribute(Qt::WA_InputMethodEnabled); + + verticalScrollMode = static_cast<QAbstractItemView::ScrollMode>(q->style()->styleHint(QStyle::SH_ItemView_ScrollMode, 0, q, 0)); + horizontalScrollMode = static_cast<QAbstractItemView::ScrollMode>(q->style()->styleHint(QStyle::SH_ItemView_ScrollMode, 0, q, 0)); } void QAbstractItemViewPrivate::setHoverIndex(const QPersistentModelIndex &index) @@ -1237,12 +1242,14 @@ QAbstractItemView::EditTriggers QAbstractItemView::editTriggers() const \brief how the view scrolls its contents in the vertical direction This property controls how the view scroll its contents vertically. - Scrolling can be done either per pixel or per item. + Scrolling can be done either per pixel or per item. Its default value + comes from the style via the QStyle::SH_ItemView_ScrollMode style hint. */ void QAbstractItemView::setVerticalScrollMode(ScrollMode mode) { Q_D(QAbstractItemView); + d->verticalScrollModeSet = true; if (mode == d->verticalScrollMode) return; QModelIndex topLeft = indexAt(QPoint(0, 0)); @@ -1261,18 +1268,27 @@ QAbstractItemView::ScrollMode QAbstractItemView::verticalScrollMode() const return d->verticalScrollMode; } +void QAbstractItemView::resetVerticalScrollMode() +{ + auto sm = static_cast<ScrollMode>(style()->styleHint(QStyle::SH_ItemView_ScrollMode, 0, this, 0)); + setVerticalScrollMode(sm); + d_func()->verticalScrollModeSet = false; +} + /*! \since 4.2 \property QAbstractItemView::horizontalScrollMode \brief how the view scrolls its contents in the horizontal direction This property controls how the view scroll its contents horizontally. - Scrolling can be done either per pixel or per item. + Scrolling can be done either per pixel or per item. Its default value + comes from the style via the QStyle::SH_ItemView_ScrollMode style hint. */ void QAbstractItemView::setHorizontalScrollMode(ScrollMode mode) { Q_D(QAbstractItemView); + d->horizontalScrollModeSet = true; if (mode == d->horizontalScrollMode) return; d->horizontalScrollMode = mode; @@ -1289,6 +1305,13 @@ QAbstractItemView::ScrollMode QAbstractItemView::horizontalScrollMode() const return d->horizontalScrollMode; } +void QAbstractItemView::resetHorizontalScrollMode() +{ + auto sm = static_cast<ScrollMode>(style()->styleHint(QStyle::SH_ItemView_ScrollMode, 0, this, 0)); + setHorizontalScrollMode(sm); + d_func()->horizontalScrollModeSet = false; +} + #ifndef QT_NO_DRAGANDDROP /*! \since 4.2 @@ -1627,6 +1650,10 @@ bool QAbstractItemView::event(QEvent *event) break; case QEvent::StyleChange: doItemsLayout(); + if (!d->verticalScrollModeSet) + resetVerticalScrollMode(); + if (!d->horizontalScrollModeSet) + resetHorizontalScrollMode(); break; case QEvent::FocusOut: d->checkPersistentEditorFocus(); diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h index fb1d222676..b8d386f234 100644 --- a/src/widgets/itemviews/qabstractitemview.h +++ b/src/widgets/itemviews/qabstractitemview.h @@ -75,8 +75,8 @@ class Q_WIDGETS_EXPORT QAbstractItemView : public QAbstractScrollArea Q_PROPERTY(SelectionBehavior selectionBehavior READ selectionBehavior WRITE setSelectionBehavior) Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize NOTIFY iconSizeChanged) Q_PROPERTY(Qt::TextElideMode textElideMode READ textElideMode WRITE setTextElideMode) - Q_PROPERTY(ScrollMode verticalScrollMode READ verticalScrollMode WRITE setVerticalScrollMode) - Q_PROPERTY(ScrollMode horizontalScrollMode READ horizontalScrollMode WRITE setHorizontalScrollMode) + Q_PROPERTY(ScrollMode verticalScrollMode READ verticalScrollMode WRITE setVerticalScrollMode RESET resetVerticalScrollMode) + Q_PROPERTY(ScrollMode horizontalScrollMode READ horizontalScrollMode WRITE setHorizontalScrollMode RESET resetHorizontalScrollMode) public: enum SelectionMode { @@ -147,9 +147,11 @@ public: void setVerticalScrollMode(ScrollMode mode); ScrollMode verticalScrollMode() const; + void resetVerticalScrollMode(); void setHorizontalScrollMode(ScrollMode mode); ScrollMode horizontalScrollMode() const; + void resetHorizontalScrollMode(); void setAutoScroll(bool enable); bool hasAutoScroll() const; diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h index 4ba24a2786..a3af79abcb 100644 --- a/src/widgets/itemviews/qabstractitemview_p.h +++ b/src/widgets/itemviews/qabstractitemview_p.h @@ -461,6 +461,10 @@ public: mutable bool delayedPendingLayout; bool moveCursorUpdatedView; + // Whether scroll mode has been explicitly set or its value come from SH_ItemView_ScrollMode + bool verticalScrollModeSet; + bool horizontalScrollModeSet; + private: mutable QBasicTimer delayedLayout; mutable QBasicTimer fetchMoreTimer; diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 17c2ea2ba8..c28a70e3f9 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -5215,6 +5215,9 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget case SH_Splitter_OpaqueResize: ret = true; break; + case SH_ItemView_ScrollMode: + ret = QAbstractItemView::ScrollPerItem; + break; default: ret = 0; break; diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 009cc1b1b0..74554f6d3d 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -3043,6 +3043,9 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w ret = [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay; } break; + case SH_ItemView_ScrollMode: + ret = QAbstractItemView::ScrollPerPixel; + break; default: ret = QCommonStyle::styleHint(sh, opt, w, hret); break; diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 34d5b49ee1..26bb227e29 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -1978,6 +1978,10 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, tab is changed while dragging over the tabbar, in milliseconds. This enum value has been introduced in Qt 5.4 + \value SH_ItemView_ScrollMode The default vertical and horizontal scroll mode as specified + by the style. Can be overridden with QAbstractItemView::setVerticalScrollMode() and + QAbstractItemView::setHorizontalScrollMode(). This enum value has been introduced in Qt 5.7. + \sa styleHint() */ diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index 425acc8301..0f9c9379f5 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -732,6 +732,7 @@ public: SH_Menu_SubMenuSloppyCloseTimeout, SH_Menu_SubMenuResetWhenReenteringParent, SH_Menu_SubMenuDontStartSloppyOnLeave, + SH_ItemView_ScrollMode, // Add new style hint values here SH_CustomBase = 0xf0000000 diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 2a26427542..2dd0337117 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -50,6 +50,7 @@ #include <qstyleditemdelegate.h> #include <qstringlistmodel.h> #include <qsortfilterproxymodel.h> +#include <qproxystyle.h> static inline void setFrameless(QWidget *w) { @@ -246,6 +247,7 @@ private slots: void sizeHintChangeTriggersLayout(); void shiftSelectionAfterChangingModelContents(); void QTBUG48968_reentrant_updateEditorGeometries(); + void QTBUG50102_SH_ItemView_ScrollMode(); }; class MyAbstractItemDelegate : public QAbstractItemDelegate @@ -2018,5 +2020,53 @@ void tst_QAbstractItemView::QTBUG48968_reentrant_updateEditorGeometries() // No crash, all fine. } +class ScrollModeProxyStyle: public QProxyStyle +{ +public: + ScrollModeProxyStyle(QAbstractItemView::ScrollMode sm, QStyle *style = 0) + : QProxyStyle(style) + , scrollMode(sm == QAbstractItemView::ScrollPerItem ? + QAbstractItemView::ScrollPerPixel : QAbstractItemView::ScrollPerItem) + { } + + int styleHint(QStyle::StyleHint hint, const QStyleOption *opt, const QWidget *w, QStyleHintReturn *returnData) const override + { + if (hint == SH_ItemView_ScrollMode) + return scrollMode; + + return baseStyle()->styleHint(hint, opt, w, returnData); + } + + QAbstractItemView::ScrollMode scrollMode; +}; + +void tst_QAbstractItemView::QTBUG50102_SH_ItemView_ScrollMode() +{ + QListView view; + + // Default comes from the style + auto styleScrollMode = static_cast<QAbstractItemView::ScrollMode>(view.style()->styleHint(QStyle::SH_ItemView_ScrollMode, 0, &view, 0)); + QCOMPARE(view.verticalScrollMode(), styleScrollMode); + QCOMPARE(view.horizontalScrollMode(), styleScrollMode); + + // Change style, get new value + view.setStyle(new ScrollModeProxyStyle(styleScrollMode)); + auto proxyScrollMode = static_cast<QAbstractItemView::ScrollMode>(view.style()->styleHint(QStyle::SH_ItemView_ScrollMode, 0, &view, 0)); + QVERIFY(styleScrollMode != proxyScrollMode); + QCOMPARE(view.verticalScrollMode(), proxyScrollMode); + QCOMPARE(view.horizontalScrollMode(), proxyScrollMode); + + // Explicitly set vertical, same value + view.setVerticalScrollMode(proxyScrollMode); + QCOMPARE(view.verticalScrollMode(), proxyScrollMode); + QCOMPARE(view.horizontalScrollMode(), proxyScrollMode); + + // Change style, won't change value for vertical, will change for horizontal + view.setStyle(new ScrollModeProxyStyle(proxyScrollMode)); + QCOMPARE(view.verticalScrollMode(), proxyScrollMode); + QCOMPARE(view.horizontalScrollMode(), styleScrollMode); +} + + QTEST_MAIN(tst_QAbstractItemView) #include "tst_qabstractitemview.moc" diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index ea9f20d5ba..5058dd2a81 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -279,6 +279,18 @@ public: mutable bool wrongIndex; }; +class ScrollPerItemListView : public QListView +{ +public: + explicit ScrollPerItemListView(QWidget *parent = Q_NULLPTR) + : QListView(parent) + { + // Force per item scroll mode since it comes from the style by default + setVerticalScrollMode(QAbstractItemView::ScrollPerItem); + setHorizontalScrollMode(QAbstractItemView::ScrollPerItem); + } +}; + void tst_QListView::initTestCase() { #ifdef Q_OS_WINCE //disable magic for WindowsCE @@ -823,7 +835,7 @@ void tst_QListView::setCurrentIndex() { QStringListModel model(generateList(QLatin1String("item "), 20)); - QListView view; + ScrollPerItemListView view; view.setModel(&model); view.resize(220,182); @@ -1153,7 +1165,7 @@ void tst_QListView::scrollTo() { QWidget topLevel; setFrameless(&topLevel); - QListView lv(&topLevel); + ScrollPerItemListView lv(&topLevel); QStringListModel model(&lv); QStringList list; list << "Short item 1"; @@ -1189,6 +1201,7 @@ void tst_QListView::scrollTo() model.setStringList(list); lv.setModel(&model); lv.setFixedSize(110, 200); + topLevel.show(); QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); @@ -1262,7 +1275,7 @@ void tst_QListView::scrollBarRanges() const int rowHeight = 20; QWidget topLevel; - QListView lv(&topLevel); + ScrollPerItemListView lv(&topLevel); QStringListModel model(&lv); QStringList list; for (int i = 0; i < rowCount; ++i) @@ -1271,6 +1284,7 @@ void tst_QListView::scrollBarRanges() model.setStringList(list); lv.setModel(&model); lv.resize(250, 130); + TestDelegate *delegate = new TestDelegate(&lv); delegate->m_sizeHint = QSize(100, rowHeight); lv.setItemDelegate(delegate); @@ -1814,7 +1828,7 @@ void tst_QListView::taskQTBUG_2233_scrollHiddenItems() QWidget topLevel; setFrameless(&topLevel); - QListView view(&topLevel); + ScrollPerItemListView view(&topLevel); QStringListModel model(&view); QStringList list; for (int i = 0; i < rowCount; ++i) @@ -2060,7 +2074,7 @@ void tst_QListView::taskQTBUG_21115_scrollToAndHiddenItems() { QFETCH(int, flow); - QListView lv; + ScrollPerItemListView lv; lv.setUniformItemSizes(true); lv.setFlow(static_cast<QListView::Flow>(flow)); @@ -2155,7 +2169,7 @@ void tst_QListView::taskQTBUG_21804_hiddenItemsAndScrollingWithKeys() model.setStringList(list); // create listview - QListView lv; + ScrollPerItemListView lv; lv.setFlow(static_cast<QListView::Flow>(flow)); lv.setSpacing(spacing); lv.setModel(&model); @@ -2227,7 +2241,7 @@ void tst_QListView::spacing() model.setStringList(list); // create listview - QListView lv; + ScrollPerItemListView lv; lv.setFlow(static_cast<QListView::Flow>(flow)); lv.setModel(&model); lv.setSpacing(spacing); diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index e21aedee1e..137f18e23a 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -503,7 +503,7 @@ void tst_QTreeView::construction() QCOMPARE(view.sizeHintForRow(1), -1); QVERIFY(!view.tabKeyNavigation()); QCOMPARE(view.textElideMode(), Qt::ElideRight); - QCOMPARE(view.verticalScrollMode(), QAbstractItemView::ScrollPerItem); + QCOMPARE(static_cast<int>(view.verticalScrollMode()), view.style()->styleHint(QStyle::SH_ItemView_ScrollMode, 0, &view)); QCOMPARE(view.visualRect(QModelIndex()), QRect()); // QTreeView properties |