Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/vcl/unx/gtk3/a11y/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 14 kB image not shown  

Quelle  atkcomponent.cxx   Sprache: C

 
/* -*- 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 <sal/log.hxx>
#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
lcl_getLocationInWindow(AtkComponent* pAtkComponent,
                        css::uno::Reference<accessibility::XAccessibleComponent> const& xComponent)
{
    // calculate position in window by adding the component's position in the parent
    // to the parent's position in the window (unless parent is a window itself)
    awt::Point aPos = xComponent->getLocation();
    AtkObject* pParent = atk_object_get_parent(ATK_OBJECT(pAtkComponent));
    if (ATK_IS_COMPONENT(pParent) && pParent->role != AtkRole::ATK_ROLE_DIALOG
            && pParent->role != AtkRole::ATK_ROLE_FILE_CHOOSER
            && pParent->role != AtkRole::ATK_ROLE_FRAME
            && pParent->role != AtkRole::ATK_ROLE_WINDOW)
    {
        int nX;
        int nY;
        atk_component_get_extents(ATK_COMPONENT(pParent), &nX, &nY, nullptr, nullptr, ATK_XY_WINDOW);
        aPos.X += nX;
        aPos.Y += nY;
    }

    return aPos;
}

/*****************************************************************************/

static awt::Point
translatePoint( AtkComponent* pAtkComponent,
                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();
    else if (t == ATK_XY_WINDOW)
        aOrigin = lcl_getLocationInWindow(pAtkComponent, pComponent);
    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;
        }
    }
    catchconst 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(component, pComponent, x, y, coord_type));
    }
    catchconst 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(component, pComponent, x, y, coord_type));
            if (xAccessible.is())
                return atk_object_wrapper_ref(xAccessible);
        }
    }
    catchconst 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 if (coord_type == ATK_XY_WINDOW)
                aPos = lcl_getLocationInWindow(component, pComponent);
#if ATK_CHECK_VERSION(2, 30, 0)
            else if (coord_type == ATK_XY_PARENT)
#else
            // ATK_XY_PARENT added in ATK 2.30, so can't use the constant here
            else
#endif
                aPos = pComponent->getLocation();
#if ATK_CHECK_VERSION(2, 30, 0)
            else
            {
                SAL_WARN("vcl.gtk",
                         "component_wrapper_get_position called with unknown AtkCoordType "
                             << coord_type);
                return;
            }
#endif

            *x = aPos.X;
            *y = aPos.Y;
        }
    }
    catchconst 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;
        }
    }
    catchconst 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 (gpointer iface_, gpointer)
{
  auto const iface = static_cast<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: */

Messung V0.5
C=93 H=100 G=96

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.