QAbstractItemView: with single selection, deselect on Ctrl+Release

After cbf1b4bc60bca3994b8f8685ee922e53a6b4eed2 the selected item got
deselected on Ctrl+Press, which made Ctrl+dragging a selected item
impossible.

Only deselect on Ctrl+Release. Add scenario to existing test case,
and update the documentation to clarify the properties involved, and
to point out that the event parameter might be nullptr.

Fixes: QTBUG-101647
Pick-to: 6.3 6.2
Change-Id: I749b1cb1a0a311f5c1d4c333984716f05f2c90b5
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Reviewed-by: Volker Enderlein <volker.enderlein@ifm-chemnitz.de>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Volker Hilsheimer 2022-03-20 16:44:26 +01:00
parent 6880b7c39b
commit dfb4697e4a
2 changed files with 30 additions and 9 deletions

View File

@ -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:

View File

@ -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<int>{};
// multi selection mode - selection toggles on press, selection can be drag-extended
// modifiers ignored