]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-window.c
Fixes bug #542924. Makes enums static to fix Solaris build.
[evince.git] / shell / ev-window.c
index 4684f7996fbf7d3ff0b3cb35e8fdcee8a08cac7a..d8d48ab13e39d456c8f89202c8f2e32357503f03 100644 (file)
 #include "ev-history.h"
 #include "ev-image.h"
 #include "ev-message-area.h"
 #include "ev-history.h"
 #include "ev-image.h"
 #include "ev-message-area.h"
+#include "ev-mount-operation.h"
+#include "ev-file-monitor.h"
+#ifdef ENABLE_DBUS
+#include "ev-media-player-keys.h"
+#endif /* ENABLE_DBUS */
 
 
-#ifdef WITH_GNOME_PRINT
-#include "ev-print-job.h"
-#include <libgnomeprintui/gnome-print-dialog.h>
-#endif
-
-#ifdef WITH_GTK_PRINT
 #include <gtk/gtkprintunixdialog.h>
 #include <gtk/gtkprintunixdialog.h>
-#endif
 
 #ifdef ENABLE_PDF
 #include <poppler.h>
 
 #ifdef ENABLE_PDF
 #include <poppler.h>
@@ -128,9 +126,7 @@ struct _EvWindowPrivate {
 
        /* Dialogs */
        GtkWidget *properties;
 
        /* Dialogs */
        GtkWidget *properties;
-#ifdef WITH_PRINT
        GtkWidget *print_dialog;
        GtkWidget *print_dialog;
-#endif
        GtkWidget *password_dialog;
 
        /* UI Builders */
        GtkWidget *password_dialog;
 
        /* UI Builders */
@@ -167,6 +163,7 @@ struct _EvWindowPrivate {
        EvLinkDest *dest;
        gboolean unlink_temp_file;
        gboolean in_reload;
        EvLinkDest *dest;
        gboolean unlink_temp_file;
        gboolean in_reload;
+       EvFileMonitor *monitor;
        
        EvDocument *document;
        EvHistory *history;
        
        EvDocument *document;
        EvHistory *history;
@@ -174,21 +171,19 @@ struct _EvWindowPrivate {
        EvWindowPageMode page_mode;
        EvWindowTitle *title;
 
        EvWindowPageMode page_mode;
        EvWindowTitle *title;
 
-       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            *reload_job;
+       EvJob            *thumbnail_job;
+       EvJob            *save_job;
        EvJob            *print_job;
        EvJob            *print_job;
+
+       /* Printing */
        gboolean          print_preview;
        GtkPrintJob      *gtk_print_job;
        GtkPrinter       *printer;
        GtkPrintSettings *print_settings;
        GtkPageSetup     *print_page_setup;
        gboolean          print_preview;
        GtkPrintJob      *gtk_print_job;
        GtkPrinter       *printer;
        GtkPrintSettings *print_settings;
        GtkPageSetup     *print_page_setup;
-#endif
+
 };
 
 #define EV_WINDOW_GET_PRIVATE(object) \
 };
 
 #define EV_WINDOW_GET_PRIVATE(object) \
@@ -209,7 +204,6 @@ struct _EvWindowPrivate {
 #define THUMBNAILS_SIDEBAR_ID "thumbnails"
 #define ATTACHMENTS_SIDEBAR_ID "attachments"
 
 #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,
 static const gchar *document_print_settings[] = {
        GTK_PRINT_SETTINGS_N_COPIES,
        GTK_PRINT_SETTINGS_COLLATE,
@@ -220,7 +214,6 @@ static const gchar *document_print_settings[] = {
        GTK_PRINT_SETTINGS_PAGE_RANGES,
        GTK_PRINT_SETTINGS_PAGE_SET
 };
        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,
 
 static void    ev_window_update_actions                (EvWindow         *ev_window);
 static void     ev_window_sidebar_visibility_changed_cb (EvSidebar        *ev_sidebar,
@@ -230,12 +223,13 @@ static void     ev_window_set_page_mode                 (EvWindow         *windo
                                                         EvWindowPageMode  page_mode);
 static void    ev_window_load_job_cb                   (EvJobLoad        *job,
                                                         gpointer          data);
                                                         EvWindowPageMode  page_mode);
 static void    ev_window_load_job_cb                   (EvJobLoad        *job,
                                                         gpointer          data);
+static void     ev_window_reload_document               (EvWindow         *window);
+static void     ev_window_reload_job_cb                 (EvJobLoad        *job,
+                                                        EvWindow         *window);
 static void     ev_window_set_icon_from_thumbnail       (EvJobThumbnail   *job,
                                                         EvWindow         *ev_window);
 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);
 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,
 static void     ev_window_save_job_cb                   (EvJobSave        *save,
                                                         EvWindow         *window);
 static void     ev_window_sizing_mode_changed_cb        (EvView           *view,
@@ -247,11 +241,13 @@ static void     ev_window_zoom_changed_cb                 (EvView           *view,
 static void     ev_window_add_recent                    (EvWindow         *window,
                                                         const char       *filename);
 static void     ev_window_run_fullscreen                (EvWindow         *window);
 static void     ev_window_add_recent                    (EvWindow         *window,
                                                         const char       *filename);
 static void     ev_window_run_fullscreen                (EvWindow         *window);
-static void     ev_window_stop_fullscreen               (EvWindow         *window);
+static void     ev_window_stop_fullscreen               (EvWindow         *window,
+                                                        gboolean          unfullscreen_window);
 static void     ev_window_cmd_view_fullscreen           (GtkAction        *action,
                                                         EvWindow         *window);
 static void     ev_window_run_presentation              (EvWindow         *window);
 static void     ev_window_cmd_view_fullscreen           (GtkAction        *action,
                                                         EvWindow         *window);
 static void     ev_window_run_presentation              (EvWindow         *window);
-static void     ev_window_stop_presentation             (EvWindow         *window);
+static void     ev_window_stop_presentation             (EvWindow         *window,
+                                                        gboolean          unfullscreen_window);
 static void     ev_window_cmd_view_presentation         (GtkAction        *action,
                                                         EvWindow         *window);
 static void     ev_window_run_preview                   (EvWindow         *window);
 static void     ev_window_cmd_view_presentation         (GtkAction        *action,
                                                         EvWindow         *window);
 static void     ev_window_run_preview                   (EvWindow         *window);
@@ -281,6 +277,9 @@ static void     ev_window_cmd_edit_find                 (GtkAction        *actio
 static void     find_bar_search_changed_cb              (EggFindBar       *find_bar,
                                                         GParamSpec       *param,
                                                         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);
+static void     ev_window_load_file_remote              (EvWindow         *ev_window,
+                                                        GFile            *source_file);
 
 G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW)
 
 
 G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW)
 
@@ -353,24 +352,13 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window)
        if (gconf_client_get_bool (client, GCONF_LOCKDOWN_PRINT, NULL)) {
                ok_to_print = FALSE;
        }
        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);
 
        /* 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);
        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);
 
        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);
 
@@ -646,9 +634,9 @@ ev_window_set_message_area (EvWindow  *window,
 }
 
 static void
 }
 
 static void
-ev_window_error_message_response_cb (EvMessageArea *area,
-                                    gint           response_id,
-                                    EvWindow      *window)
+ev_window_message_area_response_cb (EvMessageArea *area,
+                                   gint           response_id,
+                                   EvWindow      *window)
 {
        ev_window_set_message_area (window, NULL);
 }
 {
        ev_window_set_message_area (window, NULL);
 }
@@ -669,7 +657,28 @@ ev_window_error_message (GtkWindow *window, const gchar *msg, GError *error)
        if (error)
                ev_message_area_set_secondary_text (EV_MESSAGE_AREA (area), error->message);
        g_signal_connect (area, "response",
        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),
+                         G_CALLBACK (ev_window_message_area_response_cb),
+                         window);
+       gtk_widget_show (area);
+       ev_window_set_message_area (EV_WINDOW (window), area);
+}
+
+static void
+ev_window_warning_message (GtkWindow *window, const gchar *msg)
+{
+       GtkWidget *area;
+
+       if (EV_WINDOW (window)->priv->message_area)
+               return;
+
+       area = ev_message_area_new (GTK_MESSAGE_WARNING,
+                                   msg,
+                                   GTK_STOCK_CLOSE,
+                                   GTK_RESPONSE_CANCEL,
+                                   NULL);
+       
+       g_signal_connect (area, "response",
+                         G_CALLBACK (ev_window_message_area_response_cb),
                          window);
        gtk_widget_show (area);
        ev_window_set_message_area (EV_WINDOW (window), area);
                          window);
        gtk_widget_show (area);
        ev_window_set_message_area (EV_WINDOW (window), area);
@@ -1096,13 +1105,12 @@ ev_window_set_icon_from_thumbnail (EvJobThumbnail *job,
 static void
 ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation)
 {
 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;
        
        gint page_width, page_height;
        gdouble scale;
        EvDocument *document = ev_window->priv->document;
        
-       if (!EV_IS_DOCUMENT_THUMBNAILS (document)) {
+       if (!EV_IS_DOCUMENT_THUMBNAILS (document) ||
+           ev_page_cache_get_n_pages (ev_window->priv->page_cache) <= 0) {
                return;
        }
        
                return;
        }
        
@@ -1113,14 +1121,11 @@ ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation)
                                &page_width, &page_height);
        scale = (gdouble)128 / (gdouble)page_width;
        
                                &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);
+       ev_window->priv->thumbnail_job = ev_job_thumbnail_new (document, 0, rotation, scale);
        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_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
 }
 
 static gboolean
@@ -1190,11 +1195,21 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document)
 
        if (ev_page_cache_get_n_pages (ev_window->priv->page_cache) > 0) {
                ev_view_set_document (view, document);
 
        if (ev_page_cache_get_n_pages (ev_window->priv->page_cache) > 0) {
                ev_view_set_document (view, document);
+       } else {
+               ev_window_warning_message (GTK_WINDOW (ev_window),
+                                          _("The document contains no pages"));
        }
 
        g_idle_add ((GSourceFunc)ev_window_setup_document, ev_window);
 }
 
        }
 
        g_idle_add ((GSourceFunc)ev_window_setup_document, ev_window);
 }
 
+static void
+ev_window_document_changed (EvWindow *ev_window,
+                           gpointer  user_data)
+{
+       ev_window_reload_document (ev_window);
+}
+
 static void
 password_dialog_response (GtkWidget *password_dialog,
                          gint       response_id,
 static void
 password_dialog_response (GtkWidget *password_dialog,
                          gint       response_id,
@@ -1272,6 +1287,20 @@ ev_window_clear_load_job (EvWindow *ev_window)
        }
 }
 
        }
 }
 
+static void
+ev_window_clear_reload_job (EvWindow *ev_window)
+{
+       if (ev_window->priv->reload_job != NULL) {
+               
+               if (!ev_window->priv->reload_job->finished)
+                       ev_job_queue_remove_job (ev_window->priv->reload_job);
+               
+               g_signal_handlers_disconnect_by_func (ev_window->priv->reload_job, ev_window_reload_job_cb, ev_window);
+               g_object_unref (ev_window->priv->reload_job);
+               ev_window->priv->reload_job = NULL;
+       }
+}
+
 static void
 ev_window_clear_local_uri (EvWindow *ev_window)
 {
 static void
 ev_window_clear_local_uri (EvWindow *ev_window)
 {
@@ -1303,7 +1332,7 @@ ev_window_clear_temp_file (EvWindow *ev_window)
        file = g_file_new_for_uri (ev_window->priv->uri);
        tempdir = g_file_new_for_path (g_get_tmp_dir ());
 
        file = g_file_new_for_uri (ev_window->priv->uri);
        tempdir = g_file_new_for_path (g_get_tmp_dir ());
 
-       if (g_file_contains_file (tempdir, file)) {
+       if (g_file_has_prefix (file, tempdir)) {
                g_file_delete (file, NULL, NULL);
        }
 
                g_file_delete (file, NULL, NULL);
        }
 
@@ -1327,7 +1356,7 @@ ev_window_load_job_cb  (EvJobLoad *job,
        EvDocument *document = EV_JOB (job)->document;
 
        g_assert (job->uri);
        EvDocument *document = EV_JOB (job)->document;
 
        g_assert (job->uri);
-       
+
        ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
 
        /* Success! */
        ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
 
        /* Success! */
@@ -1366,23 +1395,19 @@ ev_window_load_job_cb  (EvJobLoad *job,
                                break;
                }
 
                                break;
                }
 
