From: Nickolay V. Shmyrev Date: Sun, 28 Jan 2007 20:43:21 +0000 (+0000) Subject: Implements another history variant X-Git-Tag: EVINCE_0_7_2~57 X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=commitdiff_plain;h=4bb9bc83e2de5cd88fa2e3f81a7da6e7d81cbf99;p=evince.git Implements another history variant 2007-01-28 Nickolay V. Shmyrev * NOTES: * backend/djvu/djvu-links.c: (djvu_links_get_links_model): * backend/pdf/ev-poppler.cc: * libdocument/ev-document-links.h: * libdocument/ev-link.c: (ev_link_get_page): * libdocument/ev-link.h: * shell/ev-history.c: (ev_history_init), (ev_history_class_init), (ev_history_add_link): * shell/ev-history.h: * shell/ev-navigation-action.c: (activate_menu_item_cb), (new_history_menu_item), (build_menu): * shell/ev-page-cache.c: (ev_page_cache_set_current_page_history): * shell/ev-sidebar-links.c: (create_loading_model), (print_section_cb), (ev_sidebar_links_construct), (fill_page_labels), (update_page_callback_foreach), (update_page_callback), (job_finished_callback): * shell/ev-view.c: (ev_view_handle_link): * shell/ev-window.c: (ev_window_find_chapter), (ev_window_add_history), (view_handle_link_cb), (history_changed_cb): Implements another history variant svn path=/trunk/; revision=2264 --- diff --git a/ChangeLog b/ChangeLog index 9c4d6b47..bca1bace 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2007-01-28 Nickolay V. Shmyrev + + * NOTES: + * backend/djvu/djvu-links.c: (djvu_links_get_links_model): + * backend/pdf/ev-poppler.cc: + * libdocument/ev-document-links.h: + * libdocument/ev-link.c: (ev_link_get_page): + * libdocument/ev-link.h: + * shell/ev-history.c: (ev_history_init), (ev_history_class_init), + (ev_history_add_link): + * shell/ev-history.h: + * shell/ev-navigation-action.c: (activate_menu_item_cb), + (new_history_menu_item), (build_menu): + * shell/ev-page-cache.c: (ev_page_cache_set_current_page_history): + * shell/ev-sidebar-links.c: (create_loading_model), + (print_section_cb), (ev_sidebar_links_construct), + (fill_page_labels), (update_page_callback_foreach), + (update_page_callback), (job_finished_callback): + * shell/ev-view.c: (ev_view_handle_link): + * shell/ev-window.c: (ev_window_find_chapter), + (ev_window_add_history), (view_handle_link_cb), + (history_changed_cb): + + Implements another history variant + 2007-01-28 Carlos Garcia Campos * shell/ev-window.c: (view_external_link_cb): diff --git a/NOTES b/NOTES index fadc30fb..3c7db7a6 100644 --- a/NOTES +++ b/NOTES @@ -52,3 +52,26 @@ THOUGHTS ON SELECTION: * click-drag, dbl click, triple click, shift-click, search, shift-cursor move + +THOUGHTS ON HISTORY: +==================== + + * We need single history button, back/forward will complicate things. + + * When we jump on dest link we should add current page and link to the history. + + * When we jump on external link we should just add external link. + + * It's enough to have 7 entries in history, too many entries complicates things. + + * We should avoid duplicate entries in history. If we'll activate entry + that already exists (have the same title) we can just move it to the top. + + + + + + + + + diff --git a/backend/djvu/djvu-links.c b/backend/djvu/djvu-links.c index 38fad0d1..1fc394ad 100644 --- a/backend/djvu/djvu-links.c +++ b/backend/djvu/djvu-links.c @@ -383,7 +383,8 @@ djvu_links_get_links_model (EvDocumentLinks *document_links) model = (GtkTreeModel *) gtk_tree_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_OBJECT, - G_TYPE_BOOLEAN); + G_TYPE_BOOLEAN, + G_TYPE_STRING); build_tree (djvu_document, model, NULL, outline); ddjvu_miniexp_release (djvu_document->d_document, outline); diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc index 2068998e..5c7f495d 100644 --- a/backend/pdf/ev-poppler.cc +++ b/backend/pdf/ev-poppler.cc @@ -1052,7 +1052,8 @@ pdf_document_links_get_links_model (EvDocumentLinks *document_links) model = (GtkTreeModel *) gtk_tree_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_OBJECT, - G_TYPE_BOOLEAN); + G_TYPE_BOOLEAN, + G_TYPE_STRING); build_tree (pdf_document, model, NULL, iter); poppler_index_iter_free (iter); } diff --git a/libdocument/ev-document-links.h b/libdocument/ev-document-links.h index 8e8f20a7..a9208f48 100644 --- a/libdocument/ev-document-links.h +++ b/libdocument/ev-document-links.h @@ -48,6 +48,7 @@ enum { EV_DOCUMENT_LINKS_COLUMN_MARKUP, EV_DOCUMENT_LINKS_COLUMN_LINK, EV_DOCUMENT_LINKS_COLUMN_EXPAND, + EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS }; diff --git a/libdocument/ev-link.c b/libdocument/ev-link.c index 8561914b..17e44213 100644 --- a/libdocument/ev-link.c +++ b/libdocument/ev-link.c @@ -224,3 +224,23 @@ ev_link_mapping_find (GList *link_mapping, return link; } +gint +ev_link_get_page (EvLink *link) +{ + EvLinkAction *action; + EvLinkDest *dest; + + action = ev_link_get_action (link); + if (!action) + return -1; + + if (ev_link_action_get_action_type (action) != + EV_LINK_ACTION_TYPE_GOTO_DEST) + return -1; + + dest = ev_link_action_get_dest (action); + if (dest) + return ev_link_dest_get_page (dest); + + return -1; +} diff --git a/libdocument/ev-link.h b/libdocument/ev-link.h index b7304deb..9bd7f6e0 100644 --- a/libdocument/ev-link.h +++ b/libdocument/ev-link.h @@ -43,6 +43,7 @@ EvLink *ev_link_new (const gchar *title, const gchar *ev_link_get_title (EvLink *self); EvLinkAction *ev_link_get_action (EvLink *self); +gint ev_link_get_page (EvLink *link); /* Link Mapping stuff */ typedef struct _EvLinkMapping EvLinkMapping; diff --git a/shell/ev-history.c b/shell/ev-history.c index 87a506f3..c06fa25f 100644 --- a/shell/ev-history.c +++ b/shell/ev-history.c @@ -20,18 +20,13 @@ #include "config.h" #include +#include #include "ev-history.h" struct _EvHistoryPrivate { GList *links; - int current_index; -}; - -enum { - PROP_0, - PROP_INDEX }; static void ev_history_init (EvHistory *history); @@ -47,7 +42,6 @@ ev_history_init (EvHistory *history) history->priv = EV_HISTORY_GET_PRIVATE (history); history->priv->links = NULL; - history->priv->current_index = -1; } static void @@ -67,103 +61,43 @@ ev_history_finalize (GObject *object) G_OBJECT_CLASS (ev_history_parent_class)->finalize (object); } -static void -ev_history_get_property (GObject *object, guint prop_id, GValue *value, - GParamSpec *param_spec) -{ - EvHistory *self; - - self = EV_HISTORY (object); - - switch (prop_id) { - case PROP_INDEX: - g_value_set_int (value, self->priv->current_index); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, - prop_id, - param_spec); - break; - } -} - -static void -ev_history_set_property (GObject *object, guint prop_id, const GValue *value, - GParamSpec *param_spec) -{ - EvHistory *self; - - self = EV_HISTORY (object); - - switch (prop_id) { - case PROP_INDEX: - ev_history_set_current_index (self, g_value_get_int (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, - prop_id, - param_spec); - break; - } -} - static void ev_history_class_init (EvHistoryClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); object_class->finalize = ev_history_finalize; - object_class->set_property = ev_history_set_property; - object_class->get_property = ev_history_get_property; - - g_object_class_install_property (object_class, - PROP_INDEX, - g_param_spec_int ("index", - "Current Index", - "The current index", - -1, - G_MAXINT, - 0, - G_PARAM_READWRITE)); g_type_class_add_private (object_class, sizeof (EvHistoryPrivate)); } +#define HISTORY_LENGTH 7 + void ev_history_add_link (EvHistory *history, EvLink *link) { - int length; + GList *l; g_return_if_fail (EV_IS_HISTORY (history)); g_return_if_fail (EV_IS_LINK (link)); + for (l = history->priv->links; l; l = l->next) { + if (!strcmp (ev_link_get_title (EV_LINK (l->data)), ev_link_get_title (link))) { + g_object_unref (G_OBJECT (l->data)); + history->priv->links = g_list_delete_link (history->priv->links, l); + break; + } + } g_object_ref (link); history->priv->links = g_list_append (history->priv->links, link); - - length = g_list_length (history->priv->links); - history->priv->current_index = length - 1; -} - -void -ev_history_add_page (EvHistory *history, int page, const gchar *label) -{ - EvLink *link; - EvLinkDest *dest; - EvLinkAction *action; - gchar *title; - - g_return_if_fail (EV_IS_HISTORY (history)); - - title = g_strdup_printf (_("Page: %s"), label); - - dest = ev_link_dest_new_page (page); - action = ev_link_action_new_dest (dest); - link = ev_link_new (title, action); - g_free (title); - - ev_history_add_link (history, link); + + if (g_list_length (history->priv->links) > HISTORY_LENGTH) { + g_object_unref (G_OBJECT (history->priv->links->data)); + history->priv->links = g_list_delete_link (history->priv->links, + history->priv->links); + } } EvLink * @@ -186,26 +120,9 @@ ev_history_get_n_links (EvHistory *history) return g_list_length (history->priv->links); } -int -ev_history_get_current_index (EvHistory *history) -{ - g_return_val_if_fail (EV_IS_HISTORY (history), -1); - - return history->priv->current_index; -} - -void -ev_history_set_current_index (EvHistory *history, int index) -{ - g_return_if_fail (EV_IS_HISTORY (history)); - - history->priv->current_index = index; - - g_object_notify (G_OBJECT (history), "index"); -} - EvHistory * ev_history_new (void) { return EV_HISTORY (g_object_new (EV_TYPE_HISTORY, NULL)); } + diff --git a/shell/ev-history.h b/shell/ev-history.h index 4f1ec1aa..2d27bda6 100644 --- a/shell/ev-history.h +++ b/shell/ev-history.h @@ -54,15 +54,9 @@ GType ev_history_get_type (void); EvHistory *ev_history_new (void); void ev_history_add_link (EvHistory *history, EvLink *linkk); -void ev_history_add_page (EvHistory *history, - int page, - const gchar *label); EvLink *ev_history_get_link_nth (EvHistory *history, int index); int ev_history_get_n_links (EvHistory *history); -int ev_history_get_current_index (EvHistory *history); -void ev_history_set_current_index (EvHistory *history, - int index); G_END_DECLS diff --git a/shell/ev-navigation-action.c b/shell/ev-navigation-action.c index 88fe67b6..c87940a6 100644 --- a/shell/ev-navigation-action.c +++ b/shell/ev-navigation-action.c @@ -72,7 +72,6 @@ activate_menu_item_cb (GtkWidget *widget, EvNavigationAction *action) g_return_if_fail (EV_IS_HISTORY (action->priv->history)); index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "index")); - ev_history_set_current_index (action->priv->history, index); if (action->priv->history) { EvLink *link; @@ -94,6 +93,7 @@ new_history_menu_item (EvNavigationAction *action, title = ev_link_get_title (link); item = gtk_image_menu_item_new_with_label (title); + gtk_label_set_use_markup (GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))), TRUE); g_object_set_data (G_OBJECT (item), "index", GINT_TO_POINTER (index)); @@ -139,8 +139,8 @@ build_menu (EvNavigationAction *action) return GTK_WIDGET (menu); } - start = MAX (ev_history_get_current_index (action->priv->history) - 5, 0); - end = MIN (ev_history_get_n_links (history), start + 7); + start = 0; + end = ev_history_get_n_links (history); for (i = start; i < end; i++) { link = ev_history_get_link_nth (history, i); diff --git a/shell/ev-page-cache.c b/shell/ev-page-cache.c index 7ea0c0f9..070df9d7 100644 --- a/shell/ev-page-cache.c +++ b/shell/ev-page-cache.c @@ -341,8 +341,8 @@ ev_page_cache_set_current_page_history (EvPageCache *page_cache, int page) { if (abs (page - page_cache->current_page) > 1) - g_signal_emit (page_cache, signals [HISTORY_CHANGED], 0, page_cache->current_page); - + g_signal_emit (page_cache, signals [HISTORY_CHANGED], 0, page); + ev_page_cache_set_current_page (page_cache, page); } diff --git a/shell/ev-sidebar-links.c b/shell/ev-sidebar-links.c index 1205b4e2..8017f7c6 100644 --- a/shell/ev-sidebar-links.c +++ b/shell/ev-sidebar-links.c @@ -59,11 +59,6 @@ enum { N_SIGNALS }; -static void links_page_num_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - EvSidebarLinks *sidebar_links); static void update_page_callback (EvPageCache *page_cache, gint current_page, EvSidebarLinks *sidebar_links); @@ -264,7 +259,8 @@ create_loading_model (void) retval = (GtkTreeModel *)gtk_list_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_OBJECT, - G_TYPE_BOOLEAN); + G_TYPE_BOOLEAN, + G_TYPE_STRING); gtk_list_store_append (GTK_LIST_STORE (retval), &iter); markup = g_strdup_printf ("%s", _("Loading...")); @@ -278,27 +274,6 @@ create_loading_model (void) return retval; } -static gint -get_page_from_link (EvLink *link) -{ - EvLinkAction *action; - EvLinkDest *dest; - - action = ev_link_get_action (link); - if (!action) - return -1; - - if (ev_link_action_get_action_type (action) != - EV_LINK_ACTION_TYPE_GOTO_DEST) - return -1; - - dest = ev_link_action_get_dest (action); - if (dest) - return ev_link_dest_get_page (dest); - - return -1; -} - static void print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar) { @@ -321,7 +296,7 @@ print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar) if (!link) return; - first_page = get_page_from_link (link); + first_page = ev_link_get_page (link); if (first_page == -1) { g_object_unref (link); return; @@ -336,7 +311,7 @@ print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar) -1); if (link) { - last_page = get_page_from_link (link); + last_page = ev_link_get_page (link); g_object_unref (link); } } else { @@ -461,9 +436,9 @@ ev_sidebar_links_construct (EvSidebarLinks *ev_sidebar_links) renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_end (GTK_TREE_VIEW_COLUMN (column), renderer, FALSE); - gtk_tree_view_column_set_cell_data_func (GTK_TREE_VIEW_COLUMN (column), renderer, - (GtkTreeCellDataFunc) links_page_num_func, - ev_sidebar_links, NULL); + gtk_tree_view_column_set_attributes (GTK_TREE_VIEW_COLUMN (column), renderer, + "markup", EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, + NULL); g_signal_connect (GTK_TREE_VIEW (priv->tree_view), "button_press_event", @@ -483,51 +458,43 @@ ev_sidebar_links_init (EvSidebarLinks *ev_sidebar_links) ev_sidebar_links_construct (ev_sidebar_links); } -static void -links_page_num_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - EvSidebarLinks *sidebar_links) +static gboolean +fill_page_labels (GtkTreeModel *tree_model, + GtkTreePath *path, + GtkTreeIter *iter, + EvSidebarLinks *sidebar_links) { EvLink *link; gint page; + gchar *page_label; + gchar *page_string; + gtk_tree_model_get (tree_model, iter, EV_DOCUMENT_LINKS_COLUMN_LINK, &link, -1); - if (!link) { - g_object_set (cell, - "visible", FALSE, - NULL); - return; - } - - page = get_page_from_link (link); + if (!link) + return FALSE; - if (page >= 0) { - gchar *page_label; - gchar *page_string; + page = ev_link_get_page (link); - page_label = ev_page_cache_get_page_label (sidebar_links->priv->page_cache, - page); - page_string = g_markup_printf_escaped ("%s", page_label); - - g_object_set (cell, - "markup", page_string, - "visible", TRUE, - NULL); + if (page < 0) + return FALSE; + + page_label = ev_page_cache_get_page_label (sidebar_links->priv->page_cache, + page); + page_string = g_markup_printf_escaped ("%s", page_label); + + gtk_tree_store_set (GTK_TREE_STORE (tree_model), iter, + EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, page_string, + -1); - g_free (page_label); - g_free (page_string); - } else { - g_object_set (cell, - "visible", FALSE, - NULL); - } + g_free (page_label); + g_free (page_string); g_object_unref (link); + return FALSE; } /* Public Functions */ @@ -559,7 +526,7 @@ update_page_callback_foreach (GtkTreeModel *model, int current_page; int dest_page; - dest_page = get_page_from_link (link); + dest_page = ev_link_get_page (link); g_object_unref (link); current_page = ev_page_cache_get_current_page (sidebar_links->priv->page_cache); @@ -601,7 +568,7 @@ update_page_callback (EvPageCache *page_cache, if (link) { gint dest_page; - dest_page = get_page_from_link (link); + dest_page = ev_link_get_page (link); g_object_unref (link); if (dest_page == current_page) @@ -673,6 +640,8 @@ job_finished_callback (EvJobLinks *job, priv->model = job->model; g_object_notify (G_OBJECT (sidebar_links), "model"); + + gtk_tree_model_foreach (priv->model, (GtkTreeModelForeachFunc)fill_page_labels, sidebar_links); gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree_view), job->model); diff --git a/shell/ev-view.c b/shell/ev-view.c index b722785e..a01a2171 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -1348,7 +1348,6 @@ ev_view_handle_link (EvView *view, EvLink *link) if (!action) return; - g_signal_emit (view, signals[SIGNAL_HANDLE_LINK], 0, link); type = ev_link_action_get_action_type (action); @@ -1356,6 +1355,8 @@ ev_view_handle_link (EvView *view, EvLink *link) case EV_LINK_ACTION_TYPE_GOTO_DEST: { EvLinkDest *dest; + g_signal_emit (view, signals[SIGNAL_HANDLE_LINK], 0, link); + dest = ev_link_action_get_dest (action); ev_view_goto_dest (view, dest); } diff --git a/shell/ev-window.c b/shell/ev-window.c index 8e414a57..1680b421 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -643,13 +643,112 @@ page_changed_cb (EvPageCache *page_cache, if (!ev_window_is_empty (ev_window)) ev_metadata_manager_set_int (ev_window->priv->uri, "page", page); } + +typedef struct _FindTask { + gchar *page_label; + gchar *chapter; +} FindTask; + +static gboolean +ev_window_find_chapter (GtkTreeModel *tree_model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + FindTask *task = (FindTask *)data; + gchar *page_string; + + gtk_tree_model_get (tree_model, iter, + EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, &page_string, + -1); + + if (!page_string) + return FALSE; + + if (!strncmp (page_string + strlen (""), task->page_label, strlen (task->page_label))) { + gtk_tree_model_get (tree_model, iter, + EV_DOCUMENT_LINKS_COLUMN_MARKUP, &task->chapter, + -1); + g_free (page_string); + return TRUE; + } + + g_free (page_string); + return FALSE; +} + +static void +ev_window_add_history (EvWindow *window, gint page, EvLink *link) +{ + gchar *page_label; + gchar *link_title; + FindTask find_task; + + EvLink *real_link; + EvLinkAction *action; + EvLinkDest *dest; + + if (link) { + action = g_object_ref (ev_link_get_action (link)); + dest = ev_link_action_get_dest (action); + page = ev_link_dest_get_page (dest); + } else { + dest = ev_link_dest_new_page (page); + action = ev_link_action_new_dest (dest); + } + + if (page < 0) + return; + + page_label = ev_page_cache_get_page_label (window->priv->page_cache, page); + + find_task.page_label = page_label; + find_task.chapter = NULL; + + if (EV_IS_DOCUMENT_LINKS (window->priv->document)) { + GtkTreeModel *model; + + g_object_get (G_OBJECT (window->priv->sidebar_links), "model", &model, NULL); + + gtk_tree_model_foreach (model, + ev_window_find_chapter, + &find_task); + + g_object_unref (model); + } + + if (find_task.chapter) + link_title = g_strdup_printf (_("Page %s - %s"), page_label, find_task.chapter); + else + link_title = g_strdup_printf (_("Page %s"), page_label); + + real_link = ev_link_new (link_title, action); + + ev_history_add_link (window->priv->history, real_link); + + g_free (link_title); + g_object_unref (real_link); +} + +static void +view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window) +{ + int current_page = ev_page_cache_get_current_page (window->priv->page_cache); + + ev_window_add_history (window, 0, link); + ev_window_add_history (window, current_page, NULL); +} + static void history_changed_cb (EvPageCache *page_cache, gint page, - EvWindow *ev_window) + EvWindow *window) { - ev_history_add_page (ev_window->priv->history, page, - ev_page_cache_get_page_label (ev_window->priv->page_cache, page)); + int current_page = ev_page_cache_get_current_page (window->priv->page_cache); + + ev_window_add_history (window, page, NULL); + ev_window_add_history (window, current_page, NULL); + return; } @@ -4045,11 +4144,7 @@ static void navigation_action_activate_link_cb (EvNavigationAction *action, EvLink *link, EvWindow *window) { - g_signal_handlers_block_by_func - (window->priv->view, G_CALLBACK (view_handle_link_cb), window); ev_view_handle_link (EV_VIEW (window->priv->view), link); - g_signal_handlers_unblock_by_func - (window->priv->view, G_CALLBACK (view_handle_link_cb), window); gtk_widget_grab_focus (window->priv->view); } @@ -4337,15 +4432,6 @@ do_action_named (EvWindow *window, EvLinkAction *action) } } -static void -view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window) -{ - int current_page = ev_page_cache_get_current_page (window->priv->page_cache); - ev_history_add_page (window->priv->history, - current_page, - ev_page_cache_get_page_label (window->priv->page_cache, current_page)); -} - static void view_external_link_cb (EvView *view, EvLinkAction *action, EvWindow *window) {