]> www.fi.muni.cz Git - evince.git/blob - shell/ev-view-accessible.c
369516ff3518479fd31ffe6a90940bda5ebb0199
[evince.git] / shell / ev-view-accessible.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
2 /* this file is part of evince, a gnome document viewer
3  *
4  *  Copyright (C) 2004 Red Hat, Inc
5  *
6  * Evince is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Evince is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19  */
20
21 #include <glib/gi18n.h>
22
23 #include "ev-view-accessible.h"
24 #include "ev-view-private.h"
25
26 #define EV_TYPE_VIEW_ACCESSIBLE      (ev_view_accessible_get_type ())
27 #define EV_VIEW_ACCESSIBLE(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_VIEW_ACCESSIBLE, EvViewAccessible))
28 #define EV_IS_VIEW_ACCESSIBLE(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_VIEW_ACCESSIBLE))
29
30 static GType ev_view_accessible_get_type (void);
31
32 enum {
33         ACTION_SCROLL_UP,
34         ACTION_SCROLL_DOWN,
35         LAST_ACTION
36 };
37
38 static const gchar *const ev_view_accessible_action_names[] = 
39 {
40         N_("Scroll Up"),
41         N_("Scroll Down"),
42         NULL
43 };
44
45 static const gchar *const ev_view_accessible_action_descriptions[] = 
46 {
47         N_("Scroll View Up"),
48         N_("Scroll View Down"),
49         NULL
50 };
51
52 typedef struct {
53         /* Action */
54         gchar *action_descriptions[LAST_ACTION];
55         guint action_idle_handler;  
56         EvScrollType idle_scroll;        
57 } EvViewAccessiblePriv;
58
59 typedef GtkAccessibleClass EvViewAccessibleClass;
60
61 #define EV_VIEW_ACCESSIBLE_GET_PRIVATE(inst) (G_TYPE_INSTANCE_GET_PRIVATE ((inst), EV_TYPE_VIEW_ACCESSIBLE, EvViewAccessiblePriv))
62
63 static void
64 ev_view_accessible_finalize (GObject *object)
65 {
66         EvViewAccessiblePriv *priv = EV_VIEW_ACCESSIBLE_GET_PRIVATE (object);
67         int i;
68         
69         if (priv->action_idle_handler)
70                 g_source_remove (priv->action_idle_handler);
71         for (i = 0; i < LAST_ACTION; i++)       
72                 g_free (priv->action_descriptions [i]);
73 }
74
75 static void ev_view_accessible_class_init (EvViewAccessibleClass *klass)
76 {
77   GObjectClass *object_class = G_OBJECT_CLASS (klass);
78
79   object_class->finalize = ev_view_accessible_finalize;
80
81   g_type_class_add_private (klass, sizeof (EvViewAccessiblePriv));
82 }
83
84 static gchar*
85 ev_view_accessible_get_text (AtkText *text,
86                      gint    start_pos,
87                      gint    end_pos)
88 {
89   GtkWidget *widget;
90
91   widget = GTK_ACCESSIBLE (text)->widget;
92   if (widget == NULL)
93     /* State is defunct */
94     return NULL;
95
96   return NULL;
97 }
98
99 static gunichar 
100 ev_view_accessible_get_character_at_offset (AtkText *text,
101                                     gint     offset)
102 {
103   GtkWidget *widget;
104
105   widget = GTK_ACCESSIBLE (text)->widget;
106   if (widget == NULL)
107     /* State is defunct */
108     return '\0';
109
110   return '\0';
111 }
112
113 static gchar*
114 ev_view_accessible_get_text_before_offset (AtkText          *text,
115                                    gint             offset,
116                                    AtkTextBoundary  boundary_type,
117                                    gint             *start_offset,
118                                    gint             *end_offset)
119 {
120   GtkWidget *widget;
121
122   widget = GTK_ACCESSIBLE (text)->widget;
123   if (widget == NULL)
124     /* State is defunct */
125     return NULL;
126
127   return NULL;
128 }
129
130 static gchar*
131 ev_view_accessible_get_text_at_offset (AtkText          *text,
132                                gint             offset,
133                                AtkTextBoundary  boundary_type,
134                                gint             *start_offset,
135                                gint             *end_offset)
136 {
137   GtkWidget *widget;
138
139   widget = GTK_ACCESSIBLE (text)->widget;
140   if (widget == NULL)
141     /* State is defunct */
142     return NULL;
143
144   return NULL;
145 }
146
147 static gchar*
148 ev_view_accessible_get_text_after_offset  (AtkText          *text,
149                                    gint             offset,
150                                    AtkTextBoundary  boundary_type,
151                                    gint             *start_offset,
152                                    gint             *end_offset)
153 {
154   GtkWidget *widget;
155
156   widget = GTK_ACCESSIBLE (text)->widget;
157   if (widget == NULL)
158     /* State is defunct */
159     return NULL;
160
161   return NULL;
162 }
163
164 static gint
165 ev_view_accessible_get_character_count (AtkText *text)
166 {
167   GtkWidget *widget;
168
169   widget = GTK_ACCESSIBLE (text)->widget;
170   if (widget == NULL)
171     /* State is defunct */
172     return 0;
173
174   return 0;
175 }
176
177 static gint
178 ev_view_accessible_get_caret_offset (AtkText *text)
179 {
180   GtkWidget *widget;
181
182   widget = GTK_ACCESSIBLE (text)->widget;
183   if (widget == NULL)
184     /* State is defunct */
185     return 0;
186  
187   return 0;
188 }
189
190 static gboolean
191 ev_view_accessible_set_caret_offset (AtkText *text, gint offset)
192 {
193   GtkWidget *widget;
194
195   widget = GTK_ACCESSIBLE (text)->widget;
196   if (widget == NULL)
197     /* State is defunct */
198     return FALSE;
199
200   return FALSE;
201 }
202
203 static AtkAttributeSet*
204 ev_view_accessible_get_run_attributes (AtkText *text,
205                                gint    offset,
206                                gint    *start_offset,
207                                gint    *end_offset)
208 {
209   GtkWidget *widget;
210
211   widget = GTK_ACCESSIBLE (text)->widget;
212   if (widget == NULL)
213     /* State is defunct */
214     return NULL;
215  
216   return NULL;
217 }
218
219 static AtkAttributeSet*
220 ev_view_accessible_get_default_attributes (AtkText *text)
221 {
222   GtkWidget *widget;
223
224   widget = GTK_ACCESSIBLE (text)->widget;
225   if (widget == NULL)
226     /* State is defunct */
227     return NULL;
228
229   return NULL;
230 }
231   
232 static void
233 ev_view_accessible_get_character_extents (AtkText *text,
234                                   gint    offset,
235                                   gint    *x,
236                                   gint    *y,
237                                   gint    *width,
238                                   gint    *height,
239                                   AtkCoordType coords)
240 {
241   GtkWidget *widget;
242
243   widget = GTK_ACCESSIBLE (text)->widget;
244   if (widget == NULL)
245     /* State is defunct */
246     return;
247
248   return;
249
250
251 static gint 
252 ev_view_accessible_get_offset_at_point (AtkText *text,
253                                 gint x,
254                                 gint y,
255                                 AtkCoordType coords)
256
257   GtkWidget *widget;
258
259   widget = GTK_ACCESSIBLE (text)->widget;
260   if (widget == NULL)
261     /* State is defunct */
262     return -1;
263
264   return -1;
265 }
266
267 static gint
268 ev_view_accessible_get_n_selections (AtkText              *text)
269 {
270   GtkWidget *widget;
271
272   widget = GTK_ACCESSIBLE (text)->widget;
273   if (widget == NULL)
274     /* State is defunct */
275     return -1;
276     
277   return -1;
278 }
279
280 static gchar*
281 ev_view_accessible_get_selection (AtkText *text,
282                           gint    selection_num,
283                           gint    *start_pos,
284                           gint    *end_pos)
285 {
286   GtkWidget *widget;
287
288   widget = GTK_ACCESSIBLE (text)->widget;
289   if (widget == NULL)
290     /* State is defunct */
291     return NULL;
292
293   return NULL;
294 }
295
296 static gboolean
297 ev_view_accessible_add_selection (AtkText *text,
298                           gint    start_pos,
299                           gint    end_pos)
300 {
301   GtkWidget *widget;
302
303   widget = GTK_ACCESSIBLE (text)->widget;
304   if (widget == NULL)
305     /* State is defunct */
306     return FALSE;
307
308   return FALSE;
309 }
310
311 static gboolean
312 ev_view_accessible_remove_selection (AtkText *text,
313                              gint    selection_num)
314 {
315   GtkWidget *widget;
316
317   widget = GTK_ACCESSIBLE (text)->widget;
318   if (widget == NULL)
319     /* State is defunct */
320     return FALSE;
321
322   return FALSE;
323 }
324
325 static gboolean
326 ev_view_accessible_set_selection (AtkText *text,
327                           gint    selection_num,
328                           gint    start_pos,
329                           gint    end_pos)
330 {
331   GtkWidget *widget;
332
333   widget = GTK_ACCESSIBLE (text)->widget;
334   if (widget == NULL)
335     /* State is defunct */
336     return FALSE;
337
338   return FALSE;
339 }
340
341
342 static void ev_view_accessible_text_iface_init (AtkTextIface * iface)
343 {
344         g_return_if_fail (iface != NULL);
345
346         iface->get_text = ev_view_accessible_get_text;
347         iface->get_character_at_offset = ev_view_accessible_get_character_at_offset;
348         iface->get_text_before_offset = ev_view_accessible_get_text_before_offset;
349         iface->get_text_at_offset = ev_view_accessible_get_text_at_offset;
350         iface->get_text_after_offset = ev_view_accessible_get_text_after_offset;
351         iface->get_caret_offset = ev_view_accessible_get_caret_offset;
352         iface->set_caret_offset = ev_view_accessible_set_caret_offset;
353         iface->get_character_count = ev_view_accessible_get_character_count;
354         iface->get_n_selections = ev_view_accessible_get_n_selections;
355         iface->get_selection = ev_view_accessible_get_selection;
356         iface->add_selection = ev_view_accessible_add_selection;
357         iface->remove_selection = ev_view_accessible_remove_selection;
358         iface->set_selection = ev_view_accessible_set_selection;
359         iface->get_run_attributes = ev_view_accessible_get_run_attributes;
360         iface->get_default_attributes = ev_view_accessible_get_default_attributes;
361         iface->get_character_extents = ev_view_accessible_get_character_extents;
362         iface->get_offset_at_point = ev_view_accessible_get_offset_at_point;
363         return;
364 }
365
366 static gboolean
367 ev_view_accessible_idle_do_action (gpointer data)
368 {
369         EvViewAccessiblePriv* priv = EV_VIEW_ACCESSIBLE_GET_PRIVATE (data);
370         
371         ev_view_scroll (EV_VIEW (GTK_ACCESSIBLE (data)->widget), 
372                         priv->idle_scroll,
373                         FALSE);
374         priv->action_idle_handler = 0;
375         return FALSE;
376 }
377
378 static gboolean
379 ev_view_accessible_action_do_action (AtkAction *action,
380                                      gint       i)
381 {
382         EvViewAccessiblePriv* priv = EV_VIEW_ACCESSIBLE_GET_PRIVATE (action);
383         
384         if (GTK_ACCESSIBLE (action)->widget == NULL)
385                 return FALSE;
386
387         if (priv->action_idle_handler)
388                 return FALSE;
389         
390         switch (i) {
391                 case ACTION_SCROLL_UP:
392                         priv->idle_scroll = EV_SCROLL_PAGE_BACKWARD;
393                         break;
394                 case ACTION_SCROLL_DOWN:
395                         priv->idle_scroll = EV_SCROLL_PAGE_FORWARD;
396                         break;
397                 default:
398                         return FALSE;
399         }
400         priv->action_idle_handler = g_idle_add (ev_view_accessible_idle_do_action, 
401                                                 action);
402         return TRUE;
403 }
404
405 static gint
406 ev_view_accessible_action_get_n_actions (AtkAction *action)
407 {
408         return LAST_ACTION;
409 }
410
411 static const gchar *
412 ev_view_accessible_action_get_description (AtkAction *action,
413                                            gint       i)
414 {
415   EvViewAccessiblePriv* priv = EV_VIEW_ACCESSIBLE_GET_PRIVATE (action);
416
417   if (i < 0 || i >= LAST_ACTION) 
418     return NULL;
419
420   if (priv->action_descriptions[i])
421     return priv->action_descriptions[i];
422   else
423     return ev_view_accessible_action_descriptions[i];
424 }
425
426 static const gchar *
427 ev_view_accessible_action_get_name (AtkAction *action,
428                                     gint       i)
429 {
430   if (i < 0 || i >= LAST_ACTION) 
431     return NULL;
432
433   return ev_view_accessible_action_names[i];
434 }
435
436 static gboolean
437 ev_view_accessible_action_set_description (AtkAction   *action,
438                                            gint         i,
439                                            const gchar *description)
440 {
441   EvViewAccessiblePriv* priv = EV_VIEW_ACCESSIBLE_GET_PRIVATE (action);
442   gchar *old_description;
443
444   if (i < 0 || i >= LAST_ACTION) 
445     return FALSE;
446
447   old_description = priv->action_descriptions[i];
448   priv->action_descriptions[i] = g_strdup (description);
449   g_free (old_description);
450
451   return TRUE;
452 }
453
454 static void ev_view_accessible_action_iface_init (AtkActionIface * iface)
455 {
456         iface->do_action = ev_view_accessible_action_do_action;
457         iface->get_n_actions = ev_view_accessible_action_get_n_actions;
458         iface->get_description = ev_view_accessible_action_get_description;
459         iface->get_name = ev_view_accessible_action_get_name;
460         iface->set_description = ev_view_accessible_action_set_description;
461 }
462
463 GType ev_view_accessible_get_type (void)
464 {
465         static GType type = 0;
466
467         if (G_UNLIKELY (type == 0)) {
468                 GTypeInfo tinfo = {
469                         0,      /* class size */
470                         (GBaseInitFunc) NULL,   /* base init */
471                         (GBaseFinalizeFunc) NULL,       /* base finalize */
472                         (GClassInitFunc) ev_view_accessible_class_init, /* class init */
473                         (GClassFinalizeFunc) NULL,      /* class finalize */
474                         NULL,   /* class data */
475                         0,      /* instance size */
476                         0,      /* nb preallocs */
477                         (GInstanceInitFunc) NULL,       /* instance init */
478                         NULL    /* value table */
479                 };
480
481                 const GInterfaceInfo atk_text_info = {
482                         (GInterfaceInitFunc)
483                             ev_view_accessible_text_iface_init,
484                         (GInterfaceFinalizeFunc) NULL,
485                         NULL
486                 };
487
488                 const GInterfaceInfo atk_action_info = {
489                         (GInterfaceInitFunc)
490                             ev_view_accessible_action_iface_init,
491                         (GInterfaceFinalizeFunc) NULL,
492                         NULL
493                 };
494                 /*
495                  * Figure out the size of the class and instance
496                  * we are deriving from
497                  */
498                 AtkObjectFactory *factory;
499                 GType derived_type;
500                 GTypeQuery query;
501                 GType derived_atk_type;     
502
503                 derived_type = g_type_parent (EV_TYPE_VIEW);
504                 factory = atk_registry_get_factory (atk_get_default_registry (), 
505                                                     derived_type);
506                 derived_atk_type = atk_object_factory_get_accessible_type (factory);
507
508                 g_type_query (derived_atk_type, &query);
509                 tinfo.class_size = query.class_size;
510                 tinfo.instance_size = query.instance_size;
511  
512                 type = g_type_register_static (derived_atk_type, "EvViewAccessible",
513                                                &tinfo, 0);
514                 g_type_add_interface_static (type, ATK_TYPE_TEXT,
515                                              &atk_text_info);
516                 g_type_add_interface_static (type, ATK_TYPE_ACTION,
517                                              &atk_action_info);
518         }
519
520         return type;
521 }
522
523 static AtkObject *ev_view_accessible_new(GObject * obj)
524 {
525         AtkObject *accessible;
526         
527         g_return_val_if_fail(EV_IS_VIEW (obj), NULL);
528
529         accessible = g_object_new (ev_view_accessible_get_type (), NULL);
530         atk_object_initialize (accessible, obj);
531
532         atk_object_set_name (ATK_OBJECT (accessible), _("Document View"));
533         atk_object_set_role (ATK_OBJECT (accessible), ATK_ROLE_UNKNOWN);
534
535         return accessible;
536 }
537
538 typedef AtkObjectFactory      EvViewAccessibleFactory;
539 typedef AtkObjectFactoryClass EvViewAccessibleFactoryClass;
540
541 static void ev_view_accessible_factory_init (EvViewAccessibleFactory *factory)
542 {
543 }
544
545 static GType ev_view_accessible_factory_get_accessible_type(void)
546 {
547         return ev_view_accessible_get_type();
548 }
549
550 static AtkObject *ev_view_accessible_factory_create_accessible (GObject * obj)
551 {
552         return ev_view_accessible_new(obj);
553 }
554
555 static void ev_view_accessible_factory_class_init (AtkObjectFactoryClass * klass)
556 {
557         klass->create_accessible = ev_view_accessible_factory_create_accessible;
558         klass->get_accessible_type =
559             ev_view_accessible_factory_get_accessible_type;
560 }
561
562 G_DEFINE_TYPE (EvViewAccessibleFactory, ev_view_accessible_factory, ATK_TYPE_OBJECT_FACTORY)