]> Pileus Git - ~andy/gtk/blob - gtk/a11y/gtkcontaineraccessible.c
ad475a4187a1f46c36e44c88bc101bda34e248b6
[~andy/gtk] / gtk / a11y / gtkcontaineraccessible.c
1 /* GAIL - The GNOME Accessibility Implementation Library
2  * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 #include "config.h"
21
22 #include <gtk/gtk.h>
23 #include "gtkcontaineraccessible.h"
24
25
26 G_DEFINE_TYPE (GtkContainerAccessible, gtk_container_accessible, GAIL_TYPE_WIDGET)
27
28 static void
29 gtk_container_accessible_init (GtkContainerAccessible *container)
30 {
31 }
32
33 static gint
34 gtk_container_accessible_get_n_children (AtkObject* obj)
35 {
36   GtkWidget *widget;
37   GList *children;
38   gint count = 0;
39
40   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
41   if (widget == NULL)
42     return 0;
43
44   children = gtk_container_get_children (GTK_CONTAINER(widget));
45   count = g_list_length (children);
46   g_list_free (children);
47
48   return count;
49 }
50
51 static AtkObject *
52 gtk_container_accessible_ref_child (AtkObject *obj,
53                                     gint       i)
54 {
55   GList *children, *tmp_list;
56   AtkObject  *accessible;
57   GtkWidget *widget;
58
59   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
60   if (widget == NULL)
61     return NULL;
62
63   children = gtk_container_get_children (GTK_CONTAINER (widget));
64   tmp_list = g_list_nth (children, i);
65   if (!tmp_list)
66     {
67       g_list_free (children);
68       return NULL;
69     }
70   accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
71
72   g_list_free (children);
73   g_object_ref (accessible);
74
75   return accessible;
76 }
77
78 static gint
79 gtk_container_accessible_add_gtk (GtkContainer *container,
80                                   GtkWidget    *widget,
81                                   gpointer      data)
82 {
83   GtkContainerAccessible *accessible = GTK_CONTAINER_ACCESSIBLE (data);
84   GtkContainerAccessibleClass *klass;
85
86   klass = GTK_CONTAINER_ACCESSIBLE_GET_CLASS (accessible);
87
88   if (klass->add_gtk)
89     return klass->add_gtk (container, widget, data);
90   else
91     return 1;
92 }
93  
94 static gint
95 gtk_container_accessible_remove_gtk (GtkContainer *container,
96                            GtkWidget    *widget,
97                            gpointer     data)
98 {
99   GtkContainerAccessible *accessible = GTK_CONTAINER_ACCESSIBLE (data);
100   GtkContainerAccessibleClass *klass;
101
102   klass = GTK_CONTAINER_ACCESSIBLE_GET_CLASS (accessible);
103
104   if (klass->remove_gtk)
105     return klass->remove_gtk (container, widget, data);
106   else
107     return 1;
108 }
109
110 static gint
111 gtk_container_accessible_real_add_gtk (GtkContainer *container,
112                                        GtkWidget    *widget,
113                                        gpointer      data)
114 {
115   AtkObject *atk_parent;
116   AtkObject *atk_child;
117   GtkContainerAccessible *accessible;
118   gint index;
119
120   atk_parent = ATK_OBJECT (data);
121   atk_child = gtk_widget_get_accessible (widget);
122   accessible = GTK_CONTAINER_ACCESSIBLE (atk_parent);
123
124   g_object_notify (G_OBJECT (atk_child), "accessible_parent");
125   g_list_free (accessible->children);
126   accessible->children = gtk_container_get_children (container);
127   index = g_list_index (accessible->children, widget);
128   g_signal_emit_by_name (atk_parent, "children_changed::add", index, atk_child, NULL);
129
130   return 1;
131 }
132
133 static gint
134 gtk_container_accessible_real_remove_gtk (GtkContainer *container,
135                                           GtkWidget    *widget,
136                                           gpointer      data)
137 {
138   AtkObject* atk_parent;
139   AtkObject *atk_child;
140   GtkContainerAccessible *accessible;
141   gint index;
142
143   atk_parent = ATK_OBJECT (data);
144   atk_child = gtk_widget_get_accessible (widget);
145   accessible = GTK_CONTAINER_ACCESSIBLE (atk_parent);
146
147   g_object_notify (G_OBJECT (atk_child), "accessible_parent");
148   index = g_list_index (accessible->children, widget);
149   g_list_free (accessible->children);
150   accessible->children = gtk_container_get_children (container);
151   if (index >= 0 && index <= g_list_length (accessible->children))
152     g_signal_emit_by_name (atk_parent, "children_changed::remove", index, atk_child, NULL);
153
154   return 1;
155 }
156
157 static void
158 gtk_container_accessible_real_initialize (AtkObject *obj,
159                                           gpointer   data)
160 {
161   GtkContainerAccessible *accessible = GTK_CONTAINER_ACCESSIBLE (obj);
162
163   ATK_OBJECT_CLASS (gtk_container_accessible_parent_class)->initialize (obj, data);
164
165   accessible->children = gtk_container_get_children (GTK_CONTAINER (data));
166
167   g_signal_connect (data, "add", G_CALLBACK (gtk_container_accessible_add_gtk), obj);
168   g_signal_connect (data, "remove", G_CALLBACK (gtk_container_accessible_remove_gtk), obj);
169
170   if (GTK_IS_TOOLBAR (data))
171     obj->role = ATK_ROLE_TOOL_BAR;
172   else if (GTK_IS_VIEWPORT (data))
173     obj->role = ATK_ROLE_VIEWPORT;
174   else
175     obj->role = ATK_ROLE_PANEL;
176 }
177
178 static void
179 gtk_container_accessible_finalize (GObject *object)
180 {
181   GtkContainerAccessible *accessible = GTK_CONTAINER_ACCESSIBLE (object);
182
183   g_list_free (accessible->children);
184
185   G_OBJECT_CLASS (gtk_container_accessible_parent_class)->finalize (object);
186 }
187
188 static void
189 gtk_container_accessible_class_init (GtkContainerAccessibleClass *klass)
190 {
191   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
192   AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
193
194   gobject_class->finalize = gtk_container_accessible_finalize;
195
196   class->get_n_children = gtk_container_accessible_get_n_children;
197   class->ref_child = gtk_container_accessible_ref_child;
198   class->initialize = gtk_container_accessible_real_initialize;
199
200   klass->add_gtk = gtk_container_accessible_real_add_gtk;
201   klass->remove_gtk = gtk_container_accessible_real_remove_gtk;
202 }