2022-05-10 10:06:48 +00:00
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
2012-05-10 21:52:05 +00:00
# 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>
2022-12-06 06:50:20 +00:00
# include <QtCore/qtversion.h>
2012-05-10 21:52:05 +00:00
2022-06-09 10:52:37 +00:00
# if QT_CONFIG(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
*/
2022-08-03 05:42:10 +00:00
// ATSPI_COORD_TYPE_PARENT was added in at-spi 2.30, define here for older versions
# if ATSPI_COORD_TYPE_COUNT < 3
# define ATSPI_COORD_TYPE_PARENT 2
# endif
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 "
2022-08-10 11:20:33 +00:00
" <method name= \" GetAccessibleId \" > \n "
" <arg direction= \" out \" type= \" s \" /> \n "
" </method> \n "
2012-05-10 21:52:05 +00:00
" </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-10-11 13:24:04 +00:00
static const QLatin1StringView selectionIntrospection (
" <interface name= \" org.a11y.atspi.Selection \" > \n "
" <property name= \" NSelectedChildren \" type= \" i \" access= \" read \" /> \n "
" <method name= \" GetSelectedChild \" > \n "
" <arg direction= \" in \" name= \" selectedChildIndex \" type= \" i \" /> \n "
" <arg direction= \" out \" type= \" (so) \" /> \n "
" <annotation name= \" org.qtproject.QtDBus.QtTypeName.Out0 \" value= \" QSpiObjectReference \" /> \n "
" </method> \n "
" <method name= \" SelectChild \" > \n "
" <arg direction= \" in \" name= \" childIndex \" type= \" i \" /> \n "
" <arg direction= \" out \" type= \" b \" /> \n "
" </method> \n "
" <method name= \" DeselectSelectedChild \" > \n "
" <arg direction= \" in \" name= \" selectedChildIndex \" type= \" i \" /> \n "
" <arg direction= \" out \" type= \" b \" /> \n "
" </method> \n "
" <method name= \" IsChildSelected \" > \n "
" <arg direction= \" in \" name= \" childIndex \" type= \" i \" /> \n "
" <arg direction= \" out \" type= \" b \" /> \n "
" </method> \n "
" <method name= \" SelectAll \" > \n "
" <arg direction= \" out \" type= \" b \" /> \n "
" </method> \n "
" <method name= \" ClearSelection \" > \n "
" <arg direction= \" out \" type= \" b \" /> \n "
" </method> \n "
" <method name= \" DeselectChild \" > \n "
" <arg direction= \" in \" name= \" childIndex \" type= \" i \" /> \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-07-06 12:19:28 +00:00
static const QLatin1StringView tableCellIntrospection (
" <interface name= \" org.a11y.atspi.TableCell \" > \n "
" <property access= \" read \" name= \" ColumnSpan \" type= \" i \" /> \n "
" <property access= \" read \" name= \" Position \" type= \" (ii) \" > \n "
" <annotation name= \" org.qtproject.QtDBus.QtTypeName \" value= \" QPoint \" /> \n "
" </property> \n "
" <property access= \" read \" name= \" RowSpan \" type= \" i \" /> \n "
" <property access= \" read \" name= \" Table \" type= \" (so) \" > \n "
" <annotation name= \" org.qtproject.QtDBus.QtTypeName \" value= \" QSpiObjectReference \" /> \n "
" </property> \n "
" <method name= \" GetRowColumnSpan \" > \n "
" <arg direction= \" out \" type= \" b \" /> \n "
" <arg direction= \" out \" name= \" row \" type= \" i \" /> \n "
" <arg direction= \" out \" name= \" col \" type= \" i \" /> \n "
" <arg direction= \" out \" name= \" row_extents \" type= \" i \" /> \n "
" <arg direction= \" out \" name= \" col_extents \" type= \" i \" /> \n "
" </method> \n "
" </interface> \n "
) ;
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 "
a11y atspi: Support text interface's GetStringAtOffset
The GetStringAtOffset method was added to the
AT-SPI Text interface in at-spi2-core commmit [1]:
commit 56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Author: Mike Gorse <mgorse@suse.com>
Date: Mon Aug 19 16:43:02 2013 -0500
Add atspi_text_get_string_at_offset
As compared to GetTextAtOffset, which is very similar and
already supported in Qt's AT-SPI adapter, the new method
uses a new enum, AtspiTextGranularity, to specify the region
of text that should be returned.
Other than AtspiTextBoundaryType (that is used by
GetTextAtOffset), AtspiTextGranularity now also has
a value for the paragraph granularity
(ATSPI_TEXT_GRANULARITY_PARAGRAPH).
While AtspiTextBoundaryType has two enum values for the
word/sentence/line boundaries (ATSPI_TEXT_BOUNDARY_WORD_START and
ATSPI_TEXT_BOUNDARY_WORD_END, etc.), AtspiTextGranularity
doesn't have this any more, but ATSPI_TEXT_GRANULARITY_WORD
etc. seem to correspond to what the variants ending on "_START"
do when used with GetTextAtOffset, since the documentation says that
the range is "defined by the boundaries of a word
starting at the beginning of the current word and finishing
at the beginning of the following one, if present." (and likewise
for ATSPI_TEXT_GRANULARITY_SENTENCE, ATSPI_TEXT_GRANULARITY_LINE,
ATSPI_TEXT_GRANULARITY_PARAGRAPH).
In order to support GetStringAtOffset, this
adds a new mapping from the AtspiTextGranularity enum values
to the corresponding QAccessible::TextBoundaryType, similar
to what's done for the AtspiTextBoundaryType in the
handling of the GetTextAtOffset method.
The existing AtSpiAdaptor::qAccessibleBoundaryType
method is renamed to
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiBoundaryType
to clearer distinguish it from the newly introduced
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiTextGranularity.
No similar new alternatives have been added
to AT-SPI for GetTextBeforeOffset and GetTextAfterOffset.
[1] https://gitlab.gnome.org/GNOME/at-spi2-core/-/commit/56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Fixes: QTBUG-105811
Change-Id: I674a760e80c349baea89dcb4ac7aecdef9b2b45f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2022-08-18 13:21:38 +00:00
" <method name= \" GetStringAtOffset \" > \n "
" <arg direction= \" in \" name= \" offset \" type= \" i \" /> \n "
" <arg direction= \" in \" name= \" granularity \" type= \" u \" /> \n "
" <arg direction= \" out \" type= \" s \" /> \n "
" <arg direction= \" out \" name= \" startOffset \" type= \" i \" /> \n "
" <arg direction= \" out \" name= \" endOffset \" type= \" i \" /> \n "
" </method> \n "
2012-05-10 21:52:05 +00:00
" <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 "
" </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 "
2022-08-18 09:33:02 +00:00
" </method> \n "
2012-05-10 21:52:05 +00:00
" <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 "
2022-08-22 07:38:24 +00:00
" <method name= \" ScrollSubstringTo \" > \n "
" <arg direction= \" in \" name= \" startOffset \" type= \" i \" /> \n "
" <arg direction= \" in \" name= \" endOffset \" type= \" i \" /> \n "
" <arg direction= \" in \" name= \" type \" type= \" u \" /> \n "
" <arg direction= \" out \" type= \" b \" /> \n "
" </method> \n "
2012-05-10 21:52:05 +00:00
" </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 ) {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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-10-11 13:24:04 +00:00
if ( interfaces . contains ( ATSPI_DBUS_INTERFACE_SELECTION " " _L1 ) )
xml . append ( selectionIntrospection ) ;
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-07-06 12:19:28 +00:00
if ( interfaces . contains ( ATSPI_DBUS_INTERFACE_TABLE_CELL " " _L1 ) )
xml . append ( tableCellIntrospection ) ;
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 {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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 {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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 :
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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 ) {
2022-07-22 16:48:37 +00:00
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
if ( ! iface ) {
qCDebug ( lcAccessibilityAtspi ,
" NameChanged event from invalid accessible. " ) ;
return ;
}
QString path = pathForInterface ( iface ) ;
QVariantList args = packDBusSignalArguments (
" accessible-name " _L1 , 0 , 0 ,
QVariant : : fromValue ( QDBusVariant ( iface - > text ( QAccessible : : Name ) ) ) ) ;
2022-04-11 13:54:50 +00:00
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 ) {
2022-07-22 16:48:37 +00:00
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
if ( ! iface ) {
qCDebug ( lcAccessibilityAtspi ,
" DescriptionChanged event from invalid accessible. " ) ;
return ;
}
QString path = pathForInterface ( iface ) ;
QVariantList args = packDBusSignalArguments (
" accessible-description " _L1 , 0 , 0 ,
QVariant : : fromValue ( QDBusVariant ( iface - > text ( QAccessible : : Description ) ) ) ) ;
2022-04-11 13:54:50 +00:00
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 ( ) ) {
2022-10-25 16:08:10 +00:00
qCWarning ( 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 ) ) ;
Port from container.count()/length() to size()
This is semantic patch using ClangTidyTransformator:
auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)
makeRule(cxxMemberCallExpr(on(QtContainerClass),
callee(cxxMethodDecl(hasAnyName({"count", "length"),
parameterCountIs(0))))),
changeTo(cat(access(o, cat("size"), "()"))),
cat("use 'size()' instead of 'count()/length()'"))
a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'.
<classes> are:
// sequential:
"QByteArray",
"QList",
"QQueue",
"QStack",
"QString",
"QVarLengthArray",
"QVector",
// associative:
"QHash",
"QMultiHash",
"QMap",
"QMultiMap",
"QSet",
// Qt has no QMultiSet
Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2022-09-30 12:09:04 +00:00
QVariantList args = packDBusSignalArguments ( " delete " _L1 , changePosition , textRemoved . size ( ) , QVariant : : fromValue ( data ) ) ;
2022-04-11 13:54:50 +00:00
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 ) ) ;
Port from container.count()/length() to size()
This is semantic patch using ClangTidyTransformator:
auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)
makeRule(cxxMemberCallExpr(on(QtContainerClass),
callee(cxxMethodDecl(hasAnyName({"count", "length"),
parameterCountIs(0))))),
changeTo(cat(access(o, cat("size"), "()"))),
cat("use 'size()' instead of 'count()/length()'"))
a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'.
<classes> are:
// sequential:
"QByteArray",
"QList",
"QQueue",
"QStack",
"QString",
"QVarLengthArray",
"QVector",
// associative:
"QHash",
"QMultiHash",
"QMap",
"QMultiMap",
"QSet",
// Qt has no QMultiSet
Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2022-09-30 12:09:04 +00:00
QVariantList args = packDBusSignalArguments ( " insert " _L1 , changePosition , textInserted . size ( ) , QVariant : : fromValue ( data ) ) ;
2022-04-11 13:54:50 +00:00
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-07-23 01:31:14 +00:00
QVariantList args1 = packDBusSignalArguments (
" accessible-name " _L1 , 0 , 0 ,
QVariant : : fromValue ( QDBusVariant ( iface - > text ( QAccessible : : Name ) ) ) ) ;
2022-04-11 13:54:50 +00:00
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 ;
}
2022-08-26 13:52:40 +00:00
// send event for change of selected state for the interface itself
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 ) ;
2022-08-26 13:52:40 +00:00
// send SelectionChanged event for the parent
QAccessibleInterface * parent = iface - > parent ( ) ;
if ( ! parent ) {
qCDebug ( lcAccessibilityAtspi ) < < " No valid parent in selection event. " ;
return ;
}
QString parentPath = pathForInterface ( parent ) ;
QVariantList args = packDBusSignalArguments ( QString ( ) , 0 , 0 , variantForPath ( parentPath ) ) ;
sendDBusSignal ( parentPath , QLatin1String ( ATSPI_DBUS_INTERFACE_EVENT_OBJECT ) ,
QLatin1String ( " SelectionChanged " ) , args ) ;
2012-05-10 21:52:05 +00:00
break ;
}
2022-08-26 13:37:02 +00:00
case QAccessible : : SelectionWithin : {
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
if ( ! iface ) {
qCWarning ( lcAccessibilityAtspi ) < < " SelectionWithin event from invalid accessible. " ;
return ;
}
2012-05-10 21:52:05 +00:00
2022-08-26 13:37:02 +00:00
QString path = pathForInterface ( iface ) ;
QVariantList args = packDBusSignalArguments ( QString ( ) , 0 , 0 , variantForPath ( path ) ) ;
sendDBusSignal ( path , QLatin1String ( ATSPI_DBUS_INTERFACE_EVENT_OBJECT ) , QLatin1String ( " SelectionChanged " ) , args ) ;
break ;
}
2012-05-10 21:52:05 +00:00
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 ) ;
2022-06-15 14:39:52 +00:00
} else if ( stateChange . focused ) {
QAccessibleInterface * iface = event - > accessibleInterface ( ) ;
QAccessible : : State state = iface - > state ( ) ;
bool focused = state . focused ;
notifyStateChange ( iface , " focused " _L1 , focused ) ;
2012-05-10 21:52:05 +00:00
}
}
break ;
}
2022-09-09 21:05:09 +00:00
case QAccessible : : TableModelChanged : {
QAccessibleInterface * interface = event - > accessibleInterface ( ) ;
if ( ! interface | | ! interface - > isValid ( ) ) {
qCWarning ( lcAccessibilityAtspi ) < < " TableModelChanged event from invalid accessible. " ;
return ;
}
const QString path = pathForInterface ( interface ) ;
QAccessibleTableModelChangeEvent * tableModelEvent = static_cast < QAccessibleTableModelChangeEvent * > ( event ) ;
switch ( tableModelEvent - > modelChangeType ( ) ) {
case QAccessibleTableModelChangeEvent : : ColumnsInserted : {
if ( sendObject | | sendObject_column_inserted ) {
const int firstColumn = tableModelEvent - > firstColumn ( ) ;
const int insertedColumnCount = tableModelEvent - > lastColumn ( ) - firstColumn + 1 ;
QVariantList args = packDBusSignalArguments ( QString ( ) , firstColumn , insertedColumnCount , QVariant : : fromValue ( QDBusVariant ( QVariant ( QString ( ) ) ) ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " ColumnInserted " _L1 , args ) ;
}
break ;
}
case QAccessibleTableModelChangeEvent : : ColumnsRemoved : {
if ( sendObject | | sendObject_column_deleted ) {
const int firstColumn = tableModelEvent - > firstColumn ( ) ;
const int removedColumnCount = tableModelEvent - > lastColumn ( ) - firstColumn + 1 ;
QVariantList args = packDBusSignalArguments ( QString ( ) , firstColumn , removedColumnCount , QVariant : : fromValue ( QDBusVariant ( QVariant ( QString ( ) ) ) ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " ColumnDeleted " _L1 , args ) ;
}
break ;
}
case QAccessibleTableModelChangeEvent : : RowsInserted : {
if ( sendObject | | sendObject_row_inserted ) {
const int firstRow = tableModelEvent - > firstRow ( ) ;
const int insertedRowCount = tableModelEvent - > lastRow ( ) - firstRow + 1 ;
QVariantList args = packDBusSignalArguments ( QString ( ) , firstRow , insertedRowCount , QVariant : : fromValue ( QDBusVariant ( QVariant ( QString ( ) ) ) ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " RowInserted " _L1 , args ) ;
}
break ;
}
case QAccessibleTableModelChangeEvent : : RowsRemoved : {
if ( sendObject | | sendObject_row_deleted ) {
const int firstRow = tableModelEvent - > firstRow ( ) ;
const int removedRowCount = tableModelEvent - > lastRow ( ) - firstRow + 1 ;
QVariantList args = packDBusSignalArguments ( QString ( ) , firstRow , removedRowCount , QVariant : : fromValue ( QDBusVariant ( QVariant ( QString ( ) ) ) ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " RowDeleted " _L1 , args ) ;
}
break ;
}
case QAccessibleTableModelChangeEvent : : ModelChangeType : : ModelReset : {
if ( sendObject | | sendObject_model_changed ) {
QVariantList args = packDBusSignalArguments ( QString ( ) , 0 , 0 , QVariant : : fromValue ( QDBusVariant ( QVariant ( QString ( ) ) ) ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " ModelChanged " _L1 , args ) ;
}
break ;
}
case QAccessibleTableModelChangeEvent : : DataChanged : {
if ( sendObject | | sendObject_visible_data_changed ) {
QVariantList args = packDBusSignalArguments ( QString ( ) , 0 , 0 , QVariant : : fromValue ( QDBusVariant ( QVariant ( QString ( ) ) ) ) ) ;
sendDBusSignal ( path , ATSPI_DBUS_INTERFACE_EVENT_OBJECT " " _L1 , " VisibleDataChanged " _L1 , args ) ;
}
break ;
}
}
break ;
}
2013-02-20 11:02:17 +00:00
// For now we ignore these events
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 : : 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
{
// 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 ) {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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 ( ) ) {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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-10-11 13:24:04 +00:00
if ( interface = = ATSPI_DBUS_INTERFACE_SELECTION " " _L1 )
return selectionInterface ( 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 ) ;
2022-07-06 12:19:28 +00:00
if ( interface = = ATSPI_DBUS_INTERFACE_TABLE_CELL " " _L1 )
return tableCellInterface ( accessible , function , message , connection ) ;
2012-05-10 21:52:05 +00:00
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 ) {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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 {
2022-10-25 16:08:10 +00:00
qCWarning ( 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 ;
}
2022-08-10 11:20:33 +00:00
namespace {
QString accessibleIdForAccessible ( QAccessibleInterface * accessible )
{
QString result ;
while ( accessible ) {
if ( ! result . isEmpty ( ) )
result . prepend ( u ' . ' ) ;
if ( auto obj = accessible - > object ( ) ) {
const QString name = obj - > objectName ( ) ;
if ( ! name . isEmpty ( ) )
result . prepend ( name ) ;
else
result . prepend ( QString : : fromUtf8 ( obj - > metaObject ( ) - > className ( ) ) ) ;
}
accessible = accessible - > parent ( ) ;
}
return result ;
}
} // namespace
2012-05-10 21:52:05 +00:00
// 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 ( ) ) {
2022-09-09 19:53:05 +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
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 ) ) ) ;
2022-08-10 11:20:33 +00:00
} else if ( function = = " GetAccessibleId " _L1 ) {
sendReply ( connection , message ,
QVariant : : fromValue ( QDBusVariant ( accessibleIdForAccessible ( interface ) ) ) ) ;
2012-05-10 21:52:05 +00:00
} else {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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-09-15 14:08:08 +00:00
ifaces < < u " " ATSPI_DBUS_INTERFACE_ACCESSIBLE " " _s ;
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-09-15 14:08:08 +00:00
ifaces < < u " " ATSPI_DBUS_INTERFACE_COMPONENT " " _s ;
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-09-15 14:08:08 +00:00
ifaces < < u " " ATSPI_DBUS_INTERFACE_APPLICATION " " _s ;
2012-05-10 21:52:05 +00:00
2014-06-20 12:05:09 +00:00
if ( interface - > actionInterface ( ) | | interface - > valueInterface ( ) )
2022-09-15 14:08:08 +00:00
ifaces < < u " " ATSPI_DBUS_INTERFACE_ACTION " " _s ;
2012-05-10 21:52:05 +00:00
2022-10-11 13:24:04 +00:00
if ( interface - > selectionInterface ( ) )
ifaces < < ATSPI_DBUS_INTERFACE_SELECTION " " _L1 ;
2012-05-10 21:52:05 +00:00
if ( interface - > textInterface ( ) )
2022-09-15 14:08:08 +00:00
ifaces < < u " " ATSPI_DBUS_INTERFACE_TEXT " " _s ;
2012-05-10 21:52:05 +00:00
if ( interface - > editableTextInterface ( ) )
2022-09-15 14:08:08 +00:00
ifaces < < u " " ATSPI_DBUS_INTERFACE_EDITABLE_TEXT " " _s ;
2012-05-10 21:52:05 +00:00
if ( interface - > valueInterface ( ) )
2022-09-15 14:08:08 +00:00
ifaces < < u " " ATSPI_DBUS_INTERFACE_VALUE " " _s ;
2012-05-10 21:52:05 +00:00
if ( interface - > tableInterface ( ) )
2022-09-15 14:08:08 +00:00
ifaces < < u " " ATSPI_DBUS_INTERFACE_TABLE " " _s ;
2012-05-10 21:52:05 +00:00
2022-07-06 12:19:28 +00:00
if ( interface - > tableCellInterface ( ) )
2022-09-15 14:08:08 +00:00
ifaces < < u " " ATSPI_DBUS_INTERFACE_TABLE_CELL " " _s ;
2022-07-06 12:19:28 +00:00
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 ) ) {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " AtSpiAdaptor::pathForObject: 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-09-15 14:08:08 +00:00
return u " " ATSPI_DBUS_PATH_NULL " " _s ;
2012-05-10 21:52:05 +00:00
if ( interface - > role ( ) = = QAccessible : : Application )
2022-09-15 14:08:08 +00:00
return u " " QSPI_OBJECT_PATH_ROOT " " _s ;
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
{
2022-07-18 12:48:51 +00:00
if ( interface - > role ( ) = = QAccessible : : Dialog | | interface - > role ( ) = = QAccessible : : Window )
2012-05-10 21:52:05 +00:00
return interface ;
2013-01-03 16:18:40 +00:00
QAccessibleInterface * parent = interface - > parent ( ) ;
2022-07-18 12:48:51 +00:00
while ( parent & & parent - > role ( ) ! = QAccessible : : Dialog
& & 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
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 ( ) ;
2022-08-03 05:42:10 +00:00
if ( ! isValidCoordType ( coordType ) )
return false ;
ret = getExtents ( interface , coordType ) . contains ( x , y ) ;
2012-05-10 21:52:05 +00:00
sendReply ( connection , message , ret ) ;
2022-04-11 13:54:50 +00:00
} else if ( function = = " GetAccessibleAtPoint " _L1 ) {
2022-08-03 05:42:10 +00:00
QPoint point ( message . arguments ( ) . at ( 0 ) . toInt ( ) , message . arguments ( ) . at ( 1 ) . toInt ( ) ) ;
2012-05-10 21:52:05 +00:00
uint coordType = message . arguments ( ) . at ( 2 ) . toUInt ( ) ;
2022-08-03 05:42:10 +00:00
if ( ! isValidCoordType ( coordType ) )
return false ;
QPoint screenPos = translateToScreenCoordinates ( interface , point , coordType ) ;
2012-05-10 21:52:05 +00:00
2022-08-03 05:42:10 +00:00
QAccessibleInterface * childInterface ( interface - > childAt ( screenPos . x ( ) , screenPos . y ( ) ) ) ;
2020-07-29 14:30:13 +00:00
QAccessibleInterface * iface = nullptr ;
2012-05-10 21:52:05 +00:00
while ( childInterface ) {
iface = childInterface ;
2022-08-03 05:42:10 +00:00
childInterface = iface - > childAt ( screenPos . x ( ) , screenPos . 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 ( ) ;
2022-08-03 05:42:10 +00:00
if ( ! isValidCoordType ( coordType ) )
return false ;
2012-05-10 21:52:05 +00:00
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 ( ) ;
2022-08-03 05:42:10 +00:00
if ( ! isValidCoordType ( coordType ) )
return false ;
QRect rect = getExtents ( interface , coordType ) ;
2012-05-10 21:52:05 +00:00
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 {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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
{
2022-08-03 05:42:10 +00:00
return translateFromScreenCoordinates ( interface , interface - > rect ( ) , coordType ) ;
2012-05-10 21:52:05 +00:00
}
// 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 ) {
Port from container::count() and length() to size() - V5
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2022-09-30 12:09:04 +00:00
int count = QAccessibleBridgeUtils : : effectiveActionNames ( interface ) . size ( ) ;
2014-06-20 12:05:09 +00:00
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 ) ;
Port from container::count() and length() to size() - V5
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2022-09-30 12:09:04 +00:00
if ( index < 0 | | index > = actionNames . size ( ) )
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 ) ;
Port from container::count() and length() to size() - V5
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2022-09-30 12:09:04 +00:00
if ( index < 0 | | index > = actionNames . size ( ) )
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 ) ;
Port from container::count() and length() to size() - V5
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2022-09-30 12:09:04 +00:00
if ( index < 0 | | index > = actionNames . size ( ) )
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 ) ;
Port from container::count() and length() to size() - V5
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2022-09-30 12:09:04 +00:00
if ( index < 0 | | index > = actionNames . size ( ) )
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 ) ;
}
Port from container::count() and length() to size() - V5
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2022-09-30 12:09:04 +00:00
if ( keyBindings . size ( ) > 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 {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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 ( ) ;
2022-08-18 09:12:29 +00:00
connection . send ( message . createReply ( QVariant ( 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 ( ) ;
2022-08-03 05:42:10 +00:00
if ( ! isValidCoordType ( coordType ) )
return false ;
QPoint screenPos = translateToScreenCoordinates ( interface , point , coordType ) ;
int offset = interface - > textInterface ( ) - > offsetAtPoint ( screenPos ) ;
2012-05-10 21:52:05 +00:00
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 ) ) ;
a11y atspi: Support text interface's GetStringAtOffset
The GetStringAtOffset method was added to the
AT-SPI Text interface in at-spi2-core commmit [1]:
commit 56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Author: Mike Gorse <mgorse@suse.com>
Date: Mon Aug 19 16:43:02 2013 -0500
Add atspi_text_get_string_at_offset
As compared to GetTextAtOffset, which is very similar and
already supported in Qt's AT-SPI adapter, the new method
uses a new enum, AtspiTextGranularity, to specify the region
of text that should be returned.
Other than AtspiTextBoundaryType (that is used by
GetTextAtOffset), AtspiTextGranularity now also has
a value for the paragraph granularity
(ATSPI_TEXT_GRANULARITY_PARAGRAPH).
While AtspiTextBoundaryType has two enum values for the
word/sentence/line boundaries (ATSPI_TEXT_BOUNDARY_WORD_START and
ATSPI_TEXT_BOUNDARY_WORD_END, etc.), AtspiTextGranularity
doesn't have this any more, but ATSPI_TEXT_GRANULARITY_WORD
etc. seem to correspond to what the variants ending on "_START"
do when used with GetTextAtOffset, since the documentation says that
the range is "defined by the boundaries of a word
starting at the beginning of the current word and finishing
at the beginning of the following one, if present." (and likewise
for ATSPI_TEXT_GRANULARITY_SENTENCE, ATSPI_TEXT_GRANULARITY_LINE,
ATSPI_TEXT_GRANULARITY_PARAGRAPH).
In order to support GetStringAtOffset, this
adds a new mapping from the AtspiTextGranularity enum values
to the corresponding QAccessible::TextBoundaryType, similar
to what's done for the AtspiTextBoundaryType in the
handling of the GetTextAtOffset method.
The existing AtSpiAdaptor::qAccessibleBoundaryType
method is renamed to
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiBoundaryType
to clearer distinguish it from the newly introduced
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiTextGranularity.
No similar new alternatives have been added
to AT-SPI for GetTextBeforeOffset and GetTextAfterOffset.
[1] https://gitlab.gnome.org/GNOME/at-spi2-core/-/commit/56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Fixes: QTBUG-105811
Change-Id: I674a760e80c349baea89dcb4ac7aecdef9b2b45f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2022-08-18 13:21:38 +00:00
} else if ( function = = " GetStringAtOffset " _L1 ) {
int offset = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
uint granularity = message . arguments ( ) . at ( 1 ) . toUInt ( ) ;
if ( ! isValidAtspiTextGranularity ( granularity ) )
return false ;
int startOffset , endOffset ;
QString text = interface - > textInterface ( ) - > textAtOffset ( offset , qAccessibleBoundaryTypeFromAtspiTextGranularity ( granularity ) , & startOffset , & endOffset ) ;
QVariantList ret ;
ret < < text < < startOffset < < endOffset ;
connection . send ( message . createReply ( ret ) ) ;
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 ;
a11y atspi: Support text interface's GetStringAtOffset
The GetStringAtOffset method was added to the
AT-SPI Text interface in at-spi2-core commmit [1]:
commit 56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Author: Mike Gorse <mgorse@suse.com>
Date: Mon Aug 19 16:43:02 2013 -0500
Add atspi_text_get_string_at_offset
As compared to GetTextAtOffset, which is very similar and
already supported in Qt's AT-SPI adapter, the new method
uses a new enum, AtspiTextGranularity, to specify the region
of text that should be returned.
Other than AtspiTextBoundaryType (that is used by
GetTextAtOffset), AtspiTextGranularity now also has
a value for the paragraph granularity
(ATSPI_TEXT_GRANULARITY_PARAGRAPH).
While AtspiTextBoundaryType has two enum values for the
word/sentence/line boundaries (ATSPI_TEXT_BOUNDARY_WORD_START and
ATSPI_TEXT_BOUNDARY_WORD_END, etc.), AtspiTextGranularity
doesn't have this any more, but ATSPI_TEXT_GRANULARITY_WORD
etc. seem to correspond to what the variants ending on "_START"
do when used with GetTextAtOffset, since the documentation says that
the range is "defined by the boundaries of a word
starting at the beginning of the current word and finishing
at the beginning of the following one, if present." (and likewise
for ATSPI_TEXT_GRANULARITY_SENTENCE, ATSPI_TEXT_GRANULARITY_LINE,
ATSPI_TEXT_GRANULARITY_PARAGRAPH).
In order to support GetStringAtOffset, this
adds a new mapping from the AtspiTextGranularity enum values
to the corresponding QAccessible::TextBoundaryType, similar
to what's done for the AtspiTextBoundaryType in the
handling of the GetTextAtOffset method.
The existing AtSpiAdaptor::qAccessibleBoundaryType
method is renamed to
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiBoundaryType
to clearer distinguish it from the newly introduced
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiTextGranularity.
No similar new alternatives have been added
to AT-SPI for GetTextBeforeOffset and GetTextAfterOffset.
[1] https://gitlab.gnome.org/GNOME/at-spi2-core/-/commit/56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Fixes: QTBUG-105811
Change-Id: I674a760e80c349baea89dcb4ac7aecdef9b2b45f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2022-08-18 13:21:38 +00:00
QString text = interface - > textInterface ( ) - > textAfterOffset ( offset , qAccessibleBoundaryTypeFromAtspiBoundaryType ( type ) , & startOffset , & endOffset ) ;
2012-05-10 21:52:05 +00:00
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 ;
a11y atspi: Support text interface's GetStringAtOffset
The GetStringAtOffset method was added to the
AT-SPI Text interface in at-spi2-core commmit [1]:
commit 56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Author: Mike Gorse <mgorse@suse.com>
Date: Mon Aug 19 16:43:02 2013 -0500
Add atspi_text_get_string_at_offset
As compared to GetTextAtOffset, which is very similar and
already supported in Qt's AT-SPI adapter, the new method
uses a new enum, AtspiTextGranularity, to specify the region
of text that should be returned.
Other than AtspiTextBoundaryType (that is used by
GetTextAtOffset), AtspiTextGranularity now also has
a value for the paragraph granularity
(ATSPI_TEXT_GRANULARITY_PARAGRAPH).
While AtspiTextBoundaryType has two enum values for the
word/sentence/line boundaries (ATSPI_TEXT_BOUNDARY_WORD_START and
ATSPI_TEXT_BOUNDARY_WORD_END, etc.), AtspiTextGranularity
doesn't have this any more, but ATSPI_TEXT_GRANULARITY_WORD
etc. seem to correspond to what the variants ending on "_START"
do when used with GetTextAtOffset, since the documentation says that
the range is "defined by the boundaries of a word
starting at the beginning of the current word and finishing
at the beginning of the following one, if present." (and likewise
for ATSPI_TEXT_GRANULARITY_SENTENCE, ATSPI_TEXT_GRANULARITY_LINE,
ATSPI_TEXT_GRANULARITY_PARAGRAPH).
In order to support GetStringAtOffset, this
adds a new mapping from the AtspiTextGranularity enum values
to the corresponding QAccessible::TextBoundaryType, similar
to what's done for the AtspiTextBoundaryType in the
handling of the GetTextAtOffset method.
The existing AtSpiAdaptor::qAccessibleBoundaryType
method is renamed to
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiBoundaryType
to clearer distinguish it from the newly introduced
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiTextGranularity.
No similar new alternatives have been added
to AT-SPI for GetTextBeforeOffset and GetTextAfterOffset.
[1] https://gitlab.gnome.org/GNOME/at-spi2-core/-/commit/56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Fixes: QTBUG-105811
Change-Id: I674a760e80c349baea89dcb4ac7aecdef9b2b45f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2022-08-18 13:21:38 +00:00
QString text = interface - > textInterface ( ) - > textAtOffset ( offset , qAccessibleBoundaryTypeFromAtspiBoundaryType ( type ) , & startOffset , & endOffset ) ;
2012-05-10 21:52:05 +00:00
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 ;
a11y atspi: Support text interface's GetStringAtOffset
The GetStringAtOffset method was added to the
AT-SPI Text interface in at-spi2-core commmit [1]:
commit 56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Author: Mike Gorse <mgorse@suse.com>
Date: Mon Aug 19 16:43:02 2013 -0500
Add atspi_text_get_string_at_offset
As compared to GetTextAtOffset, which is very similar and
already supported in Qt's AT-SPI adapter, the new method
uses a new enum, AtspiTextGranularity, to specify the region
of text that should be returned.
Other than AtspiTextBoundaryType (that is used by
GetTextAtOffset), AtspiTextGranularity now also has
a value for the paragraph granularity
(ATSPI_TEXT_GRANULARITY_PARAGRAPH).
While AtspiTextBoundaryType has two enum values for the
word/sentence/line boundaries (ATSPI_TEXT_BOUNDARY_WORD_START and
ATSPI_TEXT_BOUNDARY_WORD_END, etc.), AtspiTextGranularity
doesn't have this any more, but ATSPI_TEXT_GRANULARITY_WORD
etc. seem to correspond to what the variants ending on "_START"
do when used with GetTextAtOffset, since the documentation says that
the range is "defined by the boundaries of a word
starting at the beginning of the current word and finishing
at the beginning of the following one, if present." (and likewise
for ATSPI_TEXT_GRANULARITY_SENTENCE, ATSPI_TEXT_GRANULARITY_LINE,
ATSPI_TEXT_GRANULARITY_PARAGRAPH).
In order to support GetStringAtOffset, this
adds a new mapping from the AtspiTextGranularity enum values
to the corresponding QAccessible::TextBoundaryType, similar
to what's done for the AtspiTextBoundaryType in the
handling of the GetTextAtOffset method.
The existing AtSpiAdaptor::qAccessibleBoundaryType
method is renamed to
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiBoundaryType
to clearer distinguish it from the newly introduced
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiTextGranularity.
No similar new alternatives have been added
to AT-SPI for GetTextBeforeOffset and GetTextAfterOffset.
[1] https://gitlab.gnome.org/GNOME/at-spi2-core/-/commit/56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Fixes: QTBUG-105811
Change-Id: I674a760e80c349baea89dcb4ac7aecdef9b2b45f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2022-08-18 13:21:38 +00:00
QString text = interface - > textInterface ( ) - > textBeforeOffset ( offset , qAccessibleBoundaryTypeFromAtspiBoundaryType ( type ) , & startOffset , & endOffset ) ;
2012-05-10 21:52:05 +00:00
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-08-22 07:38:24 +00:00
} else if ( function = = " ScrollSubstringTo " _L1 ) {
int startOffset = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
int endOffset = message . arguments ( ) . at ( 1 ) . toInt ( ) ;
// ignore third parameter (scroll type), since QAccessibleTextInterface::scrollToSubstring doesn't have that
qCInfo ( lcAccessibilityAtspi ) < < " AtSpiAdaptor::ScrollSubstringTo doesn'take take scroll type into account. " ;
interface - > textInterface ( ) - > scrollToSubstring ( startOffset , endOffset ) ;
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 {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " AtSpiAdaptor::textInterface does not implement " < < function < < message . path ( ) ;
2012-05-10 21:52:05 +00:00
return false ;
}
return true ;
}
a11y atspi: Support text interface's GetStringAtOffset
The GetStringAtOffset method was added to the
AT-SPI Text interface in at-spi2-core commmit [1]:
commit 56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Author: Mike Gorse <mgorse@suse.com>
Date: Mon Aug 19 16:43:02 2013 -0500
Add atspi_text_get_string_at_offset
As compared to GetTextAtOffset, which is very similar and
already supported in Qt's AT-SPI adapter, the new method
uses a new enum, AtspiTextGranularity, to specify the region
of text that should be returned.
Other than AtspiTextBoundaryType (that is used by
GetTextAtOffset), AtspiTextGranularity now also has
a value for the paragraph granularity
(ATSPI_TEXT_GRANULARITY_PARAGRAPH).
While AtspiTextBoundaryType has two enum values for the
word/sentence/line boundaries (ATSPI_TEXT_BOUNDARY_WORD_START and
ATSPI_TEXT_BOUNDARY_WORD_END, etc.), AtspiTextGranularity
doesn't have this any more, but ATSPI_TEXT_GRANULARITY_WORD
etc. seem to correspond to what the variants ending on "_START"
do when used with GetTextAtOffset, since the documentation says that
the range is "defined by the boundaries of a word
starting at the beginning of the current word and finishing
at the beginning of the following one, if present." (and likewise
for ATSPI_TEXT_GRANULARITY_SENTENCE, ATSPI_TEXT_GRANULARITY_LINE,
ATSPI_TEXT_GRANULARITY_PARAGRAPH).
In order to support GetStringAtOffset, this
adds a new mapping from the AtspiTextGranularity enum values
to the corresponding QAccessible::TextBoundaryType, similar
to what's done for the AtspiTextBoundaryType in the
handling of the GetTextAtOffset method.
The existing AtSpiAdaptor::qAccessibleBoundaryType
method is renamed to
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiBoundaryType
to clearer distinguish it from the newly introduced
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiTextGranularity.
No similar new alternatives have been added
to AT-SPI for GetTextBeforeOffset and GetTextAfterOffset.
[1] https://gitlab.gnome.org/GNOME/at-spi2-core/-/commit/56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Fixes: QTBUG-105811
Change-Id: I674a760e80c349baea89dcb4ac7aecdef9b2b45f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2022-08-18 13:21:38 +00:00
QAccessible : : TextBoundaryType AtSpiAdaptor : : qAccessibleBoundaryTypeFromAtspiBoundaryType ( int atspiTextBoundaryType )
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
}
a11y atspi: Support text interface's GetStringAtOffset
The GetStringAtOffset method was added to the
AT-SPI Text interface in at-spi2-core commmit [1]:
commit 56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Author: Mike Gorse <mgorse@suse.com>
Date: Mon Aug 19 16:43:02 2013 -0500
Add atspi_text_get_string_at_offset
As compared to GetTextAtOffset, which is very similar and
already supported in Qt's AT-SPI adapter, the new method
uses a new enum, AtspiTextGranularity, to specify the region
of text that should be returned.
Other than AtspiTextBoundaryType (that is used by
GetTextAtOffset), AtspiTextGranularity now also has
a value for the paragraph granularity
(ATSPI_TEXT_GRANULARITY_PARAGRAPH).
While AtspiTextBoundaryType has two enum values for the
word/sentence/line boundaries (ATSPI_TEXT_BOUNDARY_WORD_START and
ATSPI_TEXT_BOUNDARY_WORD_END, etc.), AtspiTextGranularity
doesn't have this any more, but ATSPI_TEXT_GRANULARITY_WORD
etc. seem to correspond to what the variants ending on "_START"
do when used with GetTextAtOffset, since the documentation says that
the range is "defined by the boundaries of a word
starting at the beginning of the current word and finishing
at the beginning of the following one, if present." (and likewise
for ATSPI_TEXT_GRANULARITY_SENTENCE, ATSPI_TEXT_GRANULARITY_LINE,
ATSPI_TEXT_GRANULARITY_PARAGRAPH).
In order to support GetStringAtOffset, this
adds a new mapping from the AtspiTextGranularity enum values
to the corresponding QAccessible::TextBoundaryType, similar
to what's done for the AtspiTextBoundaryType in the
handling of the GetTextAtOffset method.
The existing AtSpiAdaptor::qAccessibleBoundaryType
method is renamed to
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiBoundaryType
to clearer distinguish it from the newly introduced
AtSpiAdaptor::qAccessibleBoundaryTypeFromAtspiTextGranularity.
No similar new alternatives have been added
to AT-SPI for GetTextBeforeOffset and GetTextAfterOffset.
[1] https://gitlab.gnome.org/GNOME/at-spi2-core/-/commit/56220f05bc8b7683911658e1a8aff4a1ab3cab8d
Fixes: QTBUG-105811
Change-Id: I674a760e80c349baea89dcb4ac7aecdef9b2b45f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2022-08-18 13:21:38 +00:00
bool AtSpiAdaptor : : isValidAtspiTextGranularity ( uint atspiTextGranularity )
{
if ( atspiTextGranularity = = ATSPI_TEXT_GRANULARITY_CHAR
| | atspiTextGranularity = = ATSPI_TEXT_GRANULARITY_WORD
| | atspiTextGranularity = = ATSPI_TEXT_GRANULARITY_SENTENCE
| | atspiTextGranularity = = ATSPI_TEXT_GRANULARITY_LINE
| | atspiTextGranularity = = ATSPI_TEXT_GRANULARITY_PARAGRAPH )
return true ;
qCWarning ( lcAccessibilityAtspi ) < < " Unknown value " < < atspiTextGranularity < < " for AT-SPI text granularity type " ;
return false ;
}
QAccessible : : TextBoundaryType AtSpiAdaptor : : qAccessibleBoundaryTypeFromAtspiTextGranularity ( uint atspiTextGranularity )
{
Q_ASSERT ( isValidAtspiTextGranularity ( atspiTextGranularity ) ) ;
switch ( atspiTextGranularity ) {
case ATSPI_TEXT_GRANULARITY_CHAR :
return QAccessible : : CharBoundary ;
case ATSPI_TEXT_GRANULARITY_WORD :
return QAccessible : : WordBoundary ;
case ATSPI_TEXT_GRANULARITY_SENTENCE :
return QAccessible : : SentenceBoundary ;
case ATSPI_TEXT_GRANULARITY_LINE :
return QAccessible : : LineBoundary ;
case ATSPI_TEXT_GRANULARITY_PARAGRAPH :
return QAccessible : : ParagraphBoundary ;
}
return QAccessible : : CharBoundary ;
}
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"
Port from container.count()/length() to size()
This is semantic patch using ClangTidyTransformator:
auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)
makeRule(cxxMemberCallExpr(on(QtContainerClass),
callee(cxxMethodDecl(hasAnyName({"count", "length"),
parameterCountIs(0))))),
changeTo(cat(access(o, cat("size"), "()"))),
cat("use 'size()' instead of 'count()/length()'"))
a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'.
<classes> are:
// sequential:
"QByteArray",
"QList",
"QQueue",
"QStack",
"QString",
"QVarLengthArray",
"QVector",
// associative:
"QHash",
"QMultiHash",
"QMap",
"QMultiMap",
"QSet",
// Qt has no QMultiSet
Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2022-09-30 12:09:04 +00:00
return ia2Color . mid ( 4 , ia2Color . size ( ) - ( 4 + 1 ) ) ;
2015-02-15 22:04:51 +00:00
}
QString atspiSize ( const QString & ia2Size )
{
// "%fpt" -> "%f"
Port from container.count()/length() to size()
This is semantic patch using ClangTidyTransformator:
auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)
makeRule(cxxMemberCallExpr(on(QtContainerClass),
callee(cxxMethodDecl(hasAnyName({"count", "length"),
parameterCountIs(0))))),
changeTo(cat(access(o, cat("size"), "()"))),
cat("use 'size()' instead of 'count()/length()'"))
a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'.
<classes> are:
// sequential:
"QByteArray",
"QList",
"QQueue",
"QStack",
"QString",
"QVarLengthArray",
"QVector",
// associative:
"QHash",
"QMultiHash",
"QMap",
"QMultiMap",
"QSet",
// Qt has no QMultiSet
Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2022-09-30 12:09:04 +00:00
return ia2Size . left ( ia2Size . size ( ) - 2 ) ;
2015-02-15 22:04:51 +00:00
}
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 ;
}
2022-08-18 09:12:29 +00:00
QString AtSpiAdaptor : : getAttributeValue ( QAccessibleInterface * interface , int offset , const QString & attributeName ) const
2012-05-10 21:52:05 +00:00
{
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
}
2022-08-18 09:12:29 +00:00
return map [ attributeName ] ;
2012-05-10 21:52:05 +00:00
}
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 ) ;
2022-08-03 05:42:10 +00:00
rect = translateFromScreenCoordinates ( interface , rect , coordType ) ;
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 ) ;
2022-08-03 05:42:10 +00:00
rect = translateFromScreenCoordinates ( interface , rect , coordType ) ;
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
}
2022-08-03 05:42:10 +00:00
bool AtSpiAdaptor : : isValidCoordType ( uint coordType )
{
if ( coordType = = ATSPI_COORD_TYPE_SCREEN | | coordType = = ATSPI_COORD_TYPE_WINDOW | | coordType = = ATSPI_COORD_TYPE_PARENT )
return true ;
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " Unknown value " < < coordType < < " for AT-SPI coord type " ;
2022-08-03 05:42:10 +00:00
return false ;
}
QRect AtSpiAdaptor : : translateFromScreenCoordinates ( QAccessibleInterface * interface , const QRect & screenRect , uint targetCoordType )
2012-05-10 21:52:05 +00:00
{
2022-08-03 05:42:10 +00:00
Q_ASSERT ( isValidCoordType ( targetCoordType ) ) ;
QAccessibleInterface * upper = nullptr ;
if ( targetCoordType = = ATSPI_COORD_TYPE_WINDOW )
upper = getWindow ( interface ) ;
else if ( targetCoordType = = ATSPI_COORD_TYPE_PARENT )
upper = interface - > parent ( ) ;
QRect rect = screenRect ;
if ( upper )
rect . translate ( - upper - > rect ( ) . x ( ) , - upper - > rect ( ) . y ( ) ) ;
2012-05-10 21:52:05 +00:00
return rect ;
}
2022-08-03 05:42:10 +00:00
QPoint AtSpiAdaptor : : translateToScreenCoordinates ( QAccessibleInterface * interface , const QPoint & pos , uint fromCoordType )
{
Q_ASSERT ( isValidCoordType ( fromCoordType ) ) ;
QAccessibleInterface * upper = nullptr ;
if ( fromCoordType = = ATSPI_COORD_TYPE_WINDOW )
upper = getWindow ( interface ) ;
else if ( fromCoordType = = ATSPI_COORD_TYPE_PARENT )
upper = interface - > parent ( ) ;
QPoint screenPos = pos ;
if ( upper )
screenPos + = upper - > rect ( ) . topLeft ( ) ;
return screenPos ;
}
2012-05-10 21:52:05 +00:00
// 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 )
Port from container.count()/length() to size()
This is semantic patch using ClangTidyTransformator:
auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)
makeRule(cxxMemberCallExpr(on(QtContainerClass),
callee(cxxMethodDecl(hasAnyName({"count", "length"),
parameterCountIs(0))))),
changeTo(cat(access(o, cat("size"), "()"))),
cat("use 'size()' instead of 'count()/length()'"))
a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'.
<classes> are:
// sequential:
"QByteArray",
"QList",
"QQueue",
"QStack",
"QString",
"QVarLengthArray",
"QVector",
// associative:
"QHash",
"QMultiHash",
"QMap",
"QMultiMap",
"QSet",
// Qt has no QMultiSet
Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2022-09-30 12:09:04 +00:00
endOffset = txt . size ( ) ;
2012-05-10 21:52:05 +00:00
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 )
Port from container.count()/length() to size()
This is semantic patch using ClangTidyTransformator:
auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)
makeRule(cxxMemberCallExpr(on(QtContainerClass),
callee(cxxMethodDecl(hasAnyName({"count", "length"),
parameterCountIs(0))))),
changeTo(cat(access(o, cat("size"), "()"))),
cat("use 'size()' instead of 'count()/length()'"))
a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'.
<classes> are:
// sequential:
"QByteArray",
"QList",
"QQueue",
"QStack",
"QString",
"QVarLengthArray",
"QVector",
// associative:
"QHash",
"QMultiHash",
"QMap",
"QMultiMap",
"QSet",
// Qt has no QMultiSet
Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2022-09-30 12:09:04 +00:00
endOffset = t . size ( ) ;
2012-05-10 21:52:05 +00:00
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-09-15 15:24:22 +00:00
} else if ( function . isEmpty ( ) ) {
2012-05-10 21:52:05 +00:00
connection . send ( message . createReply ( ) ) ;
} else {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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 ) ;
2022-08-19 08:15:58 +00:00
connection . send ( message . createReply ( ) ) ;
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 {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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 > ( ) ) {
2022-10-25 16:08:10 +00:00
qCWarning ( 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 ;
}
2022-10-11 13:24:04 +00:00
// Selection interface
bool AtSpiAdaptor : : selectionInterface ( QAccessibleInterface * interface , const QString & function , const QDBusMessage & message , const QDBusConnection & connection )
{
QAccessibleSelectionInterface * selectionInterface = interface - > selectionInterface ( ) ;
if ( ! selectionInterface ) {
qCWarning ( lcAccessibilityAtspi ) < < " Could not find selection interface for: " < < message . path ( ) < < interface ;
return false ;
}
if ( function = = " ClearSelection " _L1 ) {
connection . send ( message . createReply ( QVariant : : fromValue ( ( selectionInterface - > clear ( ) ) ) ) ) ;
} else if ( function = = " DeselectChild " _L1 ) {
int childIndex = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
bool ret = false ;
QAccessibleInterface * child = interface - > child ( childIndex ) ;
if ( child )
ret = selectionInterface - > unselect ( child ) ;
connection . send ( message . createReply ( QVariant : : fromValue ( ret ) ) ) ;
} else if ( function = = " DeselectSelectedChild " _L1 ) {
int selectionIndex = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
bool ret = false ;
QAccessibleInterface * selectedChild = selectionInterface - > selectedItem ( selectionIndex ) ;
if ( selectedChild )
ret = selectionInterface - > unselect ( selectedChild ) ;
connection . send ( message . createReply ( QVariant : : fromValue ( ret ) ) ) ;
} else if ( function = = " GetNSelectedChildren " _L1 ) {
connection . send ( message . createReply ( QVariant : : fromValue ( QDBusVariant (
QVariant : : fromValue ( selectionInterface - > selectedItemCount ( ) ) ) ) ) ) ;
} else if ( function = = " GetSelectedChild " _L1 ) {
int selectionIndex = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
QSpiObjectReference ref ( connection , QDBusObjectPath ( pathForInterface ( selectionInterface - > selectedItem ( selectionIndex ) ) ) ) ;
connection . send ( message . createReply ( QVariant : : fromValue ( ref ) ) ) ;
} else if ( function = = " IsChildSelected " _L1 ) {
int childIndex = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
bool ret = false ;
QAccessibleInterface * child = interface - > child ( childIndex ) ;
if ( child )
ret = selectionInterface - > isSelected ( child ) ;
connection . send ( message . createReply ( QVariant : : fromValue ( ret ) ) ) ;
} else if ( function = = " SelectAll " _L1 ) {
connection . send ( message . createReply ( QVariant : : fromValue ( selectionInterface - > selectAll ( ) ) ) ) ;
} else if ( function = = " SelectChild " _L1 ) {
int childIndex = message . arguments ( ) . at ( 0 ) . toInt ( ) ;
bool ret = false ;
QAccessibleInterface * child = interface - > child ( childIndex ) ;
if ( child )
ret = selectionInterface - > select ( child ) ;
connection . send ( message . createReply ( QVariant : : fromValue ( ret ) ) ) ;
} else {
qCWarning ( lcAccessibilityAtspi ) < < " AtSpiAdaptor::selectionInterface does not implement " < < function < < message . path ( ) ;
return false ;
}
return true ;
}
2012-05-10 21:52:05 +00:00
// 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 ( ) ) ) {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " Qt AtSpiAdaptor: Could not find table interface for: " < < message . path ( ) < < interface ;
2012-05-10 21:52:05 +00:00
return false ;
}
2022-06-15 14:47:17 +00:00
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 ) ) ) ;
2022-08-10 11:44:39 +00:00
sendReply ( connection , message , QVariant : : fromValue ( QDBusVariant ( QVariant : : fromValue ( ref ) ) ) ) ;
2012-05-10 21:52:05 +00:00
} else {
2022-08-10 11:44:39 +00:00
sendReply ( connection , message , QVariant : : fromValue ( QDBusVariant ( QVariant : : fromValue (
QSpiObjectReference ( connection , QDBusObjectPath ( ATSPI_DBUS_PATH_NULL ) ) ) ) ) ) ;
2012-05-10 21:52:05 +00:00
}
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 ( ) ) ) {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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 {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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 ) {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " 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 ( ) ) {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) . nospace ( ) < < " 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 ( ) ) {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) . nospace ( ) < < " AtSpiAdaptor:: " < < function < < " No table cell interface: " < < cell ;
2012-05-10 21:52:05 +00:00
return false ;
}
ret = cell - > tableCellInterface ( ) - > rowIndex ( ) ;
}
}
} else {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) . nospace ( ) < < " 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 ;
2022-09-02 06:29:47 +00:00
QAccessibleInterface * cell = interface - > tableInterface ( ) - > cellAt ( row , 0 ) ;
if ( cell & & cell - > tableCellInterface ( ) ) {
QList < QAccessibleInterface * > header = cell - > tableCellInterface ( ) - > rowHeaderCells ( ) ;
2012-05-10 21:52:05 +00:00
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 {
2022-10-25 16:08:10 +00:00
qCWarning ( lcAccessibilityAtspi ) < < " AtSpiAdaptor::tableInterface does not implement " < < function < < message . path ( ) ;
2012-05-10 21:52:05 +00:00
return false ;
}
return true ;
}
2022-07-06 12:19:28 +00:00
// Table cell interface
bool AtSpiAdaptor : : tableCellInterface ( QAccessibleInterface * interface , const QString & function , const QDBusMessage & message , const QDBusConnection & connection )
{
QAccessibleTableCellInterface * cellInterface = interface - > tableCellInterface ( ) ;
if ( ! cellInterface ) {
qCWarning ( lcAccessibilityAtspi ) < < " Could not find table cell interface for: " < < message . path ( ) < < interface ;
return false ;
}
if ( function = = " GetColumnSpan " _L1 ) {
connection . send ( message . createReply ( QVariant : : fromValue ( QDBusVariant (
QVariant : : fromValue ( cellInterface - > columnExtent ( ) ) ) ) ) ) ;
} else if ( function = = " GetPosition " _L1 ) {
const int row = cellInterface - > rowIndex ( ) ;
const int column = cellInterface - > columnIndex ( ) ;
connection . send ( message . createReply ( QVariant : : fromValue ( QDBusVariant (
QVariant : : fromValue ( QPoint ( row , column ) ) ) ) ) ) ;
} else if ( function = = " GetRowSpan " _L1 ) {
connection . send ( message . createReply ( QVariant : : fromValue ( QDBusVariant (
QVariant : : fromValue ( cellInterface - > rowExtent ( ) ) ) ) ) ) ;
} else if ( function = = " GetRowColumnSpan " _L1 ) {
QVariantList list ;
list < < cellInterface - > rowIndex ( ) < < cellInterface - > columnIndex ( ) < < cellInterface - > rowExtent ( ) < < cellInterface - > columnExtent ( ) ;
connection . send ( message . createReply ( list ) ) ;
} else if ( function = = " GetTable " _L1 ) {
QSpiObjectReference ref ;
QAccessibleInterface * table = cellInterface - > table ( ) ;
if ( table & & table - > tableInterface ( ) )
ref = QSpiObjectReference ( connection , QDBusObjectPath ( pathForInterface ( table ) ) ) ;
connection . send ( message . createReply ( QVariant : : fromValue ( QDBusVariant ( QVariant : : fromValue ( ref ) ) ) ) ) ;
}
return true ;
}
2012-05-10 21:52:05 +00:00
QT_END_NAMESPACE
2022-01-25 20:20:56 +00:00
# include "moc_atspiadaptor_p.cpp"
2022-06-09 10:52:37 +00:00
# endif // QT_CONFIG(accessibility)