]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-window.c
Update context menu for internal links. Fix for the bug #325066
[evince.git] / shell / ev-window.c
index 77bb4c91f29c3f08ee528c1ea3ed71cc37c43ef3..8d3601b5f6c7678495037a0ec2a87a1380ea7614 100644 (file)
@@ -114,12 +114,17 @@ 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;
+       EvLink    *link;
 
        /* Document */
        char *uri;
@@ -191,6 +196,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 +2616,61 @@ 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;
+       gboolean   show_external = FALSE;
+       gboolean   show_internal = FALSE;
+       GtkAction *action;
+       
+       if (ev_window->priv->link)
+               g_object_unref (ev_window->priv->link);
+       if (link)
+               ev_window->priv->link = g_object_ref (link);
+       else    
+               ev_window->priv->link = NULL;
+
+       popup = ev_window->priv->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:
+                               show_internal = TRUE;
+                               break;
+                       case EV_LINK_TYPE_EXTERNAL_URI:
+                       case EV_LINK_TYPE_LAUNCH:       
+                               show_external = TRUE;
+                               break;
+                       default:
+                               break;
+               }
+       
+       action = gtk_action_group_get_action (ev_window->priv->popups_action_group,
+                                             "OpenLink");
+       gtk_action_set_visible (action, show_external);
+
+       action = gtk_action_group_get_action (ev_window->priv->popups_action_group,
+                                             "CopyLinkAddress");
+       gtk_action_set_visible (action, show_external);
+
+       action = gtk_action_group_get_action (ev_window->priv->popups_action_group,
+                                             "GoLink");
+       gtk_action_set_visible (action, show_internal);
+
+       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 +2815,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 +2862,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 +3057,18 @@ 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) },
+       { "GoLink", GTK_STOCK_GO_FORWARD, N_("_Go To"), 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,
@@ -3300,6 +3386,25 @@ view_external_link_cb (EvView *view, EvLink *link, EvWindow *window)
        }
 }
 
+static void
+ev_popup_cmd_open_link (GtkAction *action, EvWindow *window)
+{
+       ev_view_goto_link (EV_VIEW (window->priv->view), 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)
 {
@@ -3343,6 +3448,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 +3556,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 +3641,11 @@ ev_window_init (EvWindow *ev_window)
                          G_CALLBACK (find_bar_search_changed_cb),
                          ev_window);
 
+       /* Popups */
+       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);