[gnome-notes] manager: Use GListModel to store providers



commit a4ce2a352595eb9e68a9786caf074469c33c33eb
Author: Mohammed Sadiq <sadiq sadiqpk org>
Date:   Wed Jun 23 23:02:11 2021 +0530

    manager: Use GListModel to store providers
    
    And adapt to changes.  This will make the code simple and easy
    to maintain

 src/bjb-settings-dialog.c  | 254 ++++++++++++++++-----------------------------
 src/libbiji/biji-manager.c |  76 +++++++-------
 src/libbiji/biji-manager.h |   2 +-
 3 files changed, 129 insertions(+), 203 deletions(-)
---
diff --git a/src/bjb-settings-dialog.c b/src/bjb-settings-dialog.c
index a2e2bd4c..82c87283 100644
--- a/src/bjb-settings-dialog.c
+++ b/src/bjb-settings-dialog.c
@@ -40,7 +40,6 @@ struct _BjbSettingsDialog
 
   /* Primary NoteBook page */
   GtkListBox       *listbox;
-  GList            *children;
 
   /* Note Appearance page */
   GtkColorChooser *color_button;
@@ -77,59 +76,6 @@ on_color_set (GtkColorButton    *button,
   g_object_set (self->settings, "color", color_str, NULL);
 }
 
-/* Primary Provider page */
-
-typedef struct
-{
-  GtkWidget      *widget;
-  GtkWidget      *toggle;
-
-  const gchar    *id;
-  const char     *name;
-  const char     *user;
-  const char     *domain;
-  GtkWidget      *icon;
-
-  gboolean       selected;
-
-} ProviderChild;
-
-
-static ProviderChild *
-provider_child_new (void)
-{
-  ProviderChild *retval;
-
-  retval = g_slice_new (ProviderChild);
-  retval->widget = NULL;
-  retval->toggle = NULL;
-  retval->selected = FALSE;
-  retval->id = NULL;
-  retval->icon = NULL;
-
-  return retval;
-}
-
-
-static void
-provider_child_free (gpointer child)
-{
-  g_slice_free (ProviderChild, child);
-}
-
-
-static inline GQuark
-application_quark (void)
-{
-  static GQuark quark;
-
-  if (G_UNLIKELY (quark == 0))
-    quark = g_quark_from_static_string ("bjb-application");
-
-  return quark;
-}
-
-
 static GtkWidget *
 child_toggle_new (void)
 {
@@ -142,74 +88,57 @@ child_toggle_new (void)
   return w;
 }
 
-
 static void
-toggle_child (gpointer iter,
-              gpointer user_data)
+toggle_child (GtkWidget *row,
+              gboolean   active)
 {
-  ProviderChild *child;
-
-  child = (ProviderChild*) iter;
-
-  if (child->selected)
-    {
-      child->toggle = child_toggle_new ();
-      gtk_container_add (GTK_CONTAINER (child->widget), child->toggle);
-    }
-  else
-    {
-      if (child->toggle && GTK_IS_WIDGET (child->toggle))
-        gtk_widget_destroy (child->toggle);
-
-      child->toggle = NULL;
-    }
-}
+  GtkWidget *widget, *toggle;
 
+  g_assert (GTK_IS_LIST_BOX_ROW (row));
 
+  widget = gtk_bin_get_child (GTK_BIN (row));
+  toggle = g_object_get_data (G_OBJECT (widget), "toggle");
+  g_assert (toggle);
 
-static void
-update_providers (BjbSettingsDialog *self)
-{
-  g_list_foreach (self->children, toggle_child, self);
+  gtk_widget_set_opacity (toggle, active ? 1.0 : 0.0);
 }
 
