7#include <qaccessible.h>
8#include <qapplication.h>
10#if QT_CONFIG(itemviews)
11#include <qheaderview.h>
15#include <private/qtabbar_p.h>
17#if QT_CONFIG(combobox)
20#if QT_CONFIG(lineedit)
24#include <qstyleoption.h>
28#if QT_CONFIG(whatsthis)
29#include <qwhatsthis.h>
31#include <QAbstractScrollArea>
32#if QT_CONFIG(scrollarea)
35#if QT_CONFIG(scrollbar)
40#if QT_CONFIG(accessibility)
42#include <QtGui/private/qaccessiblehelper_p.h>
46using namespace Qt::StringLiterals;
48QString qt_accHotKey(
const QString &text);
52
53
54
55
56
57
59class QAccessibleTabButton:
public QAccessibleInterface,
public QAccessibleActionInterface
62 QAccessibleTabButton(QTabBar *parent,
int index)
63 : m_parent(parent), m_index(index)
66 void *interface_cast(QAccessible::InterfaceType t) override {
67 if (t == QAccessible::ActionInterface) {
68 return static_cast<QAccessibleActionInterface*>(
this);
73 QObject *object()
const override {
return nullptr; }
74 QAccessible::Role role()
const override {
return QAccessible::PageTab; }
75 QAccessible::State state()
const override {
82 QAccessible::State s = parent()->state();
84 s.focused = (m_index == m_parent->currentIndex());
85 s.selected = s.focused;
88 QRect rect()
const override {
92 QPoint tp = m_parent->mapToGlobal(QPoint(0,0));
93 QRect rec = m_parent->tabRect(m_index);
94 rec = QRect(tp.x() + rec.x(), tp.y() + rec.y(), rec.width(), rec.height());
98 bool isValid()
const override {
100 if (
static_cast<QWidget *>(m_parent.data())->d_func()->data.in_destructor)
102 return m_parent->count() > m_index;
107 QAccessibleInterface *childAt(
int,
int)
const override {
return nullptr; }
108 int childCount()
const override {
return 0; }
109 int indexOfChild(
const QAccessibleInterface *)
const override {
return -1; }
111 QString text(QAccessible::Text t)
const override
117 case QAccessible::Name:
118 str = m_parent->accessibleTabName(m_index);
120 str = qt_accStripAmp(m_parent->tabText(m_index));
122 case QAccessible::Accelerator:
123 str = qt_accHotKey(m_parent->tabText(m_index));
125#if QT_CONFIG(tooltip)
126 case QAccessible::Description:
127 str = m_parent->tabToolTip(m_index);
130#if QT_CONFIG(whatsthis)
131 case QAccessible::Help:
132 str = m_parent->tabWhatsThis(m_index);
141 void setText(QAccessible::Text,
const QString &) override {}
143 QAccessibleInterface *parent()
const override {
144 return QAccessible::queryAccessibleInterface(m_parent.data());
146 QAccessibleInterface *child(
int)
const override {
return nullptr; }
149 QStringList actionNames()
const override
151 return QStringList(pressAction());
154 void doAction(
const QString &actionName) override
156 if (isValid() && actionName == pressAction())
157 m_parent->setCurrentIndex(m_index);
160 QStringList keyBindingsForAction(
const QString &)
const override
162 return QStringList();
165 int index()
const {
return m_index; }
168 QPointer<QTabBar> m_parent;
174
175
176QAccessibleTabBar::QAccessibleTabBar(QWidget *w)
177: QAccessibleWidgetV2(w, QAccessible::PageTabList)
182QAccessibleTabBar::~QAccessibleTabBar()
184 for (QAccessible::Id id : std::as_const(m_childInterfaces))
185 QAccessible::deleteAccessibleInterface(id);
188void *QAccessibleTabBar::interface_cast(QAccessible::InterfaceType t)
190 if (t == QAccessible::SelectionInterface) {
191 return static_cast<QAccessibleSelectionInterface*>(
this);
193 return QAccessibleWidgetV2::interface_cast(t);
197QTabBar *QAccessibleTabBar::tabBar()
const
199 return qobject_cast<QTabBar*>(object());
202QAccessibleInterface* QAccessibleTabBar::focusChild()
const
204 for (
int i = 0; i < childCount(); ++i) {
205 if (child(i)->state().focused)
212QAccessibleInterface* QAccessibleTabBar::child(
int index)
const
214 if (QAccessible::Id id = m_childInterfaces.value(index))
215 return QAccessible::accessibleInterface(id);
218 if (index < tabBar()->count()) {
219 QAccessibleTabButton *button =
new QAccessibleTabButton(tabBar(), index);
220 QAccessible::registerAccessibleInterface(button);
221 m_childInterfaces.insert(index, QAccessible::uniqueId(button));
223 }
else if (index >= tabBar()->count()) {
225 if (index - tabBar()->count() == 0) {
226 return QAccessible::queryAccessibleInterface(tabBar()->d_func()->leftB);
229 if (index - tabBar()->count() == 1) {
230 return QAccessible::queryAccessibleInterface(tabBar()->d_func()->rightB);
236int QAccessibleTabBar::indexOfChild(
const QAccessibleInterface *child)
const
238 if (child->object() && child->object() == tabBar()->d_func()->leftB)
239 return tabBar()->count();
240 if (child->object() && child->object() == tabBar()->d_func()->rightB)
241 return tabBar()->count() + 1;
242 if (child->role() == QAccessible::PageTab) {
243 QAccessibleInterface *parent = child->parent();
244 if (parent ==
this) {
245 const QAccessibleTabButton *tabButton =
static_cast<
const QAccessibleTabButton *>(child);
246 return tabButton->index();
252int QAccessibleTabBar::childCount()
const
255 return tabBar()->count() + 2;
258QString QAccessibleTabBar::text(QAccessible::Text t)
const
260 if (t == QAccessible::Name) {
261 const QTabBar *tBar = tabBar();
262 int idx = tBar->currentIndex();
263 QString str = tBar->accessibleTabName(idx);
265 str = qt_accStripAmp(tBar->tabText(idx));
267 }
else if (t == QAccessible::Accelerator) {
268 return qt_accHotKey(tabBar()->tabText(tabBar()->currentIndex()));
273int QAccessibleTabBar::selectedItemCount()
const
275 if (tabBar()->currentIndex() >= 0)
280QList<QAccessibleInterface*> QAccessibleTabBar::selectedItems()
const
282 QList<QAccessibleInterface*> items;
283 QAccessibleInterface *selected = selectedItem(0);
285 items.push_back(selected);
289QAccessibleInterface* QAccessibleTabBar::selectedItem(
int selectionIndex)
const
291 const int currentIndex = tabBar()->currentIndex();
292 if (selectionIndex != 0 || currentIndex < 0)
294 return child(currentIndex);
297bool QAccessibleTabBar::isSelected(QAccessibleInterface *childItem)
const
299 return childItem && selectedItem(0) == childItem;
302bool QAccessibleTabBar::select(QAccessibleInterface *childItem)
304 const int childIndex = indexOfChild(childItem);
305 if (childIndex >= 0) {
306 tabBar()->setCurrentIndex(childIndex);
312bool QAccessibleTabBar::unselect(QAccessibleInterface *)
317bool QAccessibleTabBar::selectAll()
322bool QAccessibleTabBar::clear()
329#if QT_CONFIG(combobox)
331
332
333
334
335
336
339
340
341QAccessibleComboBox::QAccessibleComboBox(QWidget *w)
342: QAccessibleWidgetV2(w, QAccessible::ComboBox)
344 Q_ASSERT(comboBox());
348
349
350QComboBox *QAccessibleComboBox::comboBox()
const
352 return qobject_cast<QComboBox *>(object());
355QAccessibleInterface *QAccessibleComboBox::child(
int index)
const
357 if (QComboBox *cBox = comboBox()) {
359 QAbstractItemView *view = cBox->view();
361 return QAccessible::queryAccessibleInterface(view);
362 }
else if (index == 1 && cBox->isEditable()) {
363 return QAccessible::queryAccessibleInterface(cBox->lineEdit());
369int QAccessibleComboBox::childCount()
const
372 if (QComboBox *cBox = comboBox())
373 return (cBox->isEditable()) ? 2 : 1;
377QAccessibleInterface *QAccessibleComboBox::childAt(
int x,
int y)
const
379 if (QComboBox *cBox = comboBox()) {
380 if (cBox->isEditable() && cBox->lineEdit()->rect().contains(x, y))
386int QAccessibleComboBox::indexOfChild(
const QAccessibleInterface *child)
const
388 if (QComboBox *cBox = comboBox()) {
389 if (cBox->view() == child->object())
391 if (cBox->isEditable() && cBox->lineEdit() == child->object())
397QAccessibleInterface *QAccessibleComboBox::focusChild()
const
402 if (QComboBox *cBox = comboBox()) {
403 if (cBox->isEditable())
410QString QAccessibleComboBox::text(QAccessible::Text t)
const
413 if (QComboBox *cBox = comboBox()) {
415 case QAccessible::Name:
417 str = QAccessibleWidgetV2::text(t);
420 case QAccessible::Value:
421 if (cBox->isEditable())
422 str = cBox->lineEdit()->text();
424 str = cBox->currentText();
426#ifndef QT_NO_SHORTCUT
427 case QAccessible::Accelerator:
428 str = QKeySequence(Qt::Key_Down).toString(QKeySequence::NativeText);
435 str = QAccessibleWidgetV2::text(t);
440QAccessible::State QAccessibleComboBox::state()
const
442 QAccessible::State s = QAccessibleWidgetV2::state();
444 if (QComboBox *cBox = comboBox()) {
446 s.expanded = isValid() && cBox->view() && cBox->view()->isVisible();
447 s.editable = cBox->isEditable();
452QStringList QAccessibleComboBox::actionNames()
const
454 return QStringList() << showMenuAction() << pressAction();
457QString QAccessibleComboBox::localizedActionDescription(
const QString &actionName)
const
459 if (actionName == showMenuAction() || actionName == pressAction())
460 return QComboBox::tr(
"Open the combo box selection popup");
464void QAccessibleComboBox::doAction(
const QString &actionName)
466 if (QComboBox *cBox = comboBox()) {
467 if (actionName == showMenuAction() || actionName == pressAction()) {
468 if (cBox->view()->isVisible()) {
469#if defined(Q_OS_ANDROID)
470 const auto list = child(0)->tableInterface();
471 if (list && list->selectedRowCount() > 0) {
472 cBox->setCurrentIndex(list->selectedRows().at(0));
479#if defined(Q_OS_ANDROID)
480 const auto list = child(0)->tableInterface();
481 if (list && list->selectedRowCount() > 0) {
482 auto selectedCells = list->selectedCells();
483 QAccessibleEvent ev(selectedCells.at(0),QAccessible::Focus);
484 QAccessible::updateAccessibility(&ev);
492QStringList QAccessibleComboBox::keyBindingsForAction(
const QString &)
const
494 return QStringList();
499#if QT_CONFIG(scrollarea)
501QAccessibleAbstractScrollArea::QAccessibleAbstractScrollArea(QWidget *widget)
502 : QAccessibleWidgetV2(widget, QAccessible::Client)
504 Q_ASSERT(qobject_cast<QAbstractScrollArea *>(widget));
507QAccessibleInterface *QAccessibleAbstractScrollArea::child(
int index)
const
509 return QAccessible::queryAccessibleInterface(accessibleChildren().at(index));
512int QAccessibleAbstractScrollArea::childCount()
const
514 return accessibleChildren().size();
517int QAccessibleAbstractScrollArea::indexOfChild(
const QAccessibleInterface *child)
const
519 if (!child || !child->object())
521 return accessibleChildren().indexOf(qobject_cast<QWidget *>(child->object()));
524bool QAccessibleAbstractScrollArea::isValid()
const
526 return (QAccessibleWidgetV2::isValid() && abstractScrollArea() && abstractScrollArea()->viewport());
529QAccessibleInterface *QAccessibleAbstractScrollArea::childAt(
int x,
int y)
const
531 if (!abstractScrollArea()->isVisible())
534 for (
int i = 0; i < childCount(); ++i) {
535 QPoint wpos = accessibleChildren().at(i)->mapToGlobal(QPoint(0, 0));
536 QRect rect = QRect(wpos, accessibleChildren().at(i)->size());
537 if (rect.contains(x, y))
543QAbstractScrollArea *QAccessibleAbstractScrollArea::abstractScrollArea()
const
545 return static_cast<QAbstractScrollArea *>(object());
548QWidgetList QAccessibleAbstractScrollArea::accessibleChildren()
const
550 QWidgetList children;
553 QWidget * viewport = abstractScrollArea()->viewport();
555 children.append(viewport);
558 QScrollBar *horizontalScrollBar = abstractScrollArea()->horizontalScrollBar();
559 if (horizontalScrollBar && horizontalScrollBar->isVisible()) {
560 QWidget *scrollBarParent = horizontalScrollBar->parentWidget();
562 if (elementType(scrollBarParent) == HorizontalContainer)
563 children.append(scrollBarParent);
567 QScrollBar *verticalScrollBar = abstractScrollArea()->verticalScrollBar();
568 if (verticalScrollBar && verticalScrollBar->isVisible()) {
569 QWidget *scrollBarParent = verticalScrollBar->parentWidget();
571 if (elementType(scrollBarParent) == VerticalContainer)
572 children.append(scrollBarParent);
576 QWidget *cornerWidget = abstractScrollArea()->cornerWidget();
577 if (cornerWidget && cornerWidget->isVisible())
578 children.append(cornerWidget);
583QAccessibleAbstractScrollArea::AbstractScrollAreaElement
584QAccessibleAbstractScrollArea::elementType(QWidget *widget)
const
589 if (widget == abstractScrollArea())
591 if (widget == abstractScrollArea()->viewport())
593 if (widget->objectName() ==
"qt_scrollarea_hcontainer"_L1)
594 return HorizontalContainer;
595 if (widget->objectName() ==
"qt_scrollarea_vcontainer"_L1)
596 return VerticalContainer;
597 if (widget == abstractScrollArea()->cornerWidget())
603bool QAccessibleAbstractScrollArea::isLeftToRight()
const
605 return abstractScrollArea()->isLeftToRight();
609QAccessibleScrollArea::QAccessibleScrollArea(QWidget *widget)
610 : QAccessibleAbstractScrollArea(widget)
612 Q_ASSERT(qobject_cast<QScrollArea *>(widget));