aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquicktableview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items/qquicktableview.cpp')
-rw-r--r--src/quick/items/qquicktableview.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index db5da6f886..7e1a6809d4 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -20,6 +20,10 @@
#include <QtQuick/private/qquickitemviewfxitem_p_p.h>
#include <QtQuick/private/qquicktaphandler_p.h>
+#if QT_CONFIG(accessibility)
+#include <QtGui/qaccessible.h>
+#endif
+
#include <QtCore/qtyperevision.h>
/*!
@@ -3023,6 +3027,12 @@ void QQuickTableViewPrivate::releaseItem(FxTableItem *fxTableItem, QQmlTableInst
// the item is owned by the QML context rather than the model (e.g ObjectModel etc).
auto item = fxTableItem->item;
+#if QT_CONFIG(accessibility)
+ // A released item can come back for another cell, which needs a new focus event.
+ if (item == accessibleFocusItem)
+ accessibleFocusItem = nullptr;
+#endif
+
if (fxTableItem->ownItem) {
Q_TABLEVIEW_ASSERT(item, fxTableItem->index);
delete item;
@@ -3670,6 +3680,9 @@ void QQuickTableViewPrivate::processLoadRequest()
syncLoadedTableFromLoadRequest();
layoutTableEdgeFromLoadRequest();
syncLoadedTableRectFromLoadedTable();
+#if QT_CONFIG(accessibility)
+ updateAccessibleFocus();
+#endif
if (rebuildState == RebuildState::Done) {
// Loading of this edge was not done as a part of a rebuild, but
@@ -4614,6 +4627,9 @@ void QQuickTableViewPrivate::currentChangedInSelectionModel(const QModelIndex &c
updateCurrentRowAndColumn();
setCurrentOnDelegateItem(previous, false);
setCurrentOnDelegateItem(current, true);
+#if QT_CONFIG(accessibility)
+ updateAccessibleFocus();
+#endif
}
void QQuickTableViewPrivate::updateCurrentRowAndColumn()
@@ -4644,6 +4660,31 @@ void QQuickTableViewPrivate::setCurrentOnDelegateItem(const QModelIndex &index,
setRequiredProperty(kRequiredProperty_current, QVariant::fromValue(isCurrent), cellIndex, item, false);
}
+#if QT_CONFIG(accessibility)
+// Like the widget item views, send a focus event for the current item while the
+// view has focus. TableView is no accessible item itself, so without the event
+// assistive technology does not follow the current cell. The delegate of the
+// current cell can load after the current index changed, for instance when Tab
+// scrolls it into view.
+void QQuickTableViewPrivate::updateAccessibleFocus()
+{
+ Q_Q(QQuickTableView);
+ QQuickItem *item = nullptr;
+ if (QAccessible::isActive() && q->hasActiveFocus() && selectionModel) {
+ const int cellIndex = modelIndexToCellIndex(selectionModel->currentIndex());
+ if (loadedItems.contains(cellIndex))
+ item = loadedTableItem(cellAtModelIndex(cellIndex))->item;
+ }
+ if (item == accessibleFocusItem)
+ return;
+ accessibleFocusItem = item;
+ if (item && QQuickItemPrivate::get(item)->isAccessible) {
+ QAccessibleEvent event(item, QAccessible::Focus);
+ QAccessible::updateAccessibility(&event);
+ }
+}
+#endif
+
void QQuickTableViewPrivate::itemCreatedCallback(int modelIndex, QObject*)
{
if (blockItemCreatedCallback)
@@ -5337,6 +5378,9 @@ void QQuickTableViewPrivate::init()
q->setFlag(QQuickItem::ItemIsFocusScope);
q->setActiveFocusOnTab(true);
+#if QT_CONFIG(accessibility)
+ QObject::connect(q, &QQuickItem::activeFocusChanged, q, [this] { updateAccessibleFocus(); });
+#endif
positionXAnimation.setTargetObject(q);
positionXAnimation.setProperty(QStringLiteral("contentX"));
@@ -7231,6 +7275,11 @@ void QQuickTableView::closeEditor()
// have an editItem, if the model has changed (e.g been reset)!
d->editIndex = QModelIndex();
}
+#if QT_CONFIG(accessibility)
+ // Focus goes back to the view, which is no accessible item, so announce the current cell again.
+ d->accessibleFocusItem = nullptr;
+ d->updateAccessibleFocus();
+#endif
}
QQuickTableViewAttached *QQuickTableView::qmlAttachedProperties(QObject *obj)