Currently "all_disks" and "all_removables" are used for both populating
the conversion dialog and collecting the configuration updates from the
conversion dialog.

Going forward, we want to eliminate "all_disks" and "all_removables" as
global variables. As one step in that direction, restrict the consumption
of "all_disks" and "all_removables" to when we populate the conversion
dialog. For this, introduce a new column to the list stores that back the
"fixed disks" and "removable media drives" tree views, and copy
"all_disks" and "all_removables" into the new columns, respectively. This
new column is never displayed; it's only used as a lookaside buffer when
we collect the disks / removables selections into the config structure.

Note that both gtk_list_store_set() and gtk_tree_model_get() create deep
copies of strings.

No observable changes.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2124538
Signed-off-by: Laszlo Ersek <ler...@redhat.com>
---
 gui.c | 90 +++++++++++++-------
 1 file changed, 60 insertions(+), 30 deletions(-)

diff --git a/gui.c b/gui.c
index c40ed31a8bbc..82c297b0be4b 100644
--- a/gui.c
+++ b/gui.c
@@ -702,12 +702,14 @@ static uint64_t get_memory_from_conv_dlg (void);
 
 enum {
   DISKS_COL_CONVERT = 0,
+  DISKS_COL_HW_NAME,
   DISKS_COL_DEVICE,
   NUM_DISKS_COLS,
 };
 
 enum {
   REMOVABLE_COL_CONVERT = 0,
+  REMOVABLE_COL_HW_NAME,
   REMOVABLE_COL_DEVICE,
   NUM_REMOVABLE_COLS,
 };
@@ -1103,7 +1105,8 @@ populate_disks (GtkTreeView *disks_list_p)
   size_t i;
 
   disks_store = gtk_list_store_new (NUM_DISKS_COLS,
-                                    G_TYPE_BOOLEAN, G_TYPE_STRING);
+                                    G_TYPE_BOOLEAN, G_TYPE_STRING,
+                                    G_TYPE_STRING);
   if (all_disks != NULL) {
     for (i = 0; all_disks[i] != NULL; ++i) {
       uint64_t size;
@@ -1134,6 +1137,7 @@ populate_disks (GtkTreeView *disks_list_p)
       gtk_list_store_append (disks_store, &iter);
       gtk_list_store_set (disks_store, &iter,
                           DISKS_COL_CONVERT, TRUE,
+                          DISKS_COL_HW_NAME, all_disks[i],
                           DISKS_COL_DEVICE, device_descr,
                           -1);
     }
@@ -1174,7 +1178,8 @@ populate_removable (GtkTreeView *removable_list_p)
   size_t i;
 
   removable_store = gtk_list_store_new (NUM_REMOVABLE_COLS,
-                                        G_TYPE_BOOLEAN, G_TYPE_STRING);
+                                        G_TYPE_BOOLEAN, G_TYPE_STRING,
+                                        G_TYPE_STRING);
   if (all_removable != NULL) {
     for (i = 0; all_removable[i] != NULL; ++i) {
       CLEANUP_FREE char *device_descr = NULL;
@@ -1185,6 +1190,7 @@ populate_removable (GtkTreeView *removable_list_p)
       gtk_list_store_append (removable_store, &iter);
       gtk_list_store_set (removable_store, &iter,
                           REMOVABLE_COL_CONVERT, TRUE,
+                          REMOVABLE_COL_HW_NAME, all_removable[i],
                           REMOVABLE_COL_DEVICE, device_descr,
                           -1);
     }
@@ -1397,52 +1403,76 @@ maybe_identify_click (GtkWidget *interfaces_list_p, 
GdkEventButton *event,
 }
 
 static void
-set_from_ui_generic (char **all, char ***ret, GtkTreeView *list)
+set_from_ui_generic (char ***ret, GtkTreeView *list)
 {
   GtkTreeModel *model;
-  GtkTreeIter iter;
-  gboolean b, v;
-  size_t i, j;
+  enum { COUNT, COPY, DONE } mode;
 
   guestfs_int_free_string_list (*ret);
-  if (all == NULL) {
-    *ret = NULL;
-    return;
-  }
+  *ret = NULL;
 
   model = gtk_tree_view_get_model (list);
 
-  *ret = malloc ((1 + guestfs_int_count_strings (all)) * sizeof (char *));
-  if (*ret == NULL)
-    error (EXIT_FAILURE, errno, "malloc");
-  i = j = 0;
-
-  b = gtk_tree_model_get_iter_first (model, &iter);
-  while (b) {
-    gtk_tree_model_get (model, &iter, 0 /* CONVERT */, &v, -1);
-    if (v) {
-      assert (all[i] != NULL);
-      (*ret)[j++] = strdup (all[i]);
+  for (mode = COUNT; mode != DONE; mode++) {
+    size_t found;
+    gboolean avail;
+    GtkTreeIter iter;
+
+    found = 0;
+    avail = gtk_tree_model_get_iter_first (model, &iter);
+    while (avail) {
+      gboolean active;
+
+      gtk_tree_model_get (model, &iter, 0 /* CONVERT */, &active, -1);
+      if (active) {
+        if (mode == COPY) {
+          gchar *hw_name;
+
+          gtk_tree_model_get (model, &iter, 1 /* HW_NAME */, &hw_name, -1);
+
+          /* gtk_tree_model_get() outputs a deep copy, so no need for an
+           * strdup() here
+           */
+          (*ret)[found] = hw_name;
+        }
+
+        found++;
+      }
+
+      avail = gtk_tree_model_iter_next (model, &iter);
+    } /* iteration over entries of "model" */
+
+    switch (mode) {
+    case COUNT:
+      if (found == 0)
+        return;
+
+      *ret = malloc ((found + 1) * sizeof (char *));
+      if (*ret == NULL)
+        error (EXIT_FAILURE, errno, "malloc");
+
+      break;
+
+    case COPY:
+      (*ret)[found] = NULL;
+      break;
+
+    default:
+      assert (0);
     }
-    b = gtk_tree_model_iter_next (model, &iter);
-    ++i;
-  }
-
-  (*ret)[j] = NULL;
+  } /* "mode" loop */
 }
 
 static void
 set_disks_from_ui (struct config *config)
 {
-  set_from_ui_generic (all_disks, &config->disks,
-                       GTK_TREE_VIEW (disks_list));
+  set_from_ui_generic (&config->disks, GTK_TREE_VIEW (disks_list));
 }
 
 static void
 set_removable_from_ui (struct config *config)
 {
-  set_from_ui_generic (all_removable, &config->removable,
-                       GTK_TREE_VIEW (removable_list));
+  set_from_ui_generic (&config->removable, GTK_TREE_VIEW (removable_list));
 }
 
 static void

_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to