diff options
Diffstat (limited to 'libnautilus-private/nautilus-file-operations-progress.c')
-rw-r--r-- | libnautilus-private/nautilus-file-operations-progress.c | 317 |
1 files changed, 179 insertions, 138 deletions
diff --git a/libnautilus-private/nautilus-file-operations-progress.c b/libnautilus-private/nautilus-file-operations-progress.c index c3abd919a..339950baf 100644 --- a/libnautilus-private/nautilus-file-operations-progress.c +++ b/libnautilus-private/nautilus-file-operations-progress.c @@ -1,9 +1,10 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + /* dfos-xfer-progress-dialog.c - Progress dialog for transfer operations in the GNOME Desktop File Operation Service. Copyright (C) 1999, 2000 Free Software Foundation - Copyright (C) 2000 Eazel Inc. + Copyright (C) 2000, 2001 Eazel Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -23,17 +24,23 @@ Authors: Ettore Perazzoli <ettore@gnu.org> Pavel Cisler <pavel@eazel.com> - */ +*/ #include <config.h> -#include <gnome.h> -#include <libgnomevfs/gnome-vfs-utils.h> #include "nautilus-file-operations-progress.h" -#include "libnautilus-extensions/nautilus-ellipsizing-label.h" -#include "libnautilus-extensions/nautilus-gtk-extensions.h" -#include "libnautilus-extensions/nautilus-gdk-font-extensions.h" -#include "libnautilus-extensions/nautilus-gtk-macros.h" +#include "nautilus-ellipsizing-label.h" +#include "nautilus-gdk-font-extensions.h" +#include "nautilus-glib-extensions.h" +#include "nautilus-gtk-extensions.h" +#include "nautilus-gtk-macros.h" +#include <gtk/gtkhbox.h> +#include <gtk/gtkmain.h> +#include <gtk/gtkprogressbar.h> +#include <gtk/gtktable.h> +#include <libgnome/gnome-i18n.h> +#include <libgnomeui/gnome-stock.h> +#include <libgnomevfs/gnome-vfs-utils.h> /* The width of the progress bar determines the minimum width of the * window. It will be wider only if the font is really huge and the @@ -41,13 +48,19 @@ */ #define PROGRESS_BAR_WIDTH 350 -static void nautilus_file_operations_progress_initialize_class (NautilusFileOperationsProgressClass *klass); -static void nautilus_file_operations_progress_initialize (NautilusFileOperationsProgress *dialog); +#define OUTER_BORDER 5 +#define HORIZONTAL_SPACING 3 -NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusFileOperationsProgress, nautilus_file_operations_progress, GNOME_TYPE_DIALOG); +#define MINIMUM_TIME_UP 1000 -struct NautilusFileOperationsProgressDetails { +static void nautilus_file_operations_progress_initialize_class (NautilusFileOperationsProgressClass *klass); +static void nautilus_file_operations_progress_initialize (NautilusFileOperationsProgress *dialog); + +NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusFileOperationsProgress, + nautilus_file_operations_progress, + GNOME_TYPE_DIALOG); +struct NautilusFileOperationsProgressDetails { GtkWidget *progress_title_label; GtkWidget *progress_count_label; GtkWidget *operation_name_label; @@ -62,33 +75,31 @@ struct NautilusFileOperationsProgressDetails { const char *from_prefix; const char *to_prefix; - guint freeze_count; - - gulong file_index; - gulong file_size; - gulong bytes_copied; - gulong total_bytes_copied; - gulong files_total; gulong bytes_total; + + /* system time (microseconds) when dialog was mapped */ + gint64 start_time; + + guint delayed_close_timeout_id; }; -/* Private functions. */ +/* Private functions. */ static void -nautilus_file_operations_progress_update (NautilusFileOperationsProgress *dialog) +nautilus_file_operations_progress_update (NautilusFileOperationsProgress *progress) { - if (dialog->details->bytes_total == 0) { - /* we haven't set up the file count yet, do not update the progress - * bar until we do + if (progress->details->bytes_total == 0) { + /* We haven't set up the file count yet, do not update + * the progress bar until we do. */ return; } - gtk_progress_configure (GTK_PROGRESS (dialog->details->progress_bar), - dialog->details->total_bytes_copied, - 0.0, dialog->details->bytes_total); + gtk_progress_configure (GTK_PROGRESS (progress->details->progress_bar), + progress->details->bytes_copied, + 0.0, progress->details->bytes_total); } static void @@ -106,16 +117,12 @@ set_text_unescaped_trimmed (NautilusEllipsizingLabel *label, const char *text) g_free (unescaped_text); } -/* GnomeDialog default signal overrides. */ - /* This is just to make sure the dialog is not closed without explicit - intervention. */ + * intervention. + */ static gboolean -nautilus_file_operations_progress_close (GnomeDialog *dialog) +close_callback (GnomeDialog *dialog) { - NautilusFileOperationsProgress *progress_dialog; - - progress_dialog = NAUTILUS_FILE_OPERATIONS_PROGRESS (dialog); return FALSE; } @@ -124,11 +131,17 @@ nautilus_file_operations_progress_close (GnomeDialog *dialog) static void nautilus_file_operations_progress_destroy (GtkObject *object) { - NautilusFileOperationsProgress *dialog; + NautilusFileOperationsProgress *progress; + + progress = NAUTILUS_FILE_OPERATIONS_PROGRESS (object); - dialog = NAUTILUS_FILE_OPERATIONS_PROGRESS (object); + if (progress->details->delayed_close_timeout_id != 0) { + g_source_remove (progress->details->delayed_close_timeout_id); + } - g_free (dialog->details); + g_free (progress->details); + + NAUTILUS_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); } /* Initialization. */ @@ -156,8 +169,21 @@ create_titled_label (GtkTable *table, int row, GtkWidget **title_widget, GtkWidg gtk_misc_set_alignment (GTK_MISC (*label_text_widget), 0, 0); } +static void +map_callback (GtkWidget *widget) +{ + NautilusFileOperationsProgress *progress; + + progress = NAUTILUS_FILE_OPERATIONS_PROGRESS (widget); + + NAUTILUS_CALL_PARENT (GTK_WIDGET_CLASS, map, (widget)); + + progress->details->start_time = nautilus_get_system_time (); +} + static gboolean -delete_event_callback (GtkWidget *widget, GdkEventAny *event) +delete_event_callback (GtkWidget *widget, + GdkEventAny *event) { /* Do nothing -- we shouldn't be getting a close event because * the dialog should not have a close box. @@ -166,77 +192,66 @@ delete_event_callback (GtkWidget *widget, GdkEventAny *event) } static void -nautilus_file_operations_progress_initialize (NautilusFileOperationsProgress *dialog) +nautilus_file_operations_progress_initialize (NautilusFileOperationsProgress *progress) { - GnomeDialog *gnome_dialog; GtkBox *vbox; GtkWidget *hbox; GtkTable *titled_label_table; - dialog->details = g_new0 (NautilusFileOperationsProgressDetails, 1); + progress->details = g_new0 (NautilusFileOperationsProgressDetails, 1); - - gnome_dialog = GNOME_DIALOG (dialog); - vbox = GTK_BOX (gnome_dialog->vbox); + vbox = GTK_BOX (GNOME_DIALOG (progress)->vbox); /* This is evil but makes the dialog look less cramped. */ - gtk_container_border_width (GTK_CONTAINER (vbox), 5); + gtk_container_set_border_width (GTK_CONTAINER (vbox), OUTER_BORDER); hbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (vbox, hbox, TRUE, TRUE, 3); + gtk_box_pack_start (vbox, hbox, TRUE, TRUE, HORIZONTAL_SPACING); gtk_widget_show (hbox); /* label- */ /* Files remaining to be copied: */ - dialog->details->progress_title_label = gtk_label_new (""); - gtk_label_set_justify (GTK_LABEL (dialog->details->progress_title_label), GTK_JUSTIFY_LEFT); - gtk_box_pack_start (GTK_BOX (hbox), dialog->details->progress_title_label, FALSE, FALSE, 0); - gtk_widget_show (dialog->details->progress_title_label); - nautilus_gtk_label_make_bold (GTK_LABEL (dialog->details->progress_title_label)); + progress->details->progress_title_label = gtk_label_new (""); + gtk_label_set_justify (GTK_LABEL (progress->details->progress_title_label), GTK_JUSTIFY_LEFT); + gtk_box_pack_start (GTK_BOX (hbox), progress->details->progress_title_label, FALSE, FALSE, 0); + gtk_widget_show (progress->details->progress_title_label); + nautilus_gtk_label_make_bold (GTK_LABEL (progress->details->progress_title_label)); /* label -- */ /* 24 of 30 */ - dialog->details->progress_count_label = gtk_label_new (""); - gtk_label_set_justify (GTK_LABEL (dialog->details->progress_count_label), GTK_JUSTIFY_RIGHT); - gtk_box_pack_end (GTK_BOX (hbox), dialog->details->progress_count_label, FALSE, FALSE, 0); - gtk_widget_show (dialog->details->progress_count_label); - nautilus_gtk_label_make_bold (GTK_LABEL (dialog->details->progress_count_label)); + progress->details->progress_count_label = gtk_label_new (""); + gtk_label_set_justify (GTK_LABEL (progress->details->progress_count_label), GTK_JUSTIFY_RIGHT); + gtk_box_pack_end (GTK_BOX (hbox), progress->details->progress_count_label, FALSE, FALSE, 0); + gtk_widget_show (progress->details->progress_count_label); + nautilus_gtk_label_make_bold (GTK_LABEL (progress->details->progress_count_label)); /* progress bar */ - dialog->details->progress_bar = gtk_progress_bar_new (); - gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (dialog->details->progress_bar), + progress->details->progress_bar = gtk_progress_bar_new (); + gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (progress->details->progress_bar), GTK_PROGRESS_CONTINUOUS); - gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (dialog->details->progress_bar), + gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (progress->details->progress_bar), GTK_PROGRESS_LEFT_TO_RIGHT); - gtk_widget_set_usize (GTK_WIDGET (dialog->details->progress_bar), PROGRESS_BAR_WIDTH, - -1); - gtk_box_pack_start (vbox, dialog->details->progress_bar, FALSE, TRUE, 0); - gtk_widget_show (dialog->details->progress_bar); + gtk_widget_set_usize (progress->details->progress_bar, PROGRESS_BAR_WIDTH, -1); + gtk_box_pack_start (vbox, progress->details->progress_bar, FALSE, TRUE, 0); + gtk_widget_show (progress->details->progress_bar); titled_label_table = GTK_TABLE (gtk_table_new (3, 2, FALSE)); gtk_table_set_row_spacings (titled_label_table, 4); gtk_table_set_col_spacings (titled_label_table, 4); gtk_widget_show (GTK_WIDGET (titled_label_table)); - create_titled_label (titled_label_table, 0, &dialog->details->operation_name_label, - &dialog->details->item_name); - create_titled_label (titled_label_table, 1, &dialog->details->from_label, - &dialog->details->from_path_label); - create_titled_label (titled_label_table, 2, &dialog->details->to_label, - &dialog->details->to_path_label); + create_titled_label (titled_label_table, 0, + &progress->details->operation_name_label, + &progress->details->item_name); + create_titled_label (titled_label_table, 1, + &progress->details->from_label, + &progress->details->from_path_label); + create_titled_label (titled_label_table, 2, + &progress->details->to_label, + &progress->details->to_path_label); gtk_box_pack_start (vbox, GTK_WIDGET (titled_label_table), FALSE, FALSE, 0); - - - dialog->details->file_index = 0; - dialog->details->file_size = 0; - dialog->details->files_total = 0; - dialog->details->bytes_total = 0; - dialog->details->bytes_copied = 0; - dialog->details->total_bytes_copied = 0; - - dialog->details->freeze_count = 0; } static void @@ -251,7 +266,6 @@ nautilus_file_operations_progress_initialize_class (NautilusFileOperationsProgre dialog_class = GNOME_DIALOG_CLASS (klass); object_class->destroy = nautilus_file_operations_progress_destroy; - dialog_class->close = nautilus_file_operations_progress_close; /* The progress dialog should not have a title and a close box. * Some broken window manager themes still show the window title. @@ -259,9 +273,12 @@ nautilus_file_operations_progress_initialize_class (NautilusFileOperationsProgre * a crash. */ widget_class->delete_event = delete_event_callback; + widget_class->map = map_callback; + + dialog_class->close = close_callback; } -GtkWidget * +NautilusFileOperationsProgress * nautilus_file_operations_progress_new (const char *title, const char *operation_string, const char *from_prefix, @@ -270,50 +287,51 @@ nautilus_file_operations_progress_new (const char *title, gulong total_bytes) { GtkWidget *widget; - NautilusFileOperationsProgress *dialog; + NautilusFileOperationsProgress *progress; widget = gtk_widget_new (nautilus_file_operations_progress_get_type (), NULL); - dialog = NAUTILUS_FILE_OPERATIONS_PROGRESS (widget); + progress = NAUTILUS_FILE_OPERATIONS_PROGRESS (widget); - nautilus_file_operations_progress_set_operation_string (dialog, operation_string); - nautilus_file_operations_progress_set_total (dialog, total_files, total_bytes); + nautilus_file_operations_progress_set_operation_string (progress, operation_string); + nautilus_file_operations_progress_set_total (progress, total_files, total_bytes); gtk_window_set_title (GTK_WINDOW (widget), title); gtk_window_set_wmclass (GTK_WINDOW (widget), "file_progress", "Nautilus"); - gnome_dialog_append_button (GNOME_DIALOG (widget), GNOME_STOCK_BUTTON_CANCEL); + gnome_dialog_append_button (GNOME_DIALOG (widget), + GNOME_STOCK_BUTTON_CANCEL); - dialog->details->from_prefix = from_prefix; - dialog->details->to_prefix = to_prefix; + progress->details->from_prefix = from_prefix; + progress->details->to_prefix = to_prefix; - return widget; + return progress; } void -nautilus_file_operations_progress_set_total (NautilusFileOperationsProgress *dialog, +nautilus_file_operations_progress_set_total (NautilusFileOperationsProgress *progress, gulong files_total, gulong bytes_total) { - g_return_if_fail (IS_NAUTILUS_FILE_OPERATIONS_PROGRESS (dialog)); + g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress)); - dialog->details->files_total = files_total; - dialog->details->bytes_total = bytes_total; + progress->details->files_total = files_total; + progress->details->bytes_total = bytes_total; - nautilus_file_operations_progress_update (dialog); + nautilus_file_operations_progress_update (progress); } void -nautilus_file_operations_progress_set_operation_string (NautilusFileOperationsProgress *dialog, +nautilus_file_operations_progress_set_operation_string (NautilusFileOperationsProgress *progress, const char *operation_string) { - g_return_if_fail (IS_NAUTILUS_FILE_OPERATIONS_PROGRESS (dialog)); + g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress)); - gtk_label_set_text (GTK_LABEL (dialog->details->progress_title_label), + gtk_label_set_text (GTK_LABEL (progress->details->progress_title_label), operation_string); } void -nautilus_file_operations_progress_new_file (NautilusFileOperationsProgress *dialog, +nautilus_file_operations_progress_new_file (NautilusFileOperationsProgress *progress, const char *progress_verb, const char *item_name, const char *from_path, @@ -325,81 +343,104 @@ nautilus_file_operations_progress_new_file (NautilusFileOperationsProgress *dial { char *progress_count; - g_return_if_fail (IS_NAUTILUS_FILE_OPERATIONS_PROGRESS (dialog)); - g_return_if_fail (GTK_WIDGET_REALIZED (dialog)); - - dialog->details->file_index = file_index; - dialog->details->bytes_copied = 0; - dialog->details->file_size = size; + g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress)); + g_return_if_fail (GTK_WIDGET_REALIZED (progress)); - dialog->details->from_prefix = from_prefix; - dialog->details->to_prefix = to_prefix; + progress->details->from_prefix = from_prefix; + progress->details->to_prefix = to_prefix; - if (dialog->details->bytes_total > 0) { + if (progress->details->bytes_total > 0) { /* we haven't set up the file count yet, do not update the progress * count until we do */ - gtk_label_set_text (GTK_LABEL (dialog->details->operation_name_label), progress_verb); + gtk_label_set_text (GTK_LABEL (progress->details->operation_name_label), + progress_verb); set_text_unescaped_trimmed - (NAUTILUS_ELLIPSIZING_LABEL (dialog->details->item_name), item_name); + (NAUTILUS_ELLIPSIZING_LABEL (progress->details->item_name), + item_name); - progress_count = g_strdup_printf (_("%ld of %ld"), dialog->details->file_index, - dialog->details->files_total); - gtk_label_set_text (GTK_LABEL (dialog->details->progress_count_label), progress_count); + progress_count = g_strdup_printf (_("%ld of %ld"), file_index + 1, + progress->details->files_total); + gtk_label_set_text (GTK_LABEL (progress->details->progress_count_label), progress_count); g_free (progress_count); - gtk_label_set_text (GTK_LABEL (dialog->details->from_label), from_prefix); + gtk_label_set_text (GTK_LABEL (progress->details->from_label), from_prefix); set_text_unescaped_trimmed - (NAUTILUS_ELLIPSIZING_LABEL (dialog->details->from_path_label), from_path); + (NAUTILUS_ELLIPSIZING_LABEL (progress->details->from_path_label), from_path); - if (dialog->details->to_prefix != NULL && dialog->details->to_path_label != NULL) { - gtk_label_set_text (GTK_LABEL (dialog->details->to_label), to_prefix); + if (progress->details->to_prefix != NULL && progress->details->to_path_label != NULL) { + gtk_label_set_text (GTK_LABEL (progress->details->to_label), to_prefix); set_text_unescaped_trimmed - (NAUTILUS_ELLIPSIZING_LABEL (dialog->details->to_path_label), to_path); + (NAUTILUS_ELLIPSIZING_LABEL (progress->details->to_path_label), to_path); } } - nautilus_file_operations_progress_update (dialog); + nautilus_file_operations_progress_update (progress); } void -nautilus_file_operations_progress_clear (NautilusFileOperationsProgress *dialog) +nautilus_file_operations_progress_clear (NautilusFileOperationsProgress *progress) { - gtk_label_set_text (GTK_LABEL (dialog->details->from_label), ""); - gtk_label_set_text (GTK_LABEL (dialog->details->from_path_label), ""); - gtk_label_set_text (GTK_LABEL (dialog->details->to_label), ""); - gtk_label_set_text (GTK_LABEL (dialog->details->to_path_label), ""); + 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), ""); + gtk_label_set_text (GTK_LABEL (progress->details->to_path_label), ""); - dialog->details->files_total = 0; - dialog->details->bytes_total = 0; + progress->details->files_total = 0; + progress->details->bytes_total = 0; - nautilus_file_operations_progress_update (dialog); + nautilus_file_operations_progress_update (progress); } void -nautilus_file_operations_progress_update_sizes (NautilusFileOperationsProgress *dialog, +nautilus_file_operations_progress_update_sizes (NautilusFileOperationsProgress *progress, gulong bytes_done_in_file, gulong bytes_done) { - g_return_if_fail (IS_NAUTILUS_FILE_OPERATIONS_PROGRESS (dialog)); + g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress)); - dialog->details->bytes_copied = bytes_done_in_file; - dialog->details->total_bytes_copied = bytes_done; + progress->details->bytes_copied = bytes_done; - nautilus_file_operations_progress_update (dialog); + nautilus_file_operations_progress_update (progress); } -void -nautilus_file_operations_progress_freeze (NautilusFileOperationsProgress *dialog) +static gboolean +delayed_close_callback (gpointer callback_data) { - dialog->details->freeze_count++; + NautilusFileOperationsProgress *progress; + + progress = NAUTILUS_FILE_OPERATIONS_PROGRESS (callback_data); + + progress->details->delayed_close_timeout_id = 0; + gtk_object_destroy (GTK_OBJECT (progress)); + return FALSE; } void -nautilus_file_operations_progress_thaw (NautilusFileOperationsProgress *dialog) +nautilus_file_operations_progress_done (NautilusFileOperationsProgress *progress) { - if (dialog->details->freeze_count > 0) { - dialog->details->freeze_count--; + guint time_up; + + if (!GTK_WIDGET_MAPPED (progress)) { + gtk_object_destroy (GTK_OBJECT (progress)); + return; } -} + g_assert (progress->details->start_time != 0); + /* compute time up in milliseconds */ + time_up = (nautilus_get_system_time () - progress->details->start_time) / 1000; + if (time_up >= MINIMUM_TIME_UP) { + gtk_object_destroy (GTK_OBJECT (progress)); + return; + } + + /* Make dialog look "done". */ + gnome_dialog_set_sensitive (GNOME_DIALOG (progress), 0, FALSE); + gtk_progress_configure (GTK_PROGRESS (progress->details->progress_bar), + 1.0, 0.0, 1.0); + + progress->details->delayed_close_timeout_id = gtk_timeout_add + (MINIMUM_TIME_UP - time_up, + delayed_close_callback, + progress); +} |