[virt-tools-list] [PATCH remote-viewer] Connecting to ovirt without specifying VM name
Christophe Fergeau
cfergeau at redhat.com
Wed Sep 17 11:48:05 UTC 2014
Hey,
This dialog looks very nice! :)
On Tue, Sep 16, 2014 at 01:58:47PM +0200, Pavel Grunt wrote:
> When a user tries to connect to ovirt without specifying VM name (remote-viewer ovirt://ovirt.example.com/) a list of available virtual machines is shown, and the user may pick a machine he wants to connect to.
>
> ---
> src/remote-viewer.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 129 insertions(+), 1 deletion(-)
>
> diff --git a/src/remote-viewer.c b/src/remote-viewer.c
> index 5f5fa3d..4b21696 100644
> --- a/src/remote-viewer.c
> +++ b/src/remote-viewer.c
> @@ -74,6 +74,10 @@ enum {
> PROP_OPEN_RECENT_DIALOG
> };
>
> +#ifdef HAVE_OVIRT
> +static gint choose_wm_dialog(char **vm_name, OvirtCollection *vms);
It seems you don't really use the return value of choose_wm_dialog so
you could just make it
static char *choose_vm_dialog(OvirtCollection *vms); (nb: vm VS wm)
> +#endif
> +
> static gboolean remote_viewer_start(VirtViewerApp *self);
> #ifdef HAVE_SPICE_GTK
> static gboolean remote_viewer_activate(VirtViewerApp *self, GError **error);
> @@ -840,7 +844,11 @@ create_ovirt_session(VirtViewerApp *app, const char *uri)
> goto error;
> }
> vm = OVIRT_VM(ovirt_collection_lookup_resource(vms, vm_name));
> - g_return_val_if_fail(vm != NULL, FALSE);
> + if (vm == NULL) {
> + if (choose_wm_dialog(&vm_name, vms) == 0 && vm_name != NULL)
Showing the dialog here will make sure it pops up on an invalid VM name,
but it would be nice to also get the dialog when starting remote-viewer
with an empty VM name:
remote-viewer --ovirt-ca-file=ca.crt ovirt://ovirt.example.com
> + vm = OVIRT_VM(ovirt_collection_lookup_resource(vms, vm_name));
> + g_return_val_if_fail(vm != NULL, FALSE);
> + }
> g_object_get(G_OBJECT(vm), "state", &state, NULL);
> if (state != OVIRT_VM_STATE_UP) {
> g_debug("oVirt VM %s is not running", vm_name);
> @@ -980,6 +988,20 @@ recent_item_activated_dialog_cb(GtkRecentChooser *chooser G_GNUC_UNUSED, gpointe
> gtk_dialog_response(GTK_DIALOG (data), GTK_RESPONSE_ACCEPT);
> }
>
> +static void
> +vm_list_selection_changed_dialog_cb(GtkTreeSelection *selection, gpointer data)
> +{
> + GtkTreeIter iter;
> + GtkTreeModel *model;
> + const gchar *vm_name;
> + GtkWidget *entry = data;
> +
> + if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
> + gtk_tree_model_get(model, &iter, 0, &vm_name, -1);
> + gtk_entry_set_text(GTK_ENTRY(entry), vm_name);
> + }
> +}
> +
> static void make_label_light(GtkLabel* label)
> {
> PangoAttrList* attributes = pango_attr_list_new();
> @@ -1092,6 +1114,112 @@ connect_dialog(gchar **uri)
> return retval;
> }
>
> +
> +#ifdef HAVE_OVIRT
> +static gint choose_wm_dialog(char **vm_name, OvirtCollection *vms_collection)
> +{
> + GtkWidget *dialog, *area, *box, *label, *entry, *vm_list;
> +#if !GTK_CHECK_VERSION(3, 0, 0)
> + GtkWidget *alignment;
> +#endif
> + GtkTreeModel *model;
> + GtkListStore *store;
> + GtkTreeSelection *select;
> + GtkTreeIter iter;
> + GHashTable *vms;
> + GHashTableIter vms_iter;
> + OvirtVm *vm;
> + char *tmp_vm_name;
> + OvirtVmState state;
> + gint retval;
> +
> + vms = ovirt_collection_get_resources(vms_collection);
> + g_return_val_if_fail(g_hash_table_size(vms) > 0, -1);
> +
> + dialog = gtk_dialog_new_with_buttons(_("Virtual machine 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);
> + gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
> + area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
> + box = gtk_vbox_new(FALSE, 6);
> + gtk_container_set_border_width(GTK_CONTAINER(box), 5);
> + gtk_box_pack_start(GTK_BOX(area), box, TRUE, TRUE, 0);
> +
> + label = gtk_label_new_with_mnemonic(_("_Virtual machine name"));
> + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
> + gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0);
> + entry = GTK_WIDGET(gtk_entry_new());
> + gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
> + g_object_set(entry, "width-request", 200, NULL);
> + g_signal_connect(entry, "changed", G_CALLBACK(entry_changed_cb), entry);
> + g_signal_connect(entry, "icon-release", G_CALLBACK(entry_icon_release_cb), entry);
> + gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
> + gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
> + make_label_bold(GTK_LABEL(label));
> +
> + label = gtk_label_new_with_mnemonic(_("_Available virtual machines"));
> + make_label_bold(GTK_LABEL(label));
> + gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0);
> + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
This is done by hand as the connection dialog does, but it would be
be easier to modify if this was in a UI file (similar to what is done
for the guest details for example).
> +
> + store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
> + g_hash_table_iter_init(&vms_iter, vms);
> + while (g_hash_table_iter_next(&vms_iter, (gpointer *)&tmp_vm_name, NULL)) {
> + vm = OVIRT_VM(ovirt_collection_lookup_resource(vms_collection, tmp_vm_name));
> + if (vm != NULL) {
> + g_object_get(G_OBJECT(vm), "state", &state, NULL);
> + }
> + gtk_list_store_append(store, &iter);
> + gtk_list_store_set(store, &iter,
> + 0, tmp_vm_name,
> + 1, (vm != NULL && state == OVIRT_VM_STATE_UP) ? "running" : "not running",
> + -1);
You can mark these "running"/"not running" strings for translation with
_() around them: _("running"); I don't think we handle non-running ovirt
VMs really well at the moment, so it's probably better to hide non
running VMs for now.
'vm' must be unref'ed (g_object_unref) after use as
ovirt_collection_lookup_resource() is documented as "transfer full"
which means the caller of that function has ownership of the returned
value.
You can probably skip the call to ovirt_collection_lookup_resource() if
you do:
while (g_hash_table_iter_next(&vms_iter, (gpointer *)&tmp_vm_name, &vm)) {
}
> + }
> + model = GTK_TREE_MODEL(store);
You can also use GTK_TREE_MODEL(store), in the 2 places where it's
needed instead of introducing an additional local variable.
> +
> + vm_list = GTK_WIDGET(gtk_tree_view_new());
I think this can be gtk_tree_view_new_with_model() which saves the call
to _set_model() later on.
> + gtk_label_set_mnemonic_widget(GTK_LABEL(label), vm_list);
> + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(vm_list), -1, "Name",
> + gtk_cell_renderer_text_new(), "text", 0,
> + NULL);
> + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(vm_list), -1, "State",
> + gtk_cell_renderer_text_new(), "text", 1,
> + NULL);
> + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(vm_list), TRUE);
> + gtk_tree_view_set_model(GTK_TREE_VIEW(vm_list), model);
> + gtk_box_pack_start(GTK_BOX(box), vm_list, TRUE, TRUE, 0);
> + gtk_label_set_mnemonic_widget(GTK_LABEL(label), vm_list);
> +
> + select = gtk_tree_view_get_selection(GTK_TREE_VIEW(vm_list));
> + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
> + g_signal_connect(select, "changed",
> + G_CALLBACK(vm_list_selection_changed_dialog_cb), entry);
> + if (gtk_tree_model_get_iter_first(model, &iter)) {
> + gtk_tree_selection_select_iter(select, &iter);
> + }
> + g_object_unref(model);
> + /* show and wait for response */
> + gtk_widget_show_all(dialog);
> + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
> + *vm_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
> + g_strstrip(*vm_name);
Is there any particular reason for calling g_strstrip? Did you get some
extra spaces in your testing?
Christophe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/virt-tools-list/attachments/20140917/7899f42f/attachment.sig>
More information about the virt-tools-list
mailing list