diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-08-13 10:37:50 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-09-30 16:53:32 +0200 |
commit | 1ae450504cf57457f9702684b1517fda1dd3c481 (patch) | |
tree | 2b1fc3870594dcc01217e3e406322ab084e258ef /vcl/unx/gtk/a11y | |
parent | 25ca657f8d0f1febaf0d5984bc862f3072ad197b (diff) |
drop gtk2 support
Change-Id: Ie838cabfecfef7e3225c1555536d5c9cf3b43f15
Reviewed-on: https://gerrit.libreoffice.org/77405
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/unx/gtk/a11y')
25 files changed, 0 insertions, 7970 deletions
diff --git a/vcl/unx/gtk/a11y/TODO b/vcl/unx/gtk/a11y/TODO deleted file mode 100644 index 1048bd96ef75..000000000000 --- a/vcl/unx/gtk/a11y/TODO +++ /dev/null @@ -1,49 +0,0 @@ -cws 'atkbridge' -#Issue number: i#47890# -Submitted by: mmeeks - -Hacked up prototype of atk bridge - - -Serious problems - + Threading/locking: - + incoming CORBA calls & the GDK lock - + how are these being processed & on what thread ? - + are we holding the GDK_THREADS lock ? - + can we even do that ? - + is it really necessary to be thread safe ? - + how does this work in combination with the (unsafe) GAIL code ? - + what should incoming CORBA calls be doing ? - + esp. since we can't tell if they're coming from - in-proc or not either [ though this is unlikely ] - - -Test: - + in-line text editing, does the TEXT_CHANGED signal get it right, - + why not copy/paste/delete etc. ? - + check vs. writer & other bits ... - + AtkSelection - + AtkHyper* - -* At-poke - + implement non-gui mode - for to-console event logging - + logging - + more detail from remaining events - + add a Tree navigation thing instead (?) - + poke a sub-child (?) - + embed a tree widget inside the tree view ? - + AtkHyperText testing (?) - - -Known bugs: - + AtkText - + selection interface - multiple selections ? - + word boundary issues - + copy AccessibleTextImpl.java's getAfterIndex eg. - + the 'getFoo' methods need to use UNO_QUERY_THROW & - throw an exception to avoid null pointer dereferences. - + AtkAttributeSet (etc.) - + AtkEditableText - + finish/test AtkTable - + HyperLink 'link_activated', HyperText 'link_selected' (?) - + tooltips create new toplevels with broken roles. diff --git a/vcl/unx/gtk/a11y/atkaction.cxx b/vcl/unx/gtk/a11y/atkaction.cxx deleted file mode 100644 index 14a172fe6ae3..000000000000 --- a/vcl/unx/gtk/a11y/atkaction.cxx +++ /dev/null @@ -1,275 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleAction.hpp> -#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp> - -#include <com/sun/star/awt/Key.hpp> -#include <com/sun/star/awt/KeyModifier.hpp> - -#include <rtl/strbuf.hxx> -#include <algorithm> -#include <map> - -using namespace ::com::sun::star; - -// FIXME -static const gchar * -getAsConst( const OString& rString ) -{ - static const int nMax = 10; - static OString aUgly[nMax]; - static int nIdx = 0; - nIdx = (nIdx + 1) % nMax; - aUgly[nIdx] = rString; - return aUgly[ nIdx ].getStr(); -} - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleAction> - getAction( AtkAction *action ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( action ); - - if( pWrap ) - { - if( !pWrap->mpAction.is() ) - { - pWrap->mpAction.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpAction; - } - - return css::uno::Reference<css::accessibility::XAccessibleAction>(); -} - -extern "C" { - -static gboolean -action_wrapper_do_action (AtkAction *action, - gint i) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleAction> pAction - = getAction( action ); - if( pAction.is() ) - return pAction->doAccessibleAction( i ); - } - catch(const uno::Exception&) { - g_warning( "Exception in doAccessibleAction()" ); - } - - return FALSE; -} - -static gint -action_wrapper_get_n_actions (AtkAction *action) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleAction> pAction - = getAction( action ); - if( pAction.is() ) - return pAction->getAccessibleActionCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleActionCount()" ); - } - - return 0; -} - -static const gchar * -action_wrapper_get_description (AtkAction *, gint) -{ - // GAIL implement this only for cells - g_warning( "Not implemented: get_description()" ); - return ""; -} - -static const gchar * -action_wrapper_get_localized_name (AtkAction *, gint) -{ - // GAIL doesn't implement this as well - g_warning( "Not implemented: get_localized_name()" ); - return ""; -} - -#define ACTION_NAME_PAIR( OOoName, AtkName ) \ - std::pair< const OUString, const gchar * > ( OUString( OOoName ), AtkName ) - -static const gchar * -action_wrapper_get_name (AtkAction *action, - gint i) -{ - static std::map< OUString, const gchar * > aNameMap; - - if( aNameMap.empty() ) - { - aNameMap.insert( ACTION_NAME_PAIR( "click", "click" ) ); - aNameMap.insert( ACTION_NAME_PAIR( "select", "click" ) ); - aNameMap.insert( ACTION_NAME_PAIR( "togglePopup", "push" ) ); - } - - try { - css::uno::Reference<css::accessibility::XAccessibleAction> pAction - = getAction( action ); - if( pAction.is() ) - { - std::map< OUString, const gchar * >::iterator iter; - - OUString aDesc( pAction->getAccessibleActionDescription( i ) ); - - iter = aNameMap.find( aDesc ); - if( iter != aNameMap.end() ) - return iter->second; - - std::pair< const OUString, const gchar * > aNewVal( aDesc, - g_strdup( OUStringToConstGChar(aDesc) ) ); - - if( aNameMap.insert( aNewVal ).second ) - return aNewVal.second; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleActionDescription()" ); - } - - return ""; -} - -/* -* GNOME Expects a string in the format: -* -* <mnemonic>;<full-path>;<accelerator> -* -* The keybindings in <full-path> should be separated by ":" -*/ - -static void -appendKeyStrokes(OStringBuffer& rBuffer, const uno::Sequence< awt::KeyStroke >& rKeyStrokes) -{ - for( const auto& rKeyStroke : rKeyStrokes ) - { - if( rKeyStroke.Modifiers & awt::KeyModifier::SHIFT ) - rBuffer.append("<Shift>"); - if( rKeyStroke.Modifiers & awt::KeyModifier::MOD1 ) - rBuffer.append("<Control>"); - if( rKeyStroke.Modifiers & awt::KeyModifier::MOD2 ) - rBuffer.append("<Alt>"); - - if( ( rKeyStroke.KeyCode >= awt::Key::A ) && ( rKeyStroke.KeyCode <= awt::Key::Z ) ) - rBuffer.append( static_cast<sal_Char>( 'a' + ( rKeyStroke.KeyCode - awt::Key::A ) ) ); - else - { - sal_Char c = '\0'; - - switch( rKeyStroke.KeyCode ) - { - case awt::Key::TAB: c = '\t'; break; - case awt::Key::SPACE: c = ' '; break; - case awt::Key::ADD: c = '+'; break; - case awt::Key::SUBTRACT: c = '-'; break; - case awt::Key::MULTIPLY: c = '*'; break; - case awt::Key::DIVIDE: c = '/'; break; - case awt::Key::POINT: c = '.'; break; - case awt::Key::COMMA: c = ','; break; - case awt::Key::LESS: c = '<'; break; - case awt::Key::GREATER: c = '>'; break; - case awt::Key::EQUAL: c = '='; break; - case 0: - break; - default: - g_warning( "Unmapped KeyCode: %d", rKeyStroke.KeyCode ); - break; - } - - if( c != '\0' ) - rBuffer.append( c ); - else - { - // The KeyCode approach did not work, probably a non ascii character - // let's hope that there is a character given in KeyChar. - rBuffer.append( OUStringToGChar( OUString( rKeyStroke.KeyChar ) ) ); - } - } - } -} - -static const gchar * -action_wrapper_get_keybinding (AtkAction *action, - gint i) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleAction> pAction - = getAction( action ); - if( pAction.is() ) - { - uno::Reference< accessibility::XAccessibleKeyBinding > xBinding( pAction->getAccessibleActionKeyBinding( i )); - - if( xBinding.is() ) - { - OStringBuffer aRet; - - sal_Int32 nmax = std::min( xBinding->getAccessibleKeyBindingCount(), sal_Int32(3) ); - for( sal_Int32 n = 0; n < nmax; n++ ) - { - appendKeyStrokes( aRet, xBinding->getAccessibleKeyBinding( n ) ); - - if( n < 2 ) - aRet.append( ';' ); - } - - // !! FIXME !! remember keystroke in wrapper object ? - return getAsConst( aRet.makeStringAndClear() ); - } - } - } - catch(const uno::Exception&) { - g_warning( "Exception in get_keybinding()" ); - } - - return ""; -} - -static gboolean -action_wrapper_set_description (AtkAction *, gint, const gchar *) -{ - return FALSE; -} - -} // extern "C" - -void -actionIfaceInit (AtkActionIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->do_action = action_wrapper_do_action; - iface->get_n_actions = action_wrapper_get_n_actions; - iface->get_description = action_wrapper_get_description; - iface->get_keybinding = action_wrapper_get_keybinding; - iface->get_name = action_wrapper_get_name; - iface->get_localized_name = action_wrapper_get_localized_name; - iface->set_description = action_wrapper_set_description; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkbridge.cxx b/vcl/unx/gtk/a11y/atkbridge.cxx deleted file mode 100644 index a74f1a91885f..000000000000 --- a/vcl/unx/gtk/a11y/atkbridge.cxx +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <unx/gtk/atkbridge.hxx> -#include <unx/gtk/gtkframe.hxx> - -#include "atkfactory.hxx" -#include "atkutil.hxx" -#include "atkwindow.hxx" - -bool InitAtkBridge() -{ -#if GTK_CHECK_VERSION(3,0,0) - ooo_atk_util_ensure_event_listener(); -#else - const char* pVersion = atk_get_toolkit_version(); - if( ! pVersion ) - return false; - - unsigned int major, minor, micro; - - /* check gail minimum version requirements */ - if( sscanf( pVersion, "%u.%u.%u", &major, &minor, µ) < 3 ) - { - // g_warning( "unable to parse gail version number" ); - return false; - } - - if( ( (major << 16) | (minor << 8) | micro ) < ( (1 << 16) | 8 << 8 | 6 ) ) - { - g_warning( "libgail >= 1.8.6 required for accessibility support" ); - return false; - } - - /* Initialize the AtkUtilityWrapper class */ - g_type_class_unref( g_type_class_ref( ooo_atk_util_get_type() ) ); - - /* Initialize the GailWindow wrapper class */ - g_type_class_unref( g_type_class_ref( ooo_window_wrapper_get_type() ) ); - - /* Register AtkObject wrapper factory */ - AtkRegistry * registry = atk_get_default_registry(); - if( registry ) - atk_registry_set_factory_type( registry, OOO_TYPE_FIXED, wrapper_factory_get_type() ); -#endif - return true; -} - -void DeInitAtkBridge() -{ -#if !GTK_CHECK_VERSION(3,0,0) - restore_gail_window_vtable(); -#endif -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkcomponent.cxx b/vcl/unx/gtk/a11y/atkcomponent.cxx deleted file mode 100644 index da5a48eca1f2..000000000000 --- a/vcl/unx/gtk/a11y/atkcomponent.cxx +++ /dev/null @@ -1,387 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" -#include <com/sun/star/accessibility/XAccessibleComponent.hpp> -#include <gtk/gtk.h> - -using namespace ::com::sun::star; - -static AtkObjectWrapper* getObjectWrapper(AtkComponent *pComponent) -{ - AtkObjectWrapper *pWrap = nullptr; - if (ATK_IS_OBJECT_WRAPPER(pComponent)) - pWrap = ATK_OBJECT_WRAPPER(pComponent); - else if (GTK_IS_DRAWING_AREA(pComponent)) //when using a GtkDrawingArea as a custom widget in welded gtk3 - { - GtkWidget* pDrawingArea = GTK_WIDGET(pComponent); - AtkObject* pAtkObject = gtk_widget_get_accessible(pDrawingArea); - pWrap = ATK_IS_OBJECT_WRAPPER(pAtkObject) ? ATK_OBJECT_WRAPPER(pAtkObject) : nullptr; - } - return pWrap; -} - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleComponent> - getComponent(AtkObjectWrapper *pWrap) -{ - if (pWrap) - { - if (!pWrap->mpComponent.is()) - pWrap->mpComponent.set(pWrap->mpContext, css::uno::UNO_QUERY); - return pWrap->mpComponent; - } - - return css::uno::Reference<css::accessibility::XAccessibleComponent>(); -} - -/*****************************************************************************/ - -static awt::Point -translatePoint( css::uno::Reference<accessibility::XAccessibleComponent> const & pComponent, - gint x, gint y, AtkCoordType t) -{ - awt::Point aOrigin( 0, 0 ); - if( t == ATK_XY_SCREEN ) - aOrigin = pComponent->getLocationOnScreen(); - return awt::Point( x - aOrigin.X, y - aOrigin.Y ); -} - -/*****************************************************************************/ - -extern "C" { - -static gboolean -component_wrapper_grab_focus (AtkComponent *component) -{ - AtkObjectWrapper* obj = getObjectWrapper(component); - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj && obj->mpOrig) - return atk_component_grab_focus(ATK_COMPONENT(obj->mpOrig)); - - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent - = getComponent(obj); - if( pComponent.is() ) - { - pComponent->grabFocus(); - return TRUE; - } - } - catch( const uno::Exception & ) - { - g_warning( "Exception in grabFocus()" ); - } - - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -component_wrapper_contains (AtkComponent *component, - gint x, - gint y, - AtkCoordType coord_type) -{ - AtkObjectWrapper* obj = getObjectWrapper(component); - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj && obj->mpOrig) - return atk_component_contains(ATK_COMPONENT(obj->mpOrig), x, y, coord_type); - - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent - = getComponent(obj); - if( pComponent.is() ) - return pComponent->containsPoint( translatePoint( pComponent, x, y, coord_type ) ); - } - catch( const uno::Exception & ) - { - g_warning( "Exception in containsPoint()" ); - } - - return FALSE; -} - -/*****************************************************************************/ - -static AtkObject * -component_wrapper_ref_accessible_at_point (AtkComponent *component, - gint x, - gint y, - AtkCoordType coord_type) -{ - AtkObjectWrapper* obj = getObjectWrapper(component); - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj && obj->mpOrig) - return atk_component_ref_accessible_at_point(ATK_COMPONENT(obj->mpOrig), x, y, coord_type); - - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent - = getComponent(obj); - - if( pComponent.is() ) - { - uno::Reference< accessibility::XAccessible > xAccessible = pComponent->getAccessibleAtPoint( - translatePoint( pComponent, x, y, coord_type ) ); - return atk_object_wrapper_ref( xAccessible ); - } - } - catch( const uno::Exception & ) - { - g_warning( "Exception in getAccessibleAtPoint()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static void -component_wrapper_get_position (AtkComponent *component, - gint *x, - gint *y, - AtkCoordType coord_type) -{ - AtkObjectWrapper* obj = getObjectWrapper(component); - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj && obj->mpOrig) - { - atk_component_get_extents(ATK_COMPONENT(obj->mpOrig), x, y, nullptr, nullptr, coord_type); - return; - } - - *x = *y = -1; - - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent - = getComponent(obj); - if( pComponent.is() ) - { - awt::Point aPos; - - if( coord_type == ATK_XY_SCREEN ) - aPos = pComponent->getLocationOnScreen(); - else - aPos = pComponent->getLocation(); - - *x = aPos.X; - *y = aPos.Y; - } - } - catch( const uno::Exception & ) - { - g_warning( "Exception in getLocation[OnScreen]()" ); - } -} - -/*****************************************************************************/ - -static void -component_wrapper_get_size (AtkComponent *component, - gint *width, - gint *height) -{ - AtkObjectWrapper* obj = getObjectWrapper(component); - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj && obj->mpOrig) - { - atk_component_get_extents(ATK_COMPONENT(obj->mpOrig), nullptr, nullptr, width, height, ATK_XY_WINDOW); - return; - } - - *width = *height = -1; - - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent - = getComponent(obj); - if( pComponent.is() ) - { - awt::Size aSize = pComponent->getSize(); - *width = aSize.Width; - *height = aSize.Height; - } - } - catch( const uno::Exception & ) - { - g_warning( "Exception in getSize()" ); - } -} - -/*****************************************************************************/ - -static void -component_wrapper_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type) -{ - component_wrapper_get_position( component, x, y, coord_type ); - component_wrapper_get_size( component, width, height ); -} - -/*****************************************************************************/ - -static gboolean -component_wrapper_set_extents (AtkComponent *, gint, gint, gint, gint, AtkCoordType) -{ - g_warning( "AtkComponent::set_extents unimplementable" ); - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -component_wrapper_set_position (AtkComponent *, gint, gint, AtkCoordType) -{ - g_warning( "AtkComponent::set_position unimplementable" ); - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -component_wrapper_set_size (AtkComponent *, gint, gint) -{ - g_warning( "AtkComponent::set_size unimplementable" ); - return FALSE; -} - -/*****************************************************************************/ - -static AtkLayer -component_wrapper_get_layer (AtkComponent *component) -{ - AtkRole role = atk_object_get_role( ATK_OBJECT( component ) ); - AtkLayer layer = ATK_LAYER_WIDGET; - - switch (role) - { - case ATK_ROLE_POPUP_MENU: - case ATK_ROLE_MENU_ITEM: - case ATK_ROLE_CHECK_MENU_ITEM: - case ATK_ROLE_SEPARATOR: - case ATK_ROLE_LIST_ITEM: - layer = ATK_LAYER_POPUP; - break; - case ATK_ROLE_MENU: - { - AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) ); - if( atk_object_get_role( parent ) != ATK_ROLE_MENU_BAR ) - layer = ATK_LAYER_POPUP; - } - break; - - case ATK_ROLE_LIST: - { - AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) ); - if( atk_object_get_role( parent ) == ATK_ROLE_COMBO_BOX ) - layer = ATK_LAYER_POPUP; - } - break; - - default: - ; - } - - return layer; -} - -/*****************************************************************************/ - -static gint -component_wrapper_get_mdi_zorder (AtkComponent *) -{ - // only needed for ATK_LAYER_MDI (not used) or ATK_LAYER_WINDOW (inherited from GAIL) - return G_MININT; -} - -/*****************************************************************************/ - -// This code is mostly stolen from libgail .. - -static guint -component_wrapper_add_focus_handler (AtkComponent *component, - AtkFocusHandler handler) -{ - GSignalMatchType match_type; - gulong ret; - guint signal_id; - - match_type = GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC); - signal_id = g_signal_lookup( "focus-event", ATK_TYPE_OBJECT ); - - ret = g_signal_handler_find( component, match_type, signal_id, 0, nullptr, - static_cast<gpointer>(&handler), nullptr); - if (!ret) - { - return g_signal_connect_closure_by_id (component, - signal_id, 0, - g_cclosure_new ( - G_CALLBACK (handler), nullptr, - nullptr), - FALSE); - } - else - { - return 0; - } -} - -/*****************************************************************************/ - -static void -component_wrapper_remove_focus_handler (AtkComponent *component, - guint handler_id) -{ - g_signal_handler_disconnect (component, handler_id); -} - -/*****************************************************************************/ - -} // extern "C" - -void -componentIfaceInit (AtkComponentIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->add_focus_handler = component_wrapper_add_focus_handler; - iface->contains = component_wrapper_contains; - iface->get_extents = component_wrapper_get_extents; - iface->get_layer = component_wrapper_get_layer; - iface->get_mdi_zorder = component_wrapper_get_mdi_zorder; - iface->get_position = component_wrapper_get_position; - iface->get_size = component_wrapper_get_size; - iface->grab_focus = component_wrapper_grab_focus; - iface->ref_accessible_at_point = component_wrapper_ref_accessible_at_point; - iface->remove_focus_handler = component_wrapper_remove_focus_handler; - iface->set_extents = component_wrapper_set_extents; - iface->set_position = component_wrapper_set_position; - iface->set_size = component_wrapper_set_size; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkeditabletext.cxx b/vcl/unx/gtk/a11y/atkeditabletext.cxx deleted file mode 100644 index 49d3eb9ccfc9..000000000000 --- a/vcl/unx/gtk/a11y/atkeditabletext.cxx +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" -#include "atktextattributes.hxx" - -#include <com/sun/star/accessibility/XAccessibleEditableText.hpp> -#include <com/sun/star/accessibility/TextSegment.hpp> - -#include <string.h> - -using namespace ::com::sun::star; - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleEditableText> - getEditableText( AtkEditableText *pEditableText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pEditableText ); - if( pWrap ) - { - if( !pWrap->mpEditableText.is() ) - { - pWrap->mpEditableText.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpEditableText; - } - - return css::uno::Reference<css::accessibility::XAccessibleEditableText>(); -} - -/*****************************************************************************/ - -extern "C" { - -static gboolean -editable_text_wrapper_set_run_attributes( AtkEditableText *text, - AtkAttributeSet *attribute_set, - gint nStartOffset, - gint nEndOffset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - { - uno::Sequence< beans::PropertyValue > aAttributeList; - - if( attribute_set_map_to_property_values( attribute_set, aAttributeList ) ) - return pEditableText->setAttributes(nStartOffset, nEndOffset, aAttributeList); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in setAttributes()" ); - } - - return FALSE; -} - -static void -editable_text_wrapper_set_text_contents( AtkEditableText *text, - const gchar *string ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - { - OUString aString ( string, strlen(string), RTL_TEXTENCODING_UTF8 ); - pEditableText->setText( aString ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in setText()" ); - } -} - -static void -editable_text_wrapper_insert_text( AtkEditableText *text, - const gchar *string, - gint length, - gint *pos ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - { - OUString aString ( string, length, RTL_TEXTENCODING_UTF8 ); - if( pEditableText->insertText( aString, *pos ) ) - *pos += length; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in insertText()" ); - } -} - -static void -editable_text_wrapper_cut_text( AtkEditableText *text, - gint start, - gint end ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - pEditableText->cutText( start, end ); - } - catch(const uno::Exception&) { - g_warning( "Exception in cutText()" ); - } -} - -static void -editable_text_wrapper_delete_text( AtkEditableText *text, - gint start, - gint end ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - pEditableText->deleteText( start, end ); - } - catch(const uno::Exception&) { - g_warning( "Exception in deleteText()" ); - } -} - -static void -editable_text_wrapper_paste_text( AtkEditableText *text, - gint pos ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - pEditableText->pasteText( pos ); - } - catch(const uno::Exception&) { - g_warning( "Exception in pasteText()" ); - } -} - -static void -editable_text_wrapper_copy_text( AtkEditableText *text, - gint start, - gint end ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleEditableText> - pEditableText = getEditableText( text ); - if( pEditableText.is() ) - pEditableText->copyText( start, end ); - } - catch(const uno::Exception&) { - g_warning( "Exception in copyText()" ); - } -} - -} // extern "C" - -void -editableTextIfaceInit (AtkEditableTextIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->set_text_contents = editable_text_wrapper_set_text_contents; - iface->insert_text = editable_text_wrapper_insert_text; - iface->copy_text = editable_text_wrapper_copy_text; - iface->cut_text = editable_text_wrapper_cut_text; - iface->delete_text = editable_text_wrapper_delete_text; - iface->paste_text = editable_text_wrapper_paste_text; - iface->set_run_attributes = editable_text_wrapper_set_run_attributes; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkfactory.cxx b/vcl/unx/gtk/a11y/atkfactory.cxx deleted file mode 100644 index 3a776b20dcc7..000000000000 --- a/vcl/unx/gtk/a11y/atkfactory.cxx +++ /dev/null @@ -1,195 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <unx/gtk/gtkframe.hxx> -#include <vcl/window.hxx> -#include "atkwrapper.hxx" -#include "atkfactory.hxx" -#include "atkregistry.hxx" - -using namespace ::com::sun::star; - -extern "C" { - -/* - * Instances of this dummy object class are returned whenever we have to - * create an AtkObject, but can't touch the OOo object anymore since it - * is already disposed. - */ - -static AtkStateSet * -noop_wrapper_ref_state_set( AtkObject * ) -{ - AtkStateSet *state_set = atk_state_set_new(); - atk_state_set_add_state( state_set, ATK_STATE_DEFUNCT ); - return state_set; -} - -static void -atk_noop_object_wrapper_class_init(AtkNoOpObjectClass *klass) -{ - AtkObjectClass *atk_class = ATK_OBJECT_CLASS( klass ); - atk_class->ref_state_set = noop_wrapper_ref_state_set; -} - -static GType -atk_noop_object_wrapper_get_type() -{ - static GType type = 0; - - if (!type) - { - static const GTypeInfo typeInfo = - { - sizeof (AtkNoOpObjectClass), - nullptr, - nullptr, - reinterpret_cast<GClassInitFunc>(atk_noop_object_wrapper_class_init), - nullptr, - nullptr, - sizeof (AtkObjectWrapper), - 0, - nullptr, - nullptr - } ; - - type = g_type_register_static (ATK_TYPE_OBJECT, "OOoAtkNoOpObj", &typeInfo, GTypeFlags(0)) ; - } - return type; -} - -static AtkObject* -atk_noop_object_wrapper_new() -{ - AtkObject *accessible; - - accessible = static_cast<AtkObject *>(g_object_new (atk_noop_object_wrapper_get_type(), nullptr)); - g_return_val_if_fail (accessible != nullptr, nullptr); - - accessible->role = ATK_ROLE_INVALID; - accessible->layer = ATK_LAYER_INVALID; - - return accessible; -} - -/* - * The wrapper factory - */ - -static GType -wrapper_factory_get_accessible_type() -{ - return atk_object_wrapper_get_type(); -} - -static AtkObject* -wrapper_factory_create_accessible( GObject *obj ) -{ -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget* pEventBox = gtk_widget_get_parent(GTK_WIDGET(obj)); - - // gail_container_real_remove_gtk tries to re-instantiate an accessible - // for a widget that is about to vanish .. - if (!pEventBox) - return atk_noop_object_wrapper_new(); - - GtkWidget* pTopLevelGrid = gtk_widget_get_parent(pEventBox); - if (!pTopLevelGrid) - return atk_noop_object_wrapper_new(); - - GtkWidget* pTopLevel = gtk_widget_get_parent(pTopLevelGrid); - if (!pTopLevel) - return atk_noop_object_wrapper_new(); -#else - GtkWidget* pTopLevel = gtk_widget_get_parent(GTK_WIDGET(obj)); - - // gail_container_real_remove_gtk tries to re-instantiate an accessible - // for a widget that is about to vanish .. - if (!pTopLevel) - return atk_noop_object_wrapper_new(); -#endif - - GtkSalFrame* pFrame = GtkSalFrame::getFromWindow(GTK_WINDOW(pTopLevel)); - g_return_val_if_fail( pFrame != nullptr, nullptr ); - - vcl::Window* pFrameWindow = pFrame->GetWindow(); - if( pFrameWindow ) - { - vcl::Window* pWindow = pFrameWindow; - - // skip accessible objects already exposed by the frame objects - if( WindowType::BORDERWINDOW == pWindow->GetType() ) - pWindow = pFrameWindow->GetAccessibleChildWindow(0); - - if( pWindow ) - { - uno::Reference< accessibility::XAccessible > xAccessible = pWindow->GetAccessible(); - if( xAccessible.is() ) - { - AtkObject *accessible = ooo_wrapper_registry_get( xAccessible ); - - if( accessible ) - g_object_ref( G_OBJECT(accessible) ); - else - accessible = atk_object_wrapper_new( xAccessible, gtk_widget_get_accessible(pTopLevel) ); - - return accessible; - } - } - } - - return nullptr; -} - -AtkObject* ooo_fixed_get_accessible(GtkWidget *obj) -{ - return wrapper_factory_create_accessible(G_OBJECT(obj)); -} - -static void -wrapper_factory_class_init( AtkObjectFactoryClass *klass ) -{ - klass->create_accessible = wrapper_factory_create_accessible; - klass->get_accessible_type = wrapper_factory_get_accessible_type; -} - -GType -wrapper_factory_get_type() -{ - static GType t = 0; - - if (!t) { - static const GTypeInfo tinfo = - { - sizeof (AtkObjectFactoryClass), - nullptr, nullptr, reinterpret_cast<GClassInitFunc>(wrapper_factory_class_init), - nullptr, nullptr, sizeof (AtkObjectFactory), 0, nullptr, nullptr - }; - - t = g_type_register_static ( - ATK_TYPE_OBJECT_FACTORY, "OOoAtkObjectWrapperFactory", - &tinfo, GTypeFlags(0)); - } - - return t; -} - -} // extern C - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkfactory.hxx b/vcl/unx/gtk/a11y/atkfactory.hxx deleted file mode 100644 index ac72b5897813..000000000000 --- a/vcl/unx/gtk/a11y/atkfactory.hxx +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_VCL_UNX_GTK_A11Y_ATKFACTORY_HXX -#define INCLUDED_VCL_UNX_GTK_A11Y_ATKFACTORY_HXX - -#include <atk/atk.h> - -extern "C" { - -GType wrapper_factory_get_type(); - -} // extern "C" - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkhypertext.cxx b/vcl/unx/gtk/a11y/atkhypertext.cxx deleted file mode 100644 index ab94126dfc51..000000000000 --- a/vcl/unx/gtk/a11y/atkhypertext.cxx +++ /dev/null @@ -1,273 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleHypertext.hpp> - -using namespace ::com::sun::star; - -// ---------------------- AtkHyperlink ---------------------- - -struct HyperLink { - AtkHyperlink const atk_hyper_link; - - uno::Reference< accessibility::XAccessibleHyperlink > xLink; -}; - -static uno::Reference< accessibility::XAccessibleHyperlink > const & - getHyperlink( AtkHyperlink *pHyperlink ) -{ - HyperLink *pLink = reinterpret_cast<HyperLink *>(pHyperlink); - return pLink->xLink; -} - -static GObjectClass *hyper_parent_class = nullptr; - -extern "C" { - -static void -hyper_link_finalize (GObject *obj) -{ - HyperLink *hl = reinterpret_cast<HyperLink *>(obj); - hl->xLink.clear(); - hyper_parent_class->finalize (obj); -} - -static gchar * -hyper_link_get_uri( AtkHyperlink *pLink, - gint i ) -{ - try { - uno::Any aAny = getHyperlink( pLink )->getAccessibleActionObject( i ); - OUString aUri = aAny.get< OUString > (); - return OUStringToGChar(aUri); - } - catch(const uno::Exception&) { - g_warning( "Exception in hyper_link_get_uri" ); - } - return nullptr; -} - -static AtkObject * -hyper_link_get_object( AtkHyperlink *, - gint ) -{ - g_warning( "FIXME: hyper_link_get_object unimplemented" ); - return nullptr; -} -static gint -hyper_link_get_end_index( AtkHyperlink *pLink ) -{ - try { - return getHyperlink( pLink )->getEndIndex(); - } - catch(const uno::Exception&) { - } - return -1; -} -static gint -hyper_link_get_start_index( AtkHyperlink *pLink ) -{ - try { - return getHyperlink( pLink )->getStartIndex(); - } - catch(const uno::Exception&) { - } - return -1; -} -static gboolean -hyper_link_is_valid( AtkHyperlink *pLink ) -{ - try { - return getHyperlink( pLink )->isValid(); - } - catch(const uno::Exception&) { - } - return FALSE; -} -static gint -hyper_link_get_n_anchors( AtkHyperlink *pLink ) -{ - try { - return getHyperlink( pLink )->getAccessibleActionCount(); - } - catch(const uno::Exception&) { - } - return 0; -} - -static guint -hyper_link_link_state( AtkHyperlink * ) -{ - g_warning( "FIXME: hyper_link_link_state unimplemented" ); - return 0; -} -static gboolean -hyper_link_is_selected_link( AtkHyperlink * ) -{ - g_warning( "FIXME: hyper_link_is_selected_link unimplemented" ); - return FALSE; -} - -static void -hyper_link_class_init (AtkHyperlinkClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->finalize = hyper_link_finalize; - - hyper_parent_class = static_cast<GObjectClass *>(g_type_class_peek_parent (klass)); - - klass->get_uri = hyper_link_get_uri; - klass->get_object = hyper_link_get_object; - klass->get_end_index = hyper_link_get_end_index; - klass->get_start_index = hyper_link_get_start_index; - klass->is_valid = hyper_link_is_valid; - klass->get_n_anchors = hyper_link_get_n_anchors; - klass->link_state = hyper_link_link_state; - klass->is_selected_link = hyper_link_is_selected_link; -} - -static GType -hyper_link_get_type() -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo tinfo = { - sizeof (AtkHyperlinkClass), - nullptr, /* base init */ - nullptr, /* base finalize */ - reinterpret_cast<GClassInitFunc>(hyper_link_class_init), - nullptr, /* class finalize */ - nullptr, /* class data */ - sizeof (HyperLink), /* instance size */ - 0, /* nb preallocs */ - nullptr, /* instance init */ - nullptr /* value table */ - }; - - static const GInterfaceInfo atk_action_info = { - reinterpret_cast<GInterfaceInitFunc>(actionIfaceInit), - nullptr, - nullptr - }; - - type = g_type_register_static (ATK_TYPE_HYPERLINK, - "OOoAtkObjHyperLink", &tinfo, - GTypeFlags(0)); - g_type_add_interface_static (type, ATK_TYPE_ACTION, - &atk_action_info); - } - - return type; -} - -// ---------------------- AtkHyperText ---------------------- - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleHypertext> - getHypertext( AtkHypertext *pHypertext ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pHypertext ); - if( pWrap ) - { - if( !pWrap->mpHypertext.is() ) - { - pWrap->mpHypertext.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpHypertext; - } - - return css::uno::Reference<css::accessibility::XAccessibleHypertext>(); -} - -static AtkHyperlink * -hypertext_get_link( AtkHypertext *hypertext, - gint link_index) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleHypertext> pHypertext - = getHypertext( hypertext ); - if( pHypertext.is() ) - { - HyperLink *pLink = static_cast<HyperLink *>(g_object_new( hyper_link_get_type(), nullptr )); - pLink->xLink = pHypertext->getHyperLink( link_index ); - if( !pLink->xLink.is() ) { - g_object_unref( G_OBJECT( pLink ) ); - pLink = nullptr; - } - return ATK_HYPERLINK( pLink ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getHyperLink()" ); - } - - return nullptr; -} - -static gint -hypertext_get_n_links( AtkHypertext *hypertext ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleHypertext> pHypertext - = getHypertext( hypertext ); - if( pHypertext.is() ) - return pHypertext->getHyperLinkCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getHyperLinkCount()" ); - } - - return 0; -} - -static gint -hypertext_get_link_index( AtkHypertext *hypertext, - gint index) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleHypertext> pHypertext - = getHypertext( hypertext ); - if( pHypertext.is() ) - return pHypertext->getHyperLinkIndex( index ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getHyperLinkIndex()" ); - } - - return 0; -} - -} // extern "C" - -void -hypertextIfaceInit (AtkHypertextIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->get_link = hypertext_get_link; - iface->get_n_links = hypertext_get_n_links; - iface->get_link_index = hypertext_get_link_index; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkimage.cxx b/vcl/unx/gtk/a11y/atkimage.cxx deleted file mode 100644 index acd43f467690..000000000000 --- a/vcl/unx/gtk/a11y/atkimage.cxx +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleImage.hpp> - -using namespace ::com::sun::star; - -// FIXME -static const gchar * -getAsConst( const OUString& rString ) -{ - static const int nMax = 10; - static OString aUgly[nMax]; - static int nIdx = 0; - nIdx = (nIdx + 1) % nMax; - aUgly[nIdx] = OUStringToOString( rString, RTL_TEXTENCODING_UTF8 ); - return aUgly[ nIdx ].getStr(); -} - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleImage> - getImage( AtkImage *pImage ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pImage ); - if( pWrap ) - { - if( !pWrap->mpImage.is() ) - { - pWrap->mpImage.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpImage; - } - - return css::uno::Reference<css::accessibility::XAccessibleImage>(); -} - -extern "C" { - -static const gchar * -image_get_image_description( AtkImage *image ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleImage> pImage - = getImage( image ); - if( pImage.is() ) - return getAsConst( pImage->getAccessibleImageDescription() ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleImageDescription()" ); - } - - return nullptr; -} - -static void -image_get_image_position( AtkImage *image, - gint *x, - gint *y, - AtkCoordType coord_type ) -{ - *x = *y = -1; - if( ATK_IS_COMPONENT( image ) ) - { - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_component_get_position( ATK_COMPONENT( image ), x, y, coord_type ); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - else - g_warning( "FIXME: no image position information" ); -} - -static void -image_get_image_size( AtkImage *image, - gint *width, - gint *height ) -{ - *width = *height = -1; - try { - css::uno::Reference<css::accessibility::XAccessibleImage> pImage - = getImage( image ); - if( pImage.is() ) - { - *width = pImage->getAccessibleImageWidth(); - *height = pImage->getAccessibleImageHeight(); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleImageHeight() or Width" ); - } -} - -static gboolean -image_set_image_description( AtkImage *, const gchar * ) -{ - g_warning ("FIXME: no set image description"); - return FALSE; -} - -} // extern "C" - -void -imageIfaceInit (AtkImageIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->set_image_description = image_set_image_description; - iface->get_image_description = image_get_image_description; - iface->get_image_position = image_get_image_position; - iface->get_image_size = image_get_image_size; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atklistener.cxx b/vcl/unx/gtk/a11y/atklistener.cxx deleted file mode 100644 index c30bc638bced..000000000000 --- a/vcl/unx/gtk/a11y/atklistener.cxx +++ /dev/null @@ -1,739 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifdef AIX -#define _LINUX_SOURCE_COMPAT -#include <sys/timer.h> -#undef _LINUX_SOURCE_COMPAT -#endif - -#include <com/sun/star/accessibility/TextSegment.hpp> -#include <com/sun/star/accessibility/AccessibleEventId.hpp> -#include <com/sun/star/accessibility/AccessibleStateType.hpp> -#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> -#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> -#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> -#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> - -#include "atklistener.hxx" -#include "atkwrapper.hxx" -#include <vcl/svapp.hxx> - -#include <rtl/ref.hxx> -#include <sal/log.hxx> - -#define DEBUG_ATK_LISTENER 0 - -#if DEBUG_ATK_LISTENER -#include <iostream> -#include <sstream> -#endif - -using namespace com::sun::star; - -AtkListener::AtkListener( AtkObjectWrapper* pWrapper ) : mpWrapper( pWrapper ) -{ - if( mpWrapper ) - { - g_object_ref( mpWrapper ); - updateChildList( mpWrapper->mpContext ); - } -} - -AtkListener::~AtkListener() -{ - if( mpWrapper ) - g_object_unref( mpWrapper ); -} - -/*****************************************************************************/ - -static AtkStateType mapState( const uno::Any &rAny ) -{ - sal_Int16 nState = accessibility::AccessibleStateType::INVALID; - rAny >>= nState; - return mapAtkState( nState ); -} - -/*****************************************************************************/ - -extern "C" { - // rhbz#1001768 - down to horrific problems releasing the solar mutex - // while destroying a Window - which occurs inside these notifications. - static gboolean - idle_defunc_state_change( AtkObject *atk_obj ) - { - SolarMutexGuard aGuard; - - // This is an equivalent to a state change to DEFUNC(T). - atk_object_notify_state_change( atk_obj, ATK_STATE_DEFUNCT, TRUE ); - if( atk_get_focus_object() == atk_obj ) - { - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_focus_tracker_notify( nullptr ); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - g_object_unref( G_OBJECT( atk_obj ) ); - return false; - } -} - -// XEventListener implementation -void AtkListener::disposing( const lang::EventObject& ) -{ - if( mpWrapper ) - { - AtkObject *atk_obj = ATK_OBJECT( mpWrapper ); - - // Release all interface references to avoid shutdown problems with - // global mutex - atk_object_wrapper_dispose( mpWrapper ); - - g_idle_add( reinterpret_cast<GSourceFunc>(idle_defunc_state_change), - g_object_ref( G_OBJECT( atk_obj ) ) ); - - // Release the wrapper object so that it can vanish .. - g_object_unref( mpWrapper ); - mpWrapper = nullptr; - } -} - -/*****************************************************************************/ - -static AtkObject *getObjFromAny( const uno::Any &rAny ) -{ - uno::Reference< accessibility::XAccessible > xAccessible; - rAny >>= xAccessible; - return xAccessible.is() ? atk_object_wrapper_ref( xAccessible ) : nullptr; -} - -/*****************************************************************************/ - -// Updates the child list held to provide the old IndexInParent on children_changed::remove -void AtkListener::updateChildList( - css::uno::Reference<css::accessibility::XAccessibleContext> const & - pContext) -{ - m_aChildList.clear(); - - uno::Reference< accessibility::XAccessibleStateSet > xStateSet = pContext->getAccessibleStateSet(); - if( xStateSet.is() - && !xStateSet->contains(accessibility::AccessibleStateType::DEFUNC) - && !xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS) ) - { - sal_Int32 nChildren = pContext->getAccessibleChildCount(); - m_aChildList.resize(nChildren); - for(sal_Int32 n = 0; n < nChildren; n++) - { - try - { - m_aChildList[n] = pContext->getAccessibleChild(n); - } - catch (lang::IndexOutOfBoundsException const&) - { - sal_Int32 nChildren2 = pContext->getAccessibleChildCount(); - assert(nChildren2 <= n && "consistency?"); - m_aChildList.resize(std::min(nChildren2, n)); - break; - } - } - } -} - -/*****************************************************************************/ - -void AtkListener::handleChildAdded( - const uno::Reference< accessibility::XAccessibleContext >& rxParent, - const uno::Reference< accessibility::XAccessible>& rxAccessible) -{ - AtkObject * pChild = rxAccessible.is() ? atk_object_wrapper_ref( rxAccessible ) : nullptr; - - if( pChild ) - { - updateChildList(rxParent); - - atk_object_wrapper_add_child( mpWrapper, pChild, - atk_object_get_index_in_parent( pChild )); - - g_object_unref( pChild ); - } -} - -/*****************************************************************************/ - -void AtkListener::handleChildRemoved( - const uno::Reference< accessibility::XAccessibleContext >& rxParent, - const uno::Reference< accessibility::XAccessible>& rxChild) -{ - sal_Int32 nIndex = -1; - - // Locate the child in the children list - size_t n, nmax = m_aChildList.size(); - for( n = 0; n < nmax; ++n ) - { - if( rxChild == m_aChildList[n] ) - { - nIndex = n; - break; - } - } - - // FIXME: two problems here: - // a) we get child-removed events for objects that are no real children - // in the accessibility hierarchy or have been removed before due to - // some child removing batch. - // b) spi_atk_bridge_signal_listener ignores the given parameters - // for children_changed events and always asks the parent for the - // 0. child, which breaks somehow on vanishing list boxes. - // Ignoring "remove" events for objects not in the m_aChildList - // for now. - if( nIndex >= 0 ) - { - uno::Reference<accessibility::XAccessibleEventBroadcaster> xBroadcaster( - rxChild->getAccessibleContext(), uno::UNO_QUERY); - - if (xBroadcaster.is()) - { - uno::Reference<accessibility::XAccessibleEventListener> xListener(this); - xBroadcaster->removeAccessibleEventListener(xListener); - } - - updateChildList(rxParent); - - AtkObject * pChild = atk_object_wrapper_ref( rxChild, false ); - if( pChild ) - { - atk_object_wrapper_remove_child( mpWrapper, pChild, nIndex ); - g_object_unref( pChild ); - } - } -} - -/*****************************************************************************/ - -void AtkListener::handleInvalidateChildren( - const uno::Reference< accessibility::XAccessibleContext >& rxParent) -{ - // Send notifications for all previous children - size_t n = m_aChildList.size(); - while( n-- > 0 ) - { - if( m_aChildList[n].is() ) - { - AtkObject * pChild = atk_object_wrapper_ref( m_aChildList[n], false ); - if( pChild ) - { - atk_object_wrapper_remove_child( mpWrapper, pChild, n ); - g_object_unref( pChild ); - } - } - } - - updateChildList(rxParent); - - // Send notifications for all new children - size_t nmax = m_aChildList.size(); - for( n = 0; n < nmax; ++n ) - { - if( m_aChildList[n].is() ) - { - AtkObject * pChild = atk_object_wrapper_ref( m_aChildList[n] ); - - if( pChild ) - { - atk_object_wrapper_add_child( mpWrapper, pChild, n ); - g_object_unref( pChild ); - } - } - } -} - -/*****************************************************************************/ - -static uno::Reference< accessibility::XAccessibleContext > -getAccessibleContextFromSource( const uno::Reference< uno::XInterface >& rxSource ) -{ - uno::Reference< accessibility::XAccessibleContext > xContext(rxSource, uno::UNO_QUERY); - if( ! xContext.is() ) - { - g_warning( "ERROR: Event source does not implement XAccessibleContext" ); - - // Second try - query for XAccessible, which should give us access to - // XAccessibleContext. - uno::Reference< accessibility::XAccessible > xAccessible(rxSource, uno::UNO_QUERY); - if( xAccessible.is() ) - xContext = xAccessible->getAccessibleContext(); - } - - return xContext; -} - -#if DEBUG_ATK_LISTENER - -namespace { - -void printNotifyEvent( const accessibility::AccessibleEventObject& rEvent ) -{ - static std::vector<const char*> aLabels = { - 0, - "NAME_CHANGED", // 01 - "DESCRIPTION_CHANGED", // 02 - "ACTION_CHANGED", // 03 - "STATE_CHANGED", // 04 - "ACTIVE_DESCENDANT_CHANGED", // 05 - "BOUNDRECT_CHANGED", // 06 - "CHILD", // 07 - "INVALIDATE_ALL_CHILDREN", // 08 - "SELECTION_CHANGED", // 09 - "VISIBLE_DATA_CHANGED", // 10 - "VALUE_CHANGED", // 11 - "CONTENT_FLOWS_FROM_RELATION_CHANGED", // 12 - "CONTENT_FLOWS_TO_RELATION_CHANGED", // 13 - "CONTROLLED_BY_RELATION_CHANGED", // 14 - "CONTROLLER_FOR_RELATION_CHANGED", // 15 - "LABEL_FOR_RELATION_CHANGED", // 16 - "LABELED_BY_RELATION_CHANGED", // 17 - "MEMBER_OF_RELATION_CHANGED", // 18 - "SUB_WINDOW_OF_RELATION_CHANGED", // 19 - "CARET_CHANGED", // 20 - "TEXT_SELECTION_CHANGED", // 21 - "TEXT_CHANGED", // 22 - "TEXT_ATTRIBUTE_CHANGED", // 23 - "HYPERTEXT_CHANGED", // 24 - "TABLE_CAPTION_CHANGED", // 25 - "TABLE_COLUMN_DESCRIPTION_CHANGED", // 26 - "TABLE_COLUMN_HEADER_CHANGED", // 27 - "TABLE_MODEL_CHANGED", // 28 - "TABLE_ROW_DESCRIPTION_CHANGED", // 29 - "TABLE_ROW_HEADER_CHANGED", // 30 - "TABLE_SUMMARY_CHANGED", // 31 - "LISTBOX_ENTRY_EXPANDED", // 32 - "LISTBOX_ENTRY_COLLAPSED", // 33 - "ACTIVE_DESCENDANT_CHANGED_NOFOCUS", // 34 - "SELECTION_CHANGED_ADD", // 35 - "SELECTION_CHANGED_REMOVE", // 36 - "SELECTION_CHANGED_WITHIN", // 37 - "PAGE_CHANGED", // 38 - "SECTION_CHANGED", // 39 - "COLUMN_CHANGED", // 40 - "ROLE_CHANGED", // 41 - }; - - static std::vector<const char*> aStates = { - "INVALID", // 00 - "ACTIVE", // 01 - "ARMED", // 02 - "BUSY", // 03 - "CHECKED", // 04 - "DEFUNC", // 05 - "EDITABLE", // 06 - "ENABLED", // 07 - "EXPANDABLE", // 08 - "EXPANDED", // 09 - "FOCUSABLE", // 10 - "FOCUSED", // 11 - "HORIZONTAL", // 12 - "ICONIFIED", // 13 - "INDETERMINATE", // 14 - "MANAGES_DESCENDANTS", // 15 - "MODAL", // 16 - "MULTI_LINE", // 17 - "MULTI_SELECTABLE", // 18 - "OPAQUE", // 19 - "PRESSED", // 20 - "RESIZABLE", // 21 - "SELECTABLE", // 22 - "SELECTED", // 23 - "SENSITIVE", // 24 - "SHOWING", // 25 - "SINGLE_LINE", // 26 - "STALE", // 27 - "TRANSIENT", // 28 - "VERTICAL", // 29 - "VISIBLE", // 30 - "MOVEABLE", // 31 - "DEFAULT", // 32 - "OFFSCREEN", // 33 - "COLLAPSE", // 34 - }; - - auto getOrUnknown = [](const std::vector<const char*>& rCont, size_t nIndex) -> std::string - { - return (nIndex < rCont.size()) ? rCont[nIndex] : "<unknown>"; - }; - - std::ostringstream os; - os << "--" << std::endl; - os << "* event = " << getOrUnknown(aLabels, rEvent.EventId) << std::endl; - - switch (rEvent.EventId) - { - case accessibility::AccessibleEventId::STATE_CHANGED: - { - sal_Int16 nState; - if (rEvent.OldValue >>= nState) - os << " * old state = " << getOrUnknown(aStates, nState); - if (rEvent.NewValue >>= nState) - os << " * new state = " << getOrUnknown(aStates, nState); - - os << std::endl; - break; - } - default: - ; - } - - std::cout << os.str(); -} - -} - -#endif - -void AtkListener::notifyEvent( const accessibility::AccessibleEventObject& aEvent ) -{ - if( !mpWrapper ) - return; - - AtkObject *atk_obj = ATK_OBJECT( mpWrapper ); - - switch( aEvent.EventId ) - { - // AtkObject signals: - // Hierarchy signals - case accessibility::AccessibleEventId::CHILD: - { - uno::Reference< accessibility::XAccessibleContext > xParent; - uno::Reference< accessibility::XAccessible > xChild; - - xParent = getAccessibleContextFromSource(aEvent.Source); - g_return_if_fail( xParent.is() ); - - if( aEvent.OldValue >>= xChild ) - handleChildRemoved(xParent, xChild); - - if( aEvent.NewValue >>= xChild ) - handleChildAdded(xParent, xChild); - break; - } - - case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN: - { - uno::Reference< accessibility::XAccessibleContext > xParent = getAccessibleContextFromSource(aEvent.Source); - g_return_if_fail( xParent.is() ); - - handleInvalidateChildren(xParent); - break; - } - - case accessibility::AccessibleEventId::NAME_CHANGED: - { - OUString aName; - if( aEvent.NewValue >>= aName ) - { - atk_object_set_name(atk_obj, - OUStringToOString(aName, RTL_TEXTENCODING_UTF8).getStr()); - } - break; - } - - case accessibility::AccessibleEventId::DESCRIPTION_CHANGED: - { - OUString aDescription; - if( aEvent.NewValue >>= aDescription ) - { - atk_object_set_description(atk_obj, - OUStringToOString(aDescription, RTL_TEXTENCODING_UTF8).getStr()); - } - break; - } - - case accessibility::AccessibleEventId::STATE_CHANGED: - { - AtkStateType eOldState = mapState( aEvent.OldValue ); - AtkStateType eNewState = mapState( aEvent.NewValue ); - - gboolean bState = eNewState != ATK_STATE_INVALID; - AtkStateType eRealState = bState ? eNewState : eOldState; - - atk_object_notify_state_change( atk_obj, eRealState, bState ); - break; - } - - case accessibility::AccessibleEventId::BOUNDRECT_CHANGED: - -#ifdef HAS_ATKRECTANGLE - if( ATK_IS_COMPONENT( atk_obj ) ) - { - AtkRectangle rect; - - atk_component_get_extents( ATK_COMPONENT( atk_obj ), - &rect.x, - &rect.y, - &rect.width, - &rect.height, - ATK_XY_SCREEN ); - - g_signal_emit_by_name( atk_obj, "bounds_changed", &rect ); - } - else - g_warning( "bounds_changed event for object not implementing AtkComponent\n"); -#endif - - break; - - case accessibility::AccessibleEventId::VISIBLE_DATA_CHANGED: - g_signal_emit_by_name( atk_obj, "visible-data-changed" ); - break; - - case accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED: - { - AtkObject *pChild = getObjFromAny( aEvent.NewValue ); - if( pChild ) - { - g_signal_emit_by_name( atk_obj, "active-descendant-changed", pChild ); - g_object_unref( pChild ); - } - break; - } - - //ACTIVE_DESCENDANT_CHANGED_NOFOCUS (sic) appears to have been added - //as a workaround or an aid for the ia2 winaccessibility implementation - //so ignore it silently without warning here - case accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS: - break; - - // #i92103# - case accessibility::AccessibleEventId::LISTBOX_ENTRY_EXPANDED: - { - AtkObject *pChild = getObjFromAny( aEvent.NewValue ); - if( pChild ) - { - atk_object_notify_state_change( pChild, ATK_STATE_EXPANDED, true ); - g_object_unref( pChild ); - } - break; - } - - case accessibility::AccessibleEventId::LISTBOX_ENTRY_COLLAPSED: - { - AtkObject *pChild = getObjFromAny( aEvent.NewValue ); - if( pChild ) - { - atk_object_notify_state_change( pChild, ATK_STATE_EXPANDED, false ); - g_object_unref( pChild ); - } - break; - } - - // AtkAction signals ... - case accessibility::AccessibleEventId::ACTION_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-actions"); - break; - - // AtkText - case accessibility::AccessibleEventId::CARET_CHANGED: - { - sal_Int32 nPos=0; - aEvent.NewValue >>= nPos; - g_signal_emit_by_name( atk_obj, "text_caret_moved", nPos ); - break; - } - case accessibility::AccessibleEventId::TEXT_CHANGED: - { - // TESTME: and remove this comment: - // cf. comphelper/source/misc/accessibletexthelper.cxx (implInitTextChangedEvent) - accessibility::TextSegment aDeletedText; - accessibility::TextSegment aInsertedText; - - // TODO: when GNOME starts to send "update" kind of events, change - // we need to re-think this implementation as well - if( aEvent.OldValue >>= aDeletedText ) - { - /* Remember the text segment here to be able to return removed text in get_text(). - * This is clearly a hack to be used until appropriate API exists in atk to pass - * the string value directly or we find a compelling reason to start caching the - * UTF-8 converted strings in the atk wrapper object. - */ - - g_object_set_data( G_OBJECT(atk_obj), "ooo::text_changed::delete", &aDeletedText); - - g_signal_emit_by_name( atk_obj, "text_changed::delete", - static_cast<gint>(aDeletedText.SegmentStart), - static_cast<gint>( aDeletedText.SegmentEnd - aDeletedText.SegmentStart ) ); - - g_object_steal_data( G_OBJECT(atk_obj), "ooo::text_changed::delete" ); - } - - if( aEvent.NewValue >>= aInsertedText ) - g_signal_emit_by_name( atk_obj, "text_changed::insert", - static_cast<gint>(aInsertedText.SegmentStart), - static_cast<gint>( aInsertedText.SegmentEnd - aInsertedText.SegmentStart ) ); - break; - } - - case accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED: - { - g_signal_emit_by_name( atk_obj, "text-selection-changed" ); - break; - } - - case accessibility::AccessibleEventId::TEXT_ATTRIBUTE_CHANGED: - g_signal_emit_by_name( atk_obj, "text-attributes-changed" ); - break; - - // AtkValue - case accessibility::AccessibleEventId::VALUE_CHANGED: - g_object_notify( G_OBJECT( atk_obj ), "accessible-value" ); - break; - - case accessibility::AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED: - case accessibility::AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED: - case accessibility::AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED: - case accessibility::AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED: - case accessibility::AccessibleEventId::LABEL_FOR_RELATION_CHANGED: - case accessibility::AccessibleEventId::LABELED_BY_RELATION_CHANGED: - case accessibility::AccessibleEventId::MEMBER_OF_RELATION_CHANGED: - case accessibility::AccessibleEventId::SUB_WINDOW_OF_RELATION_CHANGED: - // FIXME: ask Bill how Atk copes with this little lot ... - break; - - // AtkTable - case accessibility::AccessibleEventId::TABLE_MODEL_CHANGED: - { - accessibility::AccessibleTableModelChange aChange; - aEvent.NewValue >>= aChange; - - sal_Int32 nRowsChanged = aChange.LastRow - aChange.FirstRow + 1; - sal_Int32 nColumnsChanged = aChange.LastColumn - aChange.FirstColumn + 1; - - static const struct { - const char *row; - const char *col; - } aSignalNames[] = - { - { nullptr, nullptr }, // dummy - { "row_inserted", "column_inserted" }, // INSERT = 1 - { "row_deleted", "column_deleted" } // DELETE = 2 - }; - switch( aChange.Type ) - { - case accessibility::AccessibleTableModelChangeType::INSERT: - case accessibility::AccessibleTableModelChangeType::DELETE: - if( nRowsChanged > 0 ) - g_signal_emit_by_name( G_OBJECT( atk_obj ), - aSignalNames[aChange.Type].row, - aChange.FirstRow, nRowsChanged ); - if( nColumnsChanged > 0 ) - g_signal_emit_by_name( G_OBJECT( atk_obj ), - aSignalNames[aChange.Type].col, - aChange.FirstColumn, nColumnsChanged ); - break; - - case accessibility::AccessibleTableModelChangeType::UPDATE: - // This is not really a model change, is it ? - break; - default: - g_warning( "TESTME: unusual table model change %d\n", aChange.Type ); - break; - } - g_signal_emit_by_name( G_OBJECT( atk_obj ), "model-changed" ); - break; - } - - case accessibility::AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED: - { - accessibility::AccessibleTableModelChange aChange; - aEvent.NewValue >>= aChange; - - AtkPropertyValues values; - memset(&values, 0, sizeof(AtkPropertyValues)); - g_value_init (&values.new_value, G_TYPE_INT); - values.property_name = "accessible-table-column-header"; - - for (sal_Int32 nChangedColumn = aChange.FirstColumn; nChangedColumn <= aChange.LastColumn; ++nChangedColumn) - { - g_value_set_int (&values.new_value, nChangedColumn); - g_signal_emit_by_name(G_OBJECT(atk_obj), "property_change::accessible-table-column-header", &values, nullptr); - } - break; - } - - case accessibility::AccessibleEventId::TABLE_CAPTION_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-table-caption"); - break; - - case accessibility::AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-table-column-description"); - break; - - case accessibility::AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-table-row-description"); - break; - - case accessibility::AccessibleEventId::TABLE_ROW_HEADER_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-table-row-header"); - break; - - case accessibility::AccessibleEventId::TABLE_SUMMARY_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-table-summary"); - break; - - case accessibility::AccessibleEventId::SELECTION_CHANGED: - case accessibility::AccessibleEventId::SELECTION_CHANGED_ADD: - case accessibility::AccessibleEventId::SELECTION_CHANGED_REMOVE: - case accessibility::AccessibleEventId::SELECTION_CHANGED_WITHIN: - if (ATK_IS_SELECTION(atk_obj)) - g_signal_emit_by_name(G_OBJECT(atk_obj), "selection_changed"); - else - { - // e.g. tdf#122353, when such dialogs become native the problem will go away anyway - SAL_INFO("vcl.gtk", "selection change from obj which doesn't support XAccessibleSelection"); - } - break; - - case accessibility::AccessibleEventId::HYPERTEXT_CHANGED: - g_signal_emit_by_name( G_OBJECT( atk_obj ), "property_change::accessible-hypertext-offset"); - break; - - case accessibility::AccessibleEventId::ROLE_CHANGED: - { - uno::Reference< accessibility::XAccessibleContext > xContext = getAccessibleContextFromSource( aEvent.Source ); - atk_object_wrapper_set_role( mpWrapper, xContext->getAccessibleRole() ); - break; - } - - case accessibility::AccessibleEventId::PAGE_CHANGED: - { - /* // If we implemented AtkDocument then I imagine this is what this - // handler should look like - sal_Int32 nPos=0; - aEvent.NewValue >>= nPos; - g_signal_emit_by_name( G_OBJECT( atk_obj ), "page_changed", nPos ); - */ - break; - } - - default: - SAL_WARN("vcl.gtk", "Unknown event notification: " << aEvent.EventId); - break; - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atklistener.hxx b/vcl/unx/gtk/a11y/atklistener.hxx deleted file mode 100644 index 58798d4439fb..000000000000 --- a/vcl/unx/gtk/a11y/atklistener.hxx +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_VCL_UNX_GTK_A11Y_ATKLISTENER_HXX -#define INCLUDED_VCL_UNX_GTK_A11Y_ATKLISTENER_HXX - -#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> -#include <cppuhelper/implbase.hxx> - -#include <vector> - -#include "atkwrapper.hxx" - -class AtkListener : public ::cppu::WeakImplHelper< css::accessibility::XAccessibleEventListener > -{ -public: - explicit AtkListener(AtkObjectWrapper * pWrapper); - - // XEventListener - virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; - - // XAccessibleEventListener - virtual void SAL_CALL notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) override; - -private: - - AtkObjectWrapper *mpWrapper; - std::vector< css::uno::Reference< css::accessibility::XAccessible > > - m_aChildList; - - virtual ~AtkListener() override; - - // Updates the child list held to provide the old IndexInParent on children_changed::remove - void updateChildList( - css::uno::Reference<css::accessibility::XAccessibleContext> const & - pContext); - - // Process CHILD_EVENT notifications with a new child added - void handleChildAdded( - const css::uno::Reference< css::accessibility::XAccessibleContext >& rxParent, - const css::uno::Reference< css::accessibility::XAccessible>& rxChild); - - // Process CHILD_EVENT notifications with a child removed - void handleChildRemoved( - const css::uno::Reference< css::accessibility::XAccessibleContext >& rxParent, - const css::uno::Reference< css::accessibility::XAccessible>& rxChild); - - // Process INVALIDATE_ALL_CHILDREN notification - void handleInvalidateChildren( - const css::uno::Reference< css::accessibility::XAccessibleContext >& rxParent); -}; - -#endif // INCLUDED_VCL_UNX_GTK_A11Y_ATKLISTENER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkregistry.cxx b/vcl/unx/gtk/a11y/atkregistry.cxx deleted file mode 100644 index ff96378c41dc..000000000000 --- a/vcl/unx/gtk/a11y/atkregistry.cxx +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkregistry.hxx" - -using namespace ::com::sun::star::accessibility; -using namespace ::com::sun::star::uno; - -static GHashTable *uno_to_gobject = nullptr; - -/*****************************************************************************/ - -AtkObject * -ooo_wrapper_registry_get(const Reference< XAccessible >& rxAccessible) -{ - if( uno_to_gobject ) - { - gpointer cached = - g_hash_table_lookup(uno_to_gobject, static_cast<gpointer>(rxAccessible.get())); - - if( cached ) - return ATK_OBJECT( cached ); - } - - return nullptr; -} - -/*****************************************************************************/ - -void -ooo_wrapper_registry_add(const Reference< XAccessible >& rxAccessible, AtkObject *obj) -{ - if( !uno_to_gobject ) - uno_to_gobject = g_hash_table_new (nullptr, nullptr); - - g_hash_table_insert( uno_to_gobject, static_cast<gpointer>(rxAccessible.get()), obj ); -} - -/*****************************************************************************/ - -void -ooo_wrapper_registry_remove( - css::uno::Reference<css::accessibility::XAccessible> const & pAccessible) -{ - if( uno_to_gobject ) - g_hash_table_remove( - uno_to_gobject, static_cast<gpointer>(pAccessible.get()) ); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkregistry.hxx b/vcl/unx/gtk/a11y/atkregistry.hxx deleted file mode 100644 index b692290847d8..000000000000 --- a/vcl/unx/gtk/a11y/atkregistry.hxx +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_VCL_UNX_GTK_A11Y_ATKREGISTRY_HXX -#define INCLUDED_VCL_UNX_GTK_A11Y_ATKREGISTRY_HXX - -#include <com/sun/star/accessibility/XAccessible.hpp> -#include <atk/atk.h> - -AtkObject * ooo_wrapper_registry_get(const css::uno::Reference< css::accessibility::XAccessible >& rxAccessible); - -void ooo_wrapper_registry_add(const css::uno::Reference< css::accessibility::XAccessible >& rxAccessible, AtkObject *obj); - -void ooo_wrapper_registry_remove( - css::uno::Reference<css::accessibility::XAccessible> const & pAccessible); - -#endif // __ATK_REGISTRY_HXX_ - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkselection.cxx b/vcl/unx/gtk/a11y/atkselection.cxx deleted file mode 100644 index 1d9772bc1587..000000000000 --- a/vcl/unx/gtk/a11y/atkselection.cxx +++ /dev/null @@ -1,190 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleSelection.hpp> - -using namespace ::com::sun::star; - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleSelection> - getSelection( AtkSelection *pSelection ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pSelection ); - if( pWrap ) - { - if( !pWrap->mpSelection.is() ) - { - pWrap->mpSelection.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpSelection; - } - - return css::uno::Reference<css::accessibility::XAccessibleSelection>(); -} - -extern "C" { - -static gboolean -selection_add_selection( AtkSelection *selection, - gint i ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - { - pSelection->selectAccessibleChild( i ); - return TRUE; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in selectAccessibleChild()" ); - } - - return FALSE; -} - -static gboolean -selection_clear_selection( AtkSelection *selection ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - { - pSelection->clearAccessibleSelection(); - return TRUE; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in selectAccessibleChild()" ); - } - - return FALSE; -} - -static AtkObject* -selection_ref_selection( AtkSelection *selection, - gint i ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - return atk_object_wrapper_ref( pSelection->getSelectedAccessibleChild( i ) ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleChild()" ); - } - - return nullptr; -} - -static gint -selection_get_selection_count( AtkSelection *selection) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - return pSelection->getSelectedAccessibleChildCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleChildCount()" ); - } - - return -1; -} - -static gboolean -selection_is_child_selected( AtkSelection *selection, - gint i) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - return pSelection->isAccessibleChildSelected( i ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleChildCount()" ); - } - - return FALSE; -} - -static gboolean -selection_remove_selection( AtkSelection *selection, - gint i ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - { - pSelection->deselectAccessibleChild( i ); - return TRUE; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleChildCount()" ); - } - - return FALSE; -} - -static gboolean -selection_select_all_selection( AtkSelection *selection) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleSelection> pSelection - = getSelection( selection ); - if( pSelection.is() ) - { - pSelection->selectAllAccessibleChildren(); - return TRUE; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleChildCount()" ); - } - - return FALSE; -} - -} // extern "C" - -void -selectionIfaceInit( AtkSelectionIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->add_selection = selection_add_selection; - iface->clear_selection = selection_clear_selection; - iface->ref_selection = selection_ref_selection; - iface->get_selection_count = selection_get_selection_count; - iface->is_child_selected = selection_is_child_selected; - iface->remove_selection = selection_remove_selection; - iface->select_all_selection = selection_select_all_selection; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atktable.cxx b/vcl/unx/gtk/a11y/atktable.cxx deleted file mode 100644 index 221e55d2b287..000000000000 --- a/vcl/unx/gtk/a11y/atktable.cxx +++ /dev/null @@ -1,580 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleTable.hpp> -#include <comphelper/sequence.hxx> - -using namespace ::com::sun::star; - -static AtkObject * -atk_object_wrapper_conditional_ref( const uno::Reference< accessibility::XAccessible >& rxAccessible ) -{ - if( rxAccessible.is() ) - return atk_object_wrapper_ref( rxAccessible ); - - return nullptr; -} - -/*****************************************************************************/ - -// FIXME -static const gchar * -getAsConst( const OUString& rString ) -{ - static const int nMax = 10; - static OString aUgly[nMax]; - static int nIdx = 0; - nIdx = (nIdx + 1) % nMax; - aUgly[nIdx] = OUStringToOString( rString, RTL_TEXTENCODING_UTF8 ); - return aUgly[ nIdx ].getStr(); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleTable> - getTable( AtkTable *pTable ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pTable ); - if( pWrap ) - { - if( !pWrap->mpTable.is() ) - { - pWrap->mpTable.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpTable; - } - - return css::uno::Reference<css::accessibility::XAccessibleTable>(); -} - -/*****************************************************************************/ - -extern "C" { - -static AtkObject* -table_wrapper_ref_at (AtkTable *table, - gint row, - gint column) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable = getTable( table ); - if( pTable.is() ) - return atk_object_wrapper_conditional_ref( pTable->getAccessibleCellAt( row, column ) ); - } - - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleCellAt()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_index_at (AtkTable *table, - gint row, - gint column) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleIndex( row, column ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleIndex()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_column_at_index (AtkTable *table, - gint nIndex) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleColumn( nIndex ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleColumn()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_row_at_index( AtkTable *table, - gint nIndex ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleRow( nIndex ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleRow()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_n_columns( AtkTable *table ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleColumnCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleColumnCount()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_n_rows( AtkTable *table ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleRowCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleRowCount()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_column_extent_at( AtkTable *table, - gint row, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleColumnExtentAt( row, column ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleColumnExtentAt()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_row_extent_at( AtkTable *table, - gint row, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->getAccessibleRowExtentAt( row, column ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleRowExtentAt()" ); - } - - return -1; -} - -/*****************************************************************************/ - -static AtkObject * -table_wrapper_get_caption( AtkTable *table ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return atk_object_wrapper_conditional_ref( pTable->getAccessibleCaption() ); - } - - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleCaption()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static const gchar * -table_wrapper_get_row_description( AtkTable *table, - gint row ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return getAsConst( pTable->getAccessibleRowDescription( row ) ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleRowDescription()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static const gchar * -table_wrapper_get_column_description( AtkTable *table, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return getAsConst( pTable->getAccessibleColumnDescription( column ) ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleColumnDescription()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static AtkObject * -table_wrapper_get_row_header( AtkTable *table, - gint row ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - { - uno::Reference< accessibility::XAccessibleTable > xRowHeaders( pTable->getAccessibleRowHeaders() ); - if( xRowHeaders.is() ) - return atk_object_wrapper_conditional_ref( xRowHeaders->getAccessibleCellAt( row, 0 ) ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleRowHeaders()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static AtkObject * -table_wrapper_get_column_header( AtkTable *table, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - { - uno::Reference< accessibility::XAccessibleTable > xColumnHeaders( pTable->getAccessibleColumnHeaders() ); - if( xColumnHeaders.is() ) - return atk_object_wrapper_conditional_ref( xColumnHeaders->getAccessibleCellAt( 0, column ) ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleColumnHeaders()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static AtkObject * -table_wrapper_get_summary( AtkTable *table ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - { - return atk_object_wrapper_conditional_ref( pTable->getAccessibleSummary() ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleSummary()" ); - } - - return nullptr; -} - -/*****************************************************************************/ - -static gint -convertToGIntArray( const uno::Sequence< ::sal_Int32 >& aSequence, gint **pSelected ) -{ - if( aSequence.hasElements() ) - { - *pSelected = g_new( gint, aSequence.getLength() ); - - *pSelected = comphelper::sequenceToArray(*pSelected, aSequence); - } - - return aSequence.getLength(); -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_selected_columns( AtkTable *table, - gint **pSelected ) -{ - *pSelected = nullptr; - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return convertToGIntArray( pTable->getSelectedAccessibleColumns(), pSelected ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleColumns()" ); - } - - return 0; -} - -/*****************************************************************************/ - -static gint -table_wrapper_get_selected_rows( AtkTable *table, - gint **pSelected ) -{ - *pSelected = nullptr; - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return convertToGIntArray( pTable->getSelectedAccessibleRows(), pSelected ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectedAccessibleRows()" ); - } - - return 0; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_is_column_selected( AtkTable *table, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->isAccessibleColumnSelected( column ); - } - catch(const uno::Exception&) { - g_warning( "Exception in isAccessibleColumnSelected()" ); - } - - return 0; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_is_row_selected( AtkTable *table, - gint row ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->isAccessibleRowSelected( row ); - } - catch(const uno::Exception&) { - g_warning( "Exception in isAccessibleRowSelected()" ); - } - - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_is_selected( AtkTable *table, - gint row, - gint column ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleTable> pTable - = getTable( table ); - if( pTable.is() ) - return pTable->isAccessibleSelected( row, column ); - } - catch(const uno::Exception&) { - g_warning( "Exception in isAccessibleSelected()" ); - } - - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_add_row_selection( AtkTable *, gint ) -{ - g_warning( "FIXME: no simple analogue for add_row_selection" ); - return 0; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_remove_row_selection( AtkTable *, gint ) -{ - g_warning( "FIXME: no simple analogue for remove_row_selection" ); - return 0; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_add_column_selection( AtkTable *, gint ) -{ - g_warning( "FIXME: no simple analogue for add_column_selection" ); - return 0; -} - -/*****************************************************************************/ - -static gboolean -table_wrapper_remove_column_selection( AtkTable *, gint ) -{ - g_warning( "FIXME: no simple analogue for remove_column_selection" ); - return 0; -} - -/*****************************************************************************/ - -static void -table_wrapper_set_caption( AtkTable *, AtkObject * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -static void -table_wrapper_set_column_description( AtkTable *, gint, const gchar * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -static void -table_wrapper_set_column_header( AtkTable *, gint, AtkObject * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -static void -table_wrapper_set_row_description( AtkTable *, gint, const gchar * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -static void -table_wrapper_set_row_header( AtkTable *, gint, AtkObject * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -static void -table_wrapper_set_summary( AtkTable *, AtkObject * ) -{ // meaningless helper -} - -/*****************************************************************************/ - -} // extern "C" - -void -tableIfaceInit (AtkTableIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->ref_at = table_wrapper_ref_at; - iface->get_n_rows = table_wrapper_get_n_rows; - iface->get_n_columns = table_wrapper_get_n_columns; - iface->get_index_at = table_wrapper_get_index_at; - iface->get_column_at_index = table_wrapper_get_column_at_index; - iface->get_row_at_index = table_wrapper_get_row_at_index; - iface->is_row_selected = table_wrapper_is_row_selected; - iface->is_selected = table_wrapper_is_selected; - iface->get_selected_rows = table_wrapper_get_selected_rows; - iface->add_row_selection = table_wrapper_add_row_selection; - iface->remove_row_selection = table_wrapper_remove_row_selection; - iface->add_column_selection = table_wrapper_add_column_selection; - iface->remove_column_selection = table_wrapper_remove_column_selection; - iface->get_selected_columns = table_wrapper_get_selected_columns; - iface->is_column_selected = table_wrapper_is_column_selected; - iface->get_column_extent_at = table_wrapper_get_column_extent_at; - iface->get_row_extent_at = table_wrapper_get_row_extent_at; - iface->get_row_header = table_wrapper_get_row_header; - iface->set_row_header = table_wrapper_set_row_header; - iface->get_column_header = table_wrapper_get_column_header; - iface->set_column_header = table_wrapper_set_column_header; - iface->get_caption = table_wrapper_get_caption; - iface->set_caption = table_wrapper_set_caption; - iface->get_summary = table_wrapper_get_summary; - iface->set_summary = table_wrapper_set_summary; - iface->get_row_description = table_wrapper_get_row_description; - iface->set_row_description = table_wrapper_set_row_description; - iface->get_column_description = table_wrapper_get_column_description; - iface->set_column_description = table_wrapper_set_column_description; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atktext.cxx b/vcl/unx/gtk/a11y/atktext.cxx deleted file mode 100644 index 1406ceea5544..000000000000 --- a/vcl/unx/gtk/a11y/atktext.cxx +++ /dev/null @@ -1,838 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" -#include "atktextattributes.hxx" -#include <algorithm> - -#include <osl/diagnose.h> - -#include <com/sun/star/accessibility/AccessibleTextType.hpp> -#include <com/sun/star/accessibility/TextSegment.hpp> -#include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp> -#include <com/sun/star/accessibility/XAccessibleText.hpp> -#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp> -#include <com/sun/star/accessibility/XAccessibleTextMarkup.hpp> -#include <com/sun/star/text/TextMarkupType.hpp> - -using namespace ::com::sun::star; - -static sal_Int16 -text_type_from_boundary(AtkTextBoundary boundary_type) -{ - switch(boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - return accessibility::AccessibleTextType::CHARACTER; - case ATK_TEXT_BOUNDARY_WORD_START: - case ATK_TEXT_BOUNDARY_WORD_END: - return accessibility::AccessibleTextType::WORD; - case ATK_TEXT_BOUNDARY_SENTENCE_START: - case ATK_TEXT_BOUNDARY_SENTENCE_END: - return accessibility::AccessibleTextType::SENTENCE; - case ATK_TEXT_BOUNDARY_LINE_START: - case ATK_TEXT_BOUNDARY_LINE_END: - return accessibility::AccessibleTextType::LINE; - default: - return -1; - } -} - -/*****************************************************************************/ - -static gchar * -adjust_boundaries( css::uno::Reference<css::accessibility::XAccessibleText> const & pText, - accessibility::TextSegment const & rTextSegment, - AtkTextBoundary boundary_type, - gint * start_offset, gint * end_offset ) -{ - accessibility::TextSegment aTextSegment; - OUString aString; - gint start = 0, end = 0; - - if( !rTextSegment.SegmentText.isEmpty() ) - { - switch(boundary_type) - { - case ATK_TEXT_BOUNDARY_CHAR: - case ATK_TEXT_BOUNDARY_LINE_START: - case ATK_TEXT_BOUNDARY_LINE_END: - case ATK_TEXT_BOUNDARY_SENTENCE_START: - start = rTextSegment.SegmentStart; - end = rTextSegment.SegmentEnd; - aString = rTextSegment.SegmentText; - break; - - // the OOo break iterator behaves as SENTENCE_START - case ATK_TEXT_BOUNDARY_SENTENCE_END: - start = rTextSegment.SegmentStart; - end = rTextSegment.SegmentEnd; - - if( start > 0 ) - --start; - if( end > 0 && end < pText->getCharacterCount() - 1 ) - --end; - - aString = pText->getTextRange(start, end); - break; - - case ATK_TEXT_BOUNDARY_WORD_START: - start = rTextSegment.SegmentStart; - - // Determine the start index of the next segment - aTextSegment = pText->getTextBehindIndex(rTextSegment.SegmentEnd, - text_type_from_boundary(boundary_type)); - if( !aTextSegment.SegmentText.isEmpty() ) - end = aTextSegment.SegmentStart; - else - end = pText->getCharacterCount(); - - aString = pText->getTextRange(start, end); - break; - - case ATK_TEXT_BOUNDARY_WORD_END: - end = rTextSegment.SegmentEnd; - - // Determine the end index of the previous segment - aTextSegment = pText->getTextBeforeIndex(rTextSegment.SegmentStart, - text_type_from_boundary(boundary_type)); - if( !aTextSegment.SegmentText.isEmpty() ) - start = aTextSegment.SegmentEnd; - else - start = 0; - - aString = pText->getTextRange(start, end); - break; - - default: - return nullptr; - } - } - - *start_offset = start; - *end_offset = end; - - return OUStringToGChar(aString); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleText> - getText( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpText.is() ) - { - pWrap->mpText.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpText; - } - - return css::uno::Reference<css::accessibility::XAccessibleText>(); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleTextMarkup> - getTextMarkup( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpTextMarkup.is() ) - { - pWrap->mpTextMarkup.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpTextMarkup; - } - - return css::uno::Reference<css::accessibility::XAccessibleTextMarkup>(); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleTextAttributes> - getTextAttributes( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpTextAttributes.is() ) - { - pWrap->mpTextAttributes.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpTextAttributes; - } - - return css::uno::Reference<css::accessibility::XAccessibleTextAttributes>(); -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleMultiLineText> - getMultiLineText( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpMultiLineText.is() ) - { - pWrap->mpMultiLineText.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpMultiLineText; - } - - return css::uno::Reference<css::accessibility::XAccessibleMultiLineText>(); -} - -/*****************************************************************************/ - -extern "C" { - -static gchar * -text_wrapper_get_text (AtkText *text, - gint start_offset, - gint end_offset) -{ - gchar * ret = nullptr; - - g_return_val_if_fail( (end_offset == -1) || (end_offset >= start_offset), nullptr ); - - /* at-spi expects the delete event to be send before the deletion happened - * so we save the deleted string object in the UNO event notification and - * fool libatk-bridge.so here .. - */ - void * pData = g_object_get_data( G_OBJECT(text), "ooo::text_changed::delete" ); - if( pData != nullptr ) - { - accessibility::TextSegment * pTextSegment = - static_cast <accessibility::TextSegment *> (pData); - - if( pTextSegment->SegmentStart == start_offset && - pTextSegment->SegmentEnd == end_offset ) - { - OString aUtf8 = OUStringToOString( pTextSegment->SegmentText, RTL_TEXTENCODING_UTF8 ); - return g_strdup( aUtf8.getStr() ); - } - } - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - OUString aText; - sal_Int32 n = pText->getCharacterCount(); - - if( -1 == end_offset ) - aText = pText->getText(); - else if( start_offset < n ) - aText = pText->getTextRange(start_offset, end_offset); - - ret = g_strdup( OUStringToOString(aText, RTL_TEXTENCODING_UTF8 ).getStr() ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getText()" ); - } - - return ret; -} - -static gchar * -text_wrapper_get_text_after_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - accessibility::TextSegment aTextSegment = pText->getTextBehindIndex(offset, text_type_from_boundary(boundary_type)); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in get_text_after_offset()" ); - } - - return nullptr; -} - -static gchar * -text_wrapper_get_text_at_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - /* If the user presses the 'End' key, the caret will be placed behind the last character, - * which is the same index as the first character of the next line. In atk the magic offset - * '-2' is used to cover this special case. - */ - if ( - -2 == offset && - (ATK_TEXT_BOUNDARY_LINE_START == boundary_type || - ATK_TEXT_BOUNDARY_LINE_END == boundary_type) - ) - { - css::uno::Reference< - css::accessibility::XAccessibleMultiLineText> pMultiLineText - = getMultiLineText( text ); - if( pMultiLineText.is() ) - { - accessibility::TextSegment aTextSegment = pMultiLineText->getTextAtLineWithCaret(); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - - accessibility::TextSegment aTextSegment = pText->getTextAtIndex(offset, text_type_from_boundary(boundary_type)); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in get_text_at_offset()" ); - } - - return nullptr; -} - -static gunichar -text_wrapper_get_character_at_offset (AtkText *text, - gint offset) -{ - gint start, end; - gunichar uc = 0; - - gchar * char_as_string = - text_wrapper_get_text_at_offset(text, offset, ATK_TEXT_BOUNDARY_CHAR, - &start, &end); - if( char_as_string ) - { - uc = g_utf8_get_char( char_as_string ); - g_free( char_as_string ); - } - - return uc; -} - -static gchar * -text_wrapper_get_text_before_offset (AtkText *text, - gint offset, - AtkTextBoundary boundary_type, - gint *start_offset, - gint *end_offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - accessibility::TextSegment aTextSegment = pText->getTextBeforeIndex(offset, text_type_from_boundary(boundary_type)); - return adjust_boundaries(pText, aTextSegment, boundary_type, start_offset, end_offset); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in text_before_offset()" ); - } - - return nullptr; -} - -static gint -text_wrapper_get_caret_offset (AtkText *text) -{ - gint offset = -1; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - offset = pText->getCaretPosition(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCaretPosition()" ); - } - - return offset; -} - -static gboolean -text_wrapper_set_caret_offset (AtkText *text, - gint offset) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setCaretPosition( offset ); - } - catch(const uno::Exception&) { - g_warning( "Exception in setCaretPosition()" ); - } - - return FALSE; -} - -// #i92232# -static AtkAttributeSet* -handle_text_markup_as_run_attribute( css::uno::Reference<css::accessibility::XAccessibleTextMarkup> const & pTextMarkup, - const gint nTextMarkupType, - const gint offset, - AtkAttributeSet* pSet, - gint *start_offset, - gint *end_offset ) -{ - const gint nTextMarkupCount( pTextMarkup->getTextMarkupCount( nTextMarkupType ) ); - if ( nTextMarkupCount > 0 ) - { - for ( gint nTextMarkupIndex = 0; - nTextMarkupIndex < nTextMarkupCount; - ++nTextMarkupIndex ) - { - accessibility::TextSegment aTextSegment = - pTextMarkup->getTextMarkup( nTextMarkupIndex, nTextMarkupType ); - const gint nStartOffsetTextMarkup = aTextSegment.SegmentStart; - const gint nEndOffsetTextMarkup = aTextSegment.SegmentEnd; - if ( nStartOffsetTextMarkup <= offset ) - { - if ( offset < nEndOffsetTextMarkup ) - { - // text markup at <offset> - *start_offset = ::std::max( *start_offset, - nStartOffsetTextMarkup ); - *end_offset = ::std::min( *end_offset, - nEndOffsetTextMarkup ); - switch ( nTextMarkupType ) - { - case css::text::TextMarkupType::SPELLCHECK: - { - pSet = attribute_set_prepend_misspelled( pSet ); - } - break; - case css::text::TextMarkupType::TRACK_CHANGE_INSERTION: - { - pSet = attribute_set_prepend_tracked_change_insertion( pSet ); - } - break; - case css::text::TextMarkupType::TRACK_CHANGE_DELETION: - { - pSet = attribute_set_prepend_tracked_change_deletion( pSet ); - } - break; - case css::text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE: - { - pSet = attribute_set_prepend_tracked_change_formatchange( pSet ); - } - break; - default: - { - OSL_ASSERT( false ); - } - } - break; // no further iteration needed. - } - else - { - *start_offset = ::std::max( *start_offset, - nEndOffsetTextMarkup ); - // continue iteration. - } - } - else - { - *end_offset = ::std::min( *end_offset, - nStartOffsetTextMarkup ); - break; // no further iteration. - } - } // eof iteration over text markups - } - - return pSet; -} - -static AtkAttributeSet * -text_wrapper_get_run_attributes( AtkText *text, - gint offset, - gint *start_offset, - gint *end_offset) -{ - AtkAttributeSet *pSet = nullptr; - - try { - bool bOffsetsAreValid = false; - - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is()) - { - uno::Sequence< beans::PropertyValue > aAttributeList; - - css::uno::Reference<css::accessibility::XAccessibleTextAttributes> - pTextAttributes = getTextAttributes( text ); - if(pTextAttributes.is()) // Text attributes are available for paragraphs only - { - aAttributeList = pTextAttributes->getRunAttributes( offset, uno::Sequence< OUString > () ); - } - else // For other text objects use character attributes - { - aAttributeList = pText->getCharacterAttributes( offset, uno::Sequence< OUString > () ); - } - - pSet = attribute_set_new_from_property_values( aAttributeList, true, text ); - // #i100938# - // - always provide start_offset and end_offset - { - accessibility::TextSegment aTextSegment = - pText->getTextAtIndex(offset, accessibility::AccessibleTextType::ATTRIBUTE_RUN); - - *start_offset = aTextSegment.SegmentStart; - // #i100938# - // Do _not_ increment the end_offset provide by <accessibility::TextSegment> instance - *end_offset = aTextSegment.SegmentEnd; - bOffsetsAreValid = true; - } - } - - // Special handling for misspelled text - // #i92232# - // - add special handling for tracked changes and refactor the - // corresponding code for handling misspelled text. - css::uno::Reference<css::accessibility::XAccessibleTextMarkup> - pTextMarkup = getTextMarkup( text ); - if( pTextMarkup.is() ) - { - // Get attribute run here if it hasn't been done before - if (!bOffsetsAreValid && pText.is()) - { - accessibility::TextSegment aAttributeTextSegment = - pText->getTextAtIndex(offset, accessibility::AccessibleTextType::ATTRIBUTE_RUN); - *start_offset = aAttributeTextSegment.SegmentStart; - *end_offset = aAttributeTextSegment.SegmentEnd; - } - // handle misspelled text - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::SPELLCHECK, - offset, pSet, start_offset, end_offset ); - // handle tracked changes - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::TRACK_CHANGE_INSERTION, - offset, pSet, start_offset, end_offset ); - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::TRACK_CHANGE_DELETION, - offset, pSet, start_offset, end_offset ); - pSet = handle_text_markup_as_run_attribute( - pTextMarkup, - css::text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE, - offset, pSet, start_offset, end_offset ); - } - } - catch(const uno::Exception&){ - - g_warning( "Exception in get_run_attributes()" ); - - if( pSet ) - { - atk_attribute_set_free( pSet ); - pSet = nullptr; - } - } - - return pSet; -} - -/*****************************************************************************/ - -static AtkAttributeSet * -text_wrapper_get_default_attributes( AtkText *text ) -{ - AtkAttributeSet *pSet = nullptr; - - try { - css::uno::Reference<css::accessibility::XAccessibleTextAttributes> - pTextAttributes = getTextAttributes( text ); - if( pTextAttributes.is() ) - { - uno::Sequence< beans::PropertyValue > aAttributeList = - pTextAttributes->getDefaultAttributes( uno::Sequence< OUString > () ); - - pSet = attribute_set_new_from_property_values( aAttributeList, false, text ); - } - } - catch(const uno::Exception&) { - - g_warning( "Exception in get_default_attributes()" ); - - if( pSet ) - { - atk_attribute_set_free( pSet ); - pSet = nullptr; - } - } - - return pSet; -} - -/*****************************************************************************/ - -static void -text_wrapper_get_character_extents( AtkText *text, - gint offset, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coords ) -{ - *x = *y = *width = *height = -1; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - awt::Rectangle aRect = pText->getCharacterBounds( offset ); - - gint origin_x = 0; - gint origin_y = 0; - - if( coords == ATK_XY_SCREEN ) - { - g_return_if_fail( ATK_IS_COMPONENT( text ) ); - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_component_get_position( ATK_COMPONENT( text ), &origin_x, &origin_y, coords); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - - *x = aRect.X + origin_x; - *y = aRect.Y + origin_y; - *width = aRect.Width; - *height = aRect.Height; - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getCharacterBounds" ); - } -} - -static gint -text_wrapper_get_character_count (AtkText *text) -{ - gint rv = 0; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - rv = pText->getCharacterCount(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCharacterCount" ); - } - - return rv; -} - -static gint -text_wrapper_get_offset_at_point (AtkText *text, - gint x, - gint y, - AtkCoordType coords) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - gint origin_x = 0; - gint origin_y = 0; - - if( coords == ATK_XY_SCREEN ) - { - g_return_val_if_fail( ATK_IS_COMPONENT( text ), -1 ); - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_component_get_position( ATK_COMPONENT( text ), &origin_x, &origin_y, coords); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - - return pText->getIndexAtPoint( awt::Point(x - origin_x, y - origin_y) ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getIndexAtPoint" ); - } - - return -1; -} - -// FIXME: the whole series of selections API is problematic ... - -static gint -text_wrapper_get_n_selections (AtkText *text) -{ - gint rv = 0; - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - rv = ( pText->getSelectionEnd() > pText->getSelectionStart() ) ? 1 : 0; - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectionEnd() or getSelectionStart()" ); - } - - return rv; -} - -static gchar * -text_wrapper_get_selection (AtkText *text, - gint selection_num, - gint *start_offset, - gint *end_offset) -{ - g_return_val_if_fail( selection_num == 0, FALSE ); - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - { - *start_offset = pText->getSelectionStart(); - *end_offset = pText->getSelectionEnd(); - - return OUStringToGChar( pText->getSelectedText() ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getSelectionEnd(), getSelectionStart() or getSelectedText()" ); - } - - return nullptr; -} - -static gboolean -text_wrapper_add_selection (AtkText *text, - gint start_offset, - gint end_offset) -{ - // FIXME: can we try to be more compatible by expanding an - // existing adjacent selection ? - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setSelection( start_offset, end_offset ); // ? - } - catch(const uno::Exception&) { - g_warning( "Exception in setSelection()" ); - } - - return FALSE; -} - -static gboolean -text_wrapper_remove_selection (AtkText *text, - gint selection_num) -{ - g_return_val_if_fail( selection_num == 0, FALSE ); - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setSelection( 0, 0 ); // ? - } - catch(const uno::Exception&) { - g_warning( "Exception in setSelection()" ); - } - - return FALSE; -} - -static gboolean -text_wrapper_set_selection (AtkText *text, - gint selection_num, - gint start_offset, - gint end_offset) -{ - g_return_val_if_fail( selection_num == 0, FALSE ); - - try { - css::uno::Reference<css::accessibility::XAccessibleText> pText - = getText( text ); - if( pText.is() ) - return pText->setSelection( start_offset, end_offset ); - } - catch(const uno::Exception&) { - g_warning( "Exception in setSelection()" ); - } - - return FALSE; -} - -} // extern "C" - -void -textIfaceInit (AtkTextIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->get_text = text_wrapper_get_text; - iface->get_character_at_offset = text_wrapper_get_character_at_offset; - iface->get_text_before_offset = text_wrapper_get_text_before_offset; - iface->get_text_at_offset = text_wrapper_get_text_at_offset; - iface->get_text_after_offset = text_wrapper_get_text_after_offset; - iface->get_caret_offset = text_wrapper_get_caret_offset; - iface->set_caret_offset = text_wrapper_set_caret_offset; - iface->get_character_count = text_wrapper_get_character_count; - iface->get_n_selections = text_wrapper_get_n_selections; - iface->get_selection = text_wrapper_get_selection; - iface->add_selection = text_wrapper_add_selection; - iface->remove_selection = text_wrapper_remove_selection; - iface->set_selection = text_wrapper_set_selection; - iface->get_run_attributes = text_wrapper_get_run_attributes; - iface->get_default_attributes = text_wrapper_get_default_attributes; - iface->get_character_extents = text_wrapper_get_character_extents; - iface->get_offset_at_point = text_wrapper_get_offset_at_point; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atktextattributes.cxx b/vcl/unx/gtk/a11y/atktextattributes.cxx deleted file mode 100644 index 0ba7fd561862..000000000000 --- a/vcl/unx/gtk/a11y/atktextattributes.cxx +++ /dev/null @@ -1,1383 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atktextattributes.hxx" - -#include <com/sun/star/awt/FontSlant.hpp> -#include <com/sun/star/awt/FontStrikeout.hpp> -#include <com/sun/star/awt/FontUnderline.hpp> - -#include <com/sun/star/style/CaseMap.hpp> -#include <com/sun/star/style/LineSpacing.hpp> -#include <com/sun/star/style/LineSpacingMode.hpp> -#include <com/sun/star/style/ParagraphAdjust.hpp> -#include <com/sun/star/style/TabAlign.hpp> -#include <com/sun/star/style/TabStop.hpp> - -#include <com/sun/star/text/WritingMode2.hpp> - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleComponent.hpp> - -#include <i18nlangtag/languagetag.hxx> -#include <vcl/svapp.hxx> -#include <vcl/outdev.hxx> - -#include <stdio.h> -#include <string.h> - -using namespace ::com::sun::star; - -typedef gchar* (* AtkTextAttrFunc) ( const uno::Any& rAny ); -typedef bool (* TextPropertyValueFunc) ( uno::Any& rAny, const gchar * value ); - -#define STRNCMP_PARAM( s ) s,sizeof( s )-1 - -/*****************************************************************************/ - -static AtkTextAttribute atk_text_attribute_paragraph_style = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_font_effect = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_decoration = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_line_height = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_rotation = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_shadow = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_tab_interval = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_tab_stops = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_writing_mode = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_vertical_align = ATK_TEXT_ATTR_INVALID; -static AtkTextAttribute atk_text_attribute_misspelled = ATK_TEXT_ATTR_INVALID; -// #i92232# -static AtkTextAttribute atk_text_attribute_tracked_change = ATK_TEXT_ATTR_INVALID; -// #i92233# -static AtkTextAttribute atk_text_attribute_mm_to_pixel_ratio = ATK_TEXT_ATTR_INVALID; - -/*****************************************************************************/ - -/** - * !! IMPORTANT NOTE !! : when adding items to this list, KEEP THE LIST SORTED - * and re-arrange the enum values accordingly. - */ - -enum ExportedAttribute -{ - TEXT_ATTRIBUTE_BACKGROUND_COLOR = 0, - TEXT_ATTRIBUTE_CASEMAP, - TEXT_ATTRIBUTE_FOREGROUND_COLOR, - TEXT_ATTRIBUTE_CONTOURED, - TEXT_ATTRIBUTE_CHAR_ESCAPEMENT, - TEXT_ATTRIBUTE_BLINKING, - TEXT_ATTRIBUTE_FONT_NAME, - TEXT_ATTRIBUTE_HEIGHT, - TEXT_ATTRIBUTE_HIDDEN, - TEXT_ATTRIBUTE_KERNING, - TEXT_ATTRIBUTE_LOCALE, - TEXT_ATTRIBUTE_POSTURE, - TEXT_ATTRIBUTE_RELIEF, - TEXT_ATTRIBUTE_ROTATION, - TEXT_ATTRIBUTE_SCALE, - TEXT_ATTRIBUTE_SHADOWED, - TEXT_ATTRIBUTE_STRIKETHROUGH, - TEXT_ATTRIBUTE_UNDERLINE, - TEXT_ATTRIBUTE_WEIGHT, - // #i92233# - TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO, - TEXT_ATTRIBUTE_JUSTIFICATION, - TEXT_ATTRIBUTE_BOTTOM_MARGIN, - TEXT_ATTRIBUTE_FIRST_LINE_INDENT, - TEXT_ATTRIBUTE_LEFT_MARGIN, - TEXT_ATTRIBUTE_LINE_SPACING, - TEXT_ATTRIBUTE_RIGHT_MARGIN, - TEXT_ATTRIBUTE_STYLE_NAME, - TEXT_ATTRIBUTE_TAB_STOPS, - TEXT_ATTRIBUTE_TOP_MARGIN, - TEXT_ATTRIBUTE_WRITING_MODE, - TEXT_ATTRIBUTE_LAST -}; - -static const char * ExportedTextAttributes[TEXT_ATTRIBUTE_LAST] = -{ - "CharBackColor", // TEXT_ATTRIBUTE_BACKGROUND_COLOR - "CharCaseMap", // TEXT_ATTRIBUTE_CASEMAP - "CharColor", // TEXT_ATTRIBUTE_FOREGROUND_COLOR - "CharContoured", // TEXT_ATTRIBUTE_CONTOURED - "CharEscapement", // TEXT_ATTRIBUTE_CHAR_ESCAPEMENT - "CharFlash", // TEXT_ATTRIBUTE_BLINKING - "CharFontName", // TEXT_ATTRIBUTE_FONT_NAME - "CharHeight", // TEXT_ATTRIBUTE_HEIGHT - "CharHidden", // TEXT_ATTRIBUTE_HIDDEN - "CharKerning", // TEXT_ATTRIBUTE_KERNING - "CharLocale", // TEXT_ATTRIBUTE_LOCALE - "CharPosture", // TEXT_ATTRIBUTE_POSTURE - "CharRelief", // TEXT_ATTRIBUTE_RELIEF - "CharRotation", // TEXT_ATTRIBUTE_ROTATION - "CharScaleWidth", // TEXT_ATTRIBUTE_SCALE - "CharShadowed", // TEXT_ATTRIBUTE_SHADOWED - "CharStrikeout", // TEXT_ATTRIBUTE_STRIKETHROUGH - "CharUnderline", // TEXT_ATTRIBUTE_UNDERLINE - "CharWeight", // TEXT_ATTRIBUTE_WEIGHT - // #i92233# - "MMToPixelRatio", // TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO - "ParaAdjust", // TEXT_ATTRIBUTE_JUSTIFICATION - "ParaBottomMargin", // TEXT_ATTRIBUTE_BOTTOM_MARGIN - "ParaFirstLineIndent", // TEXT_ATTRIBUTE_FIRST_LINE_INDENT - "ParaLeftMargin", // TEXT_ATTRIBUTE_LEFT_MARGIN - "ParaLineSpacing", // TEXT_ATTRIBUTE_LINE_SPACING - "ParaRightMargin", // TEXT_ATTRIBUTE_RIGHT_MARGIN - "ParaStyleName", // TEXT_ATTRIBUTE_STYLE_NAME - "ParaTabStops", // TEXT_ATTRIBUTE_TAB_STOPS - "ParaTopMargin", // TEXT_ATTRIBUTE_TOP_MARGIN - "WritingMode" // TEXT_ATTRIBUTE_WRITING_MODE -}; - -/*****************************************************************************/ - -static gchar* -get_value( const uno::Sequence< beans::PropertyValue >& rAttributeList, - sal_Int32 nIndex, AtkTextAttrFunc func ) -{ - if( nIndex != -1 ) - return func(rAttributeList[nIndex].Value); - - return nullptr; -} - -#define get_bool_value( list, index ) get_value( list, index, Bool2String ) -#define get_height_value( list, index ) get_value( list, index, Float2String ) -#define get_justification_value( list, index ) get_value( list, index, Adjust2Justification ) -#define get_cmm_value( list, index ) get_value( list, index, CMM2UnitString ) -#define get_scale_width( list, index ) get_value( list, index, Scale2String ) -#define get_strikethrough_value( list, index ) get_value( list, index, Strikeout2String ) -#define get_string_value( list, index ) get_value( list, index, GetString ) -#define get_style_value( list, index ) get_value( list, index, FontSlant2Style ) -#define get_underline_value( list, index ) get_value( list, index, Underline2String ) -#define get_variant_value( list, index ) get_value( list, index, CaseMap2String ) -#define get_weight_value( list, index ) get_value( list, index, Weight2String ) -#define get_language_string( list, index ) get_value( list, index, Locale2String ) - -static double toPoint(sal_Int16 n) -{ - // 100th mm -> pt - return static_cast<double>(n * 72) / 2540; -} - -/*****************************************************************************/ - -static bool -InvalidValue( uno::Any&, const gchar * ) -{ - return false; -} - -/*****************************************************************************/ - -static gchar* -Float2String(const uno::Any& rAny) -{ - return g_strdup_printf( "%g", rAny.get<float>() ); -} - -static bool -String2Float( uno::Any& rAny, const gchar * value ) -{ - float fval; - - if( 1 != sscanf( value, "%g", &fval ) ) - return false; - - rAny <<= fval; - return true; -} - -/*****************************************************************************/ - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleComponent> - getComponent( AtkText *pText ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText ); - if( pWrap ) - { - if( !pWrap->mpComponent.is() ) - { - pWrap->mpComponent.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpComponent; - } - - return css::uno::Reference<css::accessibility::XAccessibleComponent>(); -} - -static gchar* -get_color_value(const uno::Sequence< beans::PropertyValue >& rAttributeList, - const sal_Int32 * pIndexArray, - ExportedAttribute attr, - AtkText * text) -{ - sal_Int32 nColor = -1; // AUTOMATIC - sal_Int32 nIndex = pIndexArray[attr]; - - if( nIndex != -1 ) - nColor = rAttributeList[nIndex].Value.get<sal_Int32>(); - - /* - * Check for color value for 100% alpha white, which means - * "automatic". Grab the RGB value from XAccessibleComponent - * in this case. - */ - - if( (nColor == -1) && text ) - { - try - { - css::uno::Reference<css::accessibility::XAccessibleComponent> - pComponent = getComponent( text ); - if( pComponent.is() ) - { - switch( attr ) - { - case TEXT_ATTRIBUTE_BACKGROUND_COLOR: - nColor = pComponent->getBackground(); - break; - case TEXT_ATTRIBUTE_FOREGROUND_COLOR: - nColor = pComponent->getForeground(); - break; - default: - break; - } - } - } - - catch(const uno::Exception&) { - g_warning( "Exception in get[Fore|Back]groundColor()" ); - } - } - - if( nColor != -1 ) - { - sal_uInt8 blue = nColor & 0xFF; - sal_uInt8 green = (nColor >> 8) & 0xFF; - sal_uInt8 red = (nColor >> 16) & 0xFF; - - return g_strdup_printf( "%u,%u,%u", red, green, blue ); - } - - return nullptr; -} - -static bool -String2Color( uno::Any& rAny, const gchar * value ) -{ - int red, green, blue; - - if( 3 != sscanf( value, "%d,%d,%d", &red, &green, &blue ) ) - return false; - - sal_Int32 nColor = static_cast<sal_Int32>(blue) | ( static_cast<sal_Int32>(green) << 8 ) | ( static_cast<sal_Int32>(red) << 16 ); - rAny <<= nColor; - return true; -} - -/*****************************************************************************/ - -static gchar* -FontSlant2Style(const uno::Any& rAny) -{ - const gchar * value = nullptr; - - awt::FontSlant aFontSlant; - if(!(rAny >>= aFontSlant)) - return nullptr; - - switch( aFontSlant ) - { - case awt::FontSlant_NONE: - value = "normal"; - break; - - case awt::FontSlant_OBLIQUE: - value = "oblique"; - break; - - case awt::FontSlant_ITALIC: - value = "italic"; - break; - - case awt::FontSlant_REVERSE_OBLIQUE: - value = "reverse oblique"; - break; - - case awt::FontSlant_REVERSE_ITALIC: - value = "reverse italic"; - break; - - default: - break; - } - - if( value ) - return g_strdup( value ); - - return nullptr; -} - -static bool -Style2FontSlant( uno::Any& rAny, const gchar * value ) -{ - awt::FontSlant aFontSlant; - - if( strncmp( value, STRNCMP_PARAM( "normal" ) ) == 0 ) - aFontSlant = awt::FontSlant_NONE; - else if( strncmp( value, STRNCMP_PARAM( "oblique" ) ) == 0 ) - aFontSlant = awt::FontSlant_OBLIQUE; - else if( strncmp( value, STRNCMP_PARAM( "italic" ) ) == 0 ) - aFontSlant = awt::FontSlant_ITALIC; - else if( strncmp( value, STRNCMP_PARAM( "reverse oblique" ) ) == 0 ) - aFontSlant = awt::FontSlant_REVERSE_OBLIQUE; - else if( strncmp( value, STRNCMP_PARAM( "reverse italic" ) ) == 0 ) - aFontSlant = awt::FontSlant_REVERSE_ITALIC; - else - return false; - - rAny <<= aFontSlant; - return true; -} - -/*****************************************************************************/ - -static gchar* -Weight2String(const uno::Any& rAny) -{ - return g_strdup_printf( "%g", rAny.get<float>() * 4 ); -} - -static bool -String2Weight( uno::Any& rAny, const gchar * value ) -{ - float weight; - - if( 1 != sscanf( value, "%g", &weight ) ) - return false; - - rAny <<= weight / 4; - return true; -} - -/*****************************************************************************/ - -static gchar* -Adjust2Justification(const uno::Any& rAny) -{ - const gchar * value = nullptr; - - switch( static_cast<style::ParagraphAdjust>(rAny.get<short>()) ) - { - case style::ParagraphAdjust_LEFT: - value = "left"; - break; - - case style::ParagraphAdjust_RIGHT: - value = "right"; - break; - - case style::ParagraphAdjust_BLOCK: - case style::ParagraphAdjust_STRETCH: - value = "fill"; - break; - - case style::ParagraphAdjust_CENTER: - value = "center"; - break; - - default: - break; - } - - if( value ) - return g_strdup( value ); - - return nullptr; -} - -static bool -Justification2Adjust( uno::Any& rAny, const gchar * value ) -{ - style::ParagraphAdjust nParagraphAdjust; - - if( strncmp( value, STRNCMP_PARAM( "left" ) ) == 0 ) - nParagraphAdjust = style::ParagraphAdjust_LEFT; - else if( strncmp( value, STRNCMP_PARAM( "right" ) ) == 0 ) - nParagraphAdjust = style::ParagraphAdjust_RIGHT; - else if( strncmp( value, STRNCMP_PARAM( "fill" ) ) == 0 ) - nParagraphAdjust = style::ParagraphAdjust_BLOCK; - else if( strncmp( value, STRNCMP_PARAM( "center" ) ) == 0 ) - nParagraphAdjust = style::ParagraphAdjust_CENTER; - else - return false; - - rAny <<= static_cast<short>(nParagraphAdjust); - return true; -} - -/*****************************************************************************/ - -const gchar * const font_strikethrough[] = { - "none", // FontStrikeout::NONE - "single", // FontStrikeout::SINGLE - "double", // FontStrikeout::DOUBLE - nullptr, // FontStrikeout::DONTKNOW - "bold", // FontStrikeout::BOLD - "with /", // FontStrikeout::SLASH - "with X" // FontStrikeout::X -}; - -static gchar* -Strikeout2String(const uno::Any& rAny) -{ - sal_Int16 n = rAny.get<sal_Int16>(); - - if( n >= 0 && n < sal_Int16(SAL_N_ELEMENTS(font_strikethrough)) ) - return g_strdup( font_strikethrough[n] ); - - return nullptr; -} - -static bool -String2Strikeout( uno::Any& rAny, const gchar * value ) -{ - for( sal_Int16 n=0; n < sal_Int16(SAL_N_ELEMENTS(font_strikethrough)); ++n ) - { - if( ( nullptr != font_strikethrough[n] ) && - 0 == strncmp( value, font_strikethrough[n], strlen( font_strikethrough[n] ) ) ) - { - rAny <<= n; - return true; - } - } - - return false; -} - -/*****************************************************************************/ - -static gchar* -Underline2String(const uno::Any& rAny) -{ - const gchar * value = nullptr; - - switch( rAny.get<sal_Int16>() ) - { - case awt::FontUnderline::NONE: - value = "none"; - break; - - case awt::FontUnderline::SINGLE: - value = "single"; - break; - - case awt::FontUnderline::DOUBLE: - value = "double"; - break; - - default: - break; - } - - if( value ) - return g_strdup( value ); - - return nullptr; -} - -static bool -String2Underline( uno::Any& rAny, const gchar * value ) -{ - short nUnderline; - - if( strncmp( value, STRNCMP_PARAM( "none" ) ) == 0 ) - nUnderline = awt::FontUnderline::NONE; - else if( strncmp( value, STRNCMP_PARAM( "single" ) ) == 0 ) - nUnderline = awt::FontUnderline::SINGLE; - else if( strncmp( value, STRNCMP_PARAM( "double" ) ) == 0 ) - nUnderline = awt::FontUnderline::DOUBLE; - else - return false; - - rAny <<= nUnderline; - return true; -} - -/*****************************************************************************/ - -static gchar* -GetString(const uno::Any& rAny) -{ - OString aFontName = OUStringToOString( rAny.get< OUString > (), RTL_TEXTENCODING_UTF8 ); - - if( !aFontName.isEmpty() ) - return g_strdup( aFontName.getStr() ); - - return nullptr; -} - -static bool -SetString( uno::Any& rAny, const gchar * value ) -{ - OString aFontName( value ); - - if( !aFontName.isEmpty() ) - { - rAny <<= OStringToOUString( aFontName, RTL_TEXTENCODING_UTF8 ); - return true; - } - - return false; -} - -/*****************************************************************************/ - -// @see http://developer.gnome.org/doc/API/2.0/atk/AtkText.html#AtkTextAttribute - -// CMM = 100th of mm -static gchar* -CMM2UnitString(const uno::Any& rAny) -{ - double fValue = rAny.get<sal_Int32>(); - fValue = fValue * 0.01; - - return g_strdup_printf( "%gmm", fValue ); -} - -static bool -UnitString2CMM( uno::Any& rAny, const gchar * value ) -{ - float fValue = 0.0; // pb: don't use double here because of warning on linux - - if( 1 != sscanf( value, "%gmm", &fValue ) ) - return false; - - fValue = fValue * 100; - - rAny <<= static_cast<sal_Int32>(fValue); - return true; -} - -/*****************************************************************************/ - -static const gchar * bool_values[] = { "true", "false" }; - -static gchar * -Bool2String( const uno::Any& rAny ) -{ - int n = 1; - - if( rAny.get<bool>() ) - n = 0; - - return g_strdup( bool_values[n] ); -} - -static bool -String2Bool( uno::Any& rAny, const gchar * value ) -{ - bool bValue; - - if( strncmp( value, STRNCMP_PARAM( "true" ) ) == 0 ) - bValue = true; - else if( strncmp( value, STRNCMP_PARAM( "false" ) ) == 0 ) - bValue = false; - else - return false; - - rAny <<= bValue; - return true; -} - -/*****************************************************************************/ - -static gchar* -Scale2String( const uno::Any& rAny ) -{ - return g_strdup_printf( "%g", static_cast<double>(rAny.get< sal_Int16 > ()) / 100 ); -} - -static bool -String2Scale( uno::Any& rAny, const gchar * value ) -{ - double dval; - - if( 1 != sscanf( value, "%lg", &dval ) ) - return false; - - rAny <<= static_cast<sal_Int16>(dval * 100); - return true; -} - -/*****************************************************************************/ - -static gchar * -CaseMap2String( const uno::Any& rAny ) -{ - const gchar * value; - - switch( rAny.get<short>() ) - { - case style::CaseMap::SMALLCAPS: - value = "small_caps"; - break; - - default: - value = "normal"; - break; - } - - return g_strdup(value); -} - -static bool -String2CaseMap( uno::Any& rAny, const gchar * value ) -{ - short nCaseMap; - - if( strncmp( value, STRNCMP_PARAM( "normal" ) ) == 0 ) - nCaseMap = style::CaseMap::NONE; - else if( strncmp( value, STRNCMP_PARAM( "small_caps" ) ) == 0 ) - nCaseMap = style::CaseMap::SMALLCAPS; - else - return false; - - rAny <<= nCaseMap; - return true; -} - -/*****************************************************************************/ - -const gchar * const font_stretch[] = { - "ultra_condensed", - "extra_condensed", - "condensed", - "semi_condensed", - "normal", - "semi_expanded", - "expanded", - "extra_expanded", - "ultra_expanded" -}; - -static gchar* -Kerning2Stretch(const uno::Any& rAny) -{ - sal_Int16 n = rAny.get<sal_Int16>(); - int i = 4; - - // No good idea for a mapping - just return the basic info - if( n < 0 ) - i=2; - else if( n > 0 ) - i=6; - - return g_strdup(font_stretch[i]); -} - -/*****************************************************************************/ - -static gchar* -Locale2String(const uno::Any& rAny) -{ - /* FIXME-BCP47: support language tags? And why is country lowercase? */ - lang::Locale aLocale = rAny.get<lang::Locale> (); - LanguageTag aLanguageTag( aLocale); - return g_strdup_printf( "%s-%s", - OUStringToOString( aLanguageTag.getLanguage(), RTL_TEXTENCODING_ASCII_US).getStr(), - OUStringToOString( aLanguageTag.getCountry(), RTL_TEXTENCODING_ASCII_US).toAsciiLowerCase().getStr() ); -} - -static bool -String2Locale( uno::Any& rAny, const gchar * value ) -{ - /* FIXME-BCP47: support language tags? */ - bool ret = false; - - gchar ** str_array = g_strsplit_set( value, "-.@", -1 ); - if( str_array[0] != nullptr ) - { - ret = true; - - lang::Locale aLocale; - - aLocale.Language = OUString::createFromAscii(str_array[0]); - if( str_array[1] != nullptr ) - { - gchar * country = g_ascii_strup(str_array[1], -1); - aLocale.Country = OUString::createFromAscii(country); - g_free(country); - } - - rAny <<= aLocale; - } - - g_strfreev(str_array); - return ret; -} - -/*****************************************************************************/ - -// @see http://www.w3.org/TR/2002/WD-css3-fonts-20020802/#font-effect-prop -static const gchar * relief[] = { "none", "emboss", "engrave" }; -static const gchar * const outline = "outline"; - -static gchar * -get_font_effect(const uno::Sequence< beans::PropertyValue >& rAttributeList, - sal_Int32 nContourIndex, sal_Int32 nReliefIndex) -{ - if( nContourIndex != -1 ) - { - if( rAttributeList[nContourIndex].Value.get<bool>() ) - return g_strdup(outline); - } - - if( nReliefIndex != -1 ) - { - sal_Int16 n = rAttributeList[nReliefIndex].Value.get<sal_Int16>(); - if( n < 3) - return g_strdup(relief[n]); - } - - return nullptr; -} - -/*****************************************************************************/ - -// @see http://www.w3.org/TR/REC-CSS2/text.html#lining-striking-props - -enum -{ - DECORATION_NONE = 0, - DECORATION_BLINK, - DECORATION_UNDERLINE, - DECORATION_LINE_THROUGH -}; - -static const gchar * decorations[] = { "none", "blink", "underline", "line-through" }; - -static gchar * -get_text_decoration(const uno::Sequence< beans::PropertyValue >& rAttributeList, - sal_Int32 nBlinkIndex, sal_Int32 nUnderlineIndex, - sal_Int16 nStrikeoutIndex) -{ - gchar * value_list[4] = { nullptr, nullptr, nullptr, nullptr }; - gint count = 0; - - // no property value found - if( ( nBlinkIndex == -1 ) && (nUnderlineIndex == -1 ) && (nStrikeoutIndex == -1)) - return nullptr; - - if( nBlinkIndex != -1 ) - { - if( rAttributeList[nBlinkIndex].Value.get<bool>() ) - value_list[count++] = const_cast <gchar *> (decorations[DECORATION_BLINK]); - } - if( nUnderlineIndex != -1 ) - { - sal_Int16 n = rAttributeList[nUnderlineIndex].Value.get<sal_Int16> (); - if( n != awt::FontUnderline::NONE ) - value_list[count++] = const_cast <gchar *> (decorations[DECORATION_UNDERLINE]); - } - if( nStrikeoutIndex != -1 ) - { - sal_Int16 n = rAttributeList[nStrikeoutIndex].Value.get<sal_Int16> (); - if( n != awt::FontStrikeout::NONE && n != awt::FontStrikeout::DONTKNOW ) - value_list[count++] = const_cast <gchar *> (decorations[DECORATION_LINE_THROUGH]); - } - - if( count == 0 ) - value_list[count++] = const_cast <gchar *> (decorations[DECORATION_NONE]); - - return g_strjoinv(" ", value_list); -} - -/*****************************************************************************/ - -// @see http://www.w3.org/TR/REC-CSS2/text.html#propdef-text-shadow - -static const gchar * shadow_values[] = { "none", "black" }; - -static gchar * -Bool2Shadow( const uno::Any& rAny ) -{ - int n = 0; - - if( rAny.get<bool>() ) - n = 1; - - return g_strdup( shadow_values[n] ); -} - -/*****************************************************************************/ - -static gchar * -Short2Degree( const uno::Any& rAny ) -{ - float f = rAny.get<sal_Int16>() / 10.0; - return g_strdup_printf( "%g", f ); -} - -/*****************************************************************************/ - -const gchar * const directions[] = { "ltr", "rtl", "rtl", "ltr", "none" }; - -static gchar * -WritingMode2Direction( const uno::Any& rAny ) -{ - sal_Int16 n = rAny.get<sal_Int16>(); - - if( 0 <= n && n <= text::WritingMode2::PAGE ) - return g_strdup(directions[n]); - - return nullptr; -} - -// @see http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection - -const gchar * const writing_modes[] = { "lr-tb", "rl-tb", "tb-rl", "tb-lr", "none" }; -static gchar * -WritingMode2String( const uno::Any& rAny ) -{ - sal_Int16 n = rAny.get<sal_Int16>(); - - if( 0 <= n && n <= text::WritingMode2::PAGE ) - return g_strdup(writing_modes[n]); - - return nullptr; -} - -/*****************************************************************************/ - -const char * const baseline_values[] = { "baseline", "sub", "super" }; - -// @see http://www.w3.org/TR/REC-CSS2/visudet.html#propdef-vertical-align -static gchar * -Escapement2VerticalAlign( const uno::Any& rAny ) -{ - sal_Int16 n = rAny.get<sal_Int16>(); - gchar * ret = nullptr; - - // Values are in %, 101% means "automatic" - if( n == 0 ) - ret = g_strdup(baseline_values[0]); - else if( n == 101 ) - ret = g_strdup(baseline_values[2]); - else if( n == -101 ) - ret = g_strdup(baseline_values[1]); - else - ret = g_strdup_printf( "%d%%", n ); - - return ret; -} - -/*****************************************************************************/ - -// @see http://www.w3.org/TR/REC-CSS2/visudet.html#propdef-line-height -static gchar * -LineSpacing2LineHeight( const uno::Any& rAny ) -{ - style::LineSpacing ls; - gchar * ret = nullptr; - - if( rAny >>= ls ) - { - if( ls.Mode == style::LineSpacingMode::PROP ) - ret = g_strdup_printf( "%d%%", ls.Height ); - else if( ls.Mode == style::LineSpacingMode::FIX ) - ret = g_strdup_printf( "%.3gpt", toPoint(ls.Height) ); - } - - return ret; -} - -/*****************************************************************************/ - -// @see http://www.w3.org/People/howcome/t/970224HTMLERB-CSS/WD-tabs-970117.html -static gchar * -TabStopList2String( const uno::Any& rAny, bool default_tabs ) -{ - uno::Sequence< style::TabStop > theTabStops; - gchar * ret = nullptr; - - if( rAny >>= theTabStops) - { - sal_Unicode lastFillChar = ' '; - - for( const auto& rTabStop : std::as_const(theTabStops) ) - { - bool is_default_tab = (style::TabAlign_DEFAULT == rTabStop.Alignment); - - if( is_default_tab != default_tabs ) - continue; - - double fValue = rTabStop.Position; - fValue = fValue * 0.01; - - const gchar * tab_align = ""; - switch( rTabStop.Alignment ) - { - case style::TabAlign_LEFT : - tab_align = "left "; - break; - case style::TabAlign_CENTER : - tab_align = "center "; - break; - case style::TabAlign_RIGHT : - tab_align = "right "; - break; - case style::TabAlign_DECIMAL : - tab_align = "decimal "; - break; - default: - break; - } - - const gchar * lead_char = ""; - - if( rTabStop.FillChar != lastFillChar ) - { - lastFillChar = rTabStop.FillChar; - switch (lastFillChar) - { - case ' ': - lead_char = "blank "; - break; - - case '.': - lead_char = "dotted "; - break; - - case '-': - lead_char = "dashed "; - break; - - case '_': - lead_char = "lined "; - break; - - default: - lead_char = "custom "; - break; - } - } - - gchar * tab_str = g_strdup_printf( "%s%s%gmm", lead_char, tab_align, fValue ); - - if( ret ) - { - gchar * old_tab_str = ret; - ret = g_strconcat(old_tab_str, " ", tab_str, nullptr); - g_free( old_tab_str ); - } - else - ret = tab_str; - } - } - - return ret; -} - -static gchar * -TabStops2String( const uno::Any& rAny ) -{ - return TabStopList2String(rAny, false); -} - -static gchar * -DefaultTabStops2String( const uno::Any& rAny ) -{ - return TabStopList2String(rAny, true); -} - -/*****************************************************************************/ - -extern "C" { - -static int -attr_compare(const void *p1,const void *p2) -{ - const rtl_uString * pustr = static_cast<const rtl_uString *>(p1); - const char * pc = *static_cast<const char * const *>(p2); - - return rtl_ustr_ascii_compare_WithLength(pustr->buffer, pustr->length, pc); -} - -} - -static void -find_exported_attributes( sal_Int32 *pArray, - const css::uno::Sequence< css::beans::PropertyValue >& rAttributeList ) -{ - for( sal_Int32 i = 0; i < rAttributeList.getLength(); i++ ) - { - const char ** pAttr = static_cast<const char **>(bsearch(rAttributeList[i].Name.pData, - ExportedTextAttributes, TEXT_ATTRIBUTE_LAST, sizeof(const char *), - attr_compare)); - - if( pAttr ) - { - sal_Int32 nIndex = pAttr - ExportedTextAttributes; - pArray[nIndex] = i; - } - } -} - -/*****************************************************************************/ - -static AtkAttributeSet* -attribute_set_prepend( AtkAttributeSet* attribute_set, - AtkTextAttribute attribute, - gchar * value ) -{ - if( value ) - { - AtkAttribute *at = static_cast<AtkAttribute *>(g_malloc( sizeof (AtkAttribute) )); - at->name = g_strdup( atk_text_attribute_get_name( attribute ) ); - at->value = value; - - return g_slist_prepend(attribute_set, at); - } - - return attribute_set; -} - -/*****************************************************************************/ - -AtkAttributeSet* -attribute_set_new_from_property_values( - const uno::Sequence< beans::PropertyValue >& rAttributeList, - bool run_attributes_only, - AtkText *text) -{ - AtkAttributeSet* attribute_set = nullptr; - - sal_Int32 aIndexList[TEXT_ATTRIBUTE_LAST] = { -1 }; - - // Initialize index array with -1 - for(sal_Int32 & rn : aIndexList) - rn = -1; - - find_exported_attributes(aIndexList, rAttributeList); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_BG_COLOR, - get_color_value(rAttributeList, aIndexList, TEXT_ATTRIBUTE_BACKGROUND_COLOR, run_attributes_only ? nullptr : text ) ); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_FG_COLOR, - get_color_value(rAttributeList, aIndexList, TEXT_ATTRIBUTE_FOREGROUND_COLOR, run_attributes_only ? nullptr : text) ); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_INVISIBLE, - get_bool_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_HIDDEN])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_UNDERLINE, - get_underline_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_UNDERLINE])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_STRIKETHROUGH, - get_strikethrough_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_STRIKETHROUGH])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_SIZE, - get_height_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_HEIGHT])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_WEIGHT, - get_weight_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_WEIGHT])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_FAMILY_NAME, - get_string_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_FONT_NAME])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_VARIANT, - get_variant_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_CASEMAP])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_STYLE, - get_style_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_POSTURE])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_SCALE, - get_scale_width(rAttributeList, aIndexList[TEXT_ATTRIBUTE_SCALE])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_LANGUAGE, - get_language_string(rAttributeList, aIndexList[TEXT_ATTRIBUTE_LOCALE])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_DIRECTION, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_WRITING_MODE], WritingMode2Direction)); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_STRETCH, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_KERNING], Kerning2Stretch)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_font_effect ) - atk_text_attribute_font_effect = atk_text_attribute_register("font-effect"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_font_effect, - get_font_effect(rAttributeList, aIndexList[TEXT_ATTRIBUTE_CONTOURED], aIndexList[TEXT_ATTRIBUTE_RELIEF])); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_decoration ) - atk_text_attribute_decoration = atk_text_attribute_register("text-decoration"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_decoration, - get_text_decoration(rAttributeList, aIndexList[TEXT_ATTRIBUTE_BLINKING], - aIndexList[TEXT_ATTRIBUTE_UNDERLINE], aIndexList[TEXT_ATTRIBUTE_STRIKETHROUGH])); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_rotation ) - atk_text_attribute_rotation = atk_text_attribute_register("text-rotation"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_rotation, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_ROTATION], Short2Degree)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_shadow ) - atk_text_attribute_shadow = atk_text_attribute_register("text-shadow"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_shadow, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_SHADOWED], Bool2Shadow)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_writing_mode ) - atk_text_attribute_writing_mode = atk_text_attribute_register("writing-mode"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_writing_mode, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_WRITING_MODE], WritingMode2String)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_vertical_align ) - atk_text_attribute_vertical_align = atk_text_attribute_register("vertical-align"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_vertical_align, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_CHAR_ESCAPEMENT], Escapement2VerticalAlign)); - - if( run_attributes_only ) - return attribute_set; - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_LEFT_MARGIN, - get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_LEFT_MARGIN])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_RIGHT_MARGIN, - get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_RIGHT_MARGIN])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_INDENT, - get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_FIRST_LINE_INDENT])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, - get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_TOP_MARGIN])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, - get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_BOTTOM_MARGIN])); - - attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_JUSTIFICATION, - get_justification_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_JUSTIFICATION])); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_paragraph_style ) - atk_text_attribute_paragraph_style = atk_text_attribute_register("paragraph-style"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_paragraph_style, - get_string_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_STYLE_NAME])); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_line_height ) - atk_text_attribute_line_height = atk_text_attribute_register("line-height"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_line_height, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_LINE_SPACING], LineSpacing2LineHeight)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tab_interval ) - atk_text_attribute_tab_interval = atk_text_attribute_register("tab-interval"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_tab_interval, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_TAB_STOPS], DefaultTabStops2String)); - - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tab_stops ) - atk_text_attribute_tab_stops = atk_text_attribute_register("tab-stops"); - - attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_tab_stops, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_TAB_STOPS], TabStops2String)); - - // #i92233# - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_mm_to_pixel_ratio ) - atk_text_attribute_mm_to_pixel_ratio = atk_text_attribute_register("mm-to-pixel-ratio"); - - attribute_set = attribute_set_prepend( attribute_set, atk_text_attribute_mm_to_pixel_ratio, - get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO], Float2String)); - - return attribute_set; -} - -AtkAttributeSet* -attribute_set_new_from_extended_attributes( - const css::uno::Reference< css::accessibility::XAccessibleExtendedAttributes >& rExtendedAttributes ) -{ - AtkAttributeSet *pSet = nullptr; - - // extended attributes is a string of colon-separated pairs of property and value, - // with pairs separated by semicolons. Example: "heading-level:2;weight:bold;" - uno::Any anyVal = rExtendedAttributes->getExtendedAttributes(); - OUString sExtendedAttrs; - anyVal >>= sExtendedAttrs; - sal_Int32 nIndex = 0; - do - { - OUString sProperty = sExtendedAttrs.getToken( 0, ';', nIndex ); - - sal_Int32 nColonPos = 0; - OString sPropertyName = OUStringToOString( sProperty.getToken( 0, ':', nColonPos ), - RTL_TEXTENCODING_UTF8 ); - OString sPropertyValue = OUStringToOString( sProperty.getToken( 0, ':', nColonPos ), - RTL_TEXTENCODING_UTF8 ); - - pSet = attribute_set_prepend( pSet, - atk_text_attribute_register( sPropertyName.getStr() ), - g_strdup_printf( "%s", sPropertyValue.getStr() ) ); - } - while ( nIndex >= 0 && nIndex < sExtendedAttrs.getLength() ); - - return pSet; -} - -AtkAttributeSet* attribute_set_prepend_misspelled( AtkAttributeSet* attribute_set ) -{ - if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_misspelled ) - atk_text_attribute_misspelled = atk_text_attribute_register( "text-spelling" ); - - attribute_set = attribute_set_prepend( attribute_set, atk_text_attribute_misspelled, - g_strdup_printf( "misspelled" ) ); - - return attribute_set; -} - -// #i92232# -AtkAttributeSet* attribute_set_prepend_tracked_change_insertion( AtkAttributeSet* attribute_set ) -{ - if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) - { - atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); - } - - attribute_set = attribute_set_prepend( attribute_set, - atk_text_attribute_tracked_change, - g_strdup_printf( "insertion" ) ); - - return attribute_set; -} - -AtkAttributeSet* attribute_set_prepend_tracked_change_deletion( AtkAttributeSet* attribute_set ) -{ - if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) - { - atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); - } - - attribute_set = attribute_set_prepend( attribute_set, - atk_text_attribute_tracked_change, - g_strdup_printf( "deletion" ) ); - - return attribute_set; -} - -AtkAttributeSet* attribute_set_prepend_tracked_change_formatchange( AtkAttributeSet* attribute_set ) -{ - if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) - { - atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); - } - - attribute_set = attribute_set_prepend( attribute_set, - atk_text_attribute_tracked_change, - g_strdup_printf( "attribute-change" ) ); - - return attribute_set; -} - -/*****************************************************************************/ - -struct AtkTextAttrMapping -{ - const char * name; - TextPropertyValueFunc const toPropertyValue; -}; - -const AtkTextAttrMapping g_TextAttrMap[] = -{ - { "", InvalidValue }, // ATK_TEXT_ATTR_INVALID = 0 - { "ParaLeftMargin", UnitString2CMM }, // ATK_TEXT_ATTR_LEFT_MARGIN - { "ParaRightMargin", UnitString2CMM }, // ATK_TEXT_ATTR_RIGHT_MARGIN - { "ParaFirstLineIndent", UnitString2CMM }, // ATK_TEXT_ATTR_INDENT - { "CharHidden", String2Bool }, // ATK_TEXT_ATTR_INVISIBLE - { "", InvalidValue }, // ATK_TEXT_ATTR_EDITABLE - { "ParaTopMargin", UnitString2CMM }, // ATK_TEXT_ATTR_PIXELS_ABOVE_LINES - { "ParaBottomMargin", UnitString2CMM }, // ATK_TEXT_ATTR_PIXELS_BELOW_LINES - { "", InvalidValue }, // ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP - { "", InvalidValue }, // ATK_TEXT_ATTR_BG_FULL_HEIGHT - { "", InvalidValue }, // ATK_TEXT_ATTR_RISE - { "CharUnderline", String2Underline }, // ATK_TEXT_ATTR_UNDERLINE - { "CharStrikeout", String2Strikeout }, // ATK_TEXT_ATTR_STRIKETHROUGH - { "CharHeight", String2Float }, // ATK_TEXT_ATTR_SIZE - { "CharScaleWidth", String2Scale }, // ATK_TEXT_ATTR_SCALE - { "CharWeight", String2Weight }, // ATK_TEXT_ATTR_WEIGHT - { "CharLocale", String2Locale }, // ATK_TEXT_ATTR_LANGUAGE - { "CharFontName", SetString }, // ATK_TEXT_ATTR_FAMILY_NAME - { "CharBackColor", String2Color }, // ATK_TEXT_ATTR_BG_COLOR - { "CharColor", String2Color }, // ATK_TEXT_ATTR_FG_COLOR - { "", InvalidValue }, // ATK_TEXT_ATTR_BG_STIPPLE - { "", InvalidValue }, // ATK_TEXT_ATTR_FG_STIPPLE - { "", InvalidValue }, // ATK_TEXT_ATTR_WRAP_MODE - { "", InvalidValue }, // ATK_TEXT_ATTR_DIRECTION - { "ParaAdjust", Justification2Adjust }, // ATK_TEXT_ATTR_JUSTIFICATION - { "", InvalidValue }, // ATK_TEXT_ATTR_STRETCH - { "CharCaseMap", String2CaseMap }, // ATK_TEXT_ATTR_VARIANT - { "CharPosture", Style2FontSlant } // ATK_TEXT_ATTR_STYLE -}; - -/*****************************************************************************/ - -bool -attribute_set_map_to_property_values( - AtkAttributeSet* attribute_set, - uno::Sequence< beans::PropertyValue >& rValueList ) -{ - // Ensure enough space .. - uno::Sequence< beans::PropertyValue > aAttributeList (SAL_N_ELEMENTS(g_TextAttrMap)); - - sal_Int32 nIndex = 0; - for( GSList * item = attribute_set; item != nullptr; item = g_slist_next( item ) ) - { - AtkAttribute* attribute = reinterpret_cast<AtkAttribute *>(item); - - AtkTextAttribute text_attr = atk_text_attribute_for_name( attribute->name ); - if( text_attr < SAL_N_ELEMENTS(g_TextAttrMap) ) - { - if( g_TextAttrMap[text_attr].name[0] != '\0' ) - { - if( ! g_TextAttrMap[text_attr].toPropertyValue( aAttributeList[nIndex].Value, attribute->value) ) - return false; - - aAttributeList[nIndex].Name = OUString::createFromAscii( g_TextAttrMap[text_attr].name ); - aAttributeList[nIndex].State = beans::PropertyState_DIRECT_VALUE; - ++nIndex; - } - } - else - { - // Unsupported text attribute - return false; - } - } - - aAttributeList.realloc( nIndex ); - rValueList = aAttributeList; - return true; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atktextattributes.hxx b/vcl/unx/gtk/a11y/atktextattributes.hxx deleted file mode 100644 index f86c82f4fe09..000000000000 --- a/vcl/unx/gtk/a11y/atktextattributes.hxx +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_VCL_UNX_GTK_A11Y_ATKTEXTATTRIBUTES_HXX -#define INCLUDED_VCL_UNX_GTK_A11Y_ATKTEXTATTRIBUTES_HXX - -#include <com/sun/star/uno/Sequence.hxx> -#include <com/sun/star/beans/PropertyValue.hpp> -#include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp> - -#include <atk/atk.h> - -AtkAttributeSet* -attribute_set_new_from_property_values( - const css::uno::Sequence< css::beans::PropertyValue >& rAttributeList, - bool run_attributes_only, - AtkText *text); - -AtkAttributeSet* -attribute_set_new_from_extended_attributes( - const css::uno::Reference< css::accessibility::XAccessibleExtendedAttributes >& rExtendedAttributes ); - -bool -attribute_set_map_to_property_values( - AtkAttributeSet* attribute_set, - css::uno::Sequence< css::beans::PropertyValue >& rValueList ); - -AtkAttributeSet* attribute_set_prepend_misspelled( AtkAttributeSet* attribute_set ); -// #i92232# -AtkAttributeSet* attribute_set_prepend_tracked_change_insertion( AtkAttributeSet* attribute_set ); -AtkAttributeSet* attribute_set_prepend_tracked_change_deletion( AtkAttributeSet* attribute_set ); -AtkAttributeSet* attribute_set_prepend_tracked_change_formatchange( AtkAttributeSet* attribute_set ); - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkutil.cxx b/vcl/unx/gtk/a11y/atkutil.cxx deleted file mode 100644 index 50ed2793bbf0..000000000000 --- a/vcl/unx/gtk/a11y/atkutil.cxx +++ /dev/null @@ -1,789 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifdef AIX -#define _LINUX_SOURCE_COMPAT -#include <sys/timer.h> -#undef _LINUX_SOURCE_COMPAT -#endif - -#include <com/sun/star/accessibility/XAccessibleContext.hpp> -#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> -#include <com/sun/star/accessibility/XAccessibleSelection.hpp> -#include <com/sun/star/accessibility/AccessibleEventId.hpp> -#include <com/sun/star/accessibility/AccessibleStateType.hpp> -#include <com/sun/star/accessibility/XAccessibleText.hpp> -#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> -#include <cppuhelper/implbase.hxx> -#include <cppuhelper/weakref.hxx> -#include <rtl/ref.hxx> -#include <sal/log.hxx> - -#include <vcl/svapp.hxx> -#include <vcl/window.hxx> -#include <vcl/menu.hxx> -#include <vcl/toolbox.hxx> - -#include <unx/gtk/gtkdata.hxx> -#include "atkwrapper.hxx" -#include "atkutil.hxx" - -#include <gtk/gtk.h> -#include <config_version.h> - -#include <cassert> -#include <set> - -using namespace ::com::sun::star; - -namespace -{ - struct theNextFocusObject : - public rtl::Static< uno::WeakReference< accessibility::XAccessible >, theNextFocusObject> - { - }; -} - -static guint focus_notify_handler = 0; - -/*****************************************************************************/ - -extern "C" { - -static gboolean -atk_wrapper_focus_idle_handler (gpointer data) -{ - SolarMutexGuard aGuard; - - focus_notify_handler = 0; - - uno::Reference< accessibility::XAccessible > xAccessible = theNextFocusObject::get(); - if( xAccessible.get() == static_cast < accessibility::XAccessible * > (data) ) - { - AtkObject *atk_obj = xAccessible.is() ? atk_object_wrapper_ref( xAccessible ) : nullptr; - // Gail does not notify focus changes to NULL, so do we .. - if( atk_obj ) - { - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_focus_tracker_notify(atk_obj); - SAL_WNODEPRECATED_DECLARATIONS_POP - // #i93269# - // emit text_caret_moved event for <XAccessibleText> object, - // if cursor is inside the <XAccessibleText> object. - // also emit state-changed:focused event under the same condition. - { - AtkObjectWrapper* wrapper_obj = ATK_OBJECT_WRAPPER (atk_obj); - if( wrapper_obj && !wrapper_obj->mpText.is() ) - { - wrapper_obj->mpText.set(wrapper_obj->mpContext, css::uno::UNO_QUERY); - if ( wrapper_obj->mpText.is() ) - { - gint caretPos = -1; - - try { - caretPos = wrapper_obj->mpText->getCaretPosition(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCaretPosition()" ); - } - - if ( caretPos != -1 ) - { - atk_object_notify_state_change( atk_obj, ATK_STATE_FOCUSED, TRUE ); - g_signal_emit_by_name( atk_obj, "text_caret_moved", caretPos ); - } - } - } - } - g_object_unref(atk_obj); - } - } - - return false; -} - -} // extern "C" - -/*****************************************************************************/ - -static void -atk_wrapper_focus_tracker_notify_when_idle( const uno::Reference< accessibility::XAccessible > &xAccessible ) -{ - if( focus_notify_handler ) - g_source_remove(focus_notify_handler); - - theNextFocusObject::get() = xAccessible; - - focus_notify_handler = g_idle_add (atk_wrapper_focus_idle_handler, xAccessible.get()); -} - -/*****************************************************************************/ - -class DocumentFocusListener : - public ::cppu::WeakImplHelper< accessibility::XAccessibleEventListener > -{ - - std::set< uno::Reference< uno::XInterface > > m_aRefList; - -public: - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible, - const uno::Reference< accessibility::XAccessibleContext >& xContext - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible, - const uno::Reference< accessibility::XAccessibleContext >& xContext, - const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void detachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void detachRecursive( - const uno::Reference< accessibility::XAccessibleContext >& xContext - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - void detachRecursive( - const uno::Reference< accessibility::XAccessibleContext >& xContext, - const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet - ); - - /// @throws lang::IndexOutOfBoundsException - /// @throws uno::RuntimeException - static uno::Reference< accessibility::XAccessible > getAccessible(const lang::EventObject& aEvent ); - - // XEventListener - virtual void SAL_CALL disposing( const lang::EventObject& Source ) override; - - // XAccessibleEventListener - virtual void SAL_CALL notifyEvent( const accessibility::AccessibleEventObject& aEvent ) override; -}; - -/*****************************************************************************/ - -void DocumentFocusListener::disposing( const lang::EventObject& aEvent ) -{ - - // Unref the object here, but do not remove as listener since the object - // might no longer be in a state that safely allows this. - if( aEvent.Source.is() ) - m_aRefList.erase(aEvent.Source); - -} - -/*****************************************************************************/ - -void DocumentFocusListener::notifyEvent( const accessibility::AccessibleEventObject& aEvent ) -{ - try { - switch( aEvent.EventId ) - { - case accessibility::AccessibleEventId::STATE_CHANGED: - { - sal_Int16 nState = accessibility::AccessibleStateType::INVALID; - aEvent.NewValue >>= nState; - - if( accessibility::AccessibleStateType::FOCUSED == nState ) - atk_wrapper_focus_tracker_notify_when_idle( getAccessible(aEvent) ); - - break; - } - - case accessibility::AccessibleEventId::CHILD: - { - uno::Reference< accessibility::XAccessible > xChild; - if( (aEvent.OldValue >>= xChild) && xChild.is() ) - detachRecursive(xChild); - - if( (aEvent.NewValue >>= xChild) && xChild.is() ) - attachRecursive(xChild); - - break; - } - - case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN: - SAL_INFO("vcl.a11y", "Invalidate all children called"); - break; - - default: - break; - } - } - catch( const lang::IndexOutOfBoundsException& e ) - { - g_warning("Focused object has invalid index in parent"); - } -} - -/*****************************************************************************/ - -uno::Reference< accessibility::XAccessible > DocumentFocusListener::getAccessible(const lang::EventObject& aEvent ) -{ - uno::Reference< accessibility::XAccessible > xAccessible(aEvent.Source, uno::UNO_QUERY); - - if( xAccessible.is() ) - return xAccessible; - - uno::Reference< accessibility::XAccessibleContext > xContext(aEvent.Source, uno::UNO_QUERY); - - if( xContext.is() ) - { - uno::Reference< accessibility::XAccessible > xParent( xContext->getAccessibleParent() ); - if( xParent.is() ) - { - uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() ); - if( xParentContext.is() ) - { - return xParentContext->getAccessibleChild( xContext->getAccessibleIndexInParent() ); - } - } - } - - return uno::Reference< accessibility::XAccessible >(); -} - -/*****************************************************************************/ - -void DocumentFocusListener::attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible -) -{ - uno::Reference< accessibility::XAccessibleContext > xContext = - xAccessible->getAccessibleContext(); - - if( xContext.is() ) - attachRecursive(xAccessible, xContext); -} - -/*****************************************************************************/ - -void DocumentFocusListener::attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible, - const uno::Reference< accessibility::XAccessibleContext >& xContext -) -{ - uno::Reference< accessibility::XAccessibleStateSet > xStateSet = - xContext->getAccessibleStateSet(); - - if( xStateSet.is() ) - attachRecursive(xAccessible, xContext, xStateSet); -} - -/*****************************************************************************/ - -void DocumentFocusListener::attachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible, - const uno::Reference< accessibility::XAccessibleContext >& xContext, - const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet -) -{ - if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED ) ) - atk_wrapper_focus_tracker_notify_when_idle( xAccessible ); - - uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster(xContext, uno::UNO_QUERY); - - if (!xBroadcaster.is()) - return; - - // If not already done, add the broadcaster to the list and attach as listener. - const uno::Reference< uno::XInterface >& xInterface = xBroadcaster; - if( m_aRefList.insert(xInterface).second ) - { - xBroadcaster->addAccessibleEventListener(static_cast< accessibility::XAccessibleEventListener *>(this)); - - if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) ) - { - sal_Int32 n, nmax = xContext->getAccessibleChildCount(); - for( n = 0; n < nmax; n++ ) - { - uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) ); - - if( xChild.is() ) - attachRecursive(xChild); - } - } - } -} - -/*****************************************************************************/ - -void DocumentFocusListener::detachRecursive( - const uno::Reference< accessibility::XAccessible >& xAccessible -) -{ - uno::Reference< accessibility::XAccessibleContext > xContext = - xAccessible->getAccessibleContext(); - - if( xContext.is() ) - detachRecursive(xContext); -} - -/*****************************************************************************/ - -void DocumentFocusListener::detachRecursive( - const uno::Reference< accessibility::XAccessibleContext >& xContext -) -{ - uno::Reference< accessibility::XAccessibleStateSet > xStateSet = - xContext->getAccessibleStateSet(); - - if( xStateSet.is() ) - detachRecursive(xContext, xStateSet); -} - -/*****************************************************************************/ - -void DocumentFocusListener::detachRecursive( - const uno::Reference< accessibility::XAccessibleContext >& xContext, - const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet -) -{ - uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster(xContext, uno::UNO_QUERY); - - if( xBroadcaster.is() && 0 < m_aRefList.erase(xBroadcaster) ) - { - xBroadcaster->removeAccessibleEventListener(static_cast< accessibility::XAccessibleEventListener *>(this)); - - if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) ) - { - sal_Int32 n, nmax = xContext->getAccessibleChildCount(); - for( n = 0; n < nmax; n++ ) - { - uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) ); - - if( xChild.is() ) - detachRecursive(xChild); - } - } - } -} - -/*****************************************************************************/ - -/* - * page tabs in gtk are widgets, so we need to simulate focus events for those - */ - -static void handle_tabpage_activated(vcl::Window *pWindow) -{ - uno::Reference< accessibility::XAccessible > xAccessible = - pWindow->GetAccessible(); - - if( ! xAccessible.is() ) - return; - - uno::Reference< accessibility::XAccessibleSelection > xSelection( - xAccessible->getAccessibleContext(), uno::UNO_QUERY); - - if( xSelection.is() ) - atk_wrapper_focus_tracker_notify_when_idle( xSelection->getSelectedAccessibleChild(0) ); -} - -/*****************************************************************************/ - -/* - * toolbar items in gtk are widgets, so we need to simulate focus events for those - */ - -static void notify_toolbox_item_focus(ToolBox *pToolBox) -{ - uno::Reference< accessibility::XAccessible > xAccessible = - pToolBox->GetAccessible(); - - if( ! xAccessible.is() ) - return; - - uno::Reference< accessibility::XAccessibleContext > xContext = - xAccessible->getAccessibleContext(); - - if( ! xContext.is() ) - return; - - ToolBox::ImplToolItems::size_type nPos = pToolBox->GetItemPos( pToolBox->GetHighlightItemId() ); - if( nPos != ToolBox::ITEM_NOTFOUND ) - atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) ); - //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32 -} - -static void handle_toolbox_highlight(vcl::Window *pWindow) -{ - ToolBox *pToolBox = static_cast <ToolBox *> (pWindow); - - // Make sure either the toolbox or its parent toolbox has the focus - if ( ! pToolBox->HasFocus() ) - { - ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() ); - if ( ! pToolBoxParent || ! pToolBoxParent->HasFocus() ) - return; - } - - notify_toolbox_item_focus(pToolBox); -} - -static void handle_toolbox_highlightoff(vcl::Window const *pWindow) -{ - ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pWindow->GetParent() ); - - // Notify when leaving sub toolboxes - if( pToolBoxParent && pToolBoxParent->HasFocus() ) - notify_toolbox_item_focus( pToolBoxParent ); -} - -/*****************************************************************************/ - -static void create_wrapper_for_child( - const uno::Reference< accessibility::XAccessibleContext >& xContext, - sal_Int32 index) -{ - if( xContext.is() ) - { - uno::Reference< accessibility::XAccessible > xChild(xContext->getAccessibleChild(index)); - if( xChild.is() ) - { - // create the wrapper object - it will survive the unref unless it is a transient object - g_object_unref( atk_object_wrapper_ref( xChild ) ); - } - } -} - -/*****************************************************************************/ - -static void handle_toolbox_buttonchange(VclWindowEvent const *pEvent) -{ - vcl::Window* pWindow = pEvent->GetWindow(); - sal_Int32 index = static_cast<sal_Int32>(reinterpret_cast<sal_IntPtr>(pEvent->GetData())); - - if( pWindow && pWindow->IsReallyVisible() ) - { - uno::Reference< accessibility::XAccessible > xAccessible(pWindow->GetAccessible()); - if( xAccessible.is() ) - { - create_wrapper_for_child(xAccessible->getAccessibleContext(), index); - } - } -} - -/*****************************************************************************/ - -namespace { - -struct WindowList { - ~WindowList() { assert(list.empty()); }; - // needs to be empty already on DeInitVCL, but at least check it's empty - // on exit - - std::set< VclPtr<vcl::Window> > list; -}; - -WindowList g_aWindowList; - -} - -DocumentFocusListener & GtkSalData::GetDocumentFocusListener() -{ - if (!m_pDocumentFocusListener) - { - m_pDocumentFocusListener = new DocumentFocusListener; - m_xDocumentFocusListener.set(m_pDocumentFocusListener); - } - return *m_pDocumentFocusListener; -} - -static void handle_get_focus(::VclWindowEvent const * pEvent) -{ - GtkSalData *const pSalData(GetGtkSalData()); - assert(pSalData); - - DocumentFocusListener & rDocumentFocusListener(pSalData->GetDocumentFocusListener()); - - vcl::Window *pWindow = pEvent->GetWindow(); - - // The menu bar is handled through VclEventId::MenuHighlightED - if( ! pWindow || !pWindow->IsReallyVisible() || pWindow->GetType() == WindowType::MENUBARWINDOW ) - return; - - // ToolBoxes are handled through VclEventId::ToolboxHighlight - if( pWindow->GetType() == WindowType::TOOLBOX ) - return; - - if( pWindow->GetType() == WindowType::TABCONTROL ) - { - handle_tabpage_activated( pWindow ); - return; - } - - uno::Reference< accessibility::XAccessible > xAccessible = - pWindow->GetAccessible(); - - if( ! xAccessible.is() ) - return; - - uno::Reference< accessibility::XAccessibleContext > xContext = - xAccessible->getAccessibleContext(); - - if( ! xContext.is() ) - return; - - uno::Reference< accessibility::XAccessibleStateSet > xStateSet = - xContext->getAccessibleStateSet(); - - if( ! xStateSet.is() ) - return; - -/* the UNO ToolBox wrapper does not (yet?) support XAccessibleSelection, so we - * need to add listeners to the children instead of re-using the tabpage stuff - */ - if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED) && - ( pWindow->GetType() != WindowType::TREELISTBOX ) ) - { - atk_wrapper_focus_tracker_notify_when_idle( xAccessible ); - } - else - { - if( g_aWindowList.list.insert(pWindow).second ) - { - try - { - rDocumentFocusListener.attachRecursive(xAccessible, xContext, xStateSet); - } - catch (const uno::Exception&) - { - g_warning( "Exception caught processing focus events" ); - } - } - } -} - -/*****************************************************************************/ - -static void handle_menu_highlighted(::VclMenuEvent const * pEvent) -{ - try - { - Menu* pMenu = pEvent->GetMenu(); - sal_uInt16 nPos = pEvent->GetItemPos(); - - if( pMenu && nPos != 0xFFFF) - { - uno::Reference< accessibility::XAccessible > xAccessible ( pMenu->GetAccessible() ); - - if( xAccessible.is() ) - { - uno::Reference< accessibility::XAccessibleContext > xContext ( xAccessible->getAccessibleContext() ); - - if( xContext.is() ) - atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) ); - } - } - } - catch (const uno::Exception&) - { - g_warning( "Exception caught processing menu highlight events" ); - } -} - -/*****************************************************************************/ - -static void WindowEventHandler(void *, VclSimpleEvent& rEvent) -{ - try - { - switch (rEvent.GetId()) - { - case VclEventId::WindowShow: - break; - case VclEventId::WindowHide: - break; - case VclEventId::WindowClose: - break; - case VclEventId::WindowGetFocus: - handle_get_focus(static_cast< ::VclWindowEvent const * >(&rEvent)); - break; - case VclEventId::WindowLoseFocus: - break; - case VclEventId::WindowMinimize: - break; - case VclEventId::WindowNormalize: - break; - case VclEventId::WindowKeyInput: - case VclEventId::WindowKeyUp: - case VclEventId::WindowCommand: - case VclEventId::WindowMouseMove: - break; - - case VclEventId::MenuHighlight: - if (const VclMenuEvent* pMenuEvent = dynamic_cast<const VclMenuEvent*>(&rEvent)) - { - handle_menu_highlighted(pMenuEvent); - } - else if (const VclAccessibleEvent* pAccEvent = dynamic_cast<const VclAccessibleEvent*>(&rEvent)) - { - const uno::Reference< accessibility::XAccessible >& xAccessible = pAccEvent->GetAccessible(); - if (xAccessible.is()) - atk_wrapper_focus_tracker_notify_when_idle(xAccessible); - } - break; - - case VclEventId::ToolboxHighlight: - handle_toolbox_highlight(static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow()); - break; - - case VclEventId::ToolboxButtonStateChanged: - handle_toolbox_buttonchange(static_cast< ::VclWindowEvent const * >(&rEvent)); - break; - - case VclEventId::ObjectDying: - g_aWindowList.list.erase( static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow() ); - [[fallthrough]]; - case VclEventId::ToolboxHighlightOff: - handle_toolbox_highlightoff(static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow()); - break; - - case VclEventId::TabpageActivate: - handle_tabpage_activated(static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow()); - break; - - case VclEventId::ComboboxSetText: - // This looks quite strange to me. Stumbled over this when fixing #i104290#. - // This kicked in when leaving the combobox in the toolbar, after that the events worked. - // I guess this was a try to work around missing combobox events, which didn't do the full job, and shouldn't be necessary anymore. - // Fix for #i104290# was done in toolkit/source/awt/vclxaccessiblecomponent, FOCUSED state for compound controls in general. - // create_wrapper_for_children(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); - break; - - default: - break; - } - } - catch (const lang::IndexOutOfBoundsException&) - { - g_warning("Focused object has invalid index in parent"); - } -} - -static Link<VclSimpleEvent&,void> g_aEventListenerLink( nullptr, WindowEventHandler ); - -/*****************************************************************************/ - -extern "C" { - -static const gchar * -ooo_atk_util_get_toolkit_name() -{ - return "VCL"; -} - -/*****************************************************************************/ - -static const gchar * -ooo_atk_util_get_toolkit_version() -{ - return LIBO_VERSION_DOTTED; -} - -/*****************************************************************************/ - -/* - * GObject inheritance - */ - -static void -ooo_atk_util_class_init (AtkUtilClass *) -{ - AtkUtilClass *atk_class; - gpointer data; - - data = g_type_class_peek (ATK_TYPE_UTIL); - atk_class = ATK_UTIL_CLASS (data); - - atk_class->get_toolkit_name = ooo_atk_util_get_toolkit_name; - atk_class->get_toolkit_version = ooo_atk_util_get_toolkit_version; - - ooo_atk_util_ensure_event_listener(); -} - -} // extern "C" - -void ooo_atk_util_ensure_event_listener() -{ - static bool bInited; - if (!bInited) - { - Application::AddEventListener( g_aEventListenerLink ); - bInited = true; - } -} - -GType -ooo_atk_util_get_type() -{ - static GType type = 0; - - if (!type) - { - GType parent_type = g_type_from_name( "GailUtil" ); - - if( ! parent_type ) - { - g_warning( "Unknown type: GailUtil" ); - parent_type = ATK_TYPE_UTIL; - } - - GTypeQuery type_query; - g_type_query( parent_type, &type_query ); - - static const GTypeInfo typeInfo = - { - static_cast<guint16>(type_query.class_size), - nullptr, - nullptr, - reinterpret_cast<GClassInitFunc>(ooo_atk_util_class_init), - nullptr, - nullptr, - static_cast<guint16>(type_query.instance_size), - 0, - nullptr, - nullptr - } ; - - type = g_type_register_static (parent_type, "OOoUtil", &typeInfo, GTypeFlags(0)) ; - } - - return type; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkutil.hxx b/vcl/unx/gtk/a11y/atkutil.hxx deleted file mode 100644 index cb4a005157a0..000000000000 --- a/vcl/unx/gtk/a11y/atkutil.hxx +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_VCL_UNX_GTK_A11Y_ATKUTIL_HXX -#define INCLUDED_VCL_UNX_GTK_A11Y_ATKUTIL_HXX - -#include <atk/atk.h> - -GType ooo_atk_util_get_type(); -void ooo_atk_util_ensure_event_listener(); - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkvalue.cxx b/vcl/unx/gtk/a11y/atkvalue.cxx deleted file mode 100644 index f5e45d3b2556..000000000000 --- a/vcl/unx/gtk/a11y/atkvalue.cxx +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "atkwrapper.hxx" - -#include <com/sun/star/accessibility/XAccessibleValue.hpp> - -#include <string.h> - -using namespace ::com::sun::star; - -/// @throws uno::RuntimeException -static css::uno::Reference<css::accessibility::XAccessibleValue> - getValue( AtkValue *pValue ) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pValue ); - if( pWrap ) - { - if( !pWrap->mpValue.is() ) - { - pWrap->mpValue.set(pWrap->mpContext, css::uno::UNO_QUERY); - } - - return pWrap->mpValue; - } - - return css::uno::Reference<css::accessibility::XAccessibleValue>(); -} - -static void anyToGValue( const uno::Any& aAny, GValue *pValue ) -{ - // FIXME: expand to lots of types etc. - double aDouble=0; - aAny >>= aDouble; - - memset( pValue, 0, sizeof( GValue ) ); - g_value_init( pValue, G_TYPE_DOUBLE ); - g_value_set_double( pValue, aDouble ); -} - -extern "C" { - -static void -value_wrapper_get_current_value( AtkValue *value, - GValue *gval ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleValue> pValue - = getValue( value ); - if( pValue.is() ) - anyToGValue( pValue->getCurrentValue(), gval ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCurrentValue()" ); - } -} - -static void -value_wrapper_get_maximum_value( AtkValue *value, - GValue *gval ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleValue> pValue - = getValue( value ); - if( pValue.is() ) - anyToGValue( pValue->getMaximumValue(), gval ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCurrentValue()" ); - } -} - -static void -value_wrapper_get_minimum_value( AtkValue *value, - GValue *gval ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleValue> pValue - = getValue( value ); - if( pValue.is() ) - anyToGValue( pValue->getMinimumValue(), gval ); - } - catch(const uno::Exception&) { - g_warning( "Exception in getCurrentValue()" ); - } -} - -static gboolean -value_wrapper_set_current_value( AtkValue *value, - const GValue *gval ) -{ - try { - css::uno::Reference<css::accessibility::XAccessibleValue> pValue - = getValue( value ); - if( pValue.is() ) - { - // FIXME - this needs expanding - double aDouble = g_value_get_double( gval ); - return pValue->setCurrentValue( uno::Any(aDouble) ); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getCurrentValue()" ); - } - - return FALSE; -} - -} // extern "C" - -void -valueIfaceInit (AtkValueIface *iface) -{ - g_return_if_fail (iface != nullptr); - - iface->get_current_value = value_wrapper_get_current_value; - iface->get_maximum_value = value_wrapper_get_maximum_value; - iface->get_minimum_value = value_wrapper_get_minimum_value; - iface->set_current_value = value_wrapper_set_current_value; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkwindow.cxx b/vcl/unx/gtk/a11y/atkwindow.cxx deleted file mode 100644 index eb72edf4908c..000000000000 --- a/vcl/unx/gtk/a11y/atkwindow.cxx +++ /dev/null @@ -1,330 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <unx/gtk/gtkframe.hxx> -#include <vcl/svapp.hxx> -#include <vcl/window.hxx> -#include <vcl/popupmenuwindow.hxx> -#include <sal/log.hxx> - -#include "atkwindow.hxx" -#include "atkwrapper.hxx" -#include "atkregistry.hxx" - -#include <com/sun/star/accessibility/AccessibleRole.hpp> - -using namespace ::com::sun::star::accessibility; -using namespace ::com::sun::star::uno; - -extern "C" { - -static void (* window_real_initialize) (AtkObject *obj, gpointer data) = nullptr; -static void (* window_real_finalize) (GObject *obj) = nullptr; - -static void -init_from_window( AtkObject *accessible, vcl::Window const *pWindow ) -{ - static AtkRole aDefaultRole = ATK_ROLE_INVALID; - - // Special role for sub-menu and combo-box popups that are exposed directly - // by their parents already. - if( aDefaultRole == ATK_ROLE_INVALID ) - { - SAL_WNODEPRECATED_DECLARATIONS_PUSH - aDefaultRole = atk_role_register( "redundant object" ); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - - AtkRole role = aDefaultRole; - - // Determine the appropriate role for the GtkWindow - switch( pWindow->GetAccessibleRole() ) - { - case AccessibleRole::ALERT: - role = ATK_ROLE_ALERT; - break; - - case AccessibleRole::DIALOG: - role = ATK_ROLE_DIALOG; - break; - - case AccessibleRole::FRAME: - role = ATK_ROLE_FRAME; - break; - - /* Ignore window objects for sub-menus, combo- and list boxes, - * which are exposed as children of their parents. - */ - case AccessibleRole::WINDOW: - { - WindowType type = WindowType::WINDOW; - bool parentIsMenuFloatingWindow = false; - - vcl::Window *pParent = pWindow->GetParent(); - if( pParent ) { - type = pParent->GetType(); - parentIsMenuFloatingWindow = pParent->IsMenuFloatingWindow(); - } - - if( (WindowType::LISTBOX != type) && (WindowType::COMBOBOX != type) && - (WindowType::MENUBARWINDOW != type) && ! parentIsMenuFloatingWindow ) - { - role = ATK_ROLE_WINDOW; - } - } - break; - - default: - { - vcl::Window *pChild = pWindow->GetWindow(GetWindowType::FirstChild); - if( pChild ) - { - if( WindowType::HELPTEXTWINDOW == pChild->GetType() ) - { - role = ATK_ROLE_TOOL_TIP; - pChild->SetAccessibleRole( AccessibleRole::LABEL ); - accessible->name = g_strdup( OUStringToOString( pChild->GetText(), RTL_TEXTENCODING_UTF8 ).getStr() ); - } - else if ( pWindow->GetType() == WindowType::BORDERWINDOW && pChild->GetType() == WindowType::FLOATINGWINDOW ) - { - PopupMenuFloatingWindow* p = dynamic_cast<PopupMenuFloatingWindow*>(pChild); - if (p && p->IsPopupMenu() && p->GetMenuStackLevel() == 0) - { - // This is a top-level menu popup. Register it. - role = ATK_ROLE_POPUP_MENU; - pChild->SetAccessibleRole( AccessibleRole::POPUP_MENU ); - accessible->name = g_strdup( OUStringToOString( pChild->GetText(), RTL_TEXTENCODING_UTF8 ).getStr() ); - } - } - } - break; - } - } - - accessible->role = role; -} - -/*****************************************************************************/ - -static gboolean -ooo_window_wrapper_clear_focus(gpointer) -{ - SolarMutexGuard aGuard; - SAL_WNODEPRECATED_DECLARATIONS_PUSH - atk_focus_tracker_notify( nullptr ); - SAL_WNODEPRECATED_DECLARATIONS_POP - return false; -} - -/*****************************************************************************/ - -static gboolean -ooo_window_wrapper_real_focus_gtk (GtkWidget *, GdkEventFocus *) -{ - g_idle_add( ooo_window_wrapper_clear_focus, nullptr ); - return false; -} - -static gboolean ooo_tooltip_map( GtkWidget* pToolTip, gpointer ) -{ - AtkObject* pAccessible = gtk_widget_get_accessible( pToolTip ); - if( pAccessible ) - atk_object_notify_state_change( pAccessible, ATK_STATE_SHOWING, TRUE ); - return FALSE; -} - -static gboolean ooo_tooltip_unmap( GtkWidget* pToolTip, gpointer ) -{ - AtkObject* pAccessible = gtk_widget_get_accessible( pToolTip ); - if( pAccessible ) - atk_object_notify_state_change( pAccessible, ATK_STATE_SHOWING, FALSE ); - return FALSE; -} - -/*****************************************************************************/ - -static bool -isChildPopupMenu(vcl::Window* pWindow) -{ - vcl::Window* pChild = pWindow->GetAccessibleChildWindow(0); - if (!pChild) - return false; - - if (WindowType::FLOATINGWINDOW != pChild->GetType()) - return false; - - PopupMenuFloatingWindow* p = dynamic_cast<PopupMenuFloatingWindow*>(pChild); - if (!p) - return false; - - return p->IsPopupMenu(); -} - -static void -ooo_window_wrapper_real_initialize(AtkObject *obj, gpointer data) -{ - window_real_initialize(obj, data); - - GtkSalFrame *pFrame = GtkSalFrame::getFromWindow( GTK_WINDOW( data ) ); - if( pFrame ) - { - vcl::Window *pWindow = pFrame->GetWindow(); - if( pWindow ) - { - init_from_window( obj, pWindow ); - - Reference< XAccessible > xAccessible( pWindow->GetAccessible() ); - - /* We need the wrapper object for the top-level XAccessible to be - * in the wrapper registry when atk traverses the hierarchy up on - * focus events - */ - if( WindowType::BORDERWINDOW == pWindow->GetType() ) - { - if ( isChildPopupMenu(pWindow) ) - { - AtkObject *child = atk_object_wrapper_new( xAccessible, obj ); - ooo_wrapper_registry_add( xAccessible, child ); - } - else - { - ooo_wrapper_registry_add( xAccessible, obj ); - g_object_set_data( G_OBJECT(obj), "ooo:atk-wrapper-key", xAccessible.get() ); - } - } - else - { - AtkObject *child = atk_object_wrapper_new( xAccessible, obj ); - child->role = ATK_ROLE_FILLER; - if( (ATK_ROLE_DIALOG == obj->role) || (ATK_ROLE_ALERT == obj->role) ) - child->role = ATK_ROLE_OPTION_PANE; - ooo_wrapper_registry_add( xAccessible, child ); - } - } - } - - g_signal_connect_after( GTK_WIDGET( data ), "focus-out-event", - G_CALLBACK (ooo_window_wrapper_real_focus_gtk), - nullptr); - - if( obj->role == ATK_ROLE_TOOL_TIP ) - { - g_signal_connect_after( GTK_WIDGET( data ), "map-event", - G_CALLBACK (ooo_tooltip_map), - nullptr); - g_signal_connect_after( GTK_WIDGET( data ), "unmap-event", - G_CALLBACK (ooo_tooltip_unmap), - nullptr); - } -} - -/*****************************************************************************/ - -static void -ooo_window_wrapper_real_finalize (GObject *obj) -{ - ooo_wrapper_registry_remove( static_cast<XAccessible *>(g_object_get_data( obj, "ooo:atk-wrapper-key" ))); - window_real_finalize( obj ); -} - -/*****************************************************************************/ - -static void -ooo_window_wrapper_class_init (AtkObjectClass *klass, gpointer) -{ - AtkObjectClass *atk_class; - GObjectClass *gobject_class; - gpointer data; - - /* - * Patch the gobject vtable of GailWindow to refer to our instance of - * "initialize". - */ - - data = g_type_class_peek_parent( klass ); - atk_class = ATK_OBJECT_CLASS (data); - - window_real_initialize = atk_class->initialize; - atk_class->initialize = ooo_window_wrapper_real_initialize; - - gobject_class = G_OBJECT_CLASS (data); - - window_real_finalize = gobject_class->finalize; - gobject_class->finalize = ooo_window_wrapper_real_finalize; -} - -} // extern "C" - -/*****************************************************************************/ - -GType -ooo_window_wrapper_get_type() -{ - static GType type = 0; - - if (!type) - { - GType parent_type = g_type_from_name( "GailWindow" ); - - if( ! parent_type ) - { - SAL_INFO("vcl.a11y", "Unknown type: GailWindow"); - parent_type = ATK_TYPE_OBJECT; - } - - GTypeQuery type_query; - g_type_query( parent_type, &type_query ); - - static const GTypeInfo typeInfo = - { - static_cast<guint16>(type_query.class_size), - nullptr, - nullptr, - reinterpret_cast<GClassInitFunc>(ooo_window_wrapper_class_init), - nullptr, - nullptr, - static_cast<guint16>(type_query.instance_size), - 0, - nullptr, - nullptr - } ; - - type = g_type_register_static (parent_type, "OOoWindowAtkObject", &typeInfo, GTypeFlags(0)) ; - } - - return type; -} - -void restore_gail_window_vtable() -{ - AtkObjectClass *atk_class; - gpointer data; - - GType type = g_type_from_name( "GailWindow" ); - - if( type == G_TYPE_INVALID ) - return; - - data = g_type_class_peek( type ); - atk_class = ATK_OBJECT_CLASS (data); - - atk_class->initialize = window_real_initialize; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkwindow.hxx b/vcl/unx/gtk/a11y/atkwindow.hxx deleted file mode 100644 index 35a4bcedf486..000000000000 --- a/vcl/unx/gtk/a11y/atkwindow.hxx +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_VCL_UNX_GTK_A11Y_ATKWINDOW_HXX -#define INCLUDED_VCL_UNX_GTK_A11Y_ATKWINDOW_HXX - -#include <atk/atk.h> - -GType ooo_window_wrapper_get_type(); -void restore_gail_window_vtable(); - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkwrapper.cxx b/vcl/unx/gtk/a11y/atkwrapper.cxx deleted file mode 100644 index cd439022cf2a..000000000000 --- a/vcl/unx/gtk/a11y/atkwrapper.cxx +++ /dev/null @@ -1,959 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <com/sun/star/uno/Any.hxx> -#include <com/sun/star/uno/Type.hxx> -#include <com/sun/star/uno/Sequence.hxx> -#include <com/sun/star/accessibility/AccessibleRole.hpp> -#include <com/sun/star/accessibility/AccessibleRelation.hpp> -#include <com/sun/star/accessibility/AccessibleRelationType.hpp> -#include <com/sun/star/accessibility/AccessibleStateType.hpp> -#include <com/sun/star/accessibility/XAccessible.hpp> -#include <com/sun/star/accessibility/XAccessibleText.hpp> -#include <com/sun/star/accessibility/XAccessibleTextMarkup.hpp> -#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp> -#include <com/sun/star/accessibility/XAccessibleValue.hpp> -#include <com/sun/star/accessibility/XAccessibleAction.hpp> -#include <com/sun/star/accessibility/XAccessibleContext.hpp> -#include <com/sun/star/accessibility/XAccessibleContext2.hpp> -#include <com/sun/star/accessibility/XAccessibleComponent.hpp> -#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> -#include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp> -#include <com/sun/star/accessibility/XAccessibleStateSet.hpp> -#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp> -#include <com/sun/star/accessibility/XAccessibleTable.hpp> -#include <com/sun/star/accessibility/XAccessibleEditableText.hpp> -#include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp> -#include <com/sun/star/accessibility/XAccessibleImage.hpp> -#include <com/sun/star/accessibility/XAccessibleHyperlink.hpp> -#include <com/sun/star/accessibility/XAccessibleHypertext.hpp> -#include <com/sun/star/accessibility/XAccessibleSelection.hpp> -#include <com/sun/star/awt/XExtendedToolkit.hpp> -#include <com/sun/star/awt/XTopWindow.hpp> -#include <com/sun/star/awt/XTopWindowListener.hpp> -#include <com/sun/star/awt/XWindow.hpp> -#include <com/sun/star/lang/XComponent.hpp> -#include <com/sun/star/lang/XServiceInfo.hpp> -#include <com/sun/star/lang/XInitialization.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/lang/XSingleServiceFactory.hpp> -#include <com/sun/star/beans/Property.hpp> - -#include <rtl/ref.hxx> -#include <rtl/strbuf.hxx> -#include <osl/diagnose.h> -#include <cppuhelper/factory.hxx> -#include <cppuhelper/queryinterface.hxx> - -#include "atkwrapper.hxx" -#include "atkregistry.hxx" -#include "atklistener.hxx" -#include "atktextattributes.hxx" - -#include <string.h> -#include <vector> - -using namespace ::com::sun::star; - -static GObjectClass *parent_class = nullptr; - -static AtkRelationType mapRelationType( sal_Int16 nRelation ) -{ - AtkRelationType type = ATK_RELATION_NULL; - - switch( nRelation ) - { - case accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM: - type = ATK_RELATION_FLOWS_FROM; - break; - - case accessibility::AccessibleRelationType::CONTENT_FLOWS_TO: - type = ATK_RELATION_FLOWS_TO; - break; - - case accessibility::AccessibleRelationType::CONTROLLED_BY: - type = ATK_RELATION_CONTROLLED_BY; - break; - - case accessibility::AccessibleRelationType::CONTROLLER_FOR: - type = ATK_RELATION_CONTROLLER_FOR; - break; - - case accessibility::AccessibleRelationType::LABEL_FOR: - type = ATK_RELATION_LABEL_FOR; - break; - - case accessibility::AccessibleRelationType::LABELED_BY: - type = ATK_RELATION_LABELLED_BY; - break; - - case accessibility::AccessibleRelationType::MEMBER_OF: - type = ATK_RELATION_MEMBER_OF; - break; - - case accessibility::AccessibleRelationType::SUB_WINDOW_OF: - type = ATK_RELATION_SUBWINDOW_OF; - break; - - case accessibility::AccessibleRelationType::NODE_CHILD_OF: - type = ATK_RELATION_NODE_CHILD_OF; - break; - - default: - break; - } - - return type; -} - -AtkStateType mapAtkState( sal_Int16 nState ) -{ - AtkStateType type = ATK_STATE_INVALID; - - // A perfect / complete mapping ... - switch( nState ) - { -#define MAP_DIRECT( a ) \ - case accessibility::AccessibleStateType::a: \ - type = ATK_STATE_##a; break - - MAP_DIRECT( INVALID ); - MAP_DIRECT( ACTIVE ); - MAP_DIRECT( ARMED ); - MAP_DIRECT( BUSY ); - MAP_DIRECT( CHECKED ); - MAP_DIRECT( EDITABLE ); - MAP_DIRECT( ENABLED ); - MAP_DIRECT( EXPANDABLE ); - MAP_DIRECT( EXPANDED ); - MAP_DIRECT( FOCUSABLE ); - MAP_DIRECT( FOCUSED ); - MAP_DIRECT( HORIZONTAL ); - MAP_DIRECT( ICONIFIED ); - MAP_DIRECT( INDETERMINATE ); - MAP_DIRECT( MANAGES_DESCENDANTS ); - MAP_DIRECT( MODAL ); - MAP_DIRECT( MULTI_LINE ); - MAP_DIRECT( OPAQUE ); - MAP_DIRECT( PRESSED ); - MAP_DIRECT( RESIZABLE ); - MAP_DIRECT( SELECTABLE ); - MAP_DIRECT( SELECTED ); - MAP_DIRECT( SENSITIVE ); - MAP_DIRECT( SHOWING ); - MAP_DIRECT( SINGLE_LINE ); - MAP_DIRECT( STALE ); - MAP_DIRECT( TRANSIENT ); - MAP_DIRECT( VERTICAL ); - MAP_DIRECT( VISIBLE ); - MAP_DIRECT( DEFAULT ); - // a spelling error ... - case accessibility::AccessibleStateType::DEFUNC: - type = ATK_STATE_DEFUNCT; break; - case accessibility::AccessibleStateType::MULTI_SELECTABLE: - type = ATK_STATE_MULTISELECTABLE; break; - default: - //Mis-use ATK_STATE_LAST_DEFINED to check if a state is unmapped - //NOTE! Do not report it - type = ATK_STATE_LAST_DEFINED; - break; - } - - return type; -} - -static AtkRole getRoleForName( const gchar * name ) -{ - AtkRole ret = atk_role_for_name( name ); - if( ATK_ROLE_INVALID == ret ) - { - // this should only happen in old ATK versions - SAL_WNODEPRECATED_DECLARATIONS_PUSH - ret = atk_role_register( name ); - SAL_WNODEPRECATED_DECLARATIONS_POP - } - - return ret; -} - -static AtkRole mapToAtkRole( sal_Int16 nRole ) -{ - AtkRole role = ATK_ROLE_UNKNOWN; - - static AtkRole roleMap[] = { - ATK_ROLE_UNKNOWN, - ATK_ROLE_ALERT, - ATK_ROLE_COLUMN_HEADER, - ATK_ROLE_CANVAS, - ATK_ROLE_CHECK_BOX, - ATK_ROLE_CHECK_MENU_ITEM, - ATK_ROLE_COLOR_CHOOSER, - ATK_ROLE_COMBO_BOX, - ATK_ROLE_DATE_EDITOR, - ATK_ROLE_DESKTOP_ICON, - ATK_ROLE_DESKTOP_FRAME, // ? pane - ATK_ROLE_DIRECTORY_PANE, - ATK_ROLE_DIALOG, - ATK_ROLE_UNKNOWN, // DOCUMENT - registered below - ATK_ROLE_UNKNOWN, // EMBEDDED_OBJECT - registered below - ATK_ROLE_UNKNOWN, // END_NOTE - registered below - ATK_ROLE_FILE_CHOOSER, - ATK_ROLE_FILLER, - ATK_ROLE_FONT_CHOOSER, - ATK_ROLE_FOOTER, - ATK_ROLE_UNKNOWN, // FOOTNOTE - registered below - ATK_ROLE_FRAME, - ATK_ROLE_GLASS_PANE, - ATK_ROLE_IMAGE, // GRAPHIC - ATK_ROLE_UNKNOWN, // GROUP_BOX - registered below - ATK_ROLE_HEADER, - ATK_ROLE_HEADING, - ATK_ROLE_TEXT, // HYPER_LINK - registered below - ATK_ROLE_ICON, - ATK_ROLE_INTERNAL_FRAME, - ATK_ROLE_LABEL, - ATK_ROLE_LAYERED_PANE, - ATK_ROLE_LIST, - ATK_ROLE_LIST_ITEM, - ATK_ROLE_MENU, - ATK_ROLE_MENU_BAR, - ATK_ROLE_MENU_ITEM, - ATK_ROLE_OPTION_PANE, - ATK_ROLE_PAGE_TAB, - ATK_ROLE_PAGE_TAB_LIST, - ATK_ROLE_PANEL, - ATK_ROLE_PARAGRAPH, - ATK_ROLE_PASSWORD_TEXT, - ATK_ROLE_POPUP_MENU, - ATK_ROLE_PUSH_BUTTON, - ATK_ROLE_PROGRESS_BAR, - ATK_ROLE_RADIO_BUTTON, - ATK_ROLE_RADIO_MENU_ITEM, - ATK_ROLE_ROW_HEADER, - ATK_ROLE_ROOT_PANE, - ATK_ROLE_SCROLL_BAR, - ATK_ROLE_SCROLL_PANE, - ATK_ROLE_PANEL, // SHAPE - ATK_ROLE_SEPARATOR, - ATK_ROLE_SLIDER, - ATK_ROLE_SPIN_BUTTON, // SPIN_BOX ? - ATK_ROLE_SPLIT_PANE, - ATK_ROLE_STATUSBAR, - ATK_ROLE_TABLE, - ATK_ROLE_TABLE_CELL, - ATK_ROLE_TEXT, - ATK_ROLE_PANEL, // TEXT_FRAME - ATK_ROLE_TOGGLE_BUTTON, - ATK_ROLE_TOOL_BAR, - ATK_ROLE_TOOL_TIP, - ATK_ROLE_TREE, - ATK_ROLE_VIEWPORT, - ATK_ROLE_WINDOW, - ATK_ROLE_PUSH_BUTTON, // BUTTON_DROPDOWN - ATK_ROLE_PUSH_BUTTON, // BUTTON_MENU - ATK_ROLE_UNKNOWN, // CAPTION - registered below - ATK_ROLE_UNKNOWN, // CHART - registered below - ATK_ROLE_UNKNOWN, // EDIT_BAR - registered below - ATK_ROLE_UNKNOWN, // FORM - registered below - ATK_ROLE_UNKNOWN, // IMAGE_MAP - registered below - ATK_ROLE_UNKNOWN, // NOTE - registered below - ATK_ROLE_UNKNOWN, // PAGE - registered below - ATK_ROLE_RULER, - ATK_ROLE_UNKNOWN, // SECTION - registered below - ATK_ROLE_UNKNOWN, // TREE_ITEM - registered below - ATK_ROLE_TREE_TABLE, - ATK_ROLE_SCROLL_PANE, // COMMENT - mapped to atk_role_scroll_pane - ATK_ROLE_UNKNOWN // COMMENT_END - mapped to atk_role_unknown -#if defined(ATK_CHECK_VERSION) - //older ver that doesn't define ATK_CHECK_VERSION doesn't have the following - , ATK_ROLE_DOCUMENT_PRESENTATION - , ATK_ROLE_DOCUMENT_SPREADSHEET - , ATK_ROLE_DOCUMENT_TEXT -#if ATK_CHECK_VERSION(2,15,2) - , ATK_ROLE_STATIC -#else - , ATK_ROLE_LABEL -#endif -#else - //older version should fallback to DOCUMENT_FRAME role - , ATK_ROLE_DOCUMENT_FRAME - , ATK_ROLE_DOCUMENT_FRAME - , ATK_ROLE_DOCUMENT_FRAME - , ATK_ROLE_LABEL -#endif - }; - - static bool initialized = false; - - if( ! initialized ) - { - // the accessible roles below were added to ATK in later versions, - // with role_for_name we will know if they exist in runtime. - roleMap[accessibility::AccessibleRole::EDIT_BAR] = getRoleForName("edit bar"); - roleMap[accessibility::AccessibleRole::EMBEDDED_OBJECT] = getRoleForName("embedded"); - roleMap[accessibility::AccessibleRole::CHART] = getRoleForName("chart"); - roleMap[accessibility::AccessibleRole::CAPTION] = getRoleForName("caption"); - roleMap[accessibility::AccessibleRole::DOCUMENT] = getRoleForName("document frame"); - roleMap[accessibility::AccessibleRole::PAGE] = getRoleForName("page"); - roleMap[accessibility::AccessibleRole::SECTION] = getRoleForName("section"); - roleMap[accessibility::AccessibleRole::FORM] = getRoleForName("form"); - roleMap[accessibility::AccessibleRole::GROUP_BOX] = getRoleForName("grouping"); - roleMap[accessibility::AccessibleRole::COMMENT] = getRoleForName("comment"); - roleMap[accessibility::AccessibleRole::IMAGE_MAP] = getRoleForName("image map"); - roleMap[accessibility::AccessibleRole::TREE_ITEM] = getRoleForName("tree item"); - roleMap[accessibility::AccessibleRole::HYPER_LINK] = getRoleForName("link"); - roleMap[accessibility::AccessibleRole::END_NOTE] = getRoleForName("footnote"); - roleMap[accessibility::AccessibleRole::FOOTNOTE] = getRoleForName("footnote"); - roleMap[accessibility::AccessibleRole::NOTE] = getRoleForName("comment"); - - initialized = true; - } - - static const sal_Int32 nMapSize = SAL_N_ELEMENTS(roleMap); - if( 0 <= nRole && nMapSize > nRole ) - role = roleMap[nRole]; - - return role; -} - -/*****************************************************************************/ - -extern "C" { - -/*****************************************************************************/ - -static const gchar* -wrapper_get_name( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - - if( obj->mpContext.is() ) - { - try { - OString aName = - OUStringToOString( - obj->mpContext->getAccessibleName(), - RTL_TEXTENCODING_UTF8); - - int nCmp = atk_obj->name ? rtl_str_compare( atk_obj->name, aName.getStr() ) : -1; - if( nCmp != 0 ) - { - if( atk_obj->name ) - g_free(atk_obj->name); - atk_obj->name = g_strdup(aName.getStr()); - } - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleName()" ); - } - } - - return ATK_OBJECT_CLASS (parent_class)->get_name(atk_obj); -} - -/*****************************************************************************/ - -static const gchar* -wrapper_get_description( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - - if( obj->mpContext.is() ) - { - try { - OString aDescription = - OUStringToOString( - obj->mpContext->getAccessibleDescription(), - RTL_TEXTENCODING_UTF8); - - g_free(atk_obj->description); - atk_obj->description = g_strdup(aDescription.getStr()); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleDescription()" ); - } - } - - return ATK_OBJECT_CLASS (parent_class)->get_description(atk_obj); - -} - -/*****************************************************************************/ - -static AtkAttributeSet * -wrapper_get_attributes( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER( atk_obj ); - AtkAttributeSet *pSet = nullptr; - - try - { - uno::Reference< accessibility::XAccessibleExtendedAttributes > - xExtendedAttrs( obj->mpContext, uno::UNO_QUERY ); - if( xExtendedAttrs.is() ) - pSet = attribute_set_new_from_extended_attributes( xExtendedAttrs ); - } - catch(const uno::Exception&) - { - g_warning( "Exception in getAccessibleAttributes()" ); - } - - return pSet; -} - -/*****************************************************************************/ - -static gint -wrapper_get_n_children( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - gint n = 0; - - if( obj->mpContext.is() ) - { - try { - n = obj->mpContext->getAccessibleChildCount(); - } - catch(const uno::Exception&) { - OSL_FAIL("Exception in getAccessibleChildCount()" ); - } - } - - return n; -} - -/*****************************************************************************/ - -static AtkObject * -wrapper_ref_child( AtkObject *atk_obj, - gint i ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - AtkObject* child = nullptr; - - // see comments above atk_object_wrapper_remove_child - if( -1 < i && obj->index_of_child_about_to_be_removed == i ) - { - g_object_ref( obj->child_about_to_be_removed ); - return obj->child_about_to_be_removed; - } - - if( obj->mpContext.is() ) - { - try { - uno::Reference< accessibility::XAccessible > xAccessible = - obj->mpContext->getAccessibleChild( i ); - - child = atk_object_wrapper_ref( xAccessible ); - } - catch(const uno::Exception&) { - OSL_FAIL("Exception in getAccessibleChild"); - } - } - - return child; -} - -/*****************************************************************************/ - -static gint -wrapper_get_index_in_parent( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y - if (obj->mpOrig) - return atk_object_get_index_in_parent(obj->mpOrig); - - gint i = -1; - - if( obj->mpContext.is() ) - { - try { - i = obj->mpContext->getAccessibleIndexInParent(); - } - catch(const uno::Exception&) { - g_warning( "Exception in getAccessibleIndexInParent()" ); - } - } - return i; -} - -/*****************************************************************************/ - -AtkRelation* -atk_object_wrapper_relation_new(const accessibility::AccessibleRelation& rRelation) -{ - sal_uInt32 nTargetCount = rRelation.TargetSet.getLength(); - - std::vector<AtkObject*> aTargets; - - for (const auto& rTarget : rRelation.TargetSet) - { - uno::Reference< accessibility::XAccessible > xAccessible( rTarget, uno::UNO_QUERY ); - aTargets.push_back(atk_object_wrapper_ref(xAccessible)); - } - - AtkRelation *pRel = - atk_relation_new( - aTargets.data(), nTargetCount, - mapRelationType( rRelation.RelationType ) - ); - - return pRel; -} - -static AtkRelationSet * -wrapper_ref_relation_set( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - - //if we're a native GtkDrawingArea with custom a11y, use the default toolkit relation set impl - if (obj->mpOrig) - return atk_object_ref_relation_set(obj->mpOrig); - - AtkRelationSet *pSet = atk_relation_set_new(); - - if( obj->mpContext.is() ) - { - try { - uno::Reference< accessibility::XAccessibleRelationSet > xRelationSet( - obj->mpContext->getAccessibleRelationSet() - ); - - sal_Int32 nRelations = xRelationSet.is() ? xRelationSet->getRelationCount() : 0; - for( sal_Int32 n = 0; n < nRelations; n++ ) - { - AtkRelation *pRel = atk_object_wrapper_relation_new(xRelationSet->getRelation(n)); - atk_relation_set_add(pSet, pRel); - g_object_unref(pRel); - } - } - catch(const uno::Exception &) { - g_object_unref( G_OBJECT( pSet ) ); - pSet = nullptr; - } - } - - return pSet; -} - -static AtkStateSet * -wrapper_ref_state_set( AtkObject *atk_obj ) -{ - AtkObjectWrapper *obj = ATK_OBJECT_WRAPPER (atk_obj); - AtkStateSet *pSet = atk_state_set_new(); - - if( obj->mpContext.is() ) - { - try { - uno::Reference< accessibility::XAccessibleStateSet > xStateSet( - obj->mpContext->getAccessibleStateSet()); - - if( xStateSet.is() ) - { - uno::Sequence< sal_Int16 > aStates = xStateSet->getStates(); - - for( const auto nState : aStates ) - { - // ATK_STATE_LAST_DEFINED is used to check if the state - // is unmapped, do not report it to Atk - if ( mapAtkState( nState ) != ATK_STATE_LAST_DEFINED ) - atk_state_set_add_state( pSet, mapAtkState( nState ) ); - } - - // We need to emulate FOCUS state for menus, menu-items etc. - if( atk_obj == atk_get_focus_object() ) - atk_state_set_add_state( pSet, ATK_STATE_FOCUSED ); -/* FIXME - should we do this ? - else - atk_state_set_remove_state( pSet, ATK_STATE_FOCUSED ); -*/ - } - } - - catch(const uno::Exception &) { - g_warning( "Exception in wrapper_ref_state_set" ); - atk_state_set_add_state( pSet, ATK_STATE_DEFUNCT ); - } - } - else - atk_state_set_add_state( pSet, ATK_STATE_DEFUNCT ); - - return pSet; -} - -/*****************************************************************************/ - -static void -atk_object_wrapper_finalize (GObject *obj) -{ - AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER (obj); - - if( pWrap->mpAccessible.is() ) - { - ooo_wrapper_registry_remove( pWrap->mpAccessible ); - pWrap->mpAccessible.clear(); - } - - atk_object_wrapper_dispose( pWrap ); - - parent_class->finalize( obj ); -} - -static void -atk_object_wrapper_class_init (AtkObjectWrapperClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS( klass ); - AtkObjectClass *atk_class = ATK_OBJECT_CLASS( klass ); - - parent_class = static_cast<GObjectClass *>(g_type_class_peek_parent (klass)); - - // GObject methods - gobject_class->finalize = atk_object_wrapper_finalize; - - // AtkObject methods - atk_class->get_name = wrapper_get_name; - atk_class->get_description = wrapper_get_description; - atk_class->get_attributes = wrapper_get_attributes; - atk_class->get_n_children = wrapper_get_n_children; - atk_class->ref_child = wrapper_ref_child; - atk_class->get_index_in_parent = wrapper_get_index_in_parent; - atk_class->ref_relation_set = wrapper_ref_relation_set; - atk_class->ref_state_set = wrapper_ref_state_set; -} - -static void -atk_object_wrapper_init (AtkObjectWrapper *wrapper, - AtkObjectWrapperClass*) -{ - wrapper->mpAction = nullptr; - wrapper->mpComponent = nullptr; - wrapper->mpEditableText = nullptr; - wrapper->mpHypertext = nullptr; - wrapper->mpImage = nullptr; - wrapper->mpSelection = nullptr; - wrapper->mpTable = nullptr; - wrapper->mpText = nullptr; - wrapper->mpValue = nullptr; -} - -} // extern "C" - -GType -atk_object_wrapper_get_type() -{ - static GType type = 0; - - if (!type) - { - static const GTypeInfo typeInfo = - { - sizeof (AtkObjectWrapperClass), - nullptr, - nullptr, - reinterpret_cast<GClassInitFunc>(atk_object_wrapper_class_init), - nullptr, - nullptr, - sizeof (AtkObjectWrapper), - 0, - reinterpret_cast<GInstanceInitFunc>(atk_object_wrapper_init), - nullptr - } ; - type = g_type_register_static (ATK_TYPE_OBJECT, - "OOoAtkObj", - &typeInfo, GTypeFlags(0)) ; - } - return type; -} - -static bool -isOfType( uno::XInterface *pInterface, const uno::Type & rType ) -{ - g_return_val_if_fail( pInterface != nullptr, false ); - - bool bIs = false; - try { - uno::Any aRet = pInterface->queryInterface( rType ); - - bIs = ( ( typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass ) && - ( aRet.pReserved != nullptr ) ); - } catch( const uno::Exception &) { } - - return bIs; -} - -extern "C" { -typedef GType (* GetGIfaceType ) (); -} -const struct { - const char *name; - GInterfaceInitFunc const aInit; - GetGIfaceType const aGetGIfaceType; - const uno::Type & (*aGetUnoType) (); -} aTypeTable[] = { -// re-location heaven: - { - "Comp", reinterpret_cast<GInterfaceInitFunc>(componentIfaceInit), - atk_component_get_type, - cppu::UnoType<accessibility::XAccessibleComponent>::get - }, - { - "Act", reinterpret_cast<GInterfaceInitFunc>(actionIfaceInit), - atk_action_get_type, - cppu::UnoType<accessibility::XAccessibleAction>::get - }, - { - "Txt", reinterpret_cast<GInterfaceInitFunc>(textIfaceInit), - atk_text_get_type, - cppu::UnoType<accessibility::XAccessibleText>::get - }, - { - "Val", reinterpret_cast<GInterfaceInitFunc>(valueIfaceInit), - atk_value_get_type, - cppu::UnoType<accessibility::XAccessibleValue>::get - }, - { - "Tab", reinterpret_cast<GInterfaceInitFunc>(tableIfaceInit), - atk_table_get_type, - cppu::UnoType<accessibility::XAccessibleTable>::get - }, - { - "Edt", reinterpret_cast<GInterfaceInitFunc>(editableTextIfaceInit), - atk_editable_text_get_type, - cppu::UnoType<accessibility::XAccessibleEditableText>::get - }, - { - "Img", reinterpret_cast<GInterfaceInitFunc>(imageIfaceInit), - atk_image_get_type, - cppu::UnoType<accessibility::XAccessibleImage>::get - }, - { - "Hyp", reinterpret_cast<GInterfaceInitFunc>(hypertextIfaceInit), - atk_hypertext_get_type, - cppu::UnoType<accessibility::XAccessibleHypertext>::get - }, - { - "Sel", reinterpret_cast<GInterfaceInitFunc>(selectionIfaceInit), - atk_selection_get_type, - cppu::UnoType<accessibility::XAccessibleSelection>::get - } - // AtkDocument is a nastily broken interface (so far) - // we could impl. get_document_type perhaps though. -}; - -const int aTypeTableSize = G_N_ELEMENTS( aTypeTable ); - -static GType -ensureTypeFor( uno::XInterface *pAccessible ) -{ - int i; - bool bTypes[ aTypeTableSize ] = { false, }; - OStringBuffer aTypeNameBuf( "OOoAtkObj" ); - - for( i = 0; i < aTypeTableSize; i++ ) - { - if( isOfType( pAccessible, aTypeTable[i].aGetUnoType() ) ) - { - aTypeNameBuf.append(aTypeTable[i].name); - bTypes[i] = true; - } - } - - OString aTypeName = aTypeNameBuf.makeStringAndClear(); - GType nType = g_type_from_name( aTypeName.getStr() ); - if( nType == G_TYPE_INVALID ) - { - GTypeInfo aTypeInfo = { - sizeof( AtkObjectWrapperClass ), - nullptr, nullptr, nullptr, nullptr, nullptr, - sizeof( AtkObjectWrapper ), - 0, nullptr, nullptr - } ; - nType = g_type_register_static( ATK_TYPE_OBJECT_WRAPPER, - aTypeName.getStr(), &aTypeInfo, - GTypeFlags(0) ) ; - - for( int j = 0; j < aTypeTableSize; j++ ) - if( bTypes[j] ) - { - GInterfaceInfo aIfaceInfo = { nullptr, nullptr, nullptr }; - aIfaceInfo.interface_init = aTypeTable[j].aInit; - g_type_add_interface_static (nType, aTypeTable[j].aGetGIfaceType(), - &aIfaceInfo); - } - } - return nType; -} - -AtkObject * -atk_object_wrapper_ref( const uno::Reference< accessibility::XAccessible > &rxAccessible, bool create ) -{ - g_return_val_if_fail( rxAccessible.get() != nullptr, nullptr ); - - AtkObject *obj = ooo_wrapper_registry_get(rxAccessible); - if( obj ) - { - g_object_ref( obj ); - return obj; - } - - if( create ) - return atk_object_wrapper_new( rxAccessible ); - - return nullptr; -} - -AtkObject * -atk_object_wrapper_new( const css::uno::Reference< css::accessibility::XAccessible >& rxAccessible, - AtkObject* parent, AtkObject* orig ) -{ - g_return_val_if_fail( rxAccessible.get() != nullptr, nullptr ); - - AtkObjectWrapper *pWrap = nullptr; - - try { - uno::Reference< accessibility::XAccessibleContext > xContext(rxAccessible->getAccessibleContext()); - - g_return_val_if_fail( xContext.get() != nullptr, nullptr ); - - GType nType = ensureTypeFor( xContext.get() ); - gpointer obj = g_object_new( nType, nullptr); - - pWrap = ATK_OBJECT_WRAPPER( obj ); - pWrap->mpAccessible = rxAccessible; - - pWrap->index_of_child_about_to_be_removed = -1; - pWrap->child_about_to_be_removed = nullptr; - - pWrap->mpContext = xContext; - pWrap->mpOrig = orig; - - AtkObject* atk_obj = ATK_OBJECT(pWrap); - atk_obj->role = mapToAtkRole( xContext->getAccessibleRole() ); - atk_obj->accessible_parent = parent; - - ooo_wrapper_registry_add( rxAccessible, atk_obj ); - - if( parent ) - g_object_ref( atk_obj->accessible_parent ); - else - { - /* gail_focus_tracker remembers the focused object at the first - * parent in the hierarchy that is a Gtk+ widget, but at the time the - * event gets processed (at idle), it may be too late to create the - * hierarchy, so doing it now .. - */ - uno::Reference< accessibility::XAccessible > xParent( xContext->getAccessibleParent() ); - - if( xParent.is() ) - atk_obj->accessible_parent = atk_object_wrapper_ref( xParent ); - } - - // Attach a listener to the UNO object if it's not TRANSIENT - uno::Reference< accessibility::XAccessibleStateSet > xStateSet( xContext->getAccessibleStateSet() ); - if( xStateSet.is() && ! xStateSet->contains( accessibility::AccessibleStateType::TRANSIENT ) ) - { - uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster(xContext, uno::UNO_QUERY); - if( xBroadcaster.is() ) - { - uno::Reference<accessibility::XAccessibleEventListener> xListener(new AtkListener(pWrap)); - xBroadcaster->addAccessibleEventListener(xListener); - } - else - OSL_ASSERT( false ); - } - -#if ATK_CHECK_VERSION(2,33,1) - { - css::uno::Reference<css::accessibility::XAccessibleContext2> xContext2(xContext, css::uno::UNO_QUERY); - if( xContext2.is() ) - { - OString aId = OUStringToOString( xContext2->getAccessibleId(), RTL_TEXTENCODING_UTF8); - atk_object_set_accessible_id(atk_obj, aId.getStr()); - } - } -#endif - - return ATK_OBJECT( pWrap ); - } - catch (const uno::Exception &) - { - if( pWrap ) - g_object_unref( pWrap ); - - return nullptr; - } -} - -/*****************************************************************************/ - -void atk_object_wrapper_add_child(AtkObjectWrapper* wrapper, AtkObject *child, gint index) -{ - AtkObject *atk_obj = ATK_OBJECT( wrapper ); - - atk_object_set_parent( child, atk_obj ); - g_signal_emit_by_name( atk_obj, "children_changed::add", index, child, nullptr ); -} - -/*****************************************************************************/ - -void atk_object_wrapper_remove_child(AtkObjectWrapper* wrapper, AtkObject *child, gint index) -{ - /* - * the atk-bridge GTK+ module gets back to the event source to ref the child just - * vanishing, so we keep this reference because the semantic on OOo side is different. - */ - wrapper->child_about_to_be_removed = child; - wrapper->index_of_child_about_to_be_removed = index; - - g_signal_emit_by_name( ATK_OBJECT( wrapper ), "children_changed::remove", index, child, nullptr ); - - wrapper->index_of_child_about_to_be_removed = -1; - wrapper->child_about_to_be_removed = nullptr; -} - -/*****************************************************************************/ - -void atk_object_wrapper_set_role(AtkObjectWrapper* wrapper, sal_Int16 role) -{ - AtkObject *atk_obj = ATK_OBJECT( wrapper ); - atk_object_set_role( atk_obj, mapToAtkRole( role ) ); -} - -/*****************************************************************************/ - -void atk_object_wrapper_dispose(AtkObjectWrapper* wrapper) -{ - wrapper->mpContext.clear(); - wrapper->mpAction.clear(); - wrapper->mpComponent.clear(); - wrapper->mpEditableText.clear(); - wrapper->mpHypertext.clear(); - wrapper->mpImage.clear(); - wrapper->mpSelection.clear(); - wrapper->mpMultiLineText.clear(); - wrapper->mpTable.clear(); - wrapper->mpText.clear(); - wrapper->mpTextMarkup.clear(); - wrapper->mpTextAttributes.clear(); - wrapper->mpValue.clear(); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/a11y/atkwrapper.hxx b/vcl/unx/gtk/a11y/atkwrapper.hxx deleted file mode 100644 index 8725e54ccf5b..000000000000 --- a/vcl/unx/gtk/a11y/atkwrapper.hxx +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_VCL_UNX_GTK_A11Y_ATKWRAPPER_HXX -#define INCLUDED_VCL_UNX_GTK_A11Y_ATKWRAPPER_HXX - -#include <atk/atk.h> -#include <gtk/gtk.h> -#if GTK_CHECK_VERSION(3,0,0) -#include <gtk/gtk-a11y.h> -#endif -#include <com/sun/star/accessibility/XAccessible.hpp> - -extern "C" { - -namespace com { namespace sun { namespace star { namespace accessibility { - class XAccessibleAction; - class XAccessibleComponent; - class XAccessibleEditableText; - class XAccessibleHypertext; - class XAccessibleImage; - class XAccessibleMultiLineText; - class XAccessibleSelection; - class XAccessibleTable; - class XAccessibleText; - class XAccessibleTextMarkup; - class XAccessibleTextAttributes; - class XAccessibleValue; -} } } } - -struct AtkObjectWrapper -{ - AtkObject const aParent; - AtkObject* mpOrig; //if we're a GtkDrawingArea acting as a custom LibreOffice widget, this is the toolkit default impl - - css::uno::Reference<css::accessibility::XAccessible> mpAccessible; - css::uno::Reference<css::accessibility::XAccessibleContext> mpContext; - css::uno::Reference<css::accessibility::XAccessibleAction> mpAction; - css::uno::Reference<css::accessibility::XAccessibleComponent> mpComponent; - css::uno::Reference<css::accessibility::XAccessibleEditableText> - mpEditableText; - css::uno::Reference<css::accessibility::XAccessibleHypertext> mpHypertext; - css::uno::Reference<css::accessibility::XAccessibleImage> mpImage; - css::uno::Reference<css::accessibility::XAccessibleMultiLineText> - mpMultiLineText; - css::uno::Reference<css::accessibility::XAccessibleSelection> mpSelection; - css::uno::Reference<css::accessibility::XAccessibleTable> mpTable; - css::uno::Reference<css::accessibility::XAccessibleText> mpText; - css::uno::Reference<css::accessibility::XAccessibleTextMarkup> mpTextMarkup; - css::uno::Reference<css::accessibility::XAccessibleTextAttributes> - mpTextAttributes; - css::uno::Reference<css::accessibility::XAccessibleValue> mpValue; - - AtkObject *child_about_to_be_removed; - gint index_of_child_about_to_be_removed; -// OString * m_pKeyBindings -}; - -struct AtkObjectWrapperClass -{ -#if GTK_CHECK_VERSION(3,0,0) - GtkWidgetAccessibleClass aParentClass; -#else - AtkObjectClass const aParentClass; -#endif -}; - -GType atk_object_wrapper_get_type() G_GNUC_CONST; -AtkObject * atk_object_wrapper_ref( - const css::uno::Reference< css::accessibility::XAccessible >& rxAccessible, - bool create = true ); - -AtkObject * atk_object_wrapper_new( - const css::uno::Reference< css::accessibility::XAccessible >& rxAccessible, - AtkObject* parent = nullptr, AtkObject* orig = nullptr ); - -void atk_object_wrapper_add_child(AtkObjectWrapper* wrapper, AtkObject *child, gint index); -void atk_object_wrapper_remove_child(AtkObjectWrapper* wrapper, AtkObject *child, gint index); -void atk_object_wrapper_set_role(AtkObjectWrapper* wrapper, sal_Int16 role); - -void atk_object_wrapper_dispose(AtkObjectWrapper* wrapper); - -AtkStateType mapAtkState( sal_Int16 nState ); - -AtkRelation* atk_object_wrapper_relation_new(const css::accessibility::AccessibleRelation& rRelation); - -void actionIfaceInit(AtkActionIface *iface); -void componentIfaceInit(AtkComponentIface *iface); -void editableTextIfaceInit(AtkEditableTextIface *iface); -void hypertextIfaceInit(AtkHypertextIface *iface); -void imageIfaceInit(AtkImageIface *iface); -void selectionIfaceInit(AtkSelectionIface *iface); -void tableIfaceInit(AtkTableIface *iface); -void textIfaceInit(AtkTextIface *iface); -void valueIfaceInit(AtkValueIface *iface); - -} // extern "C" - -#define ATK_TYPE_OBJECT_WRAPPER atk_object_wrapper_get_type() -#define ATK_OBJECT_WRAPPER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATK_TYPE_OBJECT_WRAPPER, AtkObjectWrapper)) -#define ATK_IS_OBJECT_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ATK_TYPE_OBJECT_WRAPPER)) - -static inline gchar * -OUStringToGChar(const OUString& rString ) -{ - OString aUtf8 = OUStringToOString( rString, RTL_TEXTENCODING_UTF8 ); - return g_strdup( aUtf8.getStr() ); -} - -#define OUStringToConstGChar( string ) OUStringToOString( string, RTL_TEXTENCODING_UTF8 ).getStr() - -#endif // INCLUDED_VCL_UNX_GTK_A11Y_ATKWRAPPER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |