From 9cb231d773db6deb8fb145eb40aa949a2758d002 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 1 Jul 2009 10:22:15 +0200 Subject: ItemViews: Fixed signal entered not being emitted when using the mouse wheel The solution is to check the the current "entered item" hasn't change also when the scrollbars change values Task-number: 200665 Reviewed-by: janarve --- src/gui/itemviews/qabstractitemview.cpp | 72 ++++++++++++---------- src/gui/itemviews/qabstractitemview_p.h | 3 + .../qabstractitemview/tst_qabstractitemview.cpp | 19 ++++++ 3 files changed, 61 insertions(+), 33 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index cb0037b..b64bc71 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -127,6 +127,37 @@ void QAbstractItemViewPrivate::init() q->setAttribute(Qt::WA_InputMethodEnabled); } +void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index) +{ + //we take a persistent model index because the model might change by emitting signals + Q_Q(QAbstractItemView); + if (viewportEnteredNeeded || enteredIndex != index) { + viewportEnteredNeeded = false; + + if (index.isValid()) { + emit q->entered(index); +#ifndef QT_NO_STATUSTIP + QString statustip = model->data(index, Qt::StatusTipRole).toString(); + if (parent && !statustip.isEmpty()) { + QStatusTipEvent tip(statustip); + QApplication::sendEvent(parent, &tip); + } +#endif + } else { +#ifndef QT_NO_STATUSTIP + if (parent) { + QString emptyString; + QStatusTipEvent tip( emptyString ); + QApplication::sendEvent(parent, &tip); + } +#endif + emit q->viewportEntered(); + } + enteredIndex = index; + } +} + + /*! \class QAbstractItemView @@ -1557,7 +1588,7 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event) } #endif // QT_NO_DRAGANDDROP - QModelIndex index = indexAt(bottomRight); + QPersistentModelIndex index = indexAt(bottomRight); QModelIndex buddy = d->model->buddy(d->pressedIndex); if ((state() == EditingState && d->hasEditor(buddy)) || edit(index, NoEditTriggers, event)) @@ -1568,33 +1599,7 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event) else topLeft = bottomRight; - if (d->viewportEnteredNeeded || d->enteredIndex != index) { - d->viewportEnteredNeeded = false; - - // signal handlers may change the model - QPersistentModelIndex persistent = index; - if (persistent.isValid()) { - emit entered(persistent); -#ifndef QT_NO_STATUSTIP - QString statustip = d->model->data(persistent, Qt::StatusTipRole).toString(); - if (parent() && !statustip.isEmpty()) { - QStatusTipEvent tip(statustip); - QApplication::sendEvent(parent(), &tip); - } -#endif - } else { -#ifndef QT_NO_STATUSTIP - if (parent()) { - QString emptyString; - QStatusTipEvent tip(emptyString); - QApplication::sendEvent(parent(), &tip); - } -#endif - emit viewportEntered(); - } - d->enteredIndex = persistent; - index = persistent; - } + d->checkMouseMove(index); #ifndef QT_NO_DRAGANDDROP if (index.isValid() @@ -1613,14 +1618,13 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event) // Do the normalize ourselves, since QRect::normalized() is flawed QRect selectionRect = QRect(topLeft, bottomRight); - QPersistentModelIndex persistent = index; setSelection(selectionRect, command); // set at the end because it might scroll the view - if (persistent.isValid() - && (persistent != d->selectionModel->currentIndex()) - && d->isIndexEnabled(persistent)) - d->selectionModel->setCurrentIndex(persistent, QItemSelectionModel::NoUpdate); + if (index.isValid() + && (index != d->selectionModel->currentIndex()) + && d->isIndexEnabled(index)) + d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate); } } @@ -2422,6 +2426,7 @@ void QAbstractItemView::verticalScrollbarValueChanged(int value) Q_D(QAbstractItemView); if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); + d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); } /*! @@ -2432,6 +2437,7 @@ void QAbstractItemView::horizontalScrollbarValueChanged(int value) Q_D(QAbstractItemView); if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); + d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); } /*! diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 030147b..c2c1f32 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -139,6 +139,9 @@ public: const QEvent *event) const; virtual void selectAll(QItemSelectionModel::SelectionFlags command); + void checkMouseMove(const QPersistentModelIndex &index); + inline void checkMouseMove(const QPoint &pos) { checkMouseMove(q_func()->indexAt(pos)); } + inline QItemSelectionModel::SelectionFlags selectionBehaviorFlags() const { switch (selectionBehavior) { diff --git a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp index c117aa4..0bc459e 100644 --- a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp @@ -212,6 +212,7 @@ private slots: void task221955_selectedEditor(); void task250754_fontChange(); + void task200665_itemEntered(); }; class MyAbstractItemDelegate : public QAbstractItemDelegate @@ -1199,5 +1200,23 @@ void tst_QAbstractItemView::task250754_fontChange() qApp->setStyleSheet(app_css); } +void tst_QAbstractItemView::task200665_itemEntered() +{ + //we test that view will emit entered + //when the scrollbar move but not the mouse itself + QStandardItemModel model(1000,1); + QListView view; + view.setModel(&model); + view.show(); + QTest::qWait(200); + QRect rect = view.visualRect(model.index(0,0)); + QCursor::setPos( view.viewport()->mapToGlobal(rect.center()) ); + QSignalSpy spy(&view, SIGNAL(entered(QModelIndex))); + view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum()); + QCOMPARE(spy.count(), 1); + +} + + QTEST_MAIN(tst_QAbstractItemView) #include "tst_qabstractitemview.moc" -- cgit v0.12