a11y: Implement QAccessibleSelectionInterface for QAccessibleTabBar
So far, there was custom handling for exposing the selection of tab bars on Windows via UIA, s. QWindowsUiaSelectionProvider. Implement QAccessibleSelectionInterface for QAccessibleTabBar, so selection is exposed via the platform a11y bridge on all platforms. (This makes the custom handling for tab bars in QWindowsUiaSelectionProvider obsolete for qtbase's own classes, but there are 4 more uses of the QAccessible::PageTabList role in qtdeclarative that might need a closer look before dropping the custom handling from QWindowsUiaSelectionProvider.) For consistency, also set the selectable/selected state for the tab buttons (that are the selectable children of the tab bar). Sample use via AT-SPI on Linux using Accerciser to interact on the a11y level (check the current selection, then select the second tab): 1) run the qtabbar example (tests/manual/qtabbar) 2) start Accerciser 3) select the tab bar in Accerciser's tree view of the a11y hierarchy 4) query for currently selected item, switch selection from "Tab 0" to "Tab 1" by using the following commands in Accerciser's IPython console: In [10]: sel = acc.querySelection() In [11]: sel.nSelectedChildren Out[11]: 1 In [12]: sel.getSelectedChild(0) Out[12]: <Atspi.Accessible object at 0x7fe01ce8a240 (AtspiAccessible at 0x43928c0)> In [13]: sel.getSelectedChild(0).name Out[13]: 'Tab 0' In [14]: sel.selectChild(1) Out[14]: True In [15]: sel.getSelectedChild(0).name Out[15]: 'Tab 1' Equivalent on Windows using NVDA's Python console: 1) start NVDA 2) run the qtabbar example (tests/manual/qtabbar) 3) click on the first tab ("Tab 0") in the tab bar 4) press Numpad_insert+control+z to start the NVDA Python console and capture snapshot variables 5) query and use the interfaces using NVDA's Python console: >>> import UIAHandler >>> tabbar = focus.parent >>> selectionpattern2 = tabbar.UIAElement.GetCurrentPattern(10034).QueryInterface(UIAHandler.IUIAutomationSelectionPattern2) >>> selectionpattern2.CurrentFirstSelectedItem.CurrentName 'Tab 0' >>> selectionpattern2.CurrentLastSelectedItem.CurrentName 'Tab 0' >>> selectionpattern2.CurrentItemCount 1 >>> selectionitempattern = tabbar.children[1].UIAElement.GetCurrentPattern(10010).QueryInterface(UIAHandler.IUIAutomationSelectionItemPattern) >>> selectionitempattern.Select() 0 >>> selectionpattern2.CurrentFirstSelectedItem.CurrentName 'Tab 1' Fixes: QTBUG-104602 Change-Id: I49b05bb84852c86a2b8669d7843fe173caf28e18 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
This commit is contained in:
parent
b0bcf47569
commit
3d58715e6f
@ -78,7 +78,9 @@ public:
|
||||
}
|
||||
|
||||
QAccessible::State s = parent()->state();
|
||||
s.selectable = true;
|
||||
s.focused = (m_index == m_parent->currentIndex());
|
||||
s.selected = s.focused;
|
||||
return s;
|
||||
}
|
||||
QRect rect() const override {
|
||||
@ -181,6 +183,14 @@ QAccessibleTabBar::~QAccessibleTabBar()
|
||||
QAccessible::deleteAccessibleInterface(id);
|
||||
}
|
||||
|
||||
void *QAccessibleTabBar::interface_cast(QAccessible::InterfaceType t)
|
||||
{
|
||||
if (t == QAccessible::SelectionInterface) {
|
||||
return static_cast<QAccessibleSelectionInterface*>(this);
|
||||
}
|
||||
return QAccessibleWidget::interface_cast(t);
|
||||
}
|
||||
|
||||
/*! Returns the QTabBar. */
|
||||
QTabBar *QAccessibleTabBar::tabBar() const
|
||||
{
|
||||
@ -258,6 +268,60 @@ QString QAccessibleTabBar::text(QAccessible::Text t) const
|
||||
return QString();
|
||||
}
|
||||
|
||||
int QAccessibleTabBar::selectedItemCount() const
|
||||
{
|
||||
if (tabBar()->currentIndex() >= 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
QList<QAccessibleInterface*> QAccessibleTabBar::selectedItems() const
|
||||
{
|
||||
QList<QAccessibleInterface*> items;
|
||||
QAccessibleInterface *selected = selectedItem(0);
|
||||
if (selected)
|
||||
items.push_back(selected);
|
||||
return items;
|
||||
}
|
||||
|
||||
QAccessibleInterface* QAccessibleTabBar::selectedItem(int selectionIndex) const
|
||||
{
|
||||
const int currentIndex = tabBar()->currentIndex();
|
||||
if (selectionIndex != 0 || currentIndex < 0)
|
||||
return nullptr;
|
||||
return child(currentIndex);
|
||||
}
|
||||
|
||||
bool QAccessibleTabBar::isSelected(QAccessibleInterface *childItem) const
|
||||
{
|
||||
return childItem && selectedItem(0) == childItem;
|
||||
}
|
||||
|
||||
bool QAccessibleTabBar::select(QAccessibleInterface *childItem)
|
||||
{
|
||||
const int childIndex = indexOfChild(childItem);
|
||||
if (childIndex >= 0) {
|
||||
tabBar()->setCurrentIndex(childIndex);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QAccessibleTabBar::unselect(QAccessibleInterface *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QAccessibleTabBar::selectAll()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QAccessibleTabBar::clear()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // QT_CONFIG(tabbar)
|
||||
|
||||
#if QT_CONFIG(combobox)
|
||||
|
@ -70,12 +70,14 @@ public:
|
||||
#endif // QT_CONFIG(scrollarea)
|
||||
|
||||
#if QT_CONFIG(tabbar)
|
||||
class QAccessibleTabBar : public QAccessibleWidget
|
||||
class QAccessibleTabBar : public QAccessibleWidget, public QAccessibleSelectionInterface
|
||||
{
|
||||
public:
|
||||
explicit QAccessibleTabBar(QWidget *w);
|
||||
~QAccessibleTabBar();
|
||||
|
||||
void *interface_cast(QAccessible::InterfaceType t) override;
|
||||
|
||||
QAccessibleInterface *focusChild() const override;
|
||||
int childCount() const override;
|
||||
QString text(QAccessible::Text t) const override;
|
||||
@ -83,6 +85,16 @@ public:
|
||||
QAccessibleInterface* child(int index) const override;
|
||||
int indexOfChild(const QAccessibleInterface *child) const override;
|
||||
|
||||
// QAccessibleSelectionInterface
|
||||
int selectedItemCount() const override;
|
||||
QList<QAccessibleInterface*> selectedItems() const override;
|
||||
QAccessibleInterface* selectedItem(int selectionIndex) const override;
|
||||
bool isSelected(QAccessibleInterface *childItem) const override;
|
||||
bool select(QAccessibleInterface *childItem) override;
|
||||
bool unselect(QAccessibleInterface *childItem) override;
|
||||
bool selectAll() override;
|
||||
bool clear() override;
|
||||
|
||||
protected:
|
||||
QTabBar *tabBar() const;
|
||||
mutable QHash<int, QAccessible::Id> m_childInterfaces;
|
||||
|
Loading…
x
Reference in New Issue
Block a user