Blame modules/other/gail/gailcell.c

Packit 98cdb6
/* GAIL - The GNOME Accessibility Implementation Library
Packit 98cdb6
 * Copyright 2001 Sun Microsystems Inc.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is free software; you can redistribute it and/or
Packit 98cdb6
 * modify it under the terms of the GNU Lesser General Public
Packit 98cdb6
 * License as published by the Free Software Foundation; either
Packit 98cdb6
 * version 2 of the License, or (at your option) any later version.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is distributed in the hope that it will be useful,
Packit 98cdb6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 98cdb6
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 98cdb6
 * Lesser General Public License for more details.
Packit 98cdb6
 *
Packit 98cdb6
 * You should have received a copy of the GNU Lesser General Public
Packit 98cdb6
 * License along with this library; if not, write to the
Packit 98cdb6
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 98cdb6
 * Boston, MA 02111-1307, USA.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#include "config.h"
Packit 98cdb6
Packit 98cdb6
#include <string.h>
Packit 98cdb6
#include <stdlib.h>
Packit 98cdb6
#include <gtk/gtk.h>
Packit 98cdb6
#include "gailcontainercell.h"
Packit 98cdb6
#include "gailcell.h"
Packit 98cdb6
#include "gailcellparent.h"
Packit 98cdb6
Packit 98cdb6
static void	    gail_cell_class_init          (GailCellClass       *klass);
Packit 98cdb6
static void         gail_cell_destroyed           (GtkWidget           *widget,
Packit 98cdb6
                                                   GailCell            *cell);
Packit 98cdb6
Packit 98cdb6
static void         gail_cell_init                (GailCell            *cell);
Packit 98cdb6
static void         gail_cell_object_finalize     (GObject             *cell);
Packit 98cdb6
static AtkStateSet* gail_cell_ref_state_set       (AtkObject           *obj);
Packit 98cdb6
static gint         gail_cell_get_index_in_parent (AtkObject           *obj);
Packit 98cdb6
Packit 98cdb6
/* AtkAction */
Packit 98cdb6
Packit 98cdb6
static void         atk_action_interface_init 
Packit 98cdb6
                                                  (AtkActionIface      *iface);
Packit 98cdb6
static ActionInfo * _gail_cell_get_action_info    (GailCell            *cell,
Packit 98cdb6
			                           gint                index);
Packit 98cdb6
static void         _gail_cell_destroy_action_info 
Packit 98cdb6
                                                  (gpointer            data,
Packit 98cdb6
				                   gpointer            user_data);
Packit 98cdb6
Packit 98cdb6
static gint         gail_cell_action_get_n_actions 
Packit 98cdb6
                                                  (AtkAction           *action);
Packit 98cdb6
static const gchar *
Packit 98cdb6
                    gail_cell_action_get_name     (AtkAction           *action,
Packit 98cdb6
			                           gint                index);
Packit 98cdb6
static const gchar *
Packit 98cdb6
                    gail_cell_action_get_description 
Packit 98cdb6
                                                  (AtkAction           *action,
Packit 98cdb6
				                   gint                index);
Packit 98cdb6
static gboolean     gail_cell_action_set_description 
Packit 98cdb6
                                                  (AtkAction           *action,
Packit 98cdb6
				                   gint                index,
Packit 98cdb6
				                   const gchar         *desc);
Packit 98cdb6
static const gchar *
Packit 98cdb6
                    gail_cell_action_get_keybinding 
Packit 98cdb6
                                                  (AtkAction           *action,
Packit 98cdb6
				                   gint                index);
Packit 98cdb6
static gboolean     gail_cell_action_do_action    (AtkAction           *action,
Packit 98cdb6
			                           gint                index);
Packit 98cdb6
static gboolean     idle_do_action                (gpointer            data);
Packit 98cdb6
Packit 98cdb6
static void         atk_component_interface_init  (AtkComponentIface   *iface);
Packit 98cdb6
static void         gail_cell_get_extents         (AtkComponent        *component,
Packit 98cdb6
                                                   gint                *x,
Packit 98cdb6
                                                   gint                *y,
Packit 98cdb6
                                                   gint                *width,
Packit 98cdb6
                                                   gint                *height,
Packit 98cdb6
                                                   AtkCoordType        coord_type);
