itemviews: When an index widget gets focus, update the current index

By ensuring that the current index follows the focus of an index widget,
we can ensure that moving the cursor will happen in the way that is
expected from the focused widget.

Task-number: QTBUG-27793
Change-Id: Ia36891a94ce41c7d12fba678de23a6f3b69374ae
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
bb10
Andy Shaw 2018-01-17 13:53:19 +01:00
parent 6f9c5c85ca
commit efec288f58
3 changed files with 74 additions and 0 deletions

View File

@ -3217,12 +3217,14 @@ void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget
if (QWidget *oldWidget = indexWidget(index)) {
d->persistent.remove(oldWidget);
d->removeEditor(oldWidget);
oldWidget->removeEventFilter(this);
oldWidget->deleteLater();
}
if (widget) {
widget->setParent(viewport());
d->persistent.insert(widget);
d->addEditor(index, widget, true);
widget->installEventFilter(this);
widget->show();
dataChanged(index, index); // update the geometry
if (!d->delayedPendingLayout)
@ -4499,6 +4501,24 @@ QModelIndexList QAbstractItemViewPrivate::selectedDraggableIndexes() const
return indexes;
}
/*!
\reimp
*/
bool QAbstractItemView::eventFilter(QObject *object, QEvent *event)
{
Q_D(QAbstractItemView);
if (object == this || object == viewport() || event->type() != QEvent::FocusIn)
return QAbstractScrollArea::eventFilter(object, event);
QWidget *widget = qobject_cast<QWidget *>(object);
// If it is not a persistent widget then we did not install
// the event filter on it, so assume a base implementation is
// filtering
if (!widget || !d->persistent.contains(widget))
return QAbstractScrollArea::eventFilter(object, event);
setCurrentIndex(d->indexForEditor(widget));
return false;
}
QT_END_NAMESPACE

View File

@ -346,6 +346,7 @@ protected:
void resizeEvent(QResizeEvent *event) override;
void timerEvent(QTimerEvent *event) override;
void inputMethodEvent(QInputMethodEvent *event) override;
bool eventFilter(QObject *object, QEvent *event) override;
#ifndef QT_NO_DRAGANDDROP
enum DropIndicatorPosition { OnItem, AboveItem, BelowItem, OnViewport };

View File

@ -147,6 +147,8 @@ private slots:
void testClearModelInClickedSignal();
void inputMethodEnabled_data();
void inputMethodEnabled();
void currentFollowsIndexWidget_data();
void currentFollowsIndexWidget();
};
class MyAbstractItemDelegate : public QAbstractItemDelegate
@ -2390,5 +2392,56 @@ void tst_QAbstractItemView::inputMethodEnabled()
QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
}
void tst_QAbstractItemView::currentFollowsIndexWidget_data()
{
QTest::addColumn<QByteArray>("viewType");
QList<QByteArray> widgets;
widgets << "QListView" << "QTreeView" << "QTableView";
for (const QByteArray &widget : qAsConst(widgets))
QTest::newRow(widget) << widget;
}
void tst_QAbstractItemView::currentFollowsIndexWidget()
{
QFETCH(QByteArray, viewType);
QScopedPointer<QAbstractItemView> 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 *item1 = new QStandardItem("first item");
item1->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
model->appendRow(item1);
QStandardItem *item2 = new QStandardItem("test item");
item2->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
model->appendRow(item2);
view->setModel(model);
QLineEdit *lineEdit1 = new QLineEdit;
QLineEdit *lineEdit2 = new QLineEdit;
view->setIndexWidget(item1->index(), lineEdit1);
view->setIndexWidget(item2->index(), lineEdit2);
lineEdit2->setFocus();
QTRY_VERIFY(lineEdit2->hasFocus());
QCOMPARE(view->currentIndex(), item2->index());
lineEdit1->setFocus();
QTRY_VERIFY(lineEdit1->hasFocus());
QCOMPARE(view->currentIndex(), item1->index());
}
QTEST_MAIN(tst_QAbstractItemView)
#include "tst_qabstractitemview.moc"