diff options
-rw-r--r-- | libview/ev-link-accessible.c | 44 | ||||
-rw-r--r-- | libview/ev-link-accessible.h | 4 | ||||
-rw-r--r-- | libview/ev-page-accessible.c | 118 | ||||
-rw-r--r-- | libview/ev-view-accessible.c | 132 |
4 files changed, 135 insertions, 163 deletions
diff --git a/libview/ev-link-accessible.c b/libview/ev-link-accessible.c index c6ae096c..d1f91064 100644 --- a/libview/ev-link-accessible.c +++ b/libview/ev-link-accessible.c @@ -27,7 +27,7 @@ typedef struct _EvHyperlink EvHyperlink; typedef struct _EvHyperlinkClass EvHyperlinkClass; struct _EvLinkAccessiblePrivate { - EvViewAccessible *view; + EvPageAccessible *page; EvLink *link; EvRectangle area; @@ -90,17 +90,10 @@ ev_hyperlink_get_object (AtkHyperlink *atk_hyperlink, } static gint -get_relevant_page (EvView *view) -{ - return ev_view_is_caret_navigation_enabled (view) ? view->cursor_page : view->current_page; -} - -static gint ev_hyperlink_get_start_index (AtkHyperlink *atk_hyperlink) { EvHyperlink *hyperlink = EV_HYPERLINK (atk_hyperlink); EvLinkAccessiblePrivate *impl_priv; - GtkWidget *widget; EvView *view; EvRectangle *areas = NULL; guint n_areas = 0; @@ -110,16 +103,14 @@ ev_hyperlink_get_start_index (AtkHyperlink *atk_hyperlink) return -1; impl_priv = hyperlink->link_impl->priv; - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (impl_priv->view)); - if (widget == NULL) - /* State is defunct */ - return -1; - view = EV_VIEW (widget); + view = ev_page_accessible_get_view (impl_priv->page); if (!view->page_cache) return -1; - ev_page_cache_get_text_layout (view->page_cache, get_relevant_page (view), &areas, &n_areas); + ev_page_cache_get_text_layout (view->page_cache, + ev_page_accessible_get_page (impl_priv->page), + &areas, &n_areas); if (!areas) return -1; @@ -142,7 +133,6 @@ ev_hyperlink_get_end_index (AtkHyperlink *atk_hyperlink) { EvHyperlink *hyperlink = EV_HYPERLINK (atk_hyperlink); EvLinkAccessiblePrivate *impl_priv; - GtkWidget *widget; EvView *view; EvRectangle *areas = NULL; guint n_areas = 0; @@ -152,16 +142,14 @@ ev_hyperlink_get_end_index (AtkHyperlink *atk_hyperlink) return -1; impl_priv = hyperlink->link_impl->priv; - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (impl_priv->view)); - if (widget == NULL) - /* State is defunct */ - return -1; - view = EV_VIEW (widget); + view = ev_page_accessible_get_view (impl_priv->page); if (!view->page_cache) return -1; - ev_page_cache_get_text_layout (view->page_cache, get_relevant_page (view), &areas, &n_areas); + ev_page_cache_get_text_layout (view->page_cache, + ev_page_accessible_get_page (impl_priv->page), + &areas, &n_areas); if (!areas) return -1; @@ -257,17 +245,13 @@ ev_link_accessible_action_do_action (AtkAction *atk_action, gint i) { EvLinkAccessiblePrivate *priv = EV_LINK_ACCESSIBLE (atk_action)->priv; - GtkWidget *widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (priv->view)); - if (widget == NULL) - /* State is defunct */ - return FALSE; + EvView *view; + view = ev_page_accessible_get_view (priv->page); if (!ev_link_get_action (priv->link)) return FALSE; - ev_view_handle_link (EV_VIEW (widget), priv->link); + ev_view_handle_link (view, priv->link); return TRUE; } @@ -303,14 +287,14 @@ ev_link_accessible_action_interface_init (AtkActionIface *iface) } EvLinkAccessible * -ev_link_accessible_new (EvViewAccessible *view, +ev_link_accessible_new (EvPageAccessible *page, EvLink *link, EvRectangle *area) { EvLinkAccessible *atk_link; atk_link = g_object_new (EV_TYPE_LINK_ACCESSIBLE, NULL); - atk_link->priv->view = view; + atk_link->priv->page = page; atk_link->priv->link = g_object_ref (link); atk_link->priv->area = *area; diff --git a/libview/ev-link-accessible.h b/libview/ev-link-accessible.h index 899514cf..f8cda16c 100644 --- a/libview/ev-link-accessible.h +++ b/libview/ev-link-accessible.h @@ -26,7 +26,7 @@ #define __EV_LINK_ACCESSIBLE_H__ #include <gtk/gtk-a11y.h> -#include "ev-view-accessible.h" +#include "ev-page-accessible.h" #include "ev-link.h" #define EV_TYPE_LINK_ACCESSIBLE (ev_link_accessible_get_type ()) @@ -48,7 +48,7 @@ struct _EvLinkAccessibleClass { }; GType ev_link_accessible_get_type (void); -EvLinkAccessible *ev_link_accessible_new (EvViewAccessible *view, +EvLinkAccessible *ev_link_accessible_new (EvPageAccessible *page, EvLink *link, EvRectangle *area); diff --git a/libview/ev-page-accessible.c b/libview/ev-page-accessible.c index fa1f3e02..60d07e33 100644 --- a/libview/ev-page-accessible.c +++ b/libview/ev-page-accessible.c @@ -24,22 +24,27 @@ #include <glib/gi18n-lib.h> #include "ev-page-accessible.h" +#include "ev-link-accessible.h" #include "ev-view-private.h" struct _EvPageAccessiblePrivate { EvViewAccessible *view_accessible; gint page; + GHashTable *links; }; + enum { PROP_0, PROP_VIEW_ACCESSIBLE, PROP_PAGE, }; +static void ev_page_accessible_hypertext_iface_init (AtkHypertextIface *iface); static void ev_page_accessible_text_iface_init (AtkTextIface *iface); G_DEFINE_TYPE_WITH_CODE (EvPageAccessible, ev_page_accessible, ATK_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERTEXT, ev_page_accessible_hypertext_iface_init) G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, ev_page_accessible_text_iface_init)) gint @@ -71,6 +76,16 @@ ev_page_accessible_get_parent (AtkObject *obj) } static void +ev_page_accessible_finalize (GObject *object) +{ + EvPageAccessiblePrivate *priv = EV_PAGE_ACCESSIBLE (object)->priv; + + g_clear_pointer (&priv->links, (GDestroyNotify)g_hash_table_destroy); + + G_OBJECT_CLASS (ev_page_accessible_parent_class)->finalize (object); +} + +static void ev_page_accessible_set_property (GObject *object, guint prop_id, const GValue *value, @@ -122,6 +137,7 @@ ev_page_accessible_class_init (EvPageAccessibleClass *klass) g_object_class->get_property = ev_page_accessible_get_property; g_object_class->set_property = ev_page_accessible_set_property; + g_object_class->finalize = ev_page_accessible_finalize; g_object_class_install_property (g_object_class, PROP_VIEW_ACCESSIBLE, @@ -831,6 +847,108 @@ ev_page_accessible_text_iface_init (AtkTextIface *iface) iface->get_offset_at_point = ev_page_accessible_get_offset_at_point; } +static GHashTable * +ev_page_accessible_get_links (EvPageAccessible *accessible) +{ + EvPageAccessiblePrivate* priv = accessible->priv; + + if (priv->links) + return priv->links; + + priv->links = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify)g_object_unref); + return priv->links; +} + +static AtkHyperlink * +ev_page_accessible_get_link (AtkHypertext *hypertext, + gint link_index) +{ + GHashTable *links; + EvMappingList *link_mapping; + gint n_links; + EvMapping *mapping; + EvLinkAccessible *atk_link; + EvPageAccessible *self = EV_PAGE_ACCESSIBLE (hypertext); + EvView *view = ev_page_accessible_get_view (self); + + if (link_index < 0) + return NULL; + + if (!EV_IS_DOCUMENT_LINKS (view->document)) + return NULL; + + links = ev_page_accessible_get_links (EV_PAGE_ACCESSIBLE (hypertext)); + + atk_link = g_hash_table_lookup (links, GINT_TO_POINTER (link_index)); + if (atk_link) + return atk_hyperlink_impl_get_hyperlink (ATK_HYPERLINK_IMPL (atk_link)); + + link_mapping = ev_page_cache_get_link_mapping (view->page_cache, self->priv->page); + if (!link_mapping) + return NULL; + + n_links = ev_mapping_list_length (link_mapping); + if (link_index > n_links - 1) + return NULL; + + mapping = ev_mapping_list_nth (link_mapping, n_links - link_index - 1); + atk_link = ev_link_accessible_new (EV_PAGE_ACCESSIBLE (hypertext), + EV_LINK (mapping->data), + &mapping->area); + g_hash_table_insert (links, GINT_TO_POINTER (link_index), atk_link); + + return atk_hyperlink_impl_get_hyperlink (ATK_HYPERLINK_IMPL (atk_link)); +} + +static gint +ev_page_accessible_get_n_links (AtkHypertext *hypertext) +{ + EvMappingList *link_mapping; + EvPageAccessible *self = EV_PAGE_ACCESSIBLE (hypertext); + EvView *view = ev_page_accessible_get_view (self); + + if (!EV_IS_DOCUMENT_LINKS (view->document)) + return 0; + + link_mapping = ev_page_cache_get_link_mapping (view->page_cache, + self->priv->page); + + return link_mapping ? ev_mapping_list_length (link_mapping) : 0; +} + +static gint +ev_page_accessible_get_link_index (AtkHypertext *hypertext, + gint offset) +{ + guint i; + gint n_links = ev_page_accessible_get_n_links (hypertext); + + for (i = 0; i < n_links; i++) { + AtkHyperlink *hyperlink; + gint start_index, end_index; + + hyperlink = ev_page_accessible_get_link (hypertext, i); + start_index = atk_hyperlink_get_start_index (hyperlink); + end_index = atk_hyperlink_get_end_index (hyperlink); + + if (start_index <= offset && end_index >= offset) + return i; + } + + return -1; +} + +static void +ev_page_accessible_hypertext_iface_init (AtkHypertextIface *iface) +{ + iface->get_link = ev_page_accessible_get_link; + iface->get_n_links = ev_page_accessible_get_n_links; + iface->get_link_index = ev_page_accessible_get_link_index; +} + EvPageAccessible * ev_page_accessible_new (EvViewAccessible *view_accessible, gint page) diff --git a/libview/ev-view-accessible.c b/libview/ev-view-accessible.c index afa52ef0..c350a7a6 100644 --- a/libview/ev-view-accessible.c +++ b/libview/ev-view-accessible.c @@ -26,12 +26,10 @@ #include "ev-selection.h" #include "ev-page-cache.h" #include "ev-view-accessible.h" -#include "ev-link-accessible.h" #include "ev-view-private.h" #include "ev-page-accessible.h" static void ev_view_accessible_action_iface_init (AtkActionIface *iface); -static void ev_view_accessible_hypertext_iface_init (AtkHypertextIface *iface); static void ev_view_accessible_document_iface_init (AtkDocumentIface *iface); enum { @@ -62,9 +60,6 @@ struct _EvViewAccessiblePrivate { guint action_idle_handler; GtkScrollType idle_scroll; - /* AtkHypertext */ - GHashTable *links; - gint previous_cursor_page; GPtrArray *children; @@ -72,7 +67,6 @@ struct _EvViewAccessiblePrivate { G_DEFINE_TYPE_WITH_CODE (EvViewAccessible, ev_view_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE, G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, ev_view_accessible_action_iface_init) - G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERTEXT, ev_view_accessible_hypertext_iface_init) G_IMPLEMENT_INTERFACE (ATK_TYPE_DOCUMENT, ev_view_accessible_document_iface_init) ) @@ -83,14 +77,6 @@ get_relevant_page (EvView *view) } static void -clear_cache (EvViewAccessible *accessible) -{ - EvViewAccessiblePrivate* priv = accessible->priv; - - g_clear_pointer (&priv->links, (GDestroyNotify)g_hash_table_destroy); -} - -static void clear_children (EvViewAccessible *self) { gint i; @@ -122,7 +108,7 @@ ev_view_accessible_finalize (GObject *object) g_source_remove (priv->action_idle_handler); for (i = 0; i < LAST_ACTION; i++) g_free (priv->action_descriptions [i]); - clear_cache (EV_VIEW_ACCESSIBLE (object)); + clear_children (EV_VIEW_ACCESSIBLE (object)); G_OBJECT_CLASS (ev_view_accessible_parent_class)->finalize (object); @@ -314,119 +300,6 @@ ev_view_accessible_action_iface_init (AtkActionIface * iface) iface->set_description = ev_view_accessible_action_set_description; } -static GHashTable * -ev_view_accessible_get_links (EvViewAccessible *accessible, - EvView *view) -{ - EvViewAccessiblePrivate* priv = accessible->priv; - - if (priv->links) - return priv->links; - - priv->links = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - (GDestroyNotify)g_object_unref); - return priv->links; -} - -static AtkHyperlink * -ev_view_accessible_get_link (AtkHypertext *hypertext, - gint link_index) -{ - GtkWidget *widget; - EvView *view; - GHashTable *links; - EvMappingList *link_mapping; - gint n_links; - EvMapping *mapping; - EvLinkAccessible *atk_link; - - if (link_index < 0) - return NULL; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (hypertext)); - if (widget == NULL) - /* State is defunct */ - return NULL; - - view = EV_VIEW (widget); - if (!EV_IS_DOCUMENT_LINKS (view->document)) - return NULL; - - links = ev_view_accessible_get_links (EV_VIEW_ACCESSIBLE (hypertext), view); - - atk_link = g_hash_table_lookup (links, GINT_TO_POINTER (link_index)); - if (atk_link) - return atk_hyperlink_impl_get_hyperlink (ATK_HYPERLINK_IMPL (atk_link)); - - link_mapping = ev_page_cache_get_link_mapping (view->page_cache, get_relevant_page (view)); - if (!link_mapping) - return NULL; - - n_links = ev_mapping_list_length (link_mapping); - if (link_index > n_links - 1) - return NULL; - - mapping = ev_mapping_list_nth (link_mapping, n_links - link_index - 1); - atk_link = ev_link_accessible_new (EV_VIEW_ACCESSIBLE (hypertext), - EV_LINK (mapping->data), - &mapping->area); - g_hash_table_insert (links, GINT_TO_POINTER (link_index), atk_link); - - return atk_hyperlink_impl_get_hyperlink (ATK_HYPERLINK_IMPL (atk_link)); -} - -static gint -ev_view_accessible_get_n_links (AtkHypertext *hypertext) -{ - GtkWidget *widget; - EvView *view; - EvMappingList *link_mapping; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (hypertext)); - if (widget == NULL) - /* State is defunct */ - return 0; - - view = EV_VIEW (widget); - if (!EV_IS_DOCUMENT_LINKS (view->document)) - return 0; - - link_mapping = ev_page_cache_get_link_mapping (view->page_cache, get_relevant_page (view)); - - return link_mapping ? ev_mapping_list_length (link_mapping) : 0; -} - -static gint -ev_view_accessible_get_link_index (AtkHypertext *hypertext, - gint offset) -{ - guint i; - - for (i = 0; i < ev_view_accessible_get_n_links (hypertext); i++) { - AtkHyperlink *hyperlink; - gint start_index, end_index; - - hyperlink = ev_view_accessible_get_link (hypertext, i); - start_index = atk_hyperlink_get_start_index (hyperlink); - end_index = atk_hyperlink_get_end_index (hyperlink); - - if (start_index <= offset && end_index >= offset) - return i; - } - - return -1; -} - -static void -ev_view_accessible_hypertext_iface_init (AtkHypertextIface *iface) -{ - iface->get_link = ev_view_accessible_get_link; - iface->get_n_links = ev_view_accessible_get_n_links; - iface->get_link_index = ev_view_accessible_get_link_index; -} - static void ev_view_accessible_cursor_moved (EvView *view, gint page, @@ -438,7 +311,6 @@ ev_view_accessible_cursor_moved (EvView *view, if (priv->previous_cursor_page != page) { priv->previous_cursor_page = page; - clear_cache (accessible); /* +1 as user start to count on 1, but evince starts on 0 */ g_signal_emit_by_name (accessible, "page-changed", page + 1); } @@ -464,7 +336,6 @@ page_changed_cb (EvDocumentModel *model, gint new_page, EvViewAccessible *accessible) { - clear_cache (accessible); EvView *view; view = EV_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible))); @@ -502,7 +373,6 @@ document_changed_cb (EvDocumentModel *model, if (document == NULL) return; - clear_cache (accessible); initialize_children (accessible); /* Inside this callback the document is already loaded. We |