-
-static void
-unselect_child (gpointer data, gpointer user_data)
-{
-  ProviderChild *child;
-
-  child = (ProviderChild*) data;
-  child->selected = FALSE;
-}
-
-
 static void
 on_row_activated_cb    (GtkListBox    *list_box,
                         GtkListBoxRow *row,
                         gpointer       user_data)
 {
   BjbSettingsDialog *self;
-  GtkWidget     *widget;
-  ProviderChild *child;
-
+  BijiProvider *provider;
+  GtkWidget *widget, *toggle;
+  g_autoptr(GList) children = NULL;
+  const BijiProviderInfo *info;
 
   self = BJB_SETTINGS_DIALOG (user_data);
 
-  /* Write GSettings if the provider was not the primary one */
   widget = gtk_bin_get_child (GTK_BIN (row));
-  child = g_object_get_qdata (G_OBJECT (widget), application_quark ());
+  provider = g_object_get_data (G_OBJECT (widget), "provider");
+  g_assert (provider);
+
+  info = biji_provider_get_info (provider);
+  toggle = g_object_get_data (G_OBJECT (widget), "toggle");
+  g_assert (toggle);
 
-  if (child->selected == TRUE)
+  /* If the row is already selected, simply return */
+  if (G_APPROX_VALUE (1.0, gtk_widget_get_opacity (toggle), DBL_EPSILON))
     return;
 
-  g_object_set (self->settings, "default-location", child->id, NULL);
-  biji_manager_set_provider (self->manager, child->id);
+  children = gtk_container_get_children (GTK_CONTAINER (list_box));
 
-  /* Toggle everything : unselect all but this one */
-  g_list_foreach (self->children, unselect_child, NULL);
-  child->selected = TRUE;
-  update_providers (self);
+  /* Deselect all rows first */
+  for (GList *child = children; child; child = child->next)
+    toggle_child (child->data, FALSE);
+
+  /* Now select the current one */
+  toggle_child (GTK_WIDGET (row), TRUE);
+
+  g_object_set (self->settings, "default-location", info->unique_id, NULL);
+  biji_manager_set_provider (self->manager, info->unique_id);
 }
 
 
@@ -225,52 +154,32 @@ header_func (GtkListBoxRow *row,
     gtk_list_box_row_set_header (row, NULL);
 }
 
-
-static void
-add_child (gpointer provider_info, gpointer user_data)
+static GtkWidget *
+provider_row_new (BjbSettingsDialog *self,
+                  BijiProvider      *provider)
 {
-  BjbSettingsDialog           *self;
-  const BijiProviderInfo      *info;
-  ProviderChild               *child;
-  GtkWidget                   *box, *w, *hbox;
-  g_autofree char             *identity = NULL;
-
-  self = BJB_SETTINGS_DIALOG (user_data);
-  info = (const BijiProviderInfo*) provider_info;
-
-  child = provider_child_new ();
-  child->id = info->unique_id;
-  child->icon = info->icon;
-  child->name = info->name;
-  child->user = info->user;
-  child->domain = info->domain;
+  const BijiProviderInfo *info;
+  GtkWidget *row, *w, *hbox;
+  g_autofree char *identity = NULL;
 
-  if (child->user && info->domain)
-    identity = g_strconcat(child->user, "@", child->domain, NULL);
+  g_assert (BJB_IS_SETTINGS_DIALOG (self));
+  g_assert (BIJI_IS_PROVIDER (provider));
 
-  /* Is the provider the primary ? */
-  if (g_strcmp0 (child->id, bjb_settings_get_default_location (self->settings)) ==0)
-    child->selected = TRUE;
+  info = biji_provider_get_info (provider);
 
-  /* Create the widget */
+  if (info->user && info->domain)
+    identity = g_strconcat (info->user, "@", info->domain, NULL);
 
-  child->widget = box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 24);
-  gtk_widget_set_margin_start (box, 12);
-  gtk_widget_set_margin_end (box, 12);
-  gtk_container_add (GTK_CONTAINER (self->listbox), child->widget);
-
-
-  g_object_set_qdata_full (G_OBJECT (child->widget), application_quark (),
-                           child, provider_child_free);
-
-
-  w = child->icon;
-  gtk_container_add (GTK_CONTAINER (box), w);
+  row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 24);
+  gtk_widget_set_margin_start (row, 12);
+  gtk_widget_set_margin_end (row, 12);
+  gtk_container_add (GTK_CONTAINER (row), info->icon);
+  g_object_set_data (G_OBJECT (row), "provider", provider);
 
   hbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
-  gtk_container_add (GTK_CONTAINER (box), hbox);
+  gtk_container_add (GTK_CONTAINER (row), hbox);
 
-  w = gtk_label_new (child->name);
+  w = gtk_label_new (info->name);
   gtk_widget_set_halign (w, GTK_ALIGN_START);
   gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
   gtk_widget_set_hexpand (w, TRUE);
@@ -287,8 +196,45 @@ add_child (gpointer provider_info, gpointer user_data)
       gtk_container_add (GTK_CONTAINER (hbox), w);
     }
 
