From fb1224c38b3c4269fc8ad6591ab258c0d1bad72d Mon Sep 17 00:00:00 2001 From: Antia Puentes Date: Tue, 30 Jul 2013 19:09:52 +0200 Subject: ev-view-accessible: Clear the cached data when the current page or document is updated. https://bugzilla.gnome.org/show_bug.cgi?id=704621 https://git.gnome.org/browse/evince/commit/?h=gnome-3-10&id=d71e0d7 --- libview/ev-view-accessible.c | 89 ++++++++++++++++++++++++++++++++++---------- libview/ev-view-accessible.h | 7 +++- libview/ev-view.c | 4 ++ 3 files changed, 78 insertions(+), 22 deletions(-) (limited to 'libview') diff --git a/libview/ev-view-accessible.c b/libview/ev-view-accessible.c index 7e62f70d..987079cd 100644 --- a/libview/ev-view-accessible.c +++ b/libview/ev-view-accessible.c @@ -55,7 +55,7 @@ static const gchar *const ev_view_accessible_action_descriptions[] = }; struct _EvViewAccessiblePrivate { - guint current_page; + EvDocumentModel *model; /* AtkAction */ gchar *action_descriptions[LAST_ACTION]; @@ -75,20 +75,31 @@ G_DEFINE_TYPE_WITH_CODE (EvViewAccessible, ev_view_accessible, GTK_TYPE_CONTAINE G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERTEXT, ev_view_accessible_hypertext_iface_init) ) +static void +clear_cache (EvViewAccessible *accessible) +{ + EvViewAccessiblePrivate* priv = accessible->priv; + + g_clear_object (&priv->buffer); + g_clear_pointer (&priv->links, (GDestroyNotify)g_hash_table_destroy); +} + static void ev_view_accessible_finalize (GObject *object) { EvViewAccessiblePrivate *priv = EV_VIEW_ACCESSIBLE (object)->priv; int i; + if (priv->model) { + g_signal_handlers_disconnect_by_data (priv->model, object); + g_object_unref (priv->model); + priv->model = NULL; + } if (priv->action_idle_handler) g_source_remove (priv->action_idle_handler); for (i = 0; i < LAST_ACTION; i++) g_free (priv->action_descriptions [i]); - if (priv->buffer) - g_object_unref (priv->buffer); - if (priv->links) - g_hash_table_destroy (priv->links); + clear_cache (EV_VIEW_ACCESSIBLE (object)); G_OBJECT_CLASS (ev_view_accessible_parent_class)->finalize (object); } @@ -131,21 +142,16 @@ ev_view_accessible_get_text_buffer (EvViewAccessible *accessible, EvView *view) const gchar *retval = NULL; EvViewAccessiblePrivate* priv = accessible->priv; - page_cache = view->page_cache; - if (!page_cache) { - return NULL; - } - - if (view->current_page == priv->current_page && priv->buffer) { + if (priv->buffer) { return priv->buffer; } - priv->current_page = view->current_page; - - if (!priv->buffer) { - priv->buffer = gtk_text_buffer_new (NULL); + page_cache = view->page_cache; + if (!page_cache) { + return NULL; } + priv->buffer = gtk_text_buffer_new (NULL); retval = ev_page_cache_get_text (page_cache, view->current_page); if (retval) gtk_text_buffer_set_text (priv->buffer, retval, -1); @@ -970,13 +976,9 @@ ev_view_accessible_get_links (EvViewAccessible *accessible, { EvViewAccessiblePrivate* priv = accessible->priv; - if (view->current_page == priv->current_page && priv->links) + if (priv->links) return priv->links; - priv->current_page = view->current_page; - - if (priv->links) - g_hash_table_destroy (priv->links); priv->links = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, @@ -1091,10 +1093,52 @@ ev_view_accessible_selection_changed (EvView *view, g_signal_emit_by_name (accessible, "text-selection-changed"); } +static void +page_changed_cb (EvDocumentModel *model, + gint old_page, + gint new_page, + EvViewAccessible *accessible) +{ + clear_cache (accessible); +} + +static void +document_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvViewAccessible *accessible) +{ + clear_cache (accessible); +} + +void +ev_view_accessible_set_model (EvViewAccessible *accessible, + EvDocumentModel *model) +{ + EvViewAccessiblePrivate* priv = accessible->priv; + + if (priv->model == model) + return; + + if (priv->model) { + g_signal_handlers_disconnect_by_data (priv->model, accessible); + g_object_unref (priv->model); + } + + priv->model = g_object_ref (model); + + g_signal_connect (priv->model, "page-changed", + G_CALLBACK (page_changed_cb), + accessible); + g_signal_connect (priv->model, "notify::document", + G_CALLBACK (document_changed_cb), + accessible); +} + AtkObject * ev_view_accessible_new (GtkWidget *widget) { AtkObject *accessible; + EvView *view; g_return_val_if_fail (EV_IS_VIEW (widget), NULL); @@ -1108,6 +1152,11 @@ ev_view_accessible_new (GtkWidget *widget) G_CALLBACK (ev_view_accessible_selection_changed), accessible); + view = EV_VIEW (widget); + if (view->model) + ev_view_accessible_set_model (EV_VIEW_ACCESSIBLE (accessible), + view->model); + return accessible; } diff --git a/libview/ev-view-accessible.h b/libview/ev-view-accessible.h index 04ef34e8..df3ca317 100644 --- a/libview/ev-view-accessible.h +++ b/libview/ev-view-accessible.h @@ -26,6 +26,7 @@ #define __EV_VIEW_ACCESSIBLE_H__ #include +#include "ev-document-model.h" #define EV_TYPE_VIEW_ACCESSIBLE (ev_view_accessible_get_type ()) #define EV_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_VIEW_ACCESSIBLE, EvViewAccessible)) @@ -47,8 +48,10 @@ struct _EvViewAccessibleClass GtkContainerAccessibleClass parent_class; }; -GType ev_view_accessible_get_type (void); -AtkObject *ev_view_accessible_new (GtkWidget *widget); +GType ev_view_accessible_get_type (void); +AtkObject *ev_view_accessible_new (GtkWidget *widget); +void ev_view_accessible_set_model (EvViewAccessible *accessible, + EvDocumentModel *model); #endif /* __EV_VIEW_ACCESSIBLE_H__ */ diff --git a/libview/ev-view.c b/libview/ev-view.c index e04d7298..e9f5e745 100644 --- a/libview/ev-view.c +++ b/libview/ev-view.c @@ -7027,6 +7027,10 @@ ev_view_set_model (EvView *view, g_signal_connect (view->model, "page-changed", G_CALLBACK (ev_view_page_changed_cb), view); + + if (view->accessible) + ev_view_accessible_set_model (EV_VIEW_ACCESSIBLE (view->accessible), + view->model); } static void -- cgit v1.2.1