summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-07-02 10:04:34 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-07-06 11:15:08 +0200
commit9e733622a605c841adf7da7304895758d307c843 (patch)
treee859f7cf4dee099c49835c65e5c0498bcec6f87c /src/platformsupport/linuxaccessibility/atspiadaptor.cpp
parent7067b2ca6e08e683bb9c202a7e3c1b10d08622ee (diff)
Move linuxaccessibility to QtGui
Change some too-generic file names. Task-number: QTBUG-83255 Change-Id: I4497ee2508bc323566f4061d4547707b7bda7a77 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/platformsupport/linuxaccessibility/atspiadaptor.cpp')
-rw-r--r--src/platformsupport/linuxaccessibility/atspiadaptor.cpp2482
1 files changed, 0 insertions, 2482 deletions
diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
deleted file mode 100644
index c4ff9a211b..0000000000
--- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+++ /dev/null
@@ -1,2482 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "atspiadaptor_p.h"
-
-#include <QtGui/qwindow.h>
-#include <QtGui/qguiapplication.h>
-#include <qdbusmessage.h>
-#include <qdbusreply.h>
-#include <qclipboard.h>
-
-#include <QtCore/qloggingcategory.h>
-
-#ifndef QT_NO_ACCESSIBILITY
-#include "socket_interface.h"
-#include "constant_mappings_p.h"
-#include <QtGui/private/qaccessiblebridgeutils_p.h>
-
-#include "application_p.h"
-/*!
- \class AtSpiAdaptor
- \internal
-
- \brief AtSpiAdaptor is the main class to forward between QAccessibleInterface and AT-SPI DBus
-
- AtSpiAdaptor implements the functions specified in all at-spi interfaces.
- It sends notifications coming from Qt via dbus and listens to incoming dbus requests.
-*/
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcAccessibilityAtspi, "qt.accessibility.atspi")
-Q_LOGGING_CATEGORY(lcAccessibilityAtspiCreation, "qt.accessibility.atspi.creation")
-
-AtSpiAdaptor::AtSpiAdaptor(DBusConnection *connection, QObject *parent)
- : QDBusVirtualObject(parent), m_dbus(connection)
- , sendFocus(0)
- , sendObject(0)
- , sendObject_active_descendant_changed(0)
- , sendObject_attributes_changed(0)
- , sendObject_bounds_changed(0)
- , sendObject_children_changed(0)
-// , sendObject_children_changed_add(0)
-// , sendObject_children_changed_remove(0)
- , sendObject_column_deleted(0)
- , sendObject_column_inserted(0)
- , sendObject_column_reordered(0)
- , sendObject_link_selected(0)
- , sendObject_model_changed(0)
- , sendObject_property_change(0)
- , sendObject_property_change_accessible_description(0)
- , sendObject_property_change_accessible_name(0)
- , sendObject_property_change_accessible_parent(0)
- , sendObject_property_change_accessible_role(0)
- , sendObject_property_change_accessible_table_caption(0)
- , sendObject_property_change_accessible_table_column_description(0)
- , sendObject_property_change_accessible_table_column_header(0)
- , sendObject_property_change_accessible_table_row_description(0)
- , sendObject_property_change_accessible_table_row_header(0)
- , sendObject_property_change_accessible_table_summary(0)
- , sendObject_property_change_accessible_value(0)
- , sendObject_row_deleted(0)
- , sendObject_row_inserted(0)
- , sendObject_row_reordered(0)
- , sendObject_selection_changed(0)
- , sendObject_state_changed(0)
- , sendObject_text_attributes_changed(0)
- , sendObject_text_bounds_changed(0)
- , sendObject_text_caret_moved(0)
- , sendObject_text_changed(0)
-// , sendObject_text_changed_delete(0)
-// , sendObject_text_changed_insert(0)
- , sendObject_text_selection_changed(0)
- , sendObject_value_changed(0)
- , sendObject_visible_data_changed(0)
- , sendWindow(0)
- , sendWindow_activate(0)
- , sendWindow_close(0)
- , sendWindow_create(0)
- , sendWindow_deactivate(0)
-// , sendWindow_desktop_create(0)
-// , sendWindow_desktop_destroy(0)
- , sendWindow_lower(0)
- , sendWindow_maximize(0)
- , sendWindow_minimize(0)
- , sendWindow_move(0)
- , sendWindow_raise(0)
- , sendWindow_reparent(0)
- , sendWindow_resize(0)
- , sendWindow_restore(0)
- , sendWindow_restyle(0)
- , sendWindow_shade(0)
- , sendWindow_unshade(0)
-{
- m_applicationAdaptor = new QSpiApplicationAdaptor(m_dbus->connection(), this);
- connect(m_applicationAdaptor, SIGNAL(windowActivated(QObject*,bool)), this, SLOT(windowActivated(QObject*,bool)));
-
- updateEventListeners();
- bool success = m_dbus->connection().connect(QLatin1String("org.a11y.atspi.Registry"), QLatin1String("/org/a11y/atspi/registry"),
- QLatin1String("org.a11y.atspi.Registry"), QLatin1String("EventListenerRegistered"), this,
- SLOT(eventListenerRegistered(QString,QString)));
- success = success && m_dbus->connection().connect(QLatin1String("org.a11y.atspi.Registry"), QLatin1String("/org/a11y/atspi/registry"),
- QLatin1String("org.a11y.atspi.Registry"), QLatin1String("EventListenerDeregistered"), this,
- SLOT(eventListenerDeregistered(QString,QString)));
-}
-
-AtSpiAdaptor::~AtSpiAdaptor()
-{
-}
-
-/*!
- Provide DBus introspection.
- */
-QString AtSpiAdaptor::introspect(const QString &path) const
-{
- static const QLatin1String accessibleIntrospection(
- " <interface name=\"org.a11y.atspi.Accessible\">\n"
- " <property access=\"read\" type=\"s\" name=\"Name\"/>\n"
- " <property access=\"read\" type=\"s\" name=\"Description\"/>\n"
- " <property access=\"read\" type=\"(so)\" name=\"Parent\">\n"
- " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName\"/>\n"
- " </property>\n"
- " <property access=\"read\" type=\"i\" name=\"ChildCount\"/>\n"
- " <method name=\"GetChildAtIndex\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
- " <arg direction=\"out\" type=\"(so)\"/>\n"
- " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetChildren\">\n"
- " <arg direction=\"out\" type=\"a(so)\"/>\n"
- " <annotation value=\"QSpiObjectReferenceArray\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetIndexInParent\">\n"
- " <arg direction=\"out\" type=\"i\"/>\n"
- " </method>\n"
- " <method name=\"GetRelationSet\">\n"
- " <arg direction=\"out\" type=\"a(ua(so))\"/>\n"
- " <annotation value=\"QSpiRelationArray\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetRole\">\n"
- " <arg direction=\"out\" type=\"u\"/>\n"
- " </method>\n"
- " <method name=\"GetRoleName\">\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " </method>\n"
- " <method name=\"GetLocalizedRoleName\">\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " </method>\n"
- " <method name=\"GetState\">\n"
- " <arg direction=\"out\" type=\"au\"/>\n"
- " <annotation value=\"QSpiUIntList\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetAttributes\">\n"
- " <arg direction=\"out\" type=\"a{ss}\"/>\n"
- " <annotation value=\"QSpiAttributeSet\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetApplication\">\n"
- " <arg direction=\"out\" type=\"(so)\"/>\n"
- " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " </interface>\n"
- );
-
- static const QLatin1String actionIntrospection(
- " <interface name=\"org.a11y.atspi.Action\">\n"
- " <property access=\"read\" type=\"i\" name=\"NActions\"/>\n"
- " <method name=\"GetDescription\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " </method>\n"
- " <method name=\"GetName\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " </method>\n"
- " <method name=\"GetKeyBinding\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " </method>\n"
- " <method name=\"GetActions\">\n"
- " <arg direction=\"out\" type=\"a(sss)\" name=\"index\"/>\n"
- " <annotation value=\"QSpiActionArray\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"DoAction\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " </interface>\n"
- );
-
- static const QLatin1String applicationIntrospection(
- " <interface name=\"org.a11y.atspi.Application\">\n"
- " <property access=\"read\" type=\"s\" name=\"ToolkitName\"/>\n"
- " <property access=\"read\" type=\"s\" name=\"Version\"/>\n"
- " <property access=\"readwrite\" type=\"i\" name=\"Id\"/>\n"
- " <method name=\"GetLocale\">\n"
- " <arg direction=\"in\" type=\"u\" name=\"lctype\"/>\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " </method>\n"
- " <method name=\"GetApplicationBusAddress\">\n"
- " <arg direction=\"out\" type=\"s\" name=\"address\"/>\n"
- " </method>\n"
- " </interface>\n"
- );
-
- static const QLatin1String componentIntrospection(
- " <interface name=\"org.a11y.atspi.Component\">\n"
- " <method name=\"Contains\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"y\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"coord_type\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"GetAccessibleAtPoint\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"y\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"coord_type\"/>\n"
- " <arg direction=\"out\" type=\"(so)\"/>\n"
- " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetExtents\">\n"
- " <arg direction=\"in\" type=\"u\" name=\"coord_type\"/>\n"
- " <arg direction=\"out\" type=\"(iiii)\"/>\n"
- " <annotation value=\"QSpiRect\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetPosition\">\n"
- " <arg direction=\"in\" type=\"u\" name=\"coord_type\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"x\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"y\"/>\n"
- " </method>\n"
- " <method name=\"GetSize\">\n"
- " <arg direction=\"out\" type=\"i\" name=\"width\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"height\"/>\n"
- " </method>\n"
- " <method name=\"GetLayer\">\n"
- " <arg direction=\"out\" type=\"u\"/>\n"
- " </method>\n"
- " <method name=\"GetMDIZOrder\">\n"
- " <arg direction=\"out\" type=\"n\"/>\n"
- " </method>\n"
- " <method name=\"GrabFocus\">\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"GetAlpha\">\n"
- " <arg direction=\"out\" type=\"d\"/>\n"
- " </method>\n"
- " <method name=\"SetExtents\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"y\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"width\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"height\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"coord_type\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"SetPosition\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"y\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"coord_type\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"SetSize\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"width\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"height\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " </interface>\n"
- );
-
- static const QLatin1String editableTextIntrospection(
- " <interface name=\"org.a11y.atspi.EditableText\">\n"
- " <method name=\"SetTextContents\">\n"
- " <arg direction=\"in\" type=\"s\" name=\"newContents\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"InsertText\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"position\"/>\n"
- " <arg direction=\"in\" type=\"s\" name=\"text\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"length\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"CopyText\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"startPos\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"endPos\"/>\n"
- " </method>\n"
- " <method name=\"CutText\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"startPos\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"endPos\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"DeleteText\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"startPos\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"endPos\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"PasteText\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"position\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " </interface>\n"
- );
-
- static const QLatin1String tableIntrospection(
- " <interface name=\"org.a11y.atspi.Table\">\n"
- " <property access=\"read\" type=\"i\" name=\"NRows\"/>\n"
- " <property access=\"read\" type=\"i\" name=\"NColumns\"/>\n"
- " <property access=\"read\" type=\"(so)\" name=\"Caption\">\n"
- " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName\"/>\n"
- " </property>\n"
- " <property access=\"read\" type=\"(so)\" name=\"Summary\">\n"
- " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName\"/>\n"
- " </property>\n"
- " <property access=\"read\" type=\"i\" name=\"NSelectedRows\"/>\n"
- " <property access=\"read\" type=\"i\" name=\"NSelectedColumns\"/>\n"
- " <method name=\"GetAccessibleAt\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"row\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"column\"/>\n"
- " <arg direction=\"out\" type=\"(so)\"/>\n"
- " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetIndexAt\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"row\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"column\"/>\n"
- " <arg direction=\"out\" type=\"i\"/>\n"
- " </method>\n"
- " <method name=\"GetRowAtIndex\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
- " <arg direction=\"out\" type=\"i\"/>\n"
- " </method>\n"
- " <method name=\"GetColumnAtIndex\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
- " <arg direction=\"out\" type=\"i\"/>\n"
- " </method>\n"
- " <method name=\"GetRowDescription\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"row\"/>\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " </method>\n"
- " <method name=\"GetColumnDescription\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"column\"/>\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " </method>\n"
- " <method name=\"GetRowExtentAt\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"row\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"column\"/>\n"
- " <arg direction=\"out\" type=\"i\"/>\n"
- " </method>\n"
- " <method name=\"GetColumnExtentAt\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"row\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"column\"/>\n"
- " <arg direction=\"out\" type=\"i\"/>\n"
- " </method>\n"
- " <method name=\"GetRowHeader\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"row\"/>\n"
- " <arg direction=\"out\" type=\"(so)\"/>\n"
- " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetColumnHeader\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"column\"/>\n"
- " <arg direction=\"out\" type=\"(so)\"/>\n"
- " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetSelectedRows\">\n"
- " <arg direction=\"out\" type=\"ai\"/>\n"
- " <annotation value=\"QSpiIntList\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetSelectedColumns\">\n"
- " <arg direction=\"out\" type=\"ai\"/>\n"
- " <annotation value=\"QSpiIntList\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"IsRowSelected\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"row\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"IsColumnSelected\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"column\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"IsSelected\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"row\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"column\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"AddRowSelection\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"row\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"AddColumnSelection\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"column\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"RemoveRowSelection\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"row\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"RemoveColumnSelection\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"column\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"GetRowColumnExtentsAtIndex\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"row\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"col\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"row_extents\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"col_extents\"/>\n"
- " <arg direction=\"out\" type=\"b\" name=\"is_selected\"/>\n"
- " </method>\n"
- " </interface>\n"
- );
-
- static const QLatin1String textIntrospection(
- " <interface name=\"org.a11y.atspi.Text\">\n"
- " <property access=\"read\" type=\"i\" name=\"CharacterCount\"/>\n"
- " <property access=\"read\" type=\"i\" name=\"CaretOffset\"/>\n"
- " <method name=\"GetText\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"startOffset\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"endOffset\"/>\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " </method>\n"
- " <method name=\"SetCaretOffset\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"offset\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"GetTextBeforeOffset\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"offset\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"type\"/>\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"startOffset\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"endOffset\"/>\n"
- " </method>\n"
- " <method name=\"GetTextAtOffset\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"offset\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"type\"/>\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"startOffset\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"endOffset\"/>\n"
- " </method>\n"
- " <method name=\"GetTextAfterOffset\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"offset\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"type\"/>\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"startOffset\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"endOffset\"/>\n"
- " </method>\n"
- " <method name=\"GetCharacterAtOffset\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"offset\"/>\n"
- " <arg direction=\"out\" type=\"i\"/>\n"
- " </method>\n"
- " <method name=\"GetAttributeValue\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"offset\"/>\n"
- " <arg direction=\"in\" type=\"s\" name=\"attributeName\"/>\n"
- " <arg direction=\"out\" type=\"s\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"startOffset\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"endOffset\"/>\n"
- " <arg direction=\"out\" type=\"b\" name=\"defined\"/>\n"
- " </method>\n"
- " <method name=\"GetAttributes\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"offset\"/>\n"
- " <arg direction=\"out\" type=\"a{ss}\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"startOffset\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"endOffset\"/>\n"
- " <annotation value=\"QSpiAttributeSet\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetDefaultAttributes\">\n"
- " <arg direction=\"out\" type=\"a{ss}\"/>\n"
- " <annotation value=\"QSpiAttributeSet\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetCharacterExtents\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"offset\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"x\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"y\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"width\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"height\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"coordType\"/>\n"
- " </method>\n"
- " <method name=\"GetOffsetAtPoint\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"y\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"coordType\"/>\n"
- " <arg direction=\"out\" type=\"i\"/>\n"
- " </method>\n"
- " <method name=\"GetNSelections\">\n"
- " <arg direction=\"out\" type=\"i\"/>\n"
- " <method name=\"GetSelection\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"selectionNum\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"startOffset\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"endOffset\"/>\n"
- " </method>\n"
- " <method name=\"AddSelection\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"startOffset\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"endOffset\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"RemoveSelection\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"selectionNum\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"SetSelection\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"selectionNum\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"startOffset\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"endOffset\"/>\n"
- " <arg direction=\"out\" type=\"b\"/>\n"
- " </method>\n"
- " <method name=\"GetRangeExtents\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"startOffset\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"endOffset\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"x\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"y\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"width\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"height\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"coordType\"/>\n"
- " </method>\n"
- " <method name=\"GetBoundedRanges\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"y\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"width\"/>\n"
- " <arg direction=\"in\" type=\"i\" name=\"height\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"coordType\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"xClipType\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"yClipType\"/>\n"
- " <arg direction=\"out\" type=\"a(iisv)\"/>\n"
- " <annotation value=\"QSpiRangeList\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetAttributeRun\">\n"
- " <arg direction=\"in\" type=\"i\" name=\"offset\"/>\n"
- " <arg direction=\"in\" type=\"b\" name=\"includeDefaults\"/>\n"
- " <arg direction=\"out\" type=\"a{ss}\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"startOffset\"/>\n"
- " <arg direction=\"out\" type=\"i\" name=\"endOffset\"/>\n"
- " <annotation value=\"QSpiAttributeSet\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " <method name=\"GetDefaultAttributeSet\">\n"
- " <arg direction=\"out\" type=\"a{ss}\"/>\n"
- " <annotation value=\"QSpiAttributeSet\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
- " </method>\n"
- " </interface>\n"
- );
-
- static const QLatin1String valueIntrospection(
- " <interface name=\"org.a11y.atspi.Value\">\n"
- " <property access=\"read\" type=\"d\" name=\"MinimumValue\"/>\n"
- " <property access=\"read\" type=\"d\" name=\"MaximumValue\"/>\n"
- " <property access=\"read\" type=\"d\" name=\"MinimumIncrement\"/>\n"
- " <property access=\"readwrite\" type=\"d\" name=\"CurrentValue\"/>\n"
- " <method name=\"SetCurrentValue\">\n"
- " <arg direction=\"in\" type=\"d\" name=\"value\"/>\n"
- " </method>\n"
- " </interface>\n"
- );
-
- QAccessibleInterface * interface = interfaceFromPath(path);
- if (!interface) {
- qCDebug(lcAccessibilityAtspi) << "WARNING Qt AtSpiAdaptor: Could not find accessible on path: " << path;
- return QString();
- }
-
- QStringList interfaces = accessibleInterfaces(interface);
-
- QString xml;
- xml.append(accessibleIntrospection);
-
- if (interfaces.contains(QLatin1String(ATSPI_DBUS_INTERFACE_COMPONENT)))
- xml.append(componentIntrospection);
- if (interfaces.contains(QLatin1String(ATSPI_DBUS_INTERFACE_TEXT)))
- xml.append(textIntrospection);
- if (interfaces.contains(QLatin1String(ATSPI_DBUS_INTERFACE_EDITABLE_TEXT)))
- xml.append(editableTextIntrospection);
- if (interfaces.contains(QLatin1String(ATSPI_DBUS_INTERFACE_ACTION)))
- xml.append(actionIntrospection);
- if (interfaces.contains(QLatin1String(ATSPI_DBUS_INTERFACE_TABLE)))
- xml.append(tableIntrospection);
- if (interfaces.contains(QLatin1String(ATSPI_DBUS_INTERFACE_VALUE)))
- xml.append(valueIntrospection);
- if (path == QLatin1String(QSPI_OBJECT_PATH_ROOT))
- xml.append(applicationIntrospection);
-
- return xml;
-}
-
-void AtSpiAdaptor::setBitFlag(const QString &flag)
-{
- Q_ASSERT(flag.size());
-
- // assume we don't get nonsense - look at first letter only
- switch (flag.at(0).toLower().toLatin1()) {
- case 'o': {
- if (flag.size() <= 8) { // Object::
- sendObject = 1;
- } else { // Object:Foo:Bar
- QString right = flag.mid(7);
- if (false) {
- } else if (right.startsWith(QLatin1String("ActiveDescendantChanged"))) {
- sendObject_active_descendant_changed = 1;
- } else if (right.startsWith(QLatin1String("AttributesChanged"))) {
- sendObject_attributes_changed = 1;
- } else if (right.startsWith(QLatin1String("BoundsChanged"))) {
- sendObject_bounds_changed = 1;
- } else if (right.startsWith(QLatin1String("ChildrenChanged"))) {
- sendObject_children_changed = 1;
- } else if (right.startsWith(QLatin1String("ColumnDeleted"))) {
- sendObject_column_deleted = 1;
- } else if (right.startsWith(QLatin1String("ColumnInserted"))) {
- sendObject_column_inserted = 1;
- } else if (right.startsWith(QLatin1String("ColumnReordered"))) {
- sendObject_column_reordered = 1;
- } else if (right.startsWith(QLatin1String("LinkSelected"))) {
- sendObject_link_selected = 1;
- } else if (right.startsWith(QLatin1String("ModelChanged"))) {
- sendObject_model_changed = 1;
- } else if (right.startsWith(QLatin1String("PropertyChange"))) {
- if (right == QLatin1String("PropertyChange:AccessibleDescription")) {
- sendObject_property_change_accessible_description = 1;
- } else if (right == QLatin1String("PropertyChange:AccessibleName")) {
- sendObject_property_change_accessible_name = 1;
- } else if (right == QLatin1String("PropertyChange:AccessibleParent")) {
- sendObject_property_change_accessible_parent = 1;
- } else if (right == QLatin1String("PropertyChange:AccessibleRole")) {
- sendObject_property_change_accessible_role = 1;
- } else if (right == QLatin1String("PropertyChange:TableCaption")) {
- sendObject_property_change_accessible_table_caption = 1;
- } else if (right == QLatin1String("PropertyChange:TableColumnDescription")) {
- sendObject_property_change_accessible_table_column_description = 1;
- } else if (right == QLatin1String("PropertyChange:TableColumnHeader")) {
- sendObject_property_change_accessible_table_column_header = 1;
- } else if (right == QLatin1String("PropertyChange:TableRowDescription")) {
- sendObject_property_change_accessible_table_row_description = 1;
- } else if (right == QLatin1String("PropertyChange:TableRowHeader")) {
- sendObject_property_change_accessible_table_row_header = 1;
- } else if (right == QLatin1String("PropertyChange:TableSummary")) {
- sendObject_property_change_accessible_table_summary = 1;
- } else if (right == QLatin1String("PropertyChange:AccessibleValue")) {
- sendObject_property_change_accessible_value = 1;
- } else {
- sendObject_property_change = 1;
- }
- } else if (right.startsWith(QLatin1String("RowDeleted"))) {
- sendObject_row_deleted = 1;
- } else if (right.startsWith(QLatin1String("RowInserted"))) {
- sendObject_row_inserted = 1;
- } else if (right.startsWith(QLatin1String("RowReordered"))) {
- sendObject_row_reordered = 1;
- } else if (right.startsWith(QLatin1String("SelectionChanged"))) {
- sendObject_selection_changed = 1;
- } else if (right.startsWith(QLatin1String("StateChanged"))) {
- sendObject_state_changed = 1;
- } else if (right.startsWith(QLatin1String("TextAttributesChanged"))) {
- sendObject_text_attributes_changed = 1;
- } else if (right.startsWith(QLatin1String("TextBoundsChanged"))) {
- sendObject_text_bounds_changed = 1;
- } else if (right.startsWith(QLatin1String("TextCaretMoved"))) {
- sendObject_text_caret_moved = 1;
- } else if (right.startsWith(QLatin1String("TextChanged"))) {
- sendObject_text_changed = 1;
- } else if (right.startsWith(QLatin1String("TextSelectionChanged"))) {
- sendObject_text_selection_changed = 1;
- } else if (right.startsWith(QLatin1String("ValueChanged"))) {
- sendObject_value_changed = 1;
- } else if (right.startsWith(QLatin1String("VisibleDataChanged"))
- || right.startsWith(QLatin1String("VisibledataChanged"))) { // typo in libatspi
- sendObject_visible_data_changed = 1;
- } else {
- qCDebug(lcAccessibilityAtspi) << "WARNING: subscription string not handled:" << flag;
- }
- }
- break;
- }
- case 'w': { // window
- if (flag.size() <= 8) {
- sendWindow = 1;
- } else { // object:Foo:Bar
- QString right = flag.mid(7);
- if (false) {
- } else if (right.startsWith(QLatin1String("Activate"))) {
- sendWindow_activate = 1;
- } else if (right.startsWith(QLatin1String("Close"))) {
- sendWindow_close= 1;
- } else if (right.startsWith(QLatin1String("Create"))) {
- sendWindow_create = 1;
- } else if (right.startsWith(QLatin1String("Deactivate"))) {
- sendWindow_deactivate = 1;
- } else if (right.startsWith(QLatin1String("Lower"))) {
- sendWindow_lower = 1;
- } else if (right.startsWith(QLatin1String("Maximize"))) {
- sendWindow_maximize = 1;
- } else if (right.startsWith(QLatin1String("Minimize"))) {
- sendWindow_minimize = 1;
- } else if (right.startsWith(QLatin1String("Move"))) {
- sendWindow_move = 1;
- } else if (right.startsWith(QLatin1String("Raise"))) {
- sendWindow_raise = 1;
- } else if (right.startsWith(QLatin1String("Reparent"))) {
- sendWindow_reparent = 1;
- } else if (right.startsWith(QLatin1String("Resize"))) {
- sendWindow_resize = 1;
- } else if (right.startsWith(QLatin1String("Restore"))) {
- sendWindow_restore = 1;
- } else if (right.startsWith(QLatin1String("Restyle"))) {
- sendWindow_restyle = 1;
- } else if (right.startsWith(QLatin1String("Shade"))) {
- sendWindow_shade = 1;
- } else if (right.startsWith(QLatin1String("Unshade"))) {
- sendWindow_unshade = 1;
- } else if (right.startsWith(QLatin1String("DesktopCreate"))) {
- // ignore this one
- } else if (right.startsWith(QLatin1String("DesktopDestroy"))) {
- // ignore this one
- } else {
- qCDebug(lcAccessibilityAtspi) << "WARNING: subscription string not handled:" << flag;
- }
- }
- break;
- }
- case 'f': {
- sendFocus = 1;
- break;
- }
- case 'd': { // document is not implemented
- break;
- }
- case 't': { // terminal is not implemented
- break;
- }
- case 'm': { // mouse* is handled in a different way by the gnome atspi stack
- break;
- }
- default:
- qCDebug(lcAccessibilityAtspi) << "WARNING: subscription string not handled:" << flag;
- }
-}
-
-/*!
- Checks via dbus which events should be sent.
- */
-void AtSpiAdaptor::updateEventListeners()
-{
- QDBusMessage m = QDBusMessage::createMethodCall(QLatin1String("org.a11y.atspi.Registry"),
- QLatin1String("/org/a11y/atspi/registry"),
- QLatin1String("org.a11y.atspi.Registry"), QLatin1String("GetRegisteredEvents"));
- QDBusReply<QSpiEventListenerArray> listenersReply = m_dbus->connection().call(m);
- if (listenersReply.isValid()) {
- const QSpiEventListenerArray evList = listenersReply.value();
- for (const QSpiEventListener &ev : evList)
- setBitFlag(ev.eventName);
- m_applicationAdaptor->sendEvents(!evList.isEmpty());
- } else {
- qCDebug(lcAccessibilityAtspi) << "Could not query active accessibility event listeners.";
- }
-}
-
-void AtSpiAdaptor::eventListenerDeregistered(const QString &/*bus*/, const QString &/*path*/)
-{
-// qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::eventListenerDeregistered: " << bus << path;
- updateEventListeners();
-}
-
-void AtSpiAdaptor::eventListenerRegistered(const QString &/*bus*/, const QString &/*path*/)
-{
-// qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::eventListenerRegistered: " << bus << path;
- updateEventListeners();
-}
-
-/*!
- This slot needs to get called when a \a window has be activated or deactivated (become focused).
- When \a active is true, the window just received focus, otherwise it lost the focus.
- */
-void AtSpiAdaptor::windowActivated(QObject* window, bool active)
-{
- if (!(sendWindow || sendWindow_activate))
- return;
-
- QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(window);
- Q_ASSERT(iface);
- Q_ASSERT(!active || iface->isValid());
-
- QString windowTitle;
- // in dtor it may be invalid
- if (iface->isValid())
- windowTitle = iface->text(QAccessible::Name);
-
- QDBusVariant data;
- data.setVariant(windowTitle);
-
- QVariantList args = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(data));
-
- QString status = active ? QLatin1String("Activate") : QLatin1String("Deactivate");
- QString path = pathForObject(window);
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_WINDOW), status, args);
-
- QVariantList stateArgs = packDBusSignalArguments(QLatin1String("active"), active ? 1 : 0, 0, variantForPath(path));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("StateChanged"), stateArgs);
-}
-
-QVariantList AtSpiAdaptor::packDBusSignalArguments(const QString &type, int data1, int data2, const QVariant &variantData) const
-{
- QVariantList arguments;
- arguments << type << data1 << data2 << variantData
- << QVariant::fromValue(QSpiObjectReference(m_dbus->connection(), QDBusObjectPath(QSPI_OBJECT_PATH_ROOT)));
- return arguments;
-}
-
-QVariant AtSpiAdaptor::variantForPath(const QString &path) const
-{
- QDBusVariant data;
- data.setVariant(QVariant::fromValue(QSpiObjectReference(m_dbus->connection(), QDBusObjectPath(path))));
- return QVariant::fromValue(data);
-}
-
-bool AtSpiAdaptor::sendDBusSignal(const QString &path, const QString &interface, const QString &signalName, const QVariantList &arguments) const
-{
- QDBusMessage message = QDBusMessage::createSignal(path, interface, signalName);
- message.setArguments(arguments);
- return m_dbus->connection().send(message);
-}
-
-QAccessibleInterface *AtSpiAdaptor::interfaceFromPath(const QString& dbusPath) const
-{
- if (dbusPath == QLatin1String(QSPI_OBJECT_PATH_ROOT))
- return QAccessible::queryAccessibleInterface(qApp);
-
- QStringList parts = dbusPath.split(QLatin1Char('/'));
- if (parts.size() != 6) {
- qCDebug(lcAccessibilityAtspi) << "invalid path: " << dbusPath;
- return 0;
- }
-
- QString objectString = parts.at(5);
- QAccessible::Id id = objectString.toUInt();
-
- // The id is always in the range [INT_MAX+1, UINT_MAX]
- if ((int)id >= 0)
- qCWarning(lcAccessibilityAtspi) << "No accessible object found for id: " << id;
-
- return QAccessible::accessibleInterface(id);
-}
-
-void AtSpiAdaptor::notifyStateChange(QAccessibleInterface *interface, const QString &state, int value)
-{
- QString path = pathForInterface(interface);
- QVariantList stateArgs = packDBusSignalArguments(state, value, 0, variantForPath(path));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("StateChanged"), stateArgs);
-}
-
-
-/*!
- This function gets called when Qt notifies about accessibility updates.
-*/
-void AtSpiAdaptor::notify(QAccessibleEvent *event)
-{
- switch (event->type()) {
- case QAccessible::ObjectCreated:
- if (sendObject || sendObject_children_changed)
- notifyAboutCreation(event->accessibleInterface());
- break;
- case QAccessible::ObjectShow: {
- if (sendObject || sendObject_state_changed) {
- notifyStateChange(event->accessibleInterface(), QLatin1String("showing"), 1);
- }
- break;
- }
- case QAccessible::ObjectHide: {
- if (sendObject || sendObject_state_changed) {
- notifyStateChange(event->accessibleInterface(), QLatin1String("showing"), 0);
- }
- break;
- }
- case QAccessible::ObjectDestroyed: {
- if (sendObject || sendObject_state_changed)
- 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());
- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("PropertyChange"), args);
- }
- break;
- }
- case QAccessible::DescriptionChanged: {
- if (sendObject || sendObject_property_change || sendObject_property_change_accessible_description) {
- QString path = pathForInterface(event->accessibleInterface());
- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-description"), 0, 0, variantForPath(path));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("PropertyChange"), args);
- }
- break;
- }
- case QAccessible::Focus: {
- if (sendFocus || sendObject || sendObject_state_changed)
- sendFocusChanged(event->accessibleInterface());
- break;
- }
- case QAccessible::TextInserted:
- case QAccessible::TextRemoved:
- case QAccessible::TextUpdated: {
- if (sendObject || sendObject_text_changed) {
- QAccessibleInterface * iface = event->accessibleInterface();
- if (!iface || !iface->textInterface()) {
- qCDebug(lcAccessibilityAtspi) << "Received text event for invalid interface.";
- return;
- }
- QString path = pathForInterface(iface);
-
- int changePosition = 0;
- int cursorPosition = 0;
- QString textRemoved;
- QString textInserted;
-
- if (event->type() == QAccessible::TextInserted) {
- QAccessibleTextInsertEvent *textEvent = static_cast<QAccessibleTextInsertEvent*>(event);
- textInserted = textEvent->textInserted();
- changePosition = textEvent->changePosition();
- cursorPosition = textEvent->cursorPosition();
- } else if (event->type() == QAccessible::TextRemoved) {
- QAccessibleTextRemoveEvent *textEvent = static_cast<QAccessibleTextRemoveEvent*>(event);
- textRemoved = textEvent->textRemoved();
- changePosition = textEvent->changePosition();
- cursorPosition = textEvent->cursorPosition();
- } else if (event->type() == QAccessible::TextUpdated) {
- QAccessibleTextUpdateEvent *textEvent = static_cast<QAccessibleTextUpdateEvent*>(event);
- textInserted = textEvent->textInserted();
- textRemoved = textEvent->textRemoved();
- changePosition = textEvent->changePosition();
- cursorPosition = textEvent->cursorPosition();
- }
-
- QDBusVariant data;
-
- if (!textRemoved.isEmpty()) {
- data.setVariant(QVariant::fromValue(textRemoved));
- QVariantList args = packDBusSignalArguments(QLatin1String("delete"), changePosition, textRemoved.length(), QVariant::fromValue(data));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("TextChanged"), args);
- }
-
- if (!textInserted.isEmpty()) {
- data.setVariant(QVariant::fromValue(textInserted));
- QVariantList args = packDBusSignalArguments(QLatin1String("insert"), changePosition, textInserted.length(), QVariant::fromValue(data));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("TextChanged"), args);
- }
-
- // send a cursor update
- Q_UNUSED(cursorPosition)
-// QDBusVariant cursorData;
-// cursorData.setVariant(QVariant::fromValue(cursorPosition));
-// QVariantList args = packDBusSignalArguments(QString(), cursorPosition, 0, QVariant::fromValue(cursorData));
-// sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
-// QLatin1String("TextCaretMoved"), args);
- }
- break;
- }
- case QAccessible::TextCaretMoved: {
- if (sendObject || sendObject_text_caret_moved) {
- QAccessibleInterface * iface = event->accessibleInterface();
- if (!iface || !iface->textInterface()) {
- qCWarning(lcAccessibilityAtspi) << "Sending TextCaretMoved from object that does not implement text interface: " << iface;
- return;
- }
-
- QString path = pathForInterface(iface);
- QDBusVariant cursorData;
- int pos = iface->textInterface()->cursorPosition();
- cursorData.setVariant(QVariant::fromValue(pos));
- QVariantList args = packDBusSignalArguments(QString(), pos, 0, QVariant::fromValue(cursorData));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("TextCaretMoved"), args);
- }
- break;
- }
- case QAccessible::TextSelectionChanged: {
- if (sendObject || sendObject_text_selection_changed) {
- QAccessibleInterface * iface = event->accessibleInterface();
- QString path = pathForInterface(iface);
- QVariantList args = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(QDBusVariant(QVariant(QString()))));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("TextSelectionChanged"), args);
- }
- break;
- }
- case QAccessible::ValueChanged: {
- if (sendObject || sendObject_value_changed || sendObject_property_change_accessible_value) {
- QAccessibleInterface * iface = event->accessibleInterface();
- if (!iface) {
- qCWarning(lcAccessibilityAtspi) << "ValueChanged event from invalid accessible.";
- return;
- }
- if (iface->valueInterface()) {
- QString path = pathForInterface(iface);
- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-value"), 0, 0, variantForPath(path));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("PropertyChange"), args);
- } else if (iface->role() == QAccessible::ComboBox) {
- // Combo Box with AT-SPI likes to be special
- // It requires a name-change to update caches and then selection-changed
- QString path = pathForInterface(iface);
- QVariantList args1 = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("PropertyChange"), args1);
- QVariantList args2 = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(QDBusVariant(QVariant(0))));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("SelectionChanged"), args2);
- } else {
- qCWarning(lcAccessibilityAtspi) << "ValueChanged event and no ValueInterface or ComboBox: " << iface;
- }
- }
- break;
- }
- case QAccessible::SelectionAdd:
- case QAccessible::SelectionRemove:
- case QAccessible::Selection: {
- QAccessibleInterface * iface = event->accessibleInterface();
- if (!iface) {
- qCWarning(lcAccessibilityAtspi) << "Selection event from invalid accessible.";
- return;
- }
- QString path = pathForInterface(iface);
- int selected = iface->state().selected ? 1 : 0;
- QVariantList stateArgs = packDBusSignalArguments(QLatin1String("selected"), selected, 0, variantForPath(path));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("StateChanged"), stateArgs);
- break;
- }
-
- case QAccessible::StateChanged: {
- if (sendObject || sendObject_state_changed || sendWindow || sendWindow_activate) {
- QAccessible::State stateChange = static_cast<QAccessibleStateChangeEvent*>(event)->changedStates();
- if (stateChange.checked) {
- QAccessibleInterface * iface = event->accessibleInterface();
- if (!iface) {
- qCWarning(lcAccessibilityAtspi) << "StateChanged event from invalid accessible.";
- return;
- }
- int checked = iface->state().checked;
- notifyStateChange(iface, QLatin1String("checked"), checked);
- } else if (stateChange.active) {
- 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 = isActive ? QLatin1String("Activate") : QLatin1String("Deactivate");
- QString path = pathForInterface(iface);
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_WINDOW), status, args);
- notifyStateChange(iface, QLatin1String("active"), isActive);
- } else if (stateChange.disabled) {
- QAccessibleInterface *iface = event->accessibleInterface();
- QAccessible::State state = iface->state();
- bool enabled = !state.disabled;
-
- notifyStateChange(iface, QLatin1String("enabled"), enabled);
- notifyStateChange(iface, QLatin1String("sensitive"), enabled);
- }
- }
- break;
- }
- // For now we ignore these events
- case QAccessible::TableModelChanged:
- // For tables, setting manages_descendants should
- // indicate to the client that it cannot cache these
- // interfaces.
- case QAccessible::ParentChanged:
- case QAccessible::DialogStart:
- case QAccessible::DialogEnd:
- case QAccessible::PopupMenuStart:
- case QAccessible::PopupMenuEnd:
- case QAccessible::SoundPlayed:
- case QAccessible::Alert:
- case QAccessible::ForegroundChanged:
- case QAccessible::MenuStart:
- case QAccessible::MenuEnd:
- case QAccessible::ContextHelpStart:
- case QAccessible::ContextHelpEnd:
- case QAccessible::DragDropStart:
- case QAccessible::DragDropEnd:
- case QAccessible::ScrollingStart:
- case QAccessible::ScrollingEnd:
- case QAccessible::MenuCommand:
- case QAccessible::ActionChanged:
- case QAccessible::ActiveDescendantChanged:
- case QAccessible::AttributeChanged:
- case QAccessible::DocumentContentChanged:
- case QAccessible::DocumentLoadComplete:
- case QAccessible::DocumentLoadStopped:
- case QAccessible::DocumentReload:
- case QAccessible::HyperlinkEndIndexChanged:
- case QAccessible::HyperlinkNumberOfAnchorsChanged:
- case QAccessible::HyperlinkSelectedLinkChanged:
- case QAccessible::HypertextLinkActivated:
- case QAccessible::HypertextLinkSelected:
- case QAccessible::HyperlinkStartIndexChanged:
- case QAccessible::HypertextChanged:
- case QAccessible::HypertextNLinksChanged:
- case QAccessible::ObjectAttributeChanged:
- case QAccessible::PageChanged:
- case QAccessible::SectionChanged:
- case QAccessible::TableCaptionChanged:
- case QAccessible::TableColumnDescriptionChanged:
- case QAccessible::TableColumnHeaderChanged:
- case QAccessible::TableRowDescriptionChanged:
- case QAccessible::TableRowHeaderChanged:
- case QAccessible::TableSummaryChanged:
- case QAccessible::TextAttributeChanged:
- case QAccessible::TextColumnChanged:
- case QAccessible::VisibleDataChanged:
- case QAccessible::SelectionWithin:
- case QAccessible::LocationChanged:
- case QAccessible::HelpChanged:
- case QAccessible::DefaultActionChanged:
- case QAccessible::AcceleratorChanged:
- case QAccessible::InvalidEvent:
- break;
- }
-}
-
-void AtSpiAdaptor::sendFocusChanged(QAccessibleInterface *interface) const
-{
- static QString lastFocusPath;
- // "remove" old focus
- if (!lastFocusPath.isEmpty()) {
- QVariantList stateArgs = packDBusSignalArguments(QLatin1String("focused"), 0, 0, variantForPath(lastFocusPath));
- sendDBusSignal(lastFocusPath, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("StateChanged"), stateArgs);
- }
- // send new focus
- {
- QString path = pathForInterface(interface);
-
- QVariantList stateArgs = packDBusSignalArguments(QLatin1String("focused"), 1, 0, variantForPath(path));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
- QLatin1String("StateChanged"), stateArgs);
-
- QVariantList focusArgs = packDBusSignalArguments(QString(), 0, 0, variantForPath(path));
- sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_FOCUS),
- QLatin1String("Focus"), focusArgs);
- lastFocusPath = path;
- }
-}
-
-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
-// cache->emitAddAccessible(accessible->getCacheItem());
-
- // notify about the new child of our parent
- QAccessibleInterface * parent = interface->parent();
- if (!parent) {
- qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::notifyAboutCreation: Could not find parent for " << interface->object();
- return;
- }
- QString path = pathForInterface(interface);
- int childCount = parent->childCount();
- QString parentPath = pathForInterface(parent);
- QVariantList args = packDBusSignalArguments(QLatin1String("add"), childCount, 0, variantForPath(path));
- sendDBusSignal(parentPath, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), QLatin1String("ChildrenChanged"), args);
-}
-
-void AtSpiAdaptor::notifyAboutDestruction(QAccessibleInterface *interface) const
-{
- if (!interface || !interface->isValid())
- return;
-
- QAccessibleInterface * parent = interface->parent();
- if (!parent) {
- qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::notifyAboutDestruction: Could not find parent for " << interface->object();
- return;
- }
- QString path = pathForInterface(interface);
-
- // this is in the destructor. we have no clue which child we used to be.
- // FIXME
- int childIndex = -1;
- // if (child) {
- // childIndex = child;
- // } else {
- // childIndex = parent->indexOfChild(interface);
- // }
-
- QString parentPath = pathForInterface(parent);
- QVariantList args = packDBusSignalArguments(QLatin1String("remove"), childIndex, 0, variantForPath(path));
- sendDBusSignal(parentPath, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), QLatin1String("ChildrenChanged"), args);
-}
-
-/*!
- Handle incoming DBus message.
- This function dispatches the dbus message to the right interface handler.
- */
-bool AtSpiAdaptor::handleMessage(const QDBusMessage &message, const QDBusConnection &connection)
-{
- // get accessible interface
- QAccessibleInterface * accessible = interfaceFromPath(message.path());
- if (!accessible) {
- qCDebug(lcAccessibilityAtspi) << "WARNING Qt AtSpiAdaptor: Could not find accessible on path: " << message.path();
- return false;
- }
- if (!accessible->isValid()) {
- qCWarning(lcAccessibilityAtspi) << "WARNING Qt AtSpiAdaptor: Accessible invalid: " << accessible << message.path();
- return false;
- }
-
- QString interface = message.interface();
- QString function = message.member();
-
- // qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::handleMessage: " << interface << function;
-
- if (function == QLatin1String("Introspect")) {
- //introspect(message.path());
- return false;
- }
-
- // handle properties like regular functions
- if (interface == QLatin1String("org.freedesktop.DBus.Properties")) {
- interface = message.arguments().at(0).toString();
- // Get/Set + Name
- function = message.member() + message.arguments().at(1).toString();
- }
-
- // switch interface to call
- if (interface == QLatin1String(ATSPI_DBUS_INTERFACE_ACCESSIBLE))
- return accessibleInterface(accessible, function, message, connection);
- if (interface == QLatin1String(ATSPI_DBUS_INTERFACE_APPLICATION))
- return applicationInterface(accessible, function, message, connection);
- if (interface == QLatin1String(ATSPI_DBUS_INTERFACE_COMPONENT))
- return componentInterface(accessible, function, message, connection);
- if (interface == QLatin1String(ATSPI_DBUS_INTERFACE_ACTION))
- return actionInterface(accessible, function, message, connection);
- if (interface == QLatin1String(ATSPI_DBUS_INTERFACE_TEXT))
- return textInterface(accessible, function, message, connection);
- if (interface == QLatin1String(ATSPI_DBUS_INTERFACE_EDITABLE_TEXT))
- return editableTextInterface(accessible, function, message, connection);
- if (interface == QLatin1String(ATSPI_DBUS_INTERFACE_VALUE))
- return valueInterface(accessible, function, message, connection);
- if (interface == QLatin1String(ATSPI_DBUS_INTERFACE_TABLE))
- return tableInterface(accessible, function, message, connection);
-
- qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::handleMessage with unknown interface: " << message.path() << interface << function;
- return false;
-}
-
-// Application
-bool AtSpiAdaptor::applicationInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
-{
- if (message.path() != QLatin1String(ATSPI_DBUS_PATH_ROOT)) {
- qCDebug(lcAccessibilityAtspi) << "WARNING Qt AtSpiAdaptor: Could not find application interface for: " << message.path() << interface;
- return false;
- }
-
- if (function == QLatin1String("SetId")) {
- Q_ASSERT(message.signature() == QLatin1String("ssv"));
- QVariant value = qvariant_cast<QDBusVariant>(message.arguments().at(2)).variant();
-
- m_applicationId = value.toInt();
- return true;
- }
- if (function == QLatin1String("GetId")) {
- Q_ASSERT(message.signature() == QLatin1String("ss"));
- QDBusMessage reply = message.createReply(QVariant::fromValue(QDBusVariant(m_applicationId)));
- return connection.send(reply);
- }
- if (function == QLatin1String("GetToolkitName")) {
- Q_ASSERT(message.signature() == QLatin1String("ss"));
- QDBusMessage reply = message.createReply(QVariant::fromValue(QDBusVariant(QLatin1String("Qt"))));
- return connection.send(reply);
- }
- if (function == QLatin1String("GetVersion")) {
- Q_ASSERT(message.signature() == QLatin1String("ss"));
- QDBusMessage reply = message.createReply(QVariant::fromValue(QDBusVariant(QLatin1String(qVersion()))));
- return connection.send(reply);
- }
- if (function == QLatin1String("GetLocale")) {
- Q_ASSERT(message.signature() == QLatin1String("u"));
- QDBusMessage reply = message.createReply(QVariant::fromValue(QLocale().name()));
- return connection.send(reply);
- }
- qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::applicationInterface " << message.path() << interface << function;
- return false;
-}
-
-/*!
- Register this application as accessible on the accessibility DBus.
- */
-void AtSpiAdaptor::registerApplication()
-{
- OrgA11yAtspiSocketInterface *registry;
- registry = new OrgA11yAtspiSocketInterface(QLatin1String(QSPI_REGISTRY_NAME),
- QLatin1String(QSPI_OBJECT_PATH_ROOT), m_dbus->connection());
-
- QDBusPendingReply<QSpiObjectReference> reply;
- QSpiObjectReference ref = QSpiObjectReference(m_dbus->connection(), QDBusObjectPath(QSPI_OBJECT_PATH_ROOT));
- reply = registry->Embed(ref);
- reply.waitForFinished(); // TODO: make this async
- if (reply.isValid ()) {
- const QSpiObjectReference &socket = reply.value();
- accessibilityRegistry = QSpiObjectReference(socket);
- } else {
- qCDebug(lcAccessibilityAtspi) << "Error in contacting registry: "
- << reply.error().name()
- << reply.error().message();
- }
- delete registry;
-}
-
-// Accessible
-bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
-{
- if (function == QLatin1String("GetRole")) {
- sendReply(connection, message, (uint) getRole(interface));
- } else if (function == QLatin1String("GetName")) {
- sendReply(connection, message, QVariant::fromValue(QDBusVariant(interface->text(QAccessible::Name))));
- } else if (function == QLatin1String("GetRoleName")) {
- sendReply(connection, message, qSpiRoleMapping[interface->role()].name());
- } else if (function == QLatin1String("GetLocalizedRoleName")) {
- sendReply(connection, message, QVariant::fromValue(qSpiRoleMapping[interface->role()].localizedName()));
- } else if (function == QLatin1String("GetChildCount")) {
- sendReply(connection, message, QVariant::fromValue(QDBusVariant(interface->childCount())));
- } else if (function == QLatin1String("GetIndexInParent")) {
- int childIndex = -1;
- QAccessibleInterface * parent = interface->parent();
- if (parent) {
- childIndex = parent->indexOfChild(interface);
- if (childIndex < 0) {
- qCDebug(lcAccessibilityAtspi) << "GetIndexInParent get invalid index: " << childIndex << interface;
- }
- }
- sendReply(connection, message, childIndex);
- } else if (function == QLatin1String("GetParent")) {
- QString path;
- QAccessibleInterface * parent = interface->parent();
- if (!parent) {
- path = QLatin1String(ATSPI_DBUS_PATH_NULL);
- } else if (parent->role() == QAccessible::Application) {
- path = QLatin1String(ATSPI_DBUS_PATH_ROOT);
- } else {
- path = pathForInterface(parent);
- }
- // Parent is a property, so it needs to be wrapped inside an extra variant.
- sendReply(connection, message, QVariant::fromValue(
- QDBusVariant(QVariant::fromValue(QSpiObjectReference(connection, QDBusObjectPath(path))))));
- } else if (function == QLatin1String("GetChildAtIndex")) {
- const int index = message.arguments().at(0).toInt();
- if (index < 0) {
- sendReply(connection, message, QVariant::fromValue(
- QSpiObjectReference(connection, QDBusObjectPath(ATSPI_DBUS_PATH_NULL))));
- } else {
- QAccessibleInterface * childInterface = interface->child(index);
- sendReply(connection, message, QVariant::fromValue(
- QSpiObjectReference(connection, QDBusObjectPath(pathForInterface(childInterface)))));
- }
- } else if (function == QLatin1String("GetInterfaces")) {
- sendReply(connection, message, accessibleInterfaces(interface));
- } else if (function == QLatin1String("GetDescription")) {
- sendReply(connection, message, QVariant::fromValue(QDBusVariant(interface->text(QAccessible::Description))));
- } else if (function == QLatin1String("GetState")) {
- quint64 spiState = spiStatesFromQState(interface->state());
- if (interface->tableInterface()) {
- setSpiStateBit(&spiState, ATSPI_STATE_MANAGES_DESCENDANTS);
- }
- QAccessible::Role role = interface->role();
- if (role == QAccessible::TreeItem ||
- role == QAccessible::ListItem) {
- /* Transient means libatspi2 will not cache items.
- This is important because when adding/removing an item
- the cache becomes outdated and we don't change the paths of
- items in lists/trees/tables. */
- setSpiStateBit(&spiState, ATSPI_STATE_TRANSIENT);
- }
- sendReply(connection, message,
- QVariant::fromValue(spiStateSetFromSpiStates(spiState)));
- } else if (function == QLatin1String("GetAttributes")) {
- sendReply(connection, message, QVariant::fromValue(QSpiAttributeSet()));
- } else if (function == QLatin1String("GetRelationSet")) {
- sendReply(connection, message, QVariant::fromValue(relationSet(interface, connection)));
- } else if (function == QLatin1String("GetApplication")) {
- sendReply(connection, message, QVariant::fromValue(
- QSpiObjectReference(connection, QDBusObjectPath(QSPI_OBJECT_PATH_ROOT))));
- } else if (function == QLatin1String("GetChildren")) {
- QSpiObjectReferenceArray children;
- const int numChildren = interface->childCount();
- children.reserve(numChildren);
- for (int i = 0; i < numChildren; ++i) {
- QString childPath = pathForInterface(interface->child(i));
- QSpiObjectReference ref(connection, QDBusObjectPath(childPath));
- children << ref;
- }
- connection.send(message.createReply(QVariant::fromValue(children)));
- } else {
- qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::accessibleInterface does not implement " << function << message.path();
- return false;
- }
- return true;
-}
-
-AtspiRole AtSpiAdaptor::getRole(QAccessibleInterface *interface) const
-{
- if ((interface->role() == QAccessible::EditableText) && interface->state().passwordEdit)
- return ATSPI_ROLE_PASSWORD_TEXT;
- return qSpiRoleMapping[interface->role()].spiRole();
-}
-
-QStringList AtSpiAdaptor::accessibleInterfaces(QAccessibleInterface *interface) const
-{
- QStringList ifaces;
- qCDebug(lcAccessibilityAtspiCreation) << "AtSpiAdaptor::accessibleInterfaces create: " << interface->object();
- ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_ACCESSIBLE);
-
- if ( (!interface->rect().isEmpty()) ||
- (interface->object() && interface->object()->isWidgetType()) ||
- (interface->role() == QAccessible::ListItem) ||
- (interface->role() == QAccessible::Cell) ||
- (interface->role() == QAccessible::TreeItem) ||
- (interface->role() == QAccessible::Row) ||
- (interface->object() && interface->object()->inherits("QSGItem"))
- ) {
- ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_COMPONENT);
- } else {
- qCDebug(lcAccessibilityAtspiCreation) << " IS NOT a component";
- }
- if (interface->role() == QAccessible::Application)
- ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_APPLICATION);
-
- if (interface->actionInterface() || interface->valueInterface())
- ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_ACTION);
-
- if (interface->textInterface())
- ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_TEXT);
-
- if (interface->editableTextInterface())
- ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_EDITABLE_TEXT);
-
- if (interface->valueInterface())
- ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_VALUE);
-
- if (interface->tableInterface())
- ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_TABLE);
-
- return ifaces;
-}
-
-QSpiRelationArray AtSpiAdaptor::relationSet(QAccessibleInterface *interface, const QDBusConnection &connection) const
-{
- typedef QPair<QAccessibleInterface*, QAccessible::Relation> RelationPair;
- const QVector<RelationPair> relationInterfaces = interface->relations();
-
- QSpiRelationArray relations;
- for (const RelationPair &pair : relationInterfaces) {
-// FIXME: this loop seems a bit strange... "related" always have one item when we check.
-//And why is it a list, when it always have one item? And it seems to assume that the QAccessible::Relation enum maps directly to AtSpi
- QSpiObjectReferenceArray related;
-
- QDBusObjectPath path = QDBusObjectPath(pathForInterface(pair.first));
- related.append(QSpiObjectReference(connection, path));
-
- if (!related.isEmpty())
- relations.append(QSpiRelationArrayEntry(qAccessibleRelationToAtSpiRelation(pair.second), related));
- }
- return relations;
-}
-
-void AtSpiAdaptor::sendReply(const QDBusConnection &connection, const QDBusMessage &message, const QVariant &argument) const
-{
- QDBusMessage reply = message.createReply(argument);
- connection.send(reply);
-}
-
-
-QString AtSpiAdaptor::pathForObject(QObject *object) const
-{
- Q_ASSERT(object);
-
- if (inheritsQAction(object)) {
- qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::pathForObject: warning: creating path with QAction as object.";
- }
-
- QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(object);
- return pathForInterface(iface);
-}
-
-QString AtSpiAdaptor::pathForInterface(QAccessibleInterface *interface) const
-{
- if (!interface || !interface->isValid())
- return QLatin1String(ATSPI_DBUS_PATH_NULL);
- if (interface->role() == QAccessible::Application)
- return QLatin1String(QSPI_OBJECT_PATH_ROOT);
-
- QAccessible::Id id = QAccessible::uniqueId(interface);
- Q_ASSERT((int)id < 0);
- return QLatin1String(QSPI_OBJECT_PATH_PREFIX) + QString::number(id);
-}
-
-bool AtSpiAdaptor::inheritsQAction(QObject *object)
-{
- const QMetaObject *mo = object->metaObject();
- while (mo) {
- const QLatin1String cn(mo->className());
- if (cn == QLatin1String("QAction"))
- return true;
- mo = mo->superClass();
- }
- return false;
-}
-
-// Component
-static QAccessibleInterface * getWindow(QAccessibleInterface * interface)
-{
- if (interface->role() == QAccessible::Window)
- return interface;
-
- QAccessibleInterface * parent = interface->parent();
- while (parent && parent->role() != QAccessible::Window)
- parent = parent->parent();
-
- return parent;
-}
-
-static QRect getRelativeRect(QAccessibleInterface *interface)
-{
- QAccessibleInterface * window;
- QRect wr, cr;
-
- cr = interface->rect();
-
- window = getWindow(interface);
- if (window) {
- wr = window->rect();
-
- cr.setX(cr.x() - wr.x());
- cr.setY(cr.x() - wr.y());
- }
- return cr;
-}
-
-bool AtSpiAdaptor::componentInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
-{
- if (function == QLatin1String("Contains")) {
- bool ret = false;
- int x = message.arguments().at(0).toInt();
- int y = message.arguments().at(1).toInt();
- uint coordType = message.arguments().at(2).toUInt();
- if (coordType == ATSPI_COORD_TYPE_SCREEN)
- ret = interface->rect().contains(x, y);
- else
- ret = getRelativeRect(interface).contains(x, y);
- sendReply(connection, message, ret);
- } else if (function == QLatin1String("GetAccessibleAtPoint")) {
- int x = message.arguments().at(0).toInt();
- int y = message.arguments().at(1).toInt();
- uint coordType = message.arguments().at(2).toUInt();
- if (coordType == ATSPI_COORD_TYPE_WINDOW) {
- QWindow * window = interface->window();
- if (window) {
- x += window->position().x();
- y += window->position().y();
- }
- }
-
- QAccessibleInterface * childInterface(interface->childAt(x, y));
- QAccessibleInterface * iface = 0;
- while (childInterface) {
- iface = childInterface;
- childInterface = iface->childAt(x, y);
- }
- if (iface) {
- QString path = pathForInterface(iface);
- sendReply(connection, message, QVariant::fromValue(
- QSpiObjectReference(connection, QDBusObjectPath(path))));
- } else {
- sendReply(connection, message, QVariant::fromValue(
- QSpiObjectReference(connection, QDBusObjectPath(ATSPI_DBUS_PATH_NULL))));
- }
- } else if (function == QLatin1String("GetAlpha")) {
- sendReply(connection, message, (double) 1.0);
- } else if (function == QLatin1String("GetExtents")) {
- uint coordType = message.arguments().at(0).toUInt();
- sendReply(connection, message, QVariant::fromValue(getExtents(interface, coordType)));
- } else if (function == QLatin1String("GetLayer")) {
- sendReply(connection, message, QVariant::fromValue((uint)1));
- } else if (function == QLatin1String("GetMDIZOrder")) {
- sendReply(connection, message, QVariant::fromValue((short)0));
- } else if (function == QLatin1String("GetPosition")) {
- uint coordType = message.arguments().at(0).toUInt();
- QRect rect;
- if (coordType == ATSPI_COORD_TYPE_SCREEN)
- rect = interface->rect();
- else
- rect = getRelativeRect(interface);
- QVariantList pos;
- pos << rect.x() << rect.y();
- connection.send(message.createReply(pos));
- } else if (function == QLatin1String("GetSize")) {
- QRect rect = interface->rect();
- QVariantList size;
- size << rect.width() << rect.height();
- connection.send(message.createReply(size));
- } else if (function == QLatin1String("GrabFocus")) {
- 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();
-// int width = message.arguments().at(2).toInt();
-// int height = message.arguments().at(3).toInt();
-// uint coordinateType = message.arguments().at(4).toUInt();
- qCDebug(lcAccessibilityAtspi) << "SetExtents is not implemented.";
- sendReply(connection, message, false);
- } else if (function == QLatin1String("SetPosition")) {
-// int x = message.arguments().at(0).toInt();
-// int y = message.arguments().at(1).toInt();
-// uint coordinateType = message.arguments().at(2).toUInt();
- qCDebug(lcAccessibilityAtspi) << "SetPosition is not implemented.";
- sendReply(connection, message, false);
- } else if (function == QLatin1String("SetSize")) {
-// int width = message.arguments().at(0).toInt();
-// int height = message.arguments().at(1).toInt();
- qCDebug(lcAccessibilityAtspi) << "SetSize is not implemented.";
- sendReply(connection, message, false);
- } else {
- qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::componentInterface does not implement " << function << message.path();
- return false;
- }
- return true;
-}
-
-QRect AtSpiAdaptor::getExtents(QAccessibleInterface *interface, uint coordType)
-{
- return (coordType == ATSPI_COORD_TYPE_SCREEN) ? interface->rect() : getRelativeRect(interface);
-}
-
-// Action interface
-bool AtSpiAdaptor::actionInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
-{
- if (function == QLatin1String("GetNActions")) {
- 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();
- const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
- if (index < 0 || index >= actionNames.count())
- return false;
- 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(interface)));
- } else if (function == QLatin1String("GetName")) {
- int index = message.arguments().at(0).toInt();
- const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
- if (index < 0 || index >= actionNames.count())
- return false;
- sendReply(connection, message, actionNames.at(index));
- } else if (function == QLatin1String("GetDescription")) {
- int index = message.arguments().at(0).toInt();
- const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
- if (index < 0 || index >= actionNames.count())
- return false;
- 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();
- const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
- if (index < 0 || index >= actionNames.count())
- return false;
- QStringList keyBindings;
- if (QAccessibleActionInterface *actionIface = interface->actionInterface())
- keyBindings = actionIface->keyBindingsForAction(actionNames.at(index));
- if (keyBindings.isEmpty()) {
- QString acc = interface->text(QAccessible::Accelerator);
- if (!acc.isEmpty())
- keyBindings.append(acc);
- }
- if (keyBindings.length() > 0)
- sendReply(connection, message, keyBindings.join(QLatin1Char(';')));
- else
- sendReply(connection, message, QString());
- } else {
- qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::actionInterface does not implement " << function << message.path();
- return false;
- }
- return true;
-}
-
-QSpiActionArray AtSpiAdaptor::getActions(QAccessibleInterface *interface) const
-{
- QAccessibleActionInterface *actionInterface = interface->actionInterface();
- QSpiActionArray actions;
- const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
- actions.reserve(actionNames.size());
- for (const QString &actionName : actionNames) {
- QSpiAction action;
-
- action.name = actionName;
- if (actionInterface) {
- action.description = actionInterface->localizedActionDescription(actionName);
- const QStringList keyBindings = actionInterface->keyBindingsForAction(actionName);
- if (!keyBindings.isEmpty())
- action.keyBinding = keyBindings.front();
- } else {
- action.description = qAccessibleLocalizedActionDescription(actionName);
- }
-
- actions.append(std::move(action));
- }
- return actions;
-}
-
-// Text interface
-bool AtSpiAdaptor::textInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
-{
- if (!interface->textInterface())
- return false;
-
- // properties
- if (function == QLatin1String("GetCaretOffset")) {
- sendReply(connection, message, QVariant::fromValue(QDBusVariant(QVariant::fromValue(interface->textInterface()->cursorPosition()))));
- } else if (function == QLatin1String("GetCharacterCount")) {
- sendReply(connection, message, QVariant::fromValue(QDBusVariant(QVariant::fromValue(interface->textInterface()->characterCount()))));
-
- // functions
- } else if (function == QLatin1String("AddSelection")) {
- int startOffset = message.arguments().at(0).toInt();
- int endOffset = message.arguments().at(1).toInt();
- int lastSelection = interface->textInterface()->selectionCount();
- interface->textInterface()->setSelection(lastSelection, startOffset, endOffset);
- sendReply(connection, message, (interface->textInterface()->selectionCount() > lastSelection));
- } else if (function == QLatin1String("GetAttributeRun")) {
- int offset = message.arguments().at(0).toInt();
- bool includeDefaults = message.arguments().at(1).toBool();
- Q_UNUSED(includeDefaults)
- connection.send(message.createReply(getAttributes(interface, offset, includeDefaults)));
- } else if (function == QLatin1String("GetAttributeValue")) {
- int offset = message.arguments().at(0).toInt();
- QString attributeName = message.arguments().at(1).toString();
- connection.send(message.createReply(getAttributeValue(interface, offset, attributeName)));
- } else if (function == QLatin1String("GetAttributes")) {
- int offset = message.arguments().at(0).toInt();
- connection.send(message.createReply(getAttributes(interface, offset, true)));
- } else if (function == QLatin1String("GetBoundedRanges")) {
- int x = message.arguments().at(0).toInt();
- int y = message.arguments().at(1).toInt();
- int width = message.arguments().at(2).toInt();
- int height = message.arguments().at(3).toInt();
- uint coordType = message.arguments().at(4).toUInt();
- uint xClipType = message.arguments().at(5).toUInt();
- uint yClipType = message.arguments().at(6).toUInt();
- Q_UNUSED(x);
- Q_UNUSED(y);
- Q_UNUSED(width);
- Q_UNUSED(height);
- Q_UNUSED(coordType);
- Q_UNUSED(xClipType);
- Q_UNUSED(yClipType);
- qCDebug(lcAccessibilityAtspi) << "Not implemented: QSpiAdaptor::GetBoundedRanges";
- sendReply(connection, message, QVariant::fromValue(QSpiTextRangeList()));
- } else if (function == QLatin1String("GetCharacterAtOffset")) {
- int offset = message.arguments().at(0).toInt();
- int start;
- int end;
- QString result = interface->textInterface()->textAtOffset(offset, QAccessible::CharBoundary, &start, &end);
- sendReply(connection, message, (int) *(qPrintable (result)));
- } else if (function == QLatin1String("GetCharacterExtents")) {
- int offset = message.arguments().at(0).toInt();
- int coordType = message.arguments().at(1).toUInt();
- connection.send(message.createReply(getCharacterExtents(interface, offset, coordType)));
- } else if (function == QLatin1String("GetDefaultAttributeSet") || function == QLatin1String("GetDefaultAttributes")) {
- // GetDefaultAttributes is deprecated in favour of GetDefaultAttributeSet.
- // Empty set seems reasonable. There is no default attribute set.
- sendReply(connection, message, QVariant::fromValue(QSpiAttributeSet()));
- } else if (function == QLatin1String("GetNSelections")) {
- sendReply(connection, message, interface->textInterface()->selectionCount());
- } else if (function == QLatin1String("GetOffsetAtPoint")) {
- qCDebug(lcAccessibilityAtspi) << message.signature();
- Q_ASSERT(!message.signature().isEmpty());
- QPoint point(message.arguments().at(0).toInt(), message.arguments().at(1).toInt());
- uint coordType = message.arguments().at(2).toUInt();
- if (coordType == ATSPI_COORD_TYPE_WINDOW) {
- QWindow *win = interface->window();
- point -= QPoint(win->x(), win->y());
- }
- int offset = interface->textInterface()->offsetAtPoint(point);
- sendReply(connection, message, offset);
- } else if (function == QLatin1String("GetRangeExtents")) {
- int startOffset = message.arguments().at(0).toInt();
- int endOffset = message.arguments().at(1).toInt();
- uint coordType = message.arguments().at(2).toUInt();
- connection.send(message.createReply(getRangeExtents(interface, startOffset, endOffset, coordType)));
- } else if (function == QLatin1String("GetSelection")) {
- int selectionNum = message.arguments().at(0).toInt();
- int start, end;
- interface->textInterface()->selection(selectionNum, &start, &end);
- if (start < 0)
- start = end = interface->textInterface()->cursorPosition();
- QVariantList sel;
- sel << start << end;
- connection.send(message.createReply(sel));
- } else if (function == QLatin1String("GetText")) {
- int startOffset = message.arguments().at(0).toInt();
- int endOffset = message.arguments().at(1).toInt();
- if (endOffset == -1) // AT-SPI uses -1 to signal all characters
- endOffset = interface->textInterface()->characterCount();
- sendReply(connection, message, interface->textInterface()->text(startOffset, endOffset));
- } else if (function == QLatin1String("GetTextAfterOffset")) {
- int offset = message.arguments().at(0).toInt();
- int type = message.arguments().at(1).toUInt();
- int startOffset, endOffset;
- QString text = interface->textInterface()->textAfterOffset(offset, qAccessibleBoundaryType(type), &startOffset, &endOffset);
- QVariantList ret;
- ret << text << startOffset << endOffset;
- connection.send(message.createReply(ret));
- } else if (function == QLatin1String("GetTextAtOffset")) {
- int offset = message.arguments().at(0).toInt();
- int type = message.arguments().at(1).toUInt();
- int startOffset, endOffset;
- QString text = interface->textInterface()->textAtOffset(offset, qAccessibleBoundaryType(type), &startOffset, &endOffset);
- QVariantList ret;
- ret << text << startOffset << endOffset;
- connection.send(message.createReply(ret));
- } else if (function == QLatin1String("GetTextBeforeOffset")) {
- int offset = message.arguments().at(0).toInt();
- int type = message.arguments().at(1).toUInt();
- int startOffset, endOffset;
- QString text = interface->textInterface()->textBeforeOffset(offset, qAccessibleBoundaryType(type), &startOffset, &endOffset);
- QVariantList ret;
- ret << text << startOffset << endOffset;
- connection.send(message.createReply(ret));
- } else if (function == QLatin1String("RemoveSelection")) {
- int selectionNum = message.arguments().at(0).toInt();
- interface->textInterface()->removeSelection(selectionNum);
- sendReply(connection, message, true);
- } else if (function == QLatin1String("SetCaretOffset")) {
- int offset = message.arguments().at(0).toInt();
- interface->textInterface()->setCursorPosition(offset);
- sendReply(connection, message, true);
- } else if (function == QLatin1String("SetSelection")) {
- int selectionNum = message.arguments().at(0).toInt();
- int startOffset = message.arguments().at(1).toInt();
- int endOffset = message.arguments().at(2).toInt();
- interface->textInterface()->setSelection(selectionNum, startOffset, endOffset);
- sendReply(connection, message, true);
- } else {
- qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::textInterface does not implement " << function << message.path();
- return false;
- }
- return true;
-}
-
-QAccessible::TextBoundaryType AtSpiAdaptor::qAccessibleBoundaryType(int atspiTextBoundaryType) const
-{
- switch (atspiTextBoundaryType) {
- case ATSPI_TEXT_BOUNDARY_CHAR:
- return QAccessible::CharBoundary;
- case ATSPI_TEXT_BOUNDARY_WORD_START:
- case ATSPI_TEXT_BOUNDARY_WORD_END:
- return QAccessible::WordBoundary;
- case ATSPI_TEXT_BOUNDARY_SENTENCE_START:
- case ATSPI_TEXT_BOUNDARY_SENTENCE_END:
- return QAccessible::SentenceBoundary;
- case ATSPI_TEXT_BOUNDARY_LINE_START:
- case ATSPI_TEXT_BOUNDARY_LINE_END:
- return QAccessible::LineBoundary;
- }
- Q_ASSERT_X(0, "", "Requested invalid boundary type.");
- return QAccessible::CharBoundary;
-}
-
-namespace
-{
- struct AtSpiAttribute {
- QString name;
- QString value;
- AtSpiAttribute(const QString &aName, const QString &aValue) : name(aName), value(aValue) {}
- bool isNull() const { return name.isNull() || value.isNull(); }
- };
-
- QString atspiColor(const QString &ia2Color)
- {
- // "rgb(%u,%u,%u)" -> "%u,%u,%u"
- return ia2Color.mid(4, ia2Color.length() - (4+1));
- }
-
- QString atspiSize(const QString &ia2Size)
- {
- // "%fpt" -> "%f"
- return ia2Size.left(ia2Size.length() - 2);
- }
-
- AtSpiAttribute atspiTextAttribute(const QString &ia2Name, const QString &ia2Value)
- {
- QString name = ia2Name;
- QString value = ia2Value;
-
- // IAccessible2: http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/textattributes
- // ATK attribute names: https://git.gnome.org/browse/orca/tree/src/orca/text_attribute_names.py
- // ATK attribute values: https://developer.gnome.org/atk/unstable/AtkText.html#AtkTextAttribute
-
- // https://bugzilla.gnome.org/show_bug.cgi?id=744553 "ATK docs provide no guidance for allowed values of some text attributes"
- // specifically for "weight", "invalid", "language" and value range for colors
-
- if (ia2Name == QLatin1String("background-color")) {
- name = QStringLiteral("bg-color");
- value = atspiColor(value);
- } else if (ia2Name == QLatin1String("font-family")) {
- name = QStringLiteral("family-name");
- } else if (ia2Name == QLatin1String("color")) {
- name = QStringLiteral("fg-color");
- value = atspiColor(value);
- } else if (ia2Name == QLatin1String("text-align")) {
- name = QStringLiteral("justification");
- if (value == QLatin1String("justify")) {
- value = QStringLiteral("fill");
- } else {
- if (value != QLatin1String("left") &&
- value != QLatin1String("right") &&
- value != QLatin1String("center")
- ) {
- value = QString();
- qCDebug(lcAccessibilityAtspi) << "Unknown text-align attribute value \"" << value << "\" cannot be translated to AT-SPI.";
- }
- }
- } else if (ia2Name == QLatin1String("font-size")) {
- name = QStringLiteral("size");
- value = atspiSize(value);
- } else if (ia2Name == QLatin1String("font-style")) {
- name = QStringLiteral("style");
- if (value != QLatin1String("normal") &&
- value != QLatin1String("italic") &&
- value != QLatin1String("oblique")
- ) {
- value = QString();
- qCDebug(lcAccessibilityAtspi) << "Unknown font-style attribute value \"" << value << "\" cannot be translated to AT-SPI.";
- }
- } else if (ia2Name == QLatin1String("text-underline-type")) {
- name = QStringLiteral("underline");
- if (value != QLatin1String("none") &&
- value != QLatin1String("single") &&
- value != QLatin1String("double")
- ) {
- value = QString();
- qCDebug(lcAccessibilityAtspi) << "Unknown text-underline-type attribute value \"" << value << "\" cannot be translated to AT-SPI.";
- }
- } else if (ia2Name == QLatin1String("font-weight")) {
- name = QStringLiteral("weight");
- if (value == QLatin1String("normal"))
- // Orca seems to accept all IAccessible2 values except for "normal"
- // (on which it produces traceback and fails to read any following text attributes),
- // but that is the default value, so omit it anyway
- value = QString();
- } else if (ia2Name == QLatin1String("text-position")) {
- name = QStringLiteral("vertical-align");
- if (value != QLatin1String("baseline") &&
- value != QLatin1String("super") &&
- value != QLatin1String("sub")
- ) {
- value = QString();
- qCDebug(lcAccessibilityAtspi) << "Unknown text-position attribute value \"" << value << "\" cannot be translated to AT-SPI.";
- }
- } else if (ia2Name == QLatin1String("writing-mode")) {
- name = QStringLiteral("direction");
- if (value == QLatin1String("lr"))
- value = QStringLiteral("ltr");
- else if (value == QLatin1String("rl"))
- value = QStringLiteral("rtl");
- else if (value == QLatin1String("tb")) {
- // IAccessible2 docs refer to XSL, which specifies "tb" is shorthand for "tb-rl"; so at least give a hint about the horizontal direction (ATK does not support vertical direction in this attribute (yet))
- value = QStringLiteral("rtl");
- qCDebug(lcAccessibilityAtspi) << "writing-mode attribute value \"tb\" translated only w.r.t. horizontal direction; vertical direction ignored";
- } else {
- value = QString();
- qCDebug(lcAccessibilityAtspi) << "Unknown writing-mode attribute value \"" << value << "\" cannot be translated to AT-SPI.";
- }
- } else if (ia2Name == QLatin1String("language")) {
- // OK - ATK has no docs on the format of the value, IAccessible2 has reasonable format - leave it at that now
- } else if (ia2Name == QLatin1String("invalid")) {
- // OK - ATK docs are vague but suggest they support the same range of values as IAccessible2
- } else {
- // attribute we know nothing about
- name = QString();
- value = QString();
- }
- return AtSpiAttribute(name, value);
- }
-}
-
-// FIXME all attribute methods below should share code
-QVariantList AtSpiAdaptor::getAttributes(QAccessibleInterface *interface, int offset, bool includeDefaults) const
-{
- Q_UNUSED(includeDefaults);
-
- QSpiAttributeSet set;
- int startOffset;
- int endOffset;
-
- QString joined = interface->textInterface()->attributes(offset, &startOffset, &endOffset);
- const QStringList attributes = joined.split (QLatin1Char(';'), Qt::SkipEmptyParts, Qt::CaseSensitive);
- for (const QString &attr : attributes) {
- QStringList items;
- items = attr.split(QLatin1Char(':'), Qt::SkipEmptyParts, Qt::CaseSensitive);
- AtSpiAttribute attribute = atspiTextAttribute(items[0], items[1]);
- if (!attribute.isNull())
- set[attribute.name] = attribute.value;
- }
-
- QVariantList list;
- list << QVariant::fromValue(set) << startOffset << endOffset;
-
- return list;
-}
-
-QVariantList AtSpiAdaptor::getAttributeValue(QAccessibleInterface *interface, int offset, const QString &attributeName) const
-{
- QString mapped;
- QString joined;
- QSpiAttributeSet map;
- int startOffset;
- int endOffset;
-
- joined = interface->textInterface()->attributes(offset, &startOffset, &endOffset);
- const QStringList attributes = joined.split (QLatin1Char(';'), Qt::SkipEmptyParts, Qt::CaseSensitive);
- for (const QString& attr : attributes) {
- QStringList items;
- items = attr.split(QLatin1Char(':'), Qt::SkipEmptyParts, Qt::CaseSensitive);
- AtSpiAttribute attribute = atspiTextAttribute(items[0], items[1]);
- if (!attribute.isNull())
- map[attribute.name] = attribute.value;
- }
- mapped = map[attributeName];
- const bool defined = !mapped.isEmpty();
- QVariantList list;
- list << mapped << startOffset << endOffset << defined;
- return list;
-}
-
-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 QList<QVariant>() << rect.x() << rect.y() << rect.width() << rect.height();
-}
-
-QList<QVariant> AtSpiAdaptor::getRangeExtents(QAccessibleInterface *interface,
- int startOffset, int endOffset, uint coordType) const
-{
- if (endOffset == -1)
- endOffset = interface->textInterface()->characterCount();
-
- QAccessibleTextInterface *textInterface = interface->textInterface();
- if (endOffset <= startOffset || !textInterface)
- return QList<QVariant>() << -1 << -1 << 0 << 0;
-
- QRect rect = textInterface->characterRect(startOffset);
- for (int i=startOffset + 1; i <= endOffset; i++)
- rect = rect | textInterface->characterRect(i);
-
- // relative to window
- if (coordType == ATSPI_COORD_TYPE_WINDOW)
- rect = translateRectToWindowCoordinates(interface, rect);
-
- return QList<QVariant>() << rect.x() << rect.y() << rect.width() << rect.height();
-}
-
-QRect AtSpiAdaptor::translateRectToWindowCoordinates(QAccessibleInterface *interface, const QRect &rect)
-{
- QAccessibleInterface * window = getWindow(interface);
- if (window)
- return rect.translated(-window->rect().x(), -window->rect().y());
-
- return rect;
-}
-
-
-// Editable Text interface
-static QString textForRange(QAccessibleInterface *accessible, int startOffset, int endOffset)
-{
- if (QAccessibleTextInterface *textIface = accessible->textInterface()) {
- if (endOffset == -1)
- endOffset = textIface->characterCount();
- return textIface->text(startOffset, endOffset);
- }
- QString txt = accessible->text(QAccessible::Value);
- if (endOffset == -1)
- endOffset = txt.length();
- return txt.mid(startOffset, endOffset - startOffset);
-}
-
-static void replaceTextFallback(QAccessibleInterface *accessible, long startOffset, long endOffset, const QString &txt)
-{
- QString t = textForRange(accessible, 0, -1);
- if (endOffset == -1)
- endOffset = t.length();
- if (endOffset - startOffset == 0)
- t.insert(startOffset, txt);
- else
- t.replace(startOffset, endOffset - startOffset, txt);
- accessible->setText(QAccessible::Value, t);
-}
-
-bool AtSpiAdaptor::editableTextInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
-{
- if (function == QLatin1String("CopyText")) {
-#ifndef QT_NO_CLIPBOARD
- int startOffset = message.arguments().at(0).toInt();
- int endOffset = message.arguments().at(1).toInt();
- const QString t = textForRange(interface, startOffset, endOffset);
- QGuiApplication::clipboard()->setText(t);
-#endif
- connection.send(message.createReply(true));
- } else if (function == QLatin1String("CutText")) {
-#ifndef QT_NO_CLIPBOARD
- int startOffset = message.arguments().at(0).toInt();
- int endOffset = message.arguments().at(1).toInt();
- const QString t = textForRange(interface, startOffset, endOffset);
- if (QAccessibleEditableTextInterface *editableTextIface = interface->editableTextInterface())
- editableTextIface->deleteText(startOffset, endOffset);
- else
- replaceTextFallback(interface, startOffset, endOffset, QString());
- QGuiApplication::clipboard()->setText(t);
-#endif
- connection.send(message.createReply(true));
- } else if (function == QLatin1String("DeleteText")) {
- int startOffset = message.arguments().at(0).toInt();
- int endOffset = message.arguments().at(1).toInt();
- if (QAccessibleEditableTextInterface *editableTextIface = interface->editableTextInterface())
- editableTextIface->deleteText(startOffset, endOffset);
- else
- replaceTextFallback(interface, startOffset, endOffset, QString());
- connection.send(message.createReply(true));
- } else if (function == QLatin1String("InsertText")) {
- int position = message.arguments().at(0).toInt();
- QString text = message.arguments().at(1).toString();
- int length = message.arguments().at(2).toInt();
- text.resize(length);
- if (QAccessibleEditableTextInterface *editableTextIface = interface->editableTextInterface())
- editableTextIface->insertText(position, text);
- else
- replaceTextFallback(interface, position, position, text);
- connection.send(message.createReply(true));
- } else if (function == QLatin1String("PasteText")) {
-#ifndef QT_NO_CLIPBOARD
- int position = message.arguments().at(0).toInt();
- const QString txt = QGuiApplication::clipboard()->text();
- if (QAccessibleEditableTextInterface *editableTextIface = interface->editableTextInterface())
- editableTextIface->insertText(position, txt);
- else
- replaceTextFallback(interface, position, position, txt);
-#endif
- connection.send(message.createReply(true));
- } else if (function == QLatin1String("SetTextContents")) {
- QString newContents = message.arguments().at(0).toString();
- if (QAccessibleEditableTextInterface *editableTextIface = interface->editableTextInterface())
- editableTextIface->replaceText(0, interface->textInterface()->characterCount(), newContents);
- else
- replaceTextFallback(interface, 0, -1, newContents);
- connection.send(message.createReply(true));
- } else if (function == QLatin1String("")) {
- connection.send(message.createReply());
- } else {
- qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::editableTextInterface does not implement " << function << message.path();
- return false;
- }
- return true;
-}
-
-// Value interface
-bool AtSpiAdaptor::valueInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
-{
- QAccessibleValueInterface *valueIface = interface->valueInterface();
- if (!valueIface)
- return false;
-
- if (function == QLatin1String("SetCurrentValue")) {
- QDBusVariant v = qvariant_cast<QDBusVariant>(message.arguments().at(2));
- double value = v.variant().toDouble();
- //Temporary fix
- //See https://bugzilla.gnome.org/show_bug.cgi?id=652596
- valueIface->setCurrentValue(value);
- connection.send(message.createReply()); // FIXME is the reply needed?
- } else {
- QVariant value;
- if (function == QLatin1String("GetCurrentValue"))
- value = valueIface->currentValue();
- else if (function == QLatin1String("GetMaximumValue"))
- value = valueIface->maximumValue();
- else if (function == QLatin1String("GetMinimumIncrement"))
- value = valueIface->minimumStepSize();
- else if (function == QLatin1String("GetMinimumValue"))
- value = valueIface->minimumValue();
- else {
- qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::valueInterface does not implement " << function << message.path();
- return false;
- }
- if (!value.canConvert(QMetaType::Double)) {
- qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::valueInterface: Could not convert to double: " << function;
- }
-
- // explicitly convert to dbus-variant containing one double since atspi expects that
- // everything else might fail to convert back on the other end
- connection.send(message.createReply(
- QVariant::fromValue(QDBusVariant(QVariant::fromValue(value.toDouble())))));
- }
- return true;
-}
-
-// Table interface
-bool AtSpiAdaptor::tableInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
-{
- if (!(interface->tableInterface() || interface->tableCellInterface())) {
- qCDebug(lcAccessibilityAtspi) << "WARNING Qt AtSpiAdaptor: Could not find table interface for: " << message.path() << interface;
- return false;
- }
-
- if (0) {
- // properties
- } else if (function == QLatin1String("GetCaption")) {
- QAccessibleInterface * captionInterface= interface->tableInterface()->caption();
- if (captionInterface) {
- QSpiObjectReference ref = QSpiObjectReference(connection, QDBusObjectPath(pathForInterface(captionInterface)));
- sendReply(connection, message, QVariant::fromValue(ref));
- } else {
- sendReply(connection, message, QVariant::fromValue(
- QSpiObjectReference(connection, QDBusObjectPath(ATSPI_DBUS_PATH_NULL))));
- }
- } else if (function == QLatin1String("GetNColumns")) {
- connection.send(message.createReply(QVariant::fromValue(QDBusVariant(
- QVariant::fromValue(interface->tableInterface()->columnCount())))));
- } else if (function == QLatin1String("GetNRows")) {
- connection.send(message.createReply(QVariant::fromValue(QDBusVariant(
- QVariant::fromValue(interface->tableInterface()->rowCount())))));
- } else if (function == QLatin1String("GetNSelectedColumns")) {
- connection.send(message.createReply(QVariant::fromValue(QDBusVariant(
- QVariant::fromValue(interface->tableInterface()->selectedColumnCount())))));
- } else if (function == QLatin1String("GetNSelectedRows")) {
- connection.send(message.createReply(QVariant::fromValue(QDBusVariant(
- QVariant::fromValue(interface->tableInterface()->selectedRowCount())))));
- } else if (function == QLatin1String("GetSummary")) {
- QAccessibleInterface * summary = interface->tableInterface() ? interface->tableInterface()->summary() : 0;
- QSpiObjectReference ref(connection, QDBusObjectPath(pathForInterface(summary)));
- connection.send(message.createReply(QVariant::fromValue(QDBusVariant(QVariant::fromValue(ref)))));
- } else if (function == QLatin1String("GetAccessibleAt")) {
- int row = message.arguments().at(0).toInt();
- int column = message.arguments().at(1).toInt();
- if ((row < 0) ||
- (column < 0) ||
- (row >= interface->tableInterface()->rowCount()) ||
- (column >= interface->tableInterface()->columnCount())) {
- qCDebug(lcAccessibilityAtspi) << "WARNING: invalid index for tableInterface GetAccessibleAt (" << row << ", " << column << ')';
- return false;
- }
-
- QSpiObjectReference ref;
- QAccessibleInterface * cell(interface->tableInterface()->cellAt(row, column));
- if (cell) {
- ref = QSpiObjectReference(connection, QDBusObjectPath(pathForInterface(cell)));
- } else {
- qCDebug(lcAccessibilityAtspi) << "WARNING: no cell interface returned for " << interface->object() << row << column;
- ref = QSpiObjectReference();
- }
- connection.send(message.createReply(QVariant::fromValue(ref)));
-
- } else if (function == QLatin1String("GetIndexAt")) {
- int row = message.arguments().at(0).toInt();
- int column = message.arguments().at(1).toInt();
- QAccessibleInterface *cell = interface->tableInterface()->cellAt(row, column);
- if (!cell) {
- qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::GetIndexAt(" << row << ',' << column << ") did not find a cell. " << interface;
- return false;
- }
- int index = interface->indexOfChild(cell);
- qCDebug(lcAccessibilityAtspi) << "QSpiAdaptor::GetIndexAt row:" << row << " col:" << column << " logical index:" << index;
- Q_ASSERT(index > 0);
- connection.send(message.createReply(index));
- } else if ((function == QLatin1String("GetColumnAtIndex")) || (function == QLatin1String("GetRowAtIndex"))) {
- int index = message.arguments().at(0).toInt();
- int ret = -1;
- if (index >= 0) {
- QAccessibleInterface * cell = interface->child(index);
- if (cell) {
- if (function == QLatin1String("GetColumnAtIndex")) {
- if (cell->role() == QAccessible::ColumnHeader) {
- ret = index;
- } else if (cell->role() == QAccessible::RowHeader) {
- ret = -1;
- } else {
- if (!cell->tableCellInterface()) {
- qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::" << function << " No table cell interface: " << cell;
- return false;
- }
- ret = cell->tableCellInterface()->columnIndex();
- }
- } else {
- if (cell->role() == QAccessible::ColumnHeader) {
- ret = -1;
- } else if (cell->role() == QAccessible::RowHeader) {
- ret = index % interface->tableInterface()->columnCount();
- } else {
- if (!cell->tableCellInterface()) {
- qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::" << function << " No table cell interface: " << cell;
- return false;
- }
- ret = cell->tableCellInterface()->rowIndex();
- }
- }
- } else {
- qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::" << function << " No cell at index: " << index << interface;
- return false;
- }
- }
- connection.send(message.createReply(ret));
-
- } else if (function == QLatin1String("GetColumnDescription")) {
- int column = message.arguments().at(0).toInt();
- connection.send(message.createReply(interface->tableInterface()->columnDescription(column)));
- } else if (function == QLatin1String("GetRowDescription")) {
- int row = message.arguments().at(0).toInt();
- connection.send(message.createReply(interface->tableInterface()->rowDescription(row)));
-
-
-
- } else if (function == QLatin1String("GetRowColumnExtentsAtIndex")) {
- int index = message.arguments().at(0).toInt();
- bool success = false;
-
- int row = -1;
- int col = -1;
- int rowExtents = -1;
- int colExtents = -1;
- bool isSelected = false;
-
- int cols = interface->tableInterface()->columnCount();
- if (cols > 0) {
- row = index / cols;
- col = index % cols;
- QAccessibleTableCellInterface *cell = interface->tableInterface()->cellAt(row, col)->tableCellInterface();
- if (cell) {
- row = cell->rowIndex();
- col = cell->columnIndex();
- rowExtents = cell->rowExtent();
- colExtents = cell->columnExtent();
- isSelected = cell->isSelected();
- success = true;
- }
- }
- QVariantList list;
- list << success << row << col << rowExtents << colExtents << isSelected;
- connection.send(message.createReply(list));
-
- } else if (function == QLatin1String("GetColumnExtentAt")) {
- int row = message.arguments().at(0).toInt();
- int column = message.arguments().at(1).toInt();
- connection.send(message.createReply(interface->tableInterface()->cellAt(row, column)->tableCellInterface()->columnExtent()));
-
- } else if (function == QLatin1String("GetRowExtentAt")) {
- int row = message.arguments().at(0).toInt();
- int column = message.arguments().at(1).toInt();
- connection.send(message.createReply(interface->tableInterface()->cellAt(row, column)->tableCellInterface()->rowExtent()));
-
- } else if (function == QLatin1String("GetColumnHeader")) {
- int column = message.arguments().at(0).toInt();
- QSpiObjectReference ref;
-
- QAccessibleInterface * cell(interface->tableInterface()->cellAt(0, column));
- if (cell && cell->tableCellInterface()) {
- QList<QAccessibleInterface*> header = cell->tableCellInterface()->columnHeaderCells();
- if (header.size() > 0) {
- ref = QSpiObjectReference(connection, QDBusObjectPath(pathForInterface(header.takeAt(0))));
- }
- }
- connection.send(message.createReply(QVariant::fromValue(ref)));
-
- } else if (function == QLatin1String("GetRowHeader")) {
- int row = message.arguments().at(0).toInt();
- QSpiObjectReference ref;
- QAccessibleTableCellInterface *cell = interface->tableInterface()->cellAt(row, 0)->tableCellInterface();
- if (cell) {
- QList<QAccessibleInterface*> header = cell->rowHeaderCells();
- if (header.size() > 0) {
- ref = QSpiObjectReference(connection, QDBusObjectPath(pathForInterface(header.takeAt(0))));
- }
- }
- connection.send(message.createReply(QVariant::fromValue(ref)));
-
- } else if (function == QLatin1String("GetSelectedColumns")) {
- connection.send(message.createReply(QVariant::fromValue(interface->tableInterface()->selectedColumns())));
- } else if (function == QLatin1String("GetSelectedRows")) {
- connection.send(message.createReply(QVariant::fromValue(interface->tableInterface()->selectedRows())));
- } else if (function == QLatin1String("IsColumnSelected")) {
- int column = message.arguments().at(0).toInt();
- connection.send(message.createReply(interface->tableInterface()->isColumnSelected(column)));
- } else if (function == QLatin1String("IsRowSelected")) {
- int row = message.arguments().at(0).toInt();
- connection.send(message.createReply(interface->tableInterface()->isRowSelected(row)));
- } else if (function == QLatin1String("IsSelected")) {
- int row = message.arguments().at(0).toInt();
- int column = message.arguments().at(1).toInt();
- QAccessibleTableCellInterface* cell = interface->tableInterface()->cellAt(row, column)->tableCellInterface();
- connection.send(message.createReply(cell->isSelected()));
- } else if (function == QLatin1String("AddColumnSelection")) {
- int column = message.arguments().at(0).toInt();
- connection.send(message.createReply(interface->tableInterface()->selectColumn(column)));
- } else if (function == QLatin1String("AddRowSelection")) {
- int row = message.arguments().at(0).toInt();
- connection.send(message.createReply(interface->tableInterface()->selectRow(row)));
- } else if (function == QLatin1String("RemoveColumnSelection")) {
- int column = message.arguments().at(0).toInt();
- connection.send(message.createReply(interface->tableInterface()->unselectColumn(column)));
- } else if (function == QLatin1String("RemoveRowSelection")) {
- int row = message.arguments().at(0).toInt();
- connection.send(message.createReply(interface->tableInterface()->unselectRow(row)));
- } else {
- qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::tableInterface does not implement " << function << message.path();
- return false;
- }
- return true;
-}
-
-QT_END_NAMESPACE
-#endif //QT_NO_ACCESSIBILITY