summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.1.03
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp20
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp43
-rw-r--r--tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp3
4 files changed, 68 insertions, 1 deletions
diff --git a/dist/changes-5.1.0 b/dist/changes-5.1.0
index 8dfd6a8849..2b432fc811 100644
--- a/dist/changes-5.1.0
+++ b/dist/changes-5.1.0
@@ -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 *
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 57c3b44aaa..ab98bf6438 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -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:
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
index b068413632..10a10a67ff 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
@@ -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"
diff --git a/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp b/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp
index 7a8c1d159d..b5aeb023f4 100644
--- a/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp
+++ b/tests/manual/widgets/itemviews/qheaderview/qheaderviewtest1.cpp
@@ -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();