[virt-tools-list] [PATCH virt-viewer] remote-viewer: add a simple connection dialog

Marc-André Lureau marcandre.lureau at gmail.com
Wed Mar 28 16:54:13 UTC 2012


If the user doesn't provide URI, let's show a simple dialog to enter it.

Als save & show recently used URLs too.
---
 src/remote-viewer-main.c  |  131 +++++++++++++++++++++++++++++++++++++++++++--
 src/virt-viewer-session.c |   13 +++++
 src/virt-viewer-session.h |    1 +
 3 files changed, 141 insertions(+), 4 deletions(-)

diff --git a/src/remote-viewer-main.c b/src/remote-viewer-main.c
index d857e45..39b9c92 100644
--- a/src/remote-viewer-main.c
+++ b/src/remote-viewer-main.c
@@ -35,6 +35,7 @@
 
 #include "remote-viewer.h"
 #include "virt-viewer-app.h"
+#include "virt-viewer-session.h"
 
 static void
 remote_viewer_version(void)
@@ -65,6 +66,121 @@ option_fullscreen(G_GNUC_UNUSED const gchar *option_name,
     return FALSE;
 }
 
+static void recent_selection_changed_dialog_cb(GtkRecentChooser *chooser, gpointer data)
+{
+    GtkRecentInfo *info;
+    GtkWidget *entry = data;
+    const gchar *uri;
+
+    info = gtk_recent_chooser_get_current_item(chooser);
+    if (info == NULL)
+        return;
+
+    uri = gtk_recent_info_get_uri(info);
+    g_return_if_fail(uri != NULL);
+
+    gtk_entry_set_text(GTK_ENTRY(entry), uri);
+
+    gtk_recent_info_unref(info);
+}
+
+static void recent_item_activated_dialog_cb(GtkRecentChooser *chooser G_GNUC_UNUSED, gpointer data)
+{
+   gtk_dialog_response (GTK_DIALOG (data), GTK_RESPONSE_ACCEPT);
+}
+
+static int connect_dialog(gchar **uri)
+{
+    GtkWidget *dialog, *area, *label, *entry, *recent;
+    GtkRecentFilter *rfilter;
+    GtkTable *table;
+    int i, retval;
+
+    /* Create the widgets */
+    dialog = gtk_dialog_new_with_buttons(_("Connection details"),
+                                         NULL,
+                                         GTK_DIALOG_DESTROY_WITH_PARENT,
+                                         GTK_STOCK_CANCEL,
+                                         GTK_RESPONSE_REJECT,
+                                         GTK_STOCK_CONNECT,
+                                         GTK_RESPONSE_ACCEPT,
+                                         NULL);
+    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
+    area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+    table = GTK_TABLE(gtk_table_new(1, 2, 0));
+    gtk_box_pack_start(GTK_BOX(area), GTK_WIDGET(table), TRUE, TRUE, 0);
+    gtk_table_set_row_spacings(table, 5);
+    gtk_table_set_col_spacings(table, 5);
+
+    label = gtk_label_new(_("URL:"));
+    gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+    gtk_table_attach_defaults(table, label, 0, 1, 0, 1);
+    entry = GTK_WIDGET(gtk_entry_new());
+    g_object_set(entry, "width-request", 200, NULL);
+    gtk_table_attach_defaults(table, entry, 1, 2, 0, 1);
+
+    label = gtk_label_new(_("Recent connections:"));
+    gtk_box_pack_start(GTK_BOX(area), label, TRUE, TRUE, 0);
+    gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+    recent = GTK_WIDGET(gtk_recent_chooser_widget_new());
+    gtk_recent_chooser_set_show_icons(GTK_RECENT_CHOOSER(recent), FALSE);
+    gtk_recent_chooser_set_sort_type(GTK_RECENT_CHOOSER(recent), GTK_RECENT_SORT_MRU);
+    gtk_box_pack_start(GTK_BOX(area), recent, TRUE, TRUE, 0);
+
+    rfilter = gtk_recent_filter_new();
+    gtk_recent_filter_add_mime_type(rfilter, "application/x-spice");
+    gtk_recent_filter_add_mime_type(rfilter, "application/x-vnc");
+    gtk_recent_chooser_set_filter(GTK_RECENT_CHOOSER(recent), rfilter);
+    gtk_recent_chooser_set_local_only(GTK_RECENT_CHOOSER(recent), FALSE);
+    g_signal_connect(recent, "selection-changed",
+                     G_CALLBACK(recent_selection_changed_dialog_cb), entry);
+    g_signal_connect(recent, "item-activated",
+                     G_CALLBACK(recent_item_activated_dialog_cb), dialog);
+
+    /* show and wait for response */
+    gtk_widget_show_all(dialog);
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+        *uri = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
+        retval = 0;
+    } else {
+        *uri = NULL;
+        retval = -1;
+    }
+    gtk_widget_destroy(dialog);
+
+    return retval;
+}
+
+static void
+recent_add(gchar *uri)
+{
+    GtkRecentManager *recent;
+    GtkRecentData meta = {
+        .mime_type    = (char*)"application/x-spice",
+        .app_name     = (char*)"remote-viewer",
+        .app_exec     = (char*)"remote-viewer %u",
+    };
+
+    if (uri == NULL)
+        return;
+
+    g_return_if_fail(g_str_has_prefix(uri, "spice://") || g_str_has_prefix(uri, "vnc://"));
+
+    recent = gtk_recent_manager_get_default();
+    meta.display_name = uri;
+    if (!gtk_recent_manager_add_full(recent, uri, &meta))
+        g_warning("Recent item couldn't be added");
+}
+
+static void connected(VirtViewerSession *session,
+                      VirtViewerApp *self G_GNUC_UNUSED)
+{
+    gchar *uri = virt_viewer_session_get_uri(session);
+
+    recent_add(uri);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -73,6 +189,7 @@ main(int argc, char **argv)
     int ret = 1;
     int zoom = 100;
     gchar **args = NULL;
+    gchar *uri = NULL;
     gboolean verbose = FALSE;
     gboolean debug = FALSE;
     gboolean direct = FALSE;
@@ -137,8 +254,10 @@ main(int argc, char **argv)
         && !controller
 #endif
         ) {
-        g_printerr(_("\nUsage: %s [OPTIONS] URI\n\n%s\n\n"), argv[0], help_msg);
-        goto cleanup;
+        if (connect_dialog(&uri) == -1)
+            goto cleanup;
+    } else {
+        uri = g_strdup(args[0]);
     }
 
     if (zoom < 10 || zoom > 200) {
@@ -156,8 +275,8 @@ main(int argc, char **argv)
         g_object_set(viewer, "guest-name", "defined by Spice controller", NULL);
     } else {
 #endif
-        viewer = remote_viewer_new(args[0], verbose);
-        g_object_set(viewer, "guest-name", args[0], NULL);
+        viewer = remote_viewer_new(uri, verbose);
+        g_object_set(viewer, "guest-name", uri, NULL);
 #if HAVE_SPICE_GTK
     }
 #endif
