evince r3316 - in trunk: . shell



Author: carlosgc
Date: Tue Dec 30 16:12:59 2008
New Revision: 3316
URL: http://svn.gnome.org/viewvc/evince?rev=3316&view=rev

Log:
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.

Modified:
   trunk/ChangeLog
   trunk/shell/ev-window.c

Modified: trunk/shell/ev-window.c
==============================================================================
--- trunk/shell/ev-window.c	(original)
+++ trunk/shell/ev-window.c	Tue Dec 30 16:12:59 2008
@@ -115,6 +115,12 @@
 	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 @@
 	GtkWidget *sidebar_attachments;
 	GtkWidget *sidebar_layers;
 
+	/* Progress Messages */
+	guint progress_idle;
+	GCancellable *progress_cancellable;
+
 	/* Dialogs */
 	GtkWidget *properties;
 	GtkWidget *print_dialog;
@@ -1520,6 +1530,81 @@
 }
 
 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 @@
 				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 @@
 					       (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 @@
 }
 
 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 @@
 		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,17 +1843,81 @@
 	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,
 			   EvWindow     *ev_window)
@@ -1750,14 +1941,21 @@
 			
 		/* 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 @@
 	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 @@
 	}
 	
 	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 @@
 		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 @@
 		
 		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 @@
 				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);
 		}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]