Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco 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)
commit85c366bda9f25b1249ba8333604eb3e757bc6edf (patch)
tree6b7287013297ea1d23c295f3c3b4f6cee198a949
parentb66c8a73177b462aebcb6e495341807abb31a93f (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--ChangeLog15
-rw-r--r--backend/ev-link.c74
-rw-r--r--backend/ev-link.h6
-rw-r--r--pdf/ev-poppler.cc3
-rw-r--r--shell/ev-view.c16
-rw-r--r--shell/ev-window.c55
6 files changed, 163 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 71e8678..c5faf62 100644
--- 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),
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);