X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=shell%2Fev-window.c;h=4c3fcf2397ab7ce4eb64ceb77e5b7b4f72bec9d9;hb=f51872613abaaa42c716e2fe6a2e4695c529dc4b;hp=ca4ab5853f1774bf4815bf1d713ecba06794fd8d;hpb=81dad2b0edd15c60ab8aa4d1707131da745574c6;p=evince.git diff --git a/shell/ev-window.c b/shell/ev-window.c index ca4ab585..4c3fcf23 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -32,6 +32,7 @@ #include "ev-window-title.h" #include "ev-navigation-action.h" #include "ev-page-action.h" +#include "ev-open-recent-action.h" #include "ev-sidebar.h" #include "ev-sidebar-links.h" #include "ev-sidebar-attachments.h" @@ -45,19 +46,13 @@ #include "ev-document-links.h" #include "ev-document-fonts.h" #include "ev-document-find.h" +#include "ev-document-images.h" #include "ev-document-security.h" #include "ev-document-factory.h" #include "ev-job-queue.h" #include "ev-jobs.h" #include "ev-sidebar-page.h" #include "eggfindbar.h" - -#ifndef HAVE_GTK_RECENT -#include "egg-recent-view-uimanager.h" -#include "egg-recent-view.h" -#include "egg-recent-model.h" -#endif - #include "egg-toolbar-editor.h" #include "egg-editable-toolbar.h" #include "egg-toolbars-model.h" @@ -70,15 +65,9 @@ #include "ev-utils.h" #include "ev-history.h" #include "ev-image.h" +#include "ev-message-area.h" -#ifdef WITH_GNOME_PRINT -#include "ev-print-job.h" -#include -#endif - -#ifdef WITH_GTK_PRINT #include -#endif #ifdef ENABLE_PDF #include @@ -87,9 +76,7 @@ #include #include #include -#include -#include -#include +#include #include #include @@ -97,10 +84,6 @@ #include #include -#if !GLIB_CHECK_VERSION (2, 13, 3) -char *xdg_user_dir_lookup (char *type); -#endif - typedef enum { PAGE_MODE_DOCUMENT, PAGE_MODE_PASSWORD @@ -125,10 +108,12 @@ struct _EvWindowPrivate { GtkWidget *menubar; GtkWidget *toolbar; GtkWidget *hpaned; + GtkWidget *view_box; GtkWidget *sidebar; GtkWidget *find_bar; GtkWidget *scrolled_window; GtkWidget *view; + GtkWidget *message_area; GtkWidget *password_view; GtkWidget *sidebar_thumbs; GtkWidget *sidebar_links; @@ -136,20 +121,16 @@ struct _EvWindowPrivate { /* Dialogs */ GtkWidget *properties; -#ifdef WITH_PRINT GtkWidget *print_dialog; -#endif GtkWidget *password_dialog; /* UI Builders */ GtkActionGroup *action_group; GtkActionGroup *view_popup_action_group; GtkActionGroup *attachment_popup_action_group; -#ifdef HAVE_GTK_RECENT GtkRecentManager *recent_manager; GtkActionGroup *recent_action_group; guint recent_ui_id; -#endif GtkUIManager *ui_manager; /* Fullscreen mode */ @@ -183,25 +164,19 @@ struct _EvWindowPrivate { EvPageCache *page_cache; EvWindowPageMode page_mode; EvWindowTitle *title; -#ifndef HAVE_GTK_RECENT - EggRecentViewUIManager *recent_view; -#endif - - EvJob *load_job; - EvJob *thumbnail_job; - EvJob *save_job; -#ifdef WITH_GNOME_PRINT - GnomePrintJob *print_job; -#endif -#ifdef WITH_GTK_PRINT + EvJob *load_job; + EvJob *thumbnail_job; + EvJob *save_job; EvJob *print_job; + + /* Printing */ gboolean print_preview; GtkPrintJob *gtk_print_job; GtkPrinter *printer; GtkPrintSettings *print_settings; GtkPageSetup *print_page_setup; -#endif + }; #define EV_WINDOW_GET_PRIVATE(object) \ @@ -222,6 +197,17 @@ struct _EvWindowPrivate { #define THUMBNAILS_SIDEBAR_ID "thumbnails" #define ATTACHMENTS_SIDEBAR_ID "attachments" +static const gchar *document_print_settings[] = { + GTK_PRINT_SETTINGS_N_COPIES, + GTK_PRINT_SETTINGS_COLLATE, + GTK_PRINT_SETTINGS_REVERSE, + GTK_PRINT_SETTINGS_NUMBER_UP, + GTK_PRINT_SETTINGS_SCALE, + GTK_PRINT_SETTINGS_PRINT_PAGES, + GTK_PRINT_SETTINGS_PAGE_RANGES, + GTK_PRINT_SETTINGS_PAGE_SET +}; + static void ev_window_update_actions (EvWindow *ev_window); static void ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar, GParamSpec *pspec, @@ -232,10 +218,8 @@ static void ev_window_load_job_cb (EvJobLoad *job, gpointer data); static void ev_window_set_icon_from_thumbnail (EvJobThumbnail *job, EvWindow *ev_window); -#ifdef WITH_GTK_PRINT static void ev_window_print_job_cb (EvJobPrint *job, EvWindow *window); -#endif static void ev_window_save_job_cb (EvJobSave *save, EvWindow *window); static void ev_window_sizing_mode_changed_cb (EvView *view, @@ -276,9 +260,12 @@ static void ev_window_cmd_view_page_width (GtkAction *action, static void view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window); +static void ev_window_cmd_edit_find (GtkAction *action, + EvWindow *ev_window); static void find_bar_search_changed_cb (EggFindBar *find_bar, GParamSpec *param, EvWindow *ev_window); +static void ev_window_do_preview_print (EvWindow *window); G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW) @@ -303,7 +290,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) gboolean ok_to_print = TRUE; gboolean ok_to_copy = TRUE; gboolean has_properties = TRUE; - gboolean override_restrictions = FALSE; + gboolean override_restrictions = TRUE; gboolean can_get_text = FALSE; gboolean has_pages = FALSE; gboolean can_find = FALSE; @@ -351,24 +338,13 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) if (gconf_client_get_bool (client, GCONF_LOCKDOWN_PRINT, NULL)) { ok_to_print = FALSE; } -#ifndef WITH_PRINT - ok_to_print = FALSE; -#endif - g_object_unref (client); + g_object_unref (client); /* File menu */ ev_window_set_action_sensitive (ev_window, "FileOpenCopy", has_document); ev_window_set_action_sensitive (ev_window, "FileSaveAs", has_document && ok_to_copy); - -#ifdef WITH_GTK_PRINT ev_window_set_action_sensitive (ev_window, "FilePrintSetup", has_pages && ok_to_print); -#endif - -#ifdef WITH_GNOME_PRINT - ev_window_set_action_sensitive (ev_window, "FilePrintSetup", FALSE); -#endif - ev_window_set_action_sensitive (ev_window, "FilePrint", has_pages && ok_to_print); ev_window_set_action_sensitive (ev_window, "FileProperties", has_document && has_properties); @@ -385,6 +361,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, "ViewBestFit", has_pages); ev_window_set_action_sensitive (ev_window, "ViewPageWidth", has_pages); ev_window_set_action_sensitive (ev_window, "ViewReload", has_pages); + ev_window_set_action_sensitive (ev_window, "ViewAutoscroll", has_pages); /* Toolbar-specific actions: */ ev_window_set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, has_pages); @@ -620,29 +597,56 @@ ev_window_is_empty (const EvWindow *ev_window) } static void -ev_window_error_dialog_response_cb (GtkWidget *dialog, - gint response_id, - EvWindow *ev_window) +ev_window_set_message_area (EvWindow *window, + GtkWidget *area) { - gtk_widget_destroy (dialog); + if (window->priv->message_area == area) + return; + + if (window->priv->message_area) + gtk_widget_destroy (window->priv->message_area); + window->priv->message_area = area; + + if (!area) + return; + + gtk_box_pack_start (GTK_BOX (window->priv->view_box), + window->priv->message_area, + FALSE, FALSE, 0); + gtk_box_reorder_child (GTK_BOX (window->priv->view_box), + window->priv->message_area, 0); + g_object_add_weak_pointer (G_OBJECT (window->priv->message_area), + (gpointer) &(window->priv->message_area)); } static void -ev_window_error_dialog (GtkWindow *window, const gchar *msg, GError *error) +ev_window_error_message_response_cb (EvMessageArea *area, + gint response_id, + EvWindow *window) { - GtkWidget *dialog; + ev_window_set_message_area (window, NULL); +} - dialog = gtk_message_dialog_new (GTK_WINDOW (window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - msg); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - "%s", error->message); - g_signal_connect (dialog, "response", - G_CALLBACK (ev_window_error_dialog_response_cb), - window); - gtk_widget_show (dialog); +static void +ev_window_error_message (GtkWindow *window, const gchar *msg, GError *error) +{ + GtkWidget *area; + + if (EV_WINDOW (window)->priv->message_area) + return; + + area = ev_message_area_new (GTK_MESSAGE_ERROR, + msg, + GTK_STOCK_CLOSE, + GTK_RESPONSE_CANCEL, + NULL); + if (error) + ev_message_area_set_secondary_text (EV_MESSAGE_AREA (area), error->message); + g_signal_connect (area, "response", + G_CALLBACK (ev_window_error_message_response_cb), + window); + gtk_widget_show (area); + ev_window_set_message_area (EV_WINDOW (window), area); } static void @@ -1063,6 +1067,36 @@ ev_window_set_icon_from_thumbnail (EvJobThumbnail *job, ev_window_clear_thumbnail_job (ev_window); } +static void +ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation) +{ + + EvRenderContext *rc; + gint page_width, page_height; + gdouble scale; + EvDocument *document = ev_window->priv->document; + + if (!EV_IS_DOCUMENT_THUMBNAILS (document)) { + return; + } + + ev_window_clear_thumbnail_job (ev_window); + + ev_page_cache_get_size (ev_window->priv->page_cache, + 0, 0, 1.0, + &page_width, &page_height); + scale = (gdouble)128 / (gdouble)page_width; + + rc = ev_render_context_new (rotation, 0, scale); + + ev_window->priv->thumbnail_job = ev_job_thumbnail_new (document, rc); + g_signal_connect (ev_window->priv->thumbnail_job, "finished", + G_CALLBACK (ev_window_set_icon_from_thumbnail), + ev_window); + ev_job_queue_add_job (EV_JOB (ev_window->priv->thumbnail_job), EV_JOB_PRIORITY_LOW); + g_object_unref (rc); +} + static gboolean ev_window_setup_document (EvWindow *ev_window) { @@ -1077,27 +1111,8 @@ ev_window_setup_document (EvWindow *ev_window) G_CALLBACK (find_changed_cb), ev_window, 0); } - - if (EV_IS_DOCUMENT_THUMBNAILS (document)) { - EvRenderContext *rc; - gint page_width, page_height; - gdouble scale; - - ev_window_clear_thumbnail_job (ev_window); - - ev_page_cache_get_size (ev_window->priv->page_cache, - 0, 0, 1.0, - &page_width, &page_height); - scale = (gdouble)128 / (gdouble)page_width; - - rc = ev_render_context_new (0, 0, scale); - ev_window->priv->thumbnail_job = ev_job_thumbnail_new (document, rc); - g_signal_connect (ev_window->priv->thumbnail_job, "finished", - G_CALLBACK (ev_window_set_icon_from_thumbnail), - ev_window); - ev_job_queue_add_job (EV_JOB (ev_window->priv->thumbnail_job), EV_JOB_PRIORITY_LOW); - g_object_unref (rc); - } + + ev_window_refresh_window_thumbnail (ev_window, 0); ev_window_set_page_mode (ev_window, PAGE_MODE_DOCUMENT); ev_window_title_set_document (ev_window->priv->title, document); @@ -1134,6 +1149,8 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) if (ev_window->priv->document) g_object_unref (ev_window->priv->document); ev_window->priv->document = g_object_ref (document); + + ev_window_set_message_area (ev_window, NULL); ev_window->priv->page_cache = ev_page_cache_get (ev_window->priv->document); g_signal_connect (ev_window->priv->page_cache, "page-changed", @@ -1252,30 +1269,20 @@ ev_window_clear_print_settings_file (EvWindow *ev_window) static void ev_window_clear_temp_file (EvWindow *ev_window) { - GnomeVFSURI *uri; - gchar *filename; - const gchar *tempdir; + GFile *file, *tempdir; if (!ev_window->priv->uri) return; - uri = gnome_vfs_uri_new (ev_window->priv->uri); - if (!gnome_vfs_uri_is_local (uri)) { - gnome_vfs_uri_unref (uri); - return; - } - gnome_vfs_uri_unref (uri); - - filename = g_filename_from_uri (ev_window->priv->uri, NULL, NULL); - if (!filename) - return; + file = g_file_new_for_uri (ev_window->priv->uri); + tempdir = g_file_new_for_path (g_get_tmp_dir ()); - tempdir = g_get_tmp_dir (); - if (g_ascii_strncasecmp (filename, tempdir, strlen (tempdir)) == 0) { - g_unlink (filename); + if (g_file_has_prefix (file, tempdir)) { + g_file_delete (file, NULL, NULL); } - g_free (filename); + g_object_unref (file); + g_object_unref (tempdir); } /* This callback will executed when load job will be finished. @@ -1342,6 +1349,10 @@ ev_window_load_job_cb (EvJobLoad *job, find_bar_search_changed_cb (EGG_FIND_BAR (ev_window->priv->find_bar), NULL, ev_window); } + } else if (job->search_string && EV_IS_DOCUMENT_FIND (document)) { + ev_window_cmd_edit_find (NULL, ev_window); + egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar), + job->search_string); } ev_window_clear_load_job (ev_window); @@ -1351,23 +1362,24 @@ ev_window_load_job_cb (EvJobLoad *job, if (job->error->domain == EV_DOCUMENT_ERROR && job->error->code == EV_DOCUMENT_ERROR_ENCRYPTED) { - gchar *base_name, *file_name; + GFile *file; + gchar *base_name; setup_view_from_metadata (ev_window); - file_name = gnome_vfs_format_uri_for_display (job->uri); - base_name = g_path_get_basename (file_name); + file = g_file_new_for_uri (job->uri); + base_name = g_file_get_basename (file); ev_password_view_set_file_name (EV_PASSWORD_VIEW (ev_window->priv->password_view), base_name); - g_free (file_name); + g_object_unref (file); g_free (base_name); ev_window_set_page_mode (ev_window, PAGE_MODE_PASSWORD); ev_window_popup_password_dialog (ev_window); } else { - ev_window_error_dialog (GTK_WINDOW (ev_window), - _("Unable to open document"), - job->error); + ev_window_error_message (GTK_WINDOW (ev_window), + _("Unable to open document"), + job->error); ev_window_clear_load_job (ev_window); ev_window->priv->in_reload = FALSE; } @@ -1403,44 +1415,23 @@ ev_window_close_dialogs (EvWindow *ev_window) gtk_widget_destroy (ev_window->priv->password_dialog); ev_window->priv->password_dialog = NULL; -#ifdef WITH_PRINT if (ev_window->priv->print_dialog) gtk_widget_destroy (ev_window->priv->print_dialog); ev_window->priv->print_dialog = NULL; -#endif - -#ifdef WITH_GNOME_PRINT - if (ev_window->priv->print_job) - g_object_unref (ev_window->priv->print_job); - ev_window->priv->print_job = NULL; -#endif if (ev_window->priv->properties) gtk_widget_destroy (ev_window->priv->properties); ev_window->priv->properties = NULL; } -static gint -open_xfer_update_progress_callback (GnomeVFSAsyncHandle *handle, - GnomeVFSXferProgressInfo *info, - EvWindow *ev_window) -{ - switch (info->status) { - case GNOME_VFS_XFER_PROGRESS_STATUS_OK: - if (info->phase == GNOME_VFS_XFER_PHASE_COMPLETED) { - ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH); - } - - return 1; - case GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR: - case GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE: - case GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE: - return 1; - default: - g_assert_not_reached (); - } - - return 0; +static void +window_open_file_copy_ready_cb (GFile *source, + GAsyncResult *async_result, + EvWindow *ev_window) +{ + g_file_copy_finish (source, async_result, NULL); + ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH); + g_object_unref (source); } void @@ -1448,11 +1439,17 @@ ev_window_open_uri (EvWindow *ev_window, const char *uri, EvLinkDest *dest, EvWindowRunMode mode, + const gchar *search_string, gboolean unlink_temp_file, const gchar *print_settings) { - GnomeVFSURI *source_uri; - GnomeVFSURI *target_uri; + GFile *source_file; + GFile *target_file; + + if (ev_window->priv->uri && + g_ascii_strcasecmp (ev_window->priv->uri, uri) == 0) { + ev_window->priv->in_reload = TRUE; + } ev_window_close_dialogs (ev_window); ev_window_clear_load_job (ev_window); @@ -1473,54 +1470,40 @@ ev_window_open_uri (EvWindow *ev_window, setup_size_from_metadata (ev_window); - ev_window->priv->load_job = ev_job_load_new (uri, dest, mode); + ev_window->priv->load_job = ev_job_load_new (uri, dest, mode, search_string); g_signal_connect (ev_window->priv->load_job, "finished", G_CALLBACK (ev_window_load_job_cb), ev_window); - source_uri = gnome_vfs_uri_new (uri); - if (!gnome_vfs_uri_is_local (source_uri) && !ev_window->priv->local_uri) { - GnomeVFSAsyncHandle *handle; - GList *slist = NULL; - GList *tlist = NULL; - char *tmp_name; - char *base_name; + source_file = g_file_new_for_uri (uri); + if (!g_file_is_native (source_file) && !ev_window->priv->local_uri) { + char *tmp_name; + char *base_name; /* We'd like to keep extension of source uri since * it helps to resolve some mime types, say cbz */ tmp_name = ev_tmp_filename (NULL); - base_name = gnome_vfs_uri_extract_short_name (source_uri); + base_name = g_file_get_basename (source_file); ev_window->priv->local_uri = g_strconcat ("file:", tmp_name, "-", base_name, NULL); ev_job_load_set_uri (EV_JOB_LOAD (ev_window->priv->load_job), ev_window->priv->local_uri); g_free (base_name); g_free (tmp_name); - target_uri = gnome_vfs_uri_new (ev_window->priv->local_uri); - - slist = g_list_prepend (slist, source_uri); - tlist = g_list_prepend (tlist, target_uri); - gnome_vfs_async_xfer (&handle, slist, tlist, - GNOME_VFS_XFER_DEFAULT | GNOME_VFS_XFER_FOLLOW_LINKS, - GNOME_VFS_XFER_ERROR_MODE_ABORT, - GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, - GNOME_VFS_PRIORITY_DEFAULT, - (GnomeVFSAsyncXferProgressCallback) - open_xfer_update_progress_callback, - ev_window, - NULL, NULL); - - g_list_free (slist); - g_list_free (tlist); - gnome_vfs_uri_unref (target_uri); - gnome_vfs_uri_unref (source_uri); - + target_file = g_file_new_for_uri (ev_window->priv->local_uri); + + g_file_copy_async (source_file, target_file, + 0, G_PRIORITY_DEFAULT, NULL, + NULL, NULL, /* no progress callback */ + (GAsyncReadyCallback) window_open_file_copy_ready_cb, + ev_window); + g_object_unref (target_file); return; } - gnome_vfs_uri_unref (source_uri); + g_object_unref (source_file); ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH); } @@ -1574,20 +1557,11 @@ ev_window_cmd_file_open (GtkAction *action, EvWindow *window) gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (chooser), window->priv->uri); } else { -#if GLIB_CHECK_VERSION (2, 13, 3) const gchar *folder; folder = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), folder ? folder : g_get_home_dir ()); -#else - char *folder; - - folder = xdg_user_dir_lookup ("DOCUMENTS"); - gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), - folder); - free (folder); -#endif } g_signal_connect (chooser, "response", @@ -1654,9 +1628,9 @@ ev_window_cmd_file_open_copy_at_dest (EvWindow *window, EvLinkDest *dest) new_filename = ev_window_create_tmp_symlink (old_filename, &error); if (error) { - ev_window_error_dialog (GTK_WINDOW (window), - _("Cannot open a copy."), - error); + ev_window_error_message (GTK_WINDOW (window), + _("Cannot open a copy."), + error); g_error_free (error); g_free (old_filename); @@ -1675,6 +1649,7 @@ ev_window_cmd_file_open_copy_at_dest (EvWindow *window, EvLinkDest *dest) gtk_window_get_screen (GTK_WINDOW (window)), dest, 0, + NULL, TRUE, NULL, GDK_CURRENT_TIME); @@ -1696,10 +1671,9 @@ ev_window_cmd_file_open_copy (GtkAction *action, EvWindow *window) g_object_unref (dest); } -#ifdef HAVE_GTK_RECENT static void -ev_window_cmd_recent_file_activate (GtkAction *action, - EvWindow *window) +ev_window_cmd_recent_file_activate (GtkAction *action, + EvWindow *window) { GtkRecentInfo *info; const gchar *uri; @@ -1711,46 +1685,27 @@ ev_window_cmd_recent_file_activate (GtkAction *action, ev_application_open_uri_at_dest (EV_APP, uri, gtk_window_get_screen (GTK_WINDOW (window)), - NULL, 0, FALSE, NULL, + NULL, 0, NULL, FALSE, NULL, GDK_CURRENT_TIME); } -#else + static void -ev_window_cmd_recent_file_activate (GtkAction *action, - EvWindow *ev_window) +ev_window_open_recent_action_item_activated (EvOpenRecentAction *action, + const gchar *uri, + EvWindow *window) { - char *uri; - EggRecentItem *item; - - item = egg_recent_view_uimanager_get_item (ev_window->priv->recent_view, - action); - - uri = egg_recent_item_get_uri (item); - ev_application_open_uri_at_dest (EV_APP, uri, - gtk_window_get_screen (GTK_WINDOW (ev_window)), - NULL, 0, FALSE, NULL, + gtk_window_get_screen (GTK_WINDOW (window)), + NULL, 0, NULL, FALSE, NULL, GDK_CURRENT_TIME); - - g_free (uri); } -#endif /* HAVE_GTK_RECENT */ static void ev_window_add_recent (EvWindow *window, const char *filename) { -#ifdef HAVE_GTK_RECENT gtk_recent_manager_add_item (window->priv->recent_manager, filename); -#else - EggRecentItem *item; - - item = egg_recent_item_new_from_uri (filename); - egg_recent_item_add_group (item, "Evince"); - egg_recent_model_add_full (ev_application_get_recent_model (EV_APP), item); -#endif /* HAVE_GTK_RECENT */ } -#ifdef HAVE_GTK_RECENT static gint compare_recent_items (GtkRecentInfo *a, GtkRecentInfo *b) { @@ -1775,7 +1730,6 @@ compare_recent_items (GtkRecentInfo *a, GtkRecentInfo *b) return 0; } -#endif /* HAVE_GTK_RECENT */ /* * Doubles underscore to avoid spurious menu accels. @@ -1787,12 +1741,15 @@ ev_window_get_recent_file_label (gint index, const gchar *filename) gint length; const gchar *p; const gchar *end; - + gboolean is_rtl; + + is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL); + g_return_val_if_fail (filename != NULL, NULL); length = strlen (filename); str = g_string_sized_new (length + 10); - g_string_printf (str, "_%d. ", index); + g_string_printf (str, "%s_%d. ", is_rtl ? "\xE2\x80\x8F" : "", index); p = filename; end = filename + length; @@ -1819,7 +1776,6 @@ ev_window_get_recent_file_label (gint index, const gchar *filename) static void ev_window_setup_recent (EvWindow *ev_window) { -#ifdef HAVE_GTK_RECENT GList *items, *l; guint n_items = 0; const gchar *evince = g_get_application_name (); @@ -1894,97 +1850,55 @@ ev_window_setup_recent (EvWindow *ev_window) g_list_foreach (items, (GFunc) gtk_recent_info_unref, NULL); g_list_free (items); -#else /* HAVE_GTK_RECENT */ - ev_window->priv->recent_view = egg_recent_view_uimanager_new (ev_window->priv->ui_manager, - "/MainMenu/FileMenu/RecentFilesMenu", - G_CALLBACK (ev_window_cmd_recent_file_activate), - ev_window); - - egg_recent_view_uimanager_show_icons (EGG_RECENT_VIEW_UIMANAGER (ev_window->priv->recent_view), FALSE); - - egg_recent_view_set_model (EGG_RECENT_VIEW (ev_window->priv->recent_view), - ev_application_get_recent_model (EV_APP)); - - egg_recent_view_uimanager_set_trailing_sep (ev_window->priv->recent_view, TRUE); - - g_signal_connect (ev_window->priv->recent_view, "activate", - G_CALLBACK (ev_window_cmd_recent_file_activate), ev_window); -#endif /* HAVE_GTK_RECENT */ } -static gint -save_xfer_update_progress_callback (GnomeVFSAsyncHandle *handle, - GnomeVFSXferProgressInfo *info, - GnomeVFSURI *tmp_uri) -{ - switch (info->status) { - case GNOME_VFS_XFER_PROGRESS_STATUS_OK: - if (info->phase == GNOME_VFS_XFER_PHASE_COMPLETED) { - gchar *uri; - - uri = gnome_vfs_uri_to_string (tmp_uri, 0); - ev_tmp_uri_unlink (uri); - g_free (uri); - gnome_vfs_uri_unref (tmp_uri); - } - return 1; - case GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR: - if (info->vfs_status != GNOME_VFS_OK) { - GtkWidget *dialog; - gchar *uri; - - dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - _("The file could not be saved as “%s”."), - info->target_name); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - gnome_vfs_result_to_string (info->vfs_status)); - - g_signal_connect (dialog, "response", - G_CALLBACK (gtk_widget_destroy), - NULL); - gtk_widget_show (dialog); - - uri = gnome_vfs_uri_to_string (tmp_uri, 0); - ev_tmp_uri_unlink (uri); - g_free (uri); - gnome_vfs_uri_unref (tmp_uri); - } - return 1; - case GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE: - case GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE: - return 1; - default: - g_assert_not_reached (); +static void +window_save_file_copy_ready_cb (GFile *src, + GAsyncResult *async_result, + GFile *dst) +{ + EvWindow *window; + GtkWidget *dialog; + gchar *name; + GError *error = NULL; + + if (g_file_copy_finish (src, async_result, &error)) { + ev_tmp_file_unlink (src); + return; } - return 0; + window = g_object_get_data (G_OBJECT (dst), "ev-window"); + name = g_file_get_basename (dst); + dialog = gtk_message_dialog_new (GTK_WINDOW (window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _("The file could not be saved as “%s”."), + name); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + error->message); + g_signal_connect (dialog, "response", + G_CALLBACK (gtk_widget_destroy), + NULL); + gtk_widget_show (dialog); + ev_tmp_file_unlink (src); + + g_free (name); + g_error_free (error); } static void -ev_window_save_remote (EvWindow *ev_window, - GnomeVFSURI *src, - GnomeVFSURI *dst) +ev_window_save_remote (EvWindow *ev_window, + GFile *src, + GFile *dst) { - GnomeVFSAsyncHandle *handle; - GList *slist = NULL; - GList *tlist = NULL; - - slist = g_list_prepend (slist, src); - tlist = g_list_prepend (tlist, dst); - gnome_vfs_async_xfer (&handle, slist, tlist, - GNOME_VFS_XFER_DEFAULT | GNOME_VFS_XFER_FOLLOW_LINKS, - GNOME_VFS_XFER_ERROR_MODE_ABORT, - GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, - GNOME_VFS_PRIORITY_DEFAULT, - (GnomeVFSAsyncXferProgressCallback) - save_xfer_update_progress_callback, - gnome_vfs_uri_ref (src), - NULL, NULL); - g_list_free (slist); - g_list_free (tlist); + g_object_set_data (G_OBJECT (dst), "ev-window", ev_window); + g_file_copy_async (src, dst, + G_FILE_COPY_OVERWRITE, + G_PRIORITY_DEFAULT, NULL, + NULL, NULL, /* no progress callback */ + (GAsyncReadyCallback) window_save_file_copy_ready_cb, + dst); } static void @@ -2010,7 +1924,7 @@ ev_window_save_job_cb (EvJobSave *job, gchar *msg; msg = g_strdup_printf (_("The file could not be saved as “%s”."), job->uri); - ev_window_error_dialog (GTK_WINDOW (window), msg, job->error); + ev_window_error_message (GTK_WINDOW (window), msg, job->error); g_free (msg); } @@ -2050,12 +1964,8 @@ ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window) { GtkWidget *fc; gchar *base_name; - gchar *file_name; -#if GLIB_CHECK_VERSION (2, 13, 3) + GFile *file; const gchar *folder; -#else - gchar *folder; -#endif fc = gtk_file_chooser_dialog_new ( _("Save a Copy"), @@ -2068,22 +1978,16 @@ ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window) gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (fc), FALSE); - gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE); - file_name = gnome_vfs_format_uri_for_display (ev_window->priv->uri); - base_name = g_path_get_basename (file_name); + gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE); + file = g_file_new_for_uri (ev_window->priv->uri); + base_name = g_file_get_basename (file); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (fc), base_name); -#if GLIB_CHECK_VERSION (2, 13, 3) folder = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (fc), folder ? folder : g_get_home_dir ()); -#else - folder = xdg_user_dir_lookup ("DOCUMENTS"); - gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (fc), folder); - free (folder); -#endif - g_free (file_name); + g_object_unref (file); g_free (base_name); g_signal_connect (fc, "response", @@ -2093,7 +1997,6 @@ ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window) gtk_widget_show (fc); } -#ifdef WITH_GTK_PRINT static void ev_window_print_page_setup_done_cb (GtkPageSetup *page_setup, EvWindow *window) @@ -2106,22 +2009,18 @@ ev_window_print_page_setup_done_cb (GtkPageSetup *page_setup, g_object_unref (window->priv->print_page_setup); window->priv->print_page_setup = g_object_ref (page_setup); } -#endif /* WITH_GTK_PRINT */ static void ev_window_cmd_file_print_setup (GtkAction *action, EvWindow *ev_window) { -#ifdef WITH_GTK_PRINT gtk_print_run_page_setup_dialog_async ( GTK_WINDOW (ev_window), ev_window->priv->print_page_setup, ev_window->priv->print_settings, (GtkPageSetupDoneFunc) ev_window_print_page_setup_done_cb, ev_window); -#endif /* WITH_GTK_PRINT */ } -#ifdef WITH_GTK_PRINT static void ev_window_clear_print_job (EvWindow *window) { @@ -2142,6 +2041,40 @@ ev_window_clear_print_job (EvWindow *window) } } +static void +ev_window_load_print_settings_from_metadata (EvWindow *window) +{ + gchar *uri = window->priv->uri; + gint i; + + /* Load print setting that are specific to the document */ + for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) { + GValue value = { 0, }; + gboolean success; + + success = ev_metadata_manager_get (uri, document_print_settings[i], &value, TRUE); + gtk_print_settings_set (window->priv->print_settings, + document_print_settings[i], + success ? g_value_get_string (&value) : NULL); + } +} + +static void +ev_window_save_print_settings (EvWindow *window) +{ + gchar *uri = window->priv->uri; + gint i; + + /* Save print settings that are specific to the document */ + for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) { + const gchar *value; + + value = gtk_print_settings_get (window->priv->print_settings, + document_print_settings[i]); + ev_metadata_manager_set_string (uri, document_print_settings[i], value); + } +} + static void ev_window_print_finished (GtkPrintJob *print_job, EvWindow *window, @@ -2166,6 +2099,7 @@ ev_window_print_finished (GtkPrintJob *print_job, /* If printed successfully, save print settings */ ev_application_set_print_settings (EV_APP, window->priv->print_settings); + ev_window_save_print_settings (window); } } @@ -2219,6 +2153,7 @@ ev_window_print_send (EvWindow *window, gtk_window_get_screen (GTK_WINDOW (window)), NULL, EV_WINDOW_MODE_PREVIEW, + NULL, TRUE, print_settings_file, GDK_CURRENT_TIME); @@ -2349,7 +2284,17 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog, ranges = g_memdup (page_range, n_ranges * sizeof (GtkPageRange)); } break; - default: + case GTK_PRINT_PAGES_ALL: { + gint n_pages; + + n_pages = ev_page_cache_get_n_pages (ev_page_cache_get (window->priv->document)); + + ranges = g_new0 (EvPrintRange, 1); + + ranges->start = 0; + ranges->end = n_pages - 1; + n_ranges = 1; + } break; } @@ -2416,8 +2361,9 @@ ev_window_print_range (EvWindow *ev_window, int first_page, int last_page) document_last_page = ev_page_cache_get_n_pages (page_cache); if (!ev_window->priv->print_settings) { - ev_window->priv->print_settings = g_object_ref ( + ev_window->priv->print_settings = gtk_print_settings_copy ( ev_application_get_print_settings (EV_APP)); + ev_window_load_print_settings_from_metadata (ev_window); } if (first_page != 1 || last_page != document_last_page) { @@ -2457,124 +2403,6 @@ ev_window_print_range (EvWindow *ev_window, int first_page, int last_page) gtk_widget_show (dialog); } -#endif /* WITH_GTK_PRINT */ - -#ifdef WITH_GNOME_PRINT -static gboolean -ev_window_print_dialog_response_cb (GtkDialog *print_dialog, - gint response, - EvWindow *ev_window) -{ - EvPrintJob *print_job; - GnomePrintConfig *config; - - if (response != GNOME_PRINT_DIALOG_RESPONSE_PRINT) { - gtk_widget_destroy (GTK_WIDGET (print_dialog)); - ev_window->priv->print_dialog = NULL; - g_object_unref (ev_window->priv->print_job); - ev_window->priv->print_job = NULL; - - return FALSE; - } - - config = gnome_print_dialog_get_config (GNOME_PRINT_DIALOG (print_dialog)); - - /* FIXME: Change this when we have the first backend - * that can print more than postscript - */ - if (using_pdf_printer (config)) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (GTK_WINDOW (print_dialog), GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - _("Generating PDF is not supported")); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - return FALSE; - } else if (!using_postscript_printer (config)) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (GTK_WINDOW (print_dialog), GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - _("Printing is not supported on this printer.")); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - _("You were trying to print to a printer using the “%s” driver. " - "This program requires a PostScript printer driver."), - gnome_print_config_get (config, (guchar *)"Settings.Engine.Backend.Driver")); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - return FALSE; - } - - save_print_config_to_file (config); - - print_job = g_object_new (EV_TYPE_PRINT_JOB, - "gnome_print_job", ev_window->priv->print_job, - "document", ev_window->priv->document, - "print_dialog", print_dialog, - NULL); - - if (print_job != NULL) { - ev_print_job_print (print_job, GTK_WINDOW (ev_window)); - g_object_unref (print_job); - } - - g_object_unref (config); - - gtk_widget_destroy (GTK_WIDGET (print_dialog)); - ev_window->priv->print_dialog = NULL; - g_object_unref (ev_window->priv->print_job); - ev_window->priv->print_job = NULL; - - return FALSE; -} - -void -ev_window_print_range (EvWindow *ev_window, int first_page, int last_page) -{ - GnomePrintConfig *config; - gchar *pages_label; - - g_return_if_fail (EV_IS_WINDOW (ev_window)); - g_return_if_fail (ev_window->priv->document != NULL); - - config = load_print_config_from_file (); - - if (ev_window->priv->print_job == NULL) - ev_window->priv->print_job = gnome_print_job_new (config); - - if (ev_window->priv->print_dialog == NULL) { - ev_window->priv->print_dialog = - gnome_print_dialog_new (ev_window->priv->print_job, - (guchar *) _("Print"), - (GNOME_PRINT_DIALOG_RANGE | - GNOME_PRINT_DIALOG_COPIES)); - } - - gtk_window_set_transient_for (GTK_WINDOW (ev_window->priv->print_dialog), - GTK_WINDOW (ev_window)); - g_object_unref (config); - - pages_label = g_strconcat (_("Pages"), " ", NULL); - gnome_print_dialog_construct_range_page (GNOME_PRINT_DIALOG (ev_window->priv->print_dialog), - GNOME_PRINT_RANGE_ALL | - GNOME_PRINT_RANGE_RANGE, - first_page, last_page, - NULL, (const guchar *)pages_label); - g_free (pages_label); - - gtk_dialog_set_response_sensitive (GTK_DIALOG (ev_window->priv->print_dialog), - GNOME_PRINT_DIALOG_RESPONSE_PREVIEW, - FALSE); - - g_signal_connect (G_OBJECT (ev_window->priv->print_dialog), "response", - G_CALLBACK (ev_window_print_dialog_response_cb), - ev_window); - gtk_widget_show (ev_window->priv->print_dialog); -} -#endif /* WITH_GNOME_PRINT */ static void ev_window_print (EvWindow *window) @@ -2585,9 +2413,7 @@ ev_window_print (EvWindow *window) page_cache = ev_page_cache_get (window->priv->document); last_page = ev_page_cache_get_n_pages (page_cache); -#ifdef WITH_PRINT ev_window_print_range (window, 1, last_page); -#endif } static void @@ -2795,6 +2621,27 @@ fullscreen_toolbar_setup_item_properties (GtkUIManager *ui_manager) g_object_set (item, "is-important", TRUE, NULL); } +static void +fullscreen_toolbar_remove_shadow (GtkWidget *toolbar) +{ + static gboolean done = FALSE; + + if (!done) { + gtk_rc_parse_string ( + "\n" + " style \"fullscreen-toolbar-style\"\n" + " {\n" + " GtkToolbar::shadow-type=GTK_SHADOW_NONE\n" + " }\n" + "\n" + " widget \"*.fullscreen-toolbar\" style \"fullscreen-toolbar-style\"\n" + "\n"); + done = TRUE; + } + + gtk_widget_set_name (toolbar, "fullscreen-toolbar"); +} + static void ev_window_run_fullscreen (EvWindow *window) { @@ -2805,6 +2652,7 @@ ev_window_run_fullscreen (EvWindow *window) gtk_toolbar_set_style (GTK_TOOLBAR (window->priv->fullscreen_toolbar), GTK_TOOLBAR_BOTH_HORIZ); + fullscreen_toolbar_remove_shadow (window->priv->fullscreen_toolbar); fullscreen_toolbar_setup_item_properties (window->priv->ui_manager); gtk_box_pack_start (GTK_BOX (window->priv->main_box), @@ -2894,15 +2742,9 @@ presentation_set_timeout (EvWindow *window) g_source_remove (window->priv->presentation_timeout_id); } -#if GLIB_CHECK_VERSION (2, 13, 0) window->priv->presentation_timeout_id = g_timeout_add_seconds (PRESENTATION_TIMEOUT, (GSourceFunc)presentation_timeout_cb, window); -#else - window->priv->presentation_timeout_id = - g_timeout_add (PRESENTATION_TIMEOUT * 1000, - (GSourceFunc)presentation_timeout_cb, window); -#endif ev_view_show_cursor (EV_VIEW (window->priv->view)); } @@ -3264,13 +3106,17 @@ ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window) { gchar *uri; - ev_window->priv->in_reload = TRUE; - uri = g_strdup (ev_window->priv->uri); - ev_window_open_uri (ev_window, uri, NULL, 0, FALSE, NULL); + ev_window_open_uri (ev_window, uri, NULL, 0, NULL, FALSE, NULL); g_free (uri); } +static void +ev_window_cmd_view_autoscroll (GtkAction *action, EvWindow *ev_window) +{ + ev_view_autoscroll_start (EV_VIEW (ev_window->priv->view)); +} + static void ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window) { @@ -3299,6 +3145,8 @@ ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window) if (g_file_test (uri, G_FILE_TEST_EXISTS)) { break; } + g_free (uri); + uri = NULL; } if (uri == NULL) { @@ -3331,9 +3179,6 @@ ev_window_cmd_start_presentation (GtkAction *action, EvWindow *window) ev_window_run_presentation (window); } -#ifdef WITH_GTK_PRINT -static void ev_window_do_preview_print (EvWindow *window); - static gboolean ev_window_enumerate_printer_cb (GtkPrinter *printer, EvWindow *window) @@ -3425,12 +3270,9 @@ ev_window_do_preview_print (EvWindow *window) gtk_widget_hide (GTK_WIDGET (window)); } -#endif /* WITH_GTK_PRINT */ - static void ev_window_cmd_preview_print (GtkAction *action, EvWindow *window) { -#ifdef WITH_GTK_PRINT EvWindowPrivate *priv = window->priv; GtkPrintSettings *print_settings = NULL; #if GTK_CHECK_VERSION (2, 11, 0) @@ -3461,7 +3303,6 @@ ev_window_cmd_preview_print (GtkAction *action, EvWindow *window) gtk_enumerate_printers ((GtkPrinterFunc) ev_window_enumerate_printer_cb, window, NULL, FALSE); -#endif /* WITH_GTK_PRINT */ } static void @@ -3469,6 +3310,8 @@ ev_window_cmd_escape (GtkAction *action, EvWindow *window) { GtkWidget *widget; + ev_view_autoscroll_stop (EV_VIEW (window->priv->view)); + 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, FALSE); @@ -3626,6 +3469,7 @@ ev_window_rotation_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *window ev_sidebar_thumbnails_refresh (EV_SIDEBAR_THUMBNAILS (window->priv->sidebar_thumbs), rotation); + ev_window_refresh_window_thumbnail (window, rotation); } static void @@ -4103,7 +3947,6 @@ ev_window_dispose (GObject *object) priv->attachment_popup_action_group = NULL; } -#ifdef HAVE_GTK_RECENT if (priv->recent_action_group) { g_object_unref (priv->recent_action_group); priv->recent_action_group = NULL; @@ -4117,12 +3960,6 @@ ev_window_dispose (GObject *object) } priv->recent_ui_id = 0; -#else - if (priv->recent_view) { - g_object_unref (priv->recent_view); - priv->recent_view = NULL; - } -#endif /* HAVE_GTK_RECENT */ if (priv->page_cache) { g_signal_handlers_disconnect_by_func (priv->page_cache, page_changed_cb, window); @@ -4162,8 +3999,6 @@ ev_window_dispose (GObject *object) } ev_window_close_dialogs (window); - -#ifdef WITH_GTK_PRINT ev_window_clear_print_job (window); if (window->priv->gtk_print_job) { @@ -4185,7 +4020,6 @@ ev_window_dispose (GObject *object) g_object_unref (window->priv->print_page_setup); window->priv->print_page_setup = NULL; } -#endif if (priv->link) { g_object_unref (priv->link); @@ -4289,11 +4123,7 @@ static const GtkActionEntry entries[] = { /* Edit menu */ { "EditCopy", GTK_STOCK_COPY, NULL, "C", NULL, G_CALLBACK (ev_window_cmd_edit_copy) }, -#ifdef HAVE_GTK_RECENT { "EditSelectAll", GTK_STOCK_SELECT_ALL, N_("Select _All"), "A", NULL, -#else - { "EditSelectAll", NULL, N_("Select _All"), "A", NULL, -#endif /* HAVE_GTK_RECENT */ G_CALLBACK (ev_window_cmd_edit_select_all) }, { "EditFind", GTK_STOCK_FIND, N_("_Find..."), "F", N_("Find a word or phrase in the document"), @@ -4320,17 +4150,20 @@ static const GtkActionEntry entries[] = { N_("Reload the document"), G_CALLBACK (ev_window_cmd_view_reload) }, + { "ViewAutoscroll", GTK_STOCK_MEDIA_PLAY, N_("Auto_scroll"), NULL, NULL, + G_CALLBACK (ev_window_cmd_view_autoscroll) }, + /* Go menu */ - { "GoPreviousPage", GTK_STOCK_GO_BACK, N_("_Previous Page"), "Page_Up", + { "GoPreviousPage", GTK_STOCK_GO_UP, N_("_Previous Page"), "Page_Up", N_("Go to the previous page"), G_CALLBACK (ev_window_cmd_go_previous_page) }, - { "GoNextPage", GTK_STOCK_GO_FORWARD, N_("_Next Page"), "Page_Down", + { "GoNextPage", GTK_STOCK_GO_DOWN, N_("_Next Page"), "Page_Down", N_("Go to the next page"), G_CALLBACK (ev_window_cmd_go_next_page) }, - { "GoFirstPage", GTK_STOCK_GOTO_FIRST, N_("_First Page"), "Home", + { "GoFirstPage", GTK_STOCK_GOTO_TOP, N_("_First Page"), "Home", N_("Go to the first page"), G_CALLBACK (ev_window_cmd_go_first_page) }, - { "GoLastPage", GTK_STOCK_GOTO_LAST, N_("_Last Page"), "End", + { "GoLastPage", GTK_STOCK_GOTO_BOTTOM, N_("_Last Page"), "End", N_("Go to the last page"), G_CALLBACK (ev_window_cmd_go_last_page) }, @@ -4415,7 +4248,7 @@ static const GtkToggleActionEntry toggle_entries[] = { { "ViewFullscreen", GTK_STOCK_FULLSCREEN, N_("_Fullscreen"), "F11", N_("Expand the window to fill the screen"), G_CALLBACK (ev_window_cmd_view_fullscreen) }, - { "ViewPresentation", EV_STOCK_RUN_PRESENTATION, N_("_Presentation"), "F5", + { "ViewPresentation", EV_STOCK_RUN_PRESENTATION, N_("Pre_sentation"), "F5", N_("Run document as a presentation"), G_CALLBACK (ev_window_cmd_view_presentation) }, { "ViewBestFit", EV_STOCK_ZOOM_PAGE, N_("_Best Fit"), NULL, @@ -4506,12 +4339,27 @@ register_custom_actions (EvWindow *window, GtkActionGroup *group) "is_important", TRUE, "short_label", _("Back"), "stock_id", GTK_STOCK_GO_DOWN, + /*translators: this is the history action*/ "tooltip", _("Move across visited pages"), NULL); g_signal_connect (action, "activate_link", G_CALLBACK (navigation_action_activate_link_cb), window); gtk_action_group_add_action (group, action); g_object_unref (action); + + action = g_object_new (EV_TYPE_OPEN_RECENT_ACTION, + "name", "FileOpenRecent", + "label", _("_Open..."), + "tooltip", _("Open an existing document"), + "stock_id", GTK_STOCK_OPEN, + NULL); + g_signal_connect (action, "activate", + G_CALLBACK (ev_window_cmd_file_open), window); + g_signal_connect (action, "item_activated", + G_CALLBACK (ev_window_open_recent_action_item_activated), + window); + gtk_action_group_add_action (group, action); + g_object_unref (action); } static void @@ -4676,75 +4524,98 @@ static void launch_action (EvWindow *window, EvLinkAction *action) { const char *filename = ev_link_action_get_filename (action); - char *uri = NULL; + const char *content_type; + GAppInfo *app_info; + GFileInfo *file_info; + GFile *file; + GList *file_list = NULL; + + if (filename == NULL) + return; - if (filename && g_path_is_absolute (filename)) { - uri = gnome_vfs_get_uri_from_local_path (filename); + if (g_path_is_absolute (filename)) { + file = g_file_new_for_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); - } + GFile *base_file; + + base_file = g_file_new_for_uri (window->priv->uri); + file = g_file_resolve_relative_path (base_file, + filename); + + g_object_unref (base_file); } - - if (uri) { - gnome_vfs_url_show (uri); - } else { - gnome_vfs_url_show (filename); + + file_info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + 0, NULL, NULL); + if (file_info == NULL) { + g_object_unref (file); + return; } + + content_type = g_file_info_get_content_type (file_info); + app_info = g_app_info_get_default_for_type (content_type, TRUE); + + file_list = g_list_append (file_list, file); - g_free (uri); + /* FIXME: should we use a GAppLaunchContext? */ + g_app_info_launch (app_info, file_list, + NULL, NULL); + + g_list_free (file_list); + g_object_unref (app_info); + g_object_unref (file_info); + g_object_unref (file); /* 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 gboolean -uri_is_valid (const gchar *uri) -{ - gchar *p = (gchar *) uri; - - if (!p || !g_ascii_isalpha (*p)) - return FALSE; - - p++; - while (g_ascii_isalnum (*p)) - p++; - - return (g_ascii_strncasecmp (p, "://", strlen ("://")) == 0); -} - static void launch_external_uri (EvWindow *window, EvLinkAction *action) { const gchar *uri = ev_link_action_get_uri (action); + const char *content_type; + GFile *file; + GFileInfo *file_info; + GAppInfo *app; + GList *file_list = NULL; + GError *error = NULL; + + file = g_file_new_for_uri (uri); + file_info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + 0, NULL, NULL); + if (file_info == NULL) { + g_object_unref (file); + return; + } + + content_type = g_file_info_get_content_type (file_info); + app = g_app_info_get_default_for_type (content_type, TRUE); + g_object_unref (file_info); - if (!uri_is_valid (uri)) { + file_list = g_list_append (file_list, file); + + if (!g_app_info_launch (app, file_list, NULL, &error)) { GtkWidget *dialog; - + dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Unable to open external link")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - _("Invalid URI: “%s”"), uri); + error->message, uri); g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); - - return; } - - gnome_vfs_url_show (uri); + + g_object_unref (app); + g_object_unref (file); + g_list_free (file_list); } static void @@ -4763,6 +4634,7 @@ open_remote_link (EvWindow *window, EvLinkAction *action) gtk_window_get_screen (GTK_WINDOW (window)), ev_link_action_get_dest (action), 0, + NULL, FALSE, NULL, GDK_CURRENT_TIME); @@ -4869,16 +4741,23 @@ ev_view_popup_cmd_copy_link_address (GtkAction *action, EvWindow *window) gtk_clipboard_set_text (clipboard, uri, -1); } + static void image_save_dialog_response_cb (GtkWidget *fc, gint response_id, EvWindow *ev_window) { - GnomeVFSURI *target_uri; - gchar *uri; - gchar *filename; - gboolean is_local; - GError *error = NULL; + GFile *target_file; + gboolean is_native; + GError *error = NULL; + GdkPixbuf *pixbuf; + gchar *uri; + gchar *uri_extension; + gchar **extensions; + gchar *filename; + gchar *file_format; + GdkPixbufFormat *format; + GtkFileFilter *filter; if (response_id != GTK_RESPONSE_OK) { gtk_widget_destroy (fc); @@ -4886,54 +4765,79 @@ image_save_dialog_response_cb (GtkWidget *fc, } uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc)); - target_uri = gnome_vfs_uri_new (uri); - is_local = gnome_vfs_uri_is_local (target_uri); + filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (fc)); + format = g_object_get_data (G_OBJECT (filter), "pixbuf-format"); + + if (format == NULL) { + format = get_gdk_pixbuf_format_by_extension (uri); + } + + if (format == NULL) { + ev_window_error_message (GTK_WINDOW (ev_window), + _("Couldn't find appropriate format to save image"), + NULL); + g_free (uri); + gtk_widget_destroy (fc); + + return; + } + + extensions = gdk_pixbuf_format_get_extensions (format); + uri_extension = g_strconcat (uri, ".", extensions[0], NULL); + g_strfreev(extensions); + file_format = gdk_pixbuf_format_get_name (format); - if (is_local) { - filename = g_filename_from_uri (uri, NULL, NULL); + target_file = g_file_new_for_uri (uri_extension); + is_native = g_file_is_native (target_file); + + if (is_native) { + filename = g_file_get_path (target_file); } else { filename = ev_tmp_filename ("saveimage"); } g_free (uri); + g_free (uri_extension); + + ev_document_doc_mutex_lock (); + pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (ev_window->priv->document), + ev_window->priv->image); + ev_document_doc_mutex_unlock (); - /* FIXME: allow saving in other image formats than png */ - gdk_pixbuf_save (ev_image_get_pixbuf (ev_window->priv->image), - filename, "png", &error, NULL); + gdk_pixbuf_save (pixbuf, filename, file_format, &error, NULL); + g_free (file_format); + g_object_unref (pixbuf); if (error) { - ev_window_error_dialog (GTK_WINDOW (ev_window), - _("The image could not be saved."), - error); + ev_window_error_message (GTK_WINDOW (ev_window), + _("The image could not be saved."), + error); g_error_free (error); g_free (filename); - gnome_vfs_uri_unref (target_uri); + g_object_unref (target_file); gtk_widget_destroy (fc); return; } - if (!is_local) { - GnomeVFSURI *source_uri; - gchar *local_uri; - - local_uri = g_filename_to_uri (filename, NULL, NULL); - source_uri = gnome_vfs_uri_new (local_uri); - g_free (local_uri); - ev_window_save_remote (ev_window, source_uri, target_uri); - gnome_vfs_uri_unref (source_uri); + if (!is_native) { + GFile *source_file; + + source_file = g_file_new_for_uri (filename); + + ev_window_save_remote (ev_window, source_file, target_file); + g_object_unref (source_file); } g_free (filename); - gnome_vfs_uri_unref (target_uri); + g_object_unref (target_file); gtk_widget_destroy (fc); } static void ev_view_popup_cmd_save_image_as (GtkAction *action, EvWindow *window) { - GtkWidget *fc; - GtkFileFilter *filter; + GtkWidget *fc; if (!window->priv->image) return; @@ -4949,12 +4853,9 @@ ev_view_popup_cmd_save_image_as (GtkAction *action, EvWindow *window) gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (fc), FALSE); gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE); - - filter = gtk_file_filter_new (); - gtk_file_filter_set_name (filter, _("Images")); - gtk_file_filter_add_pixbuf_formats (filter); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fc), filter); - + + file_chooser_dialog_add_writable_pixbuf_formats (GTK_FILE_CHOOSER (fc)); + g_signal_connect (fc, "response", G_CALLBACK (image_save_dialog_response_cb), window); @@ -4966,14 +4867,20 @@ static void ev_view_popup_cmd_copy_image (GtkAction *action, EvWindow *window) { GtkClipboard *clipboard; + GdkPixbuf *pixbuf; if (!window->priv->image) return; clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_CLIPBOARD); - gtk_clipboard_set_image (clipboard, - ev_image_get_pixbuf (window->priv->image)); + ev_document_doc_mutex_lock (); + pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (window->priv->document), + window->priv->image); + ev_document_doc_mutex_unlock (); + + gtk_clipboard_set_image (clipboard, pixbuf); + g_object_unref (pixbuf); } static void @@ -4993,9 +4900,9 @@ ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window) ev_attachment_open (attachment, &error); if (error) { - ev_window_error_dialog (GTK_WINDOW (window), - _("Unable to open attachment"), - error); + ev_window_error_message (GTK_WINDOW (window), + _("Unable to open attachment"), + error); g_error_free (error); } } @@ -5006,12 +4913,12 @@ attachment_save_dialog_response_cb (GtkWidget *fc, gint response_id, EvWindow *ev_window) { - GnomeVFSURI *target_uri; + GFile *target_file; gchar *uri; GList *l; GtkFileChooserAction fc_action; gboolean is_dir; - gboolean is_local; + gboolean is_native; if (response_id != GTK_RESPONSE_OK) { gtk_widget_destroy (fc); @@ -5019,69 +4926,61 @@ attachment_save_dialog_response_cb (GtkWidget *fc, } uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc)); - target_uri = gnome_vfs_uri_new (uri); + target_file = g_file_new_for_uri (uri); g_object_get (G_OBJECT (fc), "action", &fc_action, NULL); is_dir = (fc_action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); - is_local = gnome_vfs_uri_is_local (target_uri); + is_native = g_file_is_native (target_file); for (l = ev_window->priv->attach_list; l && l->data; l = g_list_next (l)) { EvAttachment *attachment; - gchar *filename; + GFile *save_to; GError *error = NULL; attachment = (EvAttachment *) l->data; - if (is_local) { + if (is_native) { if (is_dir) { - filename = g_strjoin ("/", uri, - ev_attachment_get_name (attachment), - NULL); + save_to = g_file_get_child (target_file, + ev_attachment_get_name (attachment)); } else { - filename = g_strdup (uri); + save_to = g_object_ref (target_file); } } else { - filename = ev_tmp_filename ("saveattachment"); + save_to = ev_tmp_file_get ("saveattachment"); } - ev_attachment_save (attachment, filename, &error); + ev_attachment_save (attachment, save_to, &error); if (error) { - ev_window_error_dialog (GTK_WINDOW (ev_window), - _("The attachment could not be saved."), - error); + ev_window_error_message (GTK_WINDOW (ev_window), + _("The attachment could not be saved."), + error); g_error_free (error); - g_free (filename); + g_object_unref (save_to); continue; } - if (!is_local) { - GnomeVFSURI *src_uri; - GnomeVFSURI *dest_uri; - gchar *local_uri; + if (!is_native) { + GFile *dest_file; if (is_dir) { - const gchar *name = ev_attachment_get_name (attachment); - - dest_uri = gnome_vfs_uri_append_file_name (target_uri, - name); + dest_file = g_file_get_child (target_file, + ev_attachment_get_name (attachment)); } else { - dest_uri = gnome_vfs_uri_ref (target_uri); + dest_file = g_object_ref (target_file); } - - local_uri = g_filename_to_uri (filename, NULL, NULL); - src_uri = gnome_vfs_uri_new (local_uri); - g_free (local_uri); - ev_window_save_remote (ev_window, src_uri, dest_uri); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); + + ev_window_save_remote (ev_window, save_to, dest_file); + + g_object_unref (dest_file); } - g_free (filename); + g_object_unref (save_to); } g_free (uri); - gnome_vfs_uri_unref (target_uri); + g_object_unref (target_file); gtk_widget_destroy (fc); } @@ -5190,7 +5089,6 @@ ev_window_init (EvWindow *ev_window) g_error_free (error); } -#ifdef HAVE_GTK_RECENT #if GTK_CHECK_VERSION(2,11,4) ev_window->priv->recent_manager = gtk_recent_manager_get_default (); #else @@ -5204,8 +5102,7 @@ ev_window_init (EvWindow *ev_window) "changed", G_CALLBACK (ev_window_setup_recent), ev_window); -#endif /* HAVE_GTK_RECENT */ - + ev_window->priv->menubar = gtk_ui_manager_get_widget (ev_window->priv->ui_manager, "/MainMenu"); @@ -5213,7 +5110,6 @@ ev_window_init (EvWindow *ev_window) ev_window->priv->menubar, FALSE, FALSE, 0); - ev_window->priv->toolbar = GTK_WIDGET (g_object_new (EGG_TYPE_EDITABLE_TOOLBAR, "ui-manager", ev_window->priv->ui_manager, @@ -5283,14 +5179,19 @@ ev_window_init (EvWindow *ev_window) ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar), sidebar_widget); + ev_window->priv->view_box = gtk_vbox_new (FALSE, 0); ev_window->priv->scrolled_window = GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW, "shadow-type", GTK_SHADOW_IN, NULL)); + gtk_box_pack_start (GTK_BOX (ev_window->priv->view_box), + ev_window->priv->scrolled_window, + TRUE, TRUE, 0); gtk_widget_show (ev_window->priv->scrolled_window); gtk_paned_add2 (GTK_PANED (ev_window->priv->hpaned), - ev_window->priv->scrolled_window); + ev_window->priv->view_box); + gtk_widget_show (ev_window->priv->view_box); ev_window->priv->view = ev_view_new (); ev_view_set_screen_dpi (EV_VIEW (ev_window->priv->view),