No issues found
1 /*
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with the program; if not, see <http://www.gnu.org/licenses/>
15 *
16 *
17 * Authors:
18 * Eric Zhao <eric.zhao@sun.com>
19 *
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
21 * Copyright (C) 2004 Sun Microsystem, Inc.
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <atk/atk.h>
30
31 #include "table/e-cell-vbox.h"
32
33 #include "gal-a11y-e-cell-registry.h"
34 #include "gal-a11y-e-cell-vbox.h"
35
36 static GObjectClass *parent_class;
37 static AtkComponentIface *component_parent_iface;
38 #define PARENT_TYPE (gal_a11y_e_cell_get_type ())
39
40 static gint
41 ecv_get_n_children (AtkObject *a11y)
42 {
43 g_return_val_if_fail (GAL_A11Y_IS_E_CELL_VBOX (a11y), 0);
44
45 return GAL_A11Y_E_CELL_VBOX (a11y)->a11y_subcell_count;
46 }
47
48 static void
49 subcell_destroyed (gpointer data)
50 {
51 GalA11yECell *cell;
52 AtkObject *parent;
53 GalA11yECellVbox *gaev;
54
55 g_return_if_fail (GAL_A11Y_IS_E_CELL (data));
56 cell = GAL_A11Y_E_CELL (data);
57
58 parent = atk_object_get_parent (ATK_OBJECT (cell));
59 g_return_if_fail (GAL_A11Y_IS_E_CELL_VBOX (parent));
60 gaev = GAL_A11Y_E_CELL_VBOX (parent);
61
62 if (cell->view_col < gaev->a11y_subcell_count)
63 gaev->a11y_subcells[cell->view_col] = NULL;
64 }
65
66 static AtkObject *
67 ecv_ref_child (AtkObject *a11y,
68 gint i)
69 {
70 GalA11yECellVbox *gaev = GAL_A11Y_E_CELL_VBOX (a11y);
71 GalA11yECell *gaec = GAL_A11Y_E_CELL (a11y);
72 ECellVboxView *ecvv = (ECellVboxView *) (gaec->cell_view);
73 AtkObject *ret;
74 if (i < gaev->a11y_subcell_count) {
75 if (gaev->a11y_subcells[i] == NULL) {
76 ECellView *subcell_view;
77 gint model_col, row;
78 row = gaec->row;
79 model_col = ecvv->model_cols[i];
80 subcell_view = ecvv->subcell_views[i];
81 /* FIXME Should the view column use a fake
82 * one or the same as its parent? */
83 ret = gal_a11y_e_cell_registry_get_object (
84 NULL,
85 gaec->item,
86 subcell_view,
87 a11y,
88 model_col,
89 gaec->view_col,
90 row);
91 gaev->a11y_subcells[i] = ret;
92 g_object_ref (ret);
93 g_object_weak_ref (
94 G_OBJECT (ret),
95 (GWeakNotify) subcell_destroyed,
96 ret);
97 } else {
98 ret = (AtkObject *) gaev->a11y_subcells[i];
99 if (ATK_IS_OBJECT (ret))
100 g_object_ref (ret);
101 else
102 ret = NULL;
103 }
104 } else {
105 ret = NULL;
106 }
107
108 return ret;
109 }
110
111 static void
112 ecv_dispose (GObject *object)
113 {
114 GalA11yECellVbox *gaev = GAL_A11Y_E_CELL_VBOX (object);
115 if (gaev->a11y_subcells)
116 g_free (gaev->a11y_subcells);
117
118 if (parent_class->dispose)
119 parent_class->dispose (object);
120 }
121
122 /* AtkComponet interface */
123 static AtkObject *
124 ecv_ref_accessible_at_point (AtkComponent *component,
125 gint x,
126 gint y,
127 AtkCoordType coord_type)
128 {
129 gint x0, y0, width, height;
130 gint subcell_height, i;
131
132 GalA11yECell *gaec = GAL_A11Y_E_CELL (component);
133 ECellVboxView *ecvv = (ECellVboxView *) (gaec->cell_view);
134
135 atk_component_get_extents (component, &x0, &y0, &width, &height, coord_type);
136 x -= x0;
137 y -= y0;
138 if (x < 0 || x > width || y < 0 || y > height)
139 return NULL;
140
141 for (i = 0; i < ecvv->subcell_view_count; i++) {
142 subcell_height = e_cell_height (
143 ecvv->subcell_views[i], ecvv->model_cols[i],
144 gaec->view_col, gaec->row);
145 if (0 <= y && y <= subcell_height) {
146 return ecv_ref_child ((AtkObject *) component, i);
147 } else
148 y -= subcell_height;
149 }
150
151 return NULL;
152 }
153
154 static void
155 ecv_class_init (GalA11yECellVboxClass *class)
156 {
157 GObjectClass *object_class = G_OBJECT_CLASS (class);
158 AtkObjectClass *a11y_class = ATK_OBJECT_CLASS (class);
159 parent_class = g_type_class_ref (PARENT_TYPE);
160
161 object_class->dispose = ecv_dispose;
162
163 a11y_class->get_n_children = ecv_get_n_children;
164 a11y_class->ref_child = ecv_ref_child;
165 }
166
167 static void
168 ecv_init (GalA11yECellVbox *a11y)
169 {
170 }
171
172 static void
173 ecv_atk_component_iface_init (AtkComponentIface *iface)
174 {
175 component_parent_iface = g_type_interface_peek_parent (iface);
176
177 iface->ref_accessible_at_point = ecv_ref_accessible_at_point;
178 }
179
180 GType
181 gal_a11y_e_cell_vbox_get_type (void)
182 {
183 static GType type = 0;
184 if (!type) {
185 GTypeInfo info = {
186 sizeof (GalA11yECellVboxClass),
187 (GBaseInitFunc) NULL,
188 (GBaseFinalizeFunc) NULL,
189 (GClassInitFunc) ecv_class_init,
190 (GClassFinalizeFunc) NULL,
191 NULL, /* class_data */
192 sizeof (GalA11yECellVbox),
193 0,
194 (GInstanceInitFunc) ecv_init,
195 NULL /* value_cell */
196 };
197
198 static const GInterfaceInfo atk_component_info = {
199 (GInterfaceInitFunc) ecv_atk_component_iface_init,
200 (GInterfaceFinalizeFunc) NULL,
201 NULL
202 };
203
204 type = g_type_register_static (PARENT_TYPE, "GalA11yECellVbox", &info, 0);
205 gal_a11y_e_cell_type_add_action_interface (type);
206 g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info);
207 }
208
209 return type;
210 }
211
212 AtkObject *gal_a11y_e_cell_vbox_new (ETableItem *item,
213 ECellView *cell_view,
214 AtkObject *parent,
215 gint model_col,
216 gint view_col,
217 gint row)
218 {
219 AtkObject *a11y;
220 GalA11yECell *gaec;
221 GalA11yECellVbox *gaev;
222 ECellVboxView *ecvv;
223
224 a11y = g_object_new (gal_a11y_e_cell_vbox_get_type (), NULL);
225
226 gal_a11y_e_cell_construct (
227 a11y, item, cell_view, parent, model_col, view_col, row);
228
229 gaec = GAL_A11Y_E_CELL (a11y);
230 gaev = GAL_A11Y_E_CELL_VBOX (a11y);
231 ecvv = (ECellVboxView *) (gaec->cell_view);
232 gaev->a11y_subcell_count = ecvv->subcell_view_count;
233 gaev->a11y_subcells = g_malloc0 (sizeof (AtkObject *) * gaev->a11y_subcell_count);
234 return a11y;
235 }