]> www.fi.muni.cz Git - evince.git/commitdiff
Implement launch links. Delegate external link opening to the window.
authorMarco Pesenti Gritti <mpg@redhat.com>
Mon, 26 Sep 2005 10:28:48 +0000 (10:28 +0000)
committerMarco Pesenti Gritti <marco@src.gnome.org>
Mon, 26 Sep 2005 10:28:48 +0000 (10:28 +0000)
2005-09-26  Marco Pesenti Gritti  <mpg@redhat.com>

        * backend/ev-link.c: (ev_link_type_get_type),
        (ev_link_get_filename), (ev_link_get_params),
        (ev_link_get_property), (ev_link_set_property),
        (ev_window_dispose), (ev_link_class_init), (ev_link_new_launch):
        * backend/ev-link.h:
        * pdf/ev-poppler.cc:
        * shell/ev-view.c: (ev_view_goto_link), (ev_view_class_init):
        * shell/ev-window.c: (launch_link), (view_external_link_cb),
        (ev_window_init):

        Implement launch links. Delegate external link opening to
        the window.

ChangeLog
backend/ev-link.c
backend/ev-link.h
pdf/ev-poppler.cc
shell/ev-view.c
shell/ev-window.c

index 71e8678c473f66c2d088e23cc8e7652d9004a336..c5faf62283175abaef15a73d5667caf6f2d68366 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2005-09-26  Marco Pesenti Gritti  <mpg@redhat.com>
+
+       * backend/ev-link.c: (ev_link_type_get_type),
+       (ev_link_get_filename), (ev_link_get_params),
+       (ev_link_get_property), (ev_link_set_property),
+       (ev_window_dispose), (ev_link_class_init), (ev_link_new_launch):
+       * backend/ev-link.h:
+       * pdf/ev-poppler.cc:
+       * shell/ev-view.c: (ev_view_goto_link), (ev_view_class_init):
+       * shell/ev-window.c: (launch_link), (view_external_link_cb),
+       (ev_window_init):
+
+       Implement launch links. Delegate external link opening to
+       the window.
+
 2005-09-24  Marco Pesenti Gritti  <mpg@redhat.com>
 
        * backend/ev-link.c: (ev_link_type_get_type), (ev_link_get_bottom),
index 57af5fa26151bb2049c9e247ef0e6b4ca02fc81e..b8721d9b5841c349a7d7cf56d234e2d5dae4de85 100644 (file)
@@ -34,7 +34,9 @@ enum {
        PROP_TOP,
        PROP_BOTTOM,
        PROP_RIGHT,
-       PROP_ZOOM
+       PROP_ZOOM,
+       PROP_FILENAME,
+       PROP_PARAMS
 };
 
 
@@ -50,6 +52,8 @@ struct _EvLinkClass {
 struct _EvLinkPrivate {
        char *title;
        char *uri;
+       char *filename;
+       char *params;
        EvLinkType type;
        int page;
        double top;
@@ -79,6 +83,7 @@ ev_link_type_get_type (void)
                        { 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 }
                 };
 
@@ -152,6 +157,22 @@ ev_link_get_right (EvLink *self)
        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)
 {
@@ -196,6 +217,10 @@ ev_link_get_property (GObject *object, guint prop_id, GValue *value,
        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,
@@ -238,6 +263,14 @@ ev_link_set_property (GObject *object, guint prop_id, const GValue *value,
        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,
@@ -266,6 +299,16 @@ ev_window_dispose (GObject *object)
                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_parent_class)->dispose (object);
 }
 
@@ -305,6 +348,22 @@ ev_link_class_init (EvLinkClass *ev_window_class)
                                                              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",
@@ -479,7 +538,18 @@ ev_link_new_external (const char *title, const char *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,
+                                     NULL));
+}
 
 static void
 ev_link_mapping_free_foreach (EvLinkMapping *mapping)
index c014c0102ca0fa86b417085e872b7e4904f53207..6ab2811be1621ceb16d8e0ec58eb7f29574042b1 100644 (file)
@@ -49,6 +49,7 @@ typedef enum
        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;
@@ -80,6 +81,9 @@ 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);
@@ -90,6 +94,8 @@ 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);
 
 /* Link Mapping stuff */
 
index 30b5a72e0964c6adacad8fd7532d7777174a0b79..c8405d3396463993a1e889f6d2ce28e646cd9b80 100644 (file)
@@ -784,7 +784,8 @@ ev_link_from_action (PopplerAction *action)
                unimplemented_action = "POPPLER_ACTION_GOTO_REMOTE";
                break;
        case POPPLER_ACTION_LAUNCH:
