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