summaryrefslogtreecommitdiff
path: root/vcl/qt5
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2023-04-22 09:22:38 +0300
committerMichael Weghorn <m.weghorn@posteo.de>2023-04-22 11:33:32 +0200
commit84183c84d86456e3c311b35150b1fc9b63a85561 (patch)
tree689f972dcc3ca4194fd31d5458f067849b2fbf8a /vcl/qt5
parentdabe502c362f528a529e14a90abcc79d95d393be (diff)
qt a11y: Implement QAccessibleSelectionInterface added in Qt 6.5
This adds an implementation of the `QAccessibleSelectionInterface` that was added in Qt 6.5 in commit [1] commit 9d16d5e2245c26e5746fd7609300b84a2a983457 Author: Michael Weghorn <m.weghorn@posteo.de> Date: Tue Oct 11 15:23:54 2022 +0200 a11y: Add new QAccessibleSelectionInterface , s.a. QTBUG-105909 [2]. The `QAccessibleSelectionInterface` is currently still marked as preliminary in Qt, so changes to the API *might* still happen and require an update of the implementation here as well). Quoting from the commit message of the above commit: > This interface is marked \preliminary until: > > 1. There is a working a11y bridge for macOS/VoiceOver > 2. There is a working a11y bridge for Windows/UI Automation > 3. There is a working a11y bridge for linux/AT-SPI > 4. There is at least one implementation (e.g. QAccessibleTable) > that implements it successfully (second candidate: > Qt Quick TableView [...]) The AT-SPI bridge (point 3 from above) has been implemented in [3] commit ece2feee0317b582a56a0bfc783f11fe67d3edee Author: Michael Weghorn <m.weghorn@posteo.de> Date: Tue Oct 11 15:24:04 2022 +0200 a11y atspi: Bridge newly introduced QAccessibleSelectionInterface , an implementation for `QAccessibleTable` (point 4 from above) was added in [4] commit 092bbc9ad30c6cd7389053dc4b332cc762693676 Author: Michael Weghorn <m.weghorn@posteo.de> Date: Wed Oct 12 07:07:48 2022 +0200 a11y: Implement QAccessibleSelectionInterface for item views . The Qt Gerrit changes for the macOS implementation (point 1 from above) and the Windows/UIA implementation (point 2 from above) are currently still awaiting review: [5] [6] To avoid duplication, just call the newly added methods `QtAccessibleWidget::selectedItemCount` and `QtAccessibleWidget::selectedItem` from the `QAccessibleTableInterface` methods `QtAccessibleWidget::selectedCellCount` and and `QtAccessibleWidget::selectedCells`, and therefore implement the former also for Qt < 6.5. Sample use of the interface from Accerciser's IPython console (with 18 cells selected in Calc and the spreadsheet object selected in Accerciser's a11y object tree; screencast attached to QTBUG-105909 [2]): In [10]: acc.get_interfaces() Out[10]: ['Accessible', 'Component', 'Selection', 'Table'] In [11]: sel = acc.querySelection() In [12]: sel.nSelectedChildren Out[12]: 18 In [13]: sel.getSelectedChild(0).name Out[13]: 'B1' In [14]: sel.deselectSelectedChild(1) Out[14]: True In [15]: sel.deselectChild(1) Out[15]: True In [16]: sel.selectChild(0) Out[16]: True In [17]: sel.clearSelection() Out[17]: True In [18]: sel.selectAll() Out[18]: True [1] https://code.qt.io/cgit/qt/qtbase.git/commit/?id=9d16d5e2245c26e5746fd7609300b84a2a983457 [2] https://bugreports.qt.io/browse/QTBUG-105909 [3] https://code.qt.io/cgit/qt/qtbase.git/commit/?id=ece2feee0317b582a56a0bfc783f11fe67d3edee [4] https://code.qt.io/cgit/qt/qtbase.git/commit/?id=092bbc9ad30c6cd7389053dc4b332cc762693676 [5] https://codereview.qt-project.org/c/qt/qtbase/+/451353 [6] https://codereview.qt-project.org/c/qt/qtbase/+/451646 Change-Id: Iac3c050448183610af3bd3b10a56e82d7d52cb91 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138750 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Diffstat (limited to 'vcl/qt5')
-rw-r--r--vcl/qt5/QtAccessibleWidget.cxx212
1 files changed, 164 insertions, 48 deletions
diff --git a/vcl/qt5/QtAccessibleWidget.cxx b/vcl/qt5/QtAccessibleWidget.cxx
index 237b2db64735..84b398c006cc 100644
--- a/vcl/qt5/QtAccessibleWidget.cxx
+++ b/vcl/qt5/QtAccessibleWidget.cxx
@@ -727,6 +727,10 @@ void* QtAccessibleWidget::interface_cast(QAccessible::InterfaceType t)
}
if (t == QAccessible::TableInterface && accessibleProvidesInterface<XAccessibleTable>())
return static_cast<QAccessibleTableInterface*>(this);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
+ if (t == QAccessible::SelectionInterface && accessibleProvidesInterface<XAccessibleSelection>())
+ return static_cast<QAccessibleSelectionInterface*>(this);
+#endif
return nullptr;
}
@@ -1631,55 +1635,9 @@ bool QtAccessibleWidget::selectRow(int row)
return xTableSelection->selectRow(row);
}
-int QtAccessibleWidget::selectedCellCount() const
-{
- Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
- if (!xAcc.is())
- return 0;
-
- Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
- if (!xSelection.is())
- return 0;
-
- sal_Int64 nSelected = xSelection->getSelectedAccessibleChildCount();
- if (nSelected > std::numeric_limits<int>::max())
- {
- SAL_WARN("vcl.qt",
- "QtAccessibleWidget::selectedCellCount: Cell count exceeds maximum int value, "
- "using max int.");
- nSelected = std::numeric_limits<int>::max();
- }
- return nSelected;
-}
-
-QList<QAccessibleInterface*> QtAccessibleWidget::selectedCells() const
-{
- Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
- if (!xAcc.is())
- return QList<QAccessibleInterface*>();
-
- Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
- if (!xSelection.is())
- return QList<QAccessibleInterface*>();
+int QtAccessibleWidget::selectedCellCount() const { return selectedItemCount(); }
- QList<QAccessibleInterface*> aSelectedCells;
- sal_Int64 nSelected = xSelection->getSelectedAccessibleChildCount();
- if (nSelected > std::numeric_limits<int>::max())
- {
- SAL_WARN("vcl.qt",
- "QtAccessibleWidget::selectedCells: Cell count exceeds maximum int value, "
- "using max int.");
- nSelected = std::numeric_limits<int>::max();
- }
- for (sal_Int64 i = 0; i < nSelected; i++)
- {
- Reference<XAccessible> xChild = xSelection->getSelectedAccessibleChild(i);
- QAccessibleInterface* pInterface
- = QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xChild));
- aSelectedCells.push_back(pInterface);
- }
- return aSelectedCells;
-}
+QList<QAccessibleInterface*> QtAccessibleWidget::selectedCells() const { return selectedItems(); }
int QtAccessibleWidget::selectedColumnCount() const
{
@@ -1897,4 +1855,162 @@ QAccessibleInterface* QtAccessibleWidget::table() const
return QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xTableAcc));
}
+// QAccessibleSelectionInterface
+int QtAccessibleWidget::selectedItemCount() const
+{
+ Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
+ if (!xAcc.is())
+ return 0;
+
+ Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
+ if (!xSelection.is())
+ return 0;
+
+ sal_Int64 nSelected = xSelection->getSelectedAccessibleChildCount();
+ if (nSelected > std::numeric_limits<int>::max())
+ {
+ SAL_WARN("vcl.qt",
+ "QtAccessibleWidget::selectedItemCount: Cell count exceeds maximum int value, "
+ "using max int.");
+ nSelected = std::numeric_limits<int>::max();
+ }
+ return nSelected;
+}
+
+QList<QAccessibleInterface*> QtAccessibleWidget::selectedItems() const
+{
+ Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
+ if (!xAcc.is())
+ return QList<QAccessibleInterface*>();
+
+ Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
+ if (!xSelection.is())
+ return QList<QAccessibleInterface*>();
+
+ QList<QAccessibleInterface*> aSelectedItems;
+ sal_Int64 nSelected = xSelection->getSelectedAccessibleChildCount();
+ if (nSelected > std::numeric_limits<int>::max())
+ {
+ SAL_WARN("vcl.qt",
+ "QtAccessibleWidget::selectedItems: Cell count exceeds maximum int value, "
+ "using max int.");
+ nSelected = std::numeric_limits<int>::max();
+ }
+ for (sal_Int64 i = 0; i < nSelected; i++)
+ {
+ Reference<XAccessible> xChild = xSelection->getSelectedAccessibleChild(i);
+ QAccessibleInterface* pInterface
+ = QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xChild));
+ aSelectedItems.push_back(pInterface);
+ }
+ return aSelectedItems;
+}
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
+QAccessibleInterface* QtAccessibleWidget::selectedItem(int nSelectionIndex) const
+{
+ Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
+ if (!xAcc.is())
+ return nullptr;
+
+ Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
+ if (!xSelection.is())
+ return nullptr;
+
+ if (nSelectionIndex < 0 || nSelectionIndex >= xSelection->getSelectedAccessibleChildCount())
+ {
+ SAL_WARN("vcl.qt",
+ "QtAccessibleWidget::selectedItem called with invalid index: " << nSelectionIndex);
+ return nullptr;
+ }
+
+ Reference<XAccessible> xChild = xSelection->getSelectedAccessibleChild(nSelectionIndex);
+ if (!xChild)
+ return nullptr;
+
+ return QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xChild));
+}
+
+bool QtAccessibleWidget::isSelected(QAccessibleInterface* pItem) const
+{
+ Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
+ if (!xAcc.is())
+ return false;
+
+ Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
+ if (!xSelection.is())
+ return false;
+
+ int nChildIndex = indexOfChild(pItem);
+ if (nChildIndex < 0)
+ return false;
+
+ return xSelection->isAccessibleChildSelected(nChildIndex);
+}
+
+bool QtAccessibleWidget::select(QAccessibleInterface* pItem)
+{
+ Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
+ if (!xAcc.is())
+ return false;
+
+ Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
+ if (!xSelection.is())
+ return false;
+
+ int nChildIndex = indexOfChild(pItem);
+ if (nChildIndex < 0)
+ return false;
+
+ xSelection->selectAccessibleChild(nChildIndex);
+ return true;
+}
+
+bool QtAccessibleWidget::unselect(QAccessibleInterface* pItem)
+{
+ Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
+ if (!xAcc.is())
+ return false;
+
+ Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
+ if (!xSelection.is())
+ return false;
+
+ int nChildIndex = indexOfChild(pItem);
+ if (nChildIndex < 0)
+ return false;
+
+ xSelection->deselectAccessibleChild(nChildIndex);
+ return true;
+}
+
+bool QtAccessibleWidget::selectAll()
+{
+ Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
+ if (!xAcc.is())
+ return false;
+
+ Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
+ if (!xSelection.is())
+ return false;
+
+ xSelection->selectAllAccessibleChildren();
+ return true;
+}
+
+bool QtAccessibleWidget::clear()
+{
+ Reference<XAccessibleContext> xAcc = getAccessibleContextImpl();
+ if (!xAcc.is())
+ return false;
+
+ Reference<XAccessibleSelection> xSelection(xAcc, UNO_QUERY);
+ if (!xSelection.is())
+ return false;
+
+ xSelection->clearAccessibleSelection();
+ return true;
+}
+#endif
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */