Blame SOURCES/0034-Make-the-progress-bar-smooth-during-file-transfer.patch

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