]> www.fi.muni.cz Git - evince.git/commitdiff
Rework links system, it adds support for remote links now and it makes
authorCarlos Garcia Campos <carlosgc@gnome.org>
Tue, 2 May 2006 19:02:46 +0000 (19:02 +0000)
committerCarlos Garcia Campos <carlosgc@src.gnome.org>
Tue, 2 May 2006 19:02:46 +0000 (19:02 +0000)
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

23 files changed:
ChangeLog
backend/Makefile.am
backend/ev-document-links.c
backend/ev-document-links.h
backend/ev-document.c
backend/ev-document.h
backend/ev-link-action.c [new file with mode: 0644]
backend/ev-link-action.h [new file with mode: 0644]
backend/ev-link-dest.c [new file with mode: 0644]
backend/ev-link-dest.h [new file with mode: 0644]
backend/ev-link.c
backend/ev-link.h
pdf/ev-poppler.cc
shell/ev-application.c
shell/ev-application.h
shell/ev-jobs.c
shell/ev-page-action.c
shell/ev-sidebar-links.c
shell/ev-view.c
shell/ev-view.h
shell/ev-window.c
shell/ev-window.h
shell/main.c

index a9e9791363948bf9b6233253ad460ea6ff191503..b583775a9654ce31240963c1eee0ba0e71a94eba 100644 (file)
--- 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:
index c2adf470fbd58ea570b65356c05e2d52f6c4aea6..db21e4c5c60f7db7f7a2f3a778730787d1f7c365 100644 (file)
@@ -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                   \
index 7ab3468f3ad5334afa3053a79666a106353fcf24..daec3eaa528303eca396fcf826d1ef44b6adc689 100644 (file)
@@ -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;
+}
index 1f9459647f3f92ff8fc3fdad57d00701fba2f07b..8e8f20a7dca9ca6ce5424143643362cb69d7e0fa 100644 (file)
@@ -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
index 10f1d00e2800b64596e13121b15f1f286491a5fe..8598c117703785e78ee08789eef080b4f1538fb5 100644 (file)
@@ -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)
 {
index ce7714c549495e6a43ff81ba78306fcb0d2f89e8..0da5fc7365616052a710c9802dd3f01fbd55d79a 100644 (file)
@@ -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 (file)
index 0000000..23f4194
--- /dev/null
@@ -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 (file)
index 0000000..6ca8d57
--- /dev/null
@@ -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 (file)
index 0000000..2fd2f4d
--- /dev/null
@@ -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 (file)
index 0000000..40a8a9b
--- /dev/null
@@ -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 */
index a325c3525788badbe1921341668a8996e2921f89..8561914b69935e5af88933eb31368f11c130ecb7 100644 (file)
  * 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,
index 6ab2811be1621ceb16d8e0ec58eb7f29574042b1..b7304debfe1e9d8435f8dab7fb6fcf905ab3d5cb 100644 (file)
@@ -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
 {
index a4be75ee9b7eb6323039b9e64fbe5fdec46e6c9f..efdd15f28aef4cb6762f429bfb2bd20b312304fc 100644 (file)
@@ -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 *
index 8721a0cd879a11cfa6917dabfa1a4012ca9d74e9..de5e3a0c813820f21753fa39136d4d84dc9aca93 100644 (file)
@@ -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);
index bad967dae86f18423d54265a5ff391f033586082..2202a9a32fef8bddc8255a1a1557aa8822231ca3 100644 (file)
@@ -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
 
index 7a37b2b9f6ff3faadc45e9a5ff0cff2f61c83395..fff0cf27b680d681fecd423a9acd8248ffe23a4e 100644 (file)
@@ -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,
index fc81cb709932f516a2f4d0fd82a4f2559da18653..97abd1a7870a6dfdfc4a39074a11e4d4bb53f2d8 100644 (file)
@@ -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;
index 386cdd5f141798941f1bb40b9e42154455d746ef..5a139aac6bb5d6867fe37f35a15c37a504c4a22f 100644 (file)
@@ -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);
index 9925d5abc072fb1dbc12bddb41c83c4f717d48ce..0380e226f4aab36719cfc1d41730fd5bec2f6ef6 100644 (file)
@@ -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);
        }
 }
 
index 3ad401669cbe5411f6098b352925de13fa82a1c7..e6dd3958486fcd410c38111a0813d9f66278d52f 100644 (file)
@@ -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);
 
index 6ca0de647735b131757a4e53428c0b29a2d7cc28..2fad47bfadc6ce092611f377ba5d7789924ece91 100644 (file)
@@ -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);
 
index fb6234de17bae4d0a7263f0d243e4d50739f3b77..2551073e33490b9bf66cbb7e04e2b655e8350f54 100644 (file)
@@ -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);
index b874b28bb3856abb02a49b862a067deb966e2681..3a38986bb813625dd515df683ffedabb6d4dbb9c 100644 (file)
@@ -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,