From 39267703f6953a8e471f2d4f89a4a7f58efe77e1 Mon Sep 17 00:00:00 2001
From: Victor Toso <me@victortoso.com>
Date: Thu, 11 May 2017 16:16:56 +0200
Subject: [PATCH virt-viewer 34/35] Make the progress bar smooth during
file-transfer
To: virt-tools-list@redhat.com
When the transfer of a file finishes we stop considering that file's
size in the progress bar which makes it move back due the new
'transfer size' and 'transferred bytes' - for all the other files.
This patch aims to keep the progress smooth when a file is finished
using the notify::total-bytes from SpiceFileTransferTask to be aware
of all file's sizes.
Note that as we have only one progress bar for all files being
transferred, it is expected that it will go back when a new
file-transfer operation starts (e.g we drag-and-drop new files while
we are already transferring other files).
As requested, this patch also updates the string message to include the
amount of files that will be transferred in case we have more then one
file.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1449572
Signed-off-by: Victor Toso <victortoso@redhat.com>
---
src/virt-viewer-file-transfer-dialog.c | 44 ++++++++++++++++++++++++++++------
1 file changed, 37 insertions(+), 7 deletions(-)
diff --git a/src/virt-viewer-file-transfer-dialog.c b/src/virt-viewer-file-transfer-dialog.c
index 07d25a7..dcf99a3 100644
--- a/src/virt-viewer-file-transfer-dialog.c
+++ b/src/virt-viewer-file-transfer-dialog.c
@@ -30,6 +30,9 @@ struct _VirtViewerFileTransferDialogPrivate
GSList *failed;
guint timer_show_src;
guint timer_hide_src;
+ guint num_files;
+ guint64 total_transfer_size;
+ guint64 completed_transfer_size;
GtkWidget *transfer_summary;
GtkWidget *progressbar;
};
@@ -85,6 +88,9 @@ dialog_response(GtkDialog *dialog,
for (slist = self->priv->file_transfers; slist != NULL; slist = g_slist_next(slist)) {
spice_file_transfer_task_cancel(SPICE_FILE_TRANSFER_TASK(slist->data));
}
+ self->priv->num_files = 0;
+ self->priv->total_transfer_size = 0;
+ self->priv->completed_transfer_size = 0;
break;
case GTK_RESPONSE_DELETE_EVENT:
/* silently ignore */
@@ -128,23 +134,29 @@ virt_viewer_file_transfer_dialog_new(GtkWindow *parent)
static void update_global_progress(VirtViewerFileTransferDialog *self)
{
GSList *slist;
- guint64 total = 0, transferred = 0;
+ guint64 transferred = 0;
gchar *message = NULL;
guint n_files = 0;
gdouble fraction = 1.0;
for (slist = self->priv->file_transfers; slist != NULL; slist = g_slist_next(slist)) {
SpiceFileTransferTask *task = slist->data;
- total += spice_file_transfer_task_get_total_bytes(task);
transferred += spice_file_transfer_task_get_transferred_bytes(task);
n_files++;
}
- if (n_files > 0)
- fraction = (gdouble)transferred / total;
- message = g_strdup_printf(ngettext("Transferring %d file...",
- "Transferring %d files...", n_files),
- n_files);
+ if (n_files > 0) {
+ transferred += self->priv->completed_transfer_size;
+ fraction = (gdouble)transferred / self->priv->total_transfer_size;
+ }
+
+ if (self->priv->num_files == 1) {
+ message = g_strdup(_("Transferring 1 file..."));
+ } else {
+ message = g_strdup_printf(ngettext("Transferring %d file of %d...",
+ "Transferring %d files of %d...", n_files),
+ n_files, self->priv->num_files);
+ }
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(self->priv->progressbar), fraction);
gtk_label_set_text(GTK_LABEL(self->priv->transfer_summary), message);
g_free(message);
@@ -159,6 +171,19 @@ static void task_progress_notify(GObject *object G_GNUC_UNUSED,
update_global_progress(self);
}
+static void task_total_bytes_notify(GObject *object,
+ GParamSpec *pspec G_GNUC_UNUSED,
+ gpointer user_data)
+{
+ VirtViewerFileTransferDialog *self = VIRT_VIEWER_FILE_TRANSFER_DIALOG(user_data);
+ SpiceFileTransferTask *task = SPICE_FILE_TRANSFER_TASK(object);
+
+ self->priv->total_transfer_size += spice_file_transfer_task_get_total_bytes(task);
+ self->priv->num_files++;
+ update_global_progress(self);
+}
+
+
static void
error_dialog_response(GtkDialog *dialog,
gint response_id G_GNUC_UNUSED,
@@ -222,11 +247,15 @@ static void task_finished(SpiceFileTransferTask *task,
}
self->priv->file_transfers = g_slist_remove(self->priv->file_transfers, task);
+ self->priv->completed_transfer_size += spice_file_transfer_task_get_total_bytes(task);
g_object_unref(task);
update_global_progress(self);
/* if this is the last transfer, close the dialog */
if (self->priv->file_transfers == NULL) {
+ self->priv->num_files = 0;
+ self->priv->total_transfer_size = 0;
+ self->priv->completed_transfer_size = 0;
/* cancel any pending 'show' operations if all tasks complete before
* the dialog can be shown */
if (self->priv->timer_show_src) {
@@ -274,6 +303,7 @@ void virt_viewer_file_transfer_dialog_add_task(VirtViewerFileTransferDialog *sel
{
self->priv->file_transfers = g_slist_prepend(self->priv->file_transfers, g_object_ref(task));
g_signal_connect(task, "notify::progress", G_CALLBACK(task_progress_notify), self);
+ g_signal_connect(task, "notify::total-bytes", G_CALLBACK(task_total_bytes_notify), self);
g_signal_connect(task, "finished", G_CALLBACK(task_finished), self);
show_transfer_dialog(self);
--
2.13.0