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