Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog24
-rw-r--r--backend/Makefile.am4
-rw-r--r--backend/ev-document-links.c30
-rw-r--r--backend/ev-document-links.h13
-rw-r--r--backend/ev-document.c15
-rw-r--r--backend/ev-document.h6
-rw-r--r--backend/ev-link-action.c319
-rw-r--r--backend/ev-link-action.h69
-rw-r--r--backend/ev-link-dest.c429
-rw-r--r--backend/ev-link-dest.h83
-rw-r--r--backend/ev-link.c488
-rw-r--r--backend/ev-link.h76
-rw-r--r--pdf/ev-poppler.cc390
-rw-r--r--shell/ev-application.c46
-rw-r--r--shell/ev-application.h20
-rw-r--r--shell/ev-jobs.c8
-rw-r--r--shell/ev-page-action.c20
-rw-r--r--shell/ev-sidebar-links.c94
-rw-r--r--shell/ev-view.c365
-rw-r--r--shell/ev-view.h4
-rw-r--r--shell/ev-window.c233
-rw-r--r--shell/ev-window.h5
-rw-r--r--shell/main.c2
23 files changed, 1777 insertions, 966 deletions
diff --git a/ChangeLog b/ChangeLog
index a9e9791..b583775 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2006-05-02 Carlos Garcia Campos <carlosgc@gnome.org>
+
+ * backend/Makefile.am:
+ * backend/ev-document-links.[ch]:
+ * backend/ev-document.[ch]:
+ * backend/ev-link-action.[ch]:
+ * backend/ev-link-dest.[ch]:
+ * backend/ev-link.[ch]:
+ * pdf/ev-poppler.cc: (pdf_document_find_link_dest),
+ (ev_link_dest_from_dest), (ev_link_from_action), (build_tree):
+ * shell/ev-page-action.c: (build_new_tree_cb):
+ * shell/ev-sidebar-links.c: (get_page_from_dest), (print_section_cb),
+ (links_page_num_func), (update_page_callback):
+ * shell/ev-view.[ch]: (ev_view_goto_dest), (ev_view_handle_link),
+ (tip_from_link):
+ * shell/ev-jobs.c:
+ * shell/ev-window.[ch]: (ev_window_open_uri),
+ (sidebar_links_link_activated_cb), (ev_view_popup_cmd_open_link):
+ * shell/ev-application.[ch]: (ev_application_open_window),
+ (ev_application_open_uri):
+
+ Rework links system, it adds support for remote links now and it makes
+ easier to add new kinds of actions and destinations. Fixes bug #317292
+
2006-05-02 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
* data/Makefile.am:
diff --git a/backend/Makefile.am b/backend/Makefile.am
index c2adf47..db21e4c 100644
--- a/backend/Makefile.am
+++ b/backend/Makefile.am
@@ -22,6 +22,10 @@ libevbackend_la_SOURCES= \
ev-backend-marshal.c \
ev-link.c \
ev-link.h \
+ ev-link-action.c \
+ ev-link-action.h \
+ ev-link-dest.c \
+ ev-link-dest.h \
ev-document.c \
ev-document.h \
ev-document-factory.c \
diff --git a/backend/ev-document-links.c b/backend/ev-document-links.c
index 7ab3468..daec3ea 100644
--- a/backend/ev-document-links.c
+++ b/backend/ev-document-links.c
@@ -30,10 +30,8 @@ ev_document_links_get_type (void)
{
static GType type = 0;
- if (G_UNLIKELY (type == 0))
- {
- static const GTypeInfo our_info =
- {
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo our_info = {
sizeof (EvDocumentLinksIface),
NULL,
NULL,
@@ -68,3 +66,27 @@ ev_document_links_get_links_model (EvDocumentLinks *document_links)
return retval;
}
+
+GList *
+ev_document_links_get_links (EvDocumentLinks *document_links,
+ gint page)
+{
+ EvDocumentLinksIface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
+ GList *retval;
+
+ retval = iface->get_links (document_links, page);
+
+ return retval;
+}
+
+EvLinkDest *
+ev_document_links_find_link_dest (EvDocumentLinks *document_links,
+ const gchar *link_name)
+{
+ EvDocumentLinksIface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
+ EvLinkDest *retval;
+
+ retval = iface->find_link_dest (document_links, link_name);
+
+ return retval;
+}
diff --git a/backend/ev-document-links.h b/backend/ev-document-links.h
index 1f94596..8e8f20a 100644
--- a/backend/ev-document-links.h
+++ b/backend/ev-document-links.h
@@ -56,14 +56,23 @@ struct _EvDocumentLinksIface
GTypeInterface base_iface;
/* Methods */
- gboolean (* has_document_links) (EvDocumentLinks *document_links);
- GtkTreeModel *(* get_links_model) (EvDocumentLinks *document_links);
+ gboolean (* has_document_links) (EvDocumentLinks *document_links);
+ GtkTreeModel *(* get_links_model) (EvDocumentLinks *document_links);
+ GList *(* get_links) (EvDocumentLinks *document_links,
+ gint page);
+ EvLinkDest *(* find_link_dest) (EvDocumentLinks *document_links,
+ const gchar *link_name);
};
GType ev_document_links_get_type (void);
gboolean ev_document_links_has_document_links (EvDocumentLinks *document_links);
GtkTreeModel *ev_document_links_get_links_model (EvDocumentLinks *document_links);
+GList *ev_document_links_get_links (EvDocumentLinks *document_links,
+ gint page);
+EvLinkDest *ev_document_links_find_link_dest (EvDocumentLinks *document_links,
+ const gchar *link_name);
+
G_END_DECLS
#endif
diff --git a/backend/ev-document.c b/backend/ev-document.c
index 10f1d00..8598c11 100644
--- a/backend/ev-document.c
+++ b/backend/ev-document.c
@@ -185,21 +185,6 @@ ev_document_get_text (EvDocument *document,
return retval;
}
-GList *
-ev_document_get_links (EvDocument *document,
- int page)
-{
- EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
- GList *retval;
-
- LOG ("ev_document_get_link");
- if (iface->get_links == NULL)
- return NULL;
- retval = iface->get_links (document, page);
-
- return retval;
-}
-
gboolean
ev_document_has_attachments (EvDocument *document)
{
diff --git a/backend/ev-document.h b/backend/ev-document.h
index ce7714c..0da5fc7 100644
--- a/backend/ev-document.h
+++ b/backend/ev-document.h
@@ -44,8 +44,6 @@ typedef struct _EvDocumentIface EvDocumentIface;
typedef struct _EvPageCache EvPageCache;
typedef struct _EvPageCacheClass EvPageCacheClass;
-
-
#define EV_DOCUMENT_ERROR ev_document_error_quark ()
#define EV_DOC_MUTEX_LOCK (ev_document_doc_mutex_lock ())
#define EV_DOC_MUTEX_UNLOCK (ev_document_doc_mutex_unlock ())
@@ -90,8 +88,6 @@ struct _EvDocumentIface
char * (* get_text) (EvDocument *document,
int page,
EvRectangle *rect);
- GList * (* get_links) (EvDocument *document,
- int page);
gboolean (* has_attachments) (EvDocument *document);
GList * (* get_attachments) (EvDocument *document);
GdkPixbuf * (* render_pixbuf) (EvDocument *document,
@@ -123,8 +119,6 @@ gboolean ev_document_can_get_text (EvDocument *document);
char *ev_document_get_text (EvDocument *document,
int page,
EvRectangle *rect);
-GList *ev_document_get_links (EvDocument *document,
- int page);
gboolean ev_document_has_attachments (EvDocument *document);
GList *ev_document_get_attachments (EvDocument *document);
GdkPixbuf *ev_document_render_pixbuf (EvDocument *document,
diff --git a/backend/ev-link-action.c b/backend/ev-link-action.c
new file mode 100644
index 0000000..23f4194
--- /dev/null
+++ b/backend/ev-link-action.c
@@ -0,0 +1,319 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <carlosgc@gnome.org>
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "ev-link-action.h"
+
+enum {
+ PROP_0,
+ PROP_TYPE,
+ PROP_DEST,
+ PROP_URI,
+ PROP_FILENAME,
+ PROP_PARAMS
+};
+
+struct _EvLinkAction {
+ GObject base_instance;
+
+ EvLinkActionPrivate *priv;
+};
+
+struct _EvLinkActionClass {
+ GObjectClass base_class;
+};
+
+struct _EvLinkActionPrivate {
+ EvLinkActionType type;
+ EvLinkDest *dest;
+ gchar *uri;
+ gchar *filename;
+ gchar *params;
+};
+
+G_DEFINE_TYPE (EvLinkAction, ev_link_action, G_TYPE_OBJECT)
+
+#define EV_LINK_ACTION_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_LINK_ACTION, EvLinkActionPrivate))
+
+GType
+ev_link_action_type_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GEnumValue values[] = {
+ { EV_LINK_ACTION_TYPE_GOTO_DEST, "EV_LINK_ACTION_TYPE_GOTO_DEST", "goto-dest" },
+ { EV_LINK_ACTION_TYPE_GOTO_REMOTE, "EV_LINK_ACTION_TYPE_GOTO_REMOTE", "goto-remote" },
+ { EV_LINK_ACTION_TYPE_LAUNCH, "EV_LINK_ACTION_TYPE_LAUNCH", "launch" },
+ { EV_LINK_ACTION_TYPE_EXTERNAL_URI, "EV_LINK_ACTION_TYPE_EXTERNAL_URI", "external-uri"},
+ { 0, NULL, NULL }
+ };
+
+ type = g_enum_register_static ("EvLinkActionType", values);
+ }
+
+ return type;
+}
+
+EvLinkActionType
+ev_link_action_get_action_type (EvLinkAction *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_ACTION (self), 0);
+
+ return self->priv->type;
+}
+
+EvLinkDest *
+ev_link_action_get_dest (EvLinkAction *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_ACTION (self), NULL);
+
+ return self->priv->dest;
+}
+
+const gchar *
+ev_link_action_get_uri (EvLinkAction *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_ACTION (self), NULL);
+
+ return self->priv->uri;
+}
+
+const gchar *
+ev_link_action_get_filename (EvLinkAction *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_ACTION (self), NULL);
+
+ return self->priv->filename;
+}
+
+const gchar *
+ev_link_action_get_params (EvLinkAction *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_ACTION (self), NULL);
+
+ return self->priv->params;
+}
+
+static void
+ev_link_action_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *param_spec)
+{
+ EvLinkAction *self;
+
+ self = EV_LINK_ACTION (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ g_value_set_enum (value, self->priv->type);
+ break;
+ case PROP_DEST:
+ g_value_set_pointer (value, self->priv->dest);
+ break;
+ case PROP_URI:
+ g_value_set_string (value, self->priv->uri);
+ break;
+ case PROP_FILENAME:
+ g_value_set_string (value, self->priv->filename);
+ break;
+ case PROP_PARAMS:
+ g_value_set_string (value, self->priv->params);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
+ }
+}
+
+static void
+ev_link_action_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *param_spec)
+{
+ EvLinkAction *self = EV_LINK_ACTION (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ self->priv->type = g_value_get_enum (value);
+ break;
+ case PROP_DEST:
+ self->priv->dest = g_value_get_pointer (value);
+ break;
+ case PROP_URI:
+ g_free (self->priv->uri);
+ self->priv->uri = g_value_dup_string (value);
+ break;
+ case PROP_FILENAME:
+ g_free (self->priv->filename);
+ self->priv->filename = g_value_dup_string (value);
+ break;
+ case PROP_PARAMS:
+ g_free (self->priv->params);
+ self->priv->params = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
+ }
+}
+
+static void
+ev_link_action_finalize (GObject *object)
+{
+ EvLinkActionPrivate *priv;
+
+ priv = EV_LINK_ACTION (object)->priv;
+
+ if (priv->dest) {
+ g_object_unref (priv->dest);
+ priv->dest = NULL;
+ }
+
+ if (priv->uri) {
+ g_free (priv->uri);
+ priv->uri = NULL;
+ }
+
+ if (priv->filename) {
+ g_free (priv->filename);
+ priv->filename = NULL;
+ }
+
+ if (priv->params) {
+ g_free (priv->params);
+ priv->params = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_link_action_parent_class)->finalize (object);
+}
+
+static void
+ev_link_action_init (EvLinkAction *ev_link_action)
+{
+ ev_link_action->priv = EV_LINK_ACTION_GET_PRIVATE (ev_link_action);
+
+ ev_link_action->priv->dest = NULL;
+ ev_link_action->priv->uri = NULL;
+ ev_link_action->priv->filename = NULL;
+ ev_link_action->priv->params = NULL;
+}
+
+static void
+ev_link_action_class_init (EvLinkActionClass *ev_link_action_class)
+{
+ GObjectClass *g_object_class;
+
+ g_object_class = G_OBJECT_CLASS (ev_link_action_class);
+
+ g_object_class->set_property = ev_link_action_set_property;
+ g_object_class->get_property = ev_link_action_get_property;
+
+ g_object_class->finalize = ev_link_action_finalize;
+
+ g_type_class_add_private (g_object_class, sizeof (EvLinkActionPrivate));
+
+ g_object_class_install_property (g_object_class,
+ PROP_TYPE,
+ g_param_spec_enum ("type",
+ "Action Type",
+ "The link action type",
+ EV_TYPE_LINK_ACTION_TYPE,
+ EV_LINK_ACTION_TYPE_GOTO_DEST,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_DEST,
+ g_param_spec_pointer ("dest",
+ "Action destination",
+ "The link action destination",
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_URI,
+ g_param_spec_string ("uri",
+ "Link Action URI",
+ "The link action URI",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_FILENAME,
+ g_param_spec_string ("filename",
+ "Filename",
+ "The link action filename",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_PARAMS,
+ g_param_spec_string ("params",
+ "Params",
+ "The link action params",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+EvLinkAction *
+ev_link_action_new_dest (EvLinkDest *dest)
+{
+ return EV_LINK_ACTION (g_object_new (EV_TYPE_LINK_ACTION,
+ "dest", dest,
+ "type", EV_LINK_ACTION_TYPE_GOTO_DEST,
+ NULL));
+}
+
+EvLinkAction *
+ev_link_action_new_remote (EvLinkDest *dest,
+ const gchar *filename)
+{
+ return EV_LINK_ACTION (g_object_new (EV_TYPE_LINK_ACTION,
+ "dest", dest,
+ "filename", filename,
+ "type", EV_LINK_ACTION_TYPE_GOTO_REMOTE,
+ NULL));
+}
+
+EvLinkAction *
+ev_link_action_new_external_uri (const gchar *uri)
+{
+ return EV_LINK_ACTION (g_object_new (EV_TYPE_LINK_ACTION,
+ "uri", uri,
+ "type", EV_LINK_ACTION_TYPE_EXTERNAL_URI,
+ NULL));
+}
+
+EvLinkAction *
+ev_link_action_new_launch (const gchar *filename,
+ const gchar *params)
+{
+ return EV_LINK_ACTION (g_object_new (EV_TYPE_LINK_ACTION,
+ "filename", filename,
+ "params", params,
+ "type", EV_LINK_ACTION_TYPE_LAUNCH,
+ NULL));
+}
diff --git a/backend/ev-link-action.h b/backend/ev-link-action.h
new file mode 100644
index 0000000..6ca8d57
--- /dev/null
+++ b/backend/ev-link-action.h
@@ -0,0 +1,69 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <carlosgc@gnome.org>
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef EV_LINK_ACTION_H
+#define EV_LINK_ACTION_H
+
+#include <glib-object.h>
+#include "ev-link-dest.h"
+
+G_BEGIN_DECLS
+
+typedef struct _EvLinkAction EvLinkAction;
+typedef struct _EvLinkActionClass EvLinkActionClass;
+typedef struct _EvLinkActionPrivate EvLinkActionPrivate;
+
+#define EV_TYPE_LINK_ACTION (ev_link_action_get_type())
+#define EV_LINK_ACTION(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_LINK_ACTION, EvLinkAction))
+#define EV_LINK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_LINK_ACTION, EvLinkActionClass))
+#define EV_IS_LINK_ACTION(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_LINK_ACTION))
+#define EV_IS_LINK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_LINK_ACTION))
+#define EV_LINK_ACTION_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_LINK_ACTION, EvLinkActionClass))
+
+#define EV_TYPE_LINK_ACTION_TYPE (ev_link_action_type_get_type ())
+
+typedef enum {
+ EV_LINK_ACTION_TYPE_GOTO_DEST,
+ EV_LINK_ACTION_TYPE_GOTO_REMOTE,
+ EV_LINK_ACTION_TYPE_EXTERNAL_URI,
+ EV_LINK_ACTION_TYPE_LAUNCH,
+ /* We'll probably fill this in more as we support the other types of
+ * actions */
+} EvLinkActionType;
+
+GType ev_link_action_type_get_type (void) G_GNUC_CONST;
+GType ev_link_action_get_type (void) G_GNUC_CONST;
+
+EvLinkActionType ev_link_action_get_action_type (EvLinkAction *self);
+EvLinkDest *ev_link_action_get_dest (EvLinkAction *self);
+const gchar *ev_link_action_get_uri (EvLinkAction *self);
+const gchar *ev_link_action_get_filename (EvLinkAction *self);
+const gchar *ev_link_action_get_params (EvLinkAction *self);
+
+EvLinkAction *ev_link_action_new_dest (EvLinkDest *dest);
+EvLinkAction *ev_link_action_new_remote (EvLinkDest *dest,
+ const gchar *filename);
+EvLinkAction *ev_link_action_new_external_uri (const gchar *uri);
+EvLinkAction *ev_link_action_new_launch (const gchar *filename,
+ const gchar *params);
+
+G_END_DECLS
+
+#endif /* EV_LINK_ACTION_H */
diff --git a/backend/ev-link-dest.c b/backend/ev-link-dest.c
new file mode 100644
index 0000000..2fd2f4d
--- /dev/null
+++ b/backend/ev-link-dest.c
@@ -0,0 +1,429 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <carlosgc@gnome.org>
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "ev-link-dest.h"
+
+enum {
+ PROP_0,
+ PROP_TYPE,
+ PROP_PAGE,
+ PROP_LEFT,
+ PROP_TOP,
+ PROP_BOTTOM,
+ PROP_RIGHT,
+ PROP_ZOOM,
+ PROP_NAMED
+};
+
+struct _EvLinkDest {
+ GObject base_instance;
+
+ EvLinkDestPrivate *priv;
+};
+
+struct _EvLinkDestClass {
+ GObjectClass base_class;
+};
+
+struct _EvLinkDestPrivate {
+ EvLinkDestType type;
+ int page;
+ double top;
+ double left;
+ double bottom;
+ double right;
+ double zoom;
+ gchar *named;
+};
+
+G_DEFINE_TYPE (EvLinkDest, ev_link_dest, G_TYPE_OBJECT)
+
+#define EV_LINK_DEST_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_LINK_DEST, EvLinkDestPrivate))
+
+GType
+ev_link_dest_type_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GEnumValue values[] = {
+ { EV_LINK_DEST_TYPE_PAGE, "EV_LINK_DEST_TYPE_PAGE", "page" },
+ { EV_LINK_DEST_TYPE_XYZ, "EV_LINK_DEST_TYPE_XYZ", "xyz" },
+ { EV_LINK_DEST_TYPE_FIT, "EV_LINK_DEST_TYPE_FIT", "fit" },
+ { EV_LINK_DEST_TYPE_FITH, "EV_LINK_DEST_TYPE_FITH", "fith" },
+ { EV_LINK_DEST_TYPE_FITV, "EV_LINK_DEST_TYPE_FITV", "fitv" },
+ { EV_LINK_DEST_TYPE_FITR, "EV_LINK_DEST_TYPE_FITR", "fitr" },
+ { EV_LINK_DEST_TYPE_NAMED, "EV_LINK_DEST_TYPE_NAMED", "named" },
+ { EV_LINK_DEST_TYPE_UNKNOWN, "EV_LINK_DEST_TYPE_UNKNOWN", "unknown" },
+ { 0, NULL, NULL }
+ };
+
+ type = g_enum_register_static ("EvLinkDestType", values);
+ }
+
+ return type;
+}
+
+EvLinkDestType
+ev_link_dest_get_dest_type (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ return self->priv->type;
+}
+
+gint
+ev_link_dest_get_page (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), -1);
+
+ return self->priv->page;
+}
+
+gdouble
+ev_link_dest_get_top (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ return self->priv->top;
+}
+
+gdouble
+ev_link_dest_get_left (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ return self->priv->left;
+}
+
+gdouble
+ev_link_dest_get_bottom (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ return self->priv->bottom;
+}
+
+gdouble
+ev_link_dest_get_right (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ return self->priv->right;
+}
+
+gdouble
+ev_link_dest_get_zoom (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ return self->priv->zoom;
+}
+
+const gchar *
+ev_link_dest_get_named_dest (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), NULL);
+
+ return self->priv->named;
+}
+
+static void
+ev_link_dest_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *param_spec)
+{
+ EvLinkDest *self;
+
+ self = EV_LINK_DEST (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ g_value_set_enum (value, self->priv->type);
+ break;
+ case PROP_PAGE:
+ g_value_set_int (value, self->priv->page);
+ break;
+ case PROP_TOP:
+ g_value_set_double (value, self->priv->top);
+ break;
+ case PROP_LEFT:
+ g_value_set_double (value, self->priv->left);
+ break;
+ case PROP_BOTTOM:
+ g_value_set_double (value, self->priv->bottom);
+ break;
+ case PROP_RIGHT:
+ g_value_set_double (value, self->priv->left);
+ break;
+ case PROP_ZOOM:
+ g_value_set_double (value, self->priv->zoom);
+ break;
+ case PROP_NAMED:
+ g_value_set_string (value, self->priv->named);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
+ }
+}
+
+static void
+ev_link_dest_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *param_spec)
+{
+ EvLinkDest *self = EV_LINK_DEST (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ self->priv->type = g_value_get_enum (value);
+ break;
+ case PROP_PAGE:
+ self->priv->page = g_value_get_int (value);
+ break;
+ case PROP_TOP:
+ self->priv->top = g_value_get_double (value);
+ break;
+ case PROP_LEFT:
+ self->priv->left = g_value_get_double (value);
+ break;
+ case PROP_BOTTOM:
+ self->priv->bottom = g_value_get_double (value);
+ break;
+ case PROP_RIGHT:
+ self->priv->right = g_value_get_double (value);
+ break;
+ case PROP_ZOOM:
+ self->priv->zoom = g_value_get_double (value);
+ break;
+ case PROP_NAMED:
+ self->priv->named = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
+ }
+}
+
+static void
+ev_link_dest_finalize (GObject *object)
+{
+ EvLinkDestPrivate *priv;
+
+ priv = EV_LINK_DEST (object)->priv;
+
+ if (priv->named) {
+ g_free (priv->named);
+ priv->named = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_link_dest_parent_class)->finalize (object);
+}
+
+static void
+ev_link_dest_init (EvLinkDest *ev_link_dest)
+{
+ ev_link_dest->priv = EV_LINK_DEST_GET_PRIVATE (ev_link_dest);
+
+ ev_link_dest->priv->named = NULL;
+}
+
+static void
+ev_link_dest_class_init (EvLinkDestClass *ev_link_dest_class)
+{
+ GObjectClass *g_object_class;
+
+ g_object_class = G_OBJECT_CLASS (ev_link_dest_class);
+
+ g_object_class->set_property = ev_link_dest_set_property;
+ g_object_class->get_property = ev_link_dest_get_property;
+
+ g_object_class->finalize = ev_link_dest_finalize;
+
+ g_type_class_add_private (g_object_class, sizeof (EvLinkDestPrivate));
+
+ g_object_class_install_property (g_object_class,
+ PROP_TYPE,
+ g_param_spec_enum ("type",
+ "Dest Type",
+ "The destination type",
+ EV_TYPE_LINK_DEST_TYPE,
+ EV_LINK_DEST_TYPE_UNKNOWN,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_PAGE,
+ g_param_spec_int ("page",
+ "Dest Page",
+ "The destination page",
+ -1,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_LEFT,
+ g_param_spec_double ("left",
+ "Left coordinate",
+ "The left coordinate",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_TOP,
+ g_param_spec_double ("top",
+ "Top coordinate",
+ "The top coordinate",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_BOTTOM,
+ g_param_spec_double ("bottom",
+ "Bottom coordinate",
+ "The bottom coordinate",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_RIGHT,
+ g_param_spec_double ("right",
+ "Right coordinate",
+ "The right coordinate",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (g_object_class,
+ PROP_ZOOM,
+ g_param_spec_double ("zoom",
+ "Zoom",
+ "Zoom",
+ 0,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_NAMED,
+ g_param_spec_string ("named",
+ "Named destination",
+ "The named destination",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+EvLinkDest *
+ev_link_dest_new_page (gint page)
+{
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_PAGE,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_xyz (gint page,
+ gdouble left,
+ gdouble top,
+ gdouble zoom)
+{
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_XYZ,
+ "left", left,
+ "top", top,
+ "zoom", zoom,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_fit (gint page)
+{
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_FIT,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_fith (gint page,
+ gdouble top)
+{
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_FITH,
+ "top", top,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_fitv (gint page,
+ gdouble left)
+{
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_FITV,
+ "left", left,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_fitr (gint page,
+ gdouble left,
+ gdouble bottom,
+ gdouble right,
+ gdouble top)
+{
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_FITR,
+ "left", left,
+ "bottom", bottom,
+ "right", right,
+ "top", top,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_named (const gchar *named_dest)
+{
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "named", named_dest,
+ "type", EV_LINK_DEST_TYPE_NAMED,
+ NULL));
+}
diff --git a/backend/ev-link-dest.h b/backend/ev-link-dest.h
new file mode 100644
index 0000000..40a8a9b
--- /dev/null
+++ b/backend/ev-link-dest.h
@@ -0,0 +1,83 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <carlosgc@gnome.org>
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef EV_LINK_DEST_H
+#define EV_LINK_DEST_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EvLinkDest EvLinkDest;
+typedef struct _EvLinkDestClass EvLinkDestClass;
+typedef struct _EvLinkDestPrivate EvLinkDestPrivate;
+
+#define EV_TYPE_LINK_DEST (ev_link_dest_get_type())
+#define EV_LINK_DEST(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_LINK_DEST, EvLinkDest))
+#define EV_LINK_DEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_LINK_DEST, EvLinkDestClass))
+#define EV_IS_LINK_DEST(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_LINK_DEST))
+#define EV_IS_LINK_DEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_LINK_DEST))
+#define EV_LINK_DEST_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_LINK_DEST, EvLinkDestClass))
+
+#define EV_TYPE_LINK_DEST_TYPE (ev_link_dest_type_get_type ())
+
+typedef enum {
+ EV_LINK_DEST_TYPE_PAGE,
+ EV_LINK_DEST_TYPE_XYZ,
+ EV_LINK_DEST_TYPE_FIT,
+ EV_LINK_DEST_TYPE_FITH,
+ EV_LINK_DEST_TYPE_FITV,
+ EV_LINK_DEST_TYPE_FITR,
+ EV_LINK_DEST_TYPE_NAMED,
+ EV_LINK_DEST_TYPE_UNKNOWN
+} EvLinkDestType;
+
+GType ev_link_dest_type_get_type (void) G_GNUC_CONST;
+GType ev_link_dest_get_type (void) G_GNUC_CONST;
+
+EvLinkDestType ev_link_dest_get_dest_type (EvLinkDest *self);
+gint ev_link_dest_get_page (EvLinkDest *self);
+gdouble ev_link_dest_get_top (EvLinkDest *self);
+gdouble ev_link_dest_get_left (EvLinkDest *self);
+gdouble ev_link_dest_get_bottom (EvLinkDest *self);
+gdouble ev_link_dest_get_right (EvLinkDest *self);
+gdouble ev_link_dest_get_zoom (EvLinkDest *self);
+const gchar *ev_link_dest_get_named_dest (EvLinkDest *self);
+
+EvLinkDest *ev_link_dest_new_page (gint page);
+EvLinkDest *ev_link_dest_new_xyz (gint page,
+ gdouble left,
+ gdouble top,
+ gdouble zoom);
+EvLinkDest *ev_link_dest_new_fit (gint page);
+EvLinkDest *ev_link_dest_new_fith (gint page,
+ gdouble top);
+EvLinkDest *ev_link_dest_new_fitv (gint page,
+ gdouble left);
+EvLinkDest *ev_link_dest_new_fitr (gint page,
+ gdouble left,
+ gdouble bottom,
+ gdouble right,
+ gdouble top);
+EvLinkDest *ev_link_dest_new_named (const gchar *named_dest);
+
+G_END_DECLS
+
+#endif /* EV_LINK_DEST_H */
diff --git a/backend/ev-link.c b/backend/ev-link.c
index a325c35..8561914 100644
--- a/backend/ev-link.c
+++ b/backend/ev-link.c
@@ -18,28 +18,14 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "ev-link.h"
enum {
PROP_0,
PROP_TITLE,
- PROP_TYPE,
- PROP_PAGE,
- PROP_URI,
- PROP_LEFT,
- PROP_TOP,
- PROP_BOTTOM,
- PROP_RIGHT,
- PROP_ZOOM,
- PROP_FILENAME,
- PROP_PARAMS
+ PROP_ACTION
};
-
struct _EvLink {
GObject base_instance;
EvLinkPrivate *priv;
@@ -50,17 +36,8 @@ struct _EvLinkClass {
};
struct _EvLinkPrivate {
- char *title;
- char *uri;
- char *filename;
- char *params;
- EvLinkType type;
- int page;
- double top;
- double left;
- double bottom;
- double right;
- double zoom;
+ gchar *title;
+ EvLinkAction *action;
};
G_DEFINE_TYPE (EvLink, ev_link, G_TYPE_OBJECT)
@@ -68,32 +45,7 @@ G_DEFINE_TYPE (EvLink, ev_link, G_TYPE_OBJECT)
#define EV_LINK_GET_PRIVATE(object) \
(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_LINK, EvLinkPrivate))
-GType
-ev_link_type_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GEnumValue values[] = {
- { EV_LINK_TYPE_TITLE, "EV_LINK_TYPE_TITLE", "title" },
- { EV_LINK_TYPE_PAGE, "EV_LINK_TYPE_PAGE", "page" },
- { EV_LINK_TYPE_PAGE_XYZ, "EV_LINK_TYPE_PAGE_XYZ", "page-xyz" },
- { EV_LINK_TYPE_PAGE_FIT, "EV_LINK_TYPE_PAGE_FIT", "page-fit" },
- { EV_LINK_TYPE_PAGE_FITH, "EV_LINK_TYPE_PAGE_FITH", "page-fith" },
- { EV_LINK_TYPE_PAGE_FITV, "EV_LINK_TYPE_PAGE_FITV", "page-fitv" },
- { EV_LINK_TYPE_PAGE_FITR, "EV_LINK_TYPE_PAGE_FITR", "page-fitr" },
- { EV_LINK_TYPE_EXTERNAL_URI, "EV_LINK_TYPE_EXTERNAL_URI", "external" },
- { EV_LINK_TYPE_LAUNCH, "EV_LINK_TYPE_LAUNCH", "launch" },
- { 0, NULL, NULL }
- };
-
- type = g_enum_register_static ("EvLinkType", values);
- }
-
- return type;
-}
-
-const char *
+const gchar *
ev_link_get_title (EvLink *self)
{
g_return_val_if_fail (EV_IS_LINK (self), NULL);
@@ -101,88 +53,18 @@ ev_link_get_title (EvLink *self)
return self->priv->title;
}
-const char *
-ev_link_get_uri (EvLink *self)
+EvLinkAction *
+ev_link_get_action (EvLink *self)
{
g_return_val_if_fail (EV_IS_LINK (self), NULL);
- return self->priv->uri;
-}
-
-EvLinkType
-ev_link_get_link_type (EvLink *self)
-{
- g_return_val_if_fail (EV_IS_LINK (self), 0);
-
- return self->priv->type;
-}
-
-int
-ev_link_get_page (EvLink *self)
-{
- g_return_val_if_fail (EV_IS_LINK (self), -1);
-
- return self->priv->page;
-}
-
-double
-ev_link_get_top (EvLink *self)
-{
- g_return_val_if_fail (EV_IS_LINK (self), 0);
-
- return self->priv->top;
-}
-
-double
-ev_link_get_left (EvLink *self)
-{
- g_return_val_if_fail (EV_IS_LINK (self), 0);
-
- return self->priv->left;
-}
-
-double
-ev_link_get_bottom (EvLink *self)
-{
- g_return_val_if_fail (EV_IS_LINK (self), 0);
-
- return self->priv->bottom;
-}
-
-double
-ev_link_get_right (EvLink *self)
-{
- g_return_val_if_fail (EV_IS_LINK (self), 0);
-
- return self->priv->right;
-}
-
-const char *
-ev_link_get_filename (EvLink *link)
-{
- g_return_val_if_fail (EV_IS_LINK (link), NULL);
-
- return link->priv->filename;
-}
-
-const char *
-ev_link_get_params (EvLink *link)
-{
- g_return_val_if_fail (EV_IS_LINK (link), NULL);
-
- return link->priv->params;
-}
-
-double
-ev_link_get_zoom (EvLink *self)
-{
- g_return_val_if_fail (EV_IS_LINK (self), 0);
-
- return self->priv->zoom;
+ return self->priv->action;
}
static void
-ev_link_get_property (GObject *object, guint prop_id, GValue *value,
+ev_link_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
GParamSpec *param_spec)
{
EvLink *self;
@@ -190,103 +72,48 @@ ev_link_get_property (GObject *object, guint prop_id, GValue *value,
self = EV_LINK (object);
switch (prop_id) {
- case PROP_TITLE:
- g_value_set_string (value, self->priv->title);
- break;
- case PROP_URI:
- g_value_set_string (value, self->priv->uri);
- break;
- case PROP_TYPE:
- g_value_set_enum (value, self->priv->type);
- break;
- case PROP_PAGE:
- g_value_set_int (value, self->priv->page);
- break;
- case PROP_TOP:
- g_value_set_double (value, self->priv->top);
- break;
- case PROP_LEFT:
- g_value_set_double (value, self->priv->left);
- break;
- case PROP_BOTTOM:
- g_value_set_double (value, self->priv->bottom);
- break;
- case PROP_RIGHT:
- g_value_set_double (value, self->priv->left);
- break;
- case PROP_ZOOM:
- g_value_set_double (value, self->priv->zoom);
- break;
- case PROP_FILENAME:
- g_value_set_string (value, self->priv->filename);
- case PROP_PARAMS:
- g_value_set_string (value, self->priv->params);
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
- prop_id,
- param_spec);
- break;
+ case PROP_TITLE:
+ g_value_set_string (value, self->priv->title);
+ break;
+ case PROP_ACTION:
+ g_value_set_pointer (value, self->priv->action);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
}
}
static void
-ev_link_set_property (GObject *object, guint prop_id, const GValue *value,
- GParamSpec *param_spec)
+ev_link_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *param_spec)
{
- EvLink *link = EV_LINK (object);
+ EvLink *self = EV_LINK (object);
switch (prop_id) {
- case PROP_TITLE:
- link->priv->title = g_strdup (g_value_get_string (value));
- break;
- case PROP_URI:
- link->priv->uri = g_strdup (g_value_get_string (value));
- break;
- case PROP_TYPE:
- link->priv->type = g_value_get_enum (value);
- break;
- case PROP_PAGE:
- link->priv->page = g_value_get_int (value);
- break;
- case PROP_TOP:
- link->priv->top = g_value_get_double (value);
- break;
- case PROP_LEFT:
- link->priv->left = g_value_get_double (value);
- break;
- case PROP_BOTTOM:
- link->priv->bottom = g_value_get_double (value);
- break;
- case PROP_RIGHT:
- link->priv->right = g_value_get_double (value);
- break;
- case PROP_ZOOM:
- link->priv->zoom = g_value_get_double (value);
- break;
- case PROP_FILENAME:
- g_free (link->priv->filename);
- link->priv->filename = g_strdup (g_value_get_string (value));
- break;
- case PROP_PARAMS:
- g_free (link->priv->params);
- link->priv->params = g_strdup (g_value_get_string (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
- prop_id,
- param_spec);
- break;
+ case PROP_TITLE:
+ self->priv->title = g_value_dup_string (value);
+ break;
+ case PROP_ACTION:
+ self->priv->action = g_value_get_pointer (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
}
}
static void
-ev_window_dispose (GObject *object)
+ev_link_finalize (GObject *object)
{
EvLinkPrivate *priv;
- g_return_if_fail (EV_IS_LINK (object));
-
priv = EV_LINK (object)->priv;
if (priv->title) {
@@ -294,30 +121,21 @@ ev_window_dispose (GObject *object)
priv->title = NULL;
}
- if (priv->uri) {
- g_free (priv->uri);
- priv->uri = NULL;
- }
-
- if (priv->filename) {
- g_free (priv->filename);
- priv->filename = NULL;
- }
-
- if (priv->params) {
- g_free (priv->params);
- priv->params = NULL;
+ if (priv->action) {
+ g_object_unref (priv->action);
+ priv->action = NULL;
}
- G_OBJECT_CLASS (ev_link_parent_class)->dispose (object);
+ G_OBJECT_CLASS (ev_link_parent_class)->finalize (object);
}
static void
ev_link_init (EvLink *ev_link)
{
ev_link->priv = EV_LINK_GET_PRIVATE (ev_link);
- ev_link->priv->page = -1;
- ev_link->priv->type = EV_LINK_TYPE_TITLE;
+
+ ev_link->priv->title = NULL;
+ ev_link->priv->action = NULL;
}
static void
@@ -326,10 +144,12 @@ ev_link_class_init (EvLinkClass *ev_window_class)
GObjectClass *g_object_class;
g_object_class = G_OBJECT_CLASS (ev_window_class);
- g_object_class->dispose = ev_window_dispose;
+
g_object_class->set_property = ev_link_set_property;
g_object_class->get_property = ev_link_get_property;
+ g_object_class->finalize = ev_link_finalize;
+
g_type_class_add_private (g_object_class, sizeof (EvLinkPrivate));
g_object_class_install_property (g_object_class,
@@ -341,216 +161,25 @@ ev_link_class_init (EvLinkClass *ev_window_class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (g_object_class,
- PROP_URI,
- g_param_spec_string ("uri",
- "Link URI",
- "The link URI",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (g_object_class,
- PROP_FILENAME,
- g_param_spec_string ("filename",
- "Filename",
- "The link filename",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (g_object_class,
- PROP_PARAMS,
- g_param_spec_string ("params",
- "Params",
- "The link params",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (g_object_class,
- PROP_TYPE,
- g_param_spec_enum ("type",
- "Link Type",
- "The link type",
- EV_TYPE_LINK_TYPE,
- EV_LINK_TYPE_TITLE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (g_object_class,
- PROP_PAGE,
- g_param_spec_int ("page",
- "Link Page",
- "The link page",
- -1,
- G_MAXINT,
- 0,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (g_object_class,
- PROP_LEFT,
- g_param_spec_double ("left",
- "Left coordinate",
- "The left coordinate",
- -G_MAXDOUBLE,
- G_MAXDOUBLE,
- 0,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (g_object_class,
- PROP_TOP,
- g_param_spec_double ("top",
- "Top coordinate",
- "The top coordinate",
- -G_MAXDOUBLE,
- G_MAXDOUBLE,
- 0,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (g_object_class,
- PROP_BOTTOM,
- g_param_spec_double ("bottom",
- "Bottom coordinate",
- "The bottom coordinate",
- -G_MAXDOUBLE,
- G_MAXDOUBLE,
- 0,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (g_object_class,
- PROP_RIGHT,
- g_param_spec_double ("right",
- "Right coordinate",
- "The right coordinate",
- -G_MAXDOUBLE,
- G_MAXDOUBLE,
- 0,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (g_object_class,
- PROP_ZOOM,
- g_param_spec_double ("zoom",
- "Zoom",
- "Zoom",
- 0,
- G_MAXDOUBLE,
- 0,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
-}
-
-EvLink *
-ev_link_new_title (const char *title)
-{
- return EV_LINK (g_object_new (EV_TYPE_LINK,
- "title", title,
- "type", EV_LINK_TYPE_TITLE,
- NULL));
-}
-
-EvLink *
-ev_link_new_page (const char *title, int page)
-{
- return EV_LINK (g_object_new (EV_TYPE_LINK,
- "title", title,
- "page", page,
- "type", EV_LINK_TYPE_PAGE,
- NULL));
-}
-
-EvLink *
-ev_link_new_page_xyz (const char *title,
- int page,
- double left,
- double top,
- double zoom)
-{
- return EV_LINK (g_object_new (EV_TYPE_LINK,
- "title", title,
- "page", page,
- "type", EV_LINK_TYPE_PAGE_XYZ,
- "left", left,
- "top", top,
- "zoom", zoom,
- NULL));
-}
-
-EvLink *
-ev_link_new_page_fit (const char *title,
- int page)
-{
- return EV_LINK (g_object_new (EV_TYPE_LINK,
- "title", title,
- "page", page,
- "type", EV_LINK_TYPE_PAGE_FIT,
- NULL));
-}
-
-EvLink *
-ev_link_new_page_fith (const char *title,
- int page,
- double top)
-{
- return EV_LINK (g_object_new (EV_TYPE_LINK,
- "title", title,
- "page", page,
- "type", EV_LINK_TYPE_PAGE_FITH,
- "top", top,
- NULL));
-}
-
-EvLink *
-ev_link_new_page_fitv (const char *title,
- int page,
- double left)
-{
- return EV_LINK (g_object_new (EV_TYPE_LINK,
- "title", title,
- "page", page,
- "type", EV_LINK_TYPE_PAGE_FITV,
- "left", left,
- NULL));
-}
-
-EvLink *
-ev_link_new_page_fitr (const char *title,
- int page,
- double left,
- double bottom,
- double right,
- double top)
-{
- return EV_LINK (g_object_new (EV_TYPE_LINK,
- "title", title,
- "page", page,
- "type", EV_LINK_TYPE_PAGE_FITR,
- "left", left,
- "bottom", bottom,
- "right", right,
- "top", top,
- NULL));
+ PROP_ACTION,
+ g_param_spec_pointer ("action",
+ "Link Action",
+ "The link action",
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
}
EvLink *
-ev_link_new_external (const char *title, const char *uri)
+ev_link_new (const char *title,
+ EvLinkAction *action)
{
return EV_LINK (g_object_new (EV_TYPE_LINK,
"title", title,
- "uri", uri,
- "type", EV_LINK_TYPE_EXTERNAL_URI,
- NULL));
-}
-
-EvLink *
-ev_link_new_launch (const char *title,
- const char *filename,
- const char *params)
-{
- return EV_LINK (g_object_new (EV_TYPE_LINK,
- "title", title,
- "filename", filename,
- "params", params,
- "type", EV_LINK_TYPE_LAUNCH,
+ "action", action,
NULL));
}
+/* Link Mapping stuff */
static void
ev_link_mapping_free_foreach (EvLinkMapping *mapping)
{
@@ -568,7 +197,6 @@ ev_link_mapping_free (GList *link_mapping)
g_list_free (link_mapping);
}
-
EvLink *
ev_link_mapping_find (GList *link_mapping,
gdouble x,
diff --git a/backend/ev-link.h b/backend/ev-link.h
index 6ab2811..b7304de 100644
--- a/backend/ev-link.h
+++ b/backend/ev-link.h
@@ -21,6 +21,7 @@
#define EV_LINK_H
#include <glib-object.h>
+#include "ev-link-action.h"
G_BEGIN_DECLS
@@ -28,77 +29,22 @@ typedef struct _EvLink EvLink;
typedef struct _EvLinkClass EvLinkClass;
typedef struct _EvLinkPrivate EvLinkPrivate;
-#define EV_TYPE_LINK (ev_link_get_type())
-#define EV_LINK(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_LINK, EvLink))
-#define EV_LINK_CLASS(klass) (G_TYPE_CHACK_CLASS_CAST((klass), EV_TYPE_LINK, EvLinkClass))
-#define EV_IS_LINK(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_LINK))
-#define EV_IS_LINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_LINK))
+#define EV_TYPE_LINK (ev_link_get_type())
+#define EV_LINK(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_LINK, EvLink))
+#define EV_LINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_LINK, EvLinkClass))
+#define EV_IS_LINK(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_LINK))
+#define EV_IS_LINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_LINK))
#define EV_LINK_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_LINK, EvLinkClass))
-#define EV_TYPE_LINK_TYPE (ev_link_type_get_type ())
+GType ev_link_get_type (void) G_GNUC_CONST;
+EvLink *ev_link_new (const gchar *title,
+ EvLinkAction *action);
-
-typedef enum
-{
- EV_LINK_TYPE_TITLE,
- EV_LINK_TYPE_PAGE,
- EV_LINK_TYPE_PAGE_XYZ,
- EV_LINK_TYPE_PAGE_FIT,
- EV_LINK_TYPE_PAGE_FITH,
- EV_LINK_TYPE_PAGE_FITV,
- EV_LINK_TYPE_PAGE_FITR,
- EV_LINK_TYPE_EXTERNAL_URI,
- EV_LINK_TYPE_LAUNCH
- /* We'll probably fill this in more as we support the other types of
- * links */
-} EvLinkType;
-
-GType ev_link_type_get_type (void);
-GType ev_link_get_type (void);
-
-EvLink *ev_link_new_title (const char *title);
-EvLink *ev_link_new_page (const char *title,
- int page);
-EvLink *ev_link_new_page_xyz (const char *title,
- int page,
- double top,
- double left,
- double zoom);
-EvLink *ev_link_new_page_fith (const char *title,
- int page,
- double top);
-EvLink *ev_link_new_page_fitv (const char *title,
- int page,
- double left);
-EvLink *ev_link_new_page_fitr (const char *title,
- int page,
- double left,
- double bottom,
- double right,
- double top);
-EvLink *ev_link_new_page_fit (const char *title,
- int page);
-EvLink *ev_link_new_external (const char *title,
- const char *uri);
-EvLink *ev_link_new_launch (const char *title,
- const char *filename,
- const char *params);
-
-const char *ev_link_get_title (EvLink *link);
-const char *ev_link_get_uri (EvLink *link);
-EvLinkType ev_link_get_link_type (EvLink *link);
-int ev_link_get_page (EvLink *link);
-double ev_link_get_top (EvLink *link);
-double ev_link_get_left (EvLink *link);
-double ev_link_get_bottom (EvLink *link);
-double ev_link_get_right (EvLink *link);
-double ev_link_get_zoom (EvLink *link);
-const char *ev_link_get_filename (EvLink *link);
-const char *ev_link_get_params (EvLink *link);
+const gchar *ev_link_get_title (EvLink *self);
+EvLinkAction *ev_link_get_action (EvLink *self);
/* Link Mapping stuff */
-
typedef struct _EvLinkMapping EvLinkMapping;
struct _EvLinkMapping
{
diff --git a/pdf/ev-poppler.cc b/pdf/ev-poppler.cc
index a4be75e..efdd15f 100644
--- a/pdf/ev-poppler.cc
+++ b/pdf/ev-poppler.cc
@@ -80,7 +80,8 @@ static void pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails
gint *height);
static int pdf_document_get_n_pages (EvDocument *document);
-static EvLink * ev_link_from_action (PopplerAction *action);
+static EvLinkDest *ev_link_dest_from_dest (PopplerDest *dest);
+static EvLink *ev_link_from_action (PopplerAction *action);
static void pdf_document_search_free (PdfDocumentSearch *search);
@@ -276,45 +277,6 @@ pdf_document_get_page_label (EvDocument *document,
return label;
}
-static GList *
-pdf_document_get_links (EvDocument *document,
- int page)
-{
- PdfDocument *pdf_document;
- PopplerPage *poppler_page;
- GList *retval = NULL;
- GList *mapping_list;
- GList *list;
- double height;
-
- pdf_document = PDF_DOCUMENT (document);
- poppler_page = poppler_document_get_page (pdf_document->document,
- page);
- mapping_list = poppler_page_get_link_mapping (poppler_page);
- poppler_page_get_size (poppler_page, NULL, &height);
-
- for (list = mapping_list; list; list = list->next) {
- PopplerLinkMapping *link_mapping;
- EvLinkMapping *ev_link_mapping;
-
- link_mapping = (PopplerLinkMapping *)list->data;
- ev_link_mapping = g_new (EvLinkMapping, 1);
- ev_link_mapping->link = ev_link_from_action (link_mapping->action);
- ev_link_mapping->x1 = link_mapping->area.x1;
- ev_link_mapping->x2 = link_mapping->area.x2;
- /* Invert this for X-style coordinates */
- ev_link_mapping->y1 = height - link_mapping->area.y2;
- ev_link_mapping->y2 = height - link_mapping->area.y1;
-
- retval = g_list_prepend (retval, ev_link_mapping);
- }
-
- poppler_page_free_link_mapping (mapping_list);
- g_object_unref (poppler_page);
-
- return g_list_reverse (retval);
-}
-
static gboolean
pdf_document_has_attachments (EvDocument *document)
{
@@ -666,7 +628,6 @@ pdf_document_document_iface_init (EvDocumentIface *iface)
iface->get_n_pages = pdf_document_get_n_pages;
iface->get_page_size = pdf_document_get_page_size;
iface->get_page_label = pdf_document_get_page_label;
- iface->get_links = pdf_document_get_links;
iface->has_attachments = pdf_document_has_attachments;
iface->get_attachments = pdf_document_get_attachments;
iface->render_pixbuf = pdf_document_render_pixbuf;
@@ -726,24 +687,23 @@ pdf_document_fonts_scan (EvDocumentFonts *document_fonts,
static const char *
font_type_to_string (PopplerFontType type)
{
- switch (type)
- {
- case POPPLER_FONT_TYPE_TYPE1:
- return _("Type 1");
- case POPPLER_FONT_TYPE_TYPE1C:
- return _("Type 1C");
- case POPPLER_FONT_TYPE_TYPE3:
- return _("Type 3");
- case POPPLER_FONT_TYPE_TRUETYPE:
- return _("TrueType");
- case POPPLER_FONT_TYPE_CID_TYPE0:
- return _("Type 1 (CID)");
- case POPPLER_FONT_TYPE_CID_TYPE0C:
- return _("Type 1C (CID)");
- case POPPLER_FONT_TYPE_CID_TYPE2:
- return _("TrueType (CID)");
- default:
- return _("Unknown font type");
+ switch (type) {
+ case POPPLER_FONT_TYPE_TYPE1:
+ return _("Type 1");
+ case POPPLER_FONT_TYPE_TYPE1C:
+ return _("Type 1C");
+ case POPPLER_FONT_TYPE_TYPE3:
+ return _("Type 3");
+ case POPPLER_FONT_TYPE_TRUETYPE:
+ return _("TrueType");
+ case POPPLER_FONT_TYPE_CID_TYPE0:
+ return _("Type 1 (CID)");
+ case POPPLER_FONT_TYPE_CID_TYPE0C:
+ return _("Type 1C (CID)");
+ case POPPLER_FONT_TYPE_CID_TYPE2:
+ return _("TrueType (CID)");
+ default:
+ return _("Unknown font type");
}
}
@@ -820,111 +780,115 @@ pdf_document_links_has_document_links (EvDocumentLinks *document_links)
return TRUE;
}
-static EvLink *
-ev_link_from_dest (PopplerAction *action)
+static EvLinkDest *
+ev_link_dest_from_dest (PopplerDest *dest)
{
- EvLink *link = NULL;
+ EvLinkDest *ev_dest = NULL;
const char *unimplemented_dest = NULL;
- switch (action->goto_dest.dest->type) {
- case POPPLER_DEST_UNKNOWN:
- unimplemented_dest = "POPPLER_DEST_UNKNOWN";
- break;
- case POPPLER_DEST_XYZ:
- link = ev_link_new_page_xyz (action->any.title,
- action->goto_dest.dest->page_num - 1,
- action->goto_dest.dest->left,
- action->goto_dest.dest->top,
- action->goto_dest.dest->zoom);
- break;
- case POPPLER_DEST_FIT:
- link = ev_link_new_page_fit (action->any.title,
- action->goto_dest.dest->page_num - 1);
- break;
- case POPPLER_DEST_FITH:
- link = ev_link_new_page_fith (action->any.title,
- action->goto_dest.dest->page_num - 1,
- action->goto_dest.dest->top);
- break;
- case POPPLER_DEST_FITV:
- link = ev_link_new_page_fitv (action->any.title,
- action->goto_dest.dest->page_num - 1,
- action->goto_dest.dest->left);
- break;
- case POPPLER_DEST_FITR:
- link = ev_link_new_page_fitr (action->any.title,
- action->goto_dest.dest->page_num - 1,
- action->goto_dest.dest->left,
- action->goto_dest.dest->bottom,
- action->goto_dest.dest->right,
- action->goto_dest.dest->top);
- break;
- case POPPLER_DEST_FITB:
- unimplemented_dest = "POPPLER_DEST_FITB";
- break;
- case POPPLER_DEST_FITBH:
- unimplemented_dest = "POPPLER_DEST_FITBH";
- break;
- case POPPLER_DEST_FITBV:
- unimplemented_dest = "POPPLER_DEST_FITBV";
- break;
+ g_assert (dest != NULL);
+
+ switch (dest->type) {
+ case POPPLER_DEST_XYZ:
+ ev_dest = ev_link_dest_new_xyz (dest->page_num - 1,
+ dest->left,
+ dest->top,
+ dest->zoom);
+ break;
+ case POPPLER_DEST_FIT:
+ ev_dest = ev_link_dest_new_fit (dest->page_num - 1);
+ break;
+ case POPPLER_DEST_FITH:
+ ev_dest = ev_link_dest_new_fith (dest->page_num - 1,
+ dest->top);
+ break;
+ case POPPLER_DEST_FITV:
+ ev_dest = ev_link_dest_new_fitv (dest->page_num - 1,
+ dest->left);
+ break;
+ case POPPLER_DEST_FITR:
+ ev_dest = ev_link_dest_new_fitr (dest->page_num - 1,
+ dest->left,
+ dest->bottom,
+ dest->right,
+ dest->top);
+ break;
+ case POPPLER_DEST_FITB:
+ unimplemented_dest = "POPPLER_DEST_FITB";
+ break;
+ case POPPLER_DEST_FITBH:
+ unimplemented_dest = "POPPLER_DEST_FITBH";
+ break;
+ case POPPLER_DEST_FITBV:
+ unimplemented_dest = "POPPLER_DEST_FITBV";
+ break;
+ case POPPLER_DEST_NAMED:
+ ev_dest = ev_link_dest_new_named (dest->named_dest);
+ break;
+ case POPPLER_DEST_UNKNOWN:
+ unimplemented_dest = "POPPLER_DEST_UNKNOWN";
+ break;
}
-
+
if (unimplemented_dest) {
g_warning ("Unimplemented destination: %s, please post a bug report with a testcase.",
unimplemented_dest);
}
- if (link == NULL) {
- link = ev_link_new_page (action->any.title, action->goto_dest.dest->page_num - 1);
- }
-
- return link;
+ if (!ev_dest)
+ ev_dest = ev_link_dest_new_page (dest->page_num - 1);
+
+ return ev_dest;
}
static EvLink *
ev_link_from_action (PopplerAction *action)
{
- EvLink *link = NULL;
- const char *title;
- const char *unimplemented_action = NULL;
-
- title = action->any.title;
+ EvLink *link = NULL;
+ EvLinkAction *ev_action = NULL;
+ const char *unimplemented_action = NULL;
switch (action->type) {
- case POPPLER_ACTION_UNKNOWN:
- link = ev_link_new_title (title);
- break;
- case POPPLER_ACTION_GOTO_DEST:
- link = ev_link_from_dest (action);
- break;
- case POPPLER_ACTION_GOTO_REMOTE:
- unimplemented_action = "POPPLER_ACTION_GOTO_REMOTE";
- break;
- case POPPLER_ACTION_LAUNCH:
- link = ev_link_new_launch (title, action->launch.file_name,
- action->launch.params);
- break;
- case POPPLER_ACTION_URI:
- link = ev_link_new_external (title, action->uri.uri);
- break;
- case POPPLER_ACTION_NAMED:
- unimplemented_action = "POPPLER_ACTION_NAMED";
- break;
- case POPPLER_ACTION_MOVIE:
- unimplemented_action = "POPPLER_ACTION_MOVIE";
- break;
+ case POPPLER_ACTION_GOTO_DEST: {
+ EvLinkDest *dest;
+
+ dest = ev_link_dest_from_dest (action->goto_dest.dest);
+ ev_action = ev_link_action_new_dest (dest);
+ }
+ break;
+ case POPPLER_ACTION_GOTO_REMOTE: {
+ EvLinkDest *dest;
+
+ dest = ev_link_dest_from_dest (action->goto_remote.dest);
+ ev_action = ev_link_action_new_remote (dest,
+ action->goto_remote.file_name);
+
+ }
+ break;
+ case POPPLER_ACTION_LAUNCH:
+ ev_action = ev_link_action_new_launch (action->launch.file_name,
+ action->launch.params);
+ break;
+ case POPPLER_ACTION_URI:
+ ev_action = ev_link_action_new_external_uri (action->uri.uri);
+ break;
+ case POPPLER_ACTION_NAMED:
+ unimplemented_action = "POPPLER_ACTION_NAMED";
+ break;
+ case POPPLER_ACTION_MOVIE:
+ unimplemented_action = "POPPLER_ACTION_MOVIE";
+ break;
+ case POPPLER_ACTION_UNKNOWN:
+ unimplemented_action = "POPPLER_ACTION_UNKNOWN";
}
-
+
if (unimplemented_action) {
g_warning ("Unimplemented action: %s, please post a bug report with a testcase.",
unimplemented_action);
}
-
- if (link == NULL) {
- link = ev_link_new_title (title);
- }
-
+
+ link = ev_link_new (action->any.title, ev_action);
+
return link;
}
@@ -934,49 +898,83 @@ build_tree (PdfDocument *pdf_document,
GtkTreeIter *parent,
PopplerIndexIter *iter)
{
-
+
do {
GtkTreeIter tree_iter;
PopplerIndexIter *child;
PopplerAction *action;
- EvLink *link;
+ EvLink *link = NULL;
gboolean expand;
+ char *title_markup;
action = poppler_index_iter_get_action (iter);
expand = poppler_index_iter_is_open (iter);
- if (action) {
- char *title_markup;
- gtk_tree_store_append (GTK_TREE_STORE (model), &tree_iter, parent);
- link = ev_link_from_action (action);
+ if (!action)
+ continue;
+
+ switch (action->type) {
+ case POPPLER_ACTION_GOTO_DEST: {
+ /* For bookmarks, solve named destinations */
+ if (action->goto_dest.dest->type == POPPLER_DEST_NAMED) {
+ PopplerDest *dest;
+ EvLinkDest *ev_dest = NULL;
+ EvLinkAction *ev_action;
+
+ dest = poppler_document_find_dest (pdf_document->document,
+ action->goto_dest.dest->named_dest);
+ if (!dest) {
+ link = ev_link_from_action (action);
+ break;
+ }
+
+ ev_dest = ev_link_dest_from_dest (dest);
+ poppler_dest_free (dest);
+
+ ev_action = ev_link_action_new_dest (ev_dest);
+ link = ev_link_new (action->any.title, ev_action);
+ } else {
+ link = ev_link_from_action (action);
+ }
+ }
+ break;
+ default:
+ link = ev_link_from_action (action);
+ break;
+ }
+
+ if (!link) {
poppler_action_free (action);
- title_markup = g_markup_escape_text (ev_link_get_title (link), -1);
-
- gtk_tree_store_set (GTK_TREE_STORE (model), &tree_iter,
- EV_DOCUMENT_LINKS_COLUMN_MARKUP, title_markup,
- EV_DOCUMENT_LINKS_COLUMN_LINK, link,
- EV_DOCUMENT_LINKS_COLUMN_EXPAND, expand,
- -1);
-
- g_free (title_markup);
- g_object_unref (link);
-
- child = poppler_index_iter_get_child (iter);
- if (child)
- build_tree (pdf_document, model, &tree_iter, child);
- poppler_index_iter_free (child);
+ continue;
}
+
+ gtk_tree_store_append (GTK_TREE_STORE (model), &tree_iter, parent);
+ title_markup = g_markup_escape_text (ev_link_get_title (link), -1);
+
+ gtk_tree_store_set (GTK_TREE_STORE (model), &tree_iter,
+ EV_DOCUMENT_LINKS_COLUMN_MARKUP, title_markup,
+ EV_DOCUMENT_LINKS_COLUMN_LINK, link,
+ EV_DOCUMENT_LINKS_COLUMN_EXPAND, expand,
+ -1);
+
+ g_free (title_markup);
+ g_object_unref (link);
+
+ child = poppler_index_iter_get_child (iter);
+ if (child)
+ build_tree (pdf_document, model, &tree_iter, child);
+ poppler_index_iter_free (child);
+
} while (poppler_index_iter_next (iter));
}
-
static GtkTreeModel *
pdf_document_links_get_links_model (EvDocumentLinks *document_links)
{
PdfDocument *pdf_document = PDF_DOCUMENT (document_links);
GtkTreeModel *model = NULL;
PopplerIndexIter *iter;
-
+
g_return_val_if_fail (PDF_IS_DOCUMENT (document_links), NULL);
iter = poppler_index_iter_new (pdf_document->document);
@@ -993,11 +991,71 @@ pdf_document_links_get_links_model (EvDocumentLinks *document_links)
return model;
}
+static GList *
+pdf_document_links_get_links (EvDocumentLinks *document_links,
+ gint page)
+{
+ PdfDocument *pdf_document;
+ PopplerPage *poppler_page;
+ GList *retval = NULL;
+ GList *mapping_list;
+ GList *list;
+ double height;
+
+ pdf_document = PDF_DOCUMENT (document_links);
+ poppler_page = poppler_document_get_page (pdf_document->document,
+ page);
+ mapping_list = poppler_page_get_link_mapping (poppler_page);
+ poppler_page_get_size (poppler_page, NULL, &height);
+
+ for (list = mapping_list; list; list = list->next) {
+ PopplerLinkMapping *link_mapping;
+ EvLinkMapping *ev_link_mapping;
+
+ link_mapping = (PopplerLinkMapping *)list->data;
+ ev_link_mapping = g_new (EvLinkMapping, 1);
+ ev_link_mapping->link = ev_link_from_action (link_mapping->action);
+ ev_link_mapping->x1 = link_mapping->area.x1;
+ ev_link_mapping->x2 = link_mapping->area.x2;
+ /* Invert this for X-style coordinates */
+ ev_link_mapping->y1 = height - link_mapping->area.y2;
+ ev_link_mapping->y2 = height - link_mapping->area.y1;
+
+ retval = g_list_prepend (retval, ev_link_mapping);
+ }
+
+ poppler_page_free_link_mapping (mapping_list);
+ g_object_unref (poppler_page);
+
+ return g_list_reverse (retval);
+}
+
+static EvLinkDest *
+pdf_document_links_find_link_dest (EvDocumentLinks *document_links,
+ const gchar *link_name)
+{
+ PdfDocument *pdf_document;
+ PopplerDest *dest;
+ EvLinkDest *ev_dest = NULL;
+
+ pdf_document = PDF_DOCUMENT (document_links);
+ dest = poppler_document_find_dest (pdf_document->document,
+ link_name);
+ if (dest) {
+ ev_dest = ev_link_dest_from_dest (dest);
+ poppler_dest_free (dest);
+ }
+
+ return ev_dest;
+}
+
static void
pdf_document_document_links_iface_init (EvDocumentLinksIface *iface)
{
iface->has_document_links = pdf_document_links_has_document_links;
iface->get_links_model = pdf_document_links_get_links_model;
+ iface->get_links = pdf_document_links_get_links;
+ iface->find_link_dest = pdf_document_links_find_link_dest;
}
static GdkPixbuf *
diff --git a/shell/ev-application.c b/shell/ev-application.c
index 8721a0c..de5e3a0 100644
--- a/shell/ev-application.c
+++ b/shell/ev-application.c
@@ -185,7 +185,6 @@ ev_application_open_window (EvApplication *application,
#else
gtk_window_present (GTK_WINDOW (new_window));
#endif
-
return TRUE;
}
@@ -236,16 +235,15 @@ ev_application_get_uri_window (EvApplication *application, const char *uri)
return uri_window;
}
-gboolean
-ev_application_open_uri (EvApplication *application,
- const char *uri,
- const char *page_label,
- guint timestamp,
- GError **error)
+void
+ev_application_open_uri_at_dest (EvApplication *application,
+ const char *uri,
+ EvLinkDest *dest,
+ guint timestamp)
{
EvWindow *new_window;
- g_return_val_if_fail (uri != NULL, FALSE);
+ g_return_if_fail (uri != NULL);
new_window = ev_application_get_uri_window (application, uri);
if (new_window != NULL) {
@@ -254,8 +252,11 @@ ev_application_open_uri (EvApplication *application,
timestamp);
#else
gtk_window_present (GTK_WINDOW (new_window));
-#endif
- return TRUE;
+#endif
+ if (dest)
+ ev_window_goto_dest (new_window, dest);
+
+ return;
}
new_window = ev_application_get_empty_window (application);
@@ -266,7 +267,7 @@ ev_application_open_uri (EvApplication *application,
/* We need to load uri before showing the window, so
we can restore window size without flickering */
- ev_window_open_uri (new_window, uri);
+ ev_window_open_uri (new_window, uri, dest);
gtk_widget_show (GTK_WIDGET (new_window));
@@ -276,9 +277,22 @@ ev_application_open_uri (EvApplication *application,
#else
gtk_window_present (GTK_WINDOW (new_window));
#endif
+}
+
+gboolean
+ev_application_open_uri (EvApplication *application,
+ const char *uri,
+ const char *page_label,
+ guint timestamp,
+ GError **error)
+{
+ ev_application_open_uri_at_dest (application, uri, NULL, timestamp);
+
+ if (page_label && strcmp (page_label, "") != 0) {
+ EvWindow *window;
- if (page_label != NULL) {
- ev_window_open_page_label (new_window, page_label);
+ window = ev_application_get_uri_window (application, uri);
+ ev_window_open_page_label (window, page_label);
}
return TRUE;
@@ -293,9 +307,7 @@ ev_application_open_uri_list (EvApplication *application,
for (l = uri_list; l != NULL; l = l->next) {
ev_application_open_uri (application, (char *)l->data,
- NULL,
- timestamp,
- NULL);
+ NULL, timestamp, NULL);
}
}
@@ -388,7 +400,7 @@ void ev_application_save_toolbars_model (EvApplication *application)
application->toolbars_file, "1.0");
}
-void ev_application_set_chooser_uri (EvApplication *application, gchar *uri)
+void ev_application_set_chooser_uri (EvApplication *application, const gchar *uri)
{
g_free (application->last_chooser_uri);
application->last_chooser_uri = g_strdup (uri);
diff --git a/shell/ev-application.h b/shell/ev-application.h
index bad967d..2202a9a 100644
--- a/shell/ev-application.h
+++ b/shell/ev-application.h
@@ -39,7 +39,7 @@ typedef struct _EvApplicationPrivate EvApplicationPrivate;
#define EV_TYPE_APPLICATION (ev_application_get_type ())
#define EV_APPLICATION(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_APPLICATION, EvApplication))
-#define EV_APPLICATION_CLASS(klass) (G_TYPE_CHACK_CLASS_CAST((klass), EV_TYPE_APPLICATION, EvApplicationClass))
+#define EV_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_APPLICATION, EvApplicationClass))
#define EV_IS_APPLICATION(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_APPLICATION))
#define EV_IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_APPLICATION))
#define EV_APPLICATION_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_APPLICATION, EvApplicationClass))
@@ -68,13 +68,17 @@ void ev_application_shutdown (EvApplication *application);
gboolean ev_application_open_window (EvApplication *application,
- guint32 timestamp,
+ guint32 timestamp,
GError **error);
gboolean ev_application_open_uri (EvApplication *application,
- const char *uri,
- const char *page_label,
- guint32 timestamp,
+ const char *uri,
+ const char *page_label,
+ guint timestamp,
GError **error);
+void ev_application_open_uri_at_dest (EvApplication *application,
+ const char *uri,
+ EvLinkDest *dest,
+ guint32 timestamp);
void ev_application_open_uri_list (EvApplication *application,
GSList *uri_list,
guint32 timestamp);
@@ -83,9 +87,9 @@ GList *ev_application_get_windows (EvApplication *application);
EggToolbarsModel *ev_application_get_toolbars_model (EvApplication *application);
void ev_application_save_toolbars_model (EvApplication *application);
EggRecentModel *ev_application_get_recent_model (EvApplication *application);
-void ev_application_set_chooser_uri (EvApplication *application,
- gchar *uri);
-const gchar *ev_application_get_chooser_uri (EvApplication *application);
+void ev_application_set_chooser_uri (EvApplication *application,
+ const gchar *uri);
+const gchar *ev_application_get_chooser_uri (EvApplication *application);
G_END_DECLS
diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c
index 7a37b2b..fff0cf2 100644
--- a/shell/ev-jobs.c
+++ b/shell/ev-jobs.c
@@ -272,9 +272,13 @@ ev_job_render_run (EvJobRender *job)
} else {
job->pixbuf = ev_document_render_pixbuf (EV_JOB (job)->document, job->rc);
if (job->include_links)
- job->link_mapping = ev_document_get_links (EV_JOB (job)->document, job->rc->page);
+ job->link_mapping =
+ ev_document_links_get_links (EV_DOCUMENT_LINKS (EV_JOB (job)->document),
+ job->rc->page);
if (job->include_text && EV_IS_SELECTION (EV_JOB (job)->document))
- job->text_mapping = ev_selection_get_selection_map (EV_SELECTION (EV_JOB (job)->document), job->rc);
+ job->text_mapping =
+ ev_selection_get_selection_map (EV_SELECTION (EV_JOB (job)->document),
+ job->rc);
if (job->include_selection && EV_IS_SELECTION (EV_JOB (job)->document)) {
ev_selection_render_selection (EV_SELECTION (EV_JOB (job)->document),
job->rc,
diff --git a/shell/ev-page-action.c b/shell/ev-page-action.c
index fc81cb7..97abd1a 100644
--- a/shell/ev-page-action.c
+++ b/shell/ev-page-action.c
@@ -293,12 +293,25 @@ build_new_tree_cb (GtkTreeModel *model,
{
GtkTreeModel *filter_model = GTK_TREE_MODEL (data);
EvLink *link;
+ EvLinkAction *action;
+ EvLinkActionType type;
gtk_tree_model_get (model, iter,
EV_DOCUMENT_LINKS_COLUMN_LINK, &link,
-1);
- if (link && ev_link_get_page (link) >= 0) {
+ if (!link)
+ return FALSE;
+
+ action = ev_link_get_action (link);
+ if (!action) {
+ g_object_unref (link);
+ return FALSE;
+ }
+
+ type = ev_link_action_get_action_type (action);
+
+ if (type == EV_LINK_ACTION_TYPE_GOTO_DEST) {
GtkTreeIter filter_iter;
gtk_list_store_append (GTK_LIST_STORE (filter_model), &filter_iter);
@@ -307,8 +320,7 @@ build_new_tree_cb (GtkTreeModel *model,
-1);
}
- if (link)
- g_object_unref (link);
+ g_object_unref (link);
return FALSE;
}
@@ -410,7 +422,7 @@ match_completion (GtkEntryCompletion *completion,
gtk_tree_iter_free (iter);
- if (text && key ) {
+ if (text && key) {
gchar *normalized_text;
gchar *normalized_key;
gchar *case_normalized_text;
diff --git a/shell/ev-sidebar-links.c b/shell/ev-sidebar-links.c
index 386cdd5..5a139aa 100644
--- a/shell/ev-sidebar-links.c
+++ b/shell/ev-sidebar-links.c
@@ -262,6 +262,27 @@ 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)
{
@@ -275,27 +296,39 @@ print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar)
if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
EvLink *link;
- int first_page, last_page;
+ int first_page, last_page = -1;
gtk_tree_model_get (model, &iter,
EV_DOCUMENT_LINKS_COLUMN_LINK, &link,
-1);
- first_page = ev_link_get_page (link) + 1;
- if (link)
+ if (!link)
+ return;
+
+ first_page = get_page_from_link (link) + 1;
+ if (first_page == -1) {
g_object_unref (link);
+ return;
+ }
+
+ first_page++;
+ g_object_unref (link);
if (gtk_tree_model_iter_next (model, &iter)) {
gtk_tree_model_get (model, &iter,
EV_DOCUMENT_LINKS_COLUMN_LINK, &link,
-1);
- last_page = ev_link_get_page (link);
- if (link)
- g_object_unref (link);
+ if (link) {
+ last_page = get_page_from_link (link);
+ g_object_unref (link);
+ }
} else {
- last_page = ev_page_cache_get_n_pages (sidebar->priv->page_cache);
+ last_page = ev_page_cache_get_n_pages (sidebar->priv->page_cache);
}
+
+ if (last_page == -1)
+ last_page = ev_page_cache_get_n_pages (sidebar->priv->page_cache);
window = gtk_widget_get_toplevel (GTK_WIDGET (sidebar));
if (EV_IS_WINDOW (window)) {
@@ -442,17 +475,27 @@ links_page_num_func (GtkTreeViewColumn *tree_column,
EvSidebarLinks *sidebar_links)
{
EvLink *link;
+ gint page;
gtk_tree_model_get (tree_model, iter,
EV_DOCUMENT_LINKS_COLUMN_LINK, &link,
-1);
-
- if (link != NULL &&
- ev_link_get_page (link) >= 0) {
+
+ if (!link) {
+ g_object_set (cell,
+ "visible", FALSE,
+ NULL);
+ return;
+ }
+
+ page = get_page_from_link (link);
+
+ if (page >= 0) {
gchar *page_label;
gchar *page_string;
- page_label = ev_page_cache_get_page_label (sidebar_links->priv->page_cache, 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 ("<i>%s</i>", page_label);
g_object_set (cell,
@@ -468,8 +511,7 @@ links_page_num_func (GtkTreeViewColumn *tree_column,
NULL);
}
- if (link)
- g_object_unref (link);
+ g_object_unref (link);
}
/* Public Functions */
@@ -499,18 +541,23 @@ update_page_callback_foreach (GtkTreeModel *model,
if (link) {
int current_page;
+ int dest_page;
+ dest_page = get_page_from_link (link);
+ g_object_unref (link);
+
current_page = ev_page_cache_get_current_page (sidebar_links->priv->page_cache);
- if (ev_link_get_page (link) == current_page) {
+
+ if (dest_page == current_page) {
GtkTreeSelection *selection;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (sidebar_links->priv->tree_view));
+ gtk_tree_view_expand_to_path (GTK_TREE_VIEW (sidebar_links->priv->tree_view),
+ path);
gtk_tree_selection_select_path (selection, path);
- g_object_unref (link);
return TRUE;
}
- g_object_unref (link);
}
return FALSE;
@@ -524,7 +571,7 @@ update_page_callback (EvPageCache *page_cache,
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
-
+
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (sidebar_links->priv->tree_view));
if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
@@ -534,13 +581,15 @@ update_page_callback (EvPageCache *page_cache,
EV_DOCUMENT_LINKS_COLUMN_LINK, &link,
-1);
if (link) {
- gint current_page;
+ gint current_page;
+ gint dest_page;
+
+ dest_page = get_page_from_link (link);
+ g_object_unref (link);
+
current_page = ev_page_cache_get_current_page (sidebar_links->priv->page_cache);
- if (ev_link_get_page (link) == current_page) {
- g_object_unref (link);
+ if (dest_page == current_page)
return;
- }
- g_object_unref (link);
}
}
@@ -555,6 +604,7 @@ update_page_callback (EvPageCache *page_cache,
gtk_tree_model_foreach (model,
update_page_callback_foreach,
sidebar_links);
+
g_signal_handler_unblock (selection, sidebar_links->priv->selection_id);
g_signal_handler_unblock (sidebar_links->priv->tree_view, sidebar_links->priv->row_activated_id);
diff --git a/shell/ev-view.c b/shell/ev-view.c
index 9925d5a..0380e22 100644
--- a/shell/ev-view.c
+++ b/shell/ev-view.c
@@ -33,6 +33,7 @@
#include "ev-view-private.h"
#include "ev-utils.h"
#include "ev-selection.h"
+#include "ev-document-links.h"
#include "ev-document-find.h"
#include "ev-document-misc.h"
#include "ev-debug.h"
@@ -1075,23 +1076,23 @@ ev_view_get_link_at_location (EvView *view,
}
static void
-goto_fitr_link (EvView *view, EvLink *link)
+goto_fitr_dest (EvView *view, EvLinkDest *dest)
{
EvPoint doc_point;
int page;
double zoom;
- zoom = zoom_for_size_best_fit (ev_link_get_right (link) - ev_link_get_left (link),
- ev_link_get_top (link) - ev_link_get_bottom (link),
+ zoom = zoom_for_size_best_fit (ev_link_dest_get_right (dest) - ev_link_dest_get_left (dest),
+ ev_link_dest_get_top (dest) - ev_link_dest_get_bottom (dest),
ev_view_get_width (view),
ev_view_get_height (view), 0, 0);
ev_view_set_sizing_mode (view, EV_SIZING_FREE);
ev_view_set_zoom (view, zoom, FALSE);
- page = ev_link_get_page (link);
- doc_point.x = ev_link_get_left (link);
- doc_point.y = ev_link_get_top (link);
+ page = ev_link_dest_get_page (dest);
+ doc_point.x = ev_link_dest_get_left (dest);
+ doc_point.y = ev_link_dest_get_top (dest);
view->current_page = page;
view->pending_point = doc_point;
@@ -1101,16 +1102,16 @@ goto_fitr_link (EvView *view, EvLink *link)
}
static void
-goto_fitv_link (EvView *view, EvLink *link)
+goto_fitv_dest (EvView *view, EvLinkDest *dest)
{
EvPoint doc_point;
int doc_width, doc_height, page;
double zoom;
- page = ev_link_get_page (link);
+ page = ev_link_dest_get_page (dest);
ev_page_cache_get_size (view->page_cache, page, 0, 1.0, &doc_width, &doc_height);
- doc_point.x = ev_link_get_left (link);
+ doc_point.x = ev_link_dest_get_left (dest);
doc_point.y = 0;
zoom = zoom_for_size_fit_height (doc_width - doc_point.x , doc_height,
@@ -1128,19 +1129,19 @@ goto_fitv_link (EvView *view, EvLink *link)
}
static void
-goto_fith_link (EvView *view, EvLink *link)
+goto_fith_dest (EvView *view, EvLinkDest *dest)
{
EvPoint doc_point;
int doc_width, doc_height, page;
double zoom;
- page = ev_link_get_page (link);
+ page = ev_link_dest_get_page (dest);
ev_page_cache_get_size (view->page_cache, page, 0, 1.0, &doc_width, &doc_height);
doc_point.x = 0;
- doc_point.y = doc_height - ev_link_get_top (link);
+ doc_point.y = doc_height - ev_link_dest_get_top (dest);
- zoom = zoom_for_size_fit_width (doc_width, ev_link_get_top (link),
+ zoom = zoom_for_size_fit_width (doc_width, ev_link_dest_get_top (dest),
ev_view_get_width (view),
ev_view_get_height (view), 0);
@@ -1155,13 +1156,13 @@ goto_fith_link (EvView *view, EvLink *link)
}
static void
-goto_fit_link (EvView *view, EvLink *link)
+goto_fit_dest (EvView *view, EvLinkDest *dest)
{
double zoom;
int doc_width, doc_height;
int page;
- page = ev_link_get_page (link);
+ page = ev_link_dest_get_page (dest);
ev_page_cache_get_size (view->page_cache, page, 0, 1.0, &doc_width, &doc_height);
zoom = zoom_for_size_best_fit (doc_width, doc_height, ev_view_get_width (view),
@@ -1177,14 +1178,14 @@ goto_fit_link (EvView *view, EvLink *link)
}
static void
-goto_xyz_link (EvView *view, EvLink *link)
+goto_xyz_dest (EvView *view, EvLinkDest *dest)
{
EvPoint doc_point;
int height, page;
double zoom;
- zoom = ev_link_get_zoom (link);
- page = ev_link_get_page (link);
+ zoom = ev_link_dest_get_zoom (dest);
+ page = ev_link_dest_get_page (dest);
ev_page_cache_get_size (view->page_cache, page, 0, 1.0, NULL, &height);
if (zoom != 0) {
@@ -1192,8 +1193,8 @@ goto_xyz_link (EvView *view, EvLink *link)
ev_view_set_zoom (view, zoom, FALSE);
}
- doc_point.x = ev_link_get_left (link);
- doc_point.y = height - ev_link_get_top (link);
+ doc_point.x = ev_link_dest_get_left (dest);
+ doc_point.y = height - ev_link_dest_get_top (dest);
view->current_page = page;
view->pending_point = doc_point;
@@ -1202,70 +1203,176 @@ goto_xyz_link (EvView *view, EvLink *link)
gtk_widget_queue_resize (GTK_WIDGET (view));
}
-void
-ev_view_goto_link (EvView *view, EvLink *link)
+static void
+goto_dest (EvView *view, EvLinkDest *dest)
{
- EvLinkType type;
- int page;
+ EvLinkDestType type;
+ int page, n_pages;
- type = ev_link_get_link_type (link);
+ page = ev_link_dest_get_page (dest);
+ n_pages = ev_page_cache_get_n_pages (view->page_cache);
+
+ if (page < 0 || page >= n_pages)
+ return;
+
+ type = ev_link_dest_get_dest_type (dest);
switch (type) {
- case EV_LINK_TYPE_TITLE:
- break;
- case EV_LINK_TYPE_PAGE:
- page = ev_link_get_page (link);
+ case EV_LINK_DEST_TYPE_PAGE:
ev_page_cache_set_current_page (view->page_cache, page);
break;
- case EV_LINK_TYPE_PAGE_FIT:
- goto_fit_link (view, link);
+ case EV_LINK_DEST_TYPE_FIT:
+ goto_fit_dest (view, dest);
break;
- case EV_LINK_TYPE_PAGE_FITH:
- goto_fith_link (view, link);
+ case EV_LINK_DEST_TYPE_FITH:
+ goto_fith_dest (view, dest);
break;
- case EV_LINK_TYPE_PAGE_FITV:
- goto_fitv_link (view, link);
+ case EV_LINK_DEST_TYPE_FITV:
+ goto_fitv_dest (view, dest);
break;
- case EV_LINK_TYPE_PAGE_FITR:
- goto_fitr_link (view, link);
+ case EV_LINK_DEST_TYPE_FITR:
+ goto_fitr_dest (view, dest);
break;
- case EV_LINK_TYPE_PAGE_XYZ:
- goto_xyz_link (view, link);
+ case EV_LINK_DEST_TYPE_XYZ:
+ goto_xyz_dest (view, dest);
break;
- case EV_LINK_TYPE_EXTERNAL_URI:
- case EV_LINK_TYPE_LAUNCH:
- g_signal_emit (view, signals[SIGNAL_EXTERNAL_LINK], 0, link);
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+void
+ev_view_goto_dest (EvView *view, EvLinkDest *dest)
+{
+ EvLinkDestType type;
+
+ type = ev_link_dest_get_dest_type (dest);
+
+ if (type == EV_LINK_DEST_TYPE_NAMED) {
+ EvLinkDest *dest2;
+ const gchar *named_dest;
+
+ named_dest = ev_link_dest_get_named_dest (dest);
+ dest2 = ev_document_links_find_link_dest (EV_DOCUMENT_LINKS (view->document),
+ named_dest);
+ if (dest2) {
+ goto_dest (view, dest2);
+ g_object_unref (dest2);
+ }
+
+ return;
+ }
+
+ goto_dest (view, dest);
+}
+
+void
+ev_view_handle_link (EvView *view, EvLink *link)
+{
+ EvLinkAction *action = NULL;
+ EvLinkActionType type;
+
+ action = ev_link_get_action (link);
+ if (!action)
+ return;
+
+ type = ev_link_action_get_action_type (action);
+
+ switch (type) {
+ case EV_LINK_ACTION_TYPE_GOTO_DEST: {
+ EvLinkDest *dest;
+
+ dest = ev_link_action_get_dest (action);
+ ev_view_goto_dest (view, dest);
+ }
+ break;
+ case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
+ case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
+ case EV_LINK_ACTION_TYPE_LAUNCH:
+ g_signal_emit (view, signals[SIGNAL_EXTERNAL_LINK], 0, action);
break;
}
}
+static gchar *
+page_label_from_dest (EvView *view, EvLinkDest *dest)
+{
+ EvLinkDestType type;
+ gchar *msg = NULL;
+
+ type = ev_link_dest_get_dest_type (dest);
+
+ switch (type) {
+ case EV_LINK_DEST_TYPE_NAMED: {
+ EvLinkDest *dest2;
+ const gchar *named_dest;
+
+ named_dest = ev_link_dest_get_named_dest (dest);
+ dest2 = ev_document_links_find_link_dest (EV_DOCUMENT_LINKS (view->document),
+ named_dest);
+ if (dest2) {
+ msg = ev_page_cache_get_page_label (view->page_cache,
+ ev_link_dest_get_page (dest2));
+ g_object_unref (dest2);
+ }
+ }
+
+ break;
+ default:
+ msg = ev_page_cache_get_page_label (view->page_cache,
+ ev_link_dest_get_page (dest));
+ }
+
+ return msg;
+}
+
static char *
tip_from_link (EvView *view, EvLink *link)
{
- EvLinkType type;
+ EvLinkAction *action;
+ EvLinkActionType type;
char *msg = NULL;
char *page_label;
+ const char *title;
- type = ev_link_get_link_type (link);
+ action = ev_link_get_action (link);
+ title = ev_link_get_title (link);
+
+ if (!action)
+ return title ? g_strdup (title) : NULL;
+
+ type = ev_link_action_get_action_type (action);
switch (type) {
- case EV_LINK_TYPE_TITLE:
- if (ev_link_get_title (link))
- msg = g_strdup (ev_link_get_title (link));
- break;
- case EV_LINK_TYPE_PAGE:
- case EV_LINK_TYPE_PAGE_XYZ:
- page_label = ev_page_cache_get_page_label (view->page_cache, ev_link_get_page (link));
+ case EV_LINK_ACTION_TYPE_GOTO_DEST:
+ page_label = page_label_from_dest (view,
+ ev_link_action_get_dest (action));
msg = g_strdup_printf (_("Go to page %s"), page_label);
g_free (page_label);
break;
- case EV_LINK_TYPE_EXTERNAL_URI:
- msg = g_strdup (ev_link_get_uri (link));
+ case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
+ if (title) {
+ msg = g_strdup_printf (_("Go to %s on file %s"), title,
+ ev_link_action_get_filename (action));
+ } else {
+ msg = g_strdup_printf (_("Go to file %s"),
+ ev_link_action_get_filename (action));
+ }
+
break;
- default:
+ case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
+ msg = g_strdup (ev_link_action_get_uri (action));
+ break;
+ case EV_LINK_ACTION_TYPE_LAUNCH:
+ msg = g_strdup_printf (_("Launch %s"),
+ ev_link_action_get_filename (action));
+ break;
+ default:
+ if (title)
+ msg = g_strdup (title);
break;
}
-
+
return msg;
}
@@ -1570,14 +1677,14 @@ ev_view_scroll_event (GtkWidget *widget, GdkEventScroll *event)
if (state == 0 && view->presentation) {
switch (event->direction) {
- case GDK_SCROLL_DOWN:
- case GDK_SCROLL_RIGHT:
- ev_view_next_page (view);
- break;
- case GDK_SCROLL_UP:
- case GDK_SCROLL_LEFT:
- ev_view_previous_page (view);
- break;
+ case GDK_SCROLL_DOWN:
+ case GDK_SCROLL_RIGHT:
+ ev_view_next_page (view);
+ break;
+ case GDK_SCROLL_UP:
+ case GDK_SCROLL_LEFT:
+ ev_view_previous_page (view);
+ break;
}
return TRUE;
@@ -1926,15 +2033,15 @@ ev_view_button_release_event (GtkWidget *widget,
view->selection_info.in_drag = FALSE;
} else if (link) {
- ev_view_goto_link (view, link);
+ ev_view_handle_link (view, link);
} else if (view->presentation) {
switch (event->button) {
- case 1:
- ev_view_next_page (view);
- return TRUE;
- case 3:
- ev_view_previous_page (view);
- return TRUE;
+ case 1:
+ ev_view_next_page (view);
+ return TRUE;
+ case 3:
+ ev_view_previous_page (view);
+ return TRUE;
}
}
@@ -2293,31 +2400,30 @@ ev_view_set_property (GObject *object,
{
EvView *view = EV_VIEW (object);
- switch (prop_id)
- {
- case PROP_CONTINUOUS:
- ev_view_set_continuous (view, g_value_get_boolean (value));
- break;
- case PROP_DUAL_PAGE:
- ev_view_set_dual_page (view, g_value_get_boolean (value));
- break;
- case PROP_FULLSCREEN:
- ev_view_set_fullscreen (view, g_value_get_boolean (value));
- break;
- case PROP_PRESENTATION:
- ev_view_set_presentation (view, g_value_get_boolean (value));
- break;
- case PROP_SIZING_MODE:
- ev_view_set_sizing_mode (view, g_value_get_enum (value));
- break;
- case PROP_ZOOM:
- ev_view_set_zoom (view, g_value_get_double (value), FALSE);
- break;
- case PROP_ROTATION:
- ev_view_set_rotation (view, g_value_get_int (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ switch (prop_id) {
+ case PROP_CONTINUOUS:
+ ev_view_set_continuous (view, g_value_get_boolean (value));
+ break;
+ case PROP_DUAL_PAGE:
+ ev_view_set_dual_page (view, g_value_get_boolean (value));
+ break;
+ case PROP_FULLSCREEN:
+ ev_view_set_fullscreen (view, g_value_get_boolean (value));
+ break;
+ case PROP_PRESENTATION:
+ ev_view_set_presentation (view, g_value_get_boolean (value));
+ break;
+ case PROP_SIZING_MODE:
+ ev_view_set_sizing_mode (view, g_value_get_enum (value));
+ break;
+ case PROP_ZOOM:
+ ev_view_set_zoom (view, g_value_get_double (value), FALSE);
+ break;
+ case PROP_ROTATION:
+ ev_view_set_rotation (view, g_value_get_int (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
@@ -2360,41 +2466,40 @@ ev_view_get_property (GObject *object,
{
EvView *view = EV_VIEW (object);
- switch (prop_id)
- {
- case PROP_STATUS:
- g_value_set_string (value, view->status);
- break;
- case PROP_FIND_STATUS:
- g_value_set_string (value, view->status);
- break;
- case PROP_CONTINUOUS:
- g_value_set_boolean (value, view->continuous);
- break;
- case PROP_DUAL_PAGE:
- g_value_set_boolean (value, view->dual_page);
- break;
- case PROP_FULLSCREEN:
- g_value_set_boolean (value, view->fullscreen);
- break;
- case PROP_PRESENTATION:
- g_value_set_boolean (value, view->presentation);
- break;
- case PROP_SIZING_MODE:
- g_value_set_enum (value, view->sizing_mode);
- break;
- case PROP_ZOOM:
- g_value_set_double (value, view->scale);
- break;
- case PROP_ROTATION:
- g_value_set_int (value, view->rotation);
- break;
- case PROP_HAS_SELECTION:
- g_value_set_boolean (value,
- view->selection_info.selections != NULL);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ switch (prop_id) {
+ case PROP_STATUS:
+ g_value_set_string (value, view->status);
+ break;
+ case PROP_FIND_STATUS:
+ g_value_set_string (value, view->status);
+ break;
+ case PROP_CONTINUOUS:
+ g_value_set_boolean (value, view->continuous);
+ break;
+ case PROP_DUAL_PAGE:
+ g_value_set_boolean (value, view->dual_page);
+ break;
+ case PROP_FULLSCREEN:
+ g_value_set_boolean (value, view->fullscreen);
+ break;
+ case PROP_PRESENTATION:
+ g_value_set_boolean (value, view->presentation);
+ break;
+ case PROP_SIZING_MODE:
+ g_value_set_enum (value, view->sizing_mode);
+ break;
+ case PROP_ZOOM:
+ g_value_set_double (value, view->scale);
+ break;
+ case PROP_ROTATION:
+ g_value_set_int (value, view->rotation);
+ break;
+ case PROP_HAS_SELECTION:
+ g_value_set_boolean (value,
+ view->selection_info.selections != NULL);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
diff --git a/shell/ev-view.h b/shell/ev-view.h
index 3ad4016..e6dd395 100644
--- a/shell/ev-view.h
+++ b/shell/ev-view.h
@@ -137,8 +137,10 @@ void ev_view_show_cursor (EvView *view);
void ev_view_scroll (EvView *view,
EvScrollType scroll,
gboolean horizontal);
-void ev_view_goto_link (EvView *view,
+void ev_view_handle_link (EvView *view,
EvLink *link);
+void ev_view_goto_dest (EvView *view,
+ EvLinkDest *dest);
gboolean ev_view_next_page (EvView *view);
gboolean ev_view_previous_page (EvView *view);
diff --git a/shell/ev-window.c b/shell/ev-window.c
index 6ca0de6..2fad47b 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -140,6 +140,7 @@ struct _EvWindowPrivate {
/* Document */
char *uri;
char *local_uri;
+ EvLinkDest *dest;
EvDocument *document;
EvDocument *password_document;
@@ -470,18 +471,17 @@ update_sizing_buttons (EvWindow *window)
NULL);
switch (sizing_mode) {
- case EV_SIZING_BEST_FIT:
- best_fit = TRUE;
- page_width = FALSE;
- break;
- case EV_SIZING_FIT_WIDTH:
- best_fit = FALSE;
- page_width = TRUE;
- break;
-
- default:
- best_fit = page_width = FALSE;
- break;
+ case EV_SIZING_BEST_FIT:
+ best_fit = TRUE;
+ page_width = FALSE;
+ break;
+ case EV_SIZING_FIT_WIDTH:
+ best_fit = FALSE;
+ page_width = TRUE;
+ break;
+ default:
+ best_fit = page_width = FALSE;
+ break;
}
action = gtk_action_group_get_action (action_group, "ViewBestFit");
@@ -749,17 +749,17 @@ setup_view_from_metadata (EvWindow *window)
if (ev_metadata_manager_get (uri, "rotation", &rotation, TRUE)) {
if (g_value_get_int (&rotation)) {
switch (g_value_get_int (&rotation)) {
- case 90:
- ev_view_set_rotation (view, 90);
- break;
- case 180:
- ev_view_set_rotation (view, 180);
- break;
- case 270:
- ev_view_set_rotation (view, 270);
- break;
- default:
- break;
+ case 90:
+ ev_view_set_rotation (view, 90);
+ break;
+ case 180:
+ ev_view_set_rotation (view, 180);
+ break;
+ case 270:
+ ev_view_set_rotation (view, 270);
+ break;
+ default:
+ break;
}
}
}
@@ -955,6 +955,9 @@ ev_window_xfer_job_cb (EvJobXfer *job,
ev_window_setup_document (ev_window);
ev_window_add_recent (ev_window, ev_window->priv->uri);
ev_window_clear_xfer_job (ev_window);
+
+ if (ev_window->priv->dest)
+ ev_window_goto_dest (ev_window, ev_window->priv->dest);
return;
}
@@ -1016,10 +1019,14 @@ ev_window_close_dialogs (EvWindow *ev_window)
}
void
-ev_window_open_uri (EvWindow *ev_window, const char *uri)
+ev_window_open_uri (EvWindow *ev_window, const char *uri, EvLinkDest *dest)
{
g_free (ev_window->priv->uri);
ev_window->priv->uri = NULL;
+
+ if (ev_window->priv->dest)
+ g_object_unref (ev_window->priv->dest);
+ ev_window->priv->dest = dest ? g_object_ref (dest) : NULL;
ev_window_close_dialogs (ev_window);
ev_window_clear_xfer_job (ev_window);
@@ -1034,6 +1041,12 @@ ev_window_open_uri (EvWindow *ev_window, const char *uri)
ev_job_queue_add_job (ev_window->priv->xfer_job, EV_JOB_PRIORITY_HIGH);
}
+void
+ev_window_goto_dest (EvWindow *ev_window, EvLinkDest *dest)
+{
+ ev_view_goto_dest (EV_VIEW (ev_window->priv->view), dest);
+}
+
static void
file_open_dialog_response_cb (GtkWidget *chooser,
gint response_id,
@@ -1931,14 +1944,14 @@ ev_window_set_page_mode (EvWindow *window,
window->priv->page_mode = page_mode;
switch (page_mode) {
- case PAGE_MODE_DOCUMENT:
- child = window->priv->view;
- break;
- case PAGE_MODE_PASSWORD:
- child = window->priv->password_view;
- break;
- default:
- g_assert_not_reached ();
+ case PAGE_MODE_DOCUMENT:
+ child = window->priv->view;
+ break;
+ case PAGE_MODE_PASSWORD:
+ child = window->priv->password_view;
+ break;
+ default:
+ g_assert_not_reached ();
}
real_child = gtk_bin_get_child (GTK_BIN (window->priv->scrolled_window));
@@ -2101,7 +2114,7 @@ ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window)
page = ev_page_cache_get_current_page (ev_window->priv->page_cache);
uri = g_strdup (ev_window->priv->uri);
- ev_window_open_uri (ev_window, uri);
+ ev_window_open_uri (ev_window, uri, NULL);
/* In case the number of pages in the document has changed. */
page = CLAMP (page, 0, ev_page_cache_get_n_pages (ev_window->priv->page_cache) - 1);
@@ -2225,30 +2238,30 @@ ev_window_sizing_mode_changed_cb (EvView *view, GParamSpec *pspec,
update_view_size (NULL, ev_window);
switch (sizing_mode) {
- case EV_SIZING_BEST_FIT:
- g_object_set (G_OBJECT (scrolled_window),
- "hscrollbar-policy", GTK_POLICY_NEVER,
- "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
- NULL);
- g_signal_connect (ev_window->priv->view, "zoom_invalid",
- G_CALLBACK (update_view_size),
- ev_window);
- break;
- case EV_SIZING_FIT_WIDTH:
- g_object_set (G_OBJECT (scrolled_window),
- "hscrollbar-policy", GTK_POLICY_NEVER,
- "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
- NULL);
- g_signal_connect (ev_window->priv->view, "zoom_invalid",
- G_CALLBACK (update_view_size),
- ev_window);
- break;
- case EV_SIZING_FREE:
- g_object_set (G_OBJECT (scrolled_window),
- "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
- "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
- NULL);
- break;
+ case EV_SIZING_BEST_FIT:
+ g_object_set (G_OBJECT (scrolled_window),
+ "hscrollbar-policy", GTK_POLICY_NEVER,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ NULL);
+ g_signal_connect (ev_window->priv->view, "zoom_invalid",
+ G_CALLBACK (update_view_size),
+ ev_window);
+ break;
+ case EV_SIZING_FIT_WIDTH:
+ g_object_set (G_OBJECT (scrolled_window),
+ "hscrollbar-policy", GTK_POLICY_NEVER,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ NULL);
+ g_signal_connect (ev_window->priv->view, "zoom_invalid",
+ G_CALLBACK (update_view_size),
+ ev_window);
+ break;
+ case EV_SIZING_FREE:
+ g_object_set (G_OBJECT (scrolled_window),
+ "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ NULL);
+ break;
}
update_sizing_buttons (ev_window);
@@ -2507,9 +2520,9 @@ ev_window_attachment_bar_toggled_cb (EvAttachmentBar *ev_attachbar,
}
static gboolean
-view_menu_popup_cb (EvView *view,
- EvLink *link,
- EvWindow *ev_window)
+view_menu_popup_cb (EvView *view,
+ EvLink *link,
+ EvWindow *ev_window)
{
GtkWidget *popup;
gboolean show_external = FALSE;
@@ -2521,6 +2534,7 @@ view_menu_popup_cb (EvView *view,
if (ev_window->priv->link)
g_object_unref (ev_window->priv->link);
+
if (link)
ev_window->priv->link = g_object_ref (link);
else
@@ -2528,23 +2542,26 @@ view_menu_popup_cb (EvView *view,
popup = ev_window->priv->view_popup;
- if (ev_window->priv->link)
- switch (ev_link_get_link_type (ev_window->priv->link)) {
- case EV_LINK_TYPE_PAGE:
- case EV_LINK_TYPE_PAGE_FIT:
- case EV_LINK_TYPE_PAGE_FITH:
- case EV_LINK_TYPE_PAGE_FITV:
- case EV_LINK_TYPE_PAGE_FITR:
- case EV_LINK_TYPE_PAGE_XYZ:
+ if (ev_window->priv->link) {
+ EvLinkAction *ev_action;
+
+ ev_action = ev_link_get_action (link);
+ if (!ev_action)
+ return FALSE;
+
+ switch (ev_link_action_get_action_type (ev_action)) {
+ case EV_LINK_ACTION_TYPE_GOTO_DEST:
+ case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
show_internal = TRUE;
break;
- case EV_LINK_TYPE_EXTERNAL_URI:
- case EV_LINK_TYPE_LAUNCH:
+ case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
+ case EV_LINK_ACTION_TYPE_LAUNCH:
show_external = TRUE;
break;
- default:
+ default:
break;
}
+ }
action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
"OpenLink");
@@ -2561,7 +2578,7 @@ view_menu_popup_cb (EvView *view,
gtk_menu_popup (GTK_MENU (popup), NULL, NULL,
NULL, NULL,
3, gtk_get_current_event_time ());
- return FALSE;
+ return TRUE;
}
static gboolean
@@ -2804,6 +2821,11 @@ ev_window_dispose (GObject *object)
priv->uri = NULL;
}
+ if (priv->dest) {
+ g_object_unref (priv->dest);
+ priv->dest = NULL;
+ }
+
if (priv->fullscreen_timeout_id) {
g_source_remove (priv->fullscreen_timeout_id);
priv->fullscreen_timeout_id = 0;
@@ -3031,9 +3053,7 @@ drag_data_received_cb (GtkWidget *widget, GdkDragContext *context,
static void
activate_link_cb (EvPageAction *page_action, EvLink *link, EvWindow *window)
{
- g_return_if_fail (EV_IS_WINDOW (window));
-
- ev_view_goto_link (EV_VIEW (window->priv->view), link);
+ ev_view_handle_link (EV_VIEW (window->priv->view), link);
gtk_widget_grab_focus (window->priv->view);
}
@@ -3230,13 +3250,13 @@ window_configure_event_cb (EvWindow *window, GdkEventConfigure *event, gpointer
static void
sidebar_links_link_activated_cb (EvSidebarLinks *sidebar_links, EvLink *link, EvWindow *window)
{
- ev_view_goto_link (EV_VIEW (window->priv->view), link);
+ ev_view_handle_link (EV_VIEW (window->priv->view), link);
}
static void
-launch_link (EvWindow *window, EvLink *link)
+launch_action (EvWindow *window, EvLinkAction *action)
{
- const char *filename = ev_link_get_filename (link);
+ const char *filename = ev_link_action_get_filename (action);
char *uri = NULL;
if (filename && g_path_is_absolute (filename)) {
@@ -3268,12 +3288,12 @@ launch_link (EvWindow *window, EvLink *link)
}
static void
-launch_external_uri (EvWindow *window, EvLink *link)
+launch_external_uri (EvWindow *window, EvLinkAction *action)
{
const char *uri;
char *escaped;
- uri = ev_link_get_uri (link);
+ uri = ev_link_action_get_uri (action);
escaped = gnome_vfs_escape_host_and_path_string (uri);
gnome_vfs_url_show (escaped);
@@ -3281,33 +3301,60 @@ launch_external_uri (EvWindow *window, EvLink *link)
}
static void
-view_external_link_cb (EvView *view, EvLink *link, EvWindow *window)
+open_remote_link (EvWindow *window, EvLinkAction *action)
+{
+ gchar *uri;
+ gchar *dir;
+
+ dir = g_path_get_dirname (window->priv->uri);
+
+ uri = g_build_filename (dir, ev_link_action_get_filename (action),
+ NULL);
+ g_free (dir);
+
+ ev_application_open_uri_at_dest (EV_APP, uri,
+ ev_link_action_get_dest (action),
+ GDK_CURRENT_TIME);
+
+ g_free (uri);
+}
+
+static void
+view_external_link_cb (EvView *view, EvLinkAction *action, EvWindow *window)
{
- switch (ev_link_get_link_type (link)) {
- case EV_LINK_TYPE_EXTERNAL_URI:
- launch_external_uri (window, link);
- break;
- case EV_LINK_TYPE_LAUNCH:
- launch_link (window, link);
- break;
- default:
- g_assert_not_reached ();
+ switch (ev_link_action_get_action_type (action)) {
+ case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
+ launch_external_uri (window, action);
+ break;
+ case EV_LINK_ACTION_TYPE_LAUNCH:
+ launch_action (window, action);
+ break;
+ case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
+ open_remote_link (window, action);
+ break;
+ default:
+ g_assert_not_reached ();
}
}
static void
ev_view_popup_cmd_open_link (GtkAction *action, EvWindow *window)
{
- ev_view_goto_link (EV_VIEW (window->priv->view), window->priv->link);
+ ev_view_handle_link (EV_VIEW (window->priv->view), window->priv->link);
}
static void
ev_view_popup_cmd_copy_link_address (GtkAction *action, EvWindow *window)
{
GtkClipboard *clipboard;
+ EvLinkAction *ev_action;
const gchar *uri;
- uri = ev_link_get_uri (window->priv->link);
+ ev_action = ev_link_get_action (window->priv->link);
+ if (!ev_action)
+ return;
+
+ uri = ev_link_action_get_uri (ev_action);
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window),
GDK_SELECTION_CLIPBOARD);
@@ -3443,6 +3490,8 @@ ev_window_init (EvWindow *ev_window)
ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window);
+ ev_window->priv->dest = NULL;
+
ev_window->priv->page_mode = PAGE_MODE_DOCUMENT;
ev_window->priv->title = ev_window_title_new (ev_window);
diff --git a/shell/ev-window.h b/shell/ev-window.h
index fb6234d..2551073 100644
--- a/shell/ev-window.h
+++ b/shell/ev-window.h
@@ -55,7 +55,10 @@ GType ev_window_get_type (void);
GtkWidget *ev_window_new (void);
const char *ev_window_get_uri (EvWindow *ev_window);
void ev_window_open_uri (EvWindow *ev_window,
- const char *uri);
+ const char *uri,
+ EvLinkDest *dest);
+void ev_window_goto_dest (EvWindow *ev_window,
+ EvLinkDest *dest);
void ev_window_open_page_label (EvWindow *ev_window,
const char *label);
gboolean ev_window_is_empty (const EvWindow *ev_window);
diff --git a/shell/main.c b/shell/main.c
index b874b28..3a38986 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -188,7 +188,7 @@ load_files_remote (const char **files)
char *uri;
uri = gnome_vfs_make_uri_from_shell_arg (files[i]);
- page_label = ev_page_label ? ev_page_label : "";
+ page_label = ev_page_label ? ev_page_label : "";
#if DBUS_VERSION <= 33
call = dbus_g_proxy_begin_call (remote_object, "OpenURI",
DBUS_TYPE_STRING, &uri,