]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-window.c
sv.po: Updated Swedish translation
[evince.git] / shell / ev-window.c
index c53b772b448f761de91ecf50a151ae5285a750b3..4684f7996fbf7d3ff0b3cb35e8fdcee8a08cac7a 100644 (file)
@@ -46,6 +46,7 @@
 #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"
@@ -64,6 +65,7 @@
 #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"
@@ -81,9 +83,7 @@
 #include <glib/gstdio.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
-#include <libgnomevfs/gnome-vfs-async-ops.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
+#include <gio/gio.h>
 #include <gconf/gconf-client.h>
 
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
 
-#if !GLIB_CHECK_VERSION (2, 13, 3)
-char *xdg_user_dir_lookup (char *type);
-#endif
-
 typedef enum {
        PAGE_MODE_DOCUMENT,
        PAGE_MODE_PASSWORD
@@ -119,10 +115,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;
@@ -211,6 +209,19 @@ struct _EvWindowPrivate {
 #define THUMBNAILS_SIDEBAR_ID "thumbnails"
 #define ATTACHMENTS_SIDEBAR_ID "attachments"
 
+#ifdef WITH_GTK_PRINT
+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
+};
+#endif /* WITH_GTK_PRINT */
+
 static void    ev_window_update_actions                (EvWindow         *ev_window);
 static void     ev_window_sidebar_visibility_changed_cb (EvSidebar        *ev_sidebar,
                                                         GParamSpec       *pspec,
@@ -294,7 +305,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;
@@ -376,6 +387,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);
@@ -611,29 +623,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
@@ -1136,6 +1175,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",
@@ -1254,30 +1295,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);
+       file = g_file_new_for_uri (ev_window->priv->uri);
+       tempdir = g_file_new_for_path (g_get_tmp_dir ());
 
-       filename = g_filename_from_uri (ev_window->priv->uri, NULL, NULL);
-       if (!filename)
-               return;
-
-       tempdir = g_get_tmp_dir ();
-       if (g_ascii_strncasecmp (filename, tempdir, strlen (tempdir)) == 0) {
-               g_unlink (filename);
+       if (g_file_contains_file (tempdir, file)) {
+               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.
@@ -1357,23 +1388,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;
        }       
@@ -1426,27 +1458,14 @@ ev_window_close_dialogs (EvWindow *ev_window)
        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
@@ -1458,8 +1477,8 @@ ev_window_open_uri (EvWindow       *ev_window,
                    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) {
@@ -1491,48 +1510,34 @@ ev_window_open_uri (EvWindow       *ev_window,
                          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);
 }
 
@@ -1586,20 +1591,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",
@@ -1666,9 +1662,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);
@@ -1779,12 +1775,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;
@@ -1887,79 +1886,53 @@ ev_window_setup_recent (EvWindow *ev_window)
        g_list_free (items);
 }
 
-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
@@ -1985,7 +1958,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);
        }
 
@@ -2025,12 +1998,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"),
@@ -2043,22 +2012,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",
@@ -2117,6 +2080,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,
@@ -2141,6 +2138,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);
        }
 }
 
@@ -2402,8 +2400,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) {
@@ -2781,6 +2780,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)
 {
@@ -2791,6 +2811,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),
@@ -2880,15 +2901,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));
 }
@@ -3255,6 +3270,12 @@ ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window)
        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)
 {
@@ -3455,6 +3476,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);
@@ -4296,17 +4319,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"), "<control>Page_Up",
+        { "GoPreviousPage", GTK_STOCK_GO_UP, N_("_Previous Page"), "<control>Page_Up",
           N_("Go to the previous page"),
           G_CALLBACK (ev_window_cmd_go_previous_page) },
-        { "GoNextPage", GTK_STOCK_GO_FORWARD, N_("_Next Page"), "<control>Page_Down",
+        { "GoNextPage", GTK_STOCK_GO_DOWN, N_("_Next Page"), "<control>Page_Down",
           N_("Go to the next page"),
           G_CALLBACK (ev_window_cmd_go_next_page) },
-        { "GoFirstPage", GTK_STOCK_GOTO_FIRST, N_("_First Page"), "<control>Home",
+        { "GoFirstPage", GTK_STOCK_GOTO_TOP, N_("_First Page"), "<control>Home",
           N_("Go to the first page"),
           G_CALLBACK (ev_window_cmd_go_first_page) },
-        { "GoLastPage", GTK_STOCK_GOTO_LAST, N_("_Last Page"), "<control>End",
+        { "GoLastPage", GTK_STOCK_GOTO_BOTTOM, N_("_Last Page"), "<control>End",
           N_("Go to the last page"),
           G_CALLBACK (ev_window_cmd_go_last_page) },
 
@@ -4482,6 +4508,7 @@ 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",
@@ -4666,31 +4693,48 @@ 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 */
@@ -4700,37 +4744,47 @@ static void
 launch_external_uri (EvWindow *window, EvLinkAction *action)
 {
        const gchar *uri = ev_link_action_get_uri (action);
-       GnomeVFSResult result = gnome_vfs_url_show (uri);
-       GtkWidget *dialog;
-       gchar* message = NULL;
-
-       switch(result) {
-               case GNOME_VFS_OK:
-                       break;
-               case GNOME_VFS_ERROR_BAD_PARAMETERS:
-                       message = _("Invalid URI: ā€œ%sā€");
-                       break;
-               case GNOME_VFS_ERROR_NOT_SUPPORTED:
-                       message = _("Unsupported URI: ā€œ%sā€");
-                       break;
-               default:
-                       message = _("Unknown error");
+       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;
        }
-       if(message) {
+       
+       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);
+       
+       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),
-                                                         message, uri);
+                                                         error->message, uri);
                g_signal_connect (dialog, "response",
                                  G_CALLBACK (gtk_widget_destroy),
                                  NULL);
                gtk_widget_show (dialog);
-
        }
-       return;
+
+       g_object_unref (app);
+       g_object_unref (file);
+       g_list_free (file_list);
 }
 
 static void
@@ -4856,16 +4910,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);
@@ -4873,54 +4934,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;
@@ -4936,12 +5022,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);
@@ -4953,14 +5036,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
@@ -4980,9 +5069,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);
                }
        }
@@ -4993,12 +5082,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);
@@ -5006,69 +5095,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);
 }
@@ -5267,14 +5348,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),