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
parent
6f9c5c85ca
commit
efec288f58
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue