1 /* This file is part of the GtkHTML library.
3 * Copyright 2002 Ximian, Inc.
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.
27 #include "htmlengine.h"
28 #include "htmlobject.h"
31 #include "paragraph.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
,
41 static GtkContainerAccessibleClass
*parent_class
= NULL
;
44 get_n_actions (AtkAction
*action
)
50 get_description (AtkAction
*action
,
54 return _("grab focus");
60 action_get_name (AtkAction
*action
,
64 return _("grab focus");
70 do_action (AtkAction
*action
,
74 gboolean return_value
= TRUE
;
76 widget
= gtk_accessible_get_widget (GTK_ACCESSIBLE (action
));
85 if (!gtk_widget_get_sensitive (widget
) || !gtk_widget_get_visible (widget
))
90 gtk_widget_grab_focus (widget
);
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
;
110 gtk_html_a11y_get_type (void)
112 static GType type
= 0;
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
,
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
);
143 gtk_html_a11y_finalize (GObject
*obj
)
145 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
149 gtk_html_a11y_get_n_children (AtkObject
*accessible
)
155 if (GTK_HTML_A11Y_GTKHTML (accessible
)->engine
->parsing
)
158 ss
= atk_object_ref_state_set (accessible
);
159 if (atk_state_set_contains_state (ss
, ATK_STATE_DEFUNCT
)) {
165 clue
= GTK_HTML_A11Y_GTKHTML (accessible
)->engine
->clue
;
167 AtkObject
*atk_clue
= html_utils_get_accessible (clue
, NULL
);
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
);
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); */
186 gtk_html_a11y_ref_child (AtkObject
*accessible
,
190 AtkObject
*accessible_child
= NULL
;
193 if (GTK_HTML_A11Y_GTKHTML (accessible
)->engine
->parsing
)
196 ss
= atk_object_ref_state_set (accessible
);
197 if (atk_state_set_contains_state (ss
, ATK_STATE_DEFUNCT
)) {
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
);
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
);
211 g_object_unref (ss_clue
);
214 child
= html_object_get_child (GTK_HTML_A11Y_GTKHTML (accessible
)->engine
->clue
, index
);
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
;
228 gtk_html_a11y_get_name (AtkObject
*obj
)
230 if (obj
->name
!= NULL
) {
234 return _("Panel containing HTML");
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
;
254 gtk_html_a11y_init (GtkHTMLA11Y
*a11y
)
259 gtk_html_a11y_get_focus_object (GtkWidget
*widget
)
262 HTMLObject
* htmlobj
= NULL
;
263 AtkObject
*obj
= NULL
;
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
;
276 obj
= html_utils_get_accessible (htmlobj
, NULL
);
281 static AtkObject
* gtk_html_a11y_focus_object
= NULL
;
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
)
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
);
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
);
313 if (G_IS_HTML_A11Y_TEXT (focus_object
)) {
316 offset
= (GTK_HTML (widget
))->engine
->cursor
->offset
;
317 g_signal_emit_by_name (focus_object
, "text_caret_moved",offset
);
323 gtk_html_a11y_insert_object_cb (GtkWidget
*widget
,
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
);
346 gtk_html_a11y_delete_object_cb (GtkWidget
*widget
,
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
);
366 gtk_html_a11y_initialize (AtkObject
*obj
,
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
),
389 g_signal_connect (widget
, "cursor_changed",
390 G_CALLBACK (gtk_html_a11y_cursor_changed_cb
),
392 g_signal_connect_after (widget
, "object_inserted",
393 G_CALLBACK (gtk_html_a11y_insert_object_cb
),
395 g_signal_connect_after (widget
, "object_delete",
396 G_CALLBACK (gtk_html_a11y_delete_object_cb
),
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
);