-               /* Restart the search after reloading */
-               if (ev_window->priv->in_reload) {
-                       GtkWidget *widget;
-                       
-                       widget = gtk_window_get_focus (GTK_WINDOW (ev_window));
-                       if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) {
-                               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)) {
+               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_cmd_edit_find (NULL, ev_window);
                        egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar),
                                                        job->search_string);
                }
 
+               /* Create a monitor for the document */
+               ev_window->priv->monitor = ev_file_monitor_new (job->uri);
+               g_signal_connect_swapped (G_OBJECT (ev_window->priv->monitor), "changed",
+                                         G_CALLBACK (ev_window_document_changed),
+                                         ev_window);
+               
                ev_window_clear_load_job (ev_window);
                ev_window_clear_load_job (ev_window);
-               ev_window->priv->in_reload = FALSE;
                return;
        }
 
                return;
        }
 
@@ -1407,10 +1432,32 @@ ev_window_load_job_cb  (EvJobLoad *job,
                                         _("Unable to open document"),
                                         job->error);
                ev_window_clear_load_job (ev_window);
                                         _("Unable to open document"),
                                         job->error);
                ev_window_clear_load_job (ev_window);
-               ev_window->priv->in_reload = FALSE;
        }       
        }       
+}
 
 
-       return;
+static void
+ev_window_reload_job_cb (EvJobLoad *job,
+                        EvWindow  *ev_window)
+{
+       GtkWidget *widget;
+       
+       if (job->error) {
+               ev_window_clear_reload_job (ev_window);
+               ev_window->priv->in_reload = FALSE;
+               return;
+       }
+
+       ev_window_set_document (ev_window, EV_JOB (job)->document);
+
+       /* Restart the search after reloading */
+       widget = gtk_window_get_focus (GTK_WINDOW (ev_window));
+       if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) {
+               find_bar_search_changed_cb (EGG_FIND_BAR (ev_window->priv->find_bar),
+                                           NULL, ev_window);
+       }
+
+       ev_window_clear_reload_job (ev_window);
+       ev_window->priv->in_reload = FALSE;
 }
 
 /**
 }
 
 /**
@@ -1441,31 +1488,111 @@ ev_window_close_dialogs (EvWindow *ev_window)
                gtk_widget_destroy (ev_window->priv->password_dialog);
        ev_window->priv->password_dialog = NULL;
        
                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;
        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;
 }
 
        
        if (ev_window->priv->properties)
                gtk_widget_destroy (ev_window->priv->properties);
        ev_window->priv->properties = NULL;
 }
 
+static void
+ev_window_load_remote_failed (EvWindow *ev_window,
+                             GError   *error)
+{
+       ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
+       ev_window->priv->in_reload = FALSE;
+       ev_window_error_message (GTK_WINDOW (ev_window),
+                                _("Unable to open document"),
+                                error);
+       g_free (ev_window->priv->local_uri);
+       ev_window->priv->local_uri = NULL;
+}
+
+static void
+mount_volume_ready_cb (GFile        *source,
+                      GAsyncResult *async_result,
+                      EvWindow     *ev_window)
+{
+       GError *error = NULL;
+
+       g_file_mount_enclosing_volume_finish (source, async_result, &error);
+
+       if (error) {
+               ev_window_load_remote_failed (ev_window, error);
+               g_object_unref (source);
+               g_error_free (error);
+       } else {
+               /* Volume successfully mounted,
+                  try opening the file again */
+               ev_window_load_file_remote (ev_window, source);
+       }
+}
+
 static void
 window_open_file_copy_ready_cb (GFile        *source,
                                GAsyncResult *async_result,
                                EvWindow     *ev_window)
 {
 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);
