summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2022-10-11 15:23:54 +0200
committerMichael Weghorn <m.weghorn@posteo.de>2022-11-11 17:48:51 +0100
commit9d16d5e2245c26e5746fd7609300b84a2a983457 (patch)
tree73b0b28cc453c3dc62ed34343f5abf2a95e98640 /src/gui
parenta45a1b8674d0982828d75440041a67fdb3da74f9 (diff)
a11y: Add new QAccessibleSelectionInterface
This adds a new QAccessibleSelectionInterface that implements support for handling selections, both retrieving information about the current selection as well as modifying the selection, thus providing the necessary foundation for exposing selections to assistive technology. This is similar to AT-SPI's Selection interface [1], but uses QAccessibleInterface pointers instead of child indices as parameters for methods. Bridging this newly introduced interface to AT-SPI will be done in a follow-up change. The concept for selection handling in Microsoft's UI Automation looks similar, so bridging this to the corresponding UIA interfaces ISelectionProvider [2], ISelectionItemProvider [3] and ISelectionProvider2 [4] should also be reasonably straightforward. At this point, this is only meant to be used for handling selection of direct children as is the concept in AT-SPI's Selection and presumably in UIA as well. (The ISelectionItemProvider and ISelectionProvider doc speaks of "child controls of containers" etc., but doesn't explicitly mention that this is only for direct children or whether grand children are also allowed.) (The proposed API itself could also be used to support selection of objects that are no direct children, but the practical use of that is unclear and it would make mapping/ bridging to platform a11y layers tricky.) [5] demonstrates a sample implementation of the QAccessibleSelectionInterface for the Qt-based UI variants of LibreOffice (screencast that shows the use of the interface attached to QTBUG-105909). 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 [6]) [1] https://lazka.github.io/pgi-docs/Atspi-2.0/classes/Selection.html [2] https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcore/nn-uiautomationcore-iselectionprovider [3] https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcore/nn-uiautomationcore-iselectionitemprovider [4] https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcore/nn-uiautomationcore-iselectionprovider2 [5] https://gerrit.libreoffice.org/c/core/+/138750 [6] https://doc-snapshots.qt.io/qt6-dev/qml-qtquick-tableview.html [ChangeLog][QtGui][QAccessibleSelectionInterface] Added new preliminary QAccessibleSelectionInterface that can be used to expose selections to assistive technology. Task-number: QTBUG-105909 Change-Id: If77beacd94fa3eb663f0fbb2373f12382bab2ee3 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/qaccessible.cpp111
-rw-r--r--src/gui/accessible/qaccessible.h22
-rw-r--r--src/gui/accessible/qaccessible_base.h3
3 files changed, 134 insertions, 2 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index e54738e075..e34c00c9c7 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -415,8 +415,9 @@ Q_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core");
\value TableInterface For lists, tables and trees.
\value TableCellInterface For cells in a TableInterface object.
\value HyperlinkInterface For hyperlink nodes (usually embedded as children of text nodes)
+ \value [since 6.5] SelectionInterface For non-text objects that support selection of child objects.
- \sa QAccessibleInterface::interface_cast(), QAccessibleTextInterface, QAccessibleValueInterface, QAccessibleActionInterface, QAccessibleTableInterface, QAccessibleTableCellInterface
+ \sa QAccessibleInterface::interface_cast(), QAccessibleTextInterface, QAccessibleValueInterface, QAccessibleActionInterface, QAccessibleTableInterface, QAccessibleTableCellInterface, QAccessibleSelectionInterface
*/
#if QT_CONFIG(accessibility)
@@ -2941,6 +2942,114 @@ QString QAccessibleActionInterface::nextPageAction()
return accessibleActionStrings()->nextPageAction;
}
+
+/*!
+ \since 6.5
+ \class QAccessibleSelectionInterface
+ \inmodule QtGui
+ \ingroup accessibility
+ \preliminary
+
+ \brief The QAccessibleSelectionInterface class implements support for
+ selection handling.
+
+ It provides methods for both, retrieving the current selection
+ as well as modifying the selection.
+
+ Only selections of direct children are supported.
+*/
+
+/*!
+
+ Destroys the QAccessibleSelectionInterface.
+*/
+QAccessibleSelectionInterface::~QAccessibleSelectionInterface()
+{
+}
+
+/*!
+ \fn virtual int QAccessibleSelectionInterface::selectedItemCount() const
+
+ Returns the total number of selected accessible items.
+*/
+
+/*!
+ \fn virtual QList<QAccessibleInterface *> QAccessibleSelectionInterface::selectedItems() const
+
+ Returns the list of selected accessible items.
+*/
+
+/*!
+ Returns the selected accessible item at index \a selectionIndex in the selection.
+
+ Note that the index refers to the n-th selected accessible item (i.e. the index in the current selection),
+ which generally differs from the index that would be passed to \l QAccessibleInterface::child()
+ in order to retrieve the same item.
+
+ The default implementation uses \a selectionIndex to retrieve the item from the list
+ of selected items retrieved by \l QAccessibleSelectionInterface::selectedItems().
+
+ In particular for implementations dealing with many selected items, reimplementing
+ this method in a more efficient way may be desirable for performance reasons.
+*/
+QAccessibleInterface* QAccessibleSelectionInterface::selectedItem(int selectionIndex) const
+{
+ QList<QAccessibleInterface*> items = selectedItems();
+ if (selectionIndex < 0 || selectionIndex > items.length() -1) {
+ qCWarning(lcAccessibilityCore) << "Selection index" << selectionIndex << "out of range.";
+ return nullptr;
+ }
+
+ return items.at(selectionIndex);
+}
+
+/*!
+ Returns whether \a childItem is part of the current selection.
+
+ The default implementation checks whether \a childItem is contained
+ in the list of items retrieved by \l QAccessibleSelectionInterface::selectedItems.
+*/
+bool QAccessibleSelectionInterface::isSelected(QAccessibleInterface *childItem) const
+{
+ return selectedItems().contains(childItem);
+}
+
+/*!
+ \fn virtual bool QAccessibleSelectionInterface::select(QAccessibleInterface *childItem)
+
+ Adds \a childItem to the selection.
+ Returns whether \a childItem has actually been added to the selection.
+
+ For implementations that only allow single selections,
+ this may replace the current selection.
+*/
+
+/*!
+ \fn virtual bool QAccessibleSelectionInterface::unselect(QAccessibleInterface *childItem)
+
+ Removes \a childItem from the selection.
+
+ Returns whether the accessible item has actually been removed from the selection.
+*/
+
+/*!
+ \fn virtual bool QAccessibleSelectionInterface::selectAll()
+
+ Selects all accessible child items.
+
+ Returns whether all accessible child items have actually been added to the selection.
+*/
+
+/*!
+ \fn virtual bool QAccessibleSelectionInterface::clear()
+
+ Unselects all accessible child items.
+
+ Returns whether all accessible child items have actually been removed from the selection,
+ i.e. whether the selection is empty after this method has been called.
+*/
+
+
/*! \internal */
QString qAccessibleLocalizedActionDescription(const QString &actionName)
{
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index c2f26a1e25..ac1bacd85a 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -42,6 +42,7 @@ class QAccessibleImageInterface;
class QAccessibleTableInterface;
class QAccessibleTableCellInterface;
class QAccessibleHyperlinkInterface;
+class QAccessibleSelectionInterface;
class QAccessibleTableModelChangeEvent;
class Q_GUI_EXPORT QAccessibleInterface
@@ -102,6 +103,12 @@ public:
inline QAccessibleHyperlinkInterface *hyperlinkInterface()
{ return reinterpret_cast<QAccessibleHyperlinkInterface *>(interface_cast(QAccessible::HyperlinkInterface)); }
+ /*!
+ \since 6.5
+ */
+ inline QAccessibleSelectionInterface *selectionInterface()
+ { return reinterpret_cast<QAccessibleSelectionInterface *>(interface_cast(QAccessible::SelectionInterface)); }
+
virtual void virtual_hook(int id, void *data);
virtual void *interface_cast(QAccessible::InterfaceType)
@@ -265,6 +272,21 @@ public:
virtual bool isValid() const = 0;
};
+class Q_GUI_EXPORT QAccessibleSelectionInterface
+{
+public:
+ virtual ~QAccessibleSelectionInterface();
+
+ virtual int selectedItemCount() const = 0;
+ virtual QList<QAccessibleInterface*> selectedItems() const = 0;
+ virtual QAccessibleInterface* selectedItem(int selectionIndex) const;
+ virtual bool isSelected(QAccessibleInterface *childItem) const;
+ virtual bool select(QAccessibleInterface *childItem) = 0;
+ virtual bool unselect(QAccessibleInterface *childItem) = 0;
+ virtual bool selectAll() = 0;
+ virtual bool clear() = 0;
+};
+
class Q_GUI_EXPORT QAccessibleEvent
{
Q_DISABLE_COPY(QAccessibleEvent)
diff --git a/src/gui/accessible/qaccessible_base.h b/src/gui/accessible/qaccessible_base.h
index cf5a65143b..ac50c2626e 100644
--- a/src/gui/accessible/qaccessible_base.h
+++ b/src/gui/accessible/qaccessible_base.h
@@ -344,7 +344,8 @@ public:
ImageInterface,
TableInterface,
TableCellInterface,
- HyperlinkInterface
+ HyperlinkInterface,
+ SelectionInterface
};
enum TextBoundaryType {