From 0522f86a3e8420b1a2e32dbdf798d4667c91f036 Mon Sep 17 00:00:00 2001 From: "Eduardo Lima (Etrunko)" Date: Wed, 1 Jul 2020 11:16:09 -0300 Subject: [PATCH virt-viewer] ovirt-foreign-menu: Support changing ISO from Data StorageDomain Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1835640 Signed-off-by: Eduardo Lima (Etrunko) --- src/glib-compat.c | 21 +++++ src/glib-compat.h | 5 + src/ovirt-foreign-menu.c | 104 +++++++++++++++------ src/ovirt-foreign-menu.h | 3 + src/remote-viewer-iso-list-dialog.c | 46 +++++---- src/resources/ui/remote-viewer-iso-list.ui | 2 + 6 files changed, 135 insertions(+), 46 deletions(-) diff --git a/src/glib-compat.c b/src/glib-compat.c index 62ac87e..17122f6 100644 --- a/src/glib-compat.c +++ b/src/glib-compat.c @@ -33,3 +33,24 @@ g_strv_contains (const gchar * const *strv, return FALSE; } #endif + +#if !GLIB_CHECK_VERSION(2,60,0) +gboolean +g_strv_equal (const gchar * const *strv1, + const gchar * const *strv2) +{ + g_return_val_if_fail (strv1 != NULL, FALSE); + g_return_val_if_fail (strv2 != NULL, FALSE); + + if (strv1 == strv2) + return TRUE; + + for (; *strv1 != NULL && *strv2 != NULL; strv1++, strv2++) + { + if (!g_str_equal (*strv1, *strv2)) + return FALSE; + } + + return (*strv1 == NULL && *strv2 == NULL); +} +#endif diff --git a/src/glib-compat.h b/src/glib-compat.h index f1b43ae..a89ae04 100644 --- a/src/glib-compat.h +++ b/src/glib-compat.h @@ -34,6 +34,11 @@ gboolean g_strv_contains (const gchar * const *strv, const gchar *str); #endif +#if !GLIB_CHECK_VERSION(2,60,0) +gboolean g_strv_equal (const gchar * const *strv1, + const gchar * const *strv2); +#endif + G_END_DECLS #endif // GLIB_COMPAT_H diff --git a/src/ovirt-foreign-menu.c b/src/ovirt-foreign-menu.c index 8d02a79..a6745d3 100644 --- a/src/ovirt-foreign-menu.c +++ b/src/ovirt-foreign-menu.c @@ -77,9 +77,9 @@ struct _OvirtForeignMenuPrivate { /* The next 2 members are used when changing the ISO image shown in * a VM */ /* Name of the ISO which is currently used by the VM OvirtCdrom */ - char *current_iso_name; + GStrv current_iso_info; /* Name of the ISO we are trying to insert in the VM OvirtCdrom */ - char *next_iso_name; + GStrv next_iso_info; GList *iso_names; }; @@ -112,6 +112,40 @@ ovirt_foreign_menu_get_current_iso_name(OvirtForeignMenu *foreign_menu) return name; } +static GStrv +iso_info_new(const gchar *name, const gchar *id) +{ + GStrv info = g_new0(gchar *, 3); + info[0] = g_strdup(name); + info[1] = id != NULL ? g_strdup(id) : g_strdup(name); + return info; +} + + +GStrv +ovirt_foreign_menu_get_current_iso_info(OvirtForeignMenu *menu) +{ + if (menu->priv->cdrom == NULL) + return NULL; + + return menu->priv->current_iso_info; +} + +static void +ovirt_foreign_menu_set_current_iso_info(OvirtForeignMenu *menu, const gchar *name, const gchar *id) +{ + GStrv info = NULL; + + g_debug("Setting current ISO to: name '%s', id '%s'", name, id); + if (menu->priv->cdrom == NULL) + return; + + if (name != NULL) + info = iso_info_new(name, id); + + g_strfreev(menu->priv->current_iso_info); + menu->priv->current_iso_info = info; +} GList* ovirt_foreign_menu_get_iso_names(OvirtForeignMenu *foreign_menu) @@ -211,8 +245,8 @@ ovirt_foreign_menu_dispose(GObject *obj) self->priv->iso_names = NULL; } - g_clear_pointer(&self->priv->current_iso_name, g_free); - g_clear_pointer(&self->priv->next_iso_name, g_free); + g_clear_pointer(&self->priv->current_iso_info, g_strfreev); + g_clear_pointer(&self->priv->next_iso_info, g_strfreev); G_OBJECT_CLASS(ovirt_foreign_menu_parent_class)->dispose(obj); } @@ -402,21 +436,21 @@ static void iso_name_set_cb(GObject *source_object, updated = ovirt_cdrom_update_finish(OVIRT_CDROM(source_object), result, &error); if (updated) { - g_debug("Finished updating cdrom content: %s", foreign_menu->priv->next_iso_name); - g_free(foreign_menu->priv->current_iso_name); - foreign_menu->priv->current_iso_name = foreign_menu->priv->next_iso_name; - foreign_menu->priv->next_iso_name = NULL; + g_debug("Finished updating cdrom content"); + g_strfreev(foreign_menu->priv->current_iso_info); + foreign_menu->priv->current_iso_info = foreign_menu->priv->next_iso_info; + foreign_menu->priv->next_iso_info = NULL; g_task_return_boolean(task, TRUE); goto end; } /* Reset old state back as we were not successful in switching to * the new ISO */ - g_debug("setting OvirtCdrom:file back to '%s'", - foreign_menu->priv->current_iso_name); + g_debug("setting OvirtCdrom:file back"); g_object_set(foreign_menu->priv->cdrom, "file", - foreign_menu->priv->current_iso_name, NULL); - g_clear_pointer(&foreign_menu->priv->next_iso_name, g_free); + foreign_menu->priv->current_iso_info ? foreign_menu->priv->current_iso_info[1] : NULL, + NULL); + g_clear_pointer(&foreign_menu->priv->next_iso_info, g_strfreev); if (error != NULL) { g_warning("failed to update cdrom resource: %s", error->message); @@ -434,6 +468,7 @@ end: void ovirt_foreign_menu_set_current_iso_name_async(OvirtForeignMenu *foreign_menu, const char *name, + const char *id, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) @@ -441,18 +476,18 @@ void ovirt_foreign_menu_set_current_iso_name_async(OvirtForeignMenu *foreign_men GTask *task; g_return_if_fail(foreign_menu->priv->cdrom != NULL); - g_return_if_fail(foreign_menu->priv->next_iso_name == NULL); + g_return_if_fail(foreign_menu->priv->next_iso_info == NULL); if (name) { g_debug("Updating VM cdrom image to '%s'", name); - foreign_menu->priv->next_iso_name = g_strdup(name); + foreign_menu->priv->next_iso_info = iso_info_new(name, id); } else { g_debug("Removing current cdrom image"); - foreign_menu->priv->next_iso_name = NULL; + foreign_menu->priv->next_iso_info = NULL; } g_object_set(foreign_menu->priv->cdrom, - "file", name, + "file", id, NULL); task = g_task_new(foreign_menu, cancellable, callback, user_data); @@ -477,10 +512,11 @@ static void ovirt_foreign_menu_set_files(OvirtForeignMenu *menu, GList *sorted_files = NULL; const GList *it; GList *it2; + gchar *current_iso_name = ovirt_foreign_menu_get_current_iso_name(menu); for (it = files; it != NULL; it = it->next) { - char *name; - g_object_get(it->data, "name", &name, NULL); + char *name = NULL, *id = NULL; + g_object_get(it->data, "name", &name, "guid", &id, NULL); #ifdef HAVE_OVIRT_STORAGE_DOMAIN_GET_DISKS if (OVIRT_IS_DISK(it->data)) { @@ -488,7 +524,7 @@ static void ovirt_foreign_menu_set_files(OvirtForeignMenu *menu, g_object_get(it->data, "content-type", &content_type, NULL); if (content_type != OVIRT_DISK_CONTENT_TYPE_ISO) { g_debug("Ignoring %s disk which content-type is not ISO", name); - continue; + goto loop_end; } } #endif @@ -499,13 +535,27 @@ static void ovirt_foreign_menu_set_files(OvirtForeignMenu *menu, * to differentiate between ISOs and floppy images */ if (!g_str_has_suffix(name, ".iso")) { g_debug("Ignoring %s which does not have a .iso extension", name); - g_free(name); - continue; + goto loop_end; } - sorted_files = g_list_insert_sorted(sorted_files, name, + + g_debug("Adding ISO to the list: name '%s', id '%s'", name, id); + sorted_files = g_list_insert_sorted(sorted_files, iso_info_new(name, id), (GCompareFunc)g_strcmp0); + + /* Check if info matches with current cdrom file */ + if (current_iso_name != NULL && + (g_strcmp0(current_iso_name, name) == 0 || + g_strcmp0(current_iso_name, id) == 0)) { + ovirt_foreign_menu_set_current_iso_info(menu, name, id); + } + +loop_end: + g_free(name); + g_free(id); } + g_free(current_iso_name); + for (it = sorted_files, it2 = menu->priv->iso_names; (it != NULL) && (it2 != NULL); it = it->next, it2 = it2->next) { @@ -516,11 +566,11 @@ static void ovirt_foreign_menu_set_files(OvirtForeignMenu *menu, if ((it == NULL) && (it2 == NULL)) { /* sorted_files and menu->priv->files content was the same */ - g_list_free_full(sorted_files, (GDestroyNotify)g_free); + g_list_free_full(sorted_files, (GDestroyNotify)g_strfreev); return; } - g_list_free_full(menu->priv->iso_names, (GDestroyNotify)g_free); + g_list_free_full(menu->priv->iso_names, (GDestroyNotify)g_strfreev); menu->priv->iso_names = sorted_files; } @@ -543,12 +593,6 @@ static void cdrom_file_refreshed_cb(GObject *source_object, } /* Content of OvirtCdrom is now current */ - g_clear_pointer(&menu->priv->current_iso_name, g_free); - if (menu->priv->cdrom != NULL) { - g_object_get(G_OBJECT(menu->priv->cdrom), - "file", &menu->priv->current_iso_name, - NULL); - } if (menu->priv->cdrom != NULL) { ovirt_foreign_menu_next_async_step(menu, task, STATE_CDROM_FILE); } else { diff --git a/src/ovirt-foreign-menu.h b/src/ovirt-foreign-menu.h index 340201f..6d2da77 100644 --- a/src/ovirt-foreign-menu.h +++ b/src/ovirt-foreign-menu.h @@ -79,6 +79,7 @@ GList *ovirt_foreign_menu_fetch_iso_names_finish(OvirtForeignMenu *foreign_menu, void ovirt_foreign_menu_set_current_iso_name_async(OvirtForeignMenu *foreign_menu, const char *name, + const char *id, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); @@ -91,6 +92,8 @@ GtkWidget *ovirt_foreign_menu_get_gtk_menu(OvirtForeignMenu *foreign_menu); gchar *ovirt_foreign_menu_get_current_iso_name(OvirtForeignMenu *menu); GList *ovirt_foreign_menu_get_iso_names(OvirtForeignMenu *menu); +GStrv ovirt_foreign_menu_get_current_iso_info(OvirtForeignMenu *menu); + G_END_DECLS #endif /* _OVIRT_FOREIGN_MENU_H */ diff --git a/src/remote-viewer-iso-list-dialog.c b/src/remote-viewer-iso-list-dialog.c index c6fbe50..fa10711 100644 --- a/src/remote-viewer-iso-list-dialog.c +++ b/src/remote-viewer-iso-list-dialog.c @@ -53,6 +53,7 @@ enum RemoteViewerISOListDialogModel ISO_IS_ACTIVE = 0, ISO_NAME, FONT_WEIGHT, + ISO_ID, }; enum RemoteViewerISOListDialogProperties { @@ -119,18 +120,23 @@ remote_viewer_iso_list_dialog_show_files(RemoteViewerISOListDialog *self) } static void -remote_viewer_iso_list_dialog_foreach(char *name, RemoteViewerISOListDialog *self) +remote_viewer_iso_list_dialog_foreach(GStrv info, RemoteViewerISOListDialog *self) { - gchar *current_iso = ovirt_foreign_menu_get_current_iso_name(self->foreign_menu); - gboolean active = (g_strcmp0(current_iso, name) == 0); + GStrv current_iso = ovirt_foreign_menu_get_current_iso_info(self->foreign_menu); +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + gboolean active = (g_strv_equal((const gchar * const *) current_iso, + (const gchar * const *) info) == TRUE); +G_GNUC_END_IGNORE_DEPRECATIONS gint weight = active ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL; GtkTreeIter iter; gtk_list_store_append(self->list_store, &iter); gtk_list_store_set(self->list_store, &iter, ISO_IS_ACTIVE, active, - ISO_NAME, name, - FONT_WEIGHT, weight, -1); + ISO_NAME, info[0], + FONT_WEIGHT, weight, + ISO_ID, info[1], + -1); if (active) { GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(self->list_store), &iter); @@ -138,8 +144,6 @@ remote_viewer_iso_list_dialog_foreach(char *name, RemoteViewerISOListDialog *sel gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(self->tree_view), path, NULL, TRUE, 0.5, 0.5); gtk_tree_path_free(path); } - - g_free(current_iso); } static void @@ -219,24 +223,29 @@ remote_viewer_iso_list_dialog_toggled(GtkCellRendererToggle *cell_renderer G_GNU GtkTreePath *tree_path = gtk_tree_path_new_from_string(path); GtkTreeIter iter; gboolean active; - gchar *name; + gchar *name, *id; gtk_tree_view_set_cursor(GTK_TREE_VIEW(self->tree_view), tree_path, NULL, FALSE); gtk_tree_model_get_iter(model, &iter, tree_path); gtk_tree_model_get(model, &iter, ISO_IS_ACTIVE, &active, - ISO_NAME, &name, -1); + ISO_NAME, &name, + ISO_ID, &id, + -1); gtk_dialog_set_response_sensitive(GTK_DIALOG(self), GTK_RESPONSE_NONE, FALSE); gtk_widget_set_sensitive(self->tree_view, FALSE); self->cancellable = g_cancellable_new(); - ovirt_foreign_menu_set_current_iso_name_async(self->foreign_menu, active ? NULL : name, + ovirt_foreign_menu_set_current_iso_name_async(self->foreign_menu, + active ? NULL : name, + active ? NULL : id, self->cancellable, (GAsyncReadyCallback)ovirt_foreign_menu_iso_name_changed, self); gtk_tree_path_free(tree_path); g_free(name); + g_free(id); } G_MODULE_EXPORT void @@ -305,9 +314,9 @@ ovirt_foreign_menu_iso_name_changed(OvirtForeignMenu *foreign_menu, RemoteViewerISOListDialog *self) { GtkTreeModel *model = GTK_TREE_MODEL(self->list_store); - gchar *current_iso; + GStrv current_iso; GtkTreeIter iter; - gchar *name; + gchar *name, *id; gboolean active, match = FALSE; GError *error = NULL; @@ -328,13 +337,18 @@ ovirt_foreign_menu_iso_name_changed(OvirtForeignMenu *foreign_menu, if (!gtk_tree_model_get_iter_first(model, &iter)) goto end; - current_iso = ovirt_foreign_menu_get_current_iso_name(foreign_menu); + current_iso = ovirt_foreign_menu_get_current_iso_info(foreign_menu); do { gtk_tree_model_get(model, &iter, ISO_IS_ACTIVE, &active, - ISO_NAME, &name, -1); - match = (g_strcmp0(current_iso, name) == 0); + ISO_NAME, &name, + ISO_ID, &id, + -1); + + if (current_iso) + match = (g_strcmp0(current_iso[0], name) == 0 && + g_strcmp0(current_iso[1], id) == 0); /* iso is not active anymore */ if (active && !match) { @@ -348,11 +362,11 @@ ovirt_foreign_menu_iso_name_changed(OvirtForeignMenu *foreign_menu, } g_free(name); + g_free(id); } while (gtk_tree_model_iter_next(model, &iter)); gtk_dialog_set_response_sensitive(GTK_DIALOG(self), GTK_RESPONSE_NONE, TRUE); gtk_widget_set_sensitive(self->tree_view, TRUE); - g_free(current_iso); end: g_clear_error(&error); diff --git a/src/resources/ui/remote-viewer-iso-list.ui b/src/resources/ui/remote-viewer-iso-list.ui index ab1bdc4..96fabef 100644 --- a/src/resources/ui/remote-viewer-iso-list.ui +++ b/src/resources/ui/remote-viewer-iso-list.ui @@ -10,6 +10,8 @@ + + -- 2.31.1