-               unimplemented_action = "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);
index c5cc5038a7e1018e2126536241960ebfa21a0cf7..15bd41244edcf10215eae5d720374955b0372632 100644 (file)
@@ -60,6 +60,7 @@ enum {
 enum {
        SIGNAL_BINDING_ACTIVATED,
        SIGNAL_ZOOM_INVALID,
+       SIGNAL_EXTERNAL_LINK,
        N_SIGNALS,
 };
 
@@ -188,6 +189,8 @@ struct _EvViewClass {
                                           GtkScrollType   scroll,
                                           gboolean        horizontal);
        void    (*zoom_invalid)           (EvView         *view);
+       void    (*external_link)          (EvView         *view,
+                                          EvLink         *link);
 };
 
 /*** Scrolling ***/
@@ -1234,7 +1237,6 @@ void
 ev_view_goto_link (EvView *view, EvLink *link)
 {
        EvLinkType type;
-       const char *uri;
        int page;
 
        type = ev_link_get_link_type (link);
@@ -1262,8 +1264,8 @@ ev_view_goto_link (EvView *view, EvLink *link)
                        goto_xyz_link (view, link);
                        break;
                case EV_LINK_TYPE_EXTERNAL_URI:
-                       uri = ev_link_get_uri (link);
-                       gnome_vfs_url_show (uri);
+               case EV_LINK_TYPE_LAUNCH:
+                       g_signal_emit (view, signals[SIGNAL_EXTERNAL_LINK], 0, link);
                        break;
        }
 }
@@ -2288,6 +2290,14 @@ ev_view_class_init (EvViewClass *class)
                         NULL, NULL,
                         ev_marshal_VOID__VOID,
                         G_TYPE_NONE, 0, G_TYPE_NONE);
+       signals[SIGNAL_EXTERNAL_LINK] = g_signal_new ("external-link",
+                        G_TYPE_FROM_CLASS (object_class),
+                        G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                        G_STRUCT_OFFSET (EvViewClass, external_link),
+                        NULL, NULL,
+                        g_cclosure_marshal_VOID__OBJECT,
+                        G_TYPE_NONE, 1,
+                        G_TYPE_OBJECT);
 
        g_object_class_install_property (object_class,
                                         PROP_STATUS,
index 5abda4d74837b4b52b0b7219ac710936a0c2957e..3ca912eaec42f3746394a09401d2b1ddf82b45e7 100644 (file)
@@ -3228,6 +3228,58 @@ sidebar_links_link_activated_cb (EvSidebarLinks *sidebar_links, EvLink *link, Ev
        ev_view_goto_link (EV_VIEW (window->priv->view), link);
 }
 
+static void
+launch_link (EvWindow *window, EvLink *link)
+{
+       const char *filename = ev_link_get_filename (link);
+       char *uri = NULL;
+
+       if (g_path_is_absolute (filename)) {
+               uri = g_strconcat ("file://", filename, NULL);
+       } else {
+               GnomeVFSURI *base_uri, *resolved_uri;
+
+               base_uri = gnome_vfs_uri_new (window->priv->uri);
+               if (base_uri) {
+                       resolved_uri = gnome_vfs_uri_resolve_relative (base_uri, filename);     
+                       if (resolved_uri) {
+                               uri = gnome_vfs_uri_to_string (resolved_uri, GNOME_VFS_URI_HIDE_NONE);
+                       }
+                       gnome_vfs_uri_unref (resolved_uri);
+               }
+               gnome_vfs_uri_unref (base_uri);
+       }
+
+       if (uri) {
+               gnome_vfs_url_show (uri);
+       } else {
+               gnome_vfs_url_show (filename);
+       }
+
+       g_free (uri);
+
+       /* According to the PDF spec filename can be an executable. I'm not sure
+          allowing to launch executables is a good idea though. -- marco */
+}
+
+static void
+view_external_link_cb (EvView *view, EvLink *link, EvWindow *window)
+{
+       const char *uri;
+
+       switch (ev_link_get_link_type (link)) {
+       case EV_LINK_TYPE_EXTERNAL_URI:
+               uri = ev_link_get_uri (link);
+               gnome_vfs_url_show (uri);
+               break;
+       case EV_LINK_TYPE_LAUNCH:
+               launch_link (window, link);
+               break;
+       default:
+               g_assert_not_reached ();
+       }
+}
+
 static void
 ev_window_init (EvWindow *ev_window)
 {
@@ -3368,6 +3420,9 @@ ev_window_init (EvWindow *ev_window)
        g_signal_connect_object (ev_window->priv->view, "focus_out_event",
                                 G_CALLBACK (view_actions_focus_out_cb),
                                 ev_window, 0);
+       g_signal_connect_object (ev_window->priv->view, "external-link",
+                                G_CALLBACK (view_external_link_cb),
+                                ev_window, 0);
        gtk_widget_show (ev_window->priv->view);
        gtk_widget_show (ev_window->priv->password_view);