1 /* GAIL - The GNOME Accessibility Implementation Library
2 * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
23 #include "gailcontainer.h"
25 static void gail_container_class_init (GailContainerClass *klass);
26 static void gail_container_init (GailContainer *container);
28 static gint gail_container_get_n_children (AtkObject *obj);
29 static AtkObject* gail_container_ref_child (AtkObject *obj,
31 static gint gail_container_add_gtk (GtkContainer *container,
34 static gint gail_container_remove_gtk (GtkContainer *container,
37 static gint gail_container_real_add_gtk (GtkContainer *container,
40 static gint gail_container_real_remove_gtk (GtkContainer *container,
44 static void gail_container_real_initialize (AtkObject *obj,
47 static void gail_container_finalize (GObject *object);
49 G_DEFINE_TYPE (GailContainer, gail_container, GAIL_TYPE_WIDGET)
52 gail_container_class_init (GailContainerClass *klass)
54 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
55 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
57 gobject_class->finalize = gail_container_finalize;
59 class->get_n_children = gail_container_get_n_children;
60 class->ref_child = gail_container_ref_child;
61 class->initialize = gail_container_real_initialize;
63 klass->add_gtk = gail_container_real_add_gtk;
64 klass->remove_gtk = gail_container_real_remove_gtk;
68 gail_container_init (GailContainer *container)
70 container->children = NULL;
74 gail_container_get_n_children (AtkObject* obj)
80 g_return_val_if_fail (GAIL_IS_CONTAINER (obj), count);
82 widget = GTK_ACCESSIBLE (obj)->widget;
86 children = gtk_container_get_children (GTK_CONTAINER(widget));
87 count = g_list_length (children);
88 g_list_free (children);
94 gail_container_ref_child (AtkObject *obj,
97 GList *children, *tmp_list;
98 AtkObject *accessible;
101 g_return_val_if_fail (GAIL_IS_CONTAINER (obj), NULL);
102 g_return_val_if_fail ((i >= 0), NULL);
103 widget = GTK_ACCESSIBLE (obj)->widget;
107 children = gtk_container_get_children (GTK_CONTAINER (widget));
108 tmp_list = g_list_nth (children, i);
111 g_list_free (children);
114 accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
116 g_list_free (children);
117 g_object_ref (accessible);
122 gail_container_add_gtk (GtkContainer *container,
126 GailContainer *gail_container = GAIL_CONTAINER (data);
127 GailContainerClass *klass;
129 klass = GAIL_CONTAINER_GET_CLASS (gail_container);
132 return klass->add_gtk (container, widget, data);
138 gail_container_remove_gtk (GtkContainer *container,
142 GailContainer *gail_container = GAIL_CONTAINER (data);
143 GailContainerClass *klass;
145 klass = GAIL_CONTAINER_GET_CLASS (gail_container);
147 if (klass->remove_gtk)
148 return klass->remove_gtk (container, widget, data);
154 gail_container_real_add_gtk (GtkContainer *container,
158 AtkObject* atk_parent = ATK_OBJECT (data);
159 AtkObject* atk_child = gtk_widget_get_accessible (widget);
160 GailContainer *gail_container = GAIL_CONTAINER (atk_parent);
163 g_object_notify (G_OBJECT (atk_child), "accessible_parent");
165 g_list_free (gail_container->children);
166 gail_container->children = gtk_container_get_children (container);
167 index = g_list_index (gail_container->children, widget);
168 g_signal_emit_by_name (atk_parent, "children_changed::add",
169 index, atk_child, NULL);
175 gail_container_real_remove_gtk (GtkContainer *container,
179 AtkPropertyValues values = { NULL };
180 AtkObject* atk_parent;
181 AtkObject *atk_child;
182 GailContainer *gail_container;
185 atk_parent = ATK_OBJECT (data);
186 atk_child = gtk_widget_get_accessible (widget);
190 g_value_init (&values.old_value, G_TYPE_POINTER);
191 g_value_set_pointer (&values.old_value, atk_parent);
193 values.property_name = "accessible-parent";
195 g_object_ref (atk_child);
196 g_signal_emit_by_name (atk_child,
197 "property_change::accessible-parent", &values, NULL);
198 g_object_unref (atk_child);
200 gail_container = GAIL_CONTAINER (atk_parent);
201 index = g_list_index (gail_container->children, widget);
202 g_list_free (gail_container->children);
203 gail_container->children = gtk_container_get_children (container);
204 if (index >= 0 && index <= g_list_length (gail_container->children))
205 g_signal_emit_by_name (atk_parent, "children_changed::remove",
206 index, atk_child, NULL);
212 gail_container_real_initialize (AtkObject *obj,
215 GailContainer *container = GAIL_CONTAINER (obj);
218 ATK_OBJECT_CLASS (gail_container_parent_class)->initialize (obj, data);
220 container->children = gtk_container_get_children (GTK_CONTAINER (data));
223 * We store the handler ids for these signals in case some objects
224 * need to remove these handlers.
226 handler_id = g_signal_connect (data,
228 G_CALLBACK (gail_container_add_gtk),
230 g_object_set_data (G_OBJECT (obj), "gail-add-handler-id",
231 GUINT_TO_POINTER (handler_id));
232 handler_id = g_signal_connect (data,
234 G_CALLBACK (gail_container_remove_gtk),
236 g_object_set_data (G_OBJECT (obj), "gail-remove-handler-id",
237 GUINT_TO_POINTER (handler_id));
239 if (GTK_IS_TOOLBAR (data))
240 obj->role = ATK_ROLE_TOOL_BAR;
241 else if (GTK_IS_VIEWPORT (data))
242 obj->role = ATK_ROLE_VIEWPORT;
244 obj->role = ATK_ROLE_PANEL;
248 gail_container_finalize (GObject *object)
250 GailContainer *container = GAIL_CONTAINER (object);
252 g_list_free (container->children);
253 G_OBJECT_CLASS (gail_container_parent_class)->finalize (object);