@@ -175,11 +294,15 @@ main(int argc, char **argv)
     if (!virt_viewer_app_start(app))
         goto cleanup;
 
+    g_signal_connect(virt_viewer_app_get_session(app), "session-connected",
+                     G_CALLBACK(connected), app);
+
     gtk_main();
 
     ret = 0;
 
  cleanup:
+    g_free(uri);
     if (viewer)
         g_object_unref(viewer);
     g_strfreev(args);
diff --git a/src/virt-viewer-session.c b/src/virt-viewer-session.c
index f139c48..51a8a5a 100644
--- a/src/virt-viewer-session.c
+++ b/src/virt-viewer-session.c
@@ -37,6 +37,7 @@ struct _VirtViewerSessionPrivate
     GList *displays;
     VirtViewerApp *app;
     gboolean auto_usbredir;
+    gchar *uri;
 };
 
 G_DEFINE_ABSTRACT_TYPE(VirtViewerSession, virt_viewer_session, G_TYPE_OBJECT)
@@ -60,6 +61,8 @@ virt_viewer_session_finalize(GObject *obj)
     }
     g_list_free(session->priv->displays);
 
+    g_free(session->priv->uri);
+
     G_OBJECT_CLASS(virt_viewer_session_parent_class)->finalize(obj);
 }
 
@@ -344,6 +347,8 @@ gboolean virt_viewer_session_open_uri(VirtViewerSession *session, const gchar *u
     klass = VIRT_VIEWER_SESSION_GET_CLASS(session);
     g_return_val_if_fail(klass->open_uri != NULL, FALSE);
 
+    session->priv->uri = g_strdup(uri);
+
     return klass->open_uri(session, uri);
 }
 
@@ -436,6 +441,14 @@ VirtViewerApp* virt_viewer_session_get_app(VirtViewerSession *self)
     return self->priv->app;
 }
 
+gchar* virt_viewer_session_get_uri(VirtViewerSession *self)
+{
+    g_return_val_if_fail(VIRT_VIEWER_IS_SESSION(self), FALSE);
+
+    return g_strdup(self->priv->uri);
+}
+
+
 /*
  * Local variables:
  *  c-indent-level: 4
diff --git a/src/virt-viewer-session.h b/src/virt-viewer-session.h
index c53c8b5..44e4674 100644
--- a/src/virt-viewer-session.h
+++ b/src/virt-viewer-session.h
@@ -120,6 +120,7 @@ void virt_viewer_session_usb_device_selection(VirtViewerSession *self, GtkWindow
 void virt_viewer_session_smartcard_insert(VirtViewerSession *self);
 void virt_viewer_session_smartcard_remove(VirtViewerSession *self);
 VirtViewerApp* virt_viewer_session_get_app(VirtViewerSession *self);
+gchar* virt_viewer_session_get_uri(VirtViewerSession *self);
 
 G_END_DECLS
 
-- 
1.7.7.6




More information about the virt-tools-list mailing list