Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ev-view-private.h2
-rw-r--r--shell/ev-view.c34
-rw-r--r--shell/ev-window.c92
3 files changed, 119 insertions, 9 deletions
diff --git a/shell/ev-view-private.h b/shell/ev-view-private.h
index 9a0c773..ef48e0b 100644
--- a/shell/ev-view-private.h
+++ b/shell/ev-view-private.h
@@ -128,6 +128,8 @@ struct _EvViewClass {
void (*zoom_invalid) (EvView *view);
void (*external_link) (EvView *view,
EvLink *link);
+ void (*popup_menu) (EvView *view,
+ EvLink *link);
};
#endif /* __EV_VIEW_PRIVATE_H__ */
diff --git a/shell/ev-view.c b/shell/ev-view.c
index be6f295..c39a265 100644
--- a/shell/ev-view.c
+++ b/shell/ev-view.c
@@ -64,6 +64,7 @@ enum {
SIGNAL_BINDING_ACTIVATED,
SIGNAL_ZOOM_INVALID,
SIGNAL_EXTERNAL_LINK,
+ SIGNAL_POPUP_MENU,
N_SIGNALS,
};
@@ -149,9 +150,9 @@ static void find_page_at_location (EvView
gint *y_offset);
/*** Hyperrefs ***/
-static EvLink* get_link_at_location (EvView *view,
- gdouble x,
- gdouble y);
+static EvLink * ev_view_get_link_at_location (EvView *view,
+ gdouble x,
+ gdouble y);
static char* tip_from_link (EvView *view,
EvLink *link);
static void handle_link_over_xy (EvView *view,
@@ -1031,13 +1032,16 @@ location_in_selected_text (EvView *view,
/*** Hyperref ***/
static EvLink *
-get_link_at_location (EvView *view,
- gdouble x,
- gdouble y)
+ev_view_get_link_at_location (EvView *view,
+ gdouble x,
+ gdouble y)
{
gint page = -1;
gint x_offset = 0, y_offset = 0;
GList *link_mapping;
+
+ x += view->scroll_x;
+ y += view->scroll_y;
find_page_at_location (view, x, y, &page, &x_offset, &y_offset);
@@ -1254,7 +1258,7 @@ handle_link_over_xy (EvView *view, gint x, gint y)
{
EvLink *link;
- link = get_link_at_location (view, x + view->scroll_x, y + view->scroll_y);
+ link = ev_view_get_link_at_location (view, x, y);
if (view->link_tooltip == NULL) {
view->link_tooltip = ev_tooltip_new (GTK_WIDGET (view));
@@ -1617,6 +1621,7 @@ ev_view_button_press_event (GtkWidget *widget,
GdkEventButton *event)
{
EvView *view = EV_VIEW (widget);
+ EvLink *link;
if (!GTK_WIDGET_HAS_FOCUS (widget)) {
gtk_widget_grab_focus (widget);
@@ -1654,6 +1659,10 @@ ev_view_button_press_event (GtkWidget *widget,
ev_view_set_cursor (view, EV_VIEW_CURSOR_DRAG);
return TRUE;
+ case 3:
+ link = ev_view_get_link_at_location (view, event->x, event->y);
+ g_signal_emit (view, signals[SIGNAL_POPUP_MENU], 0, link);
+ return TRUE;
}
return FALSE;
@@ -1835,8 +1844,7 @@ ev_view_button_release_event (GtkWidget *widget,
}
if (view->document) {
- link = get_link_at_location (view, event->x + view->scroll_x,
- event->y + view->scroll_y);
+ link = ev_view_get_link_at_location (view, event->x, event->y);
} else {
link = NULL;
}
@@ -2399,6 +2407,14 @@ ev_view_class_init (EvViewClass *class)
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
G_TYPE_OBJECT);
+ signals[SIGNAL_POPUP_MENU] = g_signal_new ("popup",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EvViewClass, popup_menu),
+ 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 77bb4c9..fde1dae 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -114,12 +114,18 @@ struct _EvWindowPrivate {
/* UI Builders */
GtkActionGroup *action_group;
+ GtkActionGroup *popups_action_group;
GtkUIManager *ui_manager;
/* Fullscreen mode */
GtkWidget *fullscreen_toolbar;
GtkWidget *fullscreen_popup;
GSource *fullscreen_timeout_source;
+
+ /* Popup link */
+ GtkWidget *popup;
+ GtkWidget *link_popup;
+ EvLink *link;
/* Document */
char *uri;
@@ -191,6 +197,10 @@ static void ev_window_stop_presentation (EvWindow *windo
static void ev_window_cmd_view_presentation (GtkAction *action,
EvWindow *window);
static void show_fullscreen_popup (EvWindow *window);
+static void ev_popup_cmd_open_link (GtkAction *action,
+ EvWindow *window);
+static void ev_popup_cmd_copy_link_address (GtkAction *action,
+ EvWindow *window);
G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW)
@@ -2607,6 +2617,30 @@ ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar, GParamSpec *pspe
}
}
+static gboolean
+view_menu_popup_cb (EvView *view,
+ EvLink *link,
+ EvWindow *ev_window)
+{
+ GtkWidget *popup;
+
+ if (ev_window->priv->link)
+ g_object_unref (ev_window->priv->link);
+ ev_window->priv->link = link;
+
+ if (ev_window->priv->link &&
+ (ev_link_get_link_type (ev_window->priv->link) == EV_LINK_TYPE_EXTERNAL_URI)) {
+ popup = ev_window->priv->link_popup;
+ } else {
+ popup = ev_window->priv->popup;
+ }
+
+ gtk_menu_popup (GTK_MENU (popup), NULL, NULL,
+ NULL, NULL,
+ 3, gtk_get_current_event_time ());
+ return TRUE;
+}
+
static void
view_find_status_changed_cb (EvView *view,
GParamSpec *pspec,
@@ -2751,6 +2785,11 @@ ev_window_dispose (GObject *object)
priv->action_group = NULL;
}
+ if (priv->popups_action_group) {
+ g_object_unref (priv->popups_action_group);
+ priv->popups_action_group = NULL;
+ }
+
if (priv->page_cache) {
g_signal_handlers_disconnect_by_func (priv->page_cache, page_changed_cb, window);
priv->page_cache = NULL;
@@ -2793,6 +2832,11 @@ ev_window_dispose (GObject *object)
gtk_widget_destroy (priv->password_dialog);
}
+ if (priv->link) {
+ g_object_unref (priv->link);
+ priv->link = NULL;
+ }
+
if (priv->find_bar) {
g_signal_handlers_disconnect_by_func
(window->priv->find_bar,
@@ -2983,6 +3027,16 @@ static const GtkToggleActionEntry toggle_entries[] = {
G_CALLBACK (ev_window_cmd_view_page_width) },
};
+/* Popups specific items */
+static const GtkActionEntry popups_entries [] = {
+ /* Links */
+ { "OpenLink", GTK_STOCK_OPEN, N_("_Open Link"), NULL,
+ NULL, G_CALLBACK (ev_popup_cmd_open_link) },
+ { "CopyLinkAddress", NULL, N_("_Copy Link Address"), NULL,
+ NULL,
+ G_CALLBACK (ev_popup_cmd_copy_link_address) },
+};
+
static void
drag_data_received_cb (GtkWidget *widget, GdkDragContext *context,
gint x, gint y, GtkSelectionData *selection_data,
@@ -3301,6 +3355,25 @@ view_external_link_cb (EvView *view, EvLink *link, EvWindow *window)
}
static void
+ev_popup_cmd_open_link (GtkAction *action, EvWindow *window)
+{
+ launch_external_uri (window, window->priv->link);
+}
+
+static void
+ev_popup_cmd_copy_link_address (GtkAction *action, EvWindow *window)
+{
+ GtkClipboard *clipboard;
+ const gchar *uri;
+
+ uri = ev_link_get_uri (window->priv->link);
+
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window),
+ GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (clipboard, uri, -1);
+}
+
+static void
ev_window_init (EvWindow *ev_window)
{
GtkActionGroup *action_group;
@@ -3343,6 +3416,14 @@ ev_window_init (EvWindow *ev_window)
ev_window_set_view_accels_sensitivity (ev_window, FALSE);
+ action_group = gtk_action_group_new ("PopupsActions");
+ ev_window->priv->popups_action_group = action_group;
+ gtk_action_group_set_translation_domain (action_group, NULL);
+ gtk_action_group_add_actions (action_group, popups_entries,
+ G_N_ELEMENTS (popups_entries), ev_window);
+ gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
+ action_group, 0);
+
if (!gtk_ui_manager_add_ui_from_file (ev_window->priv->ui_manager,
DATADIR"/evince-ui.xml",
&error)) {
@@ -3443,6 +3524,10 @@ ev_window_init (EvWindow *ev_window)
g_signal_connect_object (ev_window->priv->view, "external-link",
G_CALLBACK (view_external_link_cb),
ev_window, 0);
+ g_signal_connect_object (ev_window->priv->view,
+ "popup",
+ G_CALLBACK (view_menu_popup_cb),
+ ev_window, 0);
gtk_widget_show (ev_window->priv->view);
gtk_widget_show (ev_window->priv->password_view);
@@ -3524,6 +3609,13 @@ ev_window_init (EvWindow *ev_window)
G_CALLBACK (find_bar_search_changed_cb),
ev_window);
+ /* Popups */
+ ev_window->priv->link_popup = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
+ "/ExternalLinkPopup");
+ ev_window->priv->popup = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
+ "/DocumentPopup");
+ ev_window->priv->link = NULL;
+
/* Give focus to the document view */
gtk_widget_grab_focus (ev_window->priv->view);