QAbstractItemView - allow deselect in single selection mode.

This patch allows single selection to be cleared with the normal
control modifier. This affects e.g QTreeView and QListView.

Task-number: QTBUG-8836
Change-Id: I7fd50b987acc3552b36657409568192763257536
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
This commit is contained in:
Thorbjørn Lund Martsum 2012-11-04 18:17:14 +01:00 committed by The Qt Project
parent 0f014fcde8
commit 28a21d98ef
4 changed files with 68 additions and 1 deletions

3
dist/changes-5.1.0 vendored
View File

@ -34,7 +34,10 @@ Third party components
* Important Behavior Changes *
****************************************************************************
- QtWidgets
* [QTBUG-8836] QAbstractItemView now allows manual deselect in
SingleSelection mode (with control modifier)
****************************************************************************
* Library *

View File

@ -3816,13 +3816,31 @@ QItemSelectionModel::SelectionFlags QAbstractItemView::selectionCommand(const QM
const QEvent *event) const
{
Q_D(const QAbstractItemView);
Qt::KeyboardModifiers keyModifiers = Qt::NoModifier;
if (event) {
switch (event->type()) {
case QEvent::MouseButtonDblClick:
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseMove:
case QEvent::KeyPress:
case QEvent::KeyRelease:
keyModifiers = (static_cast<const QInputEvent*>(event))->modifiers();
break;
default:
keyModifiers = QApplication::keyboardModifiers();
}
}
switch (d->selectionMode) {
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;
return QItemSelectionModel::ClearAndSelect|d->selectionBehaviorFlags();
if ((keyModifiers & Qt::ControlModifier) && d->selectionModel->isSelected(index))
return QItemSelectionModel::Deselect | d->selectionBehaviorFlags();
else
return QItemSelectionModel::ClearAndSelect | d->selectionBehaviorFlags();
case MultiSelection:
return d->multiSelectionCommand(index, event);
case ExtendedSelection:

View File

@ -227,6 +227,7 @@ private slots:
void testDelegateDestroyEditor();
void testClickedSignal();
void testChangeEditorState();
void deselectInSingleSelection();
};
class MyAbstractItemDelegate : public QAbstractItemDelegate
@ -1591,5 +1592,47 @@ void tst_QAbstractItemView::testChangeEditorState()
// No segfault - the test passes.
}
void tst_QAbstractItemView::deselectInSingleSelection()
{
QTableView view;
QStandardItemModel s;
s.setRowCount(10);
s.setColumnCount(10);
view.setModel(&s);
view.show();
view.setSelectionMode(QAbstractItemView::SingleSelection);
view.setEditTriggers(QAbstractItemView::NoEditTriggers);
QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowExposed(&view));
// mouse
QModelIndex index22 = s.index(2, 2);
QRect rect22 = view.visualRect(index22);
QPoint clickpos = rect22.center();
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, clickpos);
QCOMPARE(view.currentIndex(), index22);
QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, clickpos);
QCOMPARE(view.currentIndex(), index22);
QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0);
// second click with modifier however does select
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, clickpos);
QCOMPARE(view.currentIndex(), index22);
QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
// keyboard
QTest::keyClick(&view, Qt::Key_Space, Qt::NoModifier);
QCOMPARE(view.currentIndex(), index22);
QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
QTest::keyClick(&view, Qt::Key_Space, Qt::ControlModifier);
QCOMPARE(view.currentIndex(), index22);
QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0);
// second keypress with modifier however does select
QTest::keyClick(&view, Qt::Key_Space, Qt::ControlModifier);
QCOMPARE(view.currentIndex(), index22);
QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
}
QTEST_MAIN(tst_QAbstractItemView)
#include "tst_qabstractitemview.moc"

View File

@ -99,6 +99,9 @@ int main(int argc, char *argv[])
m.setRowCount(500);
m.setColumnCount(250);
tv.setModel(&m);
tv.setSelectionMode(QAbstractItemView::SingleSelection);
// Comment in the line below to test selection with keyboard (space)
// tv.setEditTriggers(QAbstractItemView::NoEditTriggers);
SomeHandler handler(tv.horizontalHeader(), &tv);
tv.horizontalHeader()->setDefaultSectionSize(30);
tv.show();