+       GError *error = NULL;
+       
+       g_file_copy_finish (source, async_result, &error);
+       if (!error) {
+               ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
+               g_object_unref (source);
+               
+               return;
+       }
+
+       if (error->domain == G_IO_ERROR &&
+           error->code == G_IO_ERROR_NOT_MOUNTED) {
+               GMountOperation *operation;
+
+               operation = ev_mount_operation_new (GTK_WINDOW (ev_window));
+               g_file_mount_enclosing_volume (source,
+                                              G_MOUNT_MOUNT_NONE,
+                                              operation, NULL,
+                                              (GAsyncReadyCallback)mount_volume_ready_cb,
+                                              ev_window);
+               g_object_unref (operation);
+       } else {
+               ev_window_load_remote_failed (ev_window, error);
+               g_object_unref (source);
+       }
+       
+       g_error_free (error);
+}
+
+static void
+ev_window_load_file_remote (EvWindow  *ev_window,
+                           GFile     *source_file)
+{
+       GFile *target_file;
+       
+       if (!ev_window->priv->local_uri) {
+               gchar *tmp_name;
+               gchar *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 = 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_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);
 }
 
 void
 }
 
 void
@@ -1478,11 +1605,18 @@ ev_window_open_uri (EvWindow       *ev_window,
                    const gchar    *print_settings)
 {
        GFile *source_file;
                    const gchar    *print_settings)
 {
        GFile *source_file;
-       GFile *target_file;
 
 
+       ev_window->priv->in_reload = FALSE;
+       
        if (ev_window->priv->uri &&
            g_ascii_strcasecmp (ev_window->priv->uri, uri) == 0) {
        if (ev_window->priv->uri &&
            g_ascii_strcasecmp (ev_window->priv->uri, uri) == 0) {
-               ev_window->priv->in_reload = TRUE;
+               ev_window_reload_document (ev_window);
+               return;
+       }
+
+       if (ev_window->priv->monitor) {
+               g_object_unref (ev_window->priv->monitor);
+               ev_window->priv->monitor = NULL;
        }
        
        ev_window_close_dialogs (ev_window);
        }
        
        ev_window_close_dialogs (ev_window);
@@ -1512,33 +1646,27 @@ ev_window_open_uri (EvWindow       *ev_window,
 
        source_file = g_file_new_for_uri (uri);
        if (!g_file_is_native (source_file) && !ev_window->priv->local_uri) {
 
        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 = 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_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;
+               ev_window_load_file_remote (ev_window, source_file);
+       } else {
+               g_object_unref (source_file);
+               ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
        }
        }
+}
+
+static void
+ev_window_reload_document (EvWindow *ev_window)
+{
+       const gchar *uri;
 
 
-       g_object_unref (source_file);
-       ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
+       ev_window_clear_reload_job (ev_window);
+       ev_window->priv->in_reload = TRUE;
+       
+       uri = ev_window->priv->local_uri ? ev_window->priv->local_uri : ev_window->priv->uri;
+       ev_window->priv->reload_job = ev_job_load_new (uri, NULL, 0, NULL);
+       g_signal_connect (ev_window->priv->reload_job, "finished",
+                         G_CALLBACK (ev_window_reload_job_cb),
+                         ev_window);
+       ev_job_queue_add_job (ev_window->priv->reload_job, EV_JOB_PRIORITY_LOW);
 }
 
 static void
 }
 
 static void
@@ -1910,7 +2038,7 @@ window_save_file_copy_ready_cb (GFile        *src,
                                         _("The file could not be saved as “%s”."),
                                         name);
        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                         _("The file could not be saved as “%s”."),
                                         name);
        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                                 error->message);
+                                                 "%s", error->message);
        g_signal_connect (dialog, "response",
                          G_CALLBACK (gtk_widget_destroy),
                          NULL);
        g_signal_connect (dialog, "response",
                          G_CALLBACK (gtk_widget_destroy),
                          NULL);
@@ -2031,7 +2159,6 @@ ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window)
        gtk_widget_show (fc);
 }
 
        gtk_widget_show (fc);
 }
 
-#ifdef WITH_GTK_PRINT
 static void
 ev_window_print_page_setup_done_cb (GtkPageSetup *page_setup,
                                    EvWindow     *window)
 static void
 ev_window_print_page_setup_done_cb (GtkPageSetup *page_setup,
                                    EvWindow     *window)
