X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=shell%2Fev-window.c;h=8d3601b5f6c7678495037a0ec2a87a1380ea7614;hb=693b28684086b315546e6db4472a9313c0be3a3b;hp=fa4c87735c5c0517b4b08a18288dbb39c124c2cf;hpb=00a3581bfaaf0d5f825820c68b515415fe510b66;p=evince.git diff --git a/shell/ev-window.c b/shell/ev-window.c index fa4c8773..8d3601b5 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -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; @@ -152,7 +157,6 @@ static const GtkTargetEntry ev_drop_types[] = { #define PAGE_SELECTOR_ACTION "PageSelector" #define ZOOM_CONTROL_ACTION "ViewZoom" -#define GCONF_CHROME_TOOLBAR "/apps/evince/show_toolbar" #define GCONF_OVERRIDE_RESTRICTIONS "/apps/evince/override_restrictions" #define GCONF_LOCKDOWN_SAVE "/desktop/gnome/lockdown/disable_save_to_disk" #define GCONF_LOCKDOWN_PRINT "/desktop/gnome/lockdown/disable_printing" @@ -192,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) @@ -219,6 +227,8 @@ update_action_sensitivity (EvWindow *ev_window) gboolean ok_to_copy = TRUE; gboolean has_properties = TRUE; gboolean override_restrictions = FALSE; + gboolean can_get_text = FALSE; + gboolean ok_to_copy_text = FALSE; GConfClient *client; view = EV_VIEW (ev_window->priv->view); @@ -263,6 +273,11 @@ update_action_sensitivity (EvWindow *ev_window) g_object_unref (client); + if (has_document && ev_document_can_get_text (document)) { + can_get_text = TRUE; + ok_to_copy_text = ev_view_get_has_selection (view); + } + /* File menu */ /* "FileOpen": always sensitive */ set_action_sensitive (ev_window, "FileSaveAs", has_document && ok_to_copy); @@ -272,8 +287,8 @@ update_action_sensitivity (EvWindow *ev_window) /* Edit menu */ sensitive = has_pages && ev_document_can_get_text (document); - set_action_sensitive (ev_window, "EditCopy", sensitive && ok_to_copy); - set_action_sensitive (ev_window, "EditSelectAll", sensitive && ok_to_copy); + set_action_sensitive (ev_window, "EditCopy", sensitive && ok_to_copy_text); + set_action_sensitive (ev_window, "EditSelectAll", sensitive && can_get_text); set_action_sensitive (ev_window, "EditFind", has_pages && EV_IS_DOCUMENT_FIND (document)); set_action_sensitive (ev_window, "Slash", @@ -311,7 +326,9 @@ update_action_sensitivity (EvWindow *ev_window) set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, has_pages); set_action_sensitive (ev_window, ZOOM_CONTROL_ACTION, has_pages); - if (has_pages && ev_view_get_sizing_mode (view) == EV_SIZING_FREE) { + if (has_pages && + ev_view_get_sizing_mode (view) != EV_SIZING_FIT_WIDTH && + ev_view_get_sizing_mode (view) != EV_SIZING_BEST_FIT) { GtkAction *action; float zoom; float real_zoom; @@ -373,24 +390,16 @@ update_chrome_visibility (EvWindow *window) } static void -update_chrome_flag (EvWindow *window, EvChrome flag, const char *pref, gboolean active) +update_chrome_flag (EvWindow *window, EvChrome flag, gboolean active) { EvWindowPrivate *priv = window->priv; - GConfClient *client; if (active) { priv->chrome |= flag; - } - else { + } else { priv->chrome &= ~flag; } - if (pref != NULL) { - client = gconf_client_get_default (); - gconf_client_set_bool (client, pref, active, NULL); - g_object_unref (client); - } - update_chrome_visibility (window); } @@ -399,7 +408,7 @@ ev_window_cmd_focus_page_selector (GtkAction *act, EvWindow *window) { GtkAction *action; - update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, NULL, TRUE); + update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, TRUE); set_action_sensitive (window, "ViewToolbar", FALSE); action = gtk_action_group_get_action (window->priv->action_group, @@ -608,7 +617,7 @@ update_sidebar_visibility (EvWindow *window) char *uri = window->priv->uri; GValue sidebar_visibility = { 0, }; - if (uri && ev_metadata_manager_get (uri, "sidebar_visibility", &sidebar_visibility)) { + if (uri && ev_metadata_manager_get (uri, "sidebar_visibility", &sidebar_visibility, TRUE)) { set_widget_visibility (window->priv->sidebar, g_value_get_boolean (&sidebar_visibility)); } @@ -621,12 +630,26 @@ setup_document_from_metadata (EvWindow *window) GValue page = { 0, }; /* Page */ - if (uri && ev_metadata_manager_get (uri, "page", &page)) { + if (uri && ev_metadata_manager_get (uri, "page", &page, TRUE)) { ev_page_cache_set_current_page (window->priv->page_cache, g_value_get_int (&page)); } } +static void +setup_chrome_from_metadata (EvWindow *window) +{ + EvChrome chrome = EV_CHROME_NORMAL; + GValue show_toolbar = { 0, }; + + if (ev_metadata_manager_get (NULL, "show_toolbar", &show_toolbar, FALSE)) { + if (!g_value_get_boolean (&show_toolbar)) + chrome &= ~EV_CHROME_TOOLBAR; + } + window->priv->chrome = chrome; +} + + static void setup_sidebar_from_metadata (EvWindow *window, EvDocument *document) { @@ -637,12 +660,12 @@ setup_sidebar_from_metadata (EvWindow *window, EvDocument *document) GValue sidebar_size = { 0, }; GValue sidebar_page = { 0, }; - if (ev_metadata_manager_get (uri, "sidebar_size", &sidebar_size)) { + if (ev_metadata_manager_get (uri, "sidebar_size", &sidebar_size, FALSE)) { gtk_paned_set_position (GTK_PANED (window->priv->hpaned), g_value_get_int (&sidebar_size)); } - if (ev_metadata_manager_get (uri, "sidebar_page", &sidebar_page)) { + if (ev_metadata_manager_get (uri, "sidebar_page", &sidebar_page, FALSE)) { const char *page_id = g_value_get_string (&sidebar_page); if (strcmp (page_id, "links") == 0) { @@ -689,7 +712,8 @@ ev_window_setup_document (EvWindow *ev_window) ev_view_set_document (view, document); } - ev_window_title_set_document (ev_window->priv->title, document, ev_window->priv->uri); + ev_window_title_set_document (ev_window->priv->title, document); + ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri); action = gtk_action_group_get_action (ev_window->priv->action_group, PAGE_SELECTOR_ACTION); ev_page_action_set_document (EV_PAGE_ACTION (action), document); update_action_sensitivity (ev_window); @@ -762,6 +786,7 @@ ev_window_popup_password_dialog (EvWindow *ev_window) gtk_widget_set_sensitive (ev_window->priv->password_view, FALSE); + ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->password_uri); ev_window_title_set_type (ev_window->priv->title, EV_WINDOW_TITLE_PASSWORD); if (ev_window->priv->password_dialog == NULL) { @@ -941,15 +966,11 @@ setup_view_from_metadata (EvWindow *window) GValue fullscreen = { 0, }; GValue rotation = { 0, }; - if (window->priv->uri == NULL) { - return; - } - /* Window size */ if (!GTK_WIDGET_VISIBLE (window)) { gboolean restore_size = TRUE; - if (ev_metadata_manager_get (uri, "window_maximized", &maximized)) { + if (ev_metadata_manager_get (uri, "window_maximized", &maximized, TRUE)) { if (g_value_get_boolean (&maximized)) { gtk_window_maximize (GTK_WINDOW (window)); restore_size = FALSE; @@ -957,20 +978,22 @@ setup_view_from_metadata (EvWindow *window) } if (restore_size && - ev_metadata_manager_get (uri, "window_x", &x) && - ev_metadata_manager_get (uri, "window_y", &y) && - ev_metadata_manager_get (uri, "window_width", &width) && - ev_metadata_manager_get (uri, "window_height", &height)) { + ev_metadata_manager_get (uri, "window_width", &width, TRUE) && + ev_metadata_manager_get (uri, "window_height", &height, TRUE)) { gtk_window_set_default_size (GTK_WINDOW (window), g_value_get_int (&width), g_value_get_int (&height)); + } + if (restore_size && + ev_metadata_manager_get (uri, "window_x", &x, TRUE) && + ev_metadata_manager_get (uri, "window_y", &y, TRUE)) { gtk_window_move (GTK_WINDOW (window), g_value_get_int (&x), g_value_get_int (&y)); } } /* Sizing mode */ - if (ev_metadata_manager_get (uri, "sizing_mode", &sizing_mode)) { + if (ev_metadata_manager_get (uri, "sizing_mode", &sizing_mode, FALSE)) { enum_value = g_enum_get_value_by_nick (EV_SIZING_MODE_CLASS, g_value_get_string (&sizing_mode)); g_value_unset (&sizing_mode); @@ -978,37 +1001,37 @@ setup_view_from_metadata (EvWindow *window) } /* Zoom */ - if (ev_metadata_manager_get (uri, "zoom", &zoom) && + if (ev_metadata_manager_get (uri, "zoom", &zoom, FALSE) && ev_view_get_sizing_mode (view) == EV_SIZING_FREE) { ev_view_set_zoom (view, g_value_get_double (&zoom), FALSE); } /* Continuous */ - if (ev_metadata_manager_get (uri, "continuous", &continuous)) { + if (ev_metadata_manager_get (uri, "continuous", &continuous, FALSE)) { ev_view_set_continuous (view, g_value_get_boolean (&continuous)); } /* Dual page */ - if (ev_metadata_manager_get (uri, "dual-page", &dual_page)) { + if (ev_metadata_manager_get (uri, "dual-page", &dual_page, FALSE)) { ev_view_set_dual_page (view, g_value_get_boolean (&dual_page)); } /* Presentation */ - if (ev_metadata_manager_get (uri, "presentation", &presentation)) { + if (ev_metadata_manager_get (uri, "presentation", &presentation, FALSE)) { if (g_value_get_boolean (&presentation)) { ev_window_run_presentation (window); } } /* Fullscreen */ - if (ev_metadata_manager_get (uri, "fullscreen", &fullscreen)) { + if (ev_metadata_manager_get (uri, "fullscreen", &fullscreen, FALSE)) { if (g_value_get_boolean (&fullscreen)) { ev_window_run_fullscreen (window); } } /* Rotation */ - if (ev_metadata_manager_get (uri, "rotation", &rotation)) { + if (ev_metadata_manager_get (uri, "rotation", &rotation, TRUE)) { if (g_value_get_int (&rotation)) { switch (g_value_get_int (&rotation)) { case 90: @@ -1535,7 +1558,7 @@ ev_window_cmd_edit_find (GtkAction *action, EvWindow *ev_window) } else if (!EV_IS_DOCUMENT_FIND (ev_window->priv->document)) { find_not_supported_dialog (ev_window); } else { - update_chrome_flag (ev_window, EV_CHROME_FINDBAR, NULL, TRUE); + update_chrome_flag (ev_window, EV_CHROME_FINDBAR, TRUE); gtk_widget_grab_focus (ev_window->priv->find_bar); } @@ -2130,7 +2153,7 @@ ev_window_cmd_go_previous_page (GtkAction *action, EvWindow *ev_window) { g_return_if_fail (EV_IS_WINDOW (ev_window)); - ev_view_previous_page (ev_window->priv->view); + ev_view_previous_page (EV_VIEW (ev_window->priv->view)); } static void @@ -2138,7 +2161,7 @@ ev_window_cmd_go_next_page (GtkAction *action, EvWindow *ev_window) { g_return_if_fail (EV_IS_WINDOW (ev_window)); - ev_view_next_page (ev_window->priv->view); + ev_view_next_page (EV_VIEW (ev_window->priv->view)); } static void @@ -2236,7 +2259,7 @@ ev_window_cmd_escape (GtkAction *action, EvWindow *window) widget = gtk_window_get_focus (GTK_WINDOW (window)); if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) { - update_chrome_flag (window, EV_CHROME_FINDBAR, NULL, FALSE); + update_chrome_flag (window, EV_CHROME_FINDBAR, FALSE); gtk_widget_grab_focus (window->priv->view); } else { gboolean fullscreen; @@ -2419,6 +2442,12 @@ ev_window_rotation_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *window rotation); } +static void +ev_window_has_selection_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *window) +{ + update_action_sensitivity (window); +} + static void ev_window_dual_mode_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window) { @@ -2525,9 +2554,11 @@ ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window) static void ev_window_view_toolbar_cb (GtkAction *action, EvWindow *ev_window) { - update_chrome_flag (ev_window, EV_CHROME_TOOLBAR, - GCONF_CHROME_TOOLBAR, - gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))); + gboolean active; + + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + update_chrome_flag (ev_window, EV_CHROME_TOOLBAR, active); + ev_metadata_manager_set_boolean (NULL, "show_toolbar", active); } static void @@ -2578,12 +2609,68 @@ ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar, GParamSpec *pspe g_signal_handlers_unblock_by_func (action, G_CALLBACK (ev_window_view_sidebar_cb), ev_window); - if (!ev_view_get_presentation (view) && !ev_view_get_fullscreen (view)) { + if (!ev_view_get_presentation (view) && + !ev_view_get_fullscreen (view)) { ev_metadata_manager_set_boolean (ev_window->priv->uri, "sidebar_visibility", GTK_WIDGET_VISIBLE (ev_sidebar)); } } +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, @@ -2614,7 +2701,7 @@ static void find_bar_close_cb (EggFindBar *find_bar, EvWindow *ev_window) { - update_chrome_flag (ev_window, EV_CHROME_FINDBAR, NULL, FALSE); + update_chrome_flag (ev_window, EV_CHROME_FINDBAR, FALSE); } static void @@ -2656,6 +2743,7 @@ find_bar_search_changed_cb (EggFindBar *find_bar, ev_document_find_cancel (EV_DOCUMENT_FIND (ev_window->priv->document)); ev_document_doc_mutex_unlock (); + update_action_sensitivity (ev_window); egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar), NULL); gtk_widget_queue_draw (GTK_WIDGET (ev_window->priv->view)); @@ -2690,23 +2778,14 @@ zoom_control_changed_cb (EphyZoomAction *action, static void ev_window_finalize (GObject *object) { - gboolean empty = TRUE; - GList *list, *windows; + GList *windows = ev_application_get_windows (EV_APP); - - windows = gtk_window_list_toplevels (); - - for (list = windows; list; list = list->next) { - if (EV_IS_WINDOW (list->data)) { - empty = FALSE; - break; - } - } - - if (empty) + if (windows == NULL) { ev_application_shutdown (EV_APP); + } else { + g_list_free (windows); + } - g_list_free (windows); G_OBJECT_CLASS (ev_window_parent_class)->finalize (object); } @@ -2736,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; @@ -2778,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, @@ -2829,7 +2918,8 @@ static const GtkActionEntry entries[] = { { "FileOpen", GTK_STOCK_OPEN, N_("_Open..."), "O", N_("Open an existing document"), G_CALLBACK (ev_window_cmd_file_open) }, - { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), NULL, NULL, + { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), "S", + N_("Save a copy of the current document"), G_CALLBACK (ev_window_cmd_save_as) }, { "FilePrint", GTK_STOCK_PRINT, N_("_Print..."), "P", N_("Print this document"), @@ -2910,10 +3000,16 @@ static const GtkActionEntry entries[] = { G_CALLBACK (ev_window_cmd_scroll_backward) }, { "ShiftBackSpace", NULL, "", "BackSpace", NULL, G_CALLBACK (ev_window_cmd_scroll_forward) }, + { "Return", NULL, "", "Return", NULL, + G_CALLBACK (ev_window_cmd_scroll_forward) }, + { "ShiftReturn", NULL, "", "Return", NULL, + G_CALLBACK (ev_window_cmd_scroll_backward) }, { "Plus", GTK_STOCK_ZOOM_IN, NULL, "plus", NULL, G_CALLBACK (ev_window_cmd_view_zoom_in) }, { "CtrlEqual", GTK_STOCK_ZOOM_IN, NULL, "equal", NULL, G_CALLBACK (ev_window_cmd_view_zoom_in) }, + { "Equal", GTK_STOCK_ZOOM_IN, NULL, "equal", NULL, + G_CALLBACK (ev_window_cmd_view_zoom_in) }, { "Minus", GTK_STOCK_ZOOM_OUT, NULL, "minus", NULL, G_CALLBACK (ev_window_cmd_view_zoom_out) }, { "FocusPageSelector", NULL, "", "l", NULL, @@ -2926,6 +3022,10 @@ static const GtkActionEntry entries[] = { G_CALLBACK (ev_window_cmd_view_zoom_in) }, { "KpMinus", GTK_STOCK_ZOOM_OUT, NULL, "KP_Subtract", NULL, G_CALLBACK (ev_window_cmd_view_zoom_out) }, + { "CtrlKpPlus", GTK_STOCK_ZOOM_IN, NULL, "KP_Add", NULL, + G_CALLBACK (ev_window_cmd_view_zoom_in) }, + { "CtrlKpMinus", GTK_STOCK_ZOOM_OUT, NULL, "KP_Subtract", NULL, + G_CALLBACK (ev_window_cmd_view_zoom_out) }, }; /* Toggle items */ @@ -2957,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, @@ -3091,28 +3203,6 @@ set_chrome_actions (EvWindow *window) (action, G_CALLBACK (ev_window_view_toolbar_cb), window); } -static EvChrome -load_chrome (void) -{ - EvChrome chrome = EV_CHROME_NORMAL; - GConfClient *client; - GConfValue *value; - - client = gconf_client_get_default (); - - value = gconf_client_get (client, GCONF_CHROME_TOOLBAR, NULL); - if (value != NULL) { - if (value->type == GCONF_VALUE_BOOL && !gconf_value_get_bool (value)) { - chrome &= ~EV_CHROME_TOOLBAR; - } - gconf_value_free (value); - } - - g_object_unref (client); - - return chrome; -} - static void sidebar_widget_model_set (EvSidebarLinks *ev_sidebar_links, GParamSpec *pspec, @@ -3141,18 +3231,21 @@ ev_window_set_view_accels_sensitivity (EvWindow *window, gboolean sensitive) set_action_sensitive (window, "ShiftSpace", sensitive); set_action_sensitive (window, "BackSpace", sensitive); set_action_sensitive (window, "ShiftBackSpace", sensitive); + set_action_sensitive (window, "Return", sensitive); + set_action_sensitive (window, "ShiftReturn", sensitive); set_action_sensitive (window, "Slash", sensitive); set_action_sensitive (window, "Plus", sensitive); set_action_sensitive (window, "Minus", sensitive); set_action_sensitive (window, "KpPlus", sensitive); set_action_sensitive (window, "KpMinus", sensitive); + set_action_sensitive (window, "Equal", sensitive); } } static gboolean view_actions_focus_in_cb (GtkWidget *widget, GdkEventFocus *event, EvWindow *window) { - update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, NULL, FALSE); + update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, FALSE); set_action_sensitive (window, "ViewToolbar", TRUE); ev_window_set_view_accels_sensitivity (window, TRUE); @@ -3231,6 +3324,87 @@ 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 (filename && g_path_is_absolute (filename)) { + uri = gnome_vfs_get_uri_from_local_path (filename); + } else { + GnomeVFSURI *base_uri, *resolved_uri; + + base_uri = gnome_vfs_uri_new (window->priv->uri); + if (base_uri && filename) { + 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 +launch_external_uri (EvWindow *window, EvLink *link) +{ + const char *uri; + char *escaped; + + uri = ev_link_get_uri (link); + escaped = gnome_vfs_escape_host_and_path_string (uri); + + gnome_vfs_url_show (escaped); + g_free (escaped); +} + +static void +view_external_link_cb (EvView *view, EvLink *link, EvWindow *window) +{ + switch (ev_link_get_link_type (link)) { + case EV_LINK_TYPE_EXTERNAL_URI: + launch_external_uri (window, link); + break; + case EV_LINK_TYPE_LAUNCH: + launch_link (window, link); + break; + default: + g_assert_not_reached (); + } +} + +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) { @@ -3274,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)) { @@ -3371,9 +3553,20 @@ 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); + 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); + ev_window->priv->find_bar = egg_find_bar_new (); + gtk_box_pack_end (GTK_BOX (ev_window->priv->main_box), + ev_window->priv->find_bar, + FALSE, TRUE, 0); /* We own a ref on these widgets, as we can swap them in and out */ g_object_ref (ev_window->priv->view); @@ -3407,18 +3600,12 @@ ev_window_init (EvWindow *ev_window) "notify::rotation", G_CALLBACK (ev_window_rotation_changed_cb), ev_window); + g_signal_connect (ev_window->priv->view, + "notify::has-selection", + G_CALLBACK (ev_window_has_selection_changed_cb), + ev_window); - ev_window->priv->find_bar = egg_find_bar_new (); - gtk_box_pack_end (GTK_BOX (ev_window->priv->main_box), - ev_window->priv->find_bar, - FALSE, TRUE, 0); - - ev_window_setup_recent (ev_window); - ev_window->priv->chrome = load_chrome (); - set_chrome_actions (ev_window); - update_chrome_visibility (ev_window); - - /* Connect sidebar signals */ + /* Connect sidebar signals */ g_signal_connect (ev_window->priv->sidebar, "notify::visible", G_CALLBACK (ev_window_sidebar_visibility_changed_cb), @@ -3454,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); @@ -3465,7 +3657,16 @@ ev_window_init (EvWindow *ev_window) g_signal_connect (G_OBJECT (ev_window), "drag_data_received", G_CALLBACK (drag_data_received_cb), NULL); - /* Set it to something random to force a change */ + /* Set it user interface params */ + + ev_window_setup_recent (ev_window); + setup_chrome_from_metadata (ev_window); + set_chrome_actions (ev_window); + update_chrome_visibility (ev_window); + + gtk_window_set_default_size (GTK_WINDOW (ev_window), + 600, 600); + setup_view_from_metadata (ev_window); ev_window_sizing_mode_changed_cb (EV_VIEW (ev_window->priv->view), NULL, ev_window); update_action_sensitivity (ev_window); @@ -3478,8 +3679,6 @@ ev_window_new (void) ev_window = GTK_WIDGET (g_object_new (EV_TYPE_WINDOW, "type", GTK_WINDOW_TOPLEVEL, - "default-width", 600, - "default-height", 600, NULL)); return ev_window;