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 Returns the SelectionFlags to be used when updating a selection model
to include the \a index specified. The \a event is a user input event, for the specified \a index. The result depends on the current
such as a mouse or keyboard event. selectionMode(), and on the user input event \a event, which can be
\nullptr.
Reimplement this function to define your own selection behavior. 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 case NoSelection: // Never update selection model
return QItemSelectionModel::NoUpdate; return QItemSelectionModel::NoUpdate;
case SingleSelection: // ClearAndSelect on valid index otherwise NoUpdate case SingleSelection: // ClearAndSelect on valid index otherwise NoUpdate
if (event && event->type() == QEvent::MouseButtonRelease) if (event) {
return QItemSelectionModel::NoUpdate; switch (event->type()) {
if ((keyModifiers & Qt::ControlModifier) && d->selectionModel->isSelected(index) && event->type() != QEvent::MouseMove) case QEvent::MouseButtonPress:
return QItemSelectionModel::Deselect | d->selectionBehaviorFlags(); // press with any modifiers on a selected item does nothing
else if (d->pressedAlreadySelected)
return QItemSelectionModel::ClearAndSelect | d->selectionBehaviorFlags(); 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: case MultiSelection:
return d->multiSelectionCommand(index, event); return d->multiSelectionCommand(index, event);
case ExtendedSelection: case ExtendedSelection:

View File

@ -2889,9 +2889,17 @@ void tst_QAbstractItemView::mouseSelection_data()
QTest::addRow("Single:Shift+Click") << QAbstractItemView::SingleSelection << false QTest::addRow("Single:Shift+Click") << QAbstractItemView::SingleSelection << false
<< QList{SelectionEvent{SelectionEvent::Click, Qt::ShiftModifier, 2}} << QList{SelectionEvent{SelectionEvent::Click, Qt::ShiftModifier, 2}}
<< QList{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 QTest::addRow("Single:Ctrl+Click") << QAbstractItemView::SingleSelection << false
<< QList{SelectionEvent{SelectionEvent::Click, Qt::ControlModifier, 3}} << QList{SelectionEvent{SelectionEvent::Click, Qt::ControlModifier, 3}}
<< QList{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 // multi selection mode - selection toggles on press, selection can be drag-extended
// modifiers ignored // modifiers ignored