Packit 98cdb6
static gboolean     gail_cell_grab_focus         (AtkComponent        *component);
Packit 98cdb6
Packit 98cdb6
G_DEFINE_TYPE_WITH_CODE (GailCell, gail_cell, ATK_TYPE_OBJECT,
Packit 98cdb6
                         G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
Packit 98cdb6
                         G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
Packit 98cdb6
Packit 98cdb6
static void	 
Packit 98cdb6
gail_cell_class_init (GailCellClass *klass)
Packit 98cdb6
{
Packit 98cdb6
  AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
Packit 98cdb6
  GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
Packit 98cdb6
Packit 98cdb6
  g_object_class->finalize = gail_cell_object_finalize;
Packit 98cdb6
Packit 98cdb6
  class->get_index_in_parent = gail_cell_get_index_in_parent;
Packit 98cdb6
  class->ref_state_set = gail_cell_ref_state_set;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void 
Packit 98cdb6
gail_cell_initialise (GailCell  *cell,
Packit 98cdb6
                      GtkWidget *widget,
Packit 98cdb6
                      AtkObject *parent,
Packit 98cdb6
                      gint      index)
Packit 98cdb6
{
Packit 98cdb6
  g_return_if_fail (GAIL_IS_CELL (cell));
Packit 98cdb6
  g_return_if_fail (GTK_IS_WIDGET (widget));
Packit 98cdb6
Packit 98cdb6
  cell->widget = widget;
Packit 98cdb6
  atk_object_set_parent (ATK_OBJECT (cell), parent);
Packit 98cdb6
  cell->index = index;
Packit 98cdb6
Packit 98cdb6
  g_signal_connect_object (G_OBJECT (widget),
Packit 98cdb6
                           "destroy",
Packit 98cdb6
                           G_CALLBACK (gail_cell_destroyed ),
Packit 98cdb6
                           cell, 0);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gail_cell_destroyed (GtkWidget       *widget,
Packit 98cdb6
                     GailCell        *cell)
Packit 98cdb6
{
Packit 98cdb6
  /*
Packit 98cdb6
   * This is the signal handler for the "destroy" signal for the 
Packit 98cdb6
   * GtkWidget. We set the  pointer location to NULL;
Packit 98cdb6
   */
Packit 98cdb6
  cell->widget = NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gail_cell_init (GailCell *cell)
Packit 98cdb6
{
Packit 98cdb6
  cell->state_set = atk_state_set_new ();
Packit 98cdb6
  cell->widget = NULL;
Packit 98cdb6
  cell->action_list = NULL;
Packit 98cdb6
  cell->index = 0;
Packit 98cdb6
  atk_state_set_add_state (cell->state_set, ATK_STATE_TRANSIENT);
Packit 98cdb6
  atk_state_set_add_state (cell->state_set, ATK_STATE_ENABLED);
Packit 98cdb6
  atk_state_set_add_state (cell->state_set, ATK_STATE_SENSITIVE);
Packit 98cdb6
  atk_state_set_add_state (cell->state_set, ATK_STATE_SELECTABLE);
Packit 98cdb6
  cell->refresh_index = NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gail_cell_object_finalize (GObject *obj)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *cell = GAIL_CELL (obj);
Packit 98cdb6
  AtkRelationSet *relation_set;
Packit 98cdb6
  AtkRelation *relation;
Packit 98cdb6
  GPtrArray *target;
Packit 98cdb6
  gpointer target_object;
Packit 98cdb6
  gint i;
Packit 98cdb6
Packit 98cdb6
  if (cell->state_set)
Packit 98cdb6
    g_object_unref (cell->state_set);
Packit 98cdb6
  if (cell->action_list)
Packit 98cdb6
    {
Packit 98cdb6
      g_list_foreach (cell->action_list, _gail_cell_destroy_action_info, NULL);
Packit 98cdb6
      g_list_free (cell->action_list);
Packit 98cdb6
    }
Packit 98cdb6
  if (cell->action_idle_handler)
Packit 98cdb6
    {
Packit 98cdb6
      g_source_remove (cell->action_idle_handler);
Packit 98cdb6
      cell->action_idle_handler = 0;
Packit 98cdb6
    }
Packit 98cdb6
  relation_set = atk_object_ref_relation_set (ATK_OBJECT (obj));
Packit 98cdb6
  if (ATK_IS_RELATION_SET (relation_set))
Packit 98cdb6
    {
Packit 98cdb6
      relation = atk_relation_set_get_relation_by_type (relation_set, 
Packit 98cdb6
                                                        ATK_RELATION_NODE_CHILD_OF);
Packit 98cdb6
      if (relation)
Packit 98cdb6
        {
Packit 98cdb6
          target = atk_relation_get_target (relation);
Packit 98cdb6
          for (i = 0; i < target->len; i++)
Packit 98cdb6
            {
Packit 98cdb6
              target_object = g_ptr_array_index (target, i);
Packit 98cdb6
              if (GAIL_IS_CELL (target_object))
Packit 98cdb6
                {
Packit 98cdb6
                  g_object_unref (target_object);
Packit 98cdb6
                }
Packit 98cdb6
            }
Packit 98cdb6
        }
Packit 98cdb6
      g_object_unref (relation_set);
Packit 98cdb6
    }
Packit 98cdb6
  G_OBJECT_CLASS (gail_cell_parent_class)->finalize (obj);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static AtkStateSet *
Packit 98cdb6
gail_cell_ref_state_set (AtkObject *obj)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *cell = GAIL_CELL (obj);
Packit 98cdb6
  g_assert (cell->state_set);
Packit 98cdb6
Packit 98cdb6
  g_object_ref(cell->state_set);
Packit 98cdb6
  return cell->state_set;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gboolean
Packit 98cdb6
gail_cell_add_state (GailCell     *cell, 
Packit 98cdb6
                     AtkStateType state_type,
Packit 98cdb6
                     gboolean     emit_signal)
Packit 98cdb6
{
Packit 98cdb6
  if (!atk_state_set_contains_state (cell->state_set, state_type))
Packit 98cdb6
    {
Packit 98cdb6
      gboolean rc;
Packit 98cdb6
      AtkObject *parent;
Packit 98cdb6
    
Packit 98cdb6
      rc = atk_state_set_add_state (cell->state_set, state_type);
Packit 98cdb6
      /*
Packit 98cdb6
       * The signal should only be generated if the value changed,
Packit 98cdb6
       * not when the cell is set up.  So states that are set
Packit 98cdb6
       * initially should pass FALSE as the emit_signal argument.
Packit 98cdb6
       */
Packit 98cdb6
Packit 98cdb6
      if (emit_signal)
Packit 98cdb6
        {
Packit 98cdb6
          atk_object_notify_state_change (ATK_OBJECT (cell), state_type, TRUE);
Packit 98cdb6
          /* If state_type is ATK_STATE_VISIBLE, additional notification */
Packit 98cdb6
          if (state_type == ATK_STATE_VISIBLE)
Packit 98cdb6
            g_signal_emit_by_name (cell, "visible_data_changed");
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      /* 
Packit 98cdb6
       * If the parent is a flyweight container cell, propagate the state 
Packit 98cdb6
       * change to it also 
Packit 98cdb6
       */
Packit 98cdb6
Packit 98cdb6
      parent = atk_object_get_parent (ATK_OBJECT (cell));
Packit 98cdb6
      if (GAIL_IS_CONTAINER_CELL (parent))
Packit 98cdb6
        gail_cell_add_state (GAIL_CELL (parent), state_type, emit_signal);
Packit 98cdb6
      return rc;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gboolean
Packit 98cdb6
gail_cell_remove_state (GailCell     *cell, 
Packit 98cdb6
                        AtkStateType state_type,
Packit 98cdb6
                        gboolean     emit_signal)
Packit 98cdb6
{
Packit 98cdb6
  if (atk_state_set_contains_state (cell->state_set, state_type))
Packit 98cdb6
    {
Packit 98cdb6
      gboolean rc;
Packit 98cdb6
      AtkObject *parent;
Packit 98cdb6
Packit 98cdb6
      parent = atk_object_get_parent (ATK_OBJECT (cell));
Packit 98cdb6
Packit 98cdb6
      rc = atk_state_set_remove_state (cell->state_set, state_type);
Packit 98cdb6
      /*
Packit 98cdb6
       * The signal should only be generated if the value changed,
Packit 98cdb6
       * not when the cell is set up.  So states that are set
Packit 98cdb6
       * initially should pass FALSE as the emit_signal argument.
Packit 98cdb6
       */
Packit 98cdb6
Packit 98cdb6
      if (emit_signal)
Packit 98cdb6
        {
Packit 98cdb6
          atk_object_notify_state_change (ATK_OBJECT (cell), state_type, FALSE);
Packit 98cdb6
          /* If state_type is ATK_STATE_VISIBLE, additional notification */
Packit 98cdb6
          if (state_type == ATK_STATE_VISIBLE)
Packit 98cdb6
            g_signal_emit_by_name (cell, "visible_data_changed");
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      /* 
Packit 98cdb6
       * If the parent is a flyweight container cell, propagate the state 
Packit 98cdb6
       * change to it also 
Packit 98cdb6
       */
Packit 98cdb6
Packit 98cdb6
      if (GAIL_IS_CONTAINER_CELL (parent))
Packit 98cdb6
        gail_cell_remove_state (GAIL_CELL (parent), state_type, emit_signal);
Packit 98cdb6
      return rc;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gint
Packit 98cdb6
gail_cell_get_index_in_parent (AtkObject *obj)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *cell;
Packit 98cdb6
Packit 98cdb6
  g_assert (GAIL_IS_CELL (obj));
Packit 98cdb6
Packit 98cdb6
  cell = GAIL_CELL (obj);
Packit 98cdb6
  if (atk_state_set_contains_state (cell->state_set, ATK_STATE_STALE))
Packit 98cdb6
    if (cell->refresh_index)
Packit 98cdb6
      {
Packit 98cdb6
        cell->refresh_index (cell);
Packit 98cdb6
        atk_state_set_remove_state (cell->state_set, ATK_STATE_STALE);
Packit 98cdb6
      }
Packit 98cdb6
  return cell->index;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
atk_action_interface_init (AtkActionIface *iface)
Packit 98cdb6
{
Packit 98cdb6
  iface->get_n_actions = gail_cell_action_get_n_actions;
Packit 98cdb6
  iface->do_action = gail_cell_action_do_action;
Packit 98cdb6
  iface->get_name = gail_cell_action_get_name;
Packit 98cdb6
  iface->get_description = gail_cell_action_get_description;
Packit 98cdb6
  iface->set_description = gail_cell_action_set_description;
Packit 98cdb6
  iface->get_keybinding = gail_cell_action_get_keybinding;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * Deprecated: 2.22: The action interface is added for all cells now.
Packit 98cdb6
 */
Packit 98cdb6
void
Packit 98cdb6
gail_cell_type_add_action_interface (GType type)
Packit 98cdb6
{
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gboolean
Packit 98cdb6
gail_cell_add_action (GailCell    *cell,
Packit 98cdb6
		      const gchar *action_name,
Packit 98cdb6
		      const gchar *action_description,
Packit 98cdb6
		      const gchar *action_keybinding,
Packit 98cdb6
		      ACTION_FUNC action_func)
Packit 98cdb6
{
Packit 98cdb6
  ActionInfo *info;
Packit 98cdb6
  g_return_val_if_fail (GAIL_IS_CELL (cell), FALSE);
Packit 98cdb6
  info = g_new (ActionInfo, 1);
Packit 98cdb6
Packit 98cdb6
  if (action_name != NULL)
Packit 98cdb6
    info->name = g_strdup (action_name);
Packit 98cdb6
  else
Packit 98cdb6
    info->name = NULL;
Packit 98cdb6
  if (action_description != NULL)
Packit 98cdb6
    info->description = g_strdup (action_description);
Packit 98cdb6
  else
Packit 98cdb6
    info->description = NULL;
Packit 98cdb6
  if (action_keybinding != NULL)
Packit 98cdb6
    info->keybinding = g_strdup (action_keybinding);
Packit 98cdb6
  else
Packit 98cdb6
    info->keybinding = NULL;
Packit 98cdb6
  info->do_action_func = action_func;
Packit 98cdb6
Packit 98cdb6
  cell->action_list = g_list_append (cell->action_list, (gpointer) info);
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gboolean
Packit 98cdb6
gail_cell_remove_action (GailCell *cell,
Packit 98cdb6
			 gint     action_index)
Packit 98cdb6
{
Packit 98cdb6
  GList *list_node;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (GAIL_IS_CELL (cell), FALSE);
Packit 98cdb6
  list_node = g_list_nth (cell->action_list, action_index);
Packit 98cdb6
  if (!list_node)
Packit 98cdb6
    return FALSE;
Packit 98cdb6
  _gail_cell_destroy_action_info (list_node->data, NULL);
Packit 98cdb6
  cell->action_list = g_list_remove_link (cell->action_list, list_node);
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
gboolean
Packit 98cdb6
gail_cell_remove_action_by_name (GailCell    *cell,
Packit 98cdb6
				 const gchar *action_name)
Packit 98cdb6
{
Packit 98cdb6
  GList *list_node;
Packit 98cdb6
  gboolean action_found= FALSE;
Packit 98cdb6
  
Packit 98cdb6
  g_return_val_if_fail (GAIL_IS_CELL (cell), FALSE);
Packit 98cdb6
  for (list_node = cell->action_list; list_node && !action_found; 
Packit 98cdb6
                    list_node = list_node->next)
Packit 98cdb6
    {
Packit 98cdb6
      if (!strcmp (((ActionInfo *)(list_node->data))->name, action_name))
Packit 98cdb6
	{
Packit 98cdb6
	  action_found = TRUE;
Packit 98cdb6
	  break;
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
  if (!action_found)
Packit 98cdb6
    return FALSE;
Packit 98cdb6
  _gail_cell_destroy_action_info (list_node->data, NULL);
Packit 98cdb6
  cell->action_list = g_list_remove_link (cell->action_list, list_node);
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static ActionInfo *
Packit 98cdb6
_gail_cell_get_action_info (GailCell *cell,
Packit 98cdb6
			    gint     index)
Packit 98cdb6
{
Packit 98cdb6
  GList *list_node;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (GAIL_IS_CELL (cell), NULL);
Packit 98cdb6
  if (cell->action_list == NULL)
Packit 98cdb6
    return NULL;
Packit 98cdb6
  list_node = g_list_nth (cell->action_list, index);
Packit 98cdb6
  if (!list_node)
Packit 98cdb6
    return NULL;
Packit 98cdb6
  return (ActionInfo *) (list_node->data);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
_gail_cell_destroy_action_info (gpointer action_info, 
Packit 98cdb6
                                gpointer user_data)
Packit 98cdb6
{
Packit 98cdb6
  ActionInfo *info = (ActionInfo *)action_info;
Packit 98cdb6
  g_assert (info != NULL);
Packit 98cdb6
  g_free (info->name);
Packit 98cdb6
  g_free (info->description);
Packit 98cdb6
  g_free (info->keybinding);
Packit 98cdb6
  g_free (info);
Packit 98cdb6
}
Packit 98cdb6
static gint
Packit 98cdb6
gail_cell_action_get_n_actions (AtkAction *action)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *cell = GAIL_CELL(action);
Packit 98cdb6
  if (cell->action_list != NULL)
Packit 98cdb6
    return g_list_length (cell->action_list);
Packit 98cdb6
  else
Packit 98cdb6
    return 0;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static const gchar *
Packit 98cdb6
gail_cell_action_get_name (AtkAction *action,
Packit 98cdb6
			   gint      index)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *cell = GAIL_CELL(action);
Packit 98cdb6
  ActionInfo *info = _gail_cell_get_action_info (cell, index);
Packit 98cdb6
Packit 98cdb6
  if (info == NULL)
Packit 98cdb6
    return NULL;
Packit 98cdb6
  return info->name;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static const gchar *
Packit 98cdb6
gail_cell_action_get_description (AtkAction *action,
Packit 98cdb6
				  gint      index)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *cell = GAIL_CELL(action);
Packit 98cdb6
  ActionInfo *info = _gail_cell_get_action_info (cell, index);
Packit 98cdb6
Packit 98cdb6
  if (info == NULL)
Packit 98cdb6
    return NULL;
Packit 98cdb6
  return info->description;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gail_cell_action_set_description (AtkAction   *action,
Packit 98cdb6
				  gint        index,
Packit 98cdb6
				  const gchar *desc)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *cell = GAIL_CELL(action);
Packit 98cdb6
  ActionInfo *info = _gail_cell_get_action_info (cell, index);
Packit 98cdb6
Packit 98cdb6
  if (info == NULL)
Packit 98cdb6
    return FALSE;
Packit 98cdb6
  g_free (info->description);
Packit 98cdb6
  info->description = g_strdup (desc);
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static const gchar *
Packit 98cdb6
gail_cell_action_get_keybinding (AtkAction *action,
Packit 98cdb6
				 gint      index)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *cell = GAIL_CELL(action);
Packit 98cdb6
  ActionInfo *info = _gail_cell_get_action_info (cell, index);
Packit 98cdb6
  if (info == NULL)
Packit 98cdb6
    return NULL;
Packit 98cdb6
  return info->keybinding;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gail_cell_action_do_action (AtkAction *action,
Packit 98cdb6
			    gint      index)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *cell = GAIL_CELL(action);
Packit 98cdb6
  ActionInfo *info = _gail_cell_get_action_info (cell, index);
Packit 98cdb6
  if (info == NULL)
Packit 98cdb6
    return FALSE;
Packit 98cdb6
  if (info->do_action_func == NULL)
Packit 98cdb6
    return FALSE;
Packit 98cdb6
  if (cell->action_idle_handler)
Packit 98cdb6
    return FALSE;
Packit 98cdb6
  cell->action_func = info->do_action_func;
Packit 98cdb6
  cell->action_idle_handler = gdk_threads_add_idle (idle_do_action, cell);
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
idle_do_action (gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *cell;
Packit 98cdb6
Packit 98cdb6
  cell = GAIL_CELL (data);
Packit 98cdb6
  cell->action_idle_handler = 0;
Packit 98cdb6
  cell->action_func (cell);
Packit 98cdb6
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
atk_component_interface_init (AtkComponentIface *iface)
Packit 98cdb6
{
Packit 98cdb6
  iface->get_extents = gail_cell_get_extents;
Packit 98cdb6
  iface->grab_focus = gail_cell_grab_focus;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void 
Packit 98cdb6
gail_cell_get_extents (AtkComponent *component,
Packit 98cdb6
                       gint         *x,
Packit 98cdb6
                       gint         *y,
Packit 98cdb6
                       gint         *width,
Packit 98cdb6
                       gint         *height,
Packit 98cdb6
                       AtkCoordType coord_type)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *gailcell;
Packit 98cdb6
  AtkObject *cell_parent;
Packit 98cdb6
Packit 98cdb6
  g_assert (GAIL_IS_CELL (component));
Packit 98cdb6
Packit 98cdb6
  gailcell = GAIL_CELL (component);
Packit 98cdb6
Packit 98cdb6
  cell_parent = gtk_widget_get_accessible (gailcell->widget);
Packit 98cdb6
Packit 98cdb6
  gail_cell_parent_get_cell_extents (GAIL_CELL_PARENT (cell_parent), 
Packit 98cdb6
                                   gailcell, x, y, width, height, coord_type);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean 
Packit 98cdb6
gail_cell_grab_focus (AtkComponent *component)
Packit 98cdb6
{
Packit 98cdb6
  GailCell *gailcell;
Packit 98cdb6
  AtkObject *cell_parent;
Packit 98cdb6
Packit 98cdb6
  g_assert (GAIL_IS_CELL (component));
Packit 98cdb6
Packit 98cdb6
  gailcell = GAIL_CELL (component);
Packit 98cdb6
Packit 98cdb6
  cell_parent = gtk_widget_get_accessible (gailcell->widget);
Packit 98cdb6
Packit 98cdb6
  return gail_cell_parent_grab_focus (GAIL_CELL_PARENT (cell_parent), 
Packit 98cdb6
                                      gailcell);
Packit 98cdb6
}