Commit 0384290a authored by Carlos Garcia Campos's avatar Carlos Garcia Campos Committed by Carlos Garcia Campos

Show progress information when loading/saving remote files. Fixes bug

2008-12-30  Carlos Garcia Campos  <carlosgc@gnome.org>

	* shell/ev-window.c: (ev_window_clear_progress_idle),
	(reset_progress_idle), (ev_window_show_progress_message),
	(ev_window_reset_progress_cancellable),
	(ev_window_progress_response_cb), (show_loading_progress),
	(ev_window_load_remote_failed), (window_open_file_copy_ready_cb),
	(window_open_file_copy_progress_cb), (ev_window_load_file_remote),
	(show_reloading_progress), (reload_remote_copy_ready_cb),
	(reload_remote_copy_progress_cb), (query_remote_uri_mtime_cb),
	(show_saving_progress), (window_save_file_copy_ready_cb),
	(window_save_file_copy_progress_cb), (ev_window_save_remote),
	(ev_window_dispose):

	Show progress information when loading/saving remote files. Fixes
	bug #370958.

svn path=/trunk/; revision=3316
parent b2ad055b
2008-12-30 Carlos Garcia Campos <carlosgc@gnome.org>
* shell/ev-window.c: (ev_window_clear_progress_idle),
(reset_progress_idle), (ev_window_show_progress_message),
(ev_window_reset_progress_cancellable),
(ev_window_progress_response_cb), (show_loading_progress),
(ev_window_load_remote_failed), (window_open_file_copy_ready_cb),
(window_open_file_copy_progress_cb), (ev_window_load_file_remote),
(show_reloading_progress), (reload_remote_copy_ready_cb),
(reload_remote_copy_progress_cb), (query_remote_uri_mtime_cb),
(show_saving_progress), (window_save_file_copy_ready_cb),
(window_save_file_copy_progress_cb), (ev_window_save_remote),
(ev_window_dispose):
Show progress information when loading/saving remote files. Fixes
bug #370958.
2008-12-30 Carlos Garcia Campos <carlosgc@gnome.org>
* libdocument/ev-file-helpers.c: (ev_tmp_file_unlink):
......
......@@ -115,6 +115,12 @@ typedef enum {
EV_CHROME_NORMAL = EV_CHROME_MENUBAR | EV_CHROME_TOOLBAR | EV_CHROME_SIDEBAR
} EvChrome;
typedef enum {
EV_SAVE_DOCUMENT,
EV_SAVE_ATTACHMENT,
EV_SAVE_IMAGE
} EvSaveType;
struct _EvWindowPrivate {
/* UI */
EvChrome chrome;
......@@ -135,6 +141,10 @@ struct _EvWindowPrivate {
GtkWidget *sidebar_attachments;
GtkWidget *sidebar_layers;
/* Progress Messages */
guint progress_idle;
GCancellable *progress_cancellable;
/* Dialogs */
GtkWidget *properties;
GtkWidget *print_dialog;
......@@ -1519,6 +1529,81 @@ ev_window_close_dialogs (EvWindow *ev_window)
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)
......@@ -1582,6 +1667,8 @@ window_open_file_copy_ready_cb (GFile *source,
EvWindow *ev_window)
{
GError *error = NULL;
ev_window_clear_progress_idle (ev_window);
g_file_copy_finish (source, async_result, &error);
if (!error) {
......@@ -1606,6 +1693,16 @@ window_open_file_copy_ready_cb (GFile *source,
(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);
......@@ -1615,8 +1712,31 @@ window_open_file_copy_ready_cb (GFile *source,
}
static void
ev_window_load_file_remote (EvWindow *ev_window,
GFile *source_file)
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;
......@@ -1635,14 +1755,21 @@ ev_window_load_file_remote (EvWindow *ev_window,
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, NULL,
NULL, NULL, /* no progress callback */
(GAsyncReadyCallback) window_open_file_copy_ready_cb,
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
......@@ -1716,16 +1843,80 @@ ev_window_reload_local (EvWindow *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)
{
g_file_copy_finish (remote, async_result, NULL);
ev_window_reload_local (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 reaload 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,
......@@ -1750,14 +1941,21 @@ query_remote_uri_mtime_cb (GFile *remote,
/* 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, NULL,
NULL, NULL, /* no progress callback */
(GAsyncReadyCallback) reload_remote_copy_ready_cb,
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);
......@@ -2137,42 +2335,150 @@ ev_window_setup_recent (EvWindow *ev_window)
g_list_free (items);
}
static gboolean
show_saving_progress (GFile *dst)
{
EvWindow *ev_window;
GtkWidget *area;
gchar *text;
gchar *uri;
EvSaveType save_type;
ev_window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window"));
ev_window->priv->progress_idle = 0;
if (ev_window->priv->message_area)
return FALSE;
save_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dst), "save-type"));
uri = g_file_get_uri (dst);
switch (save_type) {
case EV_SAVE_DOCUMENT:
text = g_strdup_printf (_("Saving document to %s"), uri);
break;
case EV_SAVE_ATTACHMENT:
text = g_strdup_printf (_("Saving attachment to %s"), uri);
break;
case EV_SAVE_IMAGE:
text = g_strdup_printf (_("Saving image to %s"), uri);
break;
default:
g_assert_not_reached ();
}
g_free (uri);
area = ev_progress_message_area_new (GTK_STOCK_SAVE,
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
window_save_file_copy_ready_cb (GFile *src,
GAsyncResult *async_result,
GFile *dst)
{
EvWindow *window;
gchar *name;
GError *error = NULL;
EvWindow *ev_window;
GError *error = NULL;
ev_window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window"));
ev_window_clear_progress_idle (ev_window);
if (g_file_copy_finish (src, async_result, &error)) {
ev_tmp_file_unlink (src);
return;
}
window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window"));
name = g_file_get_basename (dst);
ev_window_error_message (window, error,
_("The file could not be saved as “%s”."),
name);
if (error->domain != G_IO_ERROR ||
error->code != G_IO_ERROR_CANCELLED) {
gchar *name;
name = g_file_get_basename (dst);
ev_window_error_message (ev_window, error,
_("The file could not be saved as “%s”."),
name);
g_free (name);
}
ev_tmp_file_unlink (src);
g_free (name);
g_error_free (error);
}
static void
ev_window_save_remote (EvWindow *ev_window,
GFile *src,
GFile *dst)
window_save_file_copy_progress_cb (goffset n_bytes,
goffset total_bytes,
GFile *dst)
{
EvWindow *ev_window;
EvSaveType save_type;
gchar *status;
gdouble fraction;
ev_window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window"));
if (!ev_window->priv->message_area)
return;
fraction = n_bytes / (gdouble)total_bytes;
save_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dst), "save-type"));
switch (save_type) {
case EV_SAVE_DOCUMENT:
status = g_strdup_printf (_("Uploading document %d%%"),
(gint)(fraction * 100));
break;
case EV_SAVE_ATTACHMENT:
status = g_strdup_printf (_("Uploading attachment %d%%"),
(gint)(fraction * 100));
break;
case EV_SAVE_IMAGE:
status = g_strdup_printf (_("Uploading image %d%%"),
(gint)(fraction * 100));
break;
default:
g_assert_not_reached ();
}
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_save_remote (EvWindow *ev_window,
EvSaveType save_type,
GFile *src,
GFile *dst)
{
ev_window_reset_progress_cancellable (ev_window);
g_object_set_data (G_OBJECT (dst), "ev-window", ev_window);
g_object_set_data (G_OBJECT (dst), "save-type", GINT_TO_POINTER (save_type));
g_file_copy_async (src, dst,
G_FILE_COPY_OVERWRITE,
G_PRIORITY_DEFAULT, NULL,
NULL, NULL, /* no progress callback */
(GAsyncReadyCallback) window_save_file_copy_ready_cb,
dst);
G_PRIORITY_DEFAULT,
ev_window->priv->progress_cancellable,
(GFileProgressCallback)window_save_file_copy_progress_cb,
dst,
(GAsyncReadyCallback)window_save_file_copy_ready_cb,
dst);
ev_window->priv->progress_idle =
g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
1,
(GSourceFunc)show_saving_progress,
dst,
NULL);
}
static void
......@@ -2216,6 +2522,9 @@ file_save_dialog_response_cb (GtkWidget *fc,
}
uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc));
/* FIXME: remote copy should be done here rather than in the save job,
* so that we can track progress and cancel the operation
*/
ev_window_clear_save_job (ev_window);
ev_window->priv->save_job = ev_job_save_new (ev_window->priv->document,
......@@ -4495,6 +4804,12 @@ ev_window_dispose (GObject *object)
priv->local_uri = NULL;
}
ev_window_clear_progress_idle (window);
if (priv->progress_cancellable) {
g_object_unref (priv->progress_cancellable);
priv->progress_cancellable = NULL;
}
ev_window_close_dialogs (window);
if (window->priv->printer) {
......@@ -5334,7 +5649,8 @@ image_save_dialog_response_cb (GtkWidget *fc,
source_file = g_file_new_for_path (filename);
ev_window_save_remote (ev_window, source_file, target_file);
ev_window_save_remote (ev_window, EV_SAVE_IMAGE,
source_file, target_file);
g_object_unref (source_file);
}
......@@ -5481,7 +5797,8 @@ attachment_save_dialog_response_cb (GtkWidget *fc,
dest_file = g_object_ref (target_file);
}
ev_window_save_remote (ev_window, save_to, dest_file);
ev_window_save_remote (ev_window, EV_SAVE_ATTACHMENT,
save_to, dest_file);
g_object_unref (dest_file);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment