[gnome-initial-setup/more-vendor-config-hooks: 35/35] Allow to reorder pages from the vendor configuration file



commit 57e2c30c762254041399cfbd4bc2d60ee0c60719
Author: Joaquim Rocha <jrocha endlessm com>
Date:   Wed Jul 18 12:41:12 2018 +0200

    Allow to reorder pages from the vendor configuration file
    
    Sometimes vendors may want to have pages show up in a different order
    from the default one (e.g. ask for the username before the online
    accounts). For that, this patch allows vendors to specify the order
    by using a string list in the configuration file, for example:
    
      [pages]
      order=language,keyboard
    
    The example above would show the language page before, then the
    keyboard page, and then proceed with the rest of the pages, in the
    default order they had among themselves.

 gnome-initial-setup/gnome-initial-setup.c | 80 +++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)
---
diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c
index e42639e..d8b6638 100644
--- a/gnome-initial-setup/gnome-initial-setup.c
+++ b/gnome-initial-setup/gnome-initial-setup.c
@@ -47,6 +47,7 @@
 
 #define VENDOR_PAGES_GROUP "pages"
 #define VENDOR_SKIP_KEY "skip"
+#define VENDOR_ORDER_KEY "order"
 #define VENDOR_NEW_USER_ONLY_KEY "new_user_only"
 #define VENDOR_EXISTING_USER_ONLY_KEY "existing_user_only"
 
@@ -172,6 +173,82 @@ destroy_pages_after (GisAssistant *assistant,
   }
 }
 
+static gint
+compare_pages_order (gconstpointer a,
+                     gconstpointer b,
+                     gpointer data)
+{
+  GHashTable *sort_table = data;
+  const gchar *id_a = ((PageData *) a)->page_id;
+  const gchar *id_b = ((PageData *) b)->page_id;
+  gint order_a = GPOINTER_TO_INT (g_hash_table_lookup (sort_table, id_a));
+  gint order_b = GPOINTER_TO_INT (g_hash_table_lookup (sort_table, id_b));
+
+  return order_a - order_b;
+}
+
+static void
+reorder_pages (GisDriver *driver)
+{
+  gint num_pages;
+  gsize num_ordered_pages = 0;
+  g_auto(GStrv) conf_pages_order = NULL;
+  g_autoptr(GHashTable) sort_table = NULL; /* (owned) (element-type utf8 uint) */
+
+  conf_pages_order = gis_driver_conf_get_string_list (driver,
+                                                      VENDOR_PAGES_GROUP,
+                                                      VENDOR_ORDER_KEY,
+                                                      &num_ordered_pages);
+  if (conf_pages_order == NULL)
+    return;
+
+  if (*conf_pages_order == NULL) {
+    g_warning ("No pages defined in the pages order from the conf file");
+    return;
+  }
+
+  /* sanitize the number of pages to be reordered; this should not be frequently
+   * reached as it's extremely unlikely to have that many pages */
+  if (num_ordered_pages > G_MAXINT) {
+    g_warning ("Too many pages to be reordered from the conf file... skipping!");
+    return;
+  }
+
+  /* assign the same sort weight to every page (this will make sure) that any
+   * page to be sorted differently will show up before pages that aren't in the
+   * custom sorting list */
+  sort_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+  for (num_pages = 0; page_table[num_pages].page_id != NULL; ++num_pages) {
+    g_hash_table_insert (sort_table, (gchar *) page_table[num_pages].page_id,
+                         GINT_TO_POINTER (G_MAXINT));
+  }
+
+  /* assign the new sort weights from the conf file */
+  for (guint i = 0; conf_pages_order[i] != NULL; ++i) {
+    gchar *page_id = conf_pages_order[i];
+    if (!g_hash_table_contains (sort_table, page_id)) {
+      g_warning ("No page with id '%s' found while sorting the pages!", page_id);
+      continue;
+    }
+
+    g_hash_table_insert (sort_table, page_id, GINT_TO_POINTER (i));
+  }
+
+  /* use a stable sort algorithm (this implementation is stable since
+   * glib 2.32) */
+  g_qsort_with_data (page_table,
+                     num_pages,
+                     sizeof (PageData),
+                     compare_pages_order,
+                     sort_table);
+
+  g_debug ("Pages have been reordered: ");
+  for (guint i = 0; i < num_pages; ++i) {
+    g_debug (" - %s", page_table[i].page_id);
+  }
+}
+
 static void
 rebuild_pages_cb (GisDriver *driver)
 {
@@ -274,6 +351,9 @@ main (int argc, char *argv[])
     gis_ensure_login_keyring ();
 
   driver = gis_driver_new (mode);
+
+  reorder_pages (driver);
+
   g_signal_connect (driver, "rebuild-pages", G_CALLBACK (rebuild_pages_cb), NULL);
   status = g_application_run (G_APPLICATION (driver), argc, argv);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]