]> Pileus Git - ~andy/gtk/blob - gtk/a11y/gailhtmlboxtext.c
gail: Move from modules/other/gail to gtk/a11y
[~andy/gtk] / gtk / a11y / gailhtmlboxtext.c
1 /* GAIL - The GNOME Accessibility Implementation Library
2  * Copyright 2001 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 "gailhtmlboxtext.h"
23
24 static void           gail_html_box_text_class_init          (GailHtmlBoxTextClass *klass);
25 static void           gail_html_box_text_text_interface_init (AtkTextIface        *iface);
26 static gchar*         gail_html_box_text_get_text            (AtkText             *text,
27                                                               gint                start_offset,
28                                                               gint                end_offset);
29 static gchar*         gail_html_box_text_get_text_after_offset 
30                                                              (AtkText             *text,
31                                                               gint                offset,
32                                                               AtkTextBoundary     boundary_type,
33                                                               gint                *start_offset,
34                                                               gint                *end_offset);
35 static gchar*         gail_html_box_text_get_text_at_offset  (AtkText             *text,
36                                                               gint                offset,
37                                                               AtkTextBoundary     boundary_type,
38                                                               gint                *start_offset,
39                                                               gint                *end_offset);
40 static gchar*         gail_html_box_text_get_text_before_offset 
41                                                              (AtkText             *text,
42                                                               gint                offset,
43                                                               AtkTextBoundary     boundary_type,
44                                                               gint                *start_offset,
45                                                               gint                *end_offset);
46 static gunichar       gail_html_box_text_get_character_at_offset 
47                                                               (AtkText            *text,
48                                                                gint               offset);
49 static gint           gail_html_box_text_get_character_count  (AtkText            *text);
50 static gint           gail_html_box_text_get_caret_offset     (AtkText            *text);
51 static gboolean       gail_html_box_text_set_caret_offset     (AtkText            *text,
52                                                                gint               offset);
53 static gint           gail_html_box_text_get_offset_at_point  (AtkText            *text,
54                                                                gint               x,
55                                                                gint               y,
56                                                                AtkCoordType       coords);
57 static void           gail_html_box_text_get_character_extents (AtkText           *text,
58                                                                 gint              offset,
59                                                                 gint              *x,
60                                                                 gint              *y,
61                                                                 gint              *width,
62                                                                 gint              *height,
63                                                                 AtkCoordType      coords);
64 static AtkAttributeSet* 
65                       gail_html_box_text_get_run_attributes    (AtkText           *text,
66                                                                 gint              offset,
67                                                                 gint              *start_offset,
68                                                                 gint              *end_offset);
69 static AtkAttributeSet* 
70                       gail_html_box_text_get_default_attributes (AtkText          *text);
71 static gint           gail_html_box_text_get_n_selections      (AtkText           *text);
72 static gchar*         gail_html_box_text_get_selection         (AtkText           *text,
73                                                                 gint              selection_num,
74                                                                 gint              *start_pos,
75                                                                 gint              *end_pos);
76 static gboolean       gail_html_box_text_add_selection         (AtkText           *text,
77                                                                 gint              start_pos,
78                                                                 gint              end_pos);
79 static gboolean       gail_html_box_text_remove_selection      (AtkText           *text,
80                                                                 gint              selection_num);
81 static gboolean       gail_html_box_text_set_selection         (AtkText           *text,
82                                                                 gint              selection_num,
83                                                                 gint              start_pos,
84                                                                 gint              end_pos);
85 static AtkAttributeSet*
86                       add_to_attr_set                          (AtkAttributeSet   *attrib_set,
87                                                                 GtkTextAttributes *attrs,
88                                                                 AtkTextAttribute  attr);
89 static gchar*         get_text_near_offset                     (AtkText           *text,
90                                                                 GailOffsetType    function,
91                                                                 AtkTextBoundary   boundary_type,
92                                                                 gint              offset,
93                                                                 gint              *start_offset,
94                                                                 gint              *end_offset);
95
96 G_DEFINE_TYPE_WITH_CODE (GailHtmlBoxText, gail_html_box_text, GAIL_TYPE_HTML_BOX,
97                          G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, gail_html_box_text_text_interface_init))
98
99 AtkObject*
100 gail_html_box_text_new (GObject *obj)
101 {
102   gpointer object;
103   AtkObject *atk_object;
104   GailHtmlBoxText *gail_text;
105
106   g_return_val_if_fail (HTML_IS_BOX_TEXT (obj), NULL);
107   object = g_object_new (GAIL_TYPE_HTML_BOX_TEXT, NULL);
108   atk_object = ATK_OBJECT (object);
109   gail_text = GAIL_HTML_BOX_TEXT (object);
110
111   atk_object_initialize (atk_object, obj);
112   gail_text->texthelper = gail_text_helper_new ();
113 #if 0
114   gail_text_helper_text_setup (gail_text->texthelper,
115                                HTML_BOX_TEXT (obj)->master->text);
116 #endif
117
118   atk_object->role =  ATK_ROLE_TEXT;
119   return atk_object;
120 }
121
122 static void
123 gail_html_box_text_class_init (GailHtmlBoxTextClass *klass)
124 {
125 }
126
127 static void
128 gail_html_box_text_text_interface_init (AtkTextIface *iface)
129 {
130   iface->get_text = gail_html_box_text_get_text;
131   iface->get_text_after_offset = gail_html_box_text_get_text_after_offset;
132   iface->get_text_at_offset = gail_html_box_text_get_text_at_offset;
133   iface->get_text_before_offset = gail_html_box_text_get_text_before_offset;
134   iface->get_character_at_offset = gail_html_box_text_get_character_at_offset;
135   iface->get_character_count = gail_html_box_text_get_character_count;
136   iface->get_caret_offset = gail_html_box_text_get_caret_offset;
137   iface->set_caret_offset = gail_html_box_text_set_caret_offset;
138   iface->get_offset_at_point = gail_html_box_text_get_offset_at_point;
139   iface->get_character_extents = gail_html_box_text_get_character_extents;
140   iface->get_n_selections = gail_html_box_text_get_n_selections;
141   iface->get_selection = gail_html_box_text_get_selection;
142   iface->add_selection = gail_html_box_text_add_selection;
143   iface->remove_selection = gail_html_box_text_remove_selection;
144   iface->set_selection = gail_html_box_text_set_selection;
145   iface->get_run_attributes = gail_html_box_text_get_run_attributes;
146   iface->get_default_attributes = gail_html_box_text_get_default_attributes;
147 }
148
149 static gchar*
150 gail_html_box_text_get_text (AtkText *text,
151                              gint    start_offset,
152                              gint    end_offset)
153 {
154   GailHtmlBoxText *gail_text;
155   GtkTextBuffer *buffer;
156   GtkTextIter start, end;
157
158   g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), NULL);
159   gail_text = GAIL_HTML_BOX_TEXT (text);
160   g_return_val_if_fail (gail_text->texthelper, NULL);
161
162   buffer = gail_text->texthelper->buffer;
163   gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
164   gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
165
166   return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
167 }
168
169 static gchar*
170 gail_html_box_text_get_text_after_offset (AtkText         *text,
171                                           gint            offset,
172                                           AtkTextBoundary boundary_type,
173                                           gint            *start_offset,
174                                           gint            *end_offset)
175 {
176   return get_text_near_offset (text, GAIL_AFTER_OFFSET,
177                                boundary_type, offset, 
178                                start_offset, end_offset);
179 }
180
181 static gchar*
182 gail_html_box_text_get_text_at_offset (AtkText         *text,
183                                        gint            offset,
184                                        AtkTextBoundary boundary_type,
185                                        gint            *start_offset,
186                                        gint            *end_offset)
187 {
188   return get_text_near_offset (text, GAIL_AT_OFFSET,
189                                boundary_type, offset, 
190                                start_offset, end_offset);
191 }
192
193 static gchar*
194 gail_html_box_text_get_text_before_offset (AtkText         *text,
195                                            gint            offset,
196                                            AtkTextBoundary boundary_type,
197                                            gint            *start_offset,
198                                            gint            *end_offset)
199 {
200   return get_text_near_offset (text, GAIL_BEFORE_OFFSET,
201                                boundary_type, offset, 
202                                start_offset, end_offset);
203 }
204
205 static gunichar
206 gail_html_box_text_get_character_at_offset (AtkText *text,
207                                             gint    offset)
208 {
209   GailHtmlBoxText *gail_item;
210   GtkTextIter start, end;
211   GtkTextBuffer *buffer;
212   gchar *string;
213   gchar *index;
214
215   g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), 0);
216   gail_item = GAIL_HTML_BOX_TEXT (text);
217   buffer = gail_item->texthelper->buffer;
218   gtk_text_buffer_get_start_iter (buffer, &start);
219   gtk_text_buffer_get_end_iter (buffer, &end);
220   string = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
221   index = g_utf8_offset_to_pointer (string, offset);
222   g_free (string);
223
224   return g_utf8_get_char (index);
225 }
226
227 static gint
228 gail_html_box_text_get_character_count (AtkText *text)
229 {
230   GtkTextBuffer *buffer;
231   GailHtmlBoxText *gail_text;
232
233   g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), 0);
234   gail_text = GAIL_HTML_BOX_TEXT (text);
235   g_return_val_if_fail (gail_text->texthelper, 0);
236   buffer = gail_text->texthelper->buffer;
237   return gtk_text_buffer_get_char_count (buffer);
238 }
239
240 static gint
241 gail_html_box_text_get_caret_offset (AtkText *text)
242 {
243   GailHtmlBoxText *gail_text;
244   GtkTextBuffer *buffer;
245   GtkTextMark *cursor_mark;
246   GtkTextIter cursor_itr;
247
248   g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), 0);
249   gail_text = GAIL_HTML_BOX_TEXT (text);
250   g_return_val_if_fail (gail_text->texthelper, 0);
251   buffer = gail_text->texthelper->buffer;
252   cursor_mark = gtk_text_buffer_get_insert (buffer);
253   gtk_text_buffer_get_iter_at_mark (buffer, &cursor_itr, cursor_mark);
254   return gtk_text_iter_get_offset (&cursor_itr);
255 }
256
257 static gboolean
258 gail_html_box_text_set_caret_offset (AtkText *text,
259                                      gint    offset)
260 {
261   GailHtmlBoxText *gail_text;
262   GtkTextBuffer *buffer;
263   GtkTextIter pos_itr;
264
265   g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), FALSE);
266   gail_text = GAIL_HTML_BOX_TEXT (text);
267   g_return_val_if_fail (gail_text->texthelper, FALSE);
268   buffer = gail_text->texthelper->buffer;
269   gtk_text_buffer_get_iter_at_offset (buffer,  &pos_itr, offset);
270   gtk_text_buffer_move_mark_by_name (buffer, "insert", &pos_itr);
271   return TRUE;
272 }
273
274 static gint
275 gail_html_box_text_get_offset_at_point (AtkText      *text,
276                                         gint         x,
277                                         gint         y,
278                                         AtkCoordType coords)
279 {
280   return -1;
281 }
282
283 static void
284 gail_html_box_text_get_character_extents (AtkText      *text,
285                                           gint         offset,
286                                           gint         *x,
287                                           gint         *y,
288                                           gint         *width,
289                                           gint         *height,
290                                           AtkCoordType coords)
291 {
292   return;
293 }
294
295 static AtkAttributeSet*
296 gail_html_box_text_get_run_attributes (AtkText *text,
297                                        gint    offset,
298                                        gint    *start_offset,
299                                        gint    *end_offset)
300 {
301   return NULL;
302 }
303
304 static AtkAttributeSet*
305 gail_html_box_text_get_default_attributes (AtkText *text)
306 {
307   return NULL;
308 }
309
310 static gint
311 gail_html_box_text_get_n_selections (AtkText *text)
312 {
313   return 0;
314 }
315
316 static gchar*
317 gail_html_box_text_get_selection (AtkText *text,
318                                   gint    selection_num,
319                                   gint    *start_pos,
320                                   gint    *end_pos)
321 {
322   return NULL;
323 }
324
325 static gboolean
326 gail_html_box_text_add_selection (AtkText *text,
327                                 gint    start_pos,
328                                 gint    end_pos)
329 {
330   return FALSE;
331 }
332
333 static gboolean
334 gail_html_box_text_remove_selection (AtkText *text,
335                                  gint    selection_num)
336 {
337   return FALSE;
338 }
339
340 static gboolean
341 gail_html_box_text_set_selection (AtkText *text,
342                                   gint    selection_num,
343                                   gint    start_pos,
344                                   gint    end_pos)
345 {
346   return FALSE;
347 }
348
349 static AtkAttributeSet*
350 add_to_attr_set (AtkAttributeSet   *attrib_set,
351                  GtkTextAttributes *attrs,
352                  AtkTextAttribute  attr)
353 {
354   gchar *value;
355
356   switch (attr)
357     {
358     case ATK_TEXT_ATTR_LEFT_MARGIN:
359       value = g_strdup_printf ("%i", attrs->left_margin);
360       break;
361     case ATK_TEXT_ATTR_RIGHT_MARGIN:
362       value = g_strdup_printf ("%i", attrs->right_margin);
363       break;
364     case ATK_TEXT_ATTR_INDENT:
365       value = g_strdup_printf ("%i", attrs->indent);
366       break;
367     case ATK_TEXT_ATTR_INVISIBLE:
368       value = g_strdup (atk_text_attribute_get_value (attr, attrs->invisible));
369       break;
370     case ATK_TEXT_ATTR_EDITABLE:
371       value = g_strdup (atk_text_attribute_get_value (attr, attrs->editable));
372       break;
373     case ATK_TEXT_ATTR_PIXELS_ABOVE_LINES:
374       value = g_strdup_printf ("%i", attrs->pixels_above_lines);
375       break;
376     case ATK_TEXT_ATTR_PIXELS_BELOW_LINES:
377       value = g_strdup_printf ("%i", attrs->pixels_below_lines);
378       break;
379     case ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP:
380       value = g_strdup_printf ("%i", attrs->pixels_inside_wrap);
381       break;
382     case ATK_TEXT_ATTR_BG_FULL_HEIGHT:
383       value = g_strdup (atk_text_attribute_get_value (attr, attrs->bg_full_height));
384       break;
385     case ATK_TEXT_ATTR_RISE:
386       value = g_strdup_printf ("%i", attrs->appearance.rise);
387       break;
388     case ATK_TEXT_ATTR_UNDERLINE:
389       value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.underline));
390       break;
391     case ATK_TEXT_ATTR_STRIKETHROUGH:
392       value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.strikethrough));
393       break;
394     case ATK_TEXT_ATTR_SIZE:
395       value = g_strdup_printf ("%i", 
396                               pango_font_description_get_size (attrs->font));
397       break;
398     case ATK_TEXT_ATTR_SCALE:
399       value = g_strdup_printf ("%g", attrs->font_scale);
400       break;
401     case ATK_TEXT_ATTR_WEIGHT:
402       value = g_strdup_printf ("%d", 
403                               pango_font_description_get_weight (attrs->font));
404       break;
405     case ATK_TEXT_ATTR_LANGUAGE:
406       value = g_strdup ((gchar *)(attrs->language));
407       break;
408     case ATK_TEXT_ATTR_FAMILY_NAME:
409       value = g_strdup (pango_font_description_get_family (attrs->font));
410       break;
411     case ATK_TEXT_ATTR_BG_COLOR:
412       value = g_strdup_printf ("%u,%u,%u",
413                                attrs->appearance.bg_color.red,
414                                attrs->appearance.bg_color.green,
415                                attrs->appearance.bg_color.blue);
416       break;
417     case ATK_TEXT_ATTR_FG_COLOR:
418       value = g_strdup_printf ("%u,%u,%u",
419                                attrs->appearance.fg_color.red,
420                                attrs->appearance.fg_color.green,
421                                attrs->appearance.fg_color.blue);
422       break;
423     case ATK_TEXT_ATTR_BG_STIPPLE:
424       value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.bg_stipple ? 1 : 0));
425       break;
426     case ATK_TEXT_ATTR_FG_STIPPLE:
427       value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.fg_stipple ? 1 : 0));
428       break;
429     case ATK_TEXT_ATTR_WRAP_MODE:
430       value = g_strdup (atk_text_attribute_get_value (attr, attrs->wrap_mode));
431       break;
432     case ATK_TEXT_ATTR_DIRECTION:
433       value = g_strdup (atk_text_attribute_get_value (attr, attrs->direction));
434       break;
435     case ATK_TEXT_ATTR_JUSTIFICATION:
436       value = g_strdup (atk_text_attribute_get_value (attr, attrs->justification));
437       break;
438     case ATK_TEXT_ATTR_STRETCH:
439       value = g_strdup (atk_text_attribute_get_value (attr, 
440                         pango_font_description_get_stretch (attrs->font)));
441       break;
442     case ATK_TEXT_ATTR_VARIANT:
443       value = g_strdup (atk_text_attribute_get_value (attr, 
444                         pango_font_description_get_variant (attrs->font)));
445       break;
446     case ATK_TEXT_ATTR_STYLE:
447       value = g_strdup (atk_text_attribute_get_value (attr, 
448                         pango_font_description_get_style (attrs->font)));
449       break;
450     default:
451       value = NULL;
452       break;
453     }
454   return gail_text_helper_add_attribute (attrib_set, 
455                                          attr,
456                                          value);
457 }
458
459 static gchar*
460 get_text_near_offset (AtkText          *text,
461                       GailOffsetType   function,
462                       AtkTextBoundary  boundary_type,
463                       gint             offset,
464                       gint             *start_offset,
465                       gint             *end_offset)
466 {
467   return gail_text_helper_get_text (GAIL_HTML_BOX_TEXT (text)->texthelper, NULL,
468                                     function, boundary_type, offset, 
469                                     start_offset, end_offset);
470 }