+ if (ev_window->priv->properties) {
+ ev_properties_dialog_set_document (EV_PROPERTIES_DIALOG (ev_window->priv->properties),
+ ev_window->priv->uri,
+ ev_window->priv->document);
+ }
+
+ info = ev_page_cache_get_info (ev_window->priv->page_cache);
+ update_document_mode (ev_window, info->mode);
+
+ return FALSE;
+}
+
+static void
+ev_window_set_document (EvWindow *ev_window, EvDocument *document)
+{
+ EvView *view = EV_VIEW (ev_window->priv->view);
+
+ 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",
+ G_CALLBACK (page_changed_cb), ev_window);
+ g_signal_connect (ev_window->priv->page_cache, "history-changed",
+ G_CALLBACK (history_changed_cb), ev_window);
+
+ setup_size_from_metadata (ev_window);
+ setup_sidebar_from_metadata (ev_window, document);
+ setup_document_from_metadata (ev_window);
+
+ if (ev_page_cache_get_n_pages (ev_window->priv->page_cache) > 0) {
+ ev_view_set_document (view, document);
+ } else {
+ ev_window_warning_message (ev_window, "%s",
+ _("The document contains no pages"));
+ }
+
+ if (ev_window->priv->setup_document_idle > 0)
+ g_source_remove (ev_window->priv->setup_document_idle);
+ ev_window->priv->setup_document_idle = 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
+ev_window_password_view_unlock (EvWindow *ev_window)
+{
+ const gchar *password;
+
+ g_assert (ev_window->priv->load_job);
+
+ password = ev_password_view_get_password (EV_PASSWORD_VIEW (ev_window->priv->password_view));
+ ev_job_load_set_password (EV_JOB_LOAD (ev_window->priv->load_job), password);
+ ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
+}
+
+static void
+ev_window_clear_load_job (EvWindow *ev_window)
+{
+ if (ev_window->priv->load_job != NULL) {
+ if (!ev_job_is_finished (ev_window->priv->load_job))
+ ev_job_cancel (ev_window->priv->load_job);
+
+ g_signal_handlers_disconnect_by_func (ev_window->priv->load_job, ev_window_load_job_cb, ev_window);
+ g_object_unref (ev_window->priv->load_job);
+ ev_window->priv->load_job = NULL;
+ }
+}
+
+static void
+ev_window_clear_reload_job (EvWindow *ev_window)
+{
+ if (ev_window->priv->reload_job != NULL) {
+ if (!ev_job_is_finished (ev_window->priv->reload_job))
+ ev_job_cancel (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)
+{
+ if (ev_window->priv->local_uri) {
+ ev_tmp_uri_unlink (ev_window->priv->local_uri);
+ g_free (ev_window->priv->local_uri);
+ ev_window->priv->local_uri = NULL;
+ }
+}
+
+static void
+ev_window_clear_print_settings_file (EvWindow *ev_window)
+{
+ if (ev_window->priv->print_settings_file) {
+ g_unlink (ev_window->priv->print_settings_file);
+ g_free (ev_window->priv->print_settings_file);
+ ev_window->priv->print_settings_file = NULL;
+ }
+}
+
+static void
+ev_window_clear_temp_file (EvWindow *ev_window)
+{
+ GFile *file, *tempdir;
+
+ if (!ev_window->priv->uri)
+ return;
+
+ file = g_file_new_for_uri (ev_window->priv->uri);
+ tempdir = g_file_new_for_path (g_get_tmp_dir ());
+
+ if (g_file_has_prefix (file, tempdir)) {
+ g_file_delete (file, NULL, NULL);
+ }
+
+ g_object_unref (file);
+ g_object_unref (tempdir);
+}
+
+/* This callback will executed when load job will be finished.
+ *
+ * Since the flow of the error dialog is very confusing, we assume that both
+ * document and uri will go away after this function is called, and thus we need
+ * to ref/dup them. Additionally, it needs to clear
+ * ev_window->priv->password_{uri,document}, and thus people who call this
+ * function should _not_ necessarily expect those to exist after being
+ * called. */
+static void
+ev_window_load_job_cb (EvJob *job,
+ gpointer data)
+{
+ EvWindow *ev_window = EV_WINDOW (data);
+ EvDocument *document = EV_JOB (job)->document;
+ EvJobLoad *job_load = EV_JOB_LOAD (job);
+
+ g_assert (job_load->uri);
+
+ ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
+
+ /* Success! */
+ if (!ev_job_is_failed (job)) {
+ ev_window_set_document (ev_window, document);
+
+ if (ev_window->priv->window_mode != EV_WINDOW_MODE_PREVIEW) {
+ setup_view_from_metadata (ev_window);
+ }
+
+ if (!ev_window->priv->unlink_temp_file) {
+ ev_window_add_recent (ev_window, ev_window->priv->uri);
+ }
+
+ ev_window_title_set_type (ev_window->priv->title,
+ EV_WINDOW_TITLE_DOCUMENT);
+ if (job_load->password) {
+ GPasswordSave flags;
+
+ flags = ev_password_view_get_password_save_flags (
+ EV_PASSWORD_VIEW (ev_window->priv->password_view));
+ ev_keyring_save_password (ev_window->priv->uri,
+ job_load->password,
+ flags);
+ }
+
+ if (ev_window->priv->dest) {
+ EvLink *link;
+ EvLinkAction *link_action;
+
+ link_action = ev_link_action_new_dest (ev_window->priv->dest);
+ link = ev_link_new (NULL, link_action);
+ ev_view_handle_link (EV_VIEW (ev_window->priv->view), link);
+ g_object_unref (link);
+
+ /* Already unrefed by ev_link_action
+ * FIXME: link action should inc dest ref counting
+ * or not unref it at all
+ */
+ ev_window->priv->dest = NULL;
+ }
+
+ switch (ev_window->priv->window_mode) {
+ case EV_WINDOW_MODE_FULLSCREEN:
+ ev_window_run_fullscreen (ev_window);
+ break;
+ case EV_WINDOW_MODE_PRESENTATION:
+ ev_window_run_presentation (ev_window);
+ break;
+ case EV_WINDOW_MODE_PREVIEW:
+ ev_window_run_preview (ev_window);
+ break;
+ default:
+ break;
+ }
+
+ if (ev_window->priv->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),
+ ev_window->priv->search_string);
+ }
+
+ g_free (ev_window->priv->search_string);
+ ev_window->priv->search_string = NULL;
+
+ /* Create a monitor for the document */
+ ev_window->priv->monitor = ev_file_monitor_new (ev_window->priv->uri);
+ g_signal_connect_swapped (ev_window->priv->monitor, "changed",
+ G_CALLBACK (ev_window_document_changed),
+ ev_window);
+
+ ev_window_clear_load_job (ev_window);
+ return;
+ }
+
+ if (job->error->domain == EV_DOCUMENT_ERROR &&
+ job->error->code == EV_DOCUMENT_ERROR_ENCRYPTED) {
+ gchar *password;
+
+ setup_view_from_metadata (ev_window);
+
+ /* First look whether password is in keyring */
+ password = ev_keyring_lookup_password (ev_window->priv->uri);
+ if (password) {
+ if (job_load->password && strcmp (password, job_load->password) == 0) {
+ /* Password in kering is wrong */
+ ev_job_load_set_password (job_load, NULL);
+ /* FIXME: delete password from keyring? */
+ } else {
+ ev_job_load_set_password (job_load, password);
+ ev_job_scheduler_push_job (job, EV_JOB_PRIORITY_NONE);
+ g_free (password);
+ return;
+ }
+
+ g_free (password);
+ }
+
+ /* We need to ask the user for a password */
+ ev_window_title_set_uri (ev_window->priv->title,
+ ev_window->priv->uri);
+ ev_window_title_set_type (ev_window->priv->title,
+ EV_WINDOW_TITLE_PASSWORD);
+
+ ev_password_view_set_uri (EV_PASSWORD_VIEW (ev_window->priv->password_view),
+ job_load->uri);
+
+ ev_window_set_page_mode (ev_window, PAGE_MODE_PASSWORD);
+
+ ev_job_load_set_password (job_load, NULL);
+ ev_password_view_ask_password (EV_PASSWORD_VIEW (ev_window->priv->password_view));
+ } else {
+ ev_window_error_message (ev_window, job->error,
+ "%s", _("Unable to open document"));
+ ev_window_clear_load_job (ev_window);
+ }
+}
+
+static void
+ev_window_reload_job_cb (EvJob *job,
+ EvWindow *ev_window)
+{
+ GtkWidget *widget;
+
+ if (ev_job_is_failed (job)) {
+ ev_window_clear_reload_job (ev_window);
+ ev_window->priv->in_reload = FALSE;
+ return;
+ }
+
+ ev_window_set_document (ev_window, 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;
+}
+
+/**
+ * ev_window_get_uri:
+ * @ev_window: The instance of the #EvWindow.
+ *
+ * It returns the uri of the document showed in the #EvWindow.
+ *
+ * Returns: the uri of the document showed in the #EvWindow.
+ */
+const char *
+ev_window_get_uri (EvWindow *ev_window)
+{
+ return ev_window->priv->uri;
+}
+
+/**
+ * ev_window_close_dialogs:
+ * @ev_window: The window where dialogs will be closed.
+ *
+ * It looks for password, print and properties dialogs and closes them and
+ * frees them from memory. If there is any print job it does free it too.
+ */
+static void
+ev_window_close_dialogs (EvWindow *ev_window)
+{
+ if (ev_window->priv->print_dialog)
+ gtk_widget_destroy (ev_window->priv->print_dialog);
+ ev_window->priv->print_dialog = NULL;
+
+ if (ev_window->priv->properties)
+ gtk_widget_destroy (ev_window->priv->properties);
+ ev_window->priv->properties = NULL;
+}
+
+static void
+ev_window_clear_progress_idle (EvWindow *ev_window)
+{
+ if (ev_window->priv->progress_idle > 0)
+ g_source_remove (ev_window->priv->progress_idle);
+ ev_window->priv->progress_idle = 0;
+}
+
+static void
+reset_progress_idle (EvWindow *ev_window)
+{
+ ev_window->priv->progress_idle = 0;
+}
+
+static void
+ev_window_show_progress_message (EvWindow *ev_window,
+ guint interval,
+ GSourceFunc function)
+{
+ if (ev_window->priv->progress_idle > 0)
+ g_source_remove (ev_window->priv->progress_idle);
+ ev_window->priv->progress_idle =
+ g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
+ interval, function,
+ ev_window,
+ (GDestroyNotify)reset_progress_idle);
+}
+
+static void
+ev_window_reset_progress_cancellable (EvWindow *ev_window)
+{
+ if (ev_window->priv->progress_cancellable)
+ g_cancellable_reset (ev_window->priv->progress_cancellable);
+ else
+ ev_window->priv->progress_cancellable = g_cancellable_new ();
+}
+
+static void
+ev_window_progress_response_cb (EvProgressMessageArea *area,
+ gint response,
+ EvWindow *ev_window)
+{
+ if (response == GTK_RESPONSE_CANCEL)
+ g_cancellable_cancel (ev_window->priv->progress_cancellable);
+ ev_window_set_message_area (ev_window, NULL);
+}
+
+static gboolean
+show_loading_progress (EvWindow *ev_window)
+{
+ GtkWidget *area;
+ gchar *text;
+
+ if (ev_window->priv->message_area)
+ return FALSE;
+
+ text = g_strdup_printf (_("Loading document from %s"),
+ ev_window->priv->uri);
+ area = ev_progress_message_area_new (GTK_STOCK_OPEN,
+ text,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ NULL);
+ g_signal_connect (area, "response",
+ G_CALLBACK (ev_window_progress_response_cb),
+ ev_window);
+ gtk_widget_show (area);
+ ev_window_set_message_area (ev_window, area);
+ g_free (text);
+
+ return FALSE;
+}
+
+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 (ev_window, error,
+ "%s", _("Unable to open document"));
+ g_free (ev_window->priv->local_uri);
+ ev_window->priv->local_uri = NULL;
+ ev_window->priv->uri_mtime = 0;
+}
+
+static void
+set_uri_mtime (GFile *source,
+ GAsyncResult *async_result,
+ EvWindow *ev_window)
+{
+ GFileInfo *info;
+ GError *error = NULL;
+
+ info = g_file_query_info_finish (source, async_result, &error);
+
+ if (error) {
+ ev_window->priv->uri_mtime = 0;
+ g_error_free (error);
+ } else {
+ GTimeVal mtime;
+
+ g_file_info_get_modification_time (info, &mtime);
+ ev_window->priv->uri_mtime = mtime.tv_sec;
+ g_object_unref (info);
+ }
+
+ g_object_unref (source);
+}
+
+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)
+{
+ GError *error = NULL;
+
+ ev_window_clear_progress_idle (ev_window);
+
+ g_file_copy_finish (source, async_result, &error);
+ if (!error) {
+ ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
+ g_file_query_info_async (source,
+ G_FILE_ATTRIBUTE_TIME_MODIFIED,
+ 0, G_PRIORITY_DEFAULT,
+ NULL,
+ (GAsyncReadyCallback)set_uri_mtime,
+ ev_window);
+ 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 if (error->domain == G_IO_ERROR &&
+ error->code == G_IO_ERROR_CANCELLED) {
+ ev_window_clear_load_job (ev_window);
+ ev_window_clear_local_uri (ev_window);
+ ev_window_clear_print_settings_file (ev_window);
+ g_free (ev_window->priv->uri);
+ ev_window->priv->uri = NULL;
+ g_object_unref (source);
+
+ ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
+ } else {
+ ev_window_load_remote_failed (ev_window, error);
+ g_object_unref (source);
+ }
+
+ g_error_free (error);
+}
+
+static void
+window_open_file_copy_progress_cb (goffset n_bytes,
+ goffset total_bytes,
+ EvWindow *ev_window)
+{
+ gchar *status;
+ gdouble fraction;
+
+ if (!ev_window->priv->message_area)
+ return;
+
+ fraction = n_bytes / (gdouble)total_bytes;
+ status = g_strdup_printf (_("Downloading document (%d%%)"),
+ (gint)(fraction * 100));
+
+ ev_progress_message_area_set_status (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
+ status);
+ ev_progress_message_area_set_fraction (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
+ fraction);
+
+ g_free (status);
+}
+
+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);
+ }
+
+ ev_window_reset_progress_cancellable (ev_window);
+
+ target_file = g_file_new_for_uri (ev_window->priv->local_uri);
+ g_file_copy_async (source_file, target_file,
+ 0, G_PRIORITY_DEFAULT,
+ ev_window->priv->progress_cancellable,
+ (GFileProgressCallback)window_open_file_copy_progress_cb,
+ ev_window,
+ (GAsyncReadyCallback)window_open_file_copy_ready_cb,
+ ev_window);
+ g_object_unref (target_file);
+
+ ev_window_show_progress_message (ev_window, 1,
+ (GSourceFunc)show_loading_progress);
+}
+
+void
+ev_window_open_uri (EvWindow *ev_window,
+ const char *uri,
+ EvLinkDest *dest,
+ EvWindowRunMode mode,
+ const gchar *search_string,
+ gboolean unlink_temp_file,
+ const gchar *print_settings)
+{
+ GFile *source_file;
+
+ ev_window->priv->in_reload = FALSE;
+
+ if (ev_window->priv->uri &&
+ g_ascii_strcasecmp (ev_window->priv->uri, uri) == 0) {
+ 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_clear_load_job (ev_window);
+ ev_window_clear_local_uri (ev_window);
+ ev_window_clear_print_settings_file (ev_window);
+ ev_view_set_loading (EV_VIEW (ev_window->priv->view), TRUE);
+
+ ev_window->priv->unlink_temp_file = unlink_temp_file;
+ ev_window->priv->window_mode = mode;
+
+ if (mode == EV_WINDOW_MODE_PREVIEW) {
+ ev_window->priv->print_settings_file = print_settings ?
+ g_strdup (print_settings) : NULL;
+ }
+
+ if (ev_window->priv->uri)
+ g_free (ev_window->priv->uri);
+ ev_window->priv->uri = g_strdup (uri);
+
+ if (ev_window->priv->search_string)
+ g_free (ev_window->priv->search_string);
+ ev_window->priv->search_string = search_string ?
+ g_strdup (search_string) : NULL;
+
+ if (ev_window->priv->dest)
+ g_object_unref (ev_window->priv->dest);
+ ev_window->priv->dest = dest ? g_object_ref (dest) : NULL;
+
+ setup_size_from_metadata (ev_window);
+
+ ev_window->priv->load_job = ev_job_load_new (uri);
+ g_signal_connect (ev_window->priv->load_job,
+ "finished",
+ G_CALLBACK (ev_window_load_job_cb),
+ ev_window);
+
+ source_file = g_file_new_for_uri (uri);
+ if (!g_file_is_native (source_file) && !ev_window->priv->local_uri) {
+ ev_window_load_file_remote (ev_window, source_file);
+ } else {
+ g_object_unref (source_file);
+ ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
+ }
+}
+
+static void
+ev_window_reload_local (EvWindow *ev_window)
+{
+ const gchar *uri;
+
+ 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);
+ g_signal_connect (ev_window->priv->reload_job, "finished",
+ G_CALLBACK (ev_window_reload_job_cb),
+ ev_window);
+ ev_job_scheduler_push_job (ev_window->priv->reload_job, EV_JOB_PRIORITY_NONE);
+}
+
+static gboolean
+show_reloading_progress (EvWindow *ev_window)
+{
+ GtkWidget *area;
+ gchar *text;
+
+ if (ev_window->priv->message_area)
+ return FALSE;
+
+ text = g_strdup_printf (_("Reloading document from %s"),
+ ev_window->priv->uri);
+ area = ev_progress_message_area_new (GTK_STOCK_REFRESH,
+ text,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ NULL);
+ g_signal_connect (area, "response",
+ G_CALLBACK (ev_window_progress_response_cb),
+ ev_window);
+ gtk_widget_show (area);
+ ev_window_set_message_area (ev_window, area);
+ g_free (text);
+
+ return FALSE;
+}
+
+static void
+reload_remote_copy_ready_cb (GFile *remote,
+ GAsyncResult *async_result,
+ EvWindow *ev_window)
+{
+ GError *error = NULL;
+
+ ev_window_clear_progress_idle (ev_window);
+
+ g_file_copy_finish (remote, async_result, &error);
+ if (error) {
+ if (error->domain != G_IO_ERROR ||
+ error->code != G_IO_ERROR_CANCELLED)
+ ev_window_error_message (ev_window, error,
+ "%s", _("Failed to reload document."));
+ g_error_free (error);
+ } else {
+ ev_window_reload_local (ev_window);
+ }
+
+ g_object_unref (remote);
+}
+
+static void
+reload_remote_copy_progress_cb (goffset n_bytes,
+ goffset total_bytes,
+ EvWindow *ev_window)
+{
+ gchar *status;
+ gdouble fraction;
+
+ if (!ev_window->priv->message_area)
+ return;
+
+ fraction = n_bytes / (gdouble)total_bytes;
+ status = g_strdup_printf (_("Downloading document (%d%%)"),
+ (gint)(fraction * 100));
+
+ ev_progress_message_area_set_status (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
+ status);
+ ev_progress_message_area_set_fraction (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
+ fraction);
+
+ g_free (status);
+}
+
+static void
+query_remote_uri_mtime_cb (GFile *remote,
+ GAsyncResult *async_result,
+ EvWindow *ev_window)
+{
+ GFileInfo *info;
+ GTimeVal mtime;
+ GError *error = NULL;
+
+ info = g_file_query_info_finish (remote, async_result, &error);
+ if (error) {
+ g_error_free (error);
+ g_object_unref (remote);
+ ev_window_reload_local (ev_window);
+
+ return;
+ }
+
+ g_file_info_get_modification_time (info, &mtime);
+ if (ev_window->priv->uri_mtime != mtime.tv_sec) {
+ GFile *target_file;
+
+ /* Remote file has changed */
+ ev_window->priv->uri_mtime = mtime.tv_sec;
+
+ ev_window_reset_progress_cancellable (ev_window);
+
+ target_file = g_file_new_for_uri (ev_window->priv->local_uri);
+ g_file_copy_async (remote, target_file,
+ G_FILE_COPY_OVERWRITE,
+ G_PRIORITY_DEFAULT,
+ ev_window->priv->progress_cancellable,
+ (GFileProgressCallback)reload_remote_copy_progress_cb,
+ ev_window,
+ (GAsyncReadyCallback)reload_remote_copy_ready_cb,
+ ev_window);
+ g_object_unref (target_file);
+ ev_window_show_progress_message (ev_window, 1,
+ (GSourceFunc)show_reloading_progress);
+ } else {
+ g_object_unref (remote);
+ ev_window_reload_local (ev_window);