[gtranslator] dl: Use GtrFilterSelection widget for team and module



commit 89e5d6bf0cc9e34496ffc7a0abf08fa44dad5d58
Author: Daniel GarcĂ­a Moreno <dani danigm net>
Date:   Tue Jun 11 10:25:16 2019 +0200

    dl: Use GtrFilterSelection widget for team and module
    
    See #68

 src/gtr-dl-teams.c         | 109 ++++++++++++++++++++++-----------------------
 src/gtr-filter-selection.c | 103 +++++++++++++++++++++++++++++++++++-------
 src/gtr-filter-selection.h |  25 +++++++++--
 src/gtr-lang-button.c      |   8 +++-
 4 files changed, 169 insertions(+), 76 deletions(-)
---
diff --git a/src/gtr-dl-teams.c b/src/gtr-dl-teams.c
index a508f640..a4cf8164 100644
--- a/src/gtr-dl-teams.c
+++ b/src/gtr-dl-teams.c
@@ -22,6 +22,7 @@
 
 #include "gtr-actions.h"
 #include "gtr-dl-teams.h"
+#include "gtr-filter-selection.h"
 #include "gtr-window.h"
 #include "gtr-utils.h"
 #include <libsoup/soup.h>
@@ -29,6 +30,8 @@
 #include <json-glib/json-glib.h>
 #include <json-glib/json-gobject.h>
 
+#include <glib/gi18n.h>
+
 #define API_URL "https://l10n.gnome.org/api/v1/";
 
 typedef struct
@@ -47,9 +50,6 @@ typedef struct
   GtkWidget *domains_combobox;
   GtkWidget *branches_combobox;
 
-  GtkListStore *teams_store;
-  GtkListStore *modules_store;
-
   gchar *selected_team;
   gchar *selected_module;
   gchar *selected_branch;
@@ -67,7 +67,7 @@ struct _GtrDlTeams
 G_DEFINE_TYPE_WITH_PRIVATE (GtrDlTeams, gtr_dl_teams, GTK_TYPE_BIN)
 
 static void team_add_cb (GtkButton *btn, GtrDlTeams *self);
-static void gtr_dl_teams_save_combo_selected (GtkComboBox *combo, GtrDlTeams *self);
+static void gtr_dl_teams_save_combo_selected (GtkWidget *widget, GtrDlTeams *self);
 static void gtr_dl_teams_load_po_file (GtkButton *button, GtrDlTeams *self);
 static void gtr_dl_teams_get_file_info (GtrDlTeams *self);
 
@@ -77,12 +77,13 @@ gtr_dl_teams_list_add (JsonArray *array,
                        JsonNode  *element,
                        gpointer   data)
 {
+  GSList **list = data;
   JsonObject *object = json_node_get_object (element);
+  const char *name = json_object_get_string_member (object, "name");
+  const char *desc = json_object_get_string_member (object, "description");
+  GtrFilterOption *opt = gtr_filter_option_new (name, desc);
 
-  gtk_list_store_insert_with_values(data, NULL, -1,
-                                    0, json_object_get_string_member (object, "description"),
-                                    1, json_object_get_string_member (object, "name"),
-                                    -1);
+  *list = g_slist_append (*list, opt);
 }
 
 static void
@@ -92,10 +93,11 @@ gtr_dl_modules_list_add (JsonArray *array,
                          gpointer   data)
 {
   JsonObject *object = json_node_get_object (element);
+  GSList **list = data;
+  const char *name = json_object_get_string_member (object, "name");
+  GtrFilterOption *opt = gtr_filter_option_new (name, name);
 
-  gtk_list_store_insert_with_values(data, NULL, -1,
-                                    0, json_object_get_string_member (object, "name"),
-                                    -1);
+  *list = g_slist_append (*list, opt);
 }
 
 static void
@@ -114,6 +116,8 @@ gtr_dl_teams_parse_teams_json (GObject *object,
 
   GtkWidget *dialog;
 
+  GSList *options = NULL;
+
   /* Parse JSON */
   stream = soup_session_send_finish (SOUP_SESSION (object), result, &error);
 
@@ -136,16 +140,15 @@ gtr_dl_teams_parse_teams_json (GObject *object,
   array = json_node_get_array (node);
 
   /* Fill teams list store with values from JSON and set store as combo box model */
-  json_array_foreach_element (array, gtr_dl_teams_list_add, GTK_TREE_MODEL (priv->teams_store));
-
-  gtk_combo_box_set_model (GTK_COMBO_BOX (priv->teams_combobox), GTK_TREE_MODEL (priv->teams_store));
+  json_array_foreach_element (array, gtr_dl_teams_list_add, &options);
+  gtr_filter_selection_set_options_full (GTR_FILTER_SELECTION (priv->teams_combobox), options);
 
   /* Enable selection */
   gtk_widget_set_sensitive (priv->teams_combobox, TRUE);
 }
 
 static void
-gtr_dl_teams_load_module_details_json (GtkComboBox *combo,
+gtr_dl_teams_load_module_details_json (GtkWidget  *widget,
                                        GtrDlTeams *self)
 {
   GtrDlTeamsPrivate *priv = gtr_dl_teams_get_instance_private (self);
@@ -211,13 +214,15 @@ gtr_dl_teams_load_module_details_json (GtkComboBox *combo,
 
       for (i=0; i < json_array_get_length (branchesArray); i++)
         {
+          const char *name = NULL;
           branch_element = json_array_get_element (branchesArray, i);
           branch_object = json_node_get_object (branch_element);
+          name = json_object_get_string_member (branch_object, "name"),
+
           gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (priv->branches_combobox),
-                                     json_object_get_string_member (branch_object, "name"),
-                                     json_object_get_string_member (branch_object, "name"));
+                                     name, name);
         }
-
+      gtk_combo_box_set_active (GTK_COMBO_BOX (priv->branches_combobox), 0);
       gtk_widget_set_sensitive (priv->branches_combobox, TRUE);
     }
   // TODO: check why there are no branches, display notification to user
@@ -240,6 +245,7 @@ gtr_dl_teams_load_module_details_json (GtkComboBox *combo,
                                      json_object_get_string_member (domain_object, "description"));
         }
 
+      gtk_combo_box_set_active (GTK_COMBO_BOX (priv->domains_combobox), 0);
       gtk_widget_set_sensitive (priv->domains_combobox, TRUE);
     }
   // TODO: check why there are no domains and display notification to user
@@ -262,6 +268,8 @@ gtr_dl_teams_parse_modules_json (GObject *object,
 
   GtkWidget *dialog;
 
+  GSList *options = NULL;
+
   /* Parse JSON */
   stream = soup_session_send_finish (SOUP_SESSION (object), result, &error);
   if (error)
@@ -283,9 +291,8 @@ gtr_dl_teams_parse_modules_json (GObject *object,
   array = json_node_get_array (node);
 
   /* Fill modules list store with values from JSON and set store as combo box model */
-  json_array_foreach_element (array, gtr_dl_modules_list_add, GTK_TREE_MODEL (priv->modules_store));
-
-  gtk_combo_box_set_model (GTK_COMBO_BOX (priv->modules_combobox), GTK_TREE_MODEL (priv->modules_store));
+  json_array_foreach_element (array, gtr_dl_modules_list_add, &options);
+  gtr_filter_selection_set_options_full (GTR_FILTER_SELECTION (priv->modules_combobox), options);
 
   gtk_widget_set_sensitive (priv->modules_combobox, TRUE);
 }
@@ -498,38 +505,41 @@ gtr_dl_teams_load_po_file (GtkButton *button, GtrDlTeams *self)
 }
 
 static void
-gtr_dl_teams_save_combo_selected (GtkComboBox *combo,
+gtr_dl_teams_save_combo_selected (GtkWidget  *widget,
                                   GtrDlTeams *self)
 {
   GtrDlTeamsPrivate *priv = gtr_dl_teams_get_instance_private (self);
-  GtkTreeIter iter;
-  GtkTreePath *path;
   const gchar *name;
 
-  path = gtk_tree_path_new_from_indices (gtk_combo_box_get_active (combo), -1);
-
   /* Save selected combo option */
-  name = gtk_widget_get_name (GTK_WIDGET (combo));
+  name = gtk_widget_get_name (widget);
 
   if (strcmp(name, "combo_modules") == 0)
     {
-      gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->modules_store), &iter, path);
-      gtk_tree_model_get (GTK_TREE_MODEL (priv->modules_store), &iter, 0, &priv->selected_module, -1);
+      const GtrFilterOption *opt = NULL;
+      if (priv->selected_module)
+        g_free (priv->selected_module);
+      opt = gtr_filter_selection_get_option (GTR_FILTER_SELECTION (priv->modules_combobox));
+      priv->selected_module = g_strdup (opt->name);
+
       /* Reload module details on module change */
-      gtr_dl_teams_load_module_details_json (combo, self);
+      gtr_dl_teams_load_module_details_json (widget, self);
     }
   else if (strcmp(name, "combo_teams") == 0)
     {
-      gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->teams_store), &iter, path);
-      gtk_tree_model_get (GTK_TREE_MODEL (priv->teams_store), &iter, 1, &priv->selected_team, -1);
+      const GtrFilterOption *opt = NULL;
+      if (priv->selected_team)
+        g_free (priv->selected_team);
+      opt = gtr_filter_selection_get_option (GTR_FILTER_SELECTION (priv->teams_combobox));
+      priv->selected_team = g_strdup (opt->name);
     }
   else if (strcmp(name, "combo_branches") == 0)
     {
-      priv->selected_branch = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
+      priv->selected_branch = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (widget));
     }
   else if (strcmp(name, "combo_domains") == 0)
     {
-      priv->selected_domain = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo));
+      priv->selected_domain = gtk_combo_box_get_active_id (GTK_COMBO_BOX (widget));
     }
 
   /* Check if all four required values have been selected to proceed with loading PO file */
