Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--backend/ev-document.c9
-rw-r--r--backend/ev-document.h8
-rw-r--r--pdf/xpdf/pdf-document.cc90
-rw-r--r--shell/ev-application.c27
-rw-r--r--shell/ev-application.h6
-rw-r--r--shell/ev-sidebar-links.c7
-rw-r--r--shell/ev-view.c40
8 files changed, 133 insertions, 67 deletions
diff --git a/ChangeLog b/ChangeLog
index 7ee0a7e..926ea90 100644
--- 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),
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 <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,
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 <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)
{
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 <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
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 <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