Re: PATCH: use timeouts for progress dialogs



Again a slightly updated patch that stops the show timeout while we are
waiting for user input and resumes it afterwards. This way if you are
copying one file and you get the overwrite confirmation we don't have to
pop up the progress dialog before showing the confirmation. It looks way
better this way.

- Frank


On Sun, 2002-07-28 at 22:51, Frank Worsley wrote:
> Here is a slightly updated patch that also makes sure the dialog is
> shown before we display an overwrite confirm window (not only a xfer
> error window).
> 
> - Frank
> 
> 
> On Sun, 2002-07-28 at 22:36, Frank Worsley wrote:
> > Hi all,
> > 
> > one of the main reasons I think Nautilus feels sluggish sometimes is
> > that it pops up a progress dialog for every copy/move/link I perform,
> > even if it's just a single file being moved. That's quite annoying since
> > the dialog appears only to disappear again right away.
> > 
> > The attached patch makes nautilus-file-operations-progress use a timeout
> > for displaying itself. If the operation isn't done within 1200
> > milliseconds a dialog will be displayed. This also makes sure we don't
> > actually do the work to build the dialog UI if it isn't going to be
> > displayed, the UI is only created when the dialog receives a 'realize'
> > event.
> > 
> > This patch makes simple file operations feel a whole lot snappier on my
> > machine. Ok to commit as is?
> > 
> > - Frank
> 
> ----
> 