@@ -2044,22 +2171,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);
 }
                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)
 {
 
 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);
        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)
 {
 static void
 ev_window_clear_print_job (EvWindow *window)
 {
@@ -2130,7 +2253,7 @@ ev_window_print_finished (GtkPrintJob *print_job,
                                                 GTK_BUTTONS_OK,
                                                 _("Failed to print document"));
                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                                 GTK_BUTTONS_OK,
                                                 _("Failed to print document"));
                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                                         error->message);
+                                                         "%s", error->message);
 
                gtk_dialog_run (GTK_DIALOG (dialog));
                gtk_widget_destroy (dialog);
 
                gtk_dialog_run (GTK_DIALOG (dialog));
                gtk_widget_destroy (dialog);
@@ -2202,7 +2325,7 @@ ev_window_print_send (EvWindow    *window,
                GtkPrintJob *job;
                GError      *error = NULL;
        
                GtkPrintJob *job;
                GError      *error = NULL;
        
-               job = gtk_print_job_new ("evince-print",
+               job = gtk_print_job_new (gtk_window_get_title (GTK_WINDOW (window)),
                                         window->priv->printer,
                                         settings,
                                         window->priv->print_page_setup);
                                         window->priv->printer,
                                         settings,
                                         window->priv->print_page_setup);
@@ -2217,7 +2340,7 @@ ev_window_print_send (EvWindow    *window,
                                            window, NULL);
                } else {
                        ev_window_clear_print_job (window);
                                            window, NULL);
                } else {
                        ev_window_clear_print_job (window);
-                       g_warning (error->message);
+                       g_warning ("%s", error->message);
                        g_error_free (error);
                }
        }
                        g_error_free (error);
                }
        }
@@ -2230,7 +2353,7 @@ ev_window_print_job_cb (EvJobPrint *job,
                        EvWindow   *window)
 {
        if (job->error) {
                        EvWindow   *window)
 {
        if (job->error) {
-               g_warning (job->error->message);
+               g_warning ("%s", job->error->message);
                ev_window_clear_print_job (window);
                return;
        }
                ev_window_clear_print_job (window);
                return;
        }
@@ -2259,7 +2382,8 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog,
        GtkPrintPages  print_pages;
        const gchar   *file_format;
        
        GtkPrintPages  print_pages;
        const gchar   *file_format;
        
-       if (response == GTK_RESPONSE_CANCEL) {
+       if (response != GTK_RESPONSE_OK &&
+           response != GTK_RESPONSE_APPLY) {
                gtk_widget_destroy (GTK_WIDGET (dialog));
                window->priv->print_dialog = NULL;
 
                gtk_widget_destroy (GTK_WIDGET (dialog));
                window->priv->print_dialog = NULL;
 
@@ -2442,124 +2566,6 @@ ev_window_print_range (EvWindow *ev_window, int first_page, int last_page)
 
        gtk_widget_show (dialog);
 }
 
        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)
 
 static void
 ev_window_print (EvWindow *window)
@@ -2570,9 +2576,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);
 
        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);
        ev_window_print_range (window, 1, last_page);
-#endif
 }
 
 static void
 }
 
 static void