-  self->children = g_list_prepend (self->children, child);
-  gtk_widget_show_all (box);
+  w = child_toggle_new ();
+  gtk_container_add (GTK_CONTAINER (row), w);
+  g_object_set_data (G_OBJECT (row), "toggle", w);
+
+  if (g_strcmp0 (info->unique_id, bjb_settings_get_default_location (self->settings)) == 0)
+    gtk_widget_set_opacity (w, 1.0);
+  else
+    gtk_widget_set_opacity (w, 0.0);
+
+  gtk_widget_show_all (row);
+
+  return row;
+}
+
+static void
+on_provider_items_changed_cb (BjbSettingsDialog *self)
+{
+  GListModel *providers;
+  guint n_items;
+
+  g_assert (BJB_IS_SETTINGS_DIALOG (self));
+
+  providers = biji_manager_get_providers (self->manager);
+  n_items = g_list_model_get_n_items (providers);
+
+  /* First remove every row */
+  gtk_container_foreach (GTK_CONTAINER (self->listbox),
+                         (GtkCallback)gtk_widget_destroy, NULL);
+
+  /* Now add a row for each provider */
+  for (guint i = 0; i < n_items; i++)
+    {
+      g_autoptr(BijiProvider) provider = NULL;
+      GtkWidget *child;
+
+      provider = g_list_model_get_item (providers, i);
+      child = provider_row_new (self, provider);
+      gtk_container_add (GTK_CONTAINER (self->listbox), child);
+    }
 }
 
 static void
@@ -296,7 +242,7 @@ bjb_settings_dialog_constructed (GObject *object)
 {
   BjbSettingsDialog *self;
   GApplication      *app;
-  GList             *providers;
+  GListModel *providers;
   GdkRGBA            color;
 
   G_OBJECT_CLASS (bjb_settings_dialog_parent_class)->constructed (object);
@@ -324,25 +270,10 @@ bjb_settings_dialog_constructed (GObject *object)
 
   /* Add providers */
   providers = biji_manager_get_providers (self->manager);
-  g_list_foreach (providers, add_child, self);
-  g_list_free (providers);
-
-  /* Check GSettings : toggle the actual default provider */
-  update_providers (self);
-}
-
-static void
-bjb_settings_dialog_finalize (GObject *object)
-{
-  BjbSettingsDialog *self;
-
-  g_return_if_fail (BJB_IS_SETTINGS_DIALOG (object));
-
-  self = BJB_SETTINGS_DIALOG (object);
-
-  g_list_free (self->children);
-
-  G_OBJECT_CLASS (bjb_settings_dialog_parent_class)->finalize (object);
+  g_signal_connect_object (providers, "items-changed",
+                           G_CALLBACK (on_provider_items_changed_cb),
+                           self, G_CONNECT_SWAPPED);
+  on_provider_items_changed_cb (self);
 }
 
 static void
@@ -360,7 +291,6 @@ bjb_settings_dialog_class_init (BjbSettingsDialogClass *klass)
   g_object_class = G_OBJECT_CLASS (klass);
   gtk_widget_class = GTK_WIDGET_CLASS (klass);
 
-  g_object_class->finalize = bjb_settings_dialog_finalize;
   g_object_class->constructed = bjb_settings_dialog_constructed;
 
   gtk_widget_class_set_template_from_resource (gtk_widget_class, "/org/gnome/Notes/ui/settings-dialog.ui");
diff --git a/src/libbiji/biji-manager.c b/src/libbiji/biji-manager.c
index ca57bf97..3ec7cb44 100644
--- a/src/libbiji/biji-manager.c
+++ b/src/libbiji/biji-manager.c
@@ -44,7 +44,7 @@ struct _BijiManager
   GListStore *notebooks;
   GHashTable *items;
   GHashTable *archives;
-  GHashTable *providers;
+  GListStore *providers;
   BijiProvider *local_provider;
 
   /* The active provider */
@@ -117,6 +117,32 @@ on_provider_loaded_cb (BijiProvider   *provider,
   biji_manager_notify_changed (manager, group, BIJI_MANAGER_MASS_CHANGE, NULL);
 }
 
+static BijiProvider *
+find_provider_with_id (GListModel *providers,
+                       const char *provider_id)
+{
+  guint n_items;
+
+  if (!providers || !provider_id)
+    return NULL;
+
+  n_items = g_list_model_get_n_items (providers);
+
+  for (guint i = 0; i < n_items; i++)
+    {
+      g_autoptr(BijiProvider) provider = NULL;
+      const BijiProviderInfo *info;
+
+      provider = g_list_model_get_item (providers, i);
+      info = biji_provider_get_info (provider);
+
+      if (g_strcmp0 (info->unique_id, provider_id) == 0)
+        return provider;
+    }
+
+  return NULL;
+}
+
 /*
  * It should be the right place
  * to stock somehow providers list
@@ -127,14 +153,7 @@ static void
 _add_provider (BijiManager  *self,
                BijiProvider *provider)
 {
-  const BijiProviderInfo *info;
-
-  info = biji_provider_get_info (provider);
-  /* TODO: This is a workaround related to the local provider, which
-   *        emits the signal twice but it should emit it only once */
-  if (!g_hash_table_contains (self->providers, info->unique_id))
-    g_hash_table_insert (self->providers,
-                         (gpointer) info->unique_id, provider);
+  g_list_store_append (self->providers, provider);
 
   g_signal_connect (provider, "loaded",
                     G_CALLBACK (on_provider_loaded_cb), self);
