summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport/linuxaccessibility/atspiadaptor.cpp')
-rw-r--r--src/platformsupport/linuxaccessibility/atspiadaptor.cpp134
1 files changed, 76 insertions, 58 deletions
diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
index 84f82cdeda..c3573489e9 100644
--- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
@@ -1,40 +1,32 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -51,6 +43,7 @@
#include "socket_interface.h"
#include "constant_mappings_p.h"
+#include "../accessibility/qaccessiblebridgeutils_p.h"
#include "application_p.h"
/*!
@@ -910,6 +903,11 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
notifyAboutDestruction(event->accessibleInterface());
break;
}
+ case QAccessible::ObjectReorder: {
+ if (sendObject || sendObject_children_changed)
+ childrenChanged(event->accessibleInterface());
+ break;
+ }
case QAccessible::NameChanged: {
if (sendObject || sendObject_property_change || sendObject_property_change_accessible_name) {
QString path = pathForInterface(event->accessibleInterface());
@@ -1078,16 +1076,14 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
QAccessibleInterface * iface = event->accessibleInterface();
if (!iface || !(iface->role() == QAccessible::Window && (sendWindow || sendWindow_activate)))
return;
+ int isActive = iface->state().active;
QString windowTitle = iface->text(QAccessible::Name);
QDBusVariant data;
data.setVariant(windowTitle);
QVariantList args = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(data));
-
- QString status = iface->state().active ? QLatin1String("Activate") : QLatin1String("Deactivate");
+ QString status = isActive ? QLatin1String("Activate") : QLatin1String("Deactivate");
QString path = pathForInterface(iface);
sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_WINDOW), status, args);
-
- int isActive = iface->state().active;
notifyStateChange(iface, QLatin1String("active"), isActive);
} else if (stateChange.disabled) {
QAccessibleInterface *iface = event->accessibleInterface();
@@ -1150,7 +1146,6 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
case QAccessible::TextAttributeChanged:
case QAccessible::TextColumnChanged:
case QAccessible::VisibleDataChanged:
- case QAccessible::ObjectReorder:
case QAccessible::SelectionAdd:
case QAccessible::SelectionWithin:
case QAccessible::LocationChanged:
@@ -1186,6 +1181,17 @@ void AtSpiAdaptor::sendFocusChanged(QAccessibleInterface *interface) const
}
}
+void AtSpiAdaptor::childrenChanged(QAccessibleInterface *interface) const
+{
+ QString parentPath = pathForInterface(interface);
+ int childCount = interface->childCount();
+ for (int i = 0; i < interface->childCount(); ++i) {
+ QString childPath = pathForInterface(interface->child(i));
+ QVariantList args = packDBusSignalArguments(QLatin1String("add"), childCount, 0, childPath);
+ sendDBusSignal(parentPath, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), QLatin1String("ChildrenChanged"), args);
+ }
+}
+
void AtSpiAdaptor::notifyAboutCreation(QAccessibleInterface *interface) const
{
// // say hello to d-bus
@@ -1472,7 +1478,7 @@ QStringList AtSpiAdaptor::accessibleInterfaces(QAccessibleInterface *interface)
if (interface->role() == QAccessible::Application)
ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_APPLICATION);
- if (interface->actionInterface())
+ if (interface->actionInterface() || interface->valueInterface())
ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_ACTION);
if (interface->textInterface())
@@ -1641,13 +1647,13 @@ bool AtSpiAdaptor::componentInterface(QAccessibleInterface *interface, const QSt
size << rect.width() << rect.height();
connection.send(message.createReply(size));
} else if (function == QLatin1String("GrabFocus")) {
-// FIXME: implement focus grabbing
-// if (interface->object() && interface->object()->isWidgetType()) {
-// QWidget* w = static_cast<QWidget*>(interface->object());
-// w->setFocus(Qt::OtherFocusReason);
-// sendReply(connection, message, true);
-// }
- sendReply(connection, message, false);
+ QAccessibleActionInterface *actionIface = interface->actionInterface();
+ if (actionIface && actionIface->actionNames().contains(QAccessibleActionInterface::setFocusAction())) {
+ actionIface->doAction(QAccessibleActionInterface::setFocusAction());
+ sendReply(connection, message, true);
+ } else {
+ sendReply(connection, message, false);
+ }
} else if (function == QLatin1String("SetExtents")) {
// int x = message.arguments().at(0).toInt();
// int y = message.arguments().at(1).toInt();
@@ -1682,36 +1688,44 @@ QRect AtSpiAdaptor::getExtents(QAccessibleInterface *interface, uint coordType)
// Action interface
bool AtSpiAdaptor::actionInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
{
- QAccessibleActionInterface *actionIface = interface->actionInterface();
- if (!actionIface)
- return false;
-
if (function == QLatin1String("GetNActions")) {
- sendReply(connection, message, QVariant::fromValue(QDBusVariant(QVariant::fromValue(actionIface->actionNames().count()))));
+ int count = QAccessibleBridgeUtils::effectiveActionNames(interface).count();
+ sendReply(connection, message, QVariant::fromValue(QDBusVariant(QVariant::fromValue(count))));
} else if (function == QLatin1String("DoAction")) {
int index = message.arguments().at(0).toInt();
- if (index < 0 || index >= actionIface->actionNames().count())
+ const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
+ if (index < 0 || index >= actionNames.count())
return false;
- interface->actionInterface()->doAction(actionIface->actionNames().at(index));
- sendReply(connection, message, true);
+ const QString actionName = actionNames.at(index);
+ bool success = QAccessibleBridgeUtils::performEffectiveAction(interface, actionName);
+ sendReply(connection, message, success);
} else if (function == QLatin1String("GetActions")) {
- sendReply(connection, message, QVariant::fromValue(getActions(actionIface)));
+ sendReply(connection, message, QVariant::fromValue(getActions(interface)));
} else if (function == QLatin1String("GetName")) {
int index = message.arguments().at(0).toInt();
- if (index < 0 || index >= actionIface->actionNames().count())
+ const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
+ if (index < 0 || index >= actionNames.count())
return false;
- sendReply(connection, message, actionIface->actionNames().at(index));
+ sendReply(connection, message, actionNames.at(index));
} else if (function == QLatin1String("GetDescription")) {
int index = message.arguments().at(0).toInt();
- if (index < 0 || index >= actionIface->actionNames().count())
+ const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
+ if (index < 0 || index >= actionNames.count())
return false;
- sendReply(connection, message, actionIface->localizedActionDescription(actionIface->actionNames().at(index)));
+ QString description;
+ if (QAccessibleActionInterface *actionIface = interface->actionInterface())
+ description = actionIface->localizedActionDescription(actionNames.at(index));
+ else
+ description = qAccessibleLocalizedActionDescription(actionNames.at(index));
+ sendReply(connection, message, description);
} else if (function == QLatin1String("GetKeyBinding")) {
int index = message.arguments().at(0).toInt();
- if (index < 0 || index >= actionIface->actionNames().count())
+ const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
+ if (index < 0 || index >= actionNames.count())
return false;
QStringList keyBindings;
- keyBindings = actionIface->keyBindingsForAction(actionIface->actionNames().value(index));
+ if (QAccessibleActionInterface *actionIface = interface->actionInterface())
+ keyBindings = actionIface->keyBindingsForAction(actionNames.at(index));
if (keyBindings.isEmpty()) {
QString acc = interface->text(QAccessible::Accelerator);
if (!acc.isEmpty())
@@ -1728,20 +1742,24 @@ bool AtSpiAdaptor::actionInterface(QAccessibleInterface *interface, const QStrin
return true;
}
-QSpiActionArray AtSpiAdaptor::getActions(QAccessibleActionInterface *actionInterface) const
+QSpiActionArray AtSpiAdaptor::getActions(QAccessibleInterface *interface) const
{
+ QAccessibleActionInterface *actionInterface = interface->actionInterface();
QSpiActionArray actions;
- Q_FOREACH (const QString &actionName, actionInterface->actionNames()) {
+ Q_FOREACH (const QString &actionName, QAccessibleBridgeUtils::effectiveActionNames(interface)) {
QSpiAction action;
QStringList keyBindings;
action.name = actionName;
- action.description = actionInterface->localizedActionDescription(actionName);
-
- keyBindings = actionInterface->keyBindingsForAction(actionName);
+ if (actionInterface) {
+ action.description = actionInterface->localizedActionDescription(actionName);
+ keyBindings = actionInterface->keyBindingsForAction(actionName);
+ } else {
+ action.description = qAccessibleLocalizedActionDescription(actionName);
+ }
if (keyBindings.length() > 0)
- action.keyBinding = keyBindings[0];
+ action.keyBinding = keyBindings[0];
else
action.keyBinding = QString();
@@ -1952,17 +1970,17 @@ QVariantList AtSpiAdaptor::getAttributeValue(QAccessibleInterface *interface, in
return list;
}
-QRect AtSpiAdaptor::getCharacterExtents(QAccessibleInterface *interface, int offset, uint coordType) const
+QList<QVariant> AtSpiAdaptor::getCharacterExtents(QAccessibleInterface *interface, int offset, uint coordType) const
{
QRect rect = interface->textInterface()->characterRect(offset);
if (coordType == ATSPI_COORD_TYPE_WINDOW)
rect = translateRectToWindowCoordinates(interface, rect);
- return rect;
+ return QList<QVariant>() << rect.x() << rect.y() << rect.width() << rect.height();
}
-QRect AtSpiAdaptor::getRangeExtents(QAccessibleInterface *interface,
+QList<QVariant> AtSpiAdaptor::getRangeExtents(QAccessibleInterface *interface,
int startOffset, int endOffset, uint coordType) const
{
if (endOffset == -1)
@@ -1970,7 +1988,7 @@ QRect AtSpiAdaptor::getRangeExtents(QAccessibleInterface *interface,
QAccessibleTextInterface *textInterface = interface->textInterface();
if (endOffset <= startOffset || !textInterface)
- return QRect();
+ return QList<QVariant>() << -1 << -1 << 0 << 0;
QRect rect = textInterface->characterRect(startOffset);
for (int i=startOffset + 1; i <= endOffset; i++)
@@ -1980,7 +1998,7 @@ QRect AtSpiAdaptor::getRangeExtents(QAccessibleInterface *interface,
if (coordType == ATSPI_COORD_TYPE_WINDOW)
rect = translateRectToWindowCoordinates(interface, rect);
- return rect;
+ return QList<QVariant>() << rect.x() << rect.y() << rect.width() << rect.height();
}
QRect AtSpiAdaptor::translateRectToWindowCoordinates(QAccessibleInterface *interface, const QRect &rect)