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