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