2012-05-10 21:52:05 +00:00
/****************************************************************************
* *
2016-01-15 07:08:27 +00:00
* * Copyright ( C ) 2016 The Qt Company Ltd .
* * Contact : https : //www.qt.io/licensing/
2012-05-10 21:52:05 +00:00
* *
* * This file is part of the QtGui module of the Qt Toolkit .
* *
2016-01-15 07:08:27 +00:00
* * $ QT_BEGIN_LICENSE : LGPL $
2012-09-19 12:28:29 +00:00
* * 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
2015-01-28 08:44:43 +00:00
* * a written agreement between you and The Qt Company . For licensing terms
2016-01-15 07:08:27 +00:00
* * and conditions see https : //www.qt.io/terms-conditions. For further
* * information use the contact form at https : //www.qt.io/contact-us.
2012-09-19 12:28:29 +00:00
* *
2012-05-10 21:52:05 +00:00
* * GNU Lesser General Public License Usage
2012-09-19 12:28:29 +00:00
* * Alternatively , this file may be used under the terms of the GNU Lesser
2016-01-15 07:08:27 +00:00
* * 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.
2012-09-19 12:28:29 +00:00
* *
2016-01-15 07:08:27 +00:00
* * 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.
2012-05-10 21:52:05 +00:00
* *
* * $ QT_END_LICENSE $
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "atspiadaptor_p.h"
2020-07-02 11:24:47 +00:00
# include "qspiaccessiblebridge_p.h"
2012-05-10 21:52:05 +00:00
# include <QtGui/qwindow.h>
2012-10-17 09:29:26 +00:00
# include <QtGui/qguiapplication.h>
2012-05-10 21:52:05 +00:00
# include <qdbusmessage.h>
# include <qdbusreply.h>
# include <qclipboard.h>
2017-06-16 14:37:03 +00:00
# include <QtCore/qloggingcategory.h>
2012-05-10 21:52:05 +00:00
2014-07-02 12:10:30 +00:00
# ifndef QT_NO_ACCESSIBILITY
2012-05-10 21:52:05 +00:00
# include "socket_interface.h"
2020-07-02 08:04:34 +00:00
# include "qspi_constant_mappings_p.h"
2020-03-31 13:56:40 +00:00
# include <QtGui/private/qaccessiblebridgeutils_p.h>
2012-05-10 21:52:05 +00:00
2020-07-02 08:04:34 +00:00
# include "qspiapplicationadaptor_p.h"
2012-05-10 21:52:05 +00:00
/*!
\ class AtSpiAdaptor
2012-09-05 14:23:23 +00:00
\ internal
2012-05-10 21:52:05 +00:00
\ brief AtSpiAdaptor is the main class to forward between QAccessibleInterface and AT - SPI DBus
AtSpiAdaptor implements the functions specified in all at - spi interfaces .
2012-08-16 08:46:42 +00:00
It sends notifications coming from Qt via dbus and listens to incoming dbus requests .
2012-05-10 21:52:05 +00:00
*/
QT_BEGIN_NAMESPACE
2022-04-11 13:54:50 +00:00
using namespace Qt : : StringLiterals ;
2017-06-16 14:37:03 +00:00
Q_LOGGING_CATEGORY ( lcAccessibilityAtspi , " qt.accessibility.atspi " )
Q_LOGGING_CATEGORY ( lcAccessibilityAtspiCreation , " qt.accessibility.atspi.creation " )
2012-09-28 16:04:37 +00:00
2012-05-10 21:52:05 +00:00
AtSpiAdaptor : : AtSpiAdaptor ( DBusConnection * connection , QObject * parent )
2012-12-13 17:12:40 +00:00
: QDBusVirtualObject ( parent ) , m_dbus ( connection )
2012-05-10 21:52:05 +00:00
, 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 )
2012-12-13 19:30:48 +00:00
, sendObject_state_changed ( 0 )
2012-05-10 21:52:05 +00:00
, 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 ) ) ) ;
2012-12-13 17:12:40 +00:00
updateEventListeners ( ) ;
2022-04-11 13:54:50 +00:00
bool success = m_dbus - > connection ( ) . connect ( " org.a11y.atspi.Registry " _L1 , " /org/a11y/atspi/registry " _L1 ,
" org.a11y.atspi.Registry " _L1 , " EventListenerRegistered " _L1 , this ,
2012-12-13 17:12:40 +00:00
SLOT ( eventListenerRegistered ( QString , QString ) ) ) ;
2022-04-11 13:54:50 +00:00
success = success & & m_dbus - > connection ( ) . connect ( " org.a11y.atspi.Registry " _L1 , " /org/a11y/atspi/registry " _L1 ,
" org.a11y.atspi.Registry " _L1 , " EventListenerDeregistered " _L1 , this ,
2012-12-13 17:12:40 +00:00
SLOT ( eventListenerDeregistered ( QString , QString ) ) ) ;
2012-05-10 21:52:05 +00:00
}
AtSpiAdaptor : : ~ AtSpiAdaptor ( )
{
}
/*!
Provide DBus introspection .
*/
QString AtSpiAdaptor : : introspect ( const QString & path ) const
{
2022-04-11 15:27:52 +00:00
static const QLatin1StringView accessibleIntrospection (
2012-05-10 21:52:05 +00:00
" <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 "
) ;
2022-04-11 15:27:52 +00:00
static const QLatin1StringView actionIntrospection (
2012-05-10 21:52:05 +00:00
" <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 "
) ;
2022-04-11 15:27:52 +00:00
static const QLatin1StringView applicationIntrospection (
2012-05-10 21:52:05 +00:00
" <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 "
) ;
2022-04-11 15:27:52 +00:00
static const QLatin1StringView componentIntrospection (
2012-05-10 21:52:05 +00:00
" <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 "
) ;
2022-04-11 15:27:52 +00:00
static const QLatin1StringView editableTextIntrospection (
2012-05-10 21:52:05 +00:00
" <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 "
) ;
2022-04-11 15:27:52 +00:00
static const QLatin1StringView tableIntrospection (
2012-05-10 21:52:05 +00:00
" <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 "
) ;
2022-04-11 15:27:52 +00:00
static const QLatin1StringView textIntrospection (
2012-05-10 21:52:05 +00:00
" <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 "
) ;
2022-04-11 15:27:52 +00:00
static const QLatin1StringView valueIntrospection (
2012-05-10 21:52:05 +00:00
" <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 "
) ;
2013-01-03 16:18:40 +00:00
QAccessibleInterface * interface = interfaceFromPath ( path ) ;
2012-05-10 21:52:05 +00:00
if ( ! interface ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING Qt AtSpiAdaptor: Could not find accessible on path: " < < path ;
2012-05-10 21:52:05 +00:00
return QString ( ) ;
}
QStringList interfaces = accessibleInterfaces ( interface ) ;
QString xml ;
xml . append ( accessibleIntrospection ) ;
2022-04-11 13:54:50 +00:00
if ( interfaces . contains ( ATSPI_DBUS_INTERFACE_COMPONENT " " _L1 ) )
2012-05-10 21:52:05 +00:00
xml . append ( componentIntrospection ) ;
2022-04-11 13:54:50 +00:00
if ( interfaces . contains ( ATSPI_DBUS_INTERFACE_TEXT " " _L1 ) )
2012-05-10 21:52:05 +00:00
xml . append ( textIntrospection ) ;
2022-04-11 13:54:50 +00:00
if ( interfaces . contains ( ATSPI_DBUS_INTERFACE_EDITABLE_TEXT " " _L1 ) )
2012-05-10 21:52:05 +00:00
xml . append ( editableTextIntrospection ) ;
2022-04-11 13:54:50 +00:00
if ( interfaces . contains ( ATSPI_DBUS_INTERFACE_ACTION " " _L1 ) )
2012-05-10 21:52:05 +00:00
xml . append ( actionIntrospection ) ;
2022-04-11 13:54:50 +00:00
if ( interfaces . contains ( ATSPI_DBUS_INTERFACE_TABLE " " _L1 ) )
2012-05-10 21:52:05 +00:00
xml . append ( tableIntrospection ) ;
2022-04-11 13:54:50 +00:00
if ( interfaces . contains ( ATSPI_DBUS_INTERFACE_VALUE " " _L1 ) )
2012-05-10 21:52:05 +00:00
xml . append ( valueIntrospection ) ;
2022-04-11 13:54:50 +00:00
if ( path = = QSPI_OBJECT_PATH_ROOT " " _L1 )
2012-05-10 21:52:05 +00:00
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 ) {
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " ActiveDescendantChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_active_descendant_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " AttributesChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_attributes_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " BoundsChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_bounds_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " ChildrenChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_children_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " ColumnDeleted " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_column_deleted = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " ColumnInserted " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_column_inserted = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " ColumnReordered " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_column_reordered = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " LinkSelected " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_link_selected = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " ModelChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_model_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " PropertyChange " _L1 ) ) {
if ( right = = " PropertyChange:AccessibleDescription " _L1 ) {
2012-05-10 21:52:05 +00:00
sendObject_property_change_accessible_description = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right = = " PropertyChange:AccessibleName " _L1 ) {
2012-05-10 21:52:05 +00:00
sendObject_property_change_accessible_name = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right = = " PropertyChange:AccessibleParent " _L1 ) {
2012-05-10 21:52:05 +00:00
sendObject_property_change_accessible_parent = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right = = " PropertyChange:AccessibleRole " _L1 ) {
2012-05-10 21:52:05 +00:00
sendObject_property_change_accessible_role = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right = = " PropertyChange:TableCaption " _L1 ) {
2012-05-10 21:52:05 +00:00
sendObject_property_change_accessible_table_caption = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right = = " PropertyChange:TableColumnDescription " _L1 ) {
2012-05-10 21:52:05 +00:00
sendObject_property_change_accessible_table_column_description = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right = = " PropertyChange:TableColumnHeader " _L1 ) {
2012-05-10 21:52:05 +00:00
sendObject_property_change_accessible_table_column_header = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right = = " PropertyChange:TableRowDescription " _L1 ) {
2012-05-10 21:52:05 +00:00
sendObject_property_change_accessible_table_row_description = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right = = " PropertyChange:TableRowHeader " _L1 ) {
2012-05-10 21:52:05 +00:00
sendObject_property_change_accessible_table_row_header = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right = = " PropertyChange:TableSummary " _L1 ) {
2012-05-10 21:52:05 +00:00
sendObject_property_change_accessible_table_summary = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right = = " PropertyChange:AccessibleValue " _L1 ) {
2012-05-10 21:52:05 +00:00
sendObject_property_change_accessible_value = 1 ;
} else {
sendObject_property_change = 1 ;
}
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " RowDeleted " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_row_deleted = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " RowInserted " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_row_inserted = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " RowReordered " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_row_reordered = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " SelectionChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_selection_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " StateChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_state_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " TextAttributesChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_text_attributes_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " TextBoundsChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_text_bounds_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " TextCaretMoved " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_text_caret_moved = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " TextChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_text_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " TextSelectionChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_text_selection_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " ValueChanged " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendObject_value_changed = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " VisibleDataChanged " _L1 )
| | right . startsWith ( " VisibledataChanged " _L1 ) ) { // typo in libatspi
2012-05-10 21:52:05 +00:00
sendObject_visible_data_changed = 1 ;
} else {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: subscription string not handled: " < < flag ;
2012-05-10 21:52:05 +00:00
}
}
break ;
}
case ' w ' : { // window
if ( flag . size ( ) < = 8 ) {
sendWindow = 1 ;
} else { // object:Foo:Bar
QString right = flag . mid ( 7 ) ;
if ( false ) {
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Activate " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_activate = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Close " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_close = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Create " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_create = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Deactivate " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_deactivate = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Lower " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_lower = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Maximize " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_maximize = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Minimize " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_minimize = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Move " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_move = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Raise " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_raise = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Reparent " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_reparent = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Resize " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_resize = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Restore " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_restore = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Restyle " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_restyle = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Shade " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_shade = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " Unshade " _L1 ) ) {
2012-05-10 21:52:05 +00:00
sendWindow_unshade = 1 ;
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " DesktopCreate " _L1 ) ) {
2012-05-10 21:52:05 +00:00
// ignore this one
2022-04-11 13:54:50 +00:00
} else if ( right . startsWith ( " DesktopDestroy " _L1 ) ) {
2012-05-10 21:52:05 +00:00
// ignore this one
} else {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: subscription string not handled: " < < flag ;
2012-05-10 21:52:05 +00:00
}
}
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 :
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: subscription string not handled: " < < flag ;
2012-05-10 21:52:05 +00:00
}
}
/*!
Checks via dbus which events should be sent .
*/
void AtSpiAdaptor : : updateEventListeners ( )
{
2022-04-11 13:54:50 +00:00
QDBusMessage m = QDBusMessage : : createMethodCall ( " org.a11y.atspi.Registry " _L1 ,
" /org/a11y/atspi/registry " _L1 ,
" org.a11y.atspi.Registry " _L1 , " GetRegisteredEvents " _L1 ) ;
2012-05-10 21:52:05 +00:00
QDBusReply < QSpiEventListenerArray > listenersReply = m_dbus - > connection ( ) . call ( m ) ;
if ( listenersReply . isValid ( ) ) {
const QSpiEventListenerArray evList = listenersReply . value ( ) ;
2016-08-08 13:50:35 +00:00
for ( const QSpiEventListener & ev : evList )
2012-05-10 21:52:05 +00:00
setBitFlag ( ev . eventName ) ;
m_applicationAdaptor - > sendEvents ( ! evList . isEmpty ( ) ) ;
} else {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " Could not query active accessibility event listeners. " ;
2012-05-10 21:52:05 +00:00
}
}
void AtSpiAdaptor : : eventListenerDeregistered ( const QString & /*bus*/ , const QString & /*path*/ )
{
2017-06-16 14:37:03 +00:00
// qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::eventListenerDeregistered: " << bus << path;
2012-05-10 21:52:05 +00:00
updateEventListeners ( ) ;
}
void AtSpiAdaptor : : eventListenerRegistered ( const QString & /*bus*/ , const QString & /*path*/ )
{
2017-06-16 14:37:03 +00:00
// qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::eventListenerRegistered: " << bus << path;
2012-05-10 21:52:05 +00:00
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 ) ;
2020-07-07 01:18:16 +00:00
// If the window has been quickly activated or disabled, it will cause a crash.
if ( iface = = nullptr )
return ;
2013-03-18 14:59:17 +00:00
Q_ASSERT ( ! active | | iface - > isValid ( ) ) ;
2012-05-10 21:52:05 +00:00
2013-03-18 14:59:17 +00:00
QString windowTitle ;
// in dtor it may be invalid
if ( iface - > isValid ( ) )
windowTitle = iface - > text ( QAccessible : : Name ) ;
2012-05-10 21:52:05 +00:00
QDBusVariant data ;
data . setVariant ( windowTitle ) ;
QVariantList args = packDBusSignalArguments ( QString ( ) , 0 , 0 , QVariant : : fromValue ( data ) ) ;
2022-04-11 13:54:50 +00:00
QString status = active ? " Activate " _L1 : " Deactivate " _L1 ;
2012-05-10 21:52:05 +00:00
QString path = pathForObject ( window ) ;
2022-04-11 13:54:50 +00:00
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_WINDOW " " _L1 , status , args ) ;
2012-05-10 21:52:05 +00:00
2022-04-11 13:54:50 +00:00
QVariantList stateArgs = packDBusSignalArguments ( " active " _L1 , active ? 1 : 0 , 0 , variantForPath ( path ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " StateChanged " _L1 , stateArgs ) ;
2012-05-10 21:52:05 +00:00
}
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 ) ;
}
2013-01-03 16:18:40 +00:00
QAccessibleInterface * AtSpiAdaptor : : interfaceFromPath ( const QString & dbusPath ) const
2012-05-10 21:52:05 +00:00
{
2022-04-11 13:54:50 +00:00
if ( dbusPath = = QSPI_OBJECT_PATH_ROOT " " _L1 )
2013-01-03 16:18:40 +00:00
return QAccessible : : queryAccessibleInterface ( qApp ) ;
2012-05-10 21:52:05 +00:00
2022-04-11 12:04:17 +00:00
QStringList parts = dbusPath . split ( u ' / ' ) ;
2013-01-03 16:18:40 +00:00
if ( parts . size ( ) ! = 6 ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " invalid path: " < < dbusPath ;
2020-07-29 14:30:13 +00:00
return nullptr ;
2012-05-10 21:52:05 +00:00
}
QString objectString = parts . at ( 5 ) ;
2013-01-03 16:18:40 +00:00
QAccessible : : Id id = objectString . toUInt ( ) ;
// The id is always in the range [INT_MAX+1, UINT_MAX]
if ( ( int ) id > = 0 )
2017-06-16 14:37:03 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " No accessible object found for id: " < < id ;
2013-01-03 16:18:40 +00:00
return QAccessible : : accessibleInterface ( id ) ;
2012-05-10 21:52:05 +00:00
}
2013-01-03 16:18:40 +00:00
void AtSpiAdaptor : : notifyStateChange ( QAccessibleInterface * interface , const QString & state , int value )
2012-10-26 13:23:58 +00:00
{
QString path = pathForInterface ( interface ) ;
QVariantList stateArgs = packDBusSignalArguments ( state , value , 0 , variantForPath ( path ) ) ;
2022-04-11 13:54:50 +00:00
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " StateChanged " _L1 , stateArgs ) ;
2012-10-26 13:23:58 +00:00
}
2012-05-10 21:52:05 +00:00
/*!
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 )
2013-01-03 16:18:40 +00:00
notifyAboutCreation ( event - > accessibleInterface ( ) ) ;
2012-05-10 21:52:05 +00:00
break ;
case QAccessible : : ObjectShow : {
if ( sendObject | | sendObject_state_changed ) {
2022-04-11 13:54:50 +00:00
notifyStateChange ( event - > accessibleInterface ( ) , " showing " _L1 , 1 ) ;
2012-05-10 21:52:05 +00:00
}
break ;
}
case QAccessible : : ObjectHide : {
if ( sendObject | | sendObject_state_changed ) {
2022-04-11 13:54:50 +00:00
notifyStateChange ( event - > accessibleInterface ( ) , " showing " _L1 , 0 ) ;
2012-05-10 21:52:05 +00:00
}
break ;
}
case QAccessible : : ObjectDestroyed : {
if ( sendObject | | sendObject_state_changed )
2013-01-03 16:18:40 +00:00
notifyAboutDestruction ( event - > accessibleInterface ( ) ) ;
2012-05-10 21:52:05 +00:00
break ;
}
2014-07-19 08:02:23 +00:00
case QAccessible : : ObjectReorder : {
if ( sendObject | | sendObject_children_changed )
childrenChanged ( event - > accessibleInterface ( ) ) ;
break ;
}
2012-05-10 21:52:05 +00:00
case QAccessible : : NameChanged : {
if ( sendObject | | sendObject_property_change | | sendObject_property_change_accessible_name ) {
2013-01-03 16:18:40 +00:00
QString path = pathForInterface ( event - > accessibleInterface ( ) ) ;
2022-04-11 13:54:50 +00:00
QVariantList args = packDBusSignalArguments ( " accessible-name " _L1 , 0 , 0 , variantForPath ( path ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 ,
" PropertyChange " _L1 , args ) ;
2012-05-10 21:52:05 +00:00
}
break ;
}
case QAccessible : : DescriptionChanged : {
if ( sendObject | | sendObject_property_change | | sendObject_property_change_accessible_description ) {
2013-01-03 16:18:40 +00:00
QString path = pathForInterface ( event - > accessibleInterface ( ) ) ;
2022-04-11 13:54:50 +00:00
QVariantList args = packDBusSignalArguments ( " accessible-description " _L1 , 0 , 0 , variantForPath ( path ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 ,
" PropertyChange " _L1 , args ) ;
2012-05-10 21:52:05 +00:00
}
break ;
}
case QAccessible : : Focus : {
if ( sendFocus | | sendObject | | sendObject_state_changed )
2013-01-03 16:18:40 +00:00
sendFocusChanged ( event - > accessibleInterface ( ) ) ;
2012-05-10 21:52:05 +00:00
break ;
}
case QAccessible : : TextInserted :
case QAccessible : : TextRemoved :
case QAccessible : : TextUpdated : {
if ( sendObject | | sendObject_text_changed ) {
2013-01-03 16:18:40 +00:00
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
2012-12-11 19:31:00 +00:00
if ( ! iface | | ! iface - > textInterface ( ) ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " Received text event for invalid interface. " ;
2012-12-11 19:31:00 +00:00
return ;
}
2012-05-10 21:52:05 +00:00
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 ( ) ;
2019-10-30 09:11:20 +00:00
} else if ( event - > type ( ) = = QAccessible : : TextUpdated ) {
2012-05-10 21:52:05 +00:00
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 ) ) ;
2022-04-11 13:54:50 +00:00
QVariantList args = packDBusSignalArguments ( " delete " _L1 , changePosition , textRemoved . length ( ) , QVariant : : fromValue ( data ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 ,
" TextChanged " _L1 , args ) ;
2012-05-10 21:52:05 +00:00
}
if ( ! textInserted . isEmpty ( ) ) {
data . setVariant ( QVariant : : fromValue ( textInserted ) ) ;
2022-04-11 13:54:50 +00:00
QVariantList args = packDBusSignalArguments ( " insert " _L1 , changePosition , textInserted . length ( ) , QVariant : : fromValue ( data ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 ,
" TextChanged " _L1 , args ) ;
2012-05-10 21:52:05 +00:00
}
// send a cursor update
2020-06-27 12:18:09 +00:00
Q_UNUSED ( cursorPosition ) ;
2012-05-10 21:52:05 +00:00
// QDBusVariant cursorData;
// cursorData.setVariant(QVariant::fromValue(cursorPosition));
// QVariantList args = packDBusSignalArguments(QString(), cursorPosition, 0, QVariant::fromValue(cursorData));
2022-04-11 13:54:50 +00:00
// sendDBusSignal(path, ATSPI_DBUS_INTERFACE_EVENT_OBJECT ""_L1,
// "TextCaretMoved"_L1, args);
2012-05-10 21:52:05 +00:00
}
break ;
}
case QAccessible : : TextCaretMoved : {
if ( sendObject | | sendObject_text_caret_moved ) {
2013-01-03 16:18:40 +00:00
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
2012-12-11 19:31:00 +00:00
if ( ! iface | | ! iface - > textInterface ( ) ) {
2017-06-16 14:37:03 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " Sending TextCaretMoved from object that does not implement text interface: " < < iface ;
2012-10-18 14:24:37 +00:00
return ;
}
2012-05-10 21:52:05 +00:00
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 ) ) ;
2022-04-11 13:54:50 +00:00
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 ,
" TextCaretMoved " _L1 , args ) ;
2012-05-10 21:52:05 +00:00
}
break ;
}
case QAccessible : : TextSelectionChanged : {
if ( sendObject | | sendObject_text_selection_changed ) {
2013-01-03 16:18:40 +00:00
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
2012-05-10 21:52:05 +00:00
QString path = pathForInterface ( iface ) ;
QVariantList args = packDBusSignalArguments ( QString ( ) , 0 , 0 , QVariant : : fromValue ( QDBusVariant ( QVariant ( QString ( ) ) ) ) ) ;
2022-04-11 13:54:50 +00:00
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 ,
" TextSelectionChanged " _L1 , args ) ;
2012-05-10 21:52:05 +00:00
}
break ;
}
case QAccessible : : ValueChanged : {
2012-11-03 18:21:12 +00:00
if ( sendObject | | sendObject_value_changed | | sendObject_property_change_accessible_value ) {
2013-01-03 16:18:40 +00:00
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
2014-05-07 14:06:22 +00:00
if ( ! iface ) {
2017-06-16 14:37:03 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " ValueChanged event from invalid accessible. " ;
2012-12-11 19:31:00 +00:00
return ;
}
2014-05-07 14:06:22 +00:00
if ( iface - > valueInterface ( ) ) {
QString path = pathForInterface ( iface ) ;
2022-04-11 13:54:50 +00:00
QVariantList args = packDBusSignalArguments ( " accessible-value " _L1 , 0 , 0 , variantForPath ( path ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 ,
" PropertyChange " _L1 , args ) ;
2014-05-07 14:06:22 +00:00
} 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 ) ;
2022-04-11 13:54:50 +00:00
QVariantList args1 = packDBusSignalArguments ( " accessible-name " _L1 , 0 , 0 , variantForPath ( path ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 ,
" PropertyChange " _L1 , args1 ) ;
2014-05-07 14:06:22 +00:00
QVariantList args2 = packDBusSignalArguments ( QString ( ) , 0 , 0 , QVariant : : fromValue ( QDBusVariant ( QVariant ( 0 ) ) ) ) ;
2022-04-11 13:54:50 +00:00
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 ,
" SelectionChanged " _L1 , args2 ) ;
2014-05-07 14:06:22 +00:00
} else {
2017-06-16 14:37:03 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " ValueChanged event and no ValueInterface or ComboBox: " < < iface ;
2014-05-07 14:06:22 +00:00
}
2012-05-10 21:52:05 +00:00
}
break ;
}
2014-07-01 13:39:32 +00:00
case QAccessible : : SelectionAdd :
case QAccessible : : SelectionRemove :
2012-05-10 21:52:05 +00:00
case QAccessible : : Selection : {
2013-01-03 16:18:40 +00:00
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
2012-12-11 19:31:00 +00:00
if ( ! iface ) {
2017-06-16 14:37:03 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " Selection event from invalid accessible. " ;
2012-12-11 19:31:00 +00:00
return ;
}
2012-05-10 21:52:05 +00:00
QString path = pathForInterface ( iface ) ;
int selected = iface - > state ( ) . selected ? 1 : 0 ;
2022-04-11 13:54:50 +00:00
QVariantList stateArgs = packDBusSignalArguments ( " selected " _L1 , selected , 0 , variantForPath ( path ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " StateChanged " _L1 , stateArgs ) ;
2012-05-10 21:52:05 +00:00
break ;
}
case QAccessible : : StateChanged : {
if ( sendObject | | sendObject_state_changed | | sendWindow | | sendWindow_activate ) {
QAccessible : : State stateChange = static_cast < QAccessibleStateChangeEvent * > ( event ) - > changedStates ( ) ;
if ( stateChange . checked ) {
2013-01-03 16:18:40 +00:00
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
2012-12-11 19:31:00 +00:00
if ( ! iface ) {
2017-06-16 14:37:03 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " StateChanged event from invalid accessible. " ;
2012-12-11 19:31:00 +00:00
return ;
}
2012-05-10 21:52:05 +00:00
int checked = iface - > state ( ) . checked ;
2022-04-11 13:54:50 +00:00
notifyStateChange ( iface , " checked " _L1 , checked ) ;
2012-05-10 21:52:05 +00:00
} else if ( stateChange . active ) {
2013-01-03 16:18:40 +00:00
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
2012-12-11 19:31:00 +00:00
if ( ! iface | | ! ( iface - > role ( ) = = QAccessible : : Window & & ( sendWindow | | sendWindow_activate ) ) )
2012-05-10 21:52:05 +00:00
return ;
2014-06-19 13:36:32 +00:00
int isActive = iface - > state ( ) . active ;
2012-05-10 21:52:05 +00:00
QString windowTitle = iface - > text ( QAccessible : : Name ) ;
QDBusVariant data ;
data . setVariant ( windowTitle ) ;
QVariantList args = packDBusSignalArguments ( QString ( ) , 0 , 0 , QVariant : : fromValue ( data ) ) ;
2022-04-11 13:54:50 +00:00
QString status = isActive ? " Activate " _L1 : " Deactivate " _L1 ;
2012-05-10 21:52:05 +00:00
QString path = pathForInterface ( iface ) ;
2022-04-11 13:54:50 +00:00
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_WINDOW " " _L1 , status , args ) ;
notifyStateChange ( iface , " active " _L1 , isActive ) ;
2012-10-26 14:56:00 +00:00
} else if ( stateChange . disabled ) {
2013-01-03 16:18:40 +00:00
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
2012-10-26 14:56:00 +00:00
QAccessible : : State state = iface - > state ( ) ;
bool enabled = ! state . disabled ;
2022-04-11 13:54:50 +00:00
notifyStateChange ( iface , " enabled " _L1 , enabled ) ;
notifyStateChange ( iface , " sensitive " _L1 , enabled ) ;
2012-05-10 21:52:05 +00:00
}
}
break ;
}
2013-02-20 11:02:17 +00:00
// For now we ignore these events
2013-01-31 12:48:09 +00:00
case QAccessible : : TableModelChanged :
2013-02-20 11:02:17 +00:00
// For tables, setting manages_descendants should
// indicate to the client that it cannot cache these
// interfaces.
2012-05-10 21:52:05 +00:00
case QAccessible : : ParentChanged :
case QAccessible : : DialogStart :
case QAccessible : : DialogEnd :
2013-02-20 11:02:17 +00:00
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 :
2012-05-10 21:52:05 +00:00
break ;
}
}
2013-01-03 16:18:40 +00:00
void AtSpiAdaptor : : sendFocusChanged ( QAccessibleInterface * interface ) const
2012-05-10 21:52:05 +00:00
{
static QString lastFocusPath ;
// "remove" old focus
if ( ! lastFocusPath . isEmpty ( ) ) {
2022-04-11 13:54:50 +00:00
QVariantList stateArgs = packDBusSignalArguments ( " focused " _L1 , 0 , 0 , variantForPath ( lastFocusPath ) ) ;
sendDBusSignal ( lastFocusPath , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 ,
" StateChanged " _L1 , stateArgs ) ;
2012-05-10 21:52:05 +00:00
}
// send new focus
{
QString path = pathForInterface ( interface ) ;
2022-04-11 13:54:50 +00:00
QVariantList stateArgs = packDBusSignalArguments ( " focused " _L1 , 1 , 0 , variantForPath ( path ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 ,
" StateChanged " _L1 , stateArgs ) ;
2012-05-10 21:52:05 +00:00
QVariantList focusArgs = packDBusSignalArguments ( QString ( ) , 0 , 0 , variantForPath ( path ) ) ;
2022-04-11 13:54:50 +00:00
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_FOCUS " " _L1 , " Focus " _L1 , focusArgs ) ;
2012-05-10 21:52:05 +00:00
lastFocusPath = path ;
}
}
2014-07-19 08:02:23 +00:00
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 ) ) ;
2022-04-11 13:54:50 +00:00
QVariantList args = packDBusSignalArguments ( " add " _L1 , childCount , 0 , childPath ) ;
sendDBusSignal ( parentPath , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " ChildrenChanged " _L1 , args ) ;
2014-07-19 08:02:23 +00:00
}
}
2013-01-03 16:18:40 +00:00
void AtSpiAdaptor : : notifyAboutCreation ( QAccessibleInterface * interface ) const
2012-05-10 21:52:05 +00:00
{
// // say hello to d-bus
// cache->emitAddAccessible(accessible->getCacheItem());
// notify about the new child of our parent
2013-01-03 16:18:40 +00:00
QAccessibleInterface * parent = interface - > parent ( ) ;
2012-05-10 21:52:05 +00:00
if ( ! parent ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " AtSpiAdaptor::notifyAboutCreation: Could not find parent for " < < interface - > object ( ) ;
2012-05-10 21:52:05 +00:00
return ;
}
QString path = pathForInterface ( interface ) ;
int childCount = parent - > childCount ( ) ;
QString parentPath = pathForInterface ( parent ) ;
2022-04-11 13:54:50 +00:00
QVariantList args = packDBusSignalArguments ( " add " _L1 , childCount , 0 , variantForPath ( path ) ) ;
sendDBusSignal ( parentPath , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " ChildrenChanged " _L1 , args ) ;
2012-05-10 21:52:05 +00:00
}
2013-01-03 16:18:40 +00:00
void AtSpiAdaptor : : notifyAboutDestruction ( QAccessibleInterface * interface ) const
2012-05-10 21:52:05 +00:00
{
2013-02-06 09:23:24 +00:00
if ( ! interface | | ! interface - > isValid ( ) )
2012-05-10 21:52:05 +00:00
return ;
2013-01-03 16:18:40 +00:00
QAccessibleInterface * parent = interface - > parent ( ) ;
2012-05-10 21:52:05 +00:00
if ( ! parent ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " AtSpiAdaptor::notifyAboutDestruction: Could not find parent for " < < interface - > object ( ) ;
2012-05-10 21:52:05 +00:00
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);
// }
2013-01-03 16:18:40 +00:00
QString parentPath = pathForInterface ( parent ) ;
2022-04-11 13:54:50 +00:00
QVariantList args = packDBusSignalArguments ( " remove " _L1 , childIndex , 0 , variantForPath ( path ) ) ;
sendDBusSignal ( parentPath , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " ChildrenChanged " _L1 , args ) ;
2012-05-10 21:52:05 +00:00
}
/*!
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
2013-01-03 16:18:40 +00:00
QAccessibleInterface * accessible = interfaceFromPath ( message . path ( ) ) ;
2012-05-10 21:52:05 +00:00
if ( ! accessible ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING Qt AtSpiAdaptor: Could not find accessible on path: " < < message . path ( ) ;
2012-05-10 21:52:05 +00:00
return false ;
}
2012-10-01 12:09:50 +00:00
if ( ! accessible - > isValid ( ) ) {
2017-06-16 14:37:03 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " WARNING Qt AtSpiAdaptor: Accessible invalid: " < < accessible < < message . path ( ) ;
2012-10-01 12:09:50 +00:00
return false ;
}
2012-05-10 21:52:05 +00:00
QString interface = message . interface ( ) ;
QString function = message . member ( ) ;
2017-06-16 14:37:03 +00:00
// qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::handleMessage: " << interface << function;
2012-05-10 21:52:05 +00:00
2022-04-11 13:54:50 +00:00
if ( function = = " Introspect " _L1 ) {
2012-05-10 21:52:05 +00:00
//introspect(message.path());
return false ;
}
// handle properties like regular functions
2022-04-11 13:54:50 +00:00
if ( interface = = " org.freedesktop.DBus.Properties " _L1 ) {
2012-05-10 21:52:05 +00:00
interface = message . arguments ( ) . at ( 0 ) . toString ( ) ;
// Get/Set + Name
function = message . member ( ) + message . arguments ( ) . at ( 1 ) . toString ( ) ;
}
// switch interface to call
2022-04-11 13:54:50 +00:00
if ( interface = = ATSPI_DBUS_INTERFACE_ACCESSIBLE " " _L1 )
2012-05-10 21:52:05 +00:00
return accessibleInterface ( accessible , function , message , connection ) ;
2022-04-11 13:54:50 +00:00
if ( interface = = ATSPI_DBUS_INTERFACE_APPLICATION " " _L1 )
2012-05-10 21:52:05 +00:00
return applicationInterface ( accessible , function , message , connection ) ;
2022-04-11 13:54:50 +00:00
if ( interface = = ATSPI_DBUS_INTERFACE_COMPONENT " " _L1 )
2012-05-10 21:52:05 +00:00
return componentInterface ( accessible , function , message , connection ) ;
2022-04-11 13:54:50 +00:00
if ( interface = = ATSPI_DBUS_INTERFACE_ACTION " " _L1 )
2012-05-10 21:52:05 +00:00
return actionInterface ( accessible , function , message , connection ) ;
2022-04-11 13:54:50 +00:00
if ( interface = = ATSPI_DBUS_INTERFACE_TEXT " " _L1 )
2012-05-10 21:52:05 +00:00
return textInterface ( accessible , function , message , connection ) ;
2022-04-11 13:54:50 +00:00
if ( interface = = ATSPI_DBUS_INTERFACE_EDITABLE_TEXT " " _L1 )
2012-05-10 21:52:05 +00:00
return editableTextInterface ( accessible , function , message , connection ) ;
2022-04-11 13:54:50 +00:00
if ( interface = = ATSPI_DBUS_INTERFACE_VALUE " " _L1 )
2012-05-10 21:52:05 +00:00
return valueInterface ( accessible , function , message , connection ) ;
2022-04-11 13:54:50 +00:00
if ( interface = = ATSPI_DBUS_INTERFACE_TABLE " " _L1 )
2012-05-10 21:52:05 +00:00
return tableInterface ( accessible , function , message , connection ) ;
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " AtSpiAdaptor::handleMessage with unknown interface: " < < message . path ( ) < < interface < < function ;
2012-05-10 21:52:05 +00:00
return false ;
}
// Application
2013-01-03 16:18:40 +00:00
bool AtSpiAdaptor : : applicationInterface ( QAccessibleInterface * interface , const QString & function , const QDBusMessage & message , const QDBusConnection & connection )
2012-05-10 21:52:05 +00:00
{
2022-04-11 13:54:50 +00:00
if ( message . path ( ) ! = ATSPI_DBUS_PATH_ROOT " " _L1 ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING Qt AtSpiAdaptor: Could not find application interface for: " < < message . path ( ) < < interface ;
2012-05-10 21:52:05 +00:00
return false ;
}
2022-04-11 13:54:50 +00:00
if ( function = = " SetId " _L1 ) {
Q_ASSERT ( message . signature ( ) = = " ssv " _L1 ) ;
2012-05-10 21:52:05 +00:00
QVariant value = qvariant_cast < QDBusVariant > ( message . arguments ( ) . at ( 2 ) ) . variant ( ) ;
m_applicationId = value . toInt ( ) ;
return true ;
}
2022-04-11 13:54:50 +00:00
if ( function = = " GetId " _L1 ) {
Q_ASSERT ( message . signature ( ) = = " ss " _L1 ) ;
2012-05-10 21:52:05 +00:00
QDBusMessage reply = message . createReply ( QVariant : : fromValue ( QDBusVariant ( m_applicationId ) ) ) ;
return connection . send ( reply ) ;
}
2022-04-11 13:54:50 +00:00
if ( function = = " GetToolkitName " _L1 ) {
Q_ASSERT ( message . signature ( ) = = " ss " _L1 ) ;
QDBusMessage reply = message . createReply ( QVariant : : fromValue ( QDBusVariant ( " Qt " _L1 ) ) ) ;
2012-05-10 21:52:05 +00:00
return connection . send ( reply ) ;
}
2022-04-11 13:54:50 +00:00
if ( function = = " GetVersion " _L1 ) {
Q_ASSERT ( message . signature ( ) = = " ss " _L1 ) ;
2022-04-11 15:27:52 +00:00
QDBusMessage reply = message . createReply ( QVariant : : fromValue ( QDBusVariant ( QLatin1StringView ( qVersion ( ) ) ) ) ) ;
2012-09-28 18:18:22 +00:00
return connection . send ( reply ) ;
}
2022-04-11 13:54:50 +00:00
if ( function = = " GetLocale " _L1 ) {
Q_ASSERT ( message . signature ( ) = = " u " _L1 ) ;
2012-09-28 18:18:22 +00:00
QDBusMessage reply = message . createReply ( QVariant : : fromValue ( QLocale ( ) . name ( ) ) ) ;
return connection . send ( reply ) ;
}
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " AtSpiAdaptor::applicationInterface " < < message . path ( ) < < interface < < function ;
2012-05-10 21:52:05 +00:00
return false ;
}
/*!
Register this application as accessible on the accessibility DBus .
*/
void AtSpiAdaptor : : registerApplication ( )
{
OrgA11yAtspiSocketInterface * registry ;
2022-04-11 13:54:50 +00:00
registry = new OrgA11yAtspiSocketInterface ( QSPI_REGISTRY_NAME " " _L1 ,
QSPI_OBJECT_PATH_ROOT " " _L1 , m_dbus - > connection ( ) ) ;
2012-05-10 21:52:05 +00:00
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 {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " Error in contacting registry: "
2012-09-28 16:04:37 +00:00
< < reply . error ( ) . name ( )
< < reply . error ( ) . message ( ) ;
2012-05-10 21:52:05 +00:00
}
delete registry ;
}
// Accessible
2013-01-03 16:18:40 +00:00
bool AtSpiAdaptor : : accessibleInterface ( QAccessibleInterface * interface , const QString & function , const QDBusMessage & message , const QDBusConnection & connection )
2012-05-10 21:52:05 +00:00
{
2022-04-11 13:54:50 +00:00
if ( function = = " GetRole " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , ( uint ) getRole ( interface ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetName " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue ( QDBusVariant ( interface - > text ( QAccessible : : Name ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetRoleName " _L1 ) {
2020-07-02 11:24:47 +00:00
sendReply ( connection , message , QSpiAccessibleBridge : : namesForRole ( interface - > role ( ) ) . name ( ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetLocalizedRoleName " _L1 ) {
2020-07-02 11:24:47 +00:00
sendReply ( connection , message , QVariant : : fromValue ( QSpiAccessibleBridge : : namesForRole ( interface - > role ( ) ) . localizedName ( ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetChildCount " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue ( QDBusVariant ( interface - > childCount ( ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetIndexInParent " _L1 ) {
2012-05-10 21:52:05 +00:00
int childIndex = - 1 ;
2013-01-03 16:18:40 +00:00
QAccessibleInterface * parent = interface - > parent ( ) ;
2012-05-10 21:52:05 +00:00
if ( parent ) {
2013-01-03 16:18:40 +00:00
childIndex = parent - > indexOfChild ( interface ) ;
2012-09-28 16:04:37 +00:00
if ( childIndex < 0 ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " GetIndexInParent get invalid index: " < < childIndex < < interface ;
2012-09-28 16:04:37 +00:00
}
2012-05-10 21:52:05 +00:00
}
sendReply ( connection , message , childIndex ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetParent " _L1 ) {
2012-05-10 21:52:05 +00:00
QString path ;
2013-01-03 16:18:40 +00:00
QAccessibleInterface * parent = interface - > parent ( ) ;
2012-05-10 21:52:05 +00:00
if ( ! parent ) {
2022-04-11 13:54:50 +00:00
path = ATSPI_DBUS_PATH_NULL " " _L1 ;
2012-05-10 21:52:05 +00:00
} else if ( parent - > role ( ) = = QAccessible : : Application ) {
2022-04-11 13:54:50 +00:00
path = ATSPI_DBUS_PATH_ROOT " " _L1 ;
2012-05-10 21:52:05 +00:00
} 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 ) ) ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetChildAtIndex " _L1 ) {
2017-01-17 11:48:08 +00:00
const int index = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
2012-05-10 21:52:05 +00:00
if ( index < 0 ) {
sendReply ( connection , message , QVariant : : fromValue (
QSpiObjectReference ( connection , QDBusObjectPath ( ATSPI_DBUS_PATH_NULL ) ) ) ) ;
} else {
2013-01-03 16:18:40 +00:00
QAccessibleInterface * childInterface = interface - > child ( index ) ;
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue (
QSpiObjectReference ( connection , QDBusObjectPath ( pathForInterface ( childInterface ) ) ) ) ) ;
}
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetInterfaces " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , accessibleInterfaces ( interface ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetDescription " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue ( QDBusVariant ( interface - > text ( QAccessible : : Description ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetState " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetAttributes " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue ( QSpiAttributeSet ( ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetRelationSet " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue ( relationSet ( interface , connection ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetApplication " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue (
QSpiObjectReference ( connection , QDBusObjectPath ( QSPI_OBJECT_PATH_ROOT ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetChildren " _L1 ) {
2012-05-10 21:52:05 +00:00
QSpiObjectReferenceArray children ;
2015-06-23 15:18:12 +00:00
const int numChildren = interface - > childCount ( ) ;
children . reserve ( numChildren ) ;
for ( int i = 0 ; i < numChildren ; + + i ) {
2013-01-03 16:18:40 +00:00
QString childPath = pathForInterface ( interface - > child ( i ) ) ;
2012-05-10 21:52:05 +00:00
QSpiObjectReference ref ( connection , QDBusObjectPath ( childPath ) ) ;
children < < ref ;
}
connection . send ( message . createReply ( QVariant : : fromValue ( children ) ) ) ;
} else {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: AtSpiAdaptor::accessibleInterface does not implement " < < function < < message . path ( ) ;
2012-05-10 21:52:05 +00:00
return false ;
}
return true ;
}
2013-01-03 16:18:40 +00:00
AtspiRole AtSpiAdaptor : : getRole ( QAccessibleInterface * interface ) const
2012-05-10 21:52:05 +00:00
{
if ( ( interface - > role ( ) = = QAccessible : : EditableText ) & & interface - > state ( ) . passwordEdit )
return ATSPI_ROLE_PASSWORD_TEXT ;
2020-07-02 11:24:47 +00:00
return QSpiAccessibleBridge : : namesForRole ( interface - > role ( ) ) . spiRole ( ) ;
2012-05-10 21:52:05 +00:00
}
2013-01-03 16:18:40 +00:00
QStringList AtSpiAdaptor : : accessibleInterfaces ( QAccessibleInterface * interface ) const
2012-05-10 21:52:05 +00:00
{
QStringList ifaces ;
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspiCreation ) < < " AtSpiAdaptor::accessibleInterfaces create: " < < interface - > object ( ) ;
2022-04-11 13:54:50 +00:00
ifaces < < ATSPI_DBUS_INTERFACE_ACCESSIBLE " " _L1 ;
2012-05-10 21:52:05 +00:00
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 " ) )
) {
2022-04-11 13:54:50 +00:00
ifaces < < ATSPI_DBUS_INTERFACE_COMPONENT " " _L1 ;
2017-06-16 14:37:03 +00:00
} else {
qCDebug ( lcAccessibilityAtspiCreation ) < < " IS NOT a component " ;
2012-05-10 21:52:05 +00:00
}
2012-09-28 18:15:02 +00:00
if ( interface - > role ( ) = = QAccessible : : Application )
2022-04-11 13:54:50 +00:00
ifaces < < ATSPI_DBUS_INTERFACE_APPLICATION " " _L1 ;
2012-05-10 21:52:05 +00:00
2014-06-20 12:05:09 +00:00
if ( interface - > actionInterface ( ) | | interface - > valueInterface ( ) )
2022-04-11 13:54:50 +00:00
ifaces < < ATSPI_DBUS_INTERFACE_ACTION " " _L1 ;
2012-05-10 21:52:05 +00:00
if ( interface - > textInterface ( ) )
2022-04-11 13:54:50 +00:00
ifaces < < ATSPI_DBUS_INTERFACE_TEXT " " _L1 ;
2012-05-10 21:52:05 +00:00
if ( interface - > editableTextInterface ( ) )
2022-04-11 13:54:50 +00:00
ifaces < < ATSPI_DBUS_INTERFACE_EDITABLE_TEXT " " _L1 ;
2012-05-10 21:52:05 +00:00
if ( interface - > valueInterface ( ) )
2022-04-11 13:54:50 +00:00
ifaces < < ATSPI_DBUS_INTERFACE_VALUE " " _L1 ;
2012-05-10 21:52:05 +00:00
if ( interface - > tableInterface ( ) )
2022-04-11 13:54:50 +00:00
ifaces < < ATSPI_DBUS_INTERFACE_TABLE " " _L1 ;
2012-05-10 21:52:05 +00:00
return ifaces ;
}
2013-01-03 16:18:40 +00:00
QSpiRelationArray AtSpiAdaptor : : relationSet ( QAccessibleInterface * interface , const QDBusConnection & connection ) const
2012-05-10 21:52:05 +00:00
{
typedef QPair < QAccessibleInterface * , QAccessible : : Relation > RelationPair ;
2020-07-06 10:04:36 +00:00
const QList < RelationPair > relationInterfaces = interface - > relations ( ) ;
2012-05-10 21:52:05 +00:00
QSpiRelationArray relations ;
2016-08-08 13:50:35 +00:00
for ( const RelationPair & pair : relationInterfaces ) {
2012-05-10 21:52:05 +00:00
// 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
2015-07-05 20:43:08 +00:00
QSpiObjectReferenceArray related ;
2012-05-10 21:52:05 +00:00
2013-01-03 16:18:40 +00:00
QDBusObjectPath path = QDBusObjectPath ( pathForInterface ( pair . first ) ) ;
2012-05-10 21:52:05 +00:00
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 ) ;
2013-01-03 16:18:40 +00:00
if ( inheritsQAction ( object ) ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " AtSpiAdaptor::pathForObject: warning: creating path with QAction as object. " ;
2012-05-10 21:52:05 +00:00
}
2013-01-03 16:18:40 +00:00
QAccessibleInterface * iface = QAccessible : : queryAccessibleInterface ( object ) ;
return pathForInterface ( iface ) ;
2012-05-10 21:52:05 +00:00
}
2013-01-03 16:18:40 +00:00
QString AtSpiAdaptor : : pathForInterface ( QAccessibleInterface * interface ) const
2012-05-10 21:52:05 +00:00
{
if ( ! interface | | ! interface - > isValid ( ) )
2022-04-11 13:54:50 +00:00
return ATSPI_DBUS_PATH_NULL " " _L1 ;
2012-05-10 21:52:05 +00:00
if ( interface - > role ( ) = = QAccessible : : Application )
2022-04-11 13:54:50 +00:00
return QSPI_OBJECT_PATH_ROOT " " _L1 ;
2012-05-10 21:52:05 +00:00
2013-01-03 16:18:40 +00:00
QAccessible : : Id id = QAccessible : : uniqueId ( interface ) ;
Q_ASSERT ( ( int ) id < 0 ) ;
2022-04-11 13:54:50 +00:00
return QSPI_OBJECT_PATH_PREFIX " " _L1 + QString : : number ( id ) ;
2012-05-10 21:52:05 +00:00
}
bool AtSpiAdaptor : : inheritsQAction ( QObject * object )
{
const QMetaObject * mo = object - > metaObject ( ) ;
while ( mo ) {
2022-04-11 15:27:52 +00:00
const QLatin1StringView cn ( mo - > className ( ) ) ;
2022-04-11 13:54:50 +00:00
if ( cn = = " QAction " _L1 )
2012-05-10 21:52:05 +00:00
return true ;
mo = mo - > superClass ( ) ;
}
return false ;
}
// Component
2013-01-03 16:18:40 +00:00
static QAccessibleInterface * getWindow ( QAccessibleInterface * interface )
2012-05-10 21:52:05 +00:00
{
if ( interface - > role ( ) = = QAccessible : : Window )
return interface ;
2013-01-03 16:18:40 +00:00
QAccessibleInterface * parent = interface - > parent ( ) ;
2012-05-10 21:52:05 +00:00
while ( parent & & parent - > role ( ) ! = QAccessible : : Window )
2013-01-03 16:18:40 +00:00
parent = parent - > parent ( ) ;
2012-05-10 21:52:05 +00:00
return parent ;
}
2013-01-03 16:18:40 +00:00
static QRect getRelativeRect ( QAccessibleInterface * interface )
2012-05-10 21:52:05 +00:00
{
2013-01-03 16:18:40 +00:00
QAccessibleInterface * window ;
2012-05-10 21:52:05 +00:00
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 ;
}
2013-01-03 16:18:40 +00:00
bool AtSpiAdaptor : : componentInterface ( QAccessibleInterface * interface , const QString & function , const QDBusMessage & message , const QDBusConnection & connection )
2012-05-10 21:52:05 +00:00
{
2022-04-11 13:54:50 +00:00
if ( function = = " Contains " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetAccessibleAtPoint " _L1 ) {
2012-05-10 21:52:05 +00:00
int x = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
int y = message . arguments ( ) . at ( 1 ) . toInt ( ) ;
uint coordType = message . arguments ( ) . at ( 2 ) . toUInt ( ) ;
2017-09-15 18:15:00 +00:00
if ( coordType = = ATSPI_COORD_TYPE_WINDOW ) {
QWindow * window = interface - > window ( ) ;
if ( window ) {
x + = window - > position ( ) . x ( ) ;
y + = window - > position ( ) . y ( ) ;
}
}
2012-05-10 21:52:05 +00:00
2013-01-03 16:18:40 +00:00
QAccessibleInterface * childInterface ( interface - > childAt ( x , y ) ) ;
2020-07-29 14:30:13 +00:00
QAccessibleInterface * iface = nullptr ;
2012-05-10 21:52:05 +00:00
while ( childInterface ) {
iface = childInterface ;
2013-01-03 16:18:40 +00:00
childInterface = iface - > childAt ( x , y ) ;
2012-05-10 21:52:05 +00:00
}
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 ) ) ) ) ;
}
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetAlpha " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , ( double ) 1.0 ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetExtents " _L1 ) {
2012-05-10 21:52:05 +00:00
uint coordType = message . arguments ( ) . at ( 0 ) . toUInt ( ) ;
sendReply ( connection , message , QVariant : : fromValue ( getExtents ( interface , coordType ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetLayer " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue ( ( uint ) 1 ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetMDIZOrder " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue ( ( short ) 0 ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetPosition " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetSize " _L1 ) {
2012-05-10 21:52:05 +00:00
QRect rect = interface - > rect ( ) ;
QVariantList size ;
size < < rect . width ( ) < < rect . height ( ) ;
connection . send ( message . createReply ( size ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GrabFocus " _L1 ) {
2014-07-03 14:15:21 +00:00
QAccessibleActionInterface * actionIface = interface - > actionInterface ( ) ;
if ( actionIface & & actionIface - > actionNames ( ) . contains ( QAccessibleActionInterface : : setFocusAction ( ) ) ) {
actionIface - > doAction ( QAccessibleActionInterface : : setFocusAction ( ) ) ;
sendReply ( connection , message , true ) ;
} else {
sendReply ( connection , message , false ) ;
}
2022-04-11 13:54:50 +00:00
} else if ( function = = " SetExtents " _L1 ) {
2012-05-10 21:52:05 +00:00
// 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();
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " SetExtents is not implemented. " ;
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , false ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " SetPosition " _L1 ) {
2012-05-10 21:52:05 +00:00
// int x = message.arguments().at(0).toInt();
// int y = message.arguments().at(1).toInt();
// uint coordinateType = message.arguments().at(2).toUInt();
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " SetPosition is not implemented. " ;
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , false ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " SetSize " _L1 ) {
2012-05-10 21:52:05 +00:00
// int width = message.arguments().at(0).toInt();
// int height = message.arguments().at(1).toInt();
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " SetSize is not implemented. " ;
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , false ) ;
} else {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: AtSpiAdaptor::componentInterface does not implement " < < function < < message . path ( ) ;
2012-05-10 21:52:05 +00:00
return false ;
}
return true ;
}
2013-01-03 16:18:40 +00:00
QRect AtSpiAdaptor : : getExtents ( QAccessibleInterface * interface , uint coordType )
2012-05-10 21:52:05 +00:00
{
return ( coordType = = ATSPI_COORD_TYPE_SCREEN ) ? interface - > rect ( ) : getRelativeRect ( interface ) ;
}
// Action interface
2013-01-03 16:18:40 +00:00
bool AtSpiAdaptor : : actionInterface ( QAccessibleInterface * interface , const QString & function , const QDBusMessage & message , const QDBusConnection & connection )
2012-05-10 21:52:05 +00:00
{
2022-04-11 13:54:50 +00:00
if ( function = = " GetNActions " _L1 ) {
2014-06-20 12:05:09 +00:00
int count = QAccessibleBridgeUtils : : effectiveActionNames ( interface ) . count ( ) ;
sendReply ( connection , message , QVariant : : fromValue ( QDBusVariant ( QVariant : : fromValue ( count ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " DoAction " _L1 ) {
2012-05-10 21:52:05 +00:00
int index = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
2014-06-20 12:05:09 +00:00
const QStringList actionNames = QAccessibleBridgeUtils : : effectiveActionNames ( interface ) ;
if ( index < 0 | | index > = actionNames . count ( ) )
2012-05-10 21:52:05 +00:00
return false ;
2014-06-20 12:05:09 +00:00
const QString actionName = actionNames . at ( index ) ;
bool success = QAccessibleBridgeUtils : : performEffectiveAction ( interface , actionName ) ;
sendReply ( connection , message , success ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetActions " _L1 ) {
2014-06-20 12:05:09 +00:00
sendReply ( connection , message , QVariant : : fromValue ( getActions ( interface ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetName " _L1 ) {
2012-05-10 21:52:05 +00:00
int index = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
2014-06-20 12:05:09 +00:00
const QStringList actionNames = QAccessibleBridgeUtils : : effectiveActionNames ( interface ) ;
if ( index < 0 | | index > = actionNames . count ( ) )
2012-05-10 21:52:05 +00:00
return false ;
2014-06-20 12:05:09 +00:00
sendReply ( connection , message , actionNames . at ( index ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetDescription " _L1 ) {
2012-05-10 21:52:05 +00:00
int index = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
2014-06-20 12:05:09 +00:00
const QStringList actionNames = QAccessibleBridgeUtils : : effectiveActionNames ( interface ) ;
if ( index < 0 | | index > = actionNames . count ( ) )
2012-05-10 21:52:05 +00:00
return false ;
2014-06-20 12:05:09 +00:00
QString description ;
if ( QAccessibleActionInterface * actionIface = interface - > actionInterface ( ) )
description = actionIface - > localizedActionDescription ( actionNames . at ( index ) ) ;
else
description = qAccessibleLocalizedActionDescription ( actionNames . at ( index ) ) ;
sendReply ( connection , message , description ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetKeyBinding " _L1 ) {
2012-05-10 21:52:05 +00:00
int index = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
2014-06-20 12:05:09 +00:00
const QStringList actionNames = QAccessibleBridgeUtils : : effectiveActionNames ( interface ) ;
if ( index < 0 | | index > = actionNames . count ( ) )
2012-05-10 21:52:05 +00:00
return false ;
QStringList keyBindings ;
2014-06-20 12:05:09 +00:00
if ( QAccessibleActionInterface * actionIface = interface - > actionInterface ( ) )
keyBindings = actionIface - > keyBindingsForAction ( actionNames . at ( index ) ) ;
2012-05-10 21:52:05 +00:00
if ( keyBindings . isEmpty ( ) ) {
QString acc = interface - > text ( QAccessible : : Accelerator ) ;
if ( ! acc . isEmpty ( ) )
keyBindings . append ( acc ) ;
}
if ( keyBindings . length ( ) > 0 )
2022-04-11 12:04:17 +00:00
sendReply ( connection , message , keyBindings . join ( u ' ; ' ) ) ;
2012-05-10 21:52:05 +00:00
else
sendReply ( connection , message , QString ( ) ) ;
} else {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: AtSpiAdaptor::actionInterface does not implement " < < function < < message . path ( ) ;
2012-05-10 21:52:05 +00:00
return false ;
}
return true ;
}
2014-06-20 12:05:09 +00:00
QSpiActionArray AtSpiAdaptor : : getActions ( QAccessibleInterface * interface ) const
2012-05-10 21:52:05 +00:00
{
2014-06-20 12:05:09 +00:00
QAccessibleActionInterface * actionInterface = interface - > actionInterface ( ) ;
2012-05-10 21:52:05 +00:00
QSpiActionArray actions ;
2015-06-23 15:18:12 +00:00
const QStringList actionNames = QAccessibleBridgeUtils : : effectiveActionNames ( interface ) ;
actions . reserve ( actionNames . size ( ) ) ;
2016-08-08 13:50:35 +00:00
for ( const QString & actionName : actionNames ) {
2012-05-10 21:52:05 +00:00
QSpiAction action ;
2014-01-03 07:53:57 +00:00
action . name = actionName ;
2014-06-20 12:05:09 +00:00
if ( actionInterface ) {
action . description = actionInterface - > localizedActionDescription ( actionName ) ;
2016-08-08 13:50:35 +00:00
const QStringList keyBindings = actionInterface - > keyBindingsForAction ( actionName ) ;
if ( ! keyBindings . isEmpty ( ) )
action . keyBinding = keyBindings . front ( ) ;
2014-06-20 12:05:09 +00:00
} else {
action . description = qAccessibleLocalizedActionDescription ( actionName ) ;
}
2012-05-10 21:52:05 +00:00
2016-08-08 13:50:35 +00:00
actions . append ( std : : move ( action ) ) ;
2012-05-10 21:52:05 +00:00
}
return actions ;
}
// Text interface
2013-01-03 16:18:40 +00:00
bool AtSpiAdaptor : : textInterface ( QAccessibleInterface * interface , const QString & function , const QDBusMessage & message , const QDBusConnection & connection )
2012-05-10 21:52:05 +00:00
{
if ( ! interface - > textInterface ( ) )
return false ;
// properties
2022-04-11 13:54:50 +00:00
if ( function = = " GetCaretOffset " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue ( QDBusVariant ( QVariant : : fromValue ( interface - > textInterface ( ) - > cursorPosition ( ) ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetCharacterCount " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue ( QDBusVariant ( QVariant : : fromValue ( interface - > textInterface ( ) - > characterCount ( ) ) ) ) ) ;
// functions
2022-04-11 13:54:50 +00:00
} else if ( function = = " AddSelection " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetAttributeRun " _L1 ) {
2012-05-10 21:52:05 +00:00
int offset = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
bool includeDefaults = message . arguments ( ) . at ( 1 ) . toBool ( ) ;
2020-06-27 12:18:09 +00:00
Q_UNUSED ( includeDefaults ) ;
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( getAttributes ( interface , offset , includeDefaults ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetAttributeValue " _L1 ) {
2012-05-10 21:52:05 +00:00
int offset = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
QString attributeName = message . arguments ( ) . at ( 1 ) . toString ( ) ;
connection . send ( message . createReply ( getAttributeValue ( interface , offset , attributeName ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetAttributes " _L1 ) {
2012-05-10 21:52:05 +00:00
int offset = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
connection . send ( message . createReply ( getAttributes ( interface , offset , true ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetBoundedRanges " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ( ) ;
2020-07-02 14:26:10 +00:00
Q_UNUSED ( x ) ;
Q_UNUSED ( y ) ;
Q_UNUSED ( width ) ;
Q_UNUSED ( height ) ;
Q_UNUSED ( coordType ) ;
Q_UNUSED ( xClipType ) ;
Q_UNUSED ( yClipType ) ;
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " Not implemented: QSpiAdaptor::GetBoundedRanges " ;
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , QVariant : : fromValue ( QSpiTextRangeList ( ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetCharacterAtOffset " _L1 ) {
2012-05-10 21:52:05 +00:00
int offset = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
int start ;
int end ;
2013-03-05 13:37:37 +00:00
QString result = interface - > textInterface ( ) - > textAtOffset ( offset , QAccessible : : CharBoundary , & start , & end ) ;
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , ( int ) * ( qPrintable ( result ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetCharacterExtents " _L1 ) {
2012-05-10 21:52:05 +00:00
int offset = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
int coordType = message . arguments ( ) . at ( 1 ) . toUInt ( ) ;
connection . send ( message . createReply ( getCharacterExtents ( interface , offset , coordType ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetDefaultAttributeSet " _L1 | | function = = " GetDefaultAttributes " _L1 ) {
2012-05-10 21:52:05 +00:00
// GetDefaultAttributes is deprecated in favour of GetDefaultAttributeSet.
// Empty set seems reasonable. There is no default attribute set.
sendReply ( connection , message , QVariant : : fromValue ( QSpiAttributeSet ( ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetNSelections " _L1 ) {
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , interface - > textInterface ( ) - > selectionCount ( ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetOffsetAtPoint " _L1 ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < message . signature ( ) ;
2012-05-10 21:52:05 +00:00
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 ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetRangeExtents " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetSelection " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetText " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetTextAfterOffset " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetTextAtOffset " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetTextBeforeOffset " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " RemoveSelection " _L1 ) {
2012-05-10 21:52:05 +00:00
int selectionNum = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
interface - > textInterface ( ) - > removeSelection ( selectionNum ) ;
sendReply ( connection , message , true ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " SetCaretOffset " _L1 ) {
2012-05-10 21:52:05 +00:00
int offset = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
interface - > textInterface ( ) - > setCursorPosition ( offset ) ;
sendReply ( connection , message , true ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " SetSelection " _L1 ) {
2012-05-10 21:52:05 +00:00
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 {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: AtSpiAdaptor::textInterface does not implement " < < function < < message . path ( ) ;
2012-05-10 21:52:05 +00:00
return false ;
}
return true ;
}
2013-03-05 13:37:37 +00:00
QAccessible : : TextBoundaryType AtSpiAdaptor : : qAccessibleBoundaryType ( int atspiTextBoundaryType ) const
2012-05-10 21:52:05 +00:00
{
switch ( atspiTextBoundaryType ) {
case ATSPI_TEXT_BOUNDARY_CHAR :
2013-03-05 13:37:37 +00:00
return QAccessible : : CharBoundary ;
2012-05-10 21:52:05 +00:00
case ATSPI_TEXT_BOUNDARY_WORD_START :
case ATSPI_TEXT_BOUNDARY_WORD_END :
2013-03-05 13:37:37 +00:00
return QAccessible : : WordBoundary ;
2012-05-10 21:52:05 +00:00
case ATSPI_TEXT_BOUNDARY_SENTENCE_START :
case ATSPI_TEXT_BOUNDARY_SENTENCE_END :
2013-03-05 13:37:37 +00:00
return QAccessible : : SentenceBoundary ;
2012-05-10 21:52:05 +00:00
case ATSPI_TEXT_BOUNDARY_LINE_START :
case ATSPI_TEXT_BOUNDARY_LINE_END :
2013-03-05 13:37:37 +00:00
return QAccessible : : LineBoundary ;
2012-05-10 21:52:05 +00:00
}
Q_ASSERT_X ( 0 , " " , " Requested invalid boundary type. " ) ;
2013-03-05 13:37:37 +00:00
return QAccessible : : CharBoundary ;
2012-05-10 21:52:05 +00:00
}
2015-02-15 22:04:51 +00:00
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
2022-04-11 13:54:50 +00:00
if ( ia2Name = = " background-color " _L1 ) {
2015-02-15 22:04:51 +00:00
name = QStringLiteral ( " bg-color " ) ;
value = atspiColor ( value ) ;
2022-04-11 13:54:50 +00:00
} else if ( ia2Name = = " font-family " _L1 ) {
2015-02-15 22:04:51 +00:00
name = QStringLiteral ( " family-name " ) ;
2022-04-11 13:54:50 +00:00
} else if ( ia2Name = = " color " _L1 ) {
2015-02-15 22:04:51 +00:00
name = QStringLiteral ( " fg-color " ) ;
value = atspiColor ( value ) ;
2022-04-11 13:54:50 +00:00
} else if ( ia2Name = = " text-align " _L1 ) {
2015-02-15 22:04:51 +00:00
name = QStringLiteral ( " justification " ) ;
2022-04-11 13:54:50 +00:00
if ( value = = " justify " _L1 ) {
2015-02-15 22:04:51 +00:00
value = QStringLiteral ( " fill " ) ;
2022-04-11 13:54:50 +00:00
} else if ( value ! = " left " _L1 & & value ! = " right " _L1 & & value ! = " center " _L1 ) {
qCDebug ( lcAccessibilityAtspi ) < < " Unknown text-align attribute value \" "
< < value < < " \" cannot be translated to AT-SPI. " ;
value = QString ( ) ;
2015-02-15 22:04:51 +00:00
}
2022-04-11 13:54:50 +00:00
} else if ( ia2Name = = " font-size " _L1 ) {
2015-02-15 22:04:51 +00:00
name = QStringLiteral ( " size " ) ;
value = atspiSize ( value ) ;
2022-04-11 13:54:50 +00:00
} else if ( ia2Name = = " font-style " _L1 ) {
2015-02-15 22:04:51 +00:00
name = QStringLiteral ( " style " ) ;
2022-04-11 13:54:50 +00:00
if ( value ! = " normal " _L1 & & value ! = " italic " _L1 & & value ! = " oblique " _L1 ) {
2022-04-21 12:06:56 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " Unknown font-style attribute value \" " < < value
< < " \" cannot be translated to AT-SPI. " ;
2015-02-15 22:04:51 +00:00
value = QString ( ) ;
}
2022-04-11 13:54:50 +00:00
} else if ( ia2Name = = " text-underline-type " _L1 ) {
2015-02-15 22:04:51 +00:00
name = QStringLiteral ( " underline " ) ;
2022-04-11 13:54:50 +00:00
if ( value ! = " none " _L1 & & value ! = " single " _L1 & & value ! = " double " _L1 ) {
2022-04-21 12:06:56 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " Unknown text-underline-type attribute value \" "
< < value < < " \" cannot be translated to AT-SPI. " ;
2015-02-15 22:04:51 +00:00
value = QString ( ) ;
}
2022-04-11 13:54:50 +00:00
} else if ( ia2Name = = " font-weight " _L1 ) {
2015-02-15 22:04:51 +00:00
name = QStringLiteral ( " weight " ) ;
2022-04-11 13:54:50 +00:00
if ( value = = " normal " _L1 )
2015-02-15 22:04:51 +00:00
// 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 ( ) ;
2022-04-11 13:54:50 +00:00
} else if ( ia2Name = = " text-position " _L1 ) {
2015-02-15 22:04:51 +00:00
name = QStringLiteral ( " vertical-align " ) ;
2022-04-11 13:54:50 +00:00
if ( value ! = " baseline " _L1 & & value ! = " super " _L1 & & value ! = " sub " _L1 ) {
2022-04-21 12:06:56 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " Unknown text-position attribute value \" " < < value
< < " \" cannot be translated to AT-SPI. " ;
2015-02-15 22:04:51 +00:00
value = QString ( ) ;
}
2022-04-11 13:54:50 +00:00
} else if ( ia2Name = = " writing-mode " _L1 ) {
2015-02-15 22:04:51 +00:00
name = QStringLiteral ( " direction " ) ;
2022-04-11 13:54:50 +00:00
if ( value = = " lr " _L1 )
2015-02-15 22:04:51 +00:00
value = QStringLiteral ( " ltr " ) ;
2022-04-11 13:54:50 +00:00
else if ( value = = " rl " _L1 )
2015-02-15 22:04:51 +00:00
value = QStringLiteral ( " rtl " ) ;
2022-04-11 13:54:50 +00:00
else if ( value = = " tb " _L1 ) {
2015-02-15 22:04:51 +00:00
// 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 " ) ;
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " writing-mode attribute value \" tb \" translated only w.r.t. horizontal direction; vertical direction ignored " ;
2015-02-15 22:04:51 +00:00
} else {
2022-04-21 12:06:56 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " Unknown writing-mode attribute value \" " < < value
< < " \" cannot be translated to AT-SPI. " ;
2015-02-15 22:04:51 +00:00
value = QString ( ) ;
}
2022-04-11 13:54:50 +00:00
} else if ( ia2Name = = " language " _L1 ) {
2015-02-15 22:04:51 +00:00
// OK - ATK has no docs on the format of the value, IAccessible2 has reasonable format - leave it at that now
2022-04-11 13:54:50 +00:00
} else if ( ia2Name = = " invalid " _L1 ) {
2015-02-15 22:04:51 +00:00
// 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 ) ;
}
}
2012-05-10 21:52:05 +00:00
// FIXME all attribute methods below should share code
2013-01-03 16:18:40 +00:00
QVariantList AtSpiAdaptor : : getAttributes ( QAccessibleInterface * interface , int offset , bool includeDefaults ) const
2012-05-10 21:52:05 +00:00
{
Q_UNUSED ( includeDefaults ) ;
QSpiAttributeSet set ;
int startOffset ;
int endOffset ;
QString joined = interface - > textInterface ( ) - > attributes ( offset , & startOffset , & endOffset ) ;
2022-04-11 12:04:17 +00:00
const QStringList attributes = joined . split ( u ' ; ' , Qt : : SkipEmptyParts , Qt : : CaseSensitive ) ;
2016-08-26 13:35:40 +00:00
for ( const QString & attr : attributes ) {
2012-05-10 21:52:05 +00:00
QStringList items ;
2022-04-11 12:04:17 +00:00
items = attr . split ( u ' : ' , Qt : : SkipEmptyParts , Qt : : CaseSensitive ) ;
2015-02-15 22:04:51 +00:00
AtSpiAttribute attribute = atspiTextAttribute ( items [ 0 ] , items [ 1 ] ) ;
if ( ! attribute . isNull ( ) )
set [ attribute . name ] = attribute . value ;
2012-05-10 21:52:05 +00:00
}
QVariantList list ;
list < < QVariant : : fromValue ( set ) < < startOffset < < endOffset ;
return list ;
}
2013-01-03 16:18:40 +00:00
QVariantList AtSpiAdaptor : : getAttributeValue ( QAccessibleInterface * interface , int offset , const QString & attributeName ) const
2012-05-10 21:52:05 +00:00
{
QString mapped ;
QString joined ;
QSpiAttributeSet map ;
int startOffset ;
int endOffset ;
joined = interface - > textInterface ( ) - > attributes ( offset , & startOffset , & endOffset ) ;
2022-04-11 12:04:17 +00:00
const QStringList attributes = joined . split ( u ' ; ' , Qt : : SkipEmptyParts , Qt : : CaseSensitive ) ;
2016-08-26 13:35:40 +00:00
for ( const QString & attr : attributes ) {
2012-05-10 21:52:05 +00:00
QStringList items ;
2022-04-11 12:04:17 +00:00
items = attr . split ( u ' : ' , Qt : : SkipEmptyParts , Qt : : CaseSensitive ) ;
2015-02-15 22:04:51 +00:00
AtSpiAttribute attribute = atspiTextAttribute ( items [ 0 ] , items [ 1 ] ) ;
if ( ! attribute . isNull ( ) )
map [ attribute . name ] = attribute . value ;
2012-05-10 21:52:05 +00:00
}
mapped = map [ attributeName ] ;
2016-08-09 10:28:28 +00:00
const bool defined = ! mapped . isEmpty ( ) ;
2012-05-10 21:52:05 +00:00
QVariantList list ;
list < < mapped < < startOffset < < endOffset < < defined ;
return list ;
}
2014-06-17 17:10:43 +00:00
QList < QVariant > AtSpiAdaptor : : getCharacterExtents ( QAccessibleInterface * interface , int offset , uint coordType ) const
2012-05-10 21:52:05 +00:00
{
QRect rect = interface - > textInterface ( ) - > characterRect ( offset ) ;
if ( coordType = = ATSPI_COORD_TYPE_WINDOW )
rect = translateRectToWindowCoordinates ( interface , rect ) ;
2014-06-17 17:10:43 +00:00
return QList < QVariant > ( ) < < rect . x ( ) < < rect . y ( ) < < rect . width ( ) < < rect . height ( ) ;
2012-05-10 21:52:05 +00:00
}
2014-06-17 17:10:43 +00:00
QList < QVariant > AtSpiAdaptor : : getRangeExtents ( QAccessibleInterface * interface ,
2012-05-10 21:52:05 +00:00
int startOffset , int endOffset , uint coordType ) const
{
if ( endOffset = = - 1 )
endOffset = interface - > textInterface ( ) - > characterCount ( ) ;
QAccessibleTextInterface * textInterface = interface - > textInterface ( ) ;
if ( endOffset < = startOffset | | ! textInterface )
2014-06-17 17:10:43 +00:00
return QList < QVariant > ( ) < < - 1 < < - 1 < < 0 < < 0 ;
2012-05-10 21:52:05 +00:00
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 ) ;
2014-06-17 17:10:43 +00:00
return QList < QVariant > ( ) < < rect . x ( ) < < rect . y ( ) < < rect . width ( ) < < rect . height ( ) ;
2012-05-10 21:52:05 +00:00
}
2013-01-03 16:18:40 +00:00
QRect AtSpiAdaptor : : translateRectToWindowCoordinates ( QAccessibleInterface * interface , const QRect & rect )
2012-05-10 21:52:05 +00:00
{
2013-01-03 16:18:40 +00:00
QAccessibleInterface * window = getWindow ( interface ) ;
2012-05-10 21:52:05 +00:00
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 ) ;
}
2013-01-03 16:18:40 +00:00
bool AtSpiAdaptor : : editableTextInterface ( QAccessibleInterface * interface , const QString & function , const QDBusMessage & message , const QDBusConnection & connection )
2012-05-10 21:52:05 +00:00
{
2022-04-11 13:54:50 +00:00
if ( function = = " CopyText " _L1 ) {
2012-05-10 21:52:05 +00:00
# ifndef QT_NO_CLIPBOARD
int startOffset = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
int endOffset = message . arguments ( ) . at ( 1 ) . toInt ( ) ;
2013-01-03 16:18:40 +00:00
const QString t = textForRange ( interface , startOffset , endOffset ) ;
2012-05-10 21:52:05 +00:00
QGuiApplication : : clipboard ( ) - > setText ( t ) ;
# endif
connection . send ( message . createReply ( true ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " CutText " _L1 ) {
2012-05-10 21:52:05 +00:00
# ifndef QT_NO_CLIPBOARD
int startOffset = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
int endOffset = message . arguments ( ) . at ( 1 ) . toInt ( ) ;
2013-01-03 16:18:40 +00:00
const QString t = textForRange ( interface , startOffset , endOffset ) ;
2012-05-10 21:52:05 +00:00
if ( QAccessibleEditableTextInterface * editableTextIface = interface - > editableTextInterface ( ) )
editableTextIface - > deleteText ( startOffset , endOffset ) ;
else
2013-01-03 16:18:40 +00:00
replaceTextFallback ( interface , startOffset , endOffset , QString ( ) ) ;
2012-05-10 21:52:05 +00:00
QGuiApplication : : clipboard ( ) - > setText ( t ) ;
# endif
connection . send ( message . createReply ( true ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " DeleteText " _L1 ) {
2012-05-10 21:52:05 +00:00
int startOffset = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
int endOffset = message . arguments ( ) . at ( 1 ) . toInt ( ) ;
if ( QAccessibleEditableTextInterface * editableTextIface = interface - > editableTextInterface ( ) )
editableTextIface - > deleteText ( startOffset , endOffset ) ;
else
2013-01-03 16:18:40 +00:00
replaceTextFallback ( interface , startOffset , endOffset , QString ( ) ) ;
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( true ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " InsertText " _L1 ) {
2012-05-10 21:52:05 +00:00
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
2013-01-03 16:18:40 +00:00
replaceTextFallback ( interface , position , position , text ) ;
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( true ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " PasteText " _L1 ) {
2012-05-10 21:52:05 +00:00
# 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
2013-01-03 16:18:40 +00:00
replaceTextFallback ( interface , position , position , txt ) ;
2012-05-10 21:52:05 +00:00
# endif
connection . send ( message . createReply ( true ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " SetTextContents " _L1 ) {
2012-05-10 21:52:05 +00:00
QString newContents = message . arguments ( ) . at ( 0 ) . toString ( ) ;
2014-07-03 14:09:18 +00:00
if ( QAccessibleEditableTextInterface * editableTextIface = interface - > editableTextInterface ( ) )
editableTextIface - > replaceText ( 0 , interface - > textInterface ( ) - > characterCount ( ) , newContents ) ;
else
replaceTextFallback ( interface , 0 , - 1 , newContents ) ;
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( true ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " " _L1 ) {
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( ) ) ;
} else {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: AtSpiAdaptor::editableTextInterface does not implement " < < function < < message . path ( ) ;
2012-05-10 21:52:05 +00:00
return false ;
}
return true ;
}
// Value interface
2013-01-03 16:18:40 +00:00
bool AtSpiAdaptor : : valueInterface ( QAccessibleInterface * interface , const QString & function , const QDBusMessage & message , const QDBusConnection & connection )
2012-05-10 21:52:05 +00:00
{
2014-07-03 14:09:18 +00:00
QAccessibleValueInterface * valueIface = interface - > valueInterface ( ) ;
if ( ! valueIface )
return false ;
2022-04-11 13:54:50 +00:00
if ( function = = " SetCurrentValue " _L1 ) {
2019-12-06 12:19:37 +00:00
QDBusVariant v = qvariant_cast < QDBusVariant > ( message . arguments ( ) . at ( 2 ) ) ;
2012-05-10 21:52:05 +00:00
double value = v . variant ( ) . toDouble ( ) ;
//Temporary fix
//See https://bugzilla.gnome.org/show_bug.cgi?id=652596
2014-07-03 14:09:18 +00:00
valueIface - > setCurrentValue ( value ) ;
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( ) ) ; // FIXME is the reply needed?
2012-11-03 18:21:12 +00:00
} else {
QVariant value ;
2022-04-11 13:54:50 +00:00
if ( function = = " GetCurrentValue " _L1 )
2014-07-03 14:09:18 +00:00
value = valueIface - > currentValue ( ) ;
2022-04-11 13:54:50 +00:00
else if ( function = = " GetMaximumValue " _L1 )
2014-07-03 14:09:18 +00:00
value = valueIface - > maximumValue ( ) ;
2022-04-11 13:54:50 +00:00
else if ( function = = " GetMinimumIncrement " _L1 )
2014-07-03 14:09:18 +00:00
value = valueIface - > minimumStepSize ( ) ;
2022-04-11 13:54:50 +00:00
else if ( function = = " GetMinimumValue " _L1 )
2014-07-03 14:09:18 +00:00
value = valueIface - > minimumValue ( ) ;
2012-11-03 18:21:12 +00:00
else {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: AtSpiAdaptor::valueInterface does not implement " < < function < < message . path ( ) ;
2012-11-03 18:21:12 +00:00
return false ;
2012-09-28 16:04:37 +00:00
}
2020-07-27 15:00:22 +00:00
if ( ! value . canConvert < double > ( ) ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " AtSpiAdaptor::valueInterface: Could not convert to double: " < < function ;
2012-12-22 03:39:46 +00:00
}
2012-11-03 18:21:12 +00:00
// explicitly convert to dbus-variant containing one double since atspi expects that
// everything else might fail to convert back on the other end
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply (
2012-11-03 18:21:12 +00:00
QVariant : : fromValue ( QDBusVariant ( QVariant : : fromValue ( value . toDouble ( ) ) ) ) ) ) ;
2012-05-10 21:52:05 +00:00
}
return true ;
}
// Table interface
2013-01-03 16:18:40 +00:00
bool AtSpiAdaptor : : tableInterface ( QAccessibleInterface * interface , const QString & function , const QDBusMessage & message , const QDBusConnection & connection )
2012-05-10 21:52:05 +00:00
{
if ( ! ( interface - > tableInterface ( ) | | interface - > tableCellInterface ( ) ) ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING Qt AtSpiAdaptor: Could not find table interface for: " < < message . path ( ) < < interface ;
2012-05-10 21:52:05 +00:00
return false ;
}
if ( 0 ) {
// properties
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetCaption " _L1 ) {
2013-01-03 16:18:40 +00:00
QAccessibleInterface * captionInterface = interface - > tableInterface ( ) - > caption ( ) ;
2012-05-10 21:52:05 +00:00
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 ) ) ) ) ;
}
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetNColumns " _L1 ) {
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( QVariant : : fromValue ( QDBusVariant (
QVariant : : fromValue ( interface - > tableInterface ( ) - > columnCount ( ) ) ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetNRows " _L1 ) {
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( QVariant : : fromValue ( QDBusVariant (
QVariant : : fromValue ( interface - > tableInterface ( ) - > rowCount ( ) ) ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetNSelectedColumns " _L1 ) {
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( QVariant : : fromValue ( QDBusVariant (
QVariant : : fromValue ( interface - > tableInterface ( ) - > selectedColumnCount ( ) ) ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetNSelectedRows " _L1 ) {
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( QVariant : : fromValue ( QDBusVariant (
QVariant : : fromValue ( interface - > tableInterface ( ) - > selectedRowCount ( ) ) ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetSummary " _L1 ) {
2020-07-29 14:30:13 +00:00
QAccessibleInterface * summary = interface - > tableInterface ( ) ? interface - > tableInterface ( ) - > summary ( ) : nullptr ;
2012-05-10 21:52:05 +00:00
QSpiObjectReference ref ( connection , QDBusObjectPath ( pathForInterface ( summary ) ) ) ;
connection . send ( message . createReply ( QVariant : : fromValue ( QDBusVariant ( QVariant : : fromValue ( ref ) ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetAccessibleAt " _L1 ) {
2012-05-10 21:52:05 +00:00
int row = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
int column = message . arguments ( ) . at ( 1 ) . toInt ( ) ;
2012-09-22 16:37:21 +00:00
if ( ( row < 0 ) | |
( column < 0 ) | |
( row > = interface - > tableInterface ( ) - > rowCount ( ) ) | |
( column > = interface - > tableInterface ( ) - > columnCount ( ) ) ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: invalid index for tableInterface GetAccessibleAt ( " < < row < < " , " < < column < < ' ) ' ;
2012-09-22 16:37:21 +00:00
return false ;
}
2012-05-10 21:52:05 +00:00
QSpiObjectReference ref ;
2013-01-03 16:18:40 +00:00
QAccessibleInterface * cell ( interface - > tableInterface ( ) - > cellAt ( row , column ) ) ;
2012-05-10 21:52:05 +00:00
if ( cell ) {
ref = QSpiObjectReference ( connection , QDBusObjectPath ( pathForInterface ( cell ) ) ) ;
} else {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: no cell interface returned for " < < interface - > object ( ) < < row < < column ;
2012-05-10 21:52:05 +00:00
ref = QSpiObjectReference ( ) ;
}
connection . send ( message . createReply ( QVariant : : fromValue ( ref ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetIndexAt " _L1 ) {
2012-05-10 21:52:05 +00:00
int row = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
int column = message . arguments ( ) . at ( 1 ) . toInt ( ) ;
QAccessibleInterface * cell = interface - > tableInterface ( ) - > cellAt ( row , column ) ;
if ( ! cell ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: AtSpiAdaptor::GetIndexAt( " < < row < < ' , ' < < column < < " ) did not find a cell. " < < interface ;
2012-05-10 21:52:05 +00:00
return false ;
}
int index = interface - > indexOfChild ( cell ) ;
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " QSpiAdaptor::GetIndexAt row: " < < row < < " col: " < < column < < " logical index: " < < index ;
2012-05-10 21:52:05 +00:00
Q_ASSERT ( index > 0 ) ;
connection . send ( message . createReply ( index ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( ( function = = " GetColumnAtIndex " _L1 ) | | ( function = = " GetRowAtIndex " _L1 ) ) {
2012-05-10 21:52:05 +00:00
int index = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
int ret = - 1 ;
if ( index > = 0 ) {
2013-01-03 16:18:40 +00:00
QAccessibleInterface * cell = interface - > child ( index ) ;
2012-05-10 21:52:05 +00:00
if ( cell ) {
2022-04-11 13:54:50 +00:00
if ( function = = " GetColumnAtIndex " _L1 ) {
2012-05-10 21:52:05 +00:00
if ( cell - > role ( ) = = QAccessible : : ColumnHeader ) {
ret = index ;
} else if ( cell - > role ( ) = = QAccessible : : RowHeader ) {
ret = - 1 ;
} else {
if ( ! cell - > tableCellInterface ( ) ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: AtSpiAdaptor:: " < < function < < " No table cell interface: " < < cell ;
2012-05-10 21:52:05 +00:00
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 ( ) ) {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: AtSpiAdaptor:: " < < function < < " No table cell interface: " < < cell ;
2012-05-10 21:52:05 +00:00
return false ;
}
ret = cell - > tableCellInterface ( ) - > rowIndex ( ) ;
}
}
} else {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: AtSpiAdaptor:: " < < function < < " No cell at index: " < < index < < interface ;
2012-05-10 21:52:05 +00:00
return false ;
}
}
connection . send ( message . createReply ( ret ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetColumnDescription " _L1 ) {
2012-05-10 21:52:05 +00:00
int column = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
connection . send ( message . createReply ( interface - > tableInterface ( ) - > columnDescription ( column ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetRowDescription " _L1 ) {
2012-05-10 21:52:05 +00:00
int row = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
connection . send ( message . createReply ( interface - > tableInterface ( ) - > rowDescription ( row ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetRowColumnExtentsAtIndex " _L1 ) {
2012-05-10 21:52:05 +00:00
int index = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
bool success = false ;
2013-08-17 14:51:27 +00:00
int row = - 1 ;
int col = - 1 ;
int rowExtents = - 1 ;
int colExtents = - 1 ;
bool isSelected = false ;
2012-05-10 21:52:05 +00:00
int cols = interface - > tableInterface ( ) - > columnCount ( ) ;
2013-08-17 14:51:27 +00:00
if ( cols > 0 ) {
row = index / cols ;
col = index % cols ;
QAccessibleTableCellInterface * cell = interface - > tableInterface ( ) - > cellAt ( row , col ) - > tableCellInterface ( ) ;
if ( cell ) {
2013-08-12 14:34:44 +00:00
row = cell - > rowIndex ( ) ;
col = cell - > columnIndex ( ) ;
rowExtents = cell - > rowExtent ( ) ;
colExtents = cell - > columnExtent ( ) ;
isSelected = cell - > isSelected ( ) ;
2013-08-17 14:51:27 +00:00
success = true ;
}
2012-05-10 21:52:05 +00:00
}
QVariantList list ;
list < < success < < row < < col < < rowExtents < < colExtents < < isSelected ;
connection . send ( message . createReply ( list ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetColumnExtentAt " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ( ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetRowExtentAt " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ( ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetColumnHeader " _L1 ) {
2012-05-10 21:52:05 +00:00
int column = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
QSpiObjectReference ref ;
2013-01-03 16:18:40 +00:00
QAccessibleInterface * cell ( interface - > tableInterface ( ) - > cellAt ( 0 , column ) ) ;
2012-05-10 21:52:05 +00:00
if ( cell & & cell - > tableCellInterface ( ) ) {
QList < QAccessibleInterface * > header = cell - > tableCellInterface ( ) - > columnHeaderCells ( ) ;
if ( header . size ( ) > 0 ) {
2013-01-03 16:18:40 +00:00
ref = QSpiObjectReference ( connection , QDBusObjectPath ( pathForInterface ( header . takeAt ( 0 ) ) ) ) ;
2012-05-10 21:52:05 +00:00
}
}
connection . send ( message . createReply ( QVariant : : fromValue ( ref ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetRowHeader " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ) {
2013-01-03 16:18:40 +00:00
ref = QSpiObjectReference ( connection , QDBusObjectPath ( pathForInterface ( header . takeAt ( 0 ) ) ) ) ;
2012-05-10 21:52:05 +00:00
}
}
connection . send ( message . createReply ( QVariant : : fromValue ( ref ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetSelectedColumns " _L1 ) {
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( QVariant : : fromValue ( interface - > tableInterface ( ) - > selectedColumns ( ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetSelectedRows " _L1 ) {
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( QVariant : : fromValue ( interface - > tableInterface ( ) - > selectedRows ( ) ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " IsColumnSelected " _L1 ) {
2012-05-10 21:52:05 +00:00
int column = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
connection . send ( message . createReply ( interface - > tableInterface ( ) - > isColumnSelected ( column ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " IsRowSelected " _L1 ) {
2012-05-10 21:52:05 +00:00
int row = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
connection . send ( message . createReply ( interface - > tableInterface ( ) - > isRowSelected ( row ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " IsSelected " _L1 ) {
2012-05-10 21:52:05 +00:00
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 ( ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " AddColumnSelection " _L1 ) {
2012-05-10 21:52:05 +00:00
int column = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
connection . send ( message . createReply ( interface - > tableInterface ( ) - > selectColumn ( column ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " AddRowSelection " _L1 ) {
2012-05-10 21:52:05 +00:00
int row = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
connection . send ( message . createReply ( interface - > tableInterface ( ) - > selectRow ( row ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " RemoveColumnSelection " _L1 ) {
2012-05-10 21:52:05 +00:00
int column = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
connection . send ( message . createReply ( interface - > tableInterface ( ) - > unselectColumn ( column ) ) ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " RemoveRowSelection " _L1 ) {
2012-05-10 21:52:05 +00:00
int row = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
connection . send ( message . createReply ( interface - > tableInterface ( ) - > unselectRow ( row ) ) ) ;
} else {
2017-06-16 14:37:03 +00:00
qCDebug ( lcAccessibilityAtspi ) < < " WARNING: AtSpiAdaptor::tableInterface does not implement " < < function < < message . path ( ) ;
2012-05-10 21:52:05 +00:00
return false ;
}
return true ;
}
QT_END_NAMESPACE
2014-07-02 12:10:30 +00:00
# endif //QT_NO_ACCESSIBILITY