Updated Esperanto translation
[gtkhtml.git] / a11y / object.c
blob6ec52af958dbb83ef55c6bfd13d780145e6b0f95
1 /* This file is part of the GtkHTML library.
3 * Copyright 2002 Ximian, Inc.
5 * Author: Radek Doulik
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
24 #include <config.h>
26 #include "gtkhtml.h"
27 #include "htmlengine.h"
28 #include "htmlobject.h"
30 #include "object.h"
31 #include "paragraph.h"
32 #include "utils.h"
33 #include "text.h"
34 #include <glib/gi18n-lib.h>
36 static void gtk_html_a11y_class_init (GtkHTMLA11YClass *klass);
37 static void gtk_html_a11y_init (GtkHTMLA11Y *a11y);
38 static void gtk_html_a11y_initialize (AtkObject *obj,
39 gpointer data);
41 static GtkContainerAccessibleClass *parent_class = NULL;
43 static gint
44 get_n_actions (AtkAction *action)
46 return 1;
49 static const gchar *
50 get_description (AtkAction *action,
51 gint i)
53 if (i == 0)
54 return _("grab focus");
56 return NULL;
59 static const gchar *
60 action_get_name (AtkAction *action,
61 gint i)
63 if (i == 0)
64 return _("grab focus");
66 return NULL;
69 static gboolean
70 do_action (AtkAction *action,
71 gint i)
73 GtkWidget *widget;
74 gboolean return_value = TRUE;
76 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
78 if (widget == NULL) {
80 * State is defunct
82 return FALSE;
85 if (!gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
86 return FALSE;
88 switch (i) {
89 case 0:
90 gtk_widget_grab_focus (widget);
91 default:
92 return_value = FALSE;
93 break;
95 return return_value;
98 static void
99 atk_action_interface_init (AtkActionIface *iface)
101 g_return_if_fail (iface != NULL);
103 iface->do_action = do_action;
104 iface->get_n_actions = get_n_actions;
105 iface->get_description = get_description;
106 iface->get_name = action_get_name;
109 GType
110 gtk_html_a11y_get_type (void)
112 static GType type = 0;
114 if (!type) {
115 static GTypeInfo tinfo = {
116 sizeof (GtkHTMLA11YClass),
117 NULL, /* base init */
118 NULL, /* base finalize */
119 (GClassInitFunc) gtk_html_a11y_class_init, /* class init */
120 NULL, /* class finalize */
121 NULL, /* class data */
122 sizeof (GtkHTMLA11Y), /* instance size */
123 0, /* nb preallocs */
124 (GInstanceInitFunc) gtk_html_a11y_init, /* instance init */
125 NULL /* value table */
128 static const GInterfaceInfo atk_action_info = {
129 (GInterfaceInitFunc) atk_action_interface_init,
130 (GInterfaceFinalizeFunc) NULL,
131 NULL
134 type = g_type_register_static (GTK_TYPE_CONTAINER_ACCESSIBLE, "GtkHTMLA11Y", &tinfo, 0);
136 g_type_add_interface_static (type, ATK_TYPE_ACTION, &atk_action_info);
139 return type;
142 static void
143 gtk_html_a11y_finalize (GObject *obj)
145 G_OBJECT_CLASS (parent_class)->finalize (obj);
148 static gint
149 gtk_html_a11y_get_n_children (AtkObject *accessible)
151 HTMLObject *clue;
152 gint n_children = 0;
153 AtkStateSet *ss;
155 if (GTK_HTML_A11Y_GTKHTML (accessible)->engine->parsing)
156 return 0;
158 ss = atk_object_ref_state_set (accessible);
159 if (atk_state_set_contains_state (ss, ATK_STATE_DEFUNCT)) {
160 g_object_unref (ss);
161 return 0;
163 g_object_unref (ss);
165 clue = GTK_HTML_A11Y_GTKHTML (accessible)->engine->clue;
166 if (clue) {
167 AtkObject *atk_clue = html_utils_get_accessible (clue, NULL);
168 if (atk_clue) {
169 AtkStateSet *ss_clue = atk_object_ref_state_set (atk_clue);
170 if (atk_state_set_contains_state (ss_clue, ATK_STATE_DEFUNCT)) {
171 g_object_unref (ss_clue);
172 return 0;
174 g_object_unref (ss_clue);
177 n_children = html_object_get_n_children (GTK_HTML_A11Y_GTKHTML (accessible)->engine->clue);
180 /* printf ("gtk_html_a11y_get_n_children resolves to %d\n", n_children); */
182 return n_children;
185 static AtkObject *
186 gtk_html_a11y_ref_child (AtkObject *accessible,
187 gint index)
189 HTMLObject *child;
190 AtkObject *accessible_child = NULL;
191 AtkStateSet *ss;
193 if (GTK_HTML_A11Y_GTKHTML (accessible)->engine->parsing)
194 return NULL;
196 ss = atk_object_ref_state_set (accessible);
197 if (atk_state_set_contains_state (ss, ATK_STATE_DEFUNCT)) {
198 g_object_unref (ss);
199 return NULL;
201 g_object_unref (ss);
203 if (GTK_HTML_A11Y_GTKHTML (accessible)->engine->clue) {
204 AtkObject *atk_clue = html_utils_get_accessible (GTK_HTML_A11Y_GTKHTML (accessible)->engine->clue, NULL);
205 if (atk_clue) {
206 AtkStateSet *ss_clue = atk_object_ref_state_set (atk_clue);
207 if (atk_state_set_contains_state (ss_clue, ATK_STATE_DEFUNCT)) {
208 g_object_unref (ss_clue);
209 return NULL;
211 g_object_unref (ss_clue);
214 child = html_object_get_child (GTK_HTML_A11Y_GTKHTML (accessible)->engine->clue, index);
215 if (child) {
216 accessible_child = html_utils_get_accessible (child, accessible);
217 if (accessible_child)
218 g_object_ref (accessible_child);
222 /* printf ("gtk_html_a11y_ref_child %d resolves to %p\n", index, accessible_child); */
224 return accessible_child;
227 static const gchar *
228 gtk_html_a11y_get_name (AtkObject *obj)
230 if (obj->name != NULL) {
231 return obj->name;
234 return _("Panel containing HTML");
237 static void
238 gtk_html_a11y_class_init (GtkHTMLA11YClass *klass)
240 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
241 AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass);
243 parent_class = g_type_class_peek_parent (klass);
245 atk_class->initialize = gtk_html_a11y_initialize;
246 atk_class->get_n_children = gtk_html_a11y_get_n_children;
247 atk_class->ref_child = gtk_html_a11y_ref_child;
248 atk_class->get_name = gtk_html_a11y_get_name;
250 gobject_class->finalize = gtk_html_a11y_finalize;
253 static void
254 gtk_html_a11y_init (GtkHTMLA11Y *a11y)
258 static AtkObject *
259 gtk_html_a11y_get_focus_object (GtkWidget *widget)
261 GtkHTML * html;
262 HTMLObject * htmlobj = NULL;
263 AtkObject *obj = NULL;
264 gint offset;
266 html = GTK_HTML (widget);
268 g_return_val_if_fail (html && html->engine, NULL);
270 if (!html->engine->caret_mode && !gtk_html_get_editable (html))
271 htmlobj = html_engine_get_focus_object (html->engine, &offset);
272 else if (html->engine && html->engine->cursor)
273 htmlobj = html->engine->cursor->object;
275 if (htmlobj)
276 obj = html_utils_get_accessible (htmlobj, NULL);
278 return obj;
281 static AtkObject * gtk_html_a11y_focus_object = NULL;
283 static void
284 gtk_html_a11y_grab_focus_cb (GtkWidget *widget)
286 AtkObject *focus_object, *obj, *clue;
288 focus_object = gtk_html_a11y_get_focus_object (widget);
289 if (focus_object == NULL)
290 return;
292 obj = gtk_widget_get_accessible (widget);
294 clue = html_utils_get_accessible (GTK_HTML (widget)->engine->clue, obj);
295 atk_object_set_parent (clue, obj);
297 gtk_html_a11y_focus_object = focus_object;
298 atk_focus_tracker_notify (focus_object);
301 static void
302 gtk_html_a11y_cursor_changed_cb (GtkWidget *widget)
304 AtkObject *focus_object;
306 focus_object = gtk_html_a11y_get_focus_object (widget);
307 g_return_if_fail (focus_object != NULL);
309 if (gtk_html_a11y_focus_object != focus_object) {
310 gtk_html_a11y_focus_object = focus_object;
311 atk_focus_tracker_notify (focus_object);
312 } else {
313 if (G_IS_HTML_A11Y_TEXT (focus_object)) {
314 gint offset;
316 offset = (GTK_HTML (widget))->engine->cursor->offset;
317 g_signal_emit_by_name (focus_object, "text_caret_moved",offset);
322 static void
323 gtk_html_a11y_insert_object_cb (GtkWidget *widget,
324 gint pos,
325 gint len)
327 AtkObject * a11y;
329 HTMLCursor *cursor = GTK_HTML (widget)->engine->cursor;
331 a11y = gtk_html_a11y_get_focus_object (widget);
332 g_return_if_fail (a11y != NULL);
334 if (gtk_html_a11y_focus_object != a11y) {
335 gtk_html_a11y_focus_object = a11y;
336 atk_focus_tracker_notify (a11y);
339 if (G_IS_HTML_A11Y_TEXT (a11y)) {
340 g_signal_emit_by_name (a11y, "text_changed::insert", cursor->offset - len, len);
345 static void
346 gtk_html_a11y_delete_object_cb (GtkWidget *widget,
347 gint pos,
348 gint len)
350 AtkObject * a11y;
352 a11y = gtk_html_a11y_get_focus_object (widget);
353 g_return_if_fail (a11y != NULL);
355 if (gtk_html_a11y_focus_object != a11y) {
356 gtk_html_a11y_focus_object = a11y;
357 atk_focus_tracker_notify (a11y);
360 if (G_IS_HTML_A11Y_TEXT (a11y)) {
361 g_signal_emit_by_name (a11y, "text_changed::delete", pos, len);
365 static void
366 gtk_html_a11y_initialize (AtkObject *obj,
367 gpointer data)
369 GtkWidget *widget;
370 GtkHTML *html;
371 AtkObject *accessible;
372 AtkObject *focus_object = NULL;
374 /* printf ("gtk_html_a11y_initialize\n"); */
376 if (ATK_OBJECT_CLASS (parent_class)->initialize)
377 ATK_OBJECT_CLASS (parent_class)->initialize (obj, data);
379 g_object_set_data (G_OBJECT (obj), GTK_HTML_ID, data);
381 obj->role = ATK_ROLE_PANEL;
383 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
384 accessible = ATK_OBJECT (obj);
386 g_signal_connect (widget, "grab_focus",
387 G_CALLBACK (gtk_html_a11y_grab_focus_cb),
388 NULL);
389 g_signal_connect (widget, "cursor_changed",
390 G_CALLBACK (gtk_html_a11y_cursor_changed_cb),
391 NULL);
392 g_signal_connect_after (widget, "object_inserted",
393 G_CALLBACK (gtk_html_a11y_insert_object_cb),
394 NULL);
395 g_signal_connect_after (widget, "object_delete",
396 G_CALLBACK (gtk_html_a11y_delete_object_cb),
397 NULL);
399 html = GTK_HTML (widget);
401 if (html->engine != NULL && html->engine->clue != NULL) {
402 html_utils_get_accessible (html->engine->clue, accessible);
403 focus_object = gtk_html_a11y_get_focus_object (widget);
406 if (focus_object && gtk_html_a11y_focus_object != focus_object) {
407 gtk_html_a11y_focus_object = focus_object;
408 atk_focus_tracker_notify (focus_object);