@@ -230,6 +249,7 @@ static void
 biji_manager_init (BijiManager *self)
 {
   self->notebooks = g_list_store_new (BIJI_TYPE_NOTEBOOK);
+  self->providers = g_list_store_new (BIJI_TYPE_PROVIDER);
 
   /* Item path is key for table */
   self->items = g_hash_table_new_full (g_str_hash,
@@ -241,15 +261,6 @@ biji_manager_init (BijiManager *self)
                                           g_str_equal,
                                           NULL,
                                           NULL);
-  /*
-   * Providers are the different notes storage
-   * the hash table use an id
-   *
-   * - local files stored notes = "local"
-   * - own cloud notes = account_get_id
-   */
-  self->providers = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                           NULL, g_object_unref);
   self->tracker = biji_tracker_new (self);
 }
 
@@ -274,32 +285,21 @@ biji_manager_set_provider (BijiManager *self,
   g_hash_table_remove_all (self->items);
   g_hash_table_remove_all (self->archives);
 
-  self->provider = g_hash_table_lookup (self->providers, provider_id);
+  self->provider = find_provider_with_id (G_LIST_MODEL (self->providers), provider_id);
   if (self->provider)
     biji_provider_load_items (self->provider);
   else
     g_warning ("Could not find provider with ID: %s", provider_id);
 }
 
-GList *
+GListModel *
 biji_manager_get_providers (BijiManager *self)
 {
-  GList *providers, *l, *retval;
-
-  retval = NULL;
-  providers = g_hash_table_get_values (self->providers);
-
-  for (l = providers; l != NULL; l = l->next)
-  {
-    retval = g_list_prepend (
-               retval, (gpointer) biji_provider_get_info (BIJI_PROVIDER (l->data)));
-  }
+  g_return_val_if_fail (BIJI_IS_MANAGER (self), NULL);
 
-  g_list_free (providers);
-  return retval;
+  return G_LIST_MODEL (self->providers);
 }
 
-
 static void
 biji_manager_finalize (GObject *object)
 {
@@ -310,7 +310,7 @@ biji_manager_finalize (GObject *object)
   g_clear_object (&self->tracker);
   g_hash_table_destroy (self->items);
   g_hash_table_destroy (self->archives);
-  g_hash_table_unref (self->providers);
+  g_clear_object (&self->providers);
 
   G_OBJECT_CLASS (biji_manager_parent_class)->finalize (object);
 }
@@ -932,10 +932,7 @@ biji_manager_note_new            (BijiManager  *self,
   BijiProvider *provider = NULL;
   BijiNoteObj *retval;
 
-
-  if (provider_id != NULL)
-    provider = g_hash_table_lookup (self->providers,
-                                    provider_id);
+  provider = find_provider_with_id (G_LIST_MODEL (self->providers), provider_id);
 
   if (provider == NULL)
     provider = self->local_provider;
@@ -962,8 +959,7 @@ biji_manager_note_new_full (BijiManager   *self,
   BijiProvider *provider;
   BijiNoteObj *retval;
 
-  provider = g_hash_table_lookup (self->providers,
-                                  provider_id);
+  provider = find_provider_with_id (G_LIST_MODEL (self->providers), provider_id);
 
   retval = BIJI_PROVIDER_GET_CLASS (provider)->create_note_full (provider,
                                                                  suggested_path,
diff --git a/src/libbiji/biji-manager.h b/src/libbiji/biji-manager.h
index 0471d0fe..d84e5d00 100644
--- a/src/libbiji/biji-manager.h
+++ b/src/libbiji/biji-manager.h
@@ -56,7 +56,7 @@ void             biji_manager_import_uri            (BijiManager *manager,
 void             biji_manager_set_provider          (BijiManager *manager,
                                                      const gchar *provider_id);
 
-GList           *biji_manager_get_providers         (BijiManager *manager); /* <ProviderInfo*> */
+GListModel      *biji_manager_get_providers         (BijiManager *manager);
 TrackerSparqlConnection
                 *biji_manager_get_tracker_connection (BijiManager *manager);
 gpointer         biji_manager_get_tracker            (BijiManager *self);


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