From e0ca7880392b3d064e55406f270e2f68779e3cdc Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Thu, 13 Jan 2005 17:49:01 +0000 Subject: Add support for document links 2005-01-13 Marco Pesenti Gritti * backend/ev-document.c: (ev_document_get_link): * backend/ev-document.h: * pdf/xpdf/pdf-document.cc: * shell/ev-application.c: (ev_application_open): * shell/ev-application.h: * shell/ev-sidebar-links.c: (selection_changed_cb): * shell/ev-view.c: (ev_view_button_release_event), (go_to_link), (ev_view_go_to_link): Add support for document links --- diff --git a/ChangeLog b/ChangeLog index 7ee0a7e..926ea90 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2005-01-13 Marco Pesenti Gritti + + * backend/ev-document.c: (ev_document_get_link): + * backend/ev-document.h: + * pdf/xpdf/pdf-document.cc: + * shell/ev-application.c: (ev_application_open): + * shell/ev-application.h: + * shell/ev-sidebar-links.c: (selection_changed_cb): + * shell/ev-view.c: (ev_view_button_release_event), (go_to_link), + (ev_view_go_to_link): + + Add support for document links + 2005-01-13 Anders Carlsson * shell/ev-page-action.c: (update_spin), (total_pages_changed_cb), diff --git a/backend/ev-document.c b/backend/ev-document.c index f007546..a8de9a5 100644 --- a/backend/ev-document.c +++ b/backend/ev-document.c @@ -169,6 +169,15 @@ ev_document_get_text (EvDocument *document, return iface->get_text (document, rect); } +EvLink * +ev_document_get_link (EvDocument *document, + int x, + int y) +{ + EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document); + return iface->get_link (document, x, y); +} + void ev_document_render (EvDocument *document, int clip_x, diff --git a/backend/ev-document.h b/backend/ev-document.h index ebf60af..3616e43 100644 --- a/backend/ev-document.h +++ b/backend/ev-document.h @@ -26,6 +26,8 @@ #include #include +#include "ev-link.h" + G_BEGIN_DECLS #define EV_TYPE_DOCUMENT (ev_document_get_type ()) @@ -68,6 +70,9 @@ struct _EvDocumentIface int *height); char * (* get_text) (EvDocument *document, GdkRectangle *rect); + EvLink * (* get_link) (EvDocument *document, + int x, + int y); void (* render) (EvDocument *document, int clip_x, int clip_y, @@ -100,6 +105,9 @@ void ev_document_get_page_size (EvDocument *document, int *height); char *ev_document_get_text (EvDocument *document, GdkRectangle *rect); +EvLink *ev_document_get_link (EvDocument *document, + int x, + int y); void ev_document_render (EvDocument *document, int clip_x, int clip_y, diff --git a/pdf/xpdf/pdf-document.cc b/pdf/xpdf/pdf-document.cc index a64dc4c..a8824e8 100644 --- a/pdf/xpdf/pdf-document.cc +++ b/pdf/xpdf/pdf-document.cc @@ -84,6 +84,7 @@ struct _PdfDocument GDKSplashOutputDev *out; PSOutputDev *ps_out; PDFDoc *doc; + Links *links; UnicodeMap *umap; gboolean page_valid; @@ -113,6 +114,21 @@ G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT, pdf_document_find_iface_init); }); +static void +document_init_links (PdfDocument *pdf_document) +{ + Page *page; + Object obj; + + if (pdf_document->links) { + delete pdf_document->links; + } + page = pdf_document->doc->getCatalog ()->getPage (pdf_document->page); + pdf_document->links = new Links (page->getAnnots (&obj), + pdf_document->doc->getCatalog ()->getBaseURI ()); + obj.free (); +} + static gboolean document_validate_page (PdfDocument *pdf_document) { @@ -122,6 +138,8 @@ document_validate_page (PdfDocument *pdf_document) 72 * pdf_document->scale, 0, gTrue, gTrue); + document_init_links (pdf_document); + pdf_document->page_valid = TRUE; /* Update the search results available to the app since @@ -740,27 +758,12 @@ pdf_document_links_begin_read (EvDocumentLinks *document_links) return (EvDocumentLinksIter *) iter; } -/* FIXME This returns a new object every time, probably we should cache it - in the iter */ static EvLink * -pdf_document_links_get_link (EvDocumentLinks *document_links, - EvDocumentLinksIter *links_iter) +build_link_from_action (PdfDocument *pdf_document, + LinkAction *link_action, + const char *title) { - PdfDocument *pdf_document = PDF_DOCUMENT (document_links); EvLink *link = NULL; - LinksIter *iter = (LinksIter *)links_iter; - OutlineItem *anItem; - LinkAction *link_action; - Unicode *link_title; - const char *title; - - g_return_val_if_fail (PDF_IS_DOCUMENT (document_links), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - - anItem = (OutlineItem *)iter->items->get(iter->index); - link_action = anItem->getAction (); - link_title = anItem->getTitle (); - title = unicode_to_char (anItem, pdf_document->umap); if (link_action == NULL) { link = ev_link_new_title (title); @@ -808,9 +811,33 @@ pdf_document_links_get_link (EvDocumentLinks *document_links, return link; } +/* FIXME This returns a new object every time, probably we should cache it + in the iter */ +static EvLink * +pdf_document_links_get_link (EvDocumentLinks *document_links, + EvDocumentLinksIter *links_iter) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document_links); + LinksIter *iter = (LinksIter *)links_iter; + OutlineItem *anItem; + LinkAction *link_action; + Unicode *link_title; + const char *title; + + g_return_val_if_fail (PDF_IS_DOCUMENT (document_links), FALSE); + g_return_val_if_fail (iter != NULL, FALSE); + + anItem = (OutlineItem *)iter->items->get(iter->index); + link_action = anItem->getAction (); + link_title = anItem->getTitle (); + title = unicode_to_char (anItem, pdf_document->umap); + + return build_link_from_action (pdf_document, link_action, title); +} + static EvDocumentLinksIter * pdf_document_links_get_child (EvDocumentLinks *document_links, - EvDocumentLinksIter *links_iter) + EvDocumentLinksIter *links_iter) { LinksIter *iter = (LinksIter *)links_iter; LinksIter *child_iter; @@ -834,7 +861,7 @@ pdf_document_links_get_child (EvDocumentLinks *document_links, static gboolean pdf_document_links_next (EvDocumentLinks *document_links, - EvDocumentLinksIter *links_iter) + EvDocumentLinksIter *links_iter) { LinksIter *iter = (LinksIter *) links_iter; @@ -849,7 +876,7 @@ pdf_document_links_next (EvDocumentLinks *document_links, static void pdf_document_links_free_iter (EvDocumentLinks *document_links, - EvDocumentLinksIter *iter) + EvDocumentLinksIter *iter) { g_return_if_fail (PDF_IS_DOCUMENT (document_links)); g_return_if_fail (iter != NULL); @@ -863,6 +890,10 @@ pdf_document_finalize (GObject *object) { PdfDocument *pdf_document = PDF_DOCUMENT (object); + if (pdf_document->links) { + delete pdf_document->links; + } + if (pdf_document->umap) { pdf_document->umap->decRefCnt (); pdf_document->umap = NULL; @@ -968,6 +999,20 @@ pdf_document_get_text (EvDocument *document, GdkRectangle *rect) return text ? g_strdup (text) : NULL; } +static EvLink * +pdf_document_get_link (EvDocument *document, int x, int y) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + LinkAction *action; + + action = pdf_document->links->find (x, y); + if (action) { + return build_link_from_action (pdf_document, action, ""); + } else { + return NULL; + } +} + static void pdf_document_get_property (GObject *object, guint prop_id, @@ -1005,6 +1050,7 @@ pdf_document_document_iface_init (EvDocumentIface *iface) iface->load = pdf_document_load; iface->save = pdf_document_save; iface->get_text = pdf_document_get_text; + iface->get_link = pdf_document_get_link; iface->get_n_pages = pdf_document_get_n_pages; iface->set_page = pdf_document_set_page; iface->get_page = pdf_document_get_page; @@ -1144,8 +1190,6 @@ pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnail the_page = pdf_document->doc->getCatalog ()->getPage (page + 1); the_page->getThumb (&the_thumb); - - if (!(the_thumb.isNull () || the_thumb.isNone())) { /* Build the thumbnail object */ thumb = new Thumb(pdf_document->doc->getXRef (), diff --git a/shell/ev-application.c b/shell/ev-application.c index 05f86ce..6664c6a 100644 --- a/shell/ev-application.c +++ b/shell/ev-application.c @@ -29,9 +29,6 @@ #include #include #include -#include - -#include "ev-window.h" struct _EvApplicationPrivate { GList *windows; @@ -169,30 +166,6 @@ ev_application_open (EvApplication *application, GError *err) gtk_widget_destroy (GTK_WIDGET (chooser)); } -void -ev_application_open_link (EvApplication *application, - EvWindow *window, - EvLink *link, - GError *error) -{ - EvLinkType type; - const char *uri; - - type = ev_link_get_link_type (link); - - switch (type) { - case EV_LINK_TYPE_TITLE: - break; - case EV_LINK_TYPE_PAGE: - ev_window_open_link (window, link); - break; - case EV_LINK_TYPE_EXTERNAL_URI: - uri = ev_link_get_uri (link); - gnome_vfs_url_show (uri); - break; - } -} - static void ev_application_class_init (EvApplicationClass *ev_application_class) { diff --git a/shell/ev-application.h b/shell/ev-application.h index a22e7dc..7f30a92 100644 --- a/shell/ev-application.h +++ b/shell/ev-application.h @@ -27,8 +27,6 @@ #include #include "ev-window.h" -#include "ev-document.h" -#include "ev-link.h" G_BEGIN_DECLS @@ -59,10 +57,6 @@ EvApplication *ev_application_get_instance (void); void ev_application_open (EvApplication *application, GError *err); EvWindow *ev_application_new_window (EvApplication *application); -void ev_application_open_link (EvApplication *application, - EvWindow *window, - EvLink *link, - GError *err); G_END_DECLS diff --git a/shell/ev-sidebar-links.c b/shell/ev-sidebar-links.c index 4db11b6..03d445e 100644 --- a/shell/ev-sidebar-links.c +++ b/shell/ev-sidebar-links.c @@ -29,7 +29,7 @@ #include "ev-sidebar-links.h" #include "ev-document-links.h" -#include "ev-application.h" +#include "ev-window.h" /* Amount of time we devote to each iteration of the idle, in microseconds */ #define IDLE_WORK_LENGTH 5000 @@ -105,7 +105,6 @@ selection_changed_cb (GtkTreeSelection *selection, if (gtk_tree_selection_get_selected (selection, &model, &iter)) { EvLink *link; - EvApplication *app; GtkWidget *window; GValue value = {0, }; @@ -118,9 +117,7 @@ selection_changed_cb (GtkTreeSelection *selection, window = gtk_widget_get_ancestor (GTK_WIDGET (ev_sidebar_links), EV_TYPE_WINDOW); if (window) { - app = ev_application_get_instance (); - ev_application_open_link (app, EV_WINDOW (window), - link, NULL); + ev_window_open_link (EV_WINDOW (window), link); } } } diff --git a/shell/ev-view.c b/shell/ev-view.c index 4750b4d..9d1bef3 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "ev-marshal.h" #include "ev-view.h" @@ -547,7 +548,19 @@ ev_view_button_release_event (GtkWidget *widget, { EvView *view = EV_VIEW (widget); - ev_view_update_primary_selection (view); + if (view->has_selection) { + ev_view_update_primary_selection (view); + } else { + EvLink *link; + + link = ev_document_get_link (view->document, + event->x, + event->y); + if (link) { + ev_view_go_to_link (view, link); + g_object_unref (link); + } + } return FALSE; } @@ -927,21 +940,36 @@ static void go_to_link (EvView *view, EvLink *link) { EvLinkType type; + const char *uri; int page; type = ev_link_get_link_type (link); - - if (type == EV_LINK_TYPE_PAGE) { - page = ev_link_get_page (link); - set_document_page (view, page); + + switch (type) { + case EV_LINK_TYPE_TITLE: + break; + case EV_LINK_TYPE_PAGE: + page = ev_link_get_page (link); + set_document_page (view, page); + break; + case EV_LINK_TYPE_EXTERNAL_URI: + uri = ev_link_get_uri (link); + gnome_vfs_url_show (uri); + break; } } void ev_view_go_to_link (EvView *view, EvLink *link) { + EvLinkType type; + go_to_link (view, link); - ev_history_add_link (view->history, link); + + type = ev_link_get_link_type (link); + if (type == EV_LINK_TYPE_PAGE) { + ev_history_add_link (view->history, link); + } } static void -- cgit v0.9.1