@@ -539,6 +549,11 @@ gtr_dl_teams_save_combo_selected (GtkComboBox *combo,
 static void
 gtr_dl_teams_dispose (GObject *object)
 {
+  GtrDlTeamsPrivate *priv = gtr_dl_teams_get_instance_private (GTR_DL_TEAMS (object));
+
+  if (priv->selected_team)
+    g_free (priv->selected_team);
+
   G_OBJECT_CLASS (gtr_dl_teams_parent_class)->dispose (object);
 }
 
@@ -575,41 +590,25 @@ gtr_dl_teams_class_init (GtrDlTeamsClass *klass)
 static void
 gtr_dl_teams_init (GtrDlTeams *self)
 {
-  GtkCellRenderer *column;
   GtrDlTeamsPrivate *priv = gtr_dl_teams_get_instance_private (self);
   gtk_widget_init_template (GTK_WIDGET (self));
 
   priv->main_window = NULL;
+  priv->selected_team = NULL;
 
   gtk_widget_set_sensitive (priv->load_button, FALSE);
 
-  /* Init teams and modules list stores */
-  priv->teams_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
-  priv->modules_store = gtk_list_store_new (1, G_TYPE_STRING);
-
   /* Add combo boxes for DL teams and modules */
-  priv->teams_combobox = gtk_combo_box_new ();
+  priv->teams_combobox = GTK_WIDGET (gtr_filter_selection_new ());
   gtk_widget_set_name (priv->teams_combobox, "combo_teams");
-
-  column = gtk_cell_renderer_text_new ();
-  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->teams_combobox), column, TRUE);
-
-  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->teams_combobox), column,
-                                  "text", 0,
-                                  NULL);
+  gtr_filter_selection_set_text (GTR_FILTER_SELECTION (priv->teams_combobox), _("Translation Team"));
 
   gtk_container_add (GTK_CONTAINER (priv->select_box), priv->teams_combobox);
   gtk_widget_set_sensitive (priv->teams_combobox, FALSE);
 
-  priv->modules_combobox = gtk_combo_box_new ();
+  priv->modules_combobox = GTK_WIDGET (gtr_filter_selection_new ());
   gtk_widget_set_name (priv->modules_combobox, "combo_modules");
-
-  column = gtk_cell_renderer_text_new ();
-  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->modules_combobox), column, TRUE);
-
-  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->modules_combobox), column,
-                                  "text", 0,
-                                  NULL);
+  gtr_filter_selection_set_text (GTR_FILTER_SELECTION (priv->modules_combobox), _("Module"));
 
   gtk_container_add (GTK_CONTAINER (priv->select_box), priv->modules_combobox);
   gtk_widget_set_sensitive (priv->modules_combobox, FALSE);
diff --git a/src/gtr-filter-selection.c b/src/gtr-filter-selection.c
index 1e3affd0..ca78d533 100644
--- a/src/gtr-filter-selection.c
+++ b/src/gtr-filter-selection.c
@@ -29,7 +29,7 @@ typedef struct
   GtkWidget *popup;
   GSList *options;
   // TODO: manage this as a property
-  char *option;
+  GtrFilterOption *option;
 
 } GtrFilterSelectionPrivate;
 
