]> www.fi.muni.cz Git - evince.git/commitdiff
Add support for document links
authorMarco Pesenti Gritti <marco@gnome.org>
Thu, 13 Jan 2005 17:49:01 +0000 (17:49 +0000)
committerMarco Pesenti Gritti <marco@src.gnome.org>
Thu, 13 Jan 2005 17:49:01 +0000 (17:49 +0000)
2005-01-13  Marco Pesenti Gritti  <marco@gnome.org>

        * 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

ChangeLog
backend/ev-document.c
backend/ev-document.h
pdf/xpdf/pdf-document.cc
shell/ev-application.c
shell/ev-application.h
shell/ev-sidebar-links.c
shell/ev-view.c

index 7ee0a7e67e21085d52721b8405349e5241fda1b0..926ea90b32020fd6df2c5514e5d4f9af3f5b7ffe 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2005-01-13  Marco Pesenti Gritti  <marco@gnome.org>
+
+       * 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  <andersca@gnome.org>
 
        * shell/ev-page-action.c: (update_spin), (total_pages_changed_cb),
index f0075466bbfd84c783bbeb2d8b8db042cc4ea246..a8de9a5326c47a7d15cb2deeb2e5482b74678f79 100644 (file)
@@ -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,
index ebf60af636d13b0c9bb7d5a7060343f28ced84a5..3616e4307b465988e0a74025527e0ca98d26bc3b 100644 (file)
@@ -26,6 +26,8 @@
 #include <glib.h>
 #include <gdk/gdk.h>
 
+#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,
index a64dc4cecd3abfc311a24f29ed2bec51600ad116..a8824e8845036310d9cf57424155ec1a96a777fe 100644 (file)
@@ -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 (),
index 05f86ce85bc8df5308d022d55ece7f33b6979e3a..6664c6a8a79bf2c0332fdc42245a3376e1dbf778 100644 (file)
@@ -29,9 +29,6 @@
 #include <gtk/gtkstock.h>
 #include <gtk/gtkwidget.h>
 #include <gtk/gtkmain.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
-
-#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)
 {
index a22e7dca787837f18d0b010f82fe75ffc3c547a8..7f30a927f69b1dc61f09ff912100a8449162cd5d 100644 (file)
@@ -27,8 +27,6 @@
 #include <glib-object.h>
 
 #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
 
index 4db11b668cfc642c051a2802c53317fd37a4b623..03d445e803afabf343be14a2f4c64b0edf4717ec 100644 (file)
@@ -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);
                }
        }
 }
index 4750b4d282ab3953169b132b9ee69f74eab78dbd..9d1bef31370885c832df70e28c4b9906afa8d7ad 100644 (file)
@@ -24,6 +24,7 @@
 #include <gtk/gtkselection.h>
 #include <gtk/gtkclipboard.h>
 #include <gdk/gdkkeysyms.h>
+#include <libgnomevfs/gnome-vfs-utils.h>
 
 #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