@@ -2638,7 +2642,7 @@ ev_window_cmd_continuous (GtkAction *action, EvWindow *ev_window)
 {
        gboolean continuous;
 
 {
        gboolean continuous;
 
-       ev_window_stop_presentation (ev_window);
+       ev_window_stop_presentation (ev_window, TRUE);
        continuous = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
        g_object_set (G_OBJECT (ev_window->priv->view),
                      "continuous", continuous,
        continuous = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
        g_object_set (G_OBJECT (ev_window->priv->view),
                      "continuous", continuous,
@@ -2651,7 +2655,7 @@ ev_window_cmd_dual (GtkAction *action, EvWindow *ev_window)
 {
        gboolean dual_page;
 
 {
        gboolean dual_page;
 
-       ev_window_stop_presentation (ev_window);
+       ev_window_stop_presentation (ev_window, TRUE);
        dual_page = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
        g_object_set (G_OBJECT (ev_window->priv->view),
                      "dual-page", dual_page,
        dual_page = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
        g_object_set (G_OBJECT (ev_window->priv->view),
                      "dual-page", dual_page,
@@ -2662,7 +2666,7 @@ ev_window_cmd_dual (GtkAction *action, EvWindow *ev_window)
 static void
 ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window)
 {
 static void
 ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window)
 {
-       ev_window_stop_presentation (ev_window);
+       ev_window_stop_presentation (ev_window, TRUE);
 
        if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
                ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_BEST_FIT);
 
        if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
                ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_BEST_FIT);
@@ -2675,7 +2679,7 @@ ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window)
 static void
 ev_window_cmd_view_page_width (GtkAction *action, EvWindow *ev_window)
 {
 static void
 ev_window_cmd_view_page_width (GtkAction *action, EvWindow *ev_window)
 {
-       ev_window_stop_presentation (ev_window);
+       ev_window_stop_presentation (ev_window, TRUE);
 
        if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
                ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FIT_WIDTH);
 
        if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
                ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FIT_WIDTH);
@@ -2804,6 +2808,12 @@ fullscreen_toolbar_remove_shadow (GtkWidget *toolbar)
 static void
 ev_window_run_fullscreen (EvWindow *window)
 {
 static void
 ev_window_run_fullscreen (EvWindow *window)
 {
+       EvView  *view = EV_VIEW (window->priv->view);
+       gboolean fullscreen_window = TRUE;
+
+       if (ev_view_get_fullscreen (view))
+               return;
+       
        if (!window->priv->fullscreen_toolbar) {
                window->priv->fullscreen_toolbar =
                        gtk_ui_manager_get_widget (window->priv->ui_manager,
        if (!window->priv->fullscreen_toolbar) {
                window->priv->fullscreen_toolbar =
                        gtk_ui_manager_get_widget (window->priv->ui_manager,
@@ -2821,11 +2831,16 @@ ev_window_run_fullscreen (EvWindow *window)
                                       window->priv->fullscreen_toolbar, 1);
        }
 
                                       window->priv->fullscreen_toolbar, 1);
        }
 
+       if (ev_view_get_presentation (view)) {
+               ev_window_stop_presentation (window, FALSE);
+               fullscreen_window = FALSE;
+       }
+
        g_object_set (G_OBJECT (window->priv->scrolled_window),
                      "shadow-type", GTK_SHADOW_NONE,
                      NULL);
 
        g_object_set (G_OBJECT (window->priv->scrolled_window),
                      "shadow-type", GTK_SHADOW_NONE,
                      NULL);
 
-       ev_view_set_fullscreen (EV_VIEW (window->priv->view), TRUE);
+       ev_view_set_fullscreen (view, TRUE);
        ev_window_update_fullscreen_action (window);
 
        /* If the user doesn't have the main toolbar he/she won't probably want
        ev_window_update_fullscreen_action (window);
 
        /* If the user doesn't have the main toolbar he/she won't probably want
@@ -2834,8 +2849,9 @@ ev_window_run_fullscreen (EvWindow *window)
        update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR,
                            (window->priv->chrome & EV_CHROME_TOOLBAR) != 0);
        update_chrome_visibility (window);
        update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR,
                            (window->priv->chrome & EV_CHROME_TOOLBAR) != 0);
        update_chrome_visibility (window);
-       
-       gtk_window_fullscreen (GTK_WINDOW (window));
+
+       if (fullscreen_window)
+               gtk_window_fullscreen (GTK_WINDOW (window));
        gtk_widget_grab_focus (window->priv->view);
 
        if (!ev_window_is_empty (window))
        gtk_widget_grab_focus (window->priv->view);
 
        if (!ev_window_is_empty (window))
@@ -2843,11 +2859,12 @@ ev_window_run_fullscreen (EvWindow *window)
 }
 
 static void
 }
 
 static void
-ev_window_stop_fullscreen (EvWindow *window)
+ev_window_stop_fullscreen (EvWindow *window,
+                          gboolean  unfullscreen_window)
 {
        EvView *view = EV_VIEW (window->priv->view);
 
 {
        EvView *view = EV_VIEW (window->priv->view);
 
-       if (!ev_view_get_fullscreen (EV_VIEW (view)))
+       if (!ev_view_get_fullscreen (view))
                return;
 
        g_object_set (G_OBJECT (window->priv->scrolled_window),
                return;
 
        g_object_set (G_OBJECT (window->priv->scrolled_window),
@@ -2858,7 +2875,8 @@ ev_window_stop_fullscreen (EvWindow *window)
        ev_window_update_fullscreen_action (window);
        update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR, FALSE);
        update_chrome_visibility (window);
        ev_window_update_fullscreen_action (window);
        update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR, FALSE);
        update_chrome_visibility (window);
-       gtk_window_unfullscreen (GTK_WINDOW (window));
+       if (unfullscreen_window)
+               gtk_window_unfullscreen (GTK_WINDOW (window));
 
        if (!ev_window_is_empty (window))
                ev_metadata_manager_set_boolean (window->priv->uri, "fullscreen", FALSE);
 
        if (!ev_window_is_empty (window))
                ev_metadata_manager_set_boolean (window->priv->uri, "fullscreen", FALSE);
@@ -2869,14 +2887,11 @@ ev_window_cmd_view_fullscreen (GtkAction *action, EvWindow *window)
 {
        gboolean fullscreen;
 
 {
        gboolean fullscreen;
 
-        g_return_if_fail (EV_IS_WINDOW (window));
-       ev_window_stop_presentation (window);
-
        fullscreen = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
        if (fullscreen) {
                ev_window_run_fullscreen (window);
        } else {
        fullscreen = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
        if (fullscreen) {
                ev_window_run_fullscreen (window);
        } else {
-               ev_window_stop_fullscreen (window);
+               ev_window_stop_fullscreen (window, TRUE);
        }
 }
 
        }
 }
 
@@ -2961,17 +2976,29 @@ ev_window_update_presentation_action (EvWindow *window)
 static void
 ev_window_run_presentation (EvWindow *window)
 {
 static void
 ev_window_run_presentation (EvWindow *window)
 {
+       EvView  *view = EV_VIEW (window->priv->view);
+       gboolean fullscreen_window = TRUE;
+
+       if (ev_view_get_presentation (view))
+               return;
+
+       if (ev_view_get_fullscreen (view)) {
+               ev_window_stop_fullscreen (window, FALSE);
+               fullscreen_window = FALSE;
+       }
+       
        g_object_set (G_OBJECT (window->priv->scrolled_window),
                      "shadow-type", GTK_SHADOW_NONE,
                      NULL);
 
        g_object_set (G_OBJECT (window->priv->scrolled_window),
                      "shadow-type", GTK_SHADOW_NONE,
                      NULL);
 
-       ev_view_set_presentation (EV_VIEW (window->priv->view), TRUE);
+       ev_view_set_presentation (view, TRUE);
        ev_window_update_presentation_action (window);
 
        update_chrome_visibility (window);
        
        gtk_widget_grab_focus (window->priv->view);
        ev_window_update_presentation_action (window);
 
        update_chrome_visibility (window);
        
        gtk_widget_grab_focus (window->priv->view);
-       gtk_window_fullscreen (GTK_WINDOW (window));
+       if (fullscreen_window)
+               gtk_window_fullscreen (GTK_WINDOW (window));
 
        g_signal_connect (window->priv->view,
                          "motion-notify-event",
 
        g_signal_connect (window->priv->view,
                          "motion-notify-event",
@@ -2990,9 +3017,12 @@ ev_window_run_presentation (EvWindow *window)
 }
 
 static void
 }
 
 static void
-ev_window_stop_presentation (EvWindow *window)
+ev_window_stop_presentation (EvWindow *window,
+                            gboolean  unfullscreen_window)
 {
 {
-       if (!ev_view_get_presentation (EV_VIEW (window->priv->view)))
+       EvView *view = EV_VIEW (window->priv->view);
+       
+       if (!ev_view_get_presentation (view))
                return;
 
        g_object_set (G_OBJECT (window->priv->scrolled_window),
                return;
 
        g_object_set (G_OBJECT (window->priv->scrolled_window),
@@ -3002,7 +3032,8 @@ ev_window_stop_presentation (EvWindow *window)
        ev_view_set_presentation (EV_VIEW (window->priv->view), FALSE);
        ev_window_update_presentation_action (window);
        update_chrome_visibility (window);
        ev_view_set_presentation (EV_VIEW (window->priv->view), FALSE);
        ev_window_update_presentation_action (window);
        update_chrome_visibility (window);
-       gtk_window_unfullscreen (GTK_WINDOW (window));
+       if (unfullscreen_window)
+               gtk_window_unfullscreen (GTK_WINDOW (window));
 
        g_signal_handlers_disconnect_by_func (window->priv->view,
                                              (gpointer) presentation_motion_notify_cb,
 
        g_signal_handlers_disconnect_by_func (window->priv->view,
                                              (gpointer) presentation_motion_notify_cb,
@@ -3023,14 +3054,11 @@ ev_window_cmd_view_presentation (GtkAction *action, EvWindow *window)
 {
        gboolean presentation;
 
 {
        gboolean presentation;
 
-       g_return_if_fail (EV_IS_WINDOW (window));
-       ev_window_stop_fullscreen (window);
-
        presentation = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
        if (presentation) {
                ev_window_run_presentation (window);
        } else {
        presentation = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
        if (presentation) {
                ev_window_run_presentation (window);
        } else {
-               ev_window_stop_presentation (window);
+               ev_window_stop_presentation (window, TRUE);
        }
 }
 
        }
 }
 
@@ -3206,6 +3234,12 @@ ev_window_cmd_go_previous_page (GtkAction *action, EvWindow *ev_window)
        ev_view_previous_page (EV_VIEW (ev_window->priv->view));
 }
 
        ev_view_previous_page (EV_VIEW (ev_window->priv->view));
 }
 
+void
+ev_window_go_previous_page (EvWindow *ev_window)
+{
+       ev_window_cmd_go_previous_page (NULL, ev_window);
+}
+
 static void
 ev_window_cmd_go_next_page (GtkAction *action, EvWindow *ev_window)
 {
 static void
 ev_window_cmd_go_next_page (GtkAction *action, EvWindow *ev_window)
 {
@@ -3214,6 +3248,12 @@ ev_window_cmd_go_next_page (GtkAction *action, EvWindow *ev_window)
        ev_view_next_page (EV_VIEW (ev_window->priv->view));
 }
 
        ev_view_next_page (EV_VIEW (ev_window->priv->view));
 }
 
+void
+ev_window_go_next_page (EvWindow *ev_window)
+{
+       ev_window_cmd_go_next_page (NULL, ev_window);
+}
+
 static void
 ev_window_cmd_go_first_page (GtkAction *action, EvWindow *ev_window)
 {
 static void
 ev_window_cmd_go_first_page (GtkAction *action, EvWindow *ev_window)
 {
@@ -3222,6 +3262,12 @@ ev_window_cmd_go_first_page (GtkAction *action, EvWindow *ev_window)
        ev_page_cache_set_current_page (ev_window->priv->page_cache, 0);
 }
 
        ev_page_cache_set_current_page (ev_window->priv->page_cache, 0);
 }
 
+void
+ev_window_go_first_page (EvWindow *ev_window)
+{
+       ev_window_cmd_go_first_page (NULL, ev_window);
+}
+
 static void
 ev_window_cmd_go_last_page (GtkAction *action, EvWindow *ev_window)
 {
 static void
 ev_window_cmd_go_last_page (GtkAction *action, EvWindow *ev_window)
 {
@@ -3233,6 +3279,12 @@ ev_window_cmd_go_last_page (GtkAction *action, EvWindow *ev_window)
        ev_page_cache_set_current_page (ev_window->priv->page_cache, n_pages - 1);
 }
 
        ev_page_cache_set_current_page (ev_window->priv->page_cache, n_pages - 1);
 }
 
+void
+ev_window_go_last_page (EvWindow *ev_window)
+{
+       ev_window_cmd_go_last_page (NULL, ev_window);
+}
+
 static void
 ev_window_cmd_go_forward (GtkAction *action, EvWindow *ev_window)
 {
 static void
 ev_window_cmd_go_forward (GtkAction *action, EvWindow *ev_window)
 {
@@ -3263,11 +3315,7 @@ ev_window_cmd_go_backward (GtkAction *action, EvWindow *ev_window)
 static void
 ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window)
 {
 static void
 ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window)
 {
-       gchar *uri;
-
-       uri = g_strdup (ev_window->priv->uri);
-       ev_window_open_uri (ev_window, uri, NULL, 0, NULL, FALSE, NULL);
-       g_free (uri);
+       ev_window_reload_document (ev_window);
 }
 
 static void
 }
 
 static void
@@ -3319,7 +3367,7 @@ ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window)
        screen = gtk_widget_get_screen (GTK_WIDGET (ev_window));
        gdk_spawn_command_line_on_screen (screen, command, &error);
        if (error != NULL) {
        screen = gtk_widget_get_screen (GTK_WIDGET (ev_window));
        gdk_spawn_command_line_on_screen (screen, command, &error);
        if (error != NULL) {
-               g_warning (error->message);
+               g_warning ("%s", error->message);
                g_error_free (error);
        }
        g_free (command);
                g_error_free (error);
        }
        g_free (command);
@@ -3328,18 +3376,20 @@ ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window)
 static void
 ev_window_cmd_leave_fullscreen (GtkAction *action, EvWindow *window)
 {
 static void
 ev_window_cmd_leave_fullscreen (GtkAction *action, EvWindow *window)
 {
-       ev_window_stop_fullscreen (window);
+       ev_window_stop_fullscreen (window, TRUE);
 }
 
 static void
 ev_window_cmd_start_presentation (GtkAction *action, EvWindow *window)
 {
 }
 
 static void
 ev_window_cmd_start_presentation (GtkAction *action, EvWindow *window)
 {
-       ev_window_stop_fullscreen (window);
        ev_window_run_presentation (window);
 }
 
        ev_window_run_presentation (window);
 }
 
-#ifdef WITH_GTK_PRINT
-static void ev_window_do_preview_print (EvWindow *window);
+void
+ev_window_start_presentation (EvWindow *ev_window)
+{
+       ev_window_run_presentation (ev_window);
+}
 
 static gboolean
 ev_window_enumerate_printer_cb (GtkPrinter *printer,
 
 static gboolean
 ev_window_enumerate_printer_cb (GtkPrinter *printer,
@@ -3379,7 +3429,7 @@ ev_window_preview_print_finished (GtkPrintJob *print_job,
                                                 GTK_BUTTONS_OK,
                                                 _("Failed to print document"));
                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                                 GTK_BUTTONS_OK,
                                                 _("Failed to print document"));
                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                                         error->message);
+                                                         "%s", error->message);
 
                gtk_dialog_run (GTK_DIALOG (dialog));
                gtk_widget_destroy (dialog);
 
                gtk_dialog_run (GTK_DIALOG (dialog));
                gtk_widget_destroy (dialog);
@@ -3403,7 +3453,7 @@ ev_window_do_preview_print (EvWindow *window)
 
        page_setup = gtk_page_setup_new ();
 
 
        page_setup = gtk_page_setup_new ();
 
-       job = gtk_print_job_new ("evince-print",
+       job = gtk_print_job_new (gtk_window_get_title (GTK_WINDOW (window)),
                                 priv->printer,
                                 priv->print_settings,
                                 page_setup);
                                 priv->printer,
                                 priv->print_settings,
                                 page_setup);
@@ -3423,7 +3473,7 @@ ev_window_do_preview_print (EvWindow *window)
                                    (GtkPrintJobCompleteFunc)ev_window_preview_print_finished,
                                    window, NULL);
        } else {
                                    (GtkPrintJobCompleteFunc)ev_window_preview_print_finished,
                                    window, NULL);
        } else {
-               g_warning (error->message);
+               g_warning ("%s", error->message);
                g_error_free (error);
        }
 
                g_error_free (error);
        }
 
@@ -3432,12 +3482,9 @@ ev_window_do_preview_print (EvWindow *window)
        gtk_widget_hide (GTK_WIDGET (window));
 }
 
        gtk_widget_hide (GTK_WIDGET (window));
 }
 
-#endif /* WITH_GTK_PRINT */
-
 static void
 ev_window_cmd_preview_print (GtkAction *action, EvWindow *window)
 {
 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)
        EvWindowPrivate *priv = window->priv;
        GtkPrintSettings *print_settings = NULL;
 #if GTK_CHECK_VERSION (2, 11, 0)
@@ -3451,7 +3498,7 @@ ev_window_cmd_preview_print (GtkAction *action, EvWindow *window)
                                                                           &error);
                        
                        if (error) {
                                                                           &error);
                        
                        if (error) {
-                               g_warning (error->message);
+                               g_warning ("%s", error->message);
                                g_error_free (error);
                                print_settings = NULL;
                        }
                                g_error_free (error);
                                print_settings = NULL;
                        }
@@ -3468,7 +3515,6 @@ ev_window_cmd_preview_print (GtkAction *action, EvWindow *window)
 
        gtk_enumerate_printers ((GtkPrinterFunc) ev_window_enumerate_printer_cb,
                                window, NULL, FALSE);
 
        gtk_enumerate_printers ((GtkPrinterFunc) ev_window_enumerate_printer_cb,
                                window, NULL, FALSE);
-#endif /* WITH_GTK_PRINT */
 }
 
 static void
 }
 
 static void
@@ -3493,9 +3539,9 @@ ev_window_cmd_escape (GtkAction *action, EvWindow *window)
                              NULL);
 
                if (fullscreen) {
                              NULL);
 
                if (fullscreen) {
-                       ev_window_stop_fullscreen (window);
+                       ev_window_stop_fullscreen (window, TRUE);
                } else if (presentation) {
                } else if (presentation) {
-                       ev_window_stop_presentation (window);
+                       ev_window_stop_presentation (window, TRUE);
                        gtk_widget_grab_focus (window->priv->view);
                } else {
                        gtk_widget_grab_focus (window->priv->view);
                        gtk_widget_grab_focus (window->priv->view);
                } else {
                        gtk_widget_grab_focus (window->priv->view);
@@ -3975,6 +4021,7 @@ static void
 find_bar_close_cb (EggFindBar *find_bar,
                   EvWindow   *ev_window)
 {
 find_bar_close_cb (EggFindBar *find_bar,
                   EvWindow   *ev_window)
 {
+       ev_view_find_cancel (EV_VIEW (ev_window->priv->view));
        update_chrome_flag (ev_window, EV_CHROME_FINDBAR, FALSE);
        update_chrome_visibility (ev_window);
 }
        update_chrome_flag (ev_window, EV_CHROME_FINDBAR, FALSE);
        update_chrome_visibility (ev_window);
 }
@@ -4087,7 +4134,21 @@ ev_window_dispose (GObject *object)
 {
        EvWindow *window = EV_WINDOW (object);
        EvWindowPrivate *priv = window->priv;
 {
        EvWindow *window = EV_WINDOW (object);
        EvWindowPrivate *priv = window->priv;
+#ifdef ENABLE_DBUS
+       GObject *keys;
+
+       keys = ev_application_get_media_keys (EV_APP);
+       if (keys) {
+               ev_media_player_keys_focused (EV_MEDIA_PLAYER_KEYS (keys), NULL);
+               g_object_unref (keys);
+       }
+#endif /* ENABLE_DBUS */
 
 
+       if (priv->monitor) {
+               g_object_unref (priv->monitor);
+               priv->monitor = NULL;
+       }
+       
        if (priv->title) {
                ev_window_title_free (priv->title);
                priv->title = NULL;
        if (priv->title) {
                ev_window_title_free (priv->title);
                priv->title = NULL;
@@ -4151,6 +4212,10 @@ ev_window_dispose (GObject *object)
                ev_window_clear_load_job (window);
        }
 
                ev_window_clear_load_job (window);
        }
 
+       if (priv->reload_job) {
+               ev_window_clear_reload_job (window);
+       }
+
        if (priv->save_job) {
                ev_window_clear_save_job (window);
        }
        if (priv->save_job) {
                ev_window_clear_save_job (window);
        }
@@ -4165,8 +4230,6 @@ ev_window_dispose (GObject *object)
        }
        
        ev_window_close_dialogs (window);
        }
        
        ev_window_close_dialogs (window);
-
-#ifdef WITH_GTK_PRINT
        ev_window_clear_print_job (window);
 
        if (window->priv->gtk_print_job) {
        ev_window_clear_print_job (window);
 
        if (window->priv->gtk_print_job) {
@@ -4188,7 +4251,6 @@ ev_window_dispose (GObject *object)
                g_object_unref (window->priv->print_page_setup);
                window->priv->print_page_setup = NULL;
        }
                g_object_unref (window->priv->print_page_setup);
                window->priv->print_page_setup = NULL;
        }
-#endif
 
        if (priv->link) {
                g_object_unref (priv->link);
 
        if (priv->link) {
                g_object_unref (priv->link);
@@ -4272,7 +4334,7 @@ static const GtkActionEntry entries[] = {
        { "FileOpen", GTK_STOCK_OPEN, N_("_Open..."), "<control>O",
          N_("Open an existing document"),
          G_CALLBACK (ev_window_cmd_file_open) },
        { "FileOpen", GTK_STOCK_OPEN, N_("_Open..."), "<control>O",
          N_("Open an existing document"),
          G_CALLBACK (ev_window_cmd_file_open) },
-       { "FileOpenCopy", NULL, N_("Op_en a Copy"), NULL,
+       { "FileOpenCopy", NULL, N_("Op_en a Copy"), "<control>N",
          N_("Open a copy of the current document in a new window"),
          G_CALLBACK (ev_window_cmd_file_open_copy) },
                { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), "<control>S",
          N_("Open a copy of the current document in a new window"),
          G_CALLBACK (ev_window_cmd_file_open_copy) },
                { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), "<control>S",
@@ -4303,9 +4365,9 @@ static const GtkActionEntry entries[] = {
          G_CALLBACK (ev_window_cmd_edit_find_previous) },
         { "EditToolbar", NULL, N_("T_oolbar"), NULL, NULL,
           G_CALLBACK (ev_window_cmd_edit_toolbar) },
          G_CALLBACK (ev_window_cmd_edit_find_previous) },
         { "EditToolbar", NULL, N_("T_oolbar"), NULL, NULL,
           G_CALLBACK (ev_window_cmd_edit_toolbar) },
-       { "EditRotateLeft", EV_STOCK_ROTATE_LEFT, N_("Rotate _Left"), NULL, NULL,
+       { "EditRotateLeft", EV_STOCK_ROTATE_LEFT, N_("Rotate _Left"), "<alt>Left", NULL,
          G_CALLBACK (ev_window_cmd_edit_rotate_left) },
          G_CALLBACK (ev_window_cmd_edit_rotate_left) },
-       { "EditRotateRight", EV_STOCK_ROTATE_RIGHT, N_("Rotate _Right"), NULL, NULL,
+       { "EditRotateRight", EV_STOCK_ROTATE_RIGHT, N_("Rotate _Right"), "<alt>Right", NULL,
          G_CALLBACK (ev_window_cmd_edit_rotate_right) },
 
         /* View menu */
          G_CALLBACK (ev_window_cmd_edit_rotate_right) },
 
         /* View menu */
@@ -4397,6 +4459,8 @@ static const GtkActionEntry entries[] = {
           G_CALLBACK (ev_window_cmd_view_zoom_in) },
         { "CtrlKpMinus", GTK_STOCK_ZOOM_OUT, NULL, "<control>KP_Subtract", NULL,
           G_CALLBACK (ev_window_cmd_view_zoom_out) },
           G_CALLBACK (ev_window_cmd_view_zoom_in) },
         { "CtrlKpMinus", GTK_STOCK_ZOOM_OUT, NULL, "<control>KP_Subtract", NULL,
           G_CALLBACK (ev_window_cmd_view_zoom_out) },
+       { "CtrlInsert", GTK_STOCK_COPY, NULL, "<control>Insert", NULL,
+         G_CALLBACK (ev_window_cmd_edit_copy) },
 };
 
 /* Toggle items */
 };
 
 /* Toggle items */
@@ -4602,6 +4666,16 @@ sidebar_widget_model_set (EvSidebarLinks *ev_sidebar_links,
 static gboolean
 view_actions_focus_in_cb (GtkWidget *widget, GdkEventFocus *event, EvWindow *window)
 {
 static gboolean
 view_actions_focus_in_cb (GtkWidget *widget, GdkEventFocus *event, EvWindow *window)
 {
+#ifdef ENABLE_DBUS
+       GObject *keys;
+
+       keys = ev_application_get_media_keys (EV_APP);
+       if (keys) {
+               ev_media_player_keys_focused (EV_MEDIA_PLAYER_KEYS (keys), window);
+               g_object_unref (keys);
+       }
+#endif /* ENABLE_DBUS */
+
        update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, FALSE);
        ev_window_set_action_sensitive (window, "ViewToolbar", TRUE);
 
        update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, FALSE);
        ev_window_set_action_sensitive (window, "ViewToolbar", TRUE);
 
@@ -4744,29 +4818,11 @@ static void
 launch_external_uri (EvWindow *window, EvLinkAction *action)
 {
        const gchar *uri = ev_link_action_get_uri (action);
 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;
        GError *error = NULL;
+       gboolean ret;
        
        
-       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);
-       
-       file_list = g_list_append (file_list, file);
-       
-       if (!g_app_info_launch (app, file_list, NULL, &error)) {
+       ret = g_app_info_launch_default_for_uri (uri, NULL, &error);
+       if (ret == FALSE) {
                GtkWidget *dialog;
        
                dialog = gtk_message_dialog_new (GTK_WINDOW (window),
                GtkWidget *dialog;
        
                dialog = gtk_message_dialog_new (GTK_WINDOW (window),
@@ -4780,11 +4836,8 @@ launch_external_uri (EvWindow *window, EvLinkAction *action)
                                  G_CALLBACK (gtk_widget_destroy),
                                  NULL);
                gtk_widget_show (dialog);
                                  G_CALLBACK (gtk_widget_destroy),
                                  NULL);
                gtk_widget_show (dialog);
+               g_error_free(error);
        }
        }
-
-       g_object_unref (app);
-       g_object_unref (file);
-       g_list_free (file_list);
 }
 
 static void
 }
 
 static void
@@ -4895,19 +4948,14 @@ ev_view_popup_cmd_open_link_new_window (GtkAction *action, EvWindow *window)
 static void
 ev_view_popup_cmd_copy_link_address (GtkAction *action, EvWindow *window)
 {
 static void
 ev_view_popup_cmd_copy_link_address (GtkAction *action, EvWindow *window)
 {
-       GtkClipboard *clipboard;
        EvLinkAction *ev_action;
        EvLinkAction *ev_action;
-       const gchar *uri;
 
        ev_action = ev_link_get_action (window->priv->link);
        if (!ev_action)
                return;
 
 
        ev_action = ev_link_get_action (window->priv->link);
        if (!ev_action)
                return;
 
-       uri = ev_link_action_get_uri (ev_action);
-
-       clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window),
-                                             GDK_SELECTION_CLIPBOARD);
-       gtk_clipboard_set_text (clipboard, uri, -1);
+       ev_view_copy_link_address (EV_VIEW (window->priv->view),
+                                  ev_action);
 }
 
 
 }
 
 
