a11y atspi: Support AT-SPI table cell interface

QAccessibleTableCellInterface provides everything
needed to support the AT-SPI TableCell interface [1].

Therefore, expose that AT-SPI interface and implement
handling of the corresponding methods.

[1] https://gitlab.gnome.org/GNOME/at-spi2-core/-/blob/master/xml/TableCell.xml

Fixes: QTBUG-104793
Change-Id: Ie7068c029eaf911186daf3956f11cfd4eb2800a6
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Michael Weghorn 2022-07-06 14:19:28 +02:00
parent 2df6fd5ea0
commit 5145d3899d
2 changed files with 63 additions and 0 deletions

View File

@ -414,6 +414,26 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" </interface>\n" " </interface>\n"
); );
static const QLatin1StringView tableCellIntrospection(
" <interface name=\"org.a11y.atspi.TableCell\">\n"
" <property access=\"read\" name=\"ColumnSpan\" type=\"i\" />\n"
" <property access=\"read\" name=\"Position\" type=\"(ii)\">\n"
" <annotation name=\"org.qtproject.QtDBus.QtTypeName\" value=\"QPoint\"/>\n"
" </property>\n"
" <property access=\"read\" name=\"RowSpan\" type=\"i\" />\n"
" <property access=\"read\" name=\"Table\" type=\"(so)\" >\n"
" <annotation name=\"org.qtproject.QtDBus.QtTypeName\" value=\"QSpiObjectReference\"/>\n"
" </property>\n"
" <method name=\"GetRowColumnSpan\">\n"
" <arg direction=\"out\" type=\"b\" />\n"
" <arg direction=\"out\" name=\"row\" type=\"i\" />\n"
" <arg direction=\"out\" name=\"col\" type=\"i\" />\n"
" <arg direction=\"out\" name=\"row_extents\" type=\"i\" />\n"
" <arg direction=\"out\" name=\"col_extents\" type=\"i\" />\n"
" </method>\n"
" </interface>\n"
);
static const QLatin1StringView textIntrospection( static const QLatin1StringView textIntrospection(
" <interface name=\"org.a11y.atspi.Text\">\n" " <interface name=\"org.a11y.atspi.Text\">\n"
" <property access=\"read\" type=\"i\" name=\"CharacterCount\"/>\n" " <property access=\"read\" type=\"i\" name=\"CharacterCount\"/>\n"
@ -575,6 +595,8 @@ QString AtSpiAdaptor::introspect(const QString &path) const
xml.append(actionIntrospection); xml.append(actionIntrospection);
if (interfaces.contains(ATSPI_DBUS_INTERFACE_TABLE ""_L1)) if (interfaces.contains(ATSPI_DBUS_INTERFACE_TABLE ""_L1))
xml.append(tableIntrospection); xml.append(tableIntrospection);
if (interfaces.contains(ATSPI_DBUS_INTERFACE_TABLE_CELL ""_L1))
xml.append(tableCellIntrospection);
if (interfaces.contains(ATSPI_DBUS_INTERFACE_VALUE ""_L1)) if (interfaces.contains(ATSPI_DBUS_INTERFACE_VALUE ""_L1))
xml.append(valueIntrospection); xml.append(valueIntrospection);
if (path == QSPI_OBJECT_PATH_ROOT ""_L1) if (path == QSPI_OBJECT_PATH_ROOT ""_L1)
@ -1263,6 +1285,8 @@ bool AtSpiAdaptor::handleMessage(const QDBusMessage &message, const QDBusConnect
return valueInterface(accessible, function, message, connection); return valueInterface(accessible, function, message, connection);
if (interface == ATSPI_DBUS_INTERFACE_TABLE ""_L1) if (interface == ATSPI_DBUS_INTERFACE_TABLE ""_L1)
return tableInterface(accessible, function, message, connection); return tableInterface(accessible, function, message, connection);
if (interface == ATSPI_DBUS_INTERFACE_TABLE_CELL ""_L1)
return tableCellInterface(accessible, function, message, connection);
qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::handleMessage with unknown interface: " << message.path() << interface << function; qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::handleMessage with unknown interface: " << message.path() << interface << function;
return false; return false;
@ -1464,6 +1488,9 @@ QStringList AtSpiAdaptor::accessibleInterfaces(QAccessibleInterface *interface)
if (interface->tableInterface()) if (interface->tableInterface())
ifaces << ATSPI_DBUS_INTERFACE_TABLE ""_L1; ifaces << ATSPI_DBUS_INTERFACE_TABLE ""_L1;
if (interface->tableCellInterface())
ifaces << ATSPI_DBUS_INTERFACE_TABLE_CELL ""_L1;
return ifaces; return ifaces;
} }
@ -2446,6 +2473,41 @@ bool AtSpiAdaptor::tableInterface(QAccessibleInterface *interface, const QString
return true; return true;
} }
// Table cell interface
bool AtSpiAdaptor::tableCellInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
{
QAccessibleTableCellInterface* cellInterface = interface->tableCellInterface();
if (!cellInterface) {
qCWarning(lcAccessibilityAtspi) << "Could not find table cell interface for: " << message.path() << interface;
return false;
}
if (function == "GetColumnSpan"_L1) {
connection.send(message.createReply(QVariant::fromValue(QDBusVariant(
QVariant::fromValue(cellInterface->columnExtent())))));
} else if (function == "GetPosition"_L1) {
const int row = cellInterface->rowIndex();
const int column = cellInterface->columnIndex();
connection.send(message.createReply(QVariant::fromValue(QDBusVariant(
QVariant::fromValue(QPoint(row, column))))));
} else if (function == "GetRowSpan"_L1) {
connection.send(message.createReply(QVariant::fromValue(QDBusVariant(
QVariant::fromValue(cellInterface->rowExtent())))));
} else if (function == "GetRowColumnSpan"_L1) {
QVariantList list;
list << cellInterface->rowIndex() << cellInterface->columnIndex() << cellInterface->rowExtent() << cellInterface->columnExtent();
connection.send(message.createReply(list));
} else if (function == "GetTable"_L1) {
QSpiObjectReference ref;
QAccessibleInterface* table = cellInterface->table();
if (table && table->tableInterface())
ref = QSpiObjectReference(connection, QDBusObjectPath(pathForInterface(table)));
connection.send(message.createReply(QVariant::fromValue(QDBusVariant(QVariant::fromValue(ref)))));
}
return true;
}
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_atspiadaptor_p.cpp" #include "moc_atspiadaptor_p.cpp"

View File

@ -77,6 +77,7 @@ private:
bool editableTextInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection); bool editableTextInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection);
bool valueInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection); bool valueInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection);
bool tableInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection); bool tableInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection);
bool tableCellInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection);
void sendReply(const QDBusConnection &connection, const QDBusMessage &message, const QVariant &argument) const; void sendReply(const QDBusConnection &connection, const QDBusMessage &message, const QVariant &argument) const;