diff options
author | Marco Pesenti Gritti <mpg@redhat.com> | 2005-09-26 10:28:48 (GMT) |
---|---|---|
committer | Marco Pesenti Gritti <marco@src.gnome.org> | 2005-09-26 10:28:48 (GMT) |
commit | 85c366bda9f25b1249ba8333604eb3e757bc6edf (patch) | |
tree | 6b7287013297ea1d23c295f3c3b4f6cee198a949 | |
parent | b66c8a73177b462aebcb6e495341807abb31a93f (diff) |
Implement launch links. Delegate external link opening to the window.
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.
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | backend/ev-link.c | 74 | ||||
-rw-r--r-- | backend/ev-link.h | 6 | ||||
-rw-r--r-- | pdf/ev-poppler.cc | 3 | ||||
-rw-r--r-- | shell/ev-view.c | 16 | ||||
-rw-r--r-- | shell/ev-window.c | 55 |
6 files changed, 163 insertions, 6 deletions
@@ -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), diff --git a/backend/ev-link.c b/backend/ev-link.c index 57af5fa..b8721d9 100644 --- a/backend/ev-link.c +++ b/backend/ev-link.c @@ -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); } @@ -306,6 +349,22 @@ ev_link_class_init (EvLinkClass *ev_window_class) 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", @@ -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) diff --git a/backend/ev-link.h b/backend/ev-link.h index c014c01..6ab2811 100644 --- a/backend/ev-link.h +++ b/backend/ev-link.h @@ -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 */ diff --git a/pdf/ev-poppler.cc b/pdf/ev-poppler.cc index 30b5a72..c8405d3 100644 --- a/pdf/ev-poppler.cc +++ b/pdf/ev-poppler.cc @@ -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); diff --git a/shell/ev-view.c b/shell/ev-view.c index c5cc503..15bd412 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -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, diff --git a/shell/ev-window.c b/shell/ev-window.c index 5abda4d..3ca912e 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -3229,6 +3229,58 @@ sidebar_links_link_activated_cb (EvSidebarLinks *sidebar_links, EvLink *link, Ev } 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) { GtkActionGroup *action_group; @@ -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); |