@@ -4921,7 +4969,6 @@ image_save_dialog_response_cb (GtkWidget *fc,
        GError          *error = NULL;
        GdkPixbuf       *pixbuf;
        gchar           *uri;
        GError          *error = NULL;
        GdkPixbuf       *pixbuf;
        gchar           *uri;
-       gchar           *uri_extension;
        gchar          **extensions;
        gchar           *filename;
        gchar           *file_format;
        gchar          **extensions;
        gchar           *filename;
        gchar           *file_format;
@@ -4952,27 +4999,31 @@ image_save_dialog_response_cb (GtkWidget *fc,
        }
 
        extensions = gdk_pixbuf_format_get_extensions (format);
        }
 
        extensions = gdk_pixbuf_format_get_extensions (format);
-       uri_extension = g_strconcat (uri, ".", extensions[0], NULL);
+       if (g_str_has_suffix(uri, extensions[0])) {
+               gchar *uri_extension;
+               
+               uri_extension = g_strconcat (uri, ".", extensions[0], NULL);
+               target_file = g_file_new_for_uri (uri_extension);
+               g_free (uri_extension);
+       } else {
+               target_file = g_file_new_for_uri (uri);
+       }
        g_strfreev(extensions);
        g_strfreev(extensions);
-       file_format = gdk_pixbuf_format_get_name (format);
+       g_free (uri);
        
        
-       target_file = g_file_new_for_uri (uri_extension);
        is_native = g_file_is_native (target_file);
        is_native = g_file_is_native (target_file);
-       
        if (is_native) {
                filename = g_file_get_path (target_file);
        } else {
                filename = ev_tmp_filename ("saveimage");
        }
        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 ();
 
        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 ();
-       
+
+       file_format = gdk_pixbuf_format_get_name (format);
        gdk_pixbuf_save (pixbuf, filename, file_format, &error, NULL);
        g_free (file_format);
        g_object_unref (pixbuf);
        gdk_pixbuf_save (pixbuf, filename, file_format, &error, NULL);
        g_free (file_format);
        g_object_unref (pixbuf);