@@ -48,9 +48,20 @@ change_option (GtkListBox         *box,
                GtkListBoxRow      *row,
                GtrFilterSelection *self)
 {
+  GSList *o = NULL;
   GtrFilterSelectionPrivate *priv = gtr_filter_selection_get_instance_private (self);
   GtkWidget *label = gtk_bin_get_child (GTK_BIN (row));
-  gtr_filter_selection_set_option (self, gtk_label_get_text (GTK_LABEL (label)));
+  const char *label_text = gtk_label_get_text (GTK_LABEL (label));
+
+  for (o = priv->options; o != NULL; o = g_slist_next (o))
+    {
+      GtrFilterOption *opt = (GtrFilterOption *)o->data;
+      if (!g_strcmp0 (opt->desc, label_text))
+        {
+          gtr_filter_selection_set_option_full (self, opt);
+          break;
+        }
+    }
 
   gtk_popover_popdown (GTK_POPOVER (priv->popup));
 }
@@ -76,13 +87,13 @@ filter_option (GtkEditable        *entry,
   for (o = priv->options; o != NULL; o = g_slist_next (o))
     {
       GtkWidget *child;
-      const char *opt = (char *)o->data;
-      g_autofree char *upopt = g_ascii_strup (opt, -1);
+      GtrFilterOption *opt = (GtrFilterOption *)o->data;
+      g_autofree char *upopt = g_ascii_strup (opt->desc, -1);
 
       if (g_strrstr (upopt, uptext) == NULL)
         continue;
 
-      child = gtk_label_new (opt);
+      child = gtk_label_new (opt->desc);
       gtk_label_set_xalign (GTK_LABEL (child), 0.0);
       gtk_container_add (GTK_CONTAINER (priv->option_list), child);
     }
@@ -93,9 +104,8 @@ static void
 gtr_filter_selection_finalize (GObject *object)
 {
   GtrFilterSelectionPrivate *priv = gtr_filter_selection_get_instance_private (GTR_FILTER_SELECTION 
(object));
-  g_clear_pointer (&priv->option, g_free);
   if (priv->options)
-    g_slist_free_full (priv->options, g_free);
+    g_slist_free_full (priv->options, (GDestroyNotify)gtr_filter_option_free);
   G_OBJECT_CLASS (gtr_filter_selection_parent_class)->finalize (object);
 }
 
@@ -148,7 +158,7 @@ gtr_filter_selection_new () {
   return self;
 }
 
-const char *
+const GtrFilterOption *
 gtr_filter_selection_get_option (GtrFilterSelection *self)
 {
   GtrFilterSelectionPrivate *priv = gtr_filter_selection_get_instance_private (self);
@@ -157,25 +167,42 @@ gtr_filter_selection_get_option (GtrFilterSelection *self)
 
 void
 gtr_filter_selection_set_option (GtrFilterSelection *self,
-                                 const char         *option)
+                                 const char         *name)
 {
   GtrFilterSelectionPrivate *priv = gtr_filter_selection_get_instance_private (self);
-  g_clear_pointer (&priv->option, g_free);
-  priv->option = g_strdup (option);
-  gtk_button_set_label (GTK_BUTTON (self), option);
+  GSList *o = NULL;
+
+  for (o = priv->options; o != NULL; o = g_slist_next (o))
+    {
+      GtrFilterOption *opt = (GtrFilterOption *)o->data;
+      if (!g_strcmp0 (opt->desc, name))
+        {
+          gtr_filter_selection_set_option_full (self, opt);
+          break;
+        }
+    }
+}
+
+void
+gtr_filter_selection_set_option_full (GtrFilterSelection *self,
+                                      GtrFilterOption   *option)
+{
+  GtrFilterSelectionPrivate *priv = gtr_filter_selection_get_instance_private (self);
+  priv->option = option;
+  gtk_button_set_label (GTK_BUTTON (self), option->desc);
   g_signal_emit (self, signals[CHANGED], 0, NULL);
 }
 
 void
-gtr_filter_selection_set_options (GtrFilterSelection *self,
-                                  GSList *options)
+gtr_filter_selection_set_options_full (GtrFilterSelection *self,
+                                       GSList *options)
 {
   GtrFilterSelectionPrivate *priv = gtr_filter_selection_get_instance_private (self);
   const GSList *o;
   GList *children;
 
   if (priv->options)
-    g_slist_free_full (priv->options, g_free);
+    g_slist_free_full (priv->options, (GDestroyNotify)gtr_filter_option_free);
   priv->options = options;
 
   children = gtk_container_get_children (GTK_CONTAINER (priv->option_list));
@@ -188,8 +215,8 @@ gtr_filter_selection_set_options (GtrFilterSelection *self,
 
   for (o = priv->options; o != NULL; o = g_slist_next (o))
     {
-      const char *opt = (char *)o->data;
-      GtkWidget *child = gtk_label_new (opt);
+      GtrFilterOption *opt = (GtrFilterOption *)o->data;
+      GtkWidget *child = gtk_label_new (opt->desc);
       gtk_label_set_xalign (GTK_LABEL (child), 0.0);
       gtk_container_add (GTK_CONTAINER (priv->option_list), child);
     }
@@ -197,6 +224,23 @@ gtr_filter_selection_set_options (GtrFilterSelection *self,
   gtk_widget_show_all (priv->option_list);
 }
 
+void
+gtr_filter_selection_set_options (GtrFilterSelection *self,
+                                  const GSList *options)
+{
+  const GSList *o;
+  GSList *optlist = NULL;
+
+  for (o = options; o != NULL; o = g_slist_next (o))
+    {
+      const char *opt = (char *)o->data;
+      GtrFilterOption *option = gtr_filter_option_new (opt, opt);
+      optlist = g_slist_append (optlist, option);
+    }
+
+  gtr_filter_selection_set_options_full (self, optlist);
+}
+
 void
 gtr_filter_selection_set_text (GtrFilterSelection *selection,
                                const char *text)
@@ -204,3 +248,28 @@ gtr_filter_selection_set_text (GtrFilterSelection *selection,
   gtk_button_set_label (GTK_BUTTON (selection), text);
 }
 
+void
+gtr_filter_option_free (GtrFilterOption *opt)
+{
+  if (!opt)
+    return;
+
+  if (opt->name)
+    g_free (opt->name);
+  if (opt->desc)
+    g_free (opt->desc);
+  g_free (opt);
+}
+
+GtrFilterOption *
+gtr_filter_option_new (const gchar *name,
+                       const gchar *desc)
+{
+  GtrFilterOption *option = g_malloc0 (sizeof (GtrFilterOption));
+  if (name)
+    option->name = g_strdup (name);
+  if (desc)
+    option->desc = g_strdup (desc);
+  return option;
+}
+
diff --git a/src/gtr-filter-selection.h b/src/gtr-filter-selection.h
index 5e94efa8..90e77451 100644
--- a/src/gtr-filter-selection.h
+++ b/src/gtr-filter-selection.h
@@ -31,20 +31,39 @@ struct _GtrFilterSelectionClass
   GtkMenuButtonClass parent_class;
 };
 
+typedef struct
+{
+  char *name;
+  char *desc;
+} GtrFilterOption;
+
+GtrFilterOption * gtr_filter_option_new (const char *name, const char *desc);
+void gtr_filter_option_free (GtrFilterOption *opt);
+
 GtrFilterSelection*  gtr_filter_selection_new             ();
 
 void
 gtr_filter_selection_set_text (GtrFilterSelection *selection,
                                const char *text);
 
+// options should be a GSlist<char*>
 void
 gtr_filter_selection_set_options (GtrFilterSelection *self,
-                                  GSList *options);
-const char *
+                                  const GSList *options);
+
+// options should be a GSlist<GtrFilterOption>
+void
+gtr_filter_selection_set_options_full (GtrFilterSelection *self,
+                                       GSList *options);
+
+const GtrFilterOption *
 gtr_filter_selection_get_option (GtrFilterSelection *self);
 void
 gtr_filter_selection_set_option (GtrFilterSelection *self,
-                                 const char         *option);
+                                 const char         *name);
+void
+gtr_filter_selection_set_option_full (GtrFilterSelection *self,
+                                      GtrFilterOption    *option);
 
 G_END_DECLS
 
diff --git a/src/gtr-lang-button.c b/src/gtr-lang-button.c
index a6550e56..7f7c3993 100644
--- a/src/gtr-lang-button.c
+++ b/src/gtr-lang-button.c
@@ -63,6 +63,9 @@ gtr_lang_button_init (GtrLangButton *self)
   langs = g_slist_sort (langs, (GCompareFunc)g_utf8_collate);
   gtr_filter_selection_set_options (GTR_FILTER_SELECTION (self), langs);
   gtr_filter_selection_set_text (GTR_FILTER_SELECTION (self), _("Choose Language"));
+
+  if (langs)
+    g_slist_free_full (langs, g_free);
 }
 
 GtrLangButton*
@@ -74,7 +77,10 @@ gtr_lang_button_new () {
 const gchar *
 gtr_lang_button_get_lang (GtrLangButton *self)
 {
-  return gtr_filter_selection_get_option (GTR_FILTER_SELECTION (self));
+  const GtrFilterOption *opt = gtr_filter_selection_get_option (GTR_FILTER_SELECTION (self));
+  if (!opt)
+    return NULL;
+  return opt->name;
 }
 
 void


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