[nautilus/wip/csoriano/operations: 7/8] progress-info: allow finished infos to remain alive
- From: Carlos Soriano Sánchez <csoriano src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus/wip/csoriano/operations: 7/8] progress-info: allow finished infos to remain alive
- Date: Tue, 14 Jul 2015 17:48:16 +0000 (UTC)
commit f91f5fd4002b011a524a9763e1ddb7b41b08c0c5
Author: Carlos Soriano <csoriano gnome org>
Date: Tue Jul 14 10:13:48 2015 +0200
progress-info: allow finished infos to remain alive
We want to not hide the operations and the operations button
in the toolbar if the popover is open. For that, we need to
allow operations widgets to remain alive even when the operation
is finished.
For that we need to add a new status state to copying/moving/trashing,
like copied/moved/trashed.
On the way, improve the wording of file-operations to match the mockups,
and also make the report operations code more consistent to each other.
libnautilus-private/nautilus-file-operations.c | 564 ++++++++++++++------
.../nautilus-progress-info-manager.c | 28 +-
.../nautilus-progress-info-manager.h | 1 +
src/nautilus-progress-info-widget.c | 19 +-
src/nautilus-progress-info-widget.h | 2 +
src/nautilus-toolbar-ui.xml | 1 +
src/nautilus-toolbar.c | 23 +-
7 files changed, 446 insertions(+), 192 deletions(-)
---
diff --git a/libnautilus-private/nautilus-file-operations.c b/libnautilus-private/nautilus-file-operations.c
index 7762916..88d35ff 100644
--- a/libnautilus-private/nautilus-file-operations.c
+++ b/libnautilus-private/nautilus-file-operations.c
@@ -1453,29 +1453,47 @@ report_delete_progress (CommonJob *job,
double elapsed, transfer_rate;
int remaining_time;
gint64 now;
- char *files_left_s;
+ char *details;
+ char *status;
+ DeleteJob *delete_job;
+ delete_job = (DeleteJob *) job;
now = g_get_monotonic_time ();
- if (transfer_info->last_report_time != 0 &&
- ABS ((gint64)(transfer_info->last_report_time - now)) < 100 * NSEC_PER_MICROSEC) {
- return;
- }
- transfer_info->last_report_time = now;
-
files_left = source_info->num_files - transfer_info->num_files;
/* Races and whatnot could cause this to be negative... */
if (files_left < 0) {
- files_left = 1;
+ files_left = 0;
}
- files_left_s = f (ngettext ("%'d file left to delete",
- "%'d files left to delete",
- files_left),
- files_left);
+ if (transfer_info->last_report_time != 0 &&
+ ABS ((gint64)(transfer_info->last_report_time - now)) < 100 * NSEC_PER_MICROSEC &&
+ files_left > 0) {
+ return;
+ }
- nautilus_progress_info_take_status (job->progress,
- f (_("Deleting files")));
+ transfer_info->last_report_time = now;
+
+ if (source_info->num_files == 1) {
+ if (files_left == 0) {
+ status = _("Deleted “%B”");
+ } else {
+ status = _("Deleting “%B”");
+ }
+ nautilus_progress_info_take_status (job->progress,
+ f (status,
+ (GFile*) delete_job->files->data));
+
+ } else {
+ if (files_left == 0) {
+ status = _("Deleted %'d files");
+ } else {
+ status = _("Deleting %'d files");
+ }
+ nautilus_progress_info_take_status (job->progress,
+ f (status,
+ source_info->num_files));
+ }
elapsed = g_timer_elapsed (job->time, NULL);
transfer_rate = 0;
@@ -1487,23 +1505,35 @@ report_delete_progress (CommonJob *job,
}
if (elapsed < SECONDS_NEEDED_FOR_RELIABLE_TRANSFER_RATE) {
- nautilus_progress_info_set_details (job->progress, files_left_s);
+ if (files_left > 0) {
+ details = f (_("%'d / %'d"),
+ transfer_info->num_files + 1,
+ source_info->num_files);
+ } else {
+ details = f (_("%'d / %'d"),
+ transfer_info->num_files,
+ source_info->num_files);
+ }
} else {
- char *details, *time_left_s;
-
- /* To translators: %T will expand to a time like "2 minutes".
- * The singular/plural form will be used depending on the remaining time (i.e. the %T
argument).
- */
- time_left_s = f (ngettext ("%T left",
- "%T left",
- seconds_count_format_time_units (remaining_time)),
- remaining_time);
-
- details = g_strconcat (files_left_s, " \xE2\x80\x94 ", time_left_s, NULL);
- nautilus_progress_info_take_details (job->progress, details);
-
- g_free (time_left_s);
+ if (files_left > 0) {
+ /* To translators: %T will expand to a time duration like "2 minutes".
+ * So the whole thing will be something like "1 of 5 -- 2 hours left (4 files/sec)"
+ *
+ * The singular/plural form will be used depending on the remaining time (i.e. the %T
argument).
+ */
+ details = f (ngettext ("%'d / %'d \xE2\x80\x94 %T left (%d files/sec)",
+ "%'d / %'d \xE2\x80\x94 %T left (%d files/sec)",
+ seconds_count_format_time_units (remaining_time)),
+ transfer_info->num_files + 1, source_info->num_files,
+ remaining_time,
+ (int) transfer_rate + 0.5);
+ } else {
+ details = f (_("%'d / %'d"),
+ transfer_info->num_files,
+ source_info->num_files);
+ }
}
+ nautilus_progress_info_set_details (job->progress, details);
if (elapsed > SECONDS_NEEDED_FOR_APROXIMATE_TRANSFER_RATE) {
nautilus_progress_info_set_remaining_time (job->progress,
@@ -1511,7 +1541,6 @@ report_delete_progress (CommonJob *job,
nautilus_progress_info_set_elapsed_time (job->progress,
elapsed);
}
- g_free (files_left_s);
if (source_info->num_files != 0) {
nautilus_progress_info_set_progress (job->progress, transfer_info->num_files,
source_info->num_files);
@@ -1786,114 +1815,231 @@ delete_files (CommonJob *job, GList *files, int *files_skipped)
}
static void
-report_trash_progress (CommonJob *job,
- int files_trashed,
- int total_files)
+report_trash_progress (CommonJob *job,
+ SourceInfo *source_info,
+ TransferInfo *transfer_info)
{
int files_left;
- char *s;
+ double elapsed, transfer_rate;
+ int remaining_time;
+ gint64 now;
+ char *details;
+ char *status;
+ DeleteJob *delete_job;
- files_left = total_files - files_trashed;
+ delete_job = (DeleteJob *) job;
+ now = g_get_monotonic_time ();
+ files_left = source_info->num_files - transfer_info->num_files;
- nautilus_progress_info_take_status (job->progress,
- f (_("Moving files to trash")));
+ /* Races and whatnot could cause this to be negative... */
+ if (files_left < 0) {
+ files_left = 0;
+ }
+
+ if (transfer_info->last_report_time != 0 &&
+ ABS ((gint64)(transfer_info->last_report_time - now)) < 100 * NSEC_PER_MICROSEC &&
+ files_left > 0) {
+ return;
+ }
+
+ transfer_info->last_report_time = now;
+
+ if (source_info->num_files == 1) {
+ if (files_left > 0) {
+ status = _("Trashing “%B”");
+ } else {
+ status = _("Trashed “%B”");
+ }
+ nautilus_progress_info_take_status (job->progress,
+ f (status,
+ (GFile*) delete_job->files->data));
+
+ } else {
+ if (files_left > 0) {
+ status = _("Trashing %'d files");
+ } else {
+ status = _("Trashed %'d files");
+ }
+ nautilus_progress_info_take_status (job->progress,
+ f (status,
+ source_info->num_files));
+ }
- s = f (ngettext ("%'d file left to trash",
- "%'d files left to trash",
- files_left),
- files_left);
- nautilus_progress_info_take_details (job->progress, s);
- if (total_files != 0) {
- nautilus_progress_info_set_progress (job->progress, files_trashed, total_files);
+ elapsed = g_timer_elapsed (job->time, NULL);
+ transfer_rate = 0;
+ remaining_time = INT_MAX;
+ if (elapsed > 0) {
+ transfer_rate = transfer_info->num_files / elapsed;
+ if (transfer_rate > 0)
+ remaining_time = (source_info->num_files - transfer_info->num_files) / transfer_rate;
}
-}
+ if (elapsed < SECONDS_NEEDED_FOR_RELIABLE_TRANSFER_RATE) {
+ if (files_left > 0) {
+ details = f (_("%'d / %'d"),
+ transfer_info->num_files + 1,
+ source_info->num_files);
+ } else {
+ details = f (_("%'d / %'d"),
+ transfer_info->num_files,
+ source_info->num_files);
+ }
+ } else {
+ if (files_left > 0) {
+ /* To translators: %T will expand to a time duration like "2 minutes".
+ * So the whole thing will be something like "1 of 5 -- 2 hours left (4 files/sec)"
+ *
+ * The singular/plural form will be used depending on the remaining time (i.e. the %T
argument).
+ */
+ details = f (ngettext ("%'d / %'d \xE2\x80\x94 %T left (%d files/sec)",
+ "%'d / %'d \xE2\x80\x94 %T left (%d files/sec)",
+ seconds_count_format_time_units (remaining_time)),
+ transfer_info->num_files + 1, source_info->num_files,
+ remaining_time,
+ (int) transfer_rate + 0.5);
+ } else {
+ details = f (_("%'d / %'d"),
+ transfer_info->num_files,
+ source_info->num_files);
+ }
+ }
+ nautilus_progress_info_set_details (job->progress, details);
+
+ if (elapsed > SECONDS_NEEDED_FOR_APROXIMATE_TRANSFER_RATE) {
+ nautilus_progress_info_set_remaining_time (job->progress,
+ remaining_time);
+ nautilus_progress_info_set_elapsed_time (job->progress,
+ elapsed);
+ }
+
+ if (source_info->num_files != 0) {
+ nautilus_progress_info_set_progress (job->progress, transfer_info->num_files,
source_info->num_files);
+ }
+}
static void
-trash_files (CommonJob *job, GList *files, int *files_skipped)
+trash_file (CommonJob *job,
+ GFile *file,
+ gboolean *skipped_file,
+ SourceInfo *source_info,
+ TransferInfo *transfer_info,
+ gboolean toplevel,
+ GList *to_delete)
{
- GList *l;
- GFile *file;
- GList *to_delete;
GError *error;
- int total_files, files_trashed;
char *primary, *secondary, *details;
int response;
- if (job_aborted (job)) {
+ if (should_skip_file (job, file)) {
+ *skipped_file = TRUE;
return;
}
- total_files = g_list_length (files);
- files_trashed = 0;
+ error = NULL;
- report_trash_progress (job, files_trashed, total_files);
+ if (g_file_trash (file, job->cancellable, &error)) {
+ transfer_info->num_files ++;
+ nautilus_file_changes_queue_file_removed (file);
- to_delete = NULL;
- for (l = files;
- l != NULL && !job_aborted (job);
- l = l->next) {
- file = l->data;
+ if (job->undo_info != NULL) {
+ nautilus_file_undo_info_trash_add_file (NAUTILUS_FILE_UNDO_INFO_TRASH
(job->undo_info), file);
+ }
- error = NULL;
+ report_trash_progress (job, source_info, transfer_info);
+ return;
+ }
- if (!g_file_trash (file, job->cancellable, &error)) {
- if (job->skip_all_error) {
- (*files_skipped)++;
- goto skip;
- }
+ if (job->skip_all_error) {
+ *skipped_file = TRUE;
+ goto skip;
+ }
- if (job->delete_all) {
- to_delete = g_list_prepend (to_delete, file);
- goto skip;
- }
+ if (job->delete_all) {
+ to_delete = g_list_prepend (to_delete, file);
+ goto skip;
+ }
- /* Translators: %B is a file name */
- primary = f (_("“%B” can't be put in the trash. Do you want to delete it
immediately?"), file);
- details = NULL;
- secondary = NULL;
- if (!IS_IO_ERROR (error, NOT_SUPPORTED)) {
- details = error->message;
- } else if (!g_file_is_native (file)) {
- secondary = f (_("This remote location does not support sending items to the
trash."));
- }
+ /* Translators: %B is a file name */
+ primary = f (_("“%B” can't be put in the trash. Do you want to delete it immediately?"), file);
+ details = NULL;
+ secondary = NULL;
+ if (!IS_IO_ERROR (error, NOT_SUPPORTED)) {
+ details = error->message;
+ } else if (!g_file_is_native (file)) {
+ secondary = f (_("This remote location does not support sending items to the trash."));
+ }
- response = run_question (job,
- primary,
- secondary,
- details,
- (total_files - files_trashed) > 1,
- CANCEL, SKIP_ALL, SKIP, DELETE_ALL, DELETE,
- NULL);
+ response = run_question (job,
+ primary,
+ secondary,
+ details,
+ (source_info->num_files - transfer_info->num_files) > 1,
+ CANCEL, SKIP_ALL, SKIP, DELETE_ALL, DELETE,
+ NULL);
- if (response == 0 || response == GTK_RESPONSE_DELETE_EVENT) {
- ((DeleteJob *) job)->user_cancel = TRUE;
- abort_job (job);
- } else if (response == 1) { /* skip all */
- (*files_skipped)++;
- job->skip_all_error = TRUE;
- } else if (response == 2) { /* skip */
- (*files_skipped)++;
- } else if (response == 3) { /* delete all */
- to_delete = g_list_prepend (to_delete, file);
- job->delete_all = TRUE;
- } else if (response == 4) { /* delete */
- to_delete = g_list_prepend (to_delete, file);
- }
+ if (response == 0 || response == GTK_RESPONSE_DELETE_EVENT) {
+ ((DeleteJob *) job)->user_cancel = TRUE;
+ abort_job (job);
+ } else if (response == 1) { /* skip all */
+ *skipped_file = TRUE;
+ job->skip_all_error = TRUE;
+ } else if (response == 2) { /* skip */
+ *skipped_file = TRUE;
+ job->skip_all_error = TRUE;
+ } else if (response == 3) { /* delete all */
+ to_delete = g_list_prepend (to_delete, file);
+ job->delete_all = TRUE;
+ } else if (response == 4) { /* delete */
+ to_delete = g_list_prepend (to_delete, file);
+ }
- skip:
- g_error_free (error);
- total_files--;
- } else {
- nautilus_file_changes_queue_file_removed (file);
+skip:
+ g_error_free (error);
+}
- if (job->undo_info != NULL) {
- nautilus_file_undo_info_trash_add_file (NAUTILUS_FILE_UNDO_INFO_TRASH
(job->undo_info), file);
- }
+static void
+trash_files (CommonJob *job,
+ GList *files,
+ int *files_skipped)
+{
+ GList *l;
+ GFile *file;
+ GList *to_delete;
+ SourceInfo source_info;
+ TransferInfo transfer_info;
+ gboolean skipped_file;
+
+ if (job_aborted (job)) {
+ return;
+ }
- files_trashed++;
- report_trash_progress (job, files_trashed, total_files);
+ scan_sources (files,
+ &source_info,
+ job,
+ OP_KIND_TRASH);
+ if (job_aborted (job)) {
+ return;
+ }
+
+ g_timer_start (job->time);
+
+ memset (&transfer_info, 0, sizeof (transfer_info));
+ report_trash_progress (job, &source_info, &transfer_info);
+
+ to_delete = NULL;
+ for (l = files;
+ l != NULL && !job_aborted (job);
+ l = l->next) {
+ file = l->data;
+
+ skipped_file = FALSE;
+ trash_file (job, file,
+ &skipped_file,
+ &source_info, &transfer_info,
+ TRUE, to_delete);
+ if (skipped_file) {
+ (*files_skipped)++;
}
}
@@ -2968,6 +3114,8 @@ report_copy_progress (CopyMoveJob *copy_job,
guint64 now;
CommonJob *job;
gboolean is_move;
+ gchar *status;
+ char *details;
job = (CommonJob *)copy_job;
@@ -2975,73 +3123,100 @@ report_copy_progress (CopyMoveJob *copy_job,
now = g_get_monotonic_time ();
- if (transfer_info->last_report_time != 0 &&
- ABS ((gint64)(transfer_info->last_report_time - now)) < 100 * NSEC_PER_MICROSEC) {
- return;
- }
- transfer_info->last_report_time = now;
-
files_left = source_info->num_files - transfer_info->num_files;
/* Races and whatnot could cause this to be negative... */
if (files_left < 0) {
- files_left = 1;
+ files_left = 0;
}
+ if (transfer_info->last_report_time != 0 &&
+ ABS ((gint64)(transfer_info->last_report_time - now)) < 100 * NSEC_PER_MICROSEC &&
+ files_left > 0) {
+ return;
+ }
+ transfer_info->last_report_time = now;
+
if (files_left != transfer_info->last_reported_files_left ||
transfer_info->last_reported_files_left == 0) {
/* Avoid changing this unless files_left changed since last time */
transfer_info->last_reported_files_left = files_left;
-
+
if (source_info->num_files == 1) {
if (copy_job->destination != NULL) {
+ if (is_move) {
+ if (files_left > 0) {
+ status = _("Moving “%B” to “%B”");
+ } else {
+ status = _("Moved “%B” to “%B”");
+ }
+ } else {
+ if (files_left > 0) {
+ status = _("Copying “%B” to “%B”");
+ } else {
+ status = _("Copied “%B” to “%B”");
+ }
+ }
nautilus_progress_info_take_status (job->progress,
- f (is_move ?
- _("Moving “%B” to “%B”"):
- _("Copying “%B” to “%B”"),
+ f (status,
copy_job->fake_display_source != NULL ?
copy_job->fake_display_source :
(GFile *)copy_job->files->data,
copy_job->destination));
} else {
+ if (files_left > 0) {
+ status = _("Duplicating “%B”");
+ } else {
+ status = _("Duplicated “%B”");
+ }
nautilus_progress_info_take_status (job->progress,
- f (_("Duplicating “%B”"),
- (GFile *)copy_job->files->data));
- }
- } else if (copy_job->files != NULL &&
- copy_job->files->next == NULL) {
- if (copy_job->destination != NULL) {
- nautilus_progress_info_take_status (job->progress,
- f (is_move ?
- _("Moving file %'d of %'d (in “%B”) to
“%B”")
- :
- _("Copying file %'d of %'d (in “%B”)
to “%B”"),
- transfer_info->num_files + 1,
- source_info->num_files,
- (GFile *)copy_job->files->data,
- copy_job->destination));
- } else {
- nautilus_progress_info_take_status (job->progress,
- f (_("Duplicating file %'d of %'d (in
“%B”)"),
- transfer_info->num_files + 1,
- source_info->num_files,
+ f (status,
(GFile *)copy_job->files->data));
}
- } else {
+ } else if (copy_job->files != NULL) {
if (copy_job->destination != NULL) {
- nautilus_progress_info_take_status (job->progress,
- f (is_move ?
- _("Moving file %'d of %'d to “%B”")
- :
- _ ("Copying file %'d of %'d to “%B”"),
- transfer_info->num_files + 1,
- source_info->num_files,
- copy_job->destination));
+ if (files_left > 0) {
+ if (is_move) {
+ status = _("Moving %'d files to “%B”");
+ } else {
+ status = _("Copying %'d files to “%B”");
+ }
+ nautilus_progress_info_take_status (job->progress,
+ f (status,
+ source_info->num_files,
+ (GFile *)copy_job->destination,
+ copy_job->destination));
+ } else {
+ if (is_move) {
+ status = _("Moved %'d files to “%B”");
+ } else {
+ status = _("Copied %'d files to “%B”");
+ }
+ nautilus_progress_info_take_status (job->progress,
+ f (status,
+ source_info->num_files,
+ (GFile *)copy_job->destination,
+ copy_job->destination));
+ }
} else {
- nautilus_progress_info_take_status (job->progress,
- f (_("Duplicating file %'d of %'d"),
- transfer_info->num_files + 1,
- source_info->num_files));
+ GFile *parent;
+
+ parent = g_file_get_parent (copy_job->files->data);
+ if (files_left > 0) {
+ status = _("Duplicating %'d files in “%B”");
+ nautilus_progress_info_take_status (job->progress,
+ f (status,
+ transfer_info->num_files + 1,
+ source_info->num_files,
+ parent));
+ } else {
+ status = _("Duplicated %'d files in “%B”");
+ nautilus_progress_info_take_status (job->progress,
+ f (status,
+ source_info->num_files,
+ parent));
+ }
+ g_object_unref (parent);
}
}
}
@@ -3057,28 +3232,63 @@ report_copy_progress (CopyMoveJob *copy_job,
remaining_time = (total_size - transfer_info->num_bytes) / transfer_rate;
}
- if (elapsed < SECONDS_NEEDED_FOR_RELIABLE_TRANSFER_RATE &&
- transfer_rate > 0) {
- char *s;
- /* To translators: %S will expand to a size like "2 bytes" or "3 MB", so something like "4 kb
of 4 MB" */
- s = f (_("%S of %S"), transfer_info->num_bytes, total_size);
- nautilus_progress_info_take_details (job->progress, s);
+ if (elapsed < SECONDS_NEEDED_FOR_RELIABLE_TRANSFER_RATE &&
+ transfer_rate > 0) {
+ if (source_info->num_files == 1) {
+ /* To translators: %S will expand to a size like "2 bytes" or "3 MB", so something
like "4 kb of 4 MB" */
+ details = f (_("%S / %S"), transfer_info->num_bytes, total_size);
+ } else {
+ if (files_left > 0) {
+ details = f (_("%'d / %'d"),
+ transfer_info->num_files + 1,
+ source_info->num_files);
+ } else {
+ details = f (_("%'d / %'d"),
+ transfer_info->num_files,
+ source_info->num_files);
+ }
+ }
} else {
- char *s;
-
- /* To translators: %S will expand to a size like "2 bytes" or "3 MB", %T to a time duration
like
- * "2 minutes". So the whole thing will be something like "2 kb of 4 MB -- 2 hours left
(4kb/sec)"
- *
- * The singular/plural form will be used depending on the remaining time (i.e. the %T
argument).
- */
- s = f (ngettext ("%S of %S \xE2\x80\x94 %T left (%S/sec)",
- "%S of %S \xE2\x80\x94 %T left (%S/sec)",
- seconds_count_format_time_units (remaining_time)),
- transfer_info->num_bytes, total_size,
- remaining_time,
- (goffset)transfer_rate);
- nautilus_progress_info_take_details (job->progress, s);
+ if (source_info->num_files == 1) {
+ if (files_left > 0) {
+ /* To translators: %S will expand to a size like "2 bytes" or "3 MB", %T to a
time duration like
+ * "2 minutes". So the whole thing will be something like "2 kb / 4 MB -- 2
hours left (4kb/sec)"
+ *
+ * The singular/plural form will be used depending on the remaining time
(i.e. the %T argument).
+ */
+ details = f (ngettext ("%S / %S \xE2\x80\x94 %T left (%S/sec)",
+ "%S / %S \xE2\x80\x94 %T left (%S/sec)",
+ seconds_count_format_time_units (remaining_time)),
+ transfer_info->num_bytes, total_size,
+ remaining_time,
+ (goffset)transfer_rate);
+ } else {
+ /* To translators: %S will expand to a size like "2 bytes" or "3 MB". */
+ details = f (_("%S / %S"),
+ transfer_info->num_bytes,
+ total_size);
+ }
+ } else {
+ if (files_left > 0) {
+ /* To translators: %T will expand to a time duration like "2 minutes".
+ * So the whole thing will be something like "1 / 5 -- 2 hours left
(4kb/sec)"
+ *
+ * The singular/plural form will be used depending on the remaining time
(i.e. the %T argument).
+ */
+ details = f (ngettext ("%'d / %'d \xE2\x80\x94 %T left (%S/sec)",
+ "%'d / %'d \xE2\x80\x94 %T left (%S/sec)",
+ seconds_count_format_time_units (remaining_time)),
+ transfer_info->num_files + 1, source_info->num_files,
+ remaining_time,
+ (goffset)transfer_rate);
+ } else {
+ details = f (_("%'d / %'d"),
+ transfer_info->num_files,
+ source_info->num_files);
+ }
+ }
}
+ nautilus_progress_info_take_details (job->progress, details);
if (elapsed > SECONDS_NEEDED_FOR_APROXIMATE_TRANSFER_RATE) {
nautilus_progress_info_set_remaining_time (job->progress,
@@ -3892,8 +4102,8 @@ copy_file_progress_callback (goffset current_num_bytes,
if (new_size > 0) {
pdata->transfer_info->num_bytes += new_size;
pdata->last_size = current_num_bytes;
- report_copy_progress (pdata->job,
- pdata->source_info,
+ report_copy_progress (pdata->job,
+ pdata->source_info,
pdata->transfer_info);
}
}
diff --git a/libnautilus-private/nautilus-progress-info-manager.c
b/libnautilus-private/nautilus-progress-info-manager.c
index 661f5da..2a46523 100644
--- a/libnautilus-private/nautilus-progress-info-manager.c
+++ b/libnautilus-private/nautilus-progress-info-manager.c
@@ -102,14 +102,6 @@ nautilus_progress_info_manager_class_init (NautilusProgressInfoManagerClass *kla
g_type_class_add_private (klass, sizeof (NautilusProgressInfoManagerPriv));
}
-static void
-progress_info_finished_cb (NautilusProgressInfo *info,
- NautilusProgressInfoManager *self)
-{
- self->priv->progress_infos =
- g_list_remove (self->priv->progress_infos, info);
-}
-
NautilusProgressInfoManager *
nautilus_progress_info_manager_dup_singleton (void)
{
@@ -128,12 +120,26 @@ nautilus_progress_info_manager_add_new_info (NautilusProgressInfoManager *self,
self->priv->progress_infos =
g_list_prepend (self->priv->progress_infos, g_object_ref (info));
- g_signal_connect (info, "finished",
- G_CALLBACK (progress_info_finished_cb), self);
-
g_signal_emit (self, signals[NEW_PROGRESS_INFO], 0, info);
}
+void
+nautilus_progress_info_manager_remove_finished_infos (NautilusProgressInfoManager *self)
+{
+ GList *l;
+ GList *next;
+
+ l = self->priv->progress_infos;
+ while (l != NULL) {
+ next = l->next;
+ if (nautilus_progress_info_get_is_finished (l->data)) {
+ self->priv->progress_infos = g_list_remove (self->priv->progress_infos,
+ l->data);
+ }
+ l = next;
+ }
+}
+
GList *
nautilus_progress_info_manager_get_all_infos (NautilusProgressInfoManager *self)
{
diff --git a/libnautilus-private/nautilus-progress-info-manager.h
b/libnautilus-private/nautilus-progress-info-manager.h
index 7198bd3..39a377b 100644
--- a/libnautilus-private/nautilus-progress-info-manager.h
+++ b/libnautilus-private/nautilus-progress-info-manager.h
@@ -62,6 +62,7 @@ NautilusProgressInfoManager* nautilus_progress_info_manager_dup_singleton (void)
void nautilus_progress_info_manager_add_new_info (NautilusProgressInfoManager *self,
NautilusProgressInfo *info);
GList *nautilus_progress_info_manager_get_all_infos (NautilusProgressInfoManager *self);
+void nautilus_progress_info_manager_remove_finished_infos (NautilusProgressInfoManager *self);
G_END_DECLS
diff --git a/src/nautilus-progress-info-widget.c b/src/nautilus-progress-info-widget.c
index 7834676..5bafe04 100644
--- a/src/nautilus-progress-info-widget.c
+++ b/src/nautilus-progress-info-widget.c
@@ -47,7 +47,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (NautilusProgressInfoWidget, nautilus_progress_info_w
static void
info_finished (NautilusProgressInfoWidget *self)
{
- gtk_widget_destroy (GTK_WIDGET (self));
+ gtk_widget_set_sensitive (self->priv->cancel, FALSE);
}
static void
@@ -183,10 +183,25 @@ nautilus_progress_info_widget_class_init (NautilusProgressInfoWidgetClass *klass
gtk_widget_class_bind_template_child_private (widget_class, NautilusProgressInfoWidget, cancel);
}
+void
+nautilus_progress_info_widget_destroy_if_finished (NautilusProgressInfoWidget *self)
+{
+ if (nautilus_progress_info_get_is_finished (self->priv->info)) {
+ gtk_widget_destroy (GTK_WIDGET (self));
+ }
+}
+
GtkWidget *
nautilus_progress_info_widget_new (NautilusProgressInfo *info)
{
- return g_object_new (NAUTILUS_TYPE_PROGRESS_INFO_WIDGET,
+ NautilusProgressInfoWidget *self;
+
+ self = g_object_new (NAUTILUS_TYPE_PROGRESS_INFO_WIDGET,
"info", info,
NULL);
+
+ gtk_widget_set_sensitive (self->priv->cancel,
+ !nautilus_progress_info_get_is_finished (self->priv->info));
+
+ return GTK_WIDGET (self);
}
diff --git a/src/nautilus-progress-info-widget.h b/src/nautilus-progress-info-widget.h
index f1c99c0..22bf7e3 100644
--- a/src/nautilus-progress-info-widget.h
+++ b/src/nautilus-progress-info-widget.h
@@ -58,4 +58,6 @@ GType nautilus_progress_info_widget_get_type (void);
GtkWidget * nautilus_progress_info_widget_new (NautilusProgressInfo *info);
+void nautilus_progress_info_widget_destroy_if_finished (NautilusProgressInfoWidget *self);
+
#endif /* __NAUTILUS_PROGRESS_INFO_WIDGET_H__ */
diff --git a/src/nautilus-toolbar-ui.xml b/src/nautilus-toolbar-ui.xml
index 42051b2..791ad37 100644
--- a/src/nautilus-toolbar-ui.xml
+++ b/src/nautilus-toolbar-ui.xml
@@ -179,6 +179,7 @@
<object class="GtkPopover" id="operations_popover">
<property name="modal">false</property>
<property name="relative-to">operations_button</property>
+ <signal name="closed" handler="remove_finished_operations" object="NautilusToolbar" swapped="yes"/>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
diff --git a/src/nautilus-toolbar.c b/src/nautilus-toolbar.c
index 69099c1..d6b39de 100644
--- a/src/nautilus-toolbar.c
+++ b/src/nautilus-toolbar.c
@@ -434,8 +434,7 @@ view_menu_popover_closed (GtkPopover *popover,
}
static void
-on_progress_info_finished (NautilusProgressInfo *info,
- NautilusToolbar *self)
+update_operations_button_visibility (NautilusToolbar *self)
{
GList *progress_infos;
@@ -447,6 +446,25 @@ on_progress_info_finished (NautilusProgressInfo *info,
}
static void
+remove_finished_operations (NautilusToolbar *self)
+{
+ nautilus_progress_info_manager_remove_finished_infos (self->priv->progress_manager);
+ gtk_container_foreach (GTK_CONTAINER (self->priv->operations_container),
+ (GtkCallback) nautilus_progress_info_widget_destroy_if_finished,
+ NULL);
+ update_operations_button_visibility (self);
+}
+
+static void
+on_progress_info_finished (NautilusProgressInfo *info,
+ NautilusToolbar *self)
+{
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->priv->operations_button))) {
+ remove_finished_operations (self);
+ }
+}
+
+static void
on_progress_info_progress_changed (NautilusProgressInfo *info,
NautilusToolbar *self)
{
@@ -752,6 +770,7 @@ nautilus_toolbar_class_init (NautilusToolbarClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, NautilusToolbar, forward_button);
gtk_widget_class_bind_template_callback (widget_class, on_operations_icon_draw);
+ gtk_widget_class_bind_template_callback (widget_class, remove_finished_operations);
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]