diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 88b6a30409..9870d9d49a 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -2230,7 +2230,7 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event) QAbstractScrollArea::focusInEvent(event); const QItemSelectionModel* model = selectionModel(); - const bool currentIndexValid = currentIndex().isValid(); + bool currentIndexValid = currentIndex().isValid(); if (model && !d->currentIndexSet @@ -2238,19 +2238,16 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event) bool autoScroll = d->autoScroll; d->autoScroll = false; QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index - if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason) + if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason) { selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate); + currentIndexValid = true; + } d->autoScroll = autoScroll; } - if (model && currentIndexValid) { - if (currentIndex().flags() != Qt::ItemIsEditable) - setAttribute(Qt::WA_InputMethodEnabled, false); - else - setAttribute(Qt::WA_InputMethodEnabled); - } - - if (!currentIndexValid) + if (model && currentIndexValid) + setAttribute(Qt::WA_InputMethodEnabled, (currentIndex().flags() & Qt::ItemIsEditable)); + else if (!currentIndexValid) setAttribute(Qt::WA_InputMethodEnabled, false); d->viewport->update(); @@ -3652,6 +3649,7 @@ void QAbstractItemView::currentChanged(const QModelIndex ¤t, const QModelI d->shouldScrollToCurrentOnShow = d->autoScroll; } } + setAttribute(Qt::WA_InputMethodEnabled, (current.isValid() && (current.flags() & Qt::ItemIsEditable))); } #ifndef QT_NO_DRAGANDDROP diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 83912fa2c3..2234b2b488 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -55,6 +55,8 @@ #include #include +Q_DECLARE_METATYPE(Qt::ItemFlags); + static inline void setFrameless(QWidget *w) { Qt::WindowFlags flags = w->windowFlags(); @@ -154,6 +156,8 @@ private slots: void testDialogAsEditor(); void QTBUG46785_mouseout_hover_state(); void testClearModelInClickedSignal(); + void inputMethodEnabled_data(); + void inputMethodEnabled(); }; class MyAbstractItemDelegate : public QAbstractItemDelegate @@ -2291,5 +2295,107 @@ void tst_QAbstractItemView::testClearModelInClickedSignal() QCOMPARE(view.model(), nullptr); } +void tst_QAbstractItemView::inputMethodEnabled_data() +{ + QTest::addColumn("viewType"); + QTest::addColumn("itemFlags"); + QTest::addColumn("result"); + + QList widgets; + widgets << "QListView" << "QTreeView" << "QTableView"; + + for (const QByteArray &widget : qAsConst(widgets)) { + QTest::newRow(widget + ": no flags") << widget << Qt::ItemFlags(Qt::NoItemFlags) << false; + QTest::newRow(widget + ": checkable") << widget << Qt::ItemFlags(Qt::ItemIsUserCheckable) << false; + QTest::newRow(widget + ": selectable") << widget << Qt::ItemFlags(Qt::ItemIsSelectable) << false; + QTest::newRow(widget + ": enabled") << widget << Qt::ItemFlags(Qt::ItemIsEnabled) << false; + QTest::newRow(widget + ": selectable|enabled") + << widget << Qt::ItemFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled) << false; + QTest::newRow(widget + ": editable|enabled") + << widget << Qt::ItemFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled) << true; + QTest::newRow(widget + ": editable|enabled|selectable") + << widget << Qt::ItemFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable) << true; + } +} + +void tst_QAbstractItemView::inputMethodEnabled() +{ + QFETCH(QByteArray, viewType); + QFETCH(Qt::ItemFlags, itemFlags); + QFETCH(bool, result); + + QScopedPointer view; + if (viewType == "QListView") + view.reset(new QListView()); + else if (viewType == "QTableView") + view.reset(new QTableView()); + else if (viewType == "QTreeView") + view.reset(new QTreeView()); + else + QVERIFY(0); + + centerOnScreen(view.data()); + view->show(); + QVERIFY(QTest::qWaitForWindowExposed(view.data())); + + QStandardItemModel *model = new QStandardItemModel(view.data()); + QStandardItem *item = new QStandardItem("first item"); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + model->appendRow(item); + + QStandardItem *secondItem = new QStandardItem("test item"); + secondItem->setFlags(Qt::ItemFlags(itemFlags)); + model->appendRow(secondItem); + + view->setModel(model); + + // Check current changed + view->setCurrentIndex(model->index(0, 0)); + QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled)); + view->setCurrentIndex(model->index(1, 0)); + QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result); + view->setCurrentIndex(model->index(0, 0)); + QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled)); + + // Check focus by switching the activation of the window to force a focus in + view->setCurrentIndex(model->index(1, 0)); + QApplication::setActiveWindow(0); + QApplication::setActiveWindow(view.data()); + QVERIFY(QTest::qWaitForWindowActive(view.data())); + QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result); + + view->setCurrentIndex(QModelIndex()); + QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled)); + QApplication::setActiveWindow(0); + QApplication::setActiveWindow(view.data()); + QVERIFY(QTest::qWaitForWindowActive(view.data())); + QModelIndex index = model->index(1, 0); + QPoint p = view->visualRect(index).center(); + QTest::mouseClick(view->viewport(), Qt::LeftButton, Qt::NoModifier, p); + if (itemFlags & Qt::ItemIsEnabled) + QCOMPARE(view->currentIndex(), index); + QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result); + + index = model->index(0, 0); + QApplication::setActiveWindow(0); + QApplication::setActiveWindow(view.data()); + QVERIFY(QTest::qWaitForWindowActive(view.data())); + p = view->visualRect(index).center(); + QTest::mouseClick(view->viewport(), Qt::LeftButton, Qt::NoModifier, p); + QCOMPARE(view->currentIndex(), index); + QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled)); + + // There is a case when it goes to the first visible item so we + // make the flags of the first item match the ones we are testing + // to check the attribute correctly + QApplication::setActiveWindow(0); + view->setCurrentIndex(QModelIndex()); + view->reset(); + item->setFlags(Qt::ItemFlags(itemFlags)); + QApplication::setActiveWindow(view.data()); + QVERIFY(QTest::qWaitForWindowActive(view.data())); + QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result); +} + QTEST_MAIN(tst_QAbstractItemView) #include "tst_qabstractitemview.moc"