Codebase list virt-viewer / c3c3a1f
ovirt-foreign-menu: Support changing ISO from Data StorageDomain With the possibility of having ISO images in storage domains of DATA type, we need to store the id of the object as well as its name. This is not the case with ISO storage domains, which only hold the name of the image. This patch makes it possible to use deal with both types transparently for the user. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1835640 Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com> Eduardo Lima (Etrunko) 2 years ago
6 changed file(s) with 138 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
1414 #include <config.h>
1515
1616 #include "glib-compat.h"
17
18 #if !GLIB_CHECK_VERSION(2,60,0)
19 gboolean
20 g_strv_equal (const gchar * const *strv1,
21 const gchar * const *strv2)
22 {
23 g_return_val_if_fail (strv1 != NULL, FALSE);
24 g_return_val_if_fail (strv2 != NULL, FALSE);
25
26 if (strv1 == strv2)
27 return TRUE;
28
29 for (; *strv1 != NULL && *strv2 != NULL; strv1++, strv2++)
30 {
31 if (!g_str_equal (*strv1, *strv2))
32 return FALSE;
33 }
34
35 return (*strv1 == NULL && *strv2 == NULL);
36 }
37 #endif
2222 #pragma once
2323
2424 #include <glib.h>
25
26 #if !GLIB_CHECK_VERSION(2,60,0)
27 gboolean g_strv_equal (const gchar * const *strv1,
28 const gchar * const *strv2);
29 #endif
9090 /* The next 2 members are used when changing the ISO image shown in
9191 * a VM */
9292 /* Name of the ISO which is currently used by the VM OvirtCdrom */
93 char *current_iso_name;
93 GStrv current_iso_info;
9494 /* Name of the ISO we are trying to insert in the VM OvirtCdrom */
95 char *next_iso_name;
95 GStrv next_iso_info;
9696
9797 GList *iso_names;
9898 };
125125 return name;
126126 }
127127
128 static GStrv
129 iso_info_new(const gchar *name, const gchar *id)
130 {
131 GStrv info = g_new0(gchar *, 3);
132 info[0] = g_strdup(name);
133 info[1] = id != NULL ? g_strdup(id) : g_strdup(name);
134 return info;
135 }
136
137
138 GStrv
139 ovirt_foreign_menu_get_current_iso_info(OvirtForeignMenu *menu)
140 {
141 if (menu->cdrom == NULL)
142 return NULL;
143
144 return menu->current_iso_info;
145 }
146
147 static void
148 ovirt_foreign_menu_set_current_iso_info(OvirtForeignMenu *menu, const gchar *name, const gchar *id)
149 {
150 GStrv info = NULL;
151
152 g_debug("Setting current ISO to: name '%s', id '%s'", name, id);
153 if (menu->cdrom == NULL)
154 return;
155
156 if (name != NULL)
157 info = iso_info_new(name, id);
158
159 g_strfreev(menu->current_iso_info);
160 menu->current_iso_info = info;
161 }
128162
129163 GList*
130164 ovirt_foreign_menu_get_iso_names(OvirtForeignMenu *foreign_menu)
220254 self->iso_names = NULL;
221255 }
222256
223 g_clear_pointer(&self->current_iso_name, g_free);
224 g_clear_pointer(&self->next_iso_name, g_free);
257 g_clear_pointer(&self->current_iso_info, g_strfreev);
258 g_clear_pointer(&self->next_iso_info, g_strfreev);
225259
226260 G_OBJECT_CLASS(ovirt_foreign_menu_parent_class)->dispose(obj);
227261 }
408442 updated = ovirt_cdrom_update_finish(OVIRT_CDROM(source_object),
409443 result, &error);
410444 if (updated) {
411 g_debug("Finished updating cdrom content: %s", foreign_menu->next_iso_name);
412 g_free(foreign_menu->current_iso_name);
413 foreign_menu->current_iso_name = foreign_menu->next_iso_name;
414 foreign_menu->next_iso_name = NULL;
445 g_debug("Finished updating cdrom content");
446 g_strfreev(foreign_menu->current_iso_info);
447 foreign_menu->current_iso_info = foreign_menu->next_iso_info;
448 foreign_menu->next_iso_info = NULL;
415449 g_task_return_boolean(task, TRUE);
416450 goto end;
417451 }
418452
419453 /* Reset old state back as we were not successful in switching to
420454 * the new ISO */
421 g_debug("setting OvirtCdrom:file back to '%s'",
422 foreign_menu->current_iso_name);
455 g_debug("setting OvirtCdrom:file back");
423456 g_object_set(foreign_menu->cdrom, "file",
424 foreign_menu->current_iso_name, NULL);
425 g_clear_pointer(&foreign_menu->next_iso_name, g_free);
457 foreign_menu->current_iso_info ? foreign_menu->current_iso_info[1] : NULL,
458 NULL);
459 g_clear_pointer(&foreign_menu->next_iso_info, g_strfreev);
426460
427461 if (error != NULL) {
428462 g_warning("failed to update cdrom resource: %s", error->message);
440474
441475 void ovirt_foreign_menu_set_current_iso_name_async(OvirtForeignMenu *foreign_menu,
442476 const char *name,
477 const char *id,
443478 GCancellable *cancellable,
444479 GAsyncReadyCallback callback,
445480 gpointer user_data)
447482 GTask *task;
448483
449484 g_return_if_fail(foreign_menu->cdrom != NULL);
450 g_return_if_fail(foreign_menu->next_iso_name == NULL);
485 g_return_if_fail(foreign_menu->next_iso_info == NULL);
451486
452487 if (name) {
453488 g_debug("Updating VM cdrom image to '%s'", name);
454 foreign_menu->next_iso_name = g_strdup(name);
489 foreign_menu->next_iso_info = iso_info_new(name, id);
455490 } else {
456491 g_debug("Removing current cdrom image");
457 foreign_menu->next_iso_name = NULL;
492 foreign_menu->next_iso_info = NULL;
458493 }
459494
460495 g_object_set(foreign_menu->cdrom,
461 "file", name,
496 "file", id,
462497 NULL);
463498
464499 task = g_task_new(foreign_menu, cancellable, callback, user_data);
483518 GList *sorted_files = NULL;
484519 const GList *it;
485520 GList *it2;
521 gchar *current_iso_name = ovirt_foreign_menu_get_current_iso_name(menu);
486522
487523 for (it = files; it != NULL; it = it->next) {
488 char *name;
489 g_object_get(it->data, "name", &name, NULL);
524 char *name = NULL, *id = NULL;
525 g_object_get(it->data, "name", &name, "guid", &id, NULL);
490526
491527 #ifdef HAVE_OVIRT_STORAGE_DOMAIN_GET_DISKS
492528 if (OVIRT_IS_DISK(it->data)) {
494530 g_object_get(it->data, "content-type", &content_type, NULL);
495531 if (content_type != OVIRT_DISK_CONTENT_TYPE_ISO) {
496532 g_debug("Ignoring %s disk which content-type is not ISO", name);
497 g_free(name);
498 continue;
533 goto loop_end;
499534 }
500535 }
501536 #endif
506541 * to differentiate between ISOs and floppy images */
507542 if (!g_str_has_suffix(name, ".iso")) {
508543 g_debug("Ignoring %s which does not have a .iso extension", name);
509 g_free(name);
510 continue;
511 }
512 sorted_files = g_list_insert_sorted(sorted_files, name,
544 goto loop_end;
545 }
546
547 g_debug("Adding ISO to the list: name '%s', id '%s'", name, id);
548 sorted_files = g_list_insert_sorted(sorted_files, iso_info_new(name, id),
513549 (GCompareFunc)g_strcmp0);
514 }
550
551 /* Check if info matches with current cdrom file */
552 if (current_iso_name != NULL &&
553 (g_strcmp0(current_iso_name, name) == 0 ||
554 g_strcmp0(current_iso_name, id) == 0)) {
555 ovirt_foreign_menu_set_current_iso_info(menu, name, id);
556 }
557
558 loop_end:
559 g_free(name);
560 g_free(id);
561 }
562
563 g_free(current_iso_name);
515564
516565 for (it = sorted_files, it2 = menu->iso_names;
517566 (it != NULL) && (it2 != NULL);
523572
524573 if ((it == NULL) && (it2 == NULL)) {
525574 /* sorted_files and menu->files content was the same */
526 g_list_free_full(sorted_files, (GDestroyNotify)g_free);
575 g_list_free_full(sorted_files, (GDestroyNotify)g_strfreev);
527576 return;
528577 }
529578
530 g_list_free_full(menu->iso_names, (GDestroyNotify)g_free);
579 g_list_free_full(menu->iso_names, (GDestroyNotify)g_strfreev);
531580 menu->iso_names = sorted_files;
532581 }
533582
550599 }
551600
552601 /* Content of OvirtCdrom is now current */
553 g_clear_pointer(&menu->current_iso_name, g_free);
554 if (menu->cdrom != NULL) {
555 g_object_get(G_OBJECT(menu->cdrom),
556 "file", &menu->current_iso_name,
557 NULL);
558 }
559602 if (menu->cdrom != NULL) {
560603 ovirt_foreign_menu_next_async_step(menu, task, STATE_CDROM_FILE);
561604 } else {
5252
5353 void ovirt_foreign_menu_set_current_iso_name_async(OvirtForeignMenu *foreign_menu,
5454 const char *name,
55 const char *id,
5556 GCancellable *cancellable,
5657 GAsyncReadyCallback callback,
5758 gpointer user_data);
6364 GtkWidget *ovirt_foreign_menu_get_gtk_menu(OvirtForeignMenu *foreign_menu);
6465 gchar *ovirt_foreign_menu_get_current_iso_name(OvirtForeignMenu *menu);
6566 GList *ovirt_foreign_menu_get_iso_names(OvirtForeignMenu *menu);
66
67 GStrv ovirt_foreign_menu_get_current_iso_info(OvirtForeignMenu *menu);
2121
2222 #include <glib/gi18n.h>
2323
24 #include "glib-compat.h"
2425 #include "remote-viewer-iso-list-dialog.h"
2526 #include "virt-viewer-util.h"
2627 #include "ovirt-foreign-menu.h"
4748 ISO_IS_ACTIVE = 0,
4849 ISO_NAME,
4950 FONT_WEIGHT,
51 ISO_ID,
5052 };
5153
5254 enum RemoteViewerISOListDialogProperties {
113115 }
114116
115117 static void
116 remote_viewer_iso_list_dialog_foreach(char *name, RemoteViewerISOListDialog *self)
117 {
118 gchar *current_iso = ovirt_foreign_menu_get_current_iso_name(self->foreign_menu);
119 gboolean active = (g_strcmp0(current_iso, name) == 0);
118 remote_viewer_iso_list_dialog_foreach(GStrv info, RemoteViewerISOListDialog *self)
119 {
120 GStrv current_iso = ovirt_foreign_menu_get_current_iso_info(self->foreign_menu);
121 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
122 gboolean active = (g_strv_equal((const gchar * const *) current_iso,
123 (const gchar * const *) info) == TRUE);
124 G_GNUC_END_IGNORE_DEPRECATIONS
120125 gint weight = active ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL;
121126 GtkTreeIter iter;
122127
123128 gtk_list_store_append(self->list_store, &iter);
124129 gtk_list_store_set(self->list_store, &iter,
125130 ISO_IS_ACTIVE, active,
126 ISO_NAME, name,
127 FONT_WEIGHT, weight, -1);
131 ISO_NAME, info[0],
132 FONT_WEIGHT, weight,
133 ISO_ID, info[1],
134 -1);
128135
129136 if (active) {
130137 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(self->list_store), &iter);
132139 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(self->tree_view), path, NULL, TRUE, 0.5, 0.5);
133140 gtk_tree_path_free(path);
134141 }
135
136 g_free(current_iso);
137142 }
138143
139144 static void
214219 GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);
215220 GtkTreeIter iter;
216221 gboolean active;
217 gchar *name;
222 gchar *name, *id;
218223
219224 gtk_tree_view_set_cursor(GTK_TREE_VIEW(self->tree_view), tree_path, NULL, FALSE);
220225 gtk_tree_model_get_iter(model, &iter, tree_path);
221226 gtk_tree_model_get(model, &iter,
222227 ISO_IS_ACTIVE, &active,
223 ISO_NAME, &name, -1);
228 ISO_NAME, &name,
229 ISO_ID, &id,
230 -1);
224231
225232 gtk_dialog_set_response_sensitive(GTK_DIALOG(self), GTK_RESPONSE_NONE, FALSE);
226233 gtk_widget_set_sensitive(self->tree_view, FALSE);
227234
228235 self->cancellable = g_cancellable_new();
229 ovirt_foreign_menu_set_current_iso_name_async(self->foreign_menu, active ? NULL : name,
236 ovirt_foreign_menu_set_current_iso_name_async(self->foreign_menu,
237 active ? NULL : name,
238 active ? NULL : id,
230239 self->cancellable,
231240 (GAsyncReadyCallback)ovirt_foreign_menu_iso_name_changed,
232241 self);
233242 gtk_tree_path_free(tree_path);
234243 g_free(name);
244 g_free(id);
235245 }
236246
237247 G_MODULE_EXPORT void
300310 RemoteViewerISOListDialog *self)
301311 {
302312 GtkTreeModel *model = GTK_TREE_MODEL(self->list_store);
303 gchar *current_iso;
313 GStrv current_iso;
304314 GtkTreeIter iter;
305 gchar *name;
315 gchar *name, *id;
306316 gboolean active, match = FALSE;
307317 GError *error = NULL;
308318
323333 if (!gtk_tree_model_get_iter_first(model, &iter))
324334 goto end;
325335
326 current_iso = ovirt_foreign_menu_get_current_iso_name(foreign_menu);
336 current_iso = ovirt_foreign_menu_get_current_iso_info(foreign_menu);
327337
328338 do {
329339 gtk_tree_model_get(model, &iter,
330340 ISO_IS_ACTIVE, &active,
331 ISO_NAME, &name, -1);
332 match = (g_strcmp0(current_iso, name) == 0);
341 ISO_NAME, &name,
342 ISO_ID, &id,
343 -1);
344
345 if (current_iso)
346 match = (g_strcmp0(current_iso[0], name) == 0 &&
347 g_strcmp0(current_iso[1], id) == 0);
333348
334349 /* iso is not active anymore */
335350 if (active && !match) {
343358 }
344359
345360 g_free(name);
361 g_free(id);
346362 } while (gtk_tree_model_iter_next(model, &iter));
347363
348364 gtk_dialog_set_response_sensitive(GTK_DIALOG(self), GTK_RESPONSE_NONE, TRUE);
349365 gtk_widget_set_sensitive(self->tree_view, TRUE);
350 g_free(current_iso);
351366
352367 end:
353368 g_clear_error(&error);
99 <column type="gchararray"/>
1010 <!-- column-name weight -->
1111 <column type="gint"/>
12 <!-- column-name id -->
13 <column type="gchararray"/>
1214 </columns>
1315 </object>
1416 <object class="GtkStack" id="stack">