summaryrefslogtreecommitdiff
path: root/libnautilus-private/nautilus-file-operations-progress.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnautilus-private/nautilus-file-operations-progress.c')
-rw-r--r--libnautilus-private/nautilus-file-operations-progress.c317
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);
+}