|
|
03a6ff |
From d0202bad05d3e50e074fbf6d7fd966aa5de6713c Mon Sep 17 00:00:00 2001
|
|
|
03a6ff |
From: Jonathon Jongsma <jjongsma@redhat.com>
|
|
|
03a6ff |
Date: Fri, 8 Apr 2016 10:26:32 -0500
|
|
|
03a6ff |
Subject: [PATCH] Add file transfer dialog
|
|
|
03a6ff |
MIME-Version: 1.0
|
|
|
03a6ff |
Content-Type: text/plain; charset=UTF-8
|
|
|
03a6ff |
Content-Transfer-Encoding: 8bit
|
|
|
03a6ff |
|
|
|
03a6ff |
This dialog will show the progress of files being transferred from the
|
|
|
03a6ff |
client to the guest and allows the user to cancel ongoing file transfer
|
|
|
03a6ff |
tasks. The user can cancel each transfer individually, or cancel all
|
|
|
03a6ff |
ongoing transfers at once.
|
|
|
03a6ff |
|
|
|
03a6ff |
Resolves: rhbz#1332180, rhbz#1324521
|
|
|
03a6ff |
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
|
|
|
03a6ff |
Acked-by: Fabiano FidĂȘncio <fidencio@redhat.com>
|
|
|
03a6ff |
(cherry picked from commit 0856067d79db02db86227d2f1beb0b03859613d5)
|
|
|
03a6ff |
---
|
|
|
03a6ff |
po/POTFILES.in | 1 +
|
|
|
03a6ff |
src/Makefile.am | 1 +
|
|
|
03a6ff |
src/virt-viewer-file-transfer-dialog.c | 215 +++++++++++++++++++++++++++++++++
|
|
|
03a6ff |
src/virt-viewer-file-transfer-dialog.h | 61 ++++++++++
|
|
|
03a6ff |
src/virt-viewer-session-spice.c | 43 +++++--
|
|
|
03a6ff |
5 files changed, 310 insertions(+), 11 deletions(-)
|
|
|
03a6ff |
create mode 100644 src/virt-viewer-file-transfer-dialog.c
|
|
|
03a6ff |
create mode 100644 src/virt-viewer-file-transfer-dialog.h
|
|
|
03a6ff |
|
|
|
03a6ff |
diff --git a/po/POTFILES.in b/po/POTFILES.in
|
|
|
03a6ff |
index f270898..e6cc31f 100644
|
|
|
03a6ff |
--- a/po/POTFILES.in
|
|
|
03a6ff |
+++ b/po/POTFILES.in
|
|
|
03a6ff |
@@ -8,6 +8,7 @@ src/virt-viewer-app.c
|
|
|
03a6ff |
src/virt-viewer-auth.c
|
|
|
03a6ff |
[type: gettext/glade] src/virt-viewer-auth.xml
|
|
|
03a6ff |
src/virt-viewer-display-vnc.c
|
|
|
03a6ff |
+src/virt-viewer-file-transfer-dialog.c
|
|
|
03a6ff |
src/virt-viewer-main.c
|
|
|
03a6ff |
src/virt-viewer-session-spice.c
|
|
|
03a6ff |
src/virt-viewer-session-vnc.c
|
|
|
03a6ff |
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
|
03a6ff |
index b8dbb35..182f58d 100644
|
|
|
03a6ff |
--- a/src/Makefile.am
|
|
|
03a6ff |
+++ b/src/Makefile.am
|
|
|
03a6ff |
@@ -67,6 +67,7 @@ if HAVE_SPICE_GTK
|
|
|
03a6ff |
COMMON_SOURCES += \
|
|
|
03a6ff |
virt-viewer-session-spice.h virt-viewer-session-spice.c \
|
|
|
03a6ff |
virt-viewer-display-spice.h virt-viewer-display-spice.c \
|
|
|
03a6ff |
+ virt-viewer-file-transfer-dialog.h virt-viewer-file-transfer-dialog.c \
|
|
|
03a6ff |
$(NULL)
|
|
|
03a6ff |
endif
|
|
|
03a6ff |
|
|
|
03a6ff |
diff --git a/src/virt-viewer-file-transfer-dialog.c b/src/virt-viewer-file-transfer-dialog.c
|
|
|
03a6ff |
new file mode 100644
|
|
|
03a6ff |
index 0000000..be16518
|
|
|
03a6ff |
--- /dev/null
|
|
|
03a6ff |
+++ b/src/virt-viewer-file-transfer-dialog.c
|
|
|
03a6ff |
@@ -0,0 +1,215 @@
|
|
|
03a6ff |
+/*
|
|
|
03a6ff |
+ * Virt Viewer: A virtual machine console viewer
|
|
|
03a6ff |
+ *
|
|
|
03a6ff |
+ * Copyright (C) 2016 Red Hat, Inc.
|
|
|
03a6ff |
+ *
|
|
|
03a6ff |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
03a6ff |
+ * it under the terms of the GNU General Public License as published by
|
|
|
03a6ff |
+ * the Free Software Foundation; either version 2 of the License, or
|
|
|
03a6ff |
+ * (at your option) any later version.
|
|
|
03a6ff |
+ *
|
|
|
03a6ff |
+ * This program is distributed in the hope that it will be useful,
|
|
|
03a6ff |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
03a6ff |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
03a6ff |
+ * GNU General Public License for more details.
|
|
|
03a6ff |
+ *
|
|
|
03a6ff |
+ * You should have received a copy of the GNU General Public License
|
|
|
03a6ff |
+ * along with this program; if not, write to the Free Software
|
|
|
03a6ff |
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
03a6ff |
+ */
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+#include <config.h>
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+#include "virt-viewer-file-transfer-dialog.h"
|
|
|
03a6ff |
+#include <glib/gi18n.h>
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+G_DEFINE_TYPE(VirtViewerFileTransferDialog, virt_viewer_file_transfer_dialog, GTK_TYPE_DIALOG)
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+#define FILE_TRANSFER_DIALOG_PRIVATE(o) \
|
|
|
03a6ff |
+ (G_TYPE_INSTANCE_GET_PRIVATE((o), VIRT_VIEWER_TYPE_FILE_TRANSFER_DIALOG, VirtViewerFileTransferDialogPrivate))
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+struct _VirtViewerFileTransferDialogPrivate
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ /* GHashTable<SpiceFileTransferTask, widgets> */
|
|
|
03a6ff |
+ GHashTable *file_transfers;
|
|
|
03a6ff |
+};
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+static void
|
|
|
03a6ff |
+virt_viewer_file_transfer_dialog_dispose(GObject *object)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ VirtViewerFileTransferDialog *self = VIRT_VIEWER_FILE_TRANSFER_DIALOG(object);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ g_clear_pointer(&self->priv->file_transfers, g_hash_table_unref);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ G_OBJECT_CLASS(virt_viewer_file_transfer_dialog_parent_class)->dispose(object);
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+static void
|
|
|
03a6ff |
+virt_viewer_file_transfer_dialog_class_init(VirtViewerFileTransferDialogClass *klass)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ g_type_class_add_private(klass, sizeof(VirtViewerFileTransferDialogPrivate));
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ object_class->dispose = virt_viewer_file_transfer_dialog_dispose;
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+static void
|
|
|
03a6ff |
+dialog_response(GtkDialog *dialog,
|
|
|
03a6ff |
+ gint response_id,
|
|
|
03a6ff |
+ gpointer user_data G_GNUC_UNUSED)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ VirtViewerFileTransferDialog *self = VIRT_VIEWER_FILE_TRANSFER_DIALOG(dialog);
|
|
|
03a6ff |
+ GHashTableIter iter;
|
|
|
03a6ff |
+ gpointer key, value;
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ switch (response_id) {
|
|
|
03a6ff |
+ case GTK_RESPONSE_CANCEL:
|
|
|
03a6ff |
+ /* cancel all current tasks */
|
|
|
03a6ff |
+ g_hash_table_iter_init(&iter, self->priv->file_transfers);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
|
|
|
03a6ff |
+ spice_file_transfer_task_cancel(SPICE_FILE_TRANSFER_TASK(key));
|
|
|
03a6ff |
+ }
|
|
|
03a6ff |
+ break;
|
|
|
03a6ff |
+ case GTK_RESPONSE_DELETE_EVENT:
|
|
|
03a6ff |
+ /* silently ignore */
|
|
|
03a6ff |
+ break;
|
|
|
03a6ff |
+ default:
|
|
|
03a6ff |
+ g_warn_if_reached();
|
|
|
03a6ff |
+ }
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+static void task_cancel_clicked(GtkButton *button G_GNUC_UNUSED,
|
|
|
03a6ff |
+ gpointer user_data)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ SpiceFileTransferTask *task = user_data;
|
|
|
03a6ff |
+ spice_file_transfer_task_cancel(task);
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+typedef struct {
|
|
|
03a6ff |
+ GtkWidget *vbox;
|
|
|
03a6ff |
+ GtkWidget *hbox;
|
|
|
03a6ff |
+ GtkWidget *progress;
|
|
|
03a6ff |
+ GtkWidget *label;
|
|
|
03a6ff |
+ GtkWidget *cancel;
|
|
|
03a6ff |
+} TaskWidgets;
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+static TaskWidgets *task_widgets_new(SpiceFileTransferTask *task)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ TaskWidgets *w = g_new0(TaskWidgets, 1);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ w->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
|
|
|
03a6ff |
+ w->hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
|
|
|
03a6ff |
+ w->progress = gtk_progress_bar_new();
|
|
|
03a6ff |
+ w->label = gtk_label_new(spice_file_transfer_task_get_filename(task));
|
|
|
03a6ff |
+ w->cancel = gtk_button_new_from_icon_name("gtk-cancel", GTK_ICON_SIZE_SMALL_TOOLBAR);
|
|
|
03a6ff |
+ gtk_widget_set_hexpand(w->progress, TRUE);
|
|
|
03a6ff |
+ gtk_widget_set_valign(w->progress, GTK_ALIGN_CENTER);
|
|
|
03a6ff |
+ gtk_widget_set_hexpand(w->label, TRUE);
|
|
|
03a6ff |
+ gtk_widget_set_valign(w->label, GTK_ALIGN_END);
|
|
|
03a6ff |
+ gtk_widget_set_halign(w->label, GTK_ALIGN_START);
|
|
|
03a6ff |
+ gtk_widget_set_hexpand(w->cancel, FALSE);
|
|
|
03a6ff |
+ gtk_widget_set_valign(w->cancel, GTK_ALIGN_CENTER);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ g_signal_connect(w->cancel, "clicked",
|
|
|
03a6ff |
+ G_CALLBACK(task_cancel_clicked), task);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ gtk_box_pack_start(GTK_BOX(w->hbox), w->progress, TRUE, TRUE, 0);
|
|
|
03a6ff |
+ gtk_box_pack_start(GTK_BOX(w->hbox), w->cancel, FALSE, TRUE, 0);
|
|
|
03a6ff |
+ gtk_box_pack_start(GTK_BOX(w->vbox), w->label, TRUE, TRUE, 0);
|
|
|
03a6ff |
+ gtk_box_pack_start(GTK_BOX(w->vbox), w->hbox, TRUE, TRUE, 0);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ gtk_widget_show_all(w->vbox);
|
|
|
03a6ff |
+ return w;
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+static gboolean delete_event(GtkWidget *widget,
|
|
|
03a6ff |
+ GdkEvent *event G_GNUC_UNUSED,
|
|
|
03a6ff |
+ gpointer user_data G_GNUC_UNUSED)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ /* don't allow window to be deleted, just process the response signal,
|
|
|
03a6ff |
+ * which may result in the window being hidden */
|
|
|
03a6ff |
+ gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_CANCEL);
|
|
|
03a6ff |
+ return TRUE;
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+static void
|
|
|
03a6ff |
+virt_viewer_file_transfer_dialog_init(VirtViewerFileTransferDialog *self)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ GtkBox *content = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(self)));
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ self->priv = FILE_TRANSFER_DIALOG_PRIVATE(self);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ gtk_widget_set_size_request(GTK_WIDGET(content), 400, -1);
|
|
|
03a6ff |
+ gtk_container_set_border_width(GTK_CONTAINER(content), 12);
|
|
|
03a6ff |
+ self->priv->file_transfers = g_hash_table_new_full(g_direct_hash, g_direct_equal,
|
|
|
03a6ff |
+ g_object_unref,
|
|
|
03a6ff |
+ (GDestroyNotify)g_free);
|
|
|
03a6ff |
+ gtk_dialog_add_button(GTK_DIALOG(self), _("Cancel"), GTK_RESPONSE_CANCEL);
|
|
|
03a6ff |
+ gtk_dialog_set_default_response(GTK_DIALOG(self),
|
|
|
03a6ff |
+ GTK_RESPONSE_CANCEL);
|
|
|
03a6ff |
+ g_signal_connect(self, "response", G_CALLBACK(dialog_response), NULL);
|
|
|
03a6ff |
+ g_signal_connect(self, "delete-event", G_CALLBACK(delete_event), NULL);
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+VirtViewerFileTransferDialog *
|
|
|
03a6ff |
+virt_viewer_file_transfer_dialog_new(GtkWindow *parent)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ return g_object_new(VIRT_VIEWER_TYPE_FILE_TRANSFER_DIALOG,
|
|
|
03a6ff |
+ "title", _("File Transfers"),
|
|
|
03a6ff |
+ "transient-for", parent,
|
|
|
03a6ff |
+ "resizable", FALSE,
|
|
|
03a6ff |
+ NULL);
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+static void task_progress_notify(GObject *object,
|
|
|
03a6ff |
+ GParamSpec *pspec G_GNUC_UNUSED,
|
|
|
03a6ff |
+ gpointer user_data)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ VirtViewerFileTransferDialog *self = VIRT_VIEWER_FILE_TRANSFER_DIALOG(user_data);
|
|
|
03a6ff |
+ SpiceFileTransferTask *task = SPICE_FILE_TRANSFER_TASK(object);
|
|
|
03a6ff |
+ TaskWidgets *w = g_hash_table_lookup(self->priv->file_transfers, task);
|
|
|
03a6ff |
+ g_return_if_fail(w);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ double pct = spice_file_transfer_task_get_progress(task);
|
|
|
03a6ff |
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(w->progress), pct);
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+static void task_finished(SpiceFileTransferTask *task,
|
|
|
03a6ff |
+ GError *error,
|
|
|
03a6ff |
+ gpointer user_data)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ VirtViewerFileTransferDialog *self = VIRT_VIEWER_FILE_TRANSFER_DIALOG(user_data);
|
|
|
03a6ff |
+ TaskWidgets *w = g_hash_table_lookup(self->priv->file_transfers, task);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ if (error && !g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
|
03a6ff |
+ g_warning("File transfer task %p failed: %s", task, error->message);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ g_return_if_fail(w);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ gtk_widget_destroy(w->vbox);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ g_hash_table_remove(self->priv->file_transfers, task);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ /* if this is the last transfer, close the dialog */
|
|
|
03a6ff |
+ if (!g_hash_table_size(self->priv->file_transfers))
|
|
|
03a6ff |
+ gtk_widget_hide(GTK_WIDGET(self));
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+void virt_viewer_file_transfer_dialog_add_task(VirtViewerFileTransferDialog *self,
|
|
|
03a6ff |
+ SpiceFileTransferTask *task)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ GtkBox *content = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(self)));
|
|
|
03a6ff |
+ TaskWidgets *w = task_widgets_new(task);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ gtk_box_pack_start(content,
|
|
|
03a6ff |
+ w->vbox,
|
|
|
03a6ff |
+ TRUE, TRUE, 12);
|
|
|
03a6ff |
+ g_hash_table_insert(self->priv->file_transfers, g_object_ref(task), w);
|
|
|
03a6ff |
+ g_signal_connect(task, "notify::progress", G_CALLBACK(task_progress_notify), self);
|
|
|
03a6ff |
+ g_signal_connect(task, "finished", G_CALLBACK(task_finished), self);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ gtk_widget_show(GTK_WIDGET(self));
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
diff --git a/src/virt-viewer-file-transfer-dialog.h b/src/virt-viewer-file-transfer-dialog.h
|
|
|
03a6ff |
new file mode 100644
|
|
|
03a6ff |
index 0000000..8805b14
|
|
|
03a6ff |
--- /dev/null
|
|
|
03a6ff |
+++ b/src/virt-viewer-file-transfer-dialog.h
|
|
|
03a6ff |
@@ -0,0 +1,61 @@
|
|
|
03a6ff |
+/*
|
|
|
03a6ff |
+ * Virt Viewer: A virtual machine console viewer
|
|
|
03a6ff |
+ *
|
|
|
03a6ff |
+ * Copyright (C) 2016 Red Hat, Inc.
|
|
|
03a6ff |
+ *
|
|
|
03a6ff |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
03a6ff |
+ * it under the terms of the GNU General Public License as published by
|
|
|
03a6ff |
+ * the Free Software Foundation; either version 2 of the License, or
|
|
|
03a6ff |
+ * (at your option) any later version.
|
|
|
03a6ff |
+ *
|
|
|
03a6ff |
+ * This program is distributed in the hope that it will be useful,
|
|
|
03a6ff |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
03a6ff |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
03a6ff |
+ * GNU General Public License for more details.
|
|
|
03a6ff |
+ *
|
|
|
03a6ff |
+ * You should have received a copy of the GNU General Public License
|
|
|
03a6ff |
+ * along with this program; if not, write to the Free Software
|
|
|
03a6ff |
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
03a6ff |
+ */
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+#ifndef __VIRT_VIEWER_FILE_TRANSFER_DIALOG_H__
|
|
|
03a6ff |
+#define __VIRT_VIEWER_FILE_TRANSFER_DIALOG_H__
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+#include <gtk/gtk.h>
|
|
|
03a6ff |
+#include <spice-client.h>
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+G_BEGIN_DECLS
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+#define VIRT_VIEWER_TYPE_FILE_TRANSFER_DIALOG virt_viewer_file_transfer_dialog_get_type()
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+#define VIRT_VIEWER_FILE_TRANSFER_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), VIRT_VIEWER_TYPE_FILE_TRANSFER_DIALOG, VirtViewerFileTransferDialog))
|
|
|
03a6ff |
+#define VIRT_VIEWER_FILE_TRANSFER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), VIRT_VIEWER_TYPE_FILE_TRANSFER_DIALOG, VirtViewerFileTransferDialogClass))
|
|
|
03a6ff |
+#define VIRT_VIEWER_IS_FILE_TRANSFER_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), VIRT_VIEWER_TYPE_FILE_TRANSFER_DIALOG))
|
|
|
03a6ff |
+#define VIRT_VIEWER_IS_FILE_TRANSFER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), VIRT_VIEWER_TYPE_FILE_TRANSFER_DIALOG))
|
|
|
03a6ff |
+#define VIRT_VIEWER_FILE_TRANSFER_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), VIRT_VIEWER_TYPE_FILE_TRANSFER_DIALOG, VirtViewerFileTransferDialogClass))
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+typedef struct _VirtViewerFileTransferDialog VirtViewerFileTransferDialog;
|
|
|
03a6ff |
+typedef struct _VirtViewerFileTransferDialogClass VirtViewerFileTransferDialogClass;
|
|
|
03a6ff |
+typedef struct _VirtViewerFileTransferDialogPrivate VirtViewerFileTransferDialogPrivate;
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+struct _VirtViewerFileTransferDialog
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ GtkDialog parent;
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ VirtViewerFileTransferDialogPrivate *priv;
|
|
|
03a6ff |
+};
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+struct _VirtViewerFileTransferDialogClass
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ GtkDialogClass parent_class;
|
|
|
03a6ff |
+};
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+GType virt_viewer_file_transfer_dialog_get_type(void) G_GNUC_CONST;
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+VirtViewerFileTransferDialog *virt_viewer_file_transfer_dialog_new(GtkWindow *parent);
|
|
|
03a6ff |
+void virt_viewer_file_transfer_dialog_add_task(VirtViewerFileTransferDialog *self,
|
|
|
03a6ff |
+ SpiceFileTransferTask *task);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+G_END_DECLS
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+#endif /* __VIRT_VIEWER_FILE_TRANSFER_DIALOG_H__ */
|
|
|
03a6ff |
diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c
|
|
|
03a6ff |
index 1f5242c..326336f 100644
|
|
|
03a6ff |
--- a/src/virt-viewer-session-spice.c
|
|
|
03a6ff |
+++ b/src/virt-viewer-session-spice.c
|
|
|
03a6ff |
@@ -33,21 +33,13 @@
|
|
|
03a6ff |
|
|
|
03a6ff |
#include <usb-device-widget.h>
|
|
|
03a6ff |
#include "virt-viewer-file.h"
|
|
|
03a6ff |
+#include "virt-viewer-file-transfer-dialog.h"
|
|
|
03a6ff |
#include "virt-viewer-util.h"
|
|
|
03a6ff |
#include "virt-viewer-session-spice.h"
|
|
|
03a6ff |
#include "virt-viewer-display-spice.h"
|
|
|
03a6ff |
#include "virt-viewer-auth.h"
|
|
|
03a6ff |
#include "virt-glib-compat.h"
|
|
|
03a6ff |
|
|
|
03a6ff |
-#if !GLIB_CHECK_VERSION(2, 26, 0)
|
|
|
03a6ff |
-#include "gbinding.h"
|
|
|
03a6ff |
-#include "gbinding.c"
|
|
|
03a6ff |
-#endif
|
|
|
03a6ff |
-
|
|
|
03a6ff |
-#ifndef SPICE_GTK_CHECK_VERSION
|
|
|
03a6ff |
-#define SPICE_GTK_CHECK_VERSION(x, y, z) 0
|
|
|
03a6ff |
-#endif
|
|
|
03a6ff |
-
|
|
|
03a6ff |
G_DEFINE_TYPE (VirtViewerSessionSpice, virt_viewer_session_spice, VIRT_VIEWER_TYPE_SESSION)
|
|
|
03a6ff |
|
|
|
03a6ff |
|
|
|
03a6ff |
@@ -62,6 +54,8 @@ struct _VirtViewerSessionSpicePrivate {
|
|
|
03a6ff |
gboolean has_sw_smartcard_reader;
|
|
|
03a6ff |
guint pass_try;
|
|
|
03a6ff |
gboolean did_auto_conf;
|
|
|
03a6ff |
+ VirtViewerFileTransferDialog *file_transfer_dialog;
|
|
|
03a6ff |
+
|
|
|
03a6ff |
};
|
|
|
03a6ff |
|
|
|
03a6ff |
#define VIRT_VIEWER_SESSION_SPICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), VIRT_VIEWER_TYPE_SESSION_SPICE, VirtViewerSessionSpicePrivate))
|
|
|
03a6ff |
@@ -132,8 +126,11 @@ virt_viewer_session_spice_dispose(GObject *obj)
|
|
|
03a6ff |
|
|
|
03a6ff |
spice->priv->audio = NULL;
|
|
|
03a6ff |
|
|
|
03a6ff |
- if (spice->priv->main_window)
|
|
|
03a6ff |
- g_object_unref(spice->priv->main_window);
|
|
|
03a6ff |
+ g_clear_object(&spice->priv->main_window);
|
|
|
03a6ff |
+ if (spice->priv->file_transfer_dialog) {
|
|
|
03a6ff |
+ gtk_widget_destroy(GTK_WIDGET(spice->priv->file_transfer_dialog));
|
|
|
03a6ff |
+ spice->priv->file_transfer_dialog = NULL;
|
|
|
03a6ff |
+ }
|
|
|
03a6ff |
|
|
|
03a6ff |
G_OBJECT_CLASS(virt_viewer_session_spice_parent_class)->dispose(obj);
|
|
|
03a6ff |
}
|
|
|
03a6ff |
@@ -146,6 +143,17 @@ virt_viewer_session_spice_mime_type(VirtViewerSession *self G_GNUC_UNUSED)
|
|
|
03a6ff |
}
|
|
|
03a6ff |
|
|
|
03a6ff |
static void
|
|
|
03a6ff |
+virt_viewer_session_spice_constructed(GObject *obj)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ VirtViewerSessionSpice *self = VIRT_VIEWER_SESSION_SPICE(obj);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ self->priv->file_transfer_dialog =
|
|
|
03a6ff |
+ virt_viewer_file_transfer_dialog_new(self->priv->main_window);
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+ G_OBJECT_CLASS(virt_viewer_session_spice_parent_class)->constructed(obj);
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+static void
|
|
|
03a6ff |
virt_viewer_session_spice_class_init(VirtViewerSessionSpiceClass *klass)
|
|
|
03a6ff |
{
|
|
|
03a6ff |
VirtViewerSessionClass *dclass = VIRT_VIEWER_SESSION_CLASS(klass);
|
|
|
03a6ff |
@@ -154,6 +162,7 @@ virt_viewer_session_spice_class_init(VirtViewerSessionSpiceClass *klass)
|
|
|
03a6ff |
oclass->get_property = virt_viewer_session_spice_get_property;
|
|
|
03a6ff |
oclass->set_property = virt_viewer_session_spice_set_property;
|
|
|
03a6ff |
oclass->dispose = virt_viewer_session_spice_dispose;
|
|
|
03a6ff |
+ oclass->constructed = virt_viewer_session_spice_constructed;
|
|
|
03a6ff |
|
|
|
03a6ff |
dclass->close = virt_viewer_session_spice_close;
|
|
|
03a6ff |
dclass->open_fd = virt_viewer_session_spice_open_fd;
|
|
|
03a6ff |
@@ -777,6 +786,16 @@ virt_viewer_session_spice_display_monitors(SpiceChannel *channel,
|
|
|
03a6ff |
}
|
|
|
03a6ff |
|
|
|
03a6ff |
static void
|
|
|
03a6ff |
+on_new_file_transfer(SpiceMainChannel *channel G_GNUC_UNUSED,
|
|
|
03a6ff |
+ SpiceFileTransferTask *task,
|
|
|
03a6ff |
+ gpointer user_data)
|
|
|
03a6ff |
+{
|
|
|
03a6ff |
+ VirtViewerSessionSpice *self = VIRT_VIEWER_SESSION_SPICE(user_data);
|
|
|
03a6ff |
+ virt_viewer_file_transfer_dialog_add_task(self->priv->file_transfer_dialog,
|
|
|
03a6ff |
+ task);
|
|
|
03a6ff |
+}
|
|
|
03a6ff |
+
|
|
|
03a6ff |
+static void
|
|
|
03a6ff |
virt_viewer_session_spice_channel_new(SpiceSession *s,
|
|
|
03a6ff |
SpiceChannel *channel,
|
|
|
03a6ff |
VirtViewerSession *session)
|
|
|
03a6ff |
@@ -808,6 +827,8 @@ virt_viewer_session_spice_channel_new(SpiceSession *s,
|
|
|
03a6ff |
|
|
|
03a6ff |
virt_viewer_signal_connect_object(channel, "notify::agent-connected",
|
|
|
03a6ff |
G_CALLBACK(agent_connected_changed), self, 0);
|
|
|
03a6ff |
+ virt_viewer_signal_connect_object(channel, "new-file-transfer",
|
|
|
03a6ff |
+ G_CALLBACK(on_new_file_transfer), self, 0);
|
|
|
03a6ff |
}
|
|
|
03a6ff |
|
|
|
03a6ff |
if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
|