diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 16b5c26096d..a4dee5e48cb 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -4086,9 +4086,10 @@ void QAbstractItemView::doAutoScroll() } /*! - Returns the SelectionFlags to be used when updating a selection with - to include the \a index specified. The \a event is a user input event, - such as a mouse or keyboard event. + Returns the SelectionFlags to be used when updating a selection model + for the specified \a index. The result depends on the current + selectionMode(), and on the user input event \a event, which can be + \nullptr. Reimplement this function to define your own selection behavior. @@ -4105,12 +4106,24 @@ QItemSelectionModel::SelectionFlags QAbstractItemView::selectionCommand(const QM case NoSelection: // Never update selection model return QItemSelectionModel::NoUpdate; case SingleSelection: // ClearAndSelect on valid index otherwise NoUpdate - if (event && event->type() == QEvent::MouseButtonRelease) - return QItemSelectionModel::NoUpdate; - if ((keyModifiers & Qt::ControlModifier) && d->selectionModel->isSelected(index) && event->type() != QEvent::MouseMove) - return QItemSelectionModel::Deselect | d->selectionBehaviorFlags(); - else - return QItemSelectionModel::ClearAndSelect | d->selectionBehaviorFlags(); + if (event) { + switch (event->type()) { + case QEvent::MouseButtonPress: + // press with any modifiers on a selected item does nothing + if (d->pressedAlreadySelected) + return QItemSelectionModel::NoUpdate; + break; + case QEvent::KeyPress: + case QEvent::MouseButtonRelease: + // ctrl-release on selected item deselects + if ((keyModifiers & Qt::ControlModifier) && d->selectionModel->isSelected(index)) + return QItemSelectionModel::Deselect | d->selectionBehaviorFlags(); + break; + default: + break; + } + } + return QItemSelectionModel::ClearAndSelect | d->selectionBehaviorFlags(); case MultiSelection: return d->multiSelectionCommand(index, event); case ExtendedSelection: diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 869d552a4f8..dbc27368f4c 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -2889,9 +2889,17 @@ void tst_QAbstractItemView::mouseSelection_data() QTest::addRow("Single:Shift+Click") << QAbstractItemView::SingleSelection << false << QList{SelectionEvent{SelectionEvent::Click, Qt::ShiftModifier, 2}} << QList{2}; + QTest::addRow("Single:Press;Ctrl+Press") << QAbstractItemView::SingleSelection << false + << QList{SelectionEvent{SelectionEvent::Press, 3}, + SelectionEvent{SelectionEvent::Press, Qt::ControlModifier, 3}} + << QList{3}; QTest::addRow("Single:Ctrl+Click") << QAbstractItemView::SingleSelection << false << QList{SelectionEvent{SelectionEvent::Click, Qt::ControlModifier, 3}} << QList{3}; + QTest::addRow("Single:Click;Ctrl+Click") << QAbstractItemView::SingleSelection << false + << QList{SelectionEvent{SelectionEvent::Click, 3}, + SelectionEvent{SelectionEvent::Click, Qt::ControlModifier, 3}} + << QList{}; // multi selection mode - selection toggles on press, selection can be drag-extended // modifiers ignored