> Index: ChangeLog
> ===================================================================
> RCS file: /cvs/gnome/nautilus/ChangeLog,v
> retrieving revision 1.5464
> diff -u -p -r1.5464 ChangeLog
> --- ChangeLog	28 Jul 2002 03:06:22 -0000	1.5464
> +++ ChangeLog	29 Jul 2002 05:50:09 -0000
> @@ -1,3 +1,23 @@
> +2002-07-28  Frank Worsley  <fworsley shaw ca>
> +
> +	* libnautilus-private/nautilus-file-operations-progress.h:
> +	* libnautilus-private/nautilus-file-operations-progress.c:
> +	(nautilus_file_operations_progress_update_icon),
> +	(nautilus_file_operations_progress_update),
> +	(nautilus_file_operations_progress_destroy), (create_ui),
> +	(nautilus_file_operations_progress_init), (delayed_show_callback),
> +	(nautilus_file_operations_progress_new),
> +	(nautilus_file_operations_progress_set_operation_string),
> +	(nautilus_file_operations_progress_new_file),
> +	(nautilus_file_operations_progress_clear):
> +	use a timeout to display the progress dialog, this makes it more
> +	consistent as to when we show a dialog
> +
> +	* libnautilus-private/nautilus-file-operations.c:
> +	(create_transfer_dialog), (nautilus_file_operations_copy_move),
> +	(nautilus_file_operations_delete), (do_empty_trash):
> +	use timeout instead of explicitly showing progress dialog
> +
>  2002-07-27  Dave Camp  <dave ximian com>
>  
>  	* libnautilus-private/nautilus-icon-factory.c
> Index: libnautilus-private/nautilus-file-operations-progress.c
> ===================================================================
> RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-operations-progress.c,v
> retrieving revision 1.36
> diff -u -p -r1.36 nautilus-file-operations-progress.c
> --- libnautilus-private/nautilus-file-operations-progress.c	17 Apr 2002 12:29:10 -0000	1.36
> +++ libnautilus-private/nautilus-file-operations-progress.c	29 Jul 2002 05:50:10 -0000
> @@ -87,8 +87,26 @@ struct NautilusFileOperationsProgressDet
>  	gint64 start_time;
>  
>  	guint delayed_close_timeout_id;
> +	guint delayed_show_timeout_id;
>  
>  	int progress_jar_position;
> +	
> +	/* this is set to true when the widget is first shown and
> +	 * the ui is created. ideally the operation is fast and the
> +	 * widget is never shown so we don't waste time building
> +	 * its ui.
> +	 */
> +	gboolean ui_ready;
> +	
> +	/* stuff we might need at ui creation time */
> +	char *operation_string;
> +	char *progress_verb;
> +	char *file_item_name;
> +	char *from_path;
> +	char *to_path;
> +	gulong file_index;
> +	gulong size;
> +	gboolean new_file;	
>  };
>  
>  /* Private functions. */
> @@ -100,6 +118,10 @@ nautilus_file_operations_progress_update
>  	GdkPixbuf *pixbuf;
>  	int position;
>  
> +	if (!progress->details->ui_ready) {
> +		return;
> +	}
> +
>  	position = gdk_pixbuf_get_height (empty_jar_pixbuf) * (1 - fraction);
>  
>  	if (position == progress->details->progress_jar_position) {
> @@ -124,6 +146,10 @@ static void
>  nautilus_file_operations_progress_update (NautilusFileOperationsProgress *progress)
>  {
>  	double fraction;
> +
> +	if (!progress->details->ui_ready) {
> +		return;
> +	}
>  	
>  	if (progress->details->bytes_total == 0) {
>  		/* We haven't set up the file count yet, do not update
> @@ -191,6 +217,11 @@ nautilus_file_operations_progress_destro
>  		progress->details->delayed_close_timeout_id = 0;
>  	}
>  	
> +	if (progress->details->delayed_show_timeout_id != 0) {
> +		g_source_remove (progress->details->delayed_show_timeout_id);
> +		progress->details->delayed_show_timeout_id = 0;
> +	}
> +	
>  	EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object));
>  }
>  
> @@ -242,13 +273,20 @@ delete_event_callback (GtkWidget *widget
>  }
>  
>  static void
> -nautilus_file_operations_progress_init (NautilusFileOperationsProgress *progress)
> +create_ui (NautilusFileOperationsProgress *progress, gpointer callback_data)
>  {
>  	GtkWidget *hbox, *vbox;
>  	GtkTable *titled_label_table;
>  
> -	progress->details = g_new0 (NautilusFileOperationsProgressDetails, 1);
> -
> +	if (progress->details->ui_ready) {
> +		return;
> +	}
> +	
> +	if (progress->details->delayed_show_timeout_id != 0) {
> +		g_source_remove (progress->details->delayed_show_timeout_id);
> +		progress->details->delayed_show_timeout_id = 0;
> +	}
> +	
>  	vbox = gtk_vbox_new (FALSE, VERTICAL_SPACING);
>  	gtk_container_set_border_width (GTK_CONTAINER (vbox), OUTER_BORDER);
>  	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (progress)->vbox), vbox, TRUE, TRUE, VERTICAL_SPACING);
> @@ -298,7 +336,44 @@ nautilus_file_operations_progress_init (
>  	/* Set progress jar position */
>  	progress->details->progress_jar_position = gdk_pixbuf_get_height (empty_jar_pixbuf);
>  
> +	progress->details->ui_ready = TRUE;
> +	
> +	if (progress->details->operation_string != NULL) {
> +		nautilus_file_operations_progress_set_operation_string
> +				(progress, progress->details->operation_string);
> +		g_free (progress->details->operation_string);
> +	}
> +	
> +	if (progress->details->new_file) {
> +		nautilus_file_operations_progress_new_file
> +				(progress,
> +				 progress->details->progress_verb,
> +				 progress->details->file_item_name,
> +				 progress->details->from_path,
> +				 progress->details->to_path,
> +				 progress->details->from_prefix,
> +				 progress->details->to_prefix,
> +				 progress->details->file_index,
> +				 progress->details->size);
> +
> +		g_free (progress->details->progress_verb);
> +		g_free (progress->details->file_item_name);
> +		g_free (progress->details->from_path);
> +		g_free (progress->details->to_path);
> +	}		 
> +
>  	gtk_widget_show_all (vbox);
> +}	
> +
> +
> +static void
> +nautilus_file_operations_progress_init (NautilusFileOperationsProgress *progress)
> +{
> +	progress->details = g_new0 (NautilusFileOperationsProgressDetails, 1);
> +
> +	progress->details->ui_ready = FALSE;
> +	
> +	g_signal_connect (progress, "realize", G_CALLBACK (create_ui), NULL);
>  }
>  
>  static void
> @@ -335,13 +410,29 @@ nautilus_file_operations_progress_class_
>  	
>  }
>  
> +static gboolean
> +delayed_show_callback (gpointer callback_data)
> +{
> +	NautilusFileOperationsProgress *progress;
> +	
> +	progress = NAUTILUS_FILE_OPERATIONS_PROGRESS (callback_data);
> +	
> +	progress->details->delayed_show_timeout_id = 0;
> +	
> +	create_ui (progress, NULL);
> +	gtk_widget_show (GTK_WIDGET (progress));
> +	
> +	return FALSE;
> +}
> +
>  NautilusFileOperationsProgress *
>  nautilus_file_operations_progress_new (const char *title,
>  				       const char *operation_string,
>  				       const char *from_prefix,
>  				       const char *to_prefix,
>  				       gulong total_files,
> -				       gulong total_bytes)
> +				       gulong total_bytes,
> +				       gboolean use_timeout)
>  {
>  	GtkWidget *widget;
>  	NautilusFileOperationsProgress *progress;
> @@ -359,6 +450,11 @@ nautilus_file_operations_progress_new (c
>  
>  	progress->details->from_prefix = from_prefix;
>  	progress->details->to_prefix = to_prefix;
> +
> +	if (use_timeout) {
> +		progress->details->delayed_show_timeout_id =
> +			g_timeout_add (1200, delayed_show_callback, progress);
> +	}
>  	
>  	return progress;
>  }
> @@ -382,6 +478,12 @@ nautilus_file_operations_progress_set_op
>  {
>  	g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress));
>  
> +	if (!progress->details->ui_ready) {
> +		g_free (progress->details->operation_string);	
> +		progress->details->operation_string = g_strdup (operation_string);
> +		return;
> +	}
> +
>  	gtk_label_set_text (GTK_LABEL (progress->details->progress_title_label),
>  			    operation_string);
>  }
> @@ -400,11 +502,25 @@ nautilus_file_operations_progress_new_fi
>  	char *progress_count;
>  
>  	g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress));
> -	g_return_if_fail (GTK_WIDGET_REALIZED (progress));
>  
>  	progress->details->from_prefix = from_prefix;
>  	progress->details->to_prefix = to_prefix;
>  
> +	if (!progress->details->ui_ready) {
> +		g_free (progress->details->progress_verb);
> +		g_free (progress->details->file_item_name);
> +		g_free (progress->details->from_path);
> +		g_free (progress->details->to_path);
> +		progress->details->progress_verb = g_strdup (progress_verb);
> +		progress->details->file_item_name = g_strdup (item_name);
> +		progress->details->from_path = g_strdup (from_path);
> +		progress->details->to_path = g_strdup (to_path);
> +		progress->details->file_index = file_index;
> +		progress->details->size = size;
> +		progress->details->new_file = TRUE;
> +		return;
> +	}
> +
>  	if (progress->details->bytes_total > 0) {
>  		/* we haven't set up the file count yet, do not update the progress
>  		 * count until we do
> @@ -438,6 +554,10 @@ nautilus_file_operations_progress_new_fi
>  void
>  nautilus_file_operations_progress_clear (NautilusFileOperationsProgress *progress)
>  {
> +	if (!progress->details->ui_ready) {
> +		return;
> +	}
> +
>  	gtk_label_set_text (GTK_LABEL (progress->details->from_label), "");
>  	gtk_label_set_text (GTK_LABEL (progress->details->from_path_label), "");
>  	gtk_label_set_text (GTK_LABEL (progress->details->to_label), "");
> Index: libnautilus-private/nautilus-file-operations-progress.h
> ===================================================================
> RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-operations-progress.h,v
> retrieving revision 1.10
> diff -u -p -r1.10 nautilus-file-operations-progress.h
> --- libnautilus-private/nautilus-file-operations-progress.h	27 Nov 2001 01:46:16 -0000	1.10
> +++ libnautilus-private/nautilus-file-operations-progress.h	29 Jul 2002 05:50:10 -0000
> @@ -55,7 +55,8 @@ NautilusFileOperationsProgress *nautilus
>  											const char                     *from_prefix,
>  											const char                     *to_prefix,
>  											gulong                          files_total,
> -											gulong                          bytes_total);
> +											gulong                          bytes_total,
> +											gboolean			use_timeout);
>  void                            nautilus_file_operations_progress_done                 (NautilusFileOperationsProgress *dialog);
>  void                            nautilus_file_operations_progress_set_progress_title   (NautilusFileOperationsProgress *dialog,
>  											const char                     *progress_title);
> Index: libnautilus-private/nautilus-file-operations.c
> ===================================================================
> RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-operations.c,v
> retrieving revision 1.153
> diff -u -p -r1.153 nautilus-file-operations.c
> --- libnautilus-private/nautilus-file-operations.c	12 Jul 2002 18:36:13 -0000	1.153
> +++ libnautilus-private/nautilus-file-operations.c	29 Jul 2002 05:50:10 -0000
> @@ -73,7 +73,6 @@ typedef struct {
>  	GnomeVFSXferOverwriteMode overwrite_mode;
>  	GtkWidget *parent_view;
>  	TransferKind kind;
> -	gboolean show_progress_dialog;
>  	void (* done_callback) (GHashTable *debuting_uris, gpointer data);
>  	gpointer done_callback_data;
>  	GHashTable *debuting_uris;
> @@ -280,14 +279,10 @@ static void
>  create_transfer_dialog (const GnomeVFSXferProgressInfo *progress_info,
>  			TransferInfo *transfer_info)
>  {
> -	if (!transfer_info->show_progress_dialog) {
> -		return;
> -	}
> -
>  	g_return_if_fail (transfer_info->progress_dialog == NULL);
>  
>  	transfer_info->progress_dialog = nautilus_file_operations_progress_new 
> -		(transfer_info->operation_title, "", "", "", 0, 0);
> +		(transfer_info->operation_title, "", "", "", 0, 0, TRUE);
>  
>  	/* Treat clicking on the close box or use of the escape key
>  	 * the same as clicking cancel.
> @@ -307,8 +302,6 @@ create_transfer_dialog (const GnomeVFSXf
>  			GTK_WINDOW (transfer_info->progress_dialog), 
>  			GTK_WINDOW (gtk_widget_get_toplevel (transfer_info->parent_view)));
>  	}
> -
> -	gtk_widget_show (GTK_WIDGET (transfer_info->progress_dialog));
>  }
>  
>  static void
> @@ -800,6 +793,12 @@ handle_transfer_vfs_error (const GnomeVF
>  
>  		/* transfer error, prompt the user to continue or stop */
>  
> +		/* make sure the progress dialog is shown at this point,
> +		 * otherwise it might show up behind the error window 
> +		 * which looks stupid.
> +		 */
> +		gtk_widget_show (GTK_WIDGET (transfer_info->progress_dialog));
> +
>  		formatted_source_name = NULL;
>  		formatted_target_name = NULL;
>  
> @@ -999,6 +998,9 @@ handle_transfer_overwrite (const GnomeVF
>  	int result;
>  	char *text, *formatted_name;
>  
> +	/* make sure progress dialog is shown at this point */
> +	gtk_widget_show (GTK_WIDGET (transfer_info->progress_dialog));
> +
>  	/* Handle special case files such as Trash, mount links and home directory */	
>  	if (is_special_link (progress_info->target_name)) {
>  		formatted_name = extract_and_ellipsize_file_name_for_dialog
> @@ -1688,7 +1690,6 @@ nautilus_file_operations_copy_move (cons
>  	gboolean target_is_trash;
>  	gboolean is_desktop_trash_link;
>  	gboolean duplicate;
> -	gboolean all_local;
>  	
>  	IconPositionIterator *icon_position_iterator;
>  
> @@ -1712,7 +1713,6 @@ nautilus_file_operations_copy_move (cons
>  	 */
>  	source_uri_list = NULL;
>  	target_uri_list = NULL;
> -	all_local = TRUE;
>  	duplicate = copy_action != GDK_ACTION_MOVE;
>  	for (p = item_uris; p != NULL; p = p->next) {
>  		/* Filter out special Nautilus link files */
> @@ -1750,11 +1750,6 @@ nautilus_file_operations_copy_move (cons
>  			target_uri_list = g_list_prepend (target_uri_list, target_uri);
>  			source_uri_list = g_list_prepend (source_uri_list, source_uri);
>  
> -			if (all_local && (!gnome_vfs_uri_is_local (source_uri)
> -					  || !gnome_vfs_uri_is_local (target_uri))) {
> -				all_local = FALSE;
> -			}
> -
>  			if (duplicate
>  			    && !gnome_vfs_uri_equal (source_dir_uri, target_dir_uri)) {
>  				duplicate = FALSE;
> @@ -1823,11 +1818,6 @@ nautilus_file_operations_copy_move (cons
>  
>  		transfer_info->kind = TRANSFER_MOVE_TO_TRASH;
>  
> -		/* Do an arbitrary guess that an operation will take very little
> -		 * time and the progress shouldn't be shown.
> -		 */
> -		transfer_info->show_progress_dialog = 
> -			!all_local || g_list_length ((GList *) item_uris) > 20;
>  	} else if ((move_options & GNOME_VFS_XFER_REMOVESOURCE) != 0) {
>  		/* localizers: progress dialog title */
>  		transfer_info->operation_title = _("Moving files");
> @@ -1840,11 +1830,6 @@ nautilus_file_operations_copy_move (cons
>  
>  		transfer_info->kind = TRANSFER_MOVE;
>  
> -		/* Do an arbitrary guess that an operation will take very little
> -		 * time and the progress shouldn't be shown.
> -		 */
> -		transfer_info->show_progress_dialog = 
> -			!all_local || g_list_length ((GList *) item_uris) > 20;
>  	} else if ((move_options & GNOME_VFS_XFER_LINK_ITEMS) != 0) {
>  		/* when creating links, handle name conflicts automatically */
>  		move_options |= GNOME_VFS_XFER_USE_UNIQUE_NAMES;
> @@ -1858,8 +1843,7 @@ nautilus_file_operations_copy_move (cons
>  		transfer_info->cleanup_name = _("Finishing Creating Links...");
>  
>  		transfer_info->kind = TRANSFER_LINK;
> -		transfer_info->show_progress_dialog =
> -			g_list_length ((GList *)item_uris) > 20;
> +
>  	} else {
>  		/* localizers: progress dialog title */
>  		transfer_info->operation_title = _("Copying files");
> @@ -1871,8 +1855,6 @@ nautilus_file_operations_copy_move (cons
>  		transfer_info->cleanup_name = "";
>  
>  		transfer_info->kind = TRANSFER_COPY;
> -		/* always show progress during copy */
> -		transfer_info->show_progress_dialog = TRUE;
>  	}
>  
>  	/* we'll need to check for copy into Trash and for moving/copying the Trash itself */
> @@ -2140,7 +2122,6 @@ nautilus_file_operations_delete (const G
>  	uri_list = g_list_reverse (uri_list);
>  
>  	transfer_info = transfer_info_new (parent_view);
> -	transfer_info->show_progress_dialog = TRUE;
>  
>  	/* localizers: progress dialog title */
>  	transfer_info->operation_title = _("Deleting files");
> @@ -2176,7 +2157,6 @@ do_empty_trash (GtkWidget *parent_view)
>  	if (trash_dir_list != NULL) {
>  		/* set up the move parameters */
>  		transfer_info = transfer_info_new (parent_view);
> -		transfer_info->show_progress_dialog = TRUE;
>  
>  		/* localizers: progress dialog title */
>  		transfer_info->operation_title = _("Emptying the Trash");

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/nautilus/ChangeLog,v
retrieving revision 1.5464
diff -u -p -r1.5464 ChangeLog
--- ChangeLog	28 Jul 2002 03:06:22 -0000	1.5464
+++ ChangeLog	29 Jul 2002 19:13:12 -0000
@@ -1,3 +1,23 @@
+2002-07-28  Frank Worsley  <fworsley shaw ca>
+
+	* libnautilus-private/nautilus-file-operations-progress.h:
+	* libnautilus-private/nautilus-file-operations-progress.c:
+	(nautilus_file_operations_progress_update_icon),
+	(nautilus_file_operations_progress_update),
+	(nautilus_file_operations_progress_destroy), (create_ui),
+	(nautilus_file_operations_progress_init), (delayed_show_callback),
+	(nautilus_file_operations_progress_new),
+	(nautilus_file_operations_progress_set_operation_string),
+	(nautilus_file_operations_progress_new_file),
+	(nautilus_file_operations_progress_clear):
+	use a timeout to display the progress dialog, this makes it more
+	consistent as to when we show a dialog
+
+	* libnautilus-private/nautilus-file-operations.c:
+	(create_transfer_dialog), (nautilus_file_operations_copy_move),
+	(nautilus_file_operations_delete), (do_empty_trash):
+	use timeout instead of explicitly showing progress dialog
+
 2002-07-27  Dave Camp  <dave ximian com>
 
 	* libnautilus-private/nautilus-icon-factory.c
Index: libnautilus-private/nautilus-file-operations.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-operations.c,v
retrieving revision 1.153
diff -u -p -r1.153 nautilus-file-operations.c
--- libnautilus-private/nautilus-file-operations.c	12 Jul 2002 18:36:13 -0000	1.153
+++ libnautilus-private/nautilus-file-operations.c	29 Jul 2002 19:13:12 -0000
@@ -73,7 +73,6 @@ typedef struct {
 	GnomeVFSXferOverwriteMode overwrite_mode;
 	GtkWidget *parent_view;
 	TransferKind kind;
-	gboolean show_progress_dialog;
 	void (* done_callback) (GHashTable *debuting_uris, gpointer data);
 	gpointer done_callback_data;
 	GHashTable *debuting_uris;
@@ -280,14 +279,10 @@ static void
 create_transfer_dialog (const GnomeVFSXferProgressInfo *progress_info,
 			TransferInfo *transfer_info)
 {
-	if (!transfer_info->show_progress_dialog) {
-		return;
-	}
-
 	g_return_if_fail (transfer_info->progress_dialog == NULL);
 
 	transfer_info->progress_dialog = nautilus_file_operations_progress_new 
-		(transfer_info->operation_title, "", "", "", 0, 0);
+		(transfer_info->operation_title, "", "", "", 0, 0, TRUE);
 
 	/* Treat clicking on the close box or use of the escape key
 	 * the same as clicking cancel.
@@ -307,8 +302,6 @@ create_transfer_dialog (const GnomeVFSXf
 			GTK_WINDOW (transfer_info->progress_dialog), 
 			GTK_WINDOW (gtk_widget_get_toplevel (transfer_info->parent_view)));
 	}
-
-	gtk_widget_show (GTK_WIDGET (transfer_info->progress_dialog));
 }
 
 static void
@@ -800,6 +793,9 @@ handle_transfer_vfs_error (const GnomeVF
 
 		/* transfer error, prompt the user to continue or stop */
 
+		/* stop timeout while waiting for user */
+		nautilus_file_operations_progress_stop_timeout (transfer_info->progress_dialog);
+
 		formatted_source_name = NULL;
 		formatted_target_name = NULL;
 
@@ -958,6 +954,8 @@ handle_transfer_vfs_error (const GnomeVF
 		g_free (formatted_source_name);
 		g_free (formatted_target_name);
 
+		nautilus_file_operations_progress_resume_timeout (transfer_info->progress_dialog);
+
 		return error_dialog_result;
 
 	case GNOME_VFS_XFER_ERROR_MODE_ABORT:
@@ -999,6 +997,8 @@ handle_transfer_overwrite (const GnomeVF
 	int result;
 	char *text, *formatted_name;
 
+	nautilus_file_operations_progress_stop_timeout (transfer_info->progress_dialog);	
+
 	/* Handle special case files such as Trash, mount links and home directory */	
 	if (is_special_link (progress_info->target_name)) {
 		formatted_name = extract_and_ellipsize_file_name_for_dialog
@@ -1025,6 +1025,8 @@ handle_transfer_overwrite (const GnomeVF
 		g_free (text);
 		g_free (formatted_name);
 
+		nautilus_file_operations_progress_resume_timeout (transfer_info->progress_dialog);
+
 		return GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP;
 	}
 	
@@ -1044,6 +1046,9 @@ handle_transfer_overwrite (const GnomeVF
 			(parent_for_error_dialog (transfer_info), TRUE, text, 
 			 _("Conflict while copying"),
 			 _("Replace"), _("Skip"), NULL);
+			 
+		nautilus_file_operations_progress_resume_timeout (transfer_info->progress_dialog);
+					 
 		switch (result) {
 		case 0:
 			return GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE;
@@ -1059,6 +1064,8 @@ handle_transfer_overwrite (const GnomeVF
 			 _("Conflict while copying"),
 			 _("Replace All"), _("Replace"), _("Skip"), NULL);
 
+		nautilus_file_operations_progress_resume_timeout (transfer_info->progress_dialog);
+
 		switch (result) {
 		case 0:
 			return GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL;
@@ -1688,7 +1695,6 @@ nautilus_file_operations_copy_move (cons
 	gboolean target_is_trash;
 	gboolean is_desktop_trash_link;
 	gboolean duplicate;
-	gboolean all_local;
 	
 	IconPositionIterator *icon_position_iterator;
 
@@ -1712,7 +1718,6 @@ nautilus_file_operations_copy_move (cons
 	 */
 	source_uri_list = NULL;
 	target_uri_list = NULL;
-	all_local = TRUE;
 	duplicate = copy_action != GDK_ACTION_MOVE;
 	for (p = item_uris; p != NULL; p = p->next) {
 		/* Filter out special Nautilus link files */
@@ -1750,11 +1755,6 @@ nautilus_file_operations_copy_move (cons
 			target_uri_list = g_list_prepend (target_uri_list, target_uri);
 			source_uri_list = g_list_prepend (source_uri_list, source_uri);
 
-			if (all_local && (!gnome_vfs_uri_is_local (source_uri)
-					  || !gnome_vfs_uri_is_local (target_uri))) {
-				all_local = FALSE;
-			}
-
 			if (duplicate
 			    && !gnome_vfs_uri_equal (source_dir_uri, target_dir_uri)) {
 				duplicate = FALSE;
@@ -1823,11 +1823,6 @@ nautilus_file_operations_copy_move (cons
 
 		transfer_info->kind = TRANSFER_MOVE_TO_TRASH;
 
-		/* Do an arbitrary guess that an operation will take very little
-		 * time and the progress shouldn't be shown.
-		 */
-		transfer_info->show_progress_dialog = 
-			!all_local || g_list_length ((GList *) item_uris) > 20;
 	} else if ((move_options & GNOME_VFS_XFER_REMOVESOURCE) != 0) {
 		/* localizers: progress dialog title */
 		transfer_info->operation_title = _("Moving files");
@@ -1840,11 +1835,6 @@ nautilus_file_operations_copy_move (cons
 
 		transfer_info->kind = TRANSFER_MOVE;
 
-		/* Do an arbitrary guess that an operation will take very little
-		 * time and the progress shouldn't be shown.
-		 */
-		transfer_info->show_progress_dialog = 
-			!all_local || g_list_length ((GList *) item_uris) > 20;
 	} else if ((move_options & GNOME_VFS_XFER_LINK_ITEMS) != 0) {
 		/* when creating links, handle name conflicts automatically */
 		move_options |= GNOME_VFS_XFER_USE_UNIQUE_NAMES;
@@ -1858,8 +1848,7 @@ nautilus_file_operations_copy_move (cons
 		transfer_info->cleanup_name = _("Finishing Creating Links...");
 
 		transfer_info->kind = TRANSFER_LINK;
-		transfer_info->show_progress_dialog =
-			g_list_length ((GList *)item_uris) > 20;
+
 	} else {
 		/* localizers: progress dialog title */
 		transfer_info->operation_title = _("Copying files");
@@ -1871,8 +1860,6 @@ nautilus_file_operations_copy_move (cons
 		transfer_info->cleanup_name = "";
 
 		transfer_info->kind = TRANSFER_COPY;
-		/* always show progress during copy */
-		transfer_info->show_progress_dialog = TRUE;
 	}
 
 	/* we'll need to check for copy into Trash and for moving/copying the Trash itself */
@@ -2140,7 +2127,6 @@ nautilus_file_operations_delete (const G
 	uri_list = g_list_reverse (uri_list);
 
 	transfer_info = transfer_info_new (parent_view);
-	transfer_info->show_progress_dialog = TRUE;
 
 	/* localizers: progress dialog title */
 	transfer_info->operation_title = _("Deleting files");
@@ -2176,7 +2162,6 @@ do_empty_trash (GtkWidget *parent_view)
 	if (trash_dir_list != NULL) {
 		/* set up the move parameters */
 		transfer_info = transfer_info_new (parent_view);
-		transfer_info->show_progress_dialog = TRUE;
 
 		/* localizers: progress dialog title */
 		transfer_info->operation_title = _("Emptying the Trash");
Index: libnautilus-private/nautilus-file-operations-progress.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-operations-progress.c,v
retrieving revision 1.36
diff -u -p -r1.36 nautilus-file-operations-progress.c
--- libnautilus-private/nautilus-file-operations-progress.c	17 Apr 2002 12:29:10 -0000	1.36
+++ libnautilus-private/nautilus-file-operations-progress.c	29 Jul 2002 19:13:12 -0000
@@ -55,6 +55,8 @@
 
 #define MINIMUM_TIME_UP    1000
 
+#define SHOW_TIMEOUT	   1200
+
 static GdkPixbuf *empty_jar_pixbuf, *full_jar_pixbuf;
 
 static void nautilus_file_operations_progress_class_init (NautilusFileOperationsProgressClass *klass);
@@ -83,12 +85,36 @@ struct NautilusFileOperationsProgressDet
 	gulong files_total;
 	gulong bytes_total;
 
-	/* system time (microseconds) when dialog was mapped */
+	/* system time (microseconds) when dialog was created */
 	gint64 start_time;
 
+	/* system time (microseconds) when dialog was mapped */
+	gint64 show_time;
+	
+	/* time remaining in timeout if it's stopped and resumed */
+	guint remaining_time;
+
 	guint delayed_close_timeout_id;
+	guint delayed_show_timeout_id;
 
 	int progress_jar_position;
+	
+	/* this is set to true when the widget is first shown and
+	 * the ui is created. ideally the operation is fast and the
+	 * widget is never shown so we don't waste time building
+	 * its ui.
+	 */
+	gboolean ui_ready;
+	
+	/* stuff we might need at ui creation time */
+	char *operation_string;
+	char *progress_verb;
+	char *file_item_name;
+	char *from_path;
+	char *to_path;
+	gulong file_index;
+	gulong size;
+	gboolean new_file;	
 };
 
 /* Private functions. */
@@ -100,6 +126,10 @@ nautilus_file_operations_progress_update
 	GdkPixbuf *pixbuf;
 	int position;
 
+	if (!progress->details->ui_ready) {
+		return;
+	}
+
 	position = gdk_pixbuf_get_height (empty_jar_pixbuf) * (1 - fraction);
 
 	if (position == progress->details->progress_jar_position) {
@@ -124,6 +154,10 @@ static void
 nautilus_file_operations_progress_update (NautilusFileOperationsProgress *progress)
 {
 	double fraction;
+
+	if (!progress->details->ui_ready) {
+		return;
+	}
 	
 	if (progress->details->bytes_total == 0) {
 		/* We haven't set up the file count yet, do not update
@@ -191,6 +225,11 @@ nautilus_file_operations_progress_destro
 		progress->details->delayed_close_timeout_id = 0;
 	}
 	
+	if (progress->details->delayed_show_timeout_id != 0) {
+		g_source_remove (progress->details->delayed_show_timeout_id);
+		progress->details->delayed_show_timeout_id = 0;
+	}
+	
 	EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object));
 }
 
@@ -228,7 +267,7 @@ map_callback (GtkWidget *widget)
 
 	EEL_CALL_PARENT (GTK_WIDGET_CLASS, map, (widget));
 
-	progress->details->start_time = eel_get_system_time ();
+	progress->details->show_time = eel_get_system_time ();
 }
 
 static gboolean
@@ -242,13 +281,20 @@ delete_event_callback (GtkWidget *widget
 }
 
 static void
-nautilus_file_operations_progress_init (NautilusFileOperationsProgress *progress)
+create_ui (NautilusFileOperationsProgress *progress, gpointer callback_data)
 {
 	GtkWidget *hbox, *vbox;
 	GtkTable *titled_label_table;
 
-	progress->details = g_new0 (NautilusFileOperationsProgressDetails, 1);
-
+	if (progress->details->ui_ready) {
+		return;
+	}
+	
+	if (progress->details->delayed_show_timeout_id != 0) {
+		g_source_remove (progress->details->delayed_show_timeout_id);
+		progress->details->delayed_show_timeout_id = 0;
+	}
+	
 	vbox = gtk_vbox_new (FALSE, VERTICAL_SPACING);
 	gtk_container_set_border_width (GTK_CONTAINER (vbox), OUTER_BORDER);
 	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (progress)->vbox), vbox, TRUE, TRUE, VERTICAL_SPACING);
@@ -298,7 +344,45 @@ nautilus_file_operations_progress_init (
 	/* Set progress jar position */
 	progress->details->progress_jar_position = gdk_pixbuf_get_height (empty_jar_pixbuf);
 
+	progress->details->ui_ready = TRUE;
+	
+	if (progress->details->operation_string != NULL) {
+		nautilus_file_operations_progress_set_operation_string
+				(progress, progress->details->operation_string);
+		g_free (progress->details->operation_string);
+	}
+	
+	if (progress->details->new_file) {
+		nautilus_file_operations_progress_new_file
+				(progress,
+				 progress->details->progress_verb,
+				 progress->details->file_item_name,
+				 progress->details->from_path,
+				 progress->details->to_path,
+				 progress->details->from_prefix,
+				 progress->details->to_prefix,
+				 progress->details->file_index,
+				 progress->details->size);
+
+		g_free (progress->details->progress_verb);
+		g_free (progress->details->file_item_name);
+		g_free (progress->details->from_path);
+		g_free (progress->details->to_path);
+	}		 
+
 	gtk_widget_show_all (vbox);
+}	
+
+
+static void
+nautilus_file_operations_progress_init (NautilusFileOperationsProgress *progress)
+{
+	progress->details = g_new0 (NautilusFileOperationsProgressDetails, 1);
+
+	progress->details->ui_ready = FALSE;
+	progress->details->start_time = eel_get_system_time ();
+
+	g_signal_connect (progress, "realize", G_CALLBACK (create_ui), NULL);
 }
 
 static void
@@ -335,13 +419,29 @@ nautilus_file_operations_progress_class_
 	
 }
 
+static gboolean
+delayed_show_callback (gpointer callback_data)
+{
+	NautilusFileOperationsProgress *progress;
+	
+	progress = NAUTILUS_FILE_OPERATIONS_PROGRESS (callback_data);
+	
+	progress->details->delayed_show_timeout_id = 0;
+	
+	create_ui (progress, NULL);
+	gtk_widget_show (GTK_WIDGET (progress));
+	
+	return FALSE;
+}
+
 NautilusFileOperationsProgress *
 nautilus_file_operations_progress_new (const char *title,
 				       const char *operation_string,
 				       const char *from_prefix,
 				       const char *to_prefix,
 				       gulong total_files,
-				       gulong total_bytes)
+				       gulong total_bytes,
+				       gboolean use_timeout)
 {
 	GtkWidget *widget;
 	NautilusFileOperationsProgress *progress;
@@ -359,6 +459,11 @@ nautilus_file_operations_progress_new (c
 
 	progress->details->from_prefix = from_prefix;
 	progress->details->to_prefix = to_prefix;
+
+	if (use_timeout) {
+		progress->details->delayed_show_timeout_id =
+			g_timeout_add (SHOW_TIMEOUT, delayed_show_callback, progress);
+	}
 	
 	return progress;
 }
@@ -382,6 +487,12 @@ nautilus_file_operations_progress_set_op
 {
 	g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress));
 
+	if (!progress->details->ui_ready) {
+		g_free (progress->details->operation_string);	
+		progress->details->operation_string = g_strdup (operation_string);
+		return;
+	}
+
 	gtk_label_set_text (GTK_LABEL (progress->details->progress_title_label),
 			    operation_string);
 }
@@ -400,11 +511,25 @@ nautilus_file_operations_progress_new_fi
 	char *progress_count;
 
 	g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress));
-	g_return_if_fail (GTK_WIDGET_REALIZED (progress));
 
 	progress->details->from_prefix = from_prefix;
 	progress->details->to_prefix = to_prefix;
 
+	if (!progress->details->ui_ready) {
+		g_free (progress->details->progress_verb);
+		g_free (progress->details->file_item_name);
+		g_free (progress->details->from_path);
+		g_free (progress->details->to_path);
+		progress->details->progress_verb = g_strdup (progress_verb);
+		progress->details->file_item_name = g_strdup (item_name);
+		progress->details->from_path = g_strdup (from_path);
+		progress->details->to_path = g_strdup (to_path);
+		progress->details->file_index = file_index;
+		progress->details->size = size;
+		progress->details->new_file = TRUE;
+		return;
+	}
+
 	if (progress->details->bytes_total > 0) {
 		/* we haven't set up the file count yet, do not update the progress
 		 * count until we do
@@ -438,6 +563,10 @@ nautilus_file_operations_progress_new_fi
 void
 nautilus_file_operations_progress_clear (NautilusFileOperationsProgress *progress)
 {
+	if (!progress->details->ui_ready) {
+		return;
+	}
+
 	gtk_label_set_text (GTK_LABEL (progress->details->from_label), "");
 	gtk_label_set_text (GTK_LABEL (progress->details->from_path_label), "");
 	gtk_label_set_text (GTK_LABEL (progress->details->to_label), "");
@@ -485,7 +614,7 @@ nautilus_file_operations_progress_done (
 	g_assert (progress->details->start_time != 0);
 
 	/* compute time up in milliseconds */
-	time_up = (eel_get_system_time () - progress->details->start_time) / 1000;
+	time_up = (eel_get_system_time () - progress->details->show_time) / 1000;
 	if (time_up >= MINIMUM_TIME_UP) {
 		gtk_object_destroy (GTK_OBJECT (progress));
 		return;
@@ -498,4 +627,45 @@ nautilus_file_operations_progress_done (
 		(MINIMUM_TIME_UP - time_up,
 		 delayed_close_callback,
 		 progress);
+}
+
+void
+nautilus_file_operations_progress_stop_timeout (NautilusFileOperationsProgress *progress)
+{
+	guint time_up;
+
+	if (progress->details->delayed_show_timeout_id == 0) {
+		progress->details->remaining_time = 0;
+		return;
+	}
+	
+	time_up = (eel_get_system_time () - progress->details->start_time) / 1000;
+	
+	if (time_up >= SHOW_TIMEOUT) {
+		progress->details->remaining_time = 0;
+		return;
+	}
+	
+	g_source_remove (progress->details->delayed_show_timeout_id);
+	progress->details->delayed_show_timeout_id = 0;
+	progress->details->remaining_time = SHOW_TIMEOUT - time_up;
+}
+
+void
+nautilus_file_operations_progress_resume_timeout (NautilusFileOperationsProgress *progress)
+{
+	if (progress->details->delayed_show_timeout_id != 0) {
+		return;
+	}
+	
+	if (progress->details->remaining_time <= 0) {
+		return;
+	}
+	
+	progress->details->delayed_show_timeout_id =
+		g_timeout_add (progress->details->remaining_time,
+			       delayed_show_callback,
+			       progress);
+			       
+	progress->details->remaining_time = 0;		       
 }
Index: libnautilus-private/nautilus-file-operations-progress.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-operations-progress.h,v
retrieving revision 1.10
diff -u -p -r1.10 nautilus-file-operations-progress.h
--- libnautilus-private/nautilus-file-operations-progress.h	27 Nov 2001 01:46:16 -0000	1.10
+++ libnautilus-private/nautilus-file-operations-progress.h	29 Jul 2002 19:13:12 -0000
@@ -55,7 +55,8 @@ NautilusFileOperationsProgress *nautilus
 											const char                     *from_prefix,
 											const char                     *to_prefix,
 											gulong                          files_total,
-											gulong                          bytes_total);
+											gulong                          bytes_total,
+											gboolean			use_timeout);
 void                            nautilus_file_operations_progress_done                 (NautilusFileOperationsProgress *dialog);
 void                            nautilus_file_operations_progress_set_progress_title   (NautilusFileOperationsProgress *dialog,
 											const char                     *progress_title);
@@ -77,5 +78,7 @@ void                            nautilus
 void                            nautilus_file_operations_progress_update_sizes         (NautilusFileOperationsProgress *dialog,
 											gulong                          bytes_done_in_file,
 											gulong                          bytes_done);
+void				nautilus_file_operations_progress_stop_timeout	       (NautilusFileOperationsProgress *progress);
+void				nautilus_file_operations_progress_resume_timeout       (NautilusFileOperationsProgress *progress);
 
 #endif /* NAUTILUS_FILE_OPERATIONS_PROGRESS_H */


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