[easytag/wip/musicbrainz-support-merge: 104/149] FIXME (split) Implemented Refresh Operation. Fixed a memory leak and Escape Press during search bug



commit 0c080e3dcf9622d1a24f85858b4b16c9a5cfaac5
Author: Abhinav <abhijangda hotmail com>
Date:   Thu Jun 26 18:56:15 2014 +0530

    FIXME (split) Implemented Refresh Operation. Fixed a memory leak and Escape Press during search bug
    
    Added Refresh Button in musicbrainz_dialog.ui. Implemented Refresh
    Operations in musicbrainz_dialog.c and mbentityview.c. Added macro
    CHECK_CANCELLED instead of using the if-then block everywhere in
    mb_search.c. Pressing Escape during search would crash. Fixed it by
    adding checks at the end of search, closing dialog during search would
    stop the search

 data/musicbrainz_dialog.ui |   12 +-
 src/mb_search.c            |  121 ++++++++----------------
 src/mb_search.h            |    2 +-
 src/mbentityview.c         |  187 ++++++++++++++++++++++++++++++-------
 src/mbentityview.h         |    4 +
 src/musicbrainz_dialog.c   |  222 ++++++++++++++++++++++++++++++++++++++------
 src/musicbrainz_dialog.h   |    2 +
 7 files changed, 399 insertions(+), 151 deletions(-)
---
diff --git a/data/musicbrainz_dialog.ui b/data/musicbrainz_dialog.ui
index 053076a..ef5e334 100644
--- a/data/musicbrainz_dialog.ui
+++ b/data/musicbrainz_dialog.ui
@@ -6,6 +6,11 @@
     <property name="can_focus">False</property>
     <property name="stock">gtk-find</property>
   </object>
+  <object class="GtkImage" id="img_invert_selection">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="stock">easytag-invert-selection</property>
+  </object>
   <object class="GtkImage" id="img_red_lines">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
@@ -16,11 +21,6 @@
     <property name="can_focus">False</property>
     <property name="stock">easytag-unselect-all</property>
   </object>
-  <object class="GtkImage" id="img_invert_selection">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="stock">easytag-invert-selection</property>
-  </object>
   <object class="GtkDialog" id="mbDialog">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
@@ -408,7 +408,7 @@
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkButton" id="button10">
+                      <object class="GtkButton" id="btnApplyChanges">
                         <property name="label" translatable="yes">Apply Tag Changes</property>
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
diff --git a/src/mb_search.c b/src/mb_search.c
index c59a362..ae65428 100644
--- a/src/mb_search.c
+++ b/src/mb_search.c
@@ -30,6 +30,15 @@
 static gchar *server = NULL;
 static int port = 0;
 
+#define CHECK_CANCELLED(cancellable) if (g_cancellable_is_cancelled (cancellable))\
+                                     {\
+                                           g_set_error (error, ET_MB5_SEARCH_ERROR,\
+                                                        ET_MB5_SEARCH_ERROR_CANCELLED,\
+                                                        _("Operation cancelled by user"));\
+                                           g_assert (error == NULL || *error != NULL);\
+                                           return FALSE;\
+                                      }
+
 /*
  * et_mb5_search_error_quark:
  *
@@ -80,14 +89,7 @@ et_musicbrainz_search_in_entity (MbEntityKind child_type,
     char *param_values[1];
     char *param_names[1];
 
-    if (g_cancellable_is_cancelled (cancellable))
-    {
-        g_set_error (error, ET_MB5_SEARCH_ERROR,
-                     ET_MB5_SEARCH_ERROR_CANCELLED,
-                     _("Operation cancelled by user"));
-        g_assert (error == NULL || *error != NULL);
-        return FALSE;
-    }
+    CHECK_CANCELLED(cancellable);
 
     param_names [0] = "inc";
     query = mb5_query_new ("easytag", server, port);
@@ -109,17 +111,7 @@ et_musicbrainz_search_in_entity (MbEntityKind child_type,
                 Mb5Artist artist;
                 gchar *message;
 
-                if (g_cancellable_is_cancelled (cancellable))
-                {
-                    g_set_error (error, ET_MB5_SEARCH_ERROR,
-                                 ET_MB5_SEARCH_ERROR_CANCELLED,
-                                 _("Operation cancelled by user"));
-                    mb5_query_delete (query);
-                    mb5_metadata_delete (metadata);
-                    g_assert (error == NULL || *error != NULL);
-                    return FALSE;
-                }
-
+                CHECK_CANCELLED(cancellable);
                 artist = mb5_metadata_get_artist (metadata);
                 list = mb5_artist_get_releaselist (artist);
                 param_values[0] = "artists release-groups";
@@ -143,17 +135,7 @@ et_musicbrainz_search_in_entity (MbEntityKind child_type,
                         EtMbEntity *entity;
                         int size;
 
-                        if (g_cancellable_is_cancelled (cancellable))
-                        {
-                            g_set_error (error, ET_MB5_SEARCH_ERROR,
-                                         ET_MB5_SEARCH_ERROR_CANCELLED,
-                                         _("Operation cancelled by user"));
-                            mb5_query_delete (query);
-                            mb5_metadata_delete (metadata);
-                            g_assert (error == NULL || *error != NULL);
-                            return FALSE;
-                        }
-
+                        CHECK_CANCELLED(cancellable);
                         size = mb5_release_get_title ((Mb5Release)release, buf,
                                                       sizeof (buf));
                         buf [size] = '\0';
@@ -173,6 +155,7 @@ et_musicbrainz_search_in_entity (MbEntityKind child_type,
                                                             buf, "",
                                                             1, param_names,
                                                             param_values);
+                        CHECK_CANCELLED(cancellable);
                         entity = g_malloc (sizeof (EtMbEntity));
                         entity->entity = mb5_release_clone (mb5_metadata_get_release (metadata_release));
                         entity->type = MB_ENTITY_KIND_ALBUM;
@@ -195,8 +178,10 @@ et_musicbrainz_search_in_entity (MbEntityKind child_type,
              parent_type == MB_ENTITY_KIND_ALBUM)
     {
         param_values [0] = "recordings";
+        CHECK_CANCELLED(cancellable);
         metadata = mb5_query_query (query, "release", parent_mbid, "", 1,
                                     param_names, param_values);
+        CHECK_CANCELLED(cancellable);
         result = mb5_query_get_lastresult (query);
 
         if (result == eQuery_Success)
@@ -264,12 +249,13 @@ et_musicbrainz_search_in_entity (MbEntityKind child_type,
                             size = mb5_recording_get_id (recording,
                                                          buf,
                                                          sizeof (buf));
-
+                            CHECK_CANCELLED(cancellable);
                             metadata_recording = mb5_query_query (query,
                                                                   "recording",
                                                                   buf, "", 1,
                                                                   param_names,
                                                                   param_values);
+                            CHECK_CANCELLED(cancellable);
                             entity = g_malloc (sizeof (EtMbEntity));
                             entity->entity = mb5_recording_clone (mb5_metadata_get_recording 
(metadata_recording));
                             entity->type = MB_ENTITY_KIND_TRACK;
@@ -290,6 +276,7 @@ et_musicbrainz_search_in_entity (MbEntityKind child_type,
         }
     }
 
+    CHECK_CANCELLED(cancellable);
     mb5_query_delete (query);
 
     return TRUE;
@@ -398,17 +385,7 @@ et_musicbrainz_search (gchar *string, MbEntityKind type, GNode *root,
                 {
                     Mb5Artist artist;
 
-                    if (g_cancellable_is_cancelled (cancellable))
-                    {
-                        g_set_error (error, ET_MB5_SEARCH_ERROR,
-                                     ET_MB5_SEARCH_ERROR_CANCELLED,
-                                     _("Operation cancelled by user"));
-                        mb5_query_delete (query);
-                        mb5_metadata_delete (metadata);
-                        g_assert (error == NULL || *error != NULL);
-                        return FALSE;
-                    }
-
+                    CHECK_CANCELLED(cancellable);
                     artist = mb5_artist_list_item (list, i);
 
                     if (artist)
@@ -463,17 +440,7 @@ et_musicbrainz_search (gchar *string, MbEntityKind type, GNode *root,
                 {
                     Mb5Release release;
 
-                    if (g_cancellable_is_cancelled (cancellable))
-                    {
-                        g_set_error (error, ET_MB5_SEARCH_ERROR,
-                                     ET_MB5_SEARCH_ERROR_CANCELLED,
-                                     _("Operation cancelled by user"));
-                        mb5_query_delete (query);
-                        mb5_metadata_delete (metadata);
-                        g_assert (error == NULL || *error != NULL);
-                        return FALSE;
-                    }
-
+                    CHECK_CANCELLED(cancellable);
                     release = mb5_release_list_item (list, i);
 
                     if (release)
@@ -498,10 +465,12 @@ et_musicbrainz_search (gchar *string, MbEntityKind type, GNode *root,
                         mb5_release_get_id ((Mb5Release)release,
                                             buf,
                                             sizeof (buf));
+                        CHECK_CANCELLED(cancellable);
                         metadata_release = mb5_query_query (query, "release",
                                                             buf, "",
                                                             1, param_names,
                                                             param_values);
+                        CHECK_CANCELLED(cancellable);
                         entity = g_malloc (sizeof (EtMbEntity));
                         entity->entity = mb5_release_clone (mb5_metadata_get_release (metadata_release));
                         entity->type = MB_ENTITY_KIND_ALBUM;
@@ -539,7 +508,7 @@ et_musicbrainz_search (gchar *string, MbEntityKind type, GNode *root,
 
                 list = mb5_metadata_get_recordinglist (metadata);
                 param_names [0] = "inc";
-                param_values[0] = "releases artists";
+                param_values[0] = "releases artists artist-credits release-groups";
                 message = g_strdup_printf (_("Found %d Track(s)"),
                                            mb5_recording_list_size (list));
 #ifndef TEST
@@ -556,17 +525,7 @@ et_musicbrainz_search (gchar *string, MbEntityKind type, GNode *root,
                     EtMbEntity *entity;
                     int size;
 
-                    if (g_cancellable_is_cancelled (cancellable))
-                    {
-                        g_set_error (error, ET_MB5_SEARCH_ERROR,
-                                     ET_MB5_SEARCH_ERROR_CANCELLED,
-                                     _("Operation cancelled by user"));
-                        mb5_query_delete (query);
-                        mb5_metadata_delete (metadata);
-                        g_assert (error == NULL || *error != NULL);
-                        return FALSE;
-                    }
-
+                    CHECK_CANCELLED(cancellable);
                     recording = mb5_recording_list_item (list, i);
                     size = mb5_recording_get_title (recording, buf, sizeof (buf));
                     buf [size] = '\0';
@@ -585,6 +544,7 @@ et_musicbrainz_search (gchar *string, MbEntityKind type, GNode *root,
                                                           buf, "",
                                                           1, param_names,
                                                           param_values);
+                    CHECK_CANCELLED(cancellable);
                     entity = g_malloc (sizeof (EtMbEntity));
                     entity->entity = mb5_recording_clone (mb5_metadata_get_recording (metadata_recording));
                     entity->type = MB_ENTITY_KIND_TRACK;
@@ -635,17 +595,7 @@ et_musicbrainz_search (gchar *string, MbEntityKind type, GNode *root,
                 {
                     Mb5Release release;
 
-                    if (g_cancellable_is_cancelled (cancellable))
-                    {
-                        g_set_error (error, ET_MB5_SEARCH_ERROR,
-                                     ET_MB5_SEARCH_ERROR_CANCELLED,
-                                     _("Operation cancelled by user"));
-                        mb5_query_delete (query);
-                        mb5_metadata_delete (metadata);
-                        g_assert (error == NULL || *error != NULL);
-                        return FALSE;
-                    }
-
+                    CHECK_CANCELLED(cancellable);
                     release = mb5_release_list_item (list, i);
 
                     if (release)
@@ -674,6 +624,7 @@ et_musicbrainz_search (gchar *string, MbEntityKind type, GNode *root,
                                                             buf, "",
                                                             1, param_names,
                                                             param_values);
+                        CHECK_CANCELLED(cancellable);
                         entity = g_malloc (sizeof (EtMbEntity));
                         entity->entity = mb5_release_clone (mb5_metadata_get_release (metadata_release));
                         entity->type = MB_ENTITY_KIND_ALBUM;
@@ -694,6 +645,7 @@ et_musicbrainz_search (gchar *string, MbEntityKind type, GNode *root,
     }
 
     mb5_query_delete (query);
+    CHECK_CANCELLED(cancellable);
 
     return TRUE;
 
@@ -749,10 +701,18 @@ et_musicbrainz_search (gchar *string, MbEntityKind type, GNode *root,
  * To free the memory occupied by the tree.
  */
 void
-free_mb_tree (GNode *node)
+free_mb_tree (GNode **_node)
 {
     EtMbEntity *et_entity;
     GNode *child;
+    GNode *node;
+
+    node = *_node;
+
+    if (!node)
+    {
+        return;
+    }
 
     et_entity = (EtMbEntity *)node->data;
 
@@ -780,10 +740,13 @@ free_mb_tree (GNode *node)
 
     while (child)
     {
-        free_mb_tree (child);
-        child = g_node_next_sibling (child);
+        GNode *child1;
+        child1 = g_node_next_sibling (child);
+        free_mb_tree (&child);
+        child = child1;
     }
 
     g_node_destroy (node);
+    *_node = NULL;
 }
 #endif /* ENABLE_MUSICBRAINZ */
diff --git a/src/mb_search.h b/src/mb_search.h
index 4a77ada..0b5e4b1 100644
--- a/src/mb_search.h
+++ b/src/mb_search.h
@@ -101,6 +101,6 @@ gboolean
 et_musicbrainz_search (gchar *string, MbEntityKind type, GNode *root,
                        GError **error, GCancellable *cancellable);
 void
-free_mb_tree (GNode *node);
+free_mb_tree (GNode **node);
 #endif /* __MB_SEARCH_H__ */
 #endif /* ENABLE_MUSICBRAINZ */
diff --git a/src/mbentityview.c b/src/mbentityview.c
index 5bdd349..b071157 100644
--- a/src/mbentityview.c
+++ b/src/mbentityview.c
@@ -29,7 +29,6 @@
 #include "mbentityview.h"
 #include "log.h"
 #include "musicbrainz_dialog.h"
-#include "mb_search.h"
 
 #define ET_MB_ENTITY_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
                                             ET_MB_ENTITY_VIEW_TYPE, \
@@ -131,6 +130,10 @@ tree_filter_visible_func (GtkTreeModel *model, GtkTreeIter *iter,
                           gpointer data);
 static void
 et_mb_entity_view_finalize (GObject *object);
+static void
+search_in_levels (EtMbEntityView *entity_view, GNode *child,
+                  GtkTreeIter *iter, gboolean is_refresh);
+
 /*************
  * Functions *
  *************/
@@ -334,7 +337,11 @@ add_iter_to_list_store (GtkListStore *list_store, GNode *node)
                         size = mb5_artist_get_name (name_credit_artist, name,
                                                     sizeof (name));
                         g_string_append_len (gstring, name, size);
-                        g_string_append_c (gstring, ' ');
+
+                        if (i + 1 < mb5_namecredit_list_size (name_list))
+                        {
+                            g_string_append_len (gstring, ", ", 2);
+                        }
                     }
                 }
 
@@ -393,7 +400,11 @@ add_iter_to_list_store (GtkListStore *list_store, GNode *node)
                         size = mb5_artist_get_name (name_credit_artist, name,
                                                     sizeof (name));
                         g_string_append_len (artists, name, size);
-                        g_string_append_c (artists, ' ');
+
+                        if (i + 1 < mb5_namecredit_list_size (name_list))
+                        {
+                            g_string_append_len (artists, ", ", 2);
+                        }
                     }
                 }
 
@@ -402,17 +413,41 @@ add_iter_to_list_store (GtkListStore *list_store, GNode *node)
 
                 if (release_list)
                 {
+                    GHashTable *hash_table;
+
+                    hash_table = g_hash_table_new (g_str_hash, g_str_equal);
+
                     for (i = 0; i < mb5_release_list_size (release_list); i++)
                     {
+                        /* Display Release Name if its any other Release of 
+                         * its Release Group hasn't been displayed
+                         */
                         Mb5Release release;
                         int size;
 
                         release = mb5_release_list_item (release_list, i);
-                        size = mb5_release_get_title (release, name,
-                                                      sizeof (name));
+                        size = mb5_releasegroup_get_id (mb5_release_get_releasegroup (release),
+                                                        name, sizeof (name));
+                        name [size] = '\0';
+
+                        if (g_hash_table_contains (hash_table, name))
+                        {
+                            continue;
+                        }
+
+                        g_hash_table_add (hash_table, name);
+                        size = mb5_release_get_title (release,
+                                                      name, sizeof (name));
+
+                        if (!releases->str || *releases->str)
+                        {
+                            g_string_append_len (releases, ", ", 2);
+                        }
+
                         g_string_append_len (releases, name, size);
-                        g_string_append_c (releases, ' ');
                     }
+
+                    g_hash_table_destroy (hash_table);
                 }
 
                 minutes = mb5_recording_get_length ((Mb5Recording)entity)/60000;
@@ -619,32 +654,40 @@ search_in_levels_callback (GObject *source, GAsyncResult *res,
     }
 
     priv->mb_tree_current_node = thread_data->child;
-    children = gtk_container_get_children (GTK_CONTAINER (priv->bread_crumb_box));
-    active_child = g_list_find (children, priv->active_toggle_button);
-    while ((active_child = g_list_next (active_child)))
-    {
-        gtk_container_remove (GTK_CONTAINER (priv->bread_crumb_box),
-                              GTK_WIDGET (active_child->data));
-    }
 
-    toggle_btn = insert_togglebtn_in_breadcrumb (GTK_BOX (priv->bread_crumb_box));
-    children = gtk_container_get_children (GTK_CONTAINER (priv->bread_crumb_box));
-    priv->bread_crumb_nodes [g_list_length (children) - 1] = thread_data->child;
-
-    if (priv->active_toggle_button)
+    if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (priv->list_store), &thread_data->iter))
     {
-        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->active_toggle_button),
-                                      FALSE);
+        /* Only run if iter is valid i.e. it is not a Refresh Option */
+        children = gtk_container_get_children (GTK_CONTAINER (priv->bread_crumb_box));
+        active_child = g_list_find (children, priv->active_toggle_button);
+    
+        while ((active_child = g_list_next (active_child)))
+        {
+            gtk_container_remove (GTK_CONTAINER (priv->bread_crumb_box),
+                                  GTK_WIDGET (active_child->data));
+        }
+    
+        toggle_btn = insert_togglebtn_in_breadcrumb (GTK_BOX (priv->bread_crumb_box));
+        children = gtk_container_get_children (GTK_CONTAINER (priv->bread_crumb_box));
+        priv->bread_crumb_nodes [g_list_length (children) - 1] = thread_data->child;
+    
+        if (priv->active_toggle_button)
+        {
+            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->active_toggle_button),
+                                          FALSE);
+        }
+    
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_btn), TRUE);
+        g_signal_connect (G_OBJECT (toggle_btn), "clicked",
+                          G_CALLBACK (toggle_button_clicked), entity_view);
+        priv->active_toggle_button = toggle_btn;
+    
+        gtk_tree_model_get (priv->list_store, &thread_data->iter, 0, &entity_name,
+                            -1);
+        gtk_button_set_label (GTK_BUTTON (toggle_btn), entity_name);
+        gtk_widget_show_all (GTK_WIDGET (priv->bread_crumb_box));
     }
 
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_btn), TRUE);
-    g_signal_connect (G_OBJECT (toggle_btn), "clicked",
-                      G_CALLBACK (toggle_button_clicked), entity_view);
-    priv->active_toggle_button = toggle_btn;
-    gtk_tree_model_get (priv->list_store, &thread_data->iter, 0, &entity_name,
-                        -1);
-    gtk_button_set_label (GTK_BUTTON (toggle_btn), entity_name);
-    gtk_widget_show_all (GTK_WIDGET (priv->bread_crumb_box));
     ((EtMbEntity *)thread_data->child->data)->is_red_line = TRUE;
     show_data_in_entity_view (entity_view);
 
@@ -766,7 +809,6 @@ static void
 tree_view_row_activated (GtkTreeView *tree_view, GtkTreePath *path,
                          GtkTreeViewColumn *column, gpointer user_data)
 {
-    SearchInLevelThreadData *thread_data;
     EtMbEntityView *entity_view;
     EtMbEntityViewPrivate *priv;
     GNode *child;
@@ -788,20 +830,35 @@ tree_view_row_activated (GtkTreeView *tree_view, GtkTreePath *path,
 
     child = g_node_nth_child (priv->mb_tree_current_node,
                               depth);
+    search_in_levels (ET_MB_ENTITY_VIEW (user_data), child, &filter_iter, FALSE);
+}
+
+static void
+search_in_levels (EtMbEntityView *entity_view, GNode *child,
+                  GtkTreeIter *filter_iter, gboolean is_refresh)
+{
+    SearchInLevelThreadData *thread_data;
+    EtMbEntityViewPrivate *priv;
 
     if (((EtMbEntity *)child->data)->type ==
         MB_ENTITY_KIND_TRACK)
-    {
+    {printf ("sdsd\n");
         return;
     }
 
     thread_data = g_malloc (sizeof (SearchInLevelThreadData));
-    thread_data->entity_view = ET_MB_ENTITY_VIEW (user_data);
+    thread_data->entity_view = entity_view;
     thread_data->child = child;
-    gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (priv->filter),
-                                                      &thread_data->iter,
-                                                      &filter_iter);
-    if (((EtMbEntity *)child->data)->is_red_line)
+    priv = ET_MB_ENTITY_VIEW_GET_PRIVATE (entity_view);
+
+    if (filter_iter)
+    {
+        gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (priv->filter),
+                                                          &thread_data->iter,
+                                                          filter_iter);
+    }
+
+    if (!is_refresh && ((EtMbEntity *)child->data)->is_red_line)
     {
         search_in_levels_callback (NULL, NULL, thread_data);
         return;
@@ -1140,6 +1197,26 @@ et_mb_entity_view_select_down (EtMbEntityView *entity_view)
 void
 et_mb_entity_view_refresh_current_level (EtMbEntityView *entity_view)
 {
+    EtMbEntityViewPrivate *priv;
+    EtMbEntity *et_entity;
+    GNode *child;
+
+    priv = ET_MB_ENTITY_VIEW_GET_PRIVATE (entity_view);
+    et_entity = priv->mb_tree_current_node->data;
+
+    /* Delete Current Data */
+    et_mb_entity_view_clear_all (entity_view);
+    child = g_node_first_child (priv->mb_tree_current_node);
+
+    while (child)
+    {
+        GNode *child1;
+        child1 = g_node_next_sibling (child);
+        free_mb_tree (&child);
+        child = child1;
+    }
+
+    search_in_levels (entity_view, priv->mb_tree_current_node, NULL, TRUE);
 }
 
 void
@@ -1175,4 +1252,44 @@ et_mb_entity_view_finalize (GObject *object)
     g_clear_object (&priv->list_store);
     G_OBJECT_CLASS (et_mb_entity_view_parent_class)->finalize(object);
 }
+
+EtMbEntity *
+et_mb_entity_view_get_selected_entity (EtMbEntityView *entity_view)
+{
+    EtMbEntityViewPrivate *priv;
+    GNode *child;
+    int depth;
+    GtkTreeIter filter_iter;
+    GtkTreeIter iter;
+    GtkTreeSelection *selection;
+    GList* list_sel_rows;
+
+    priv = ET_MB_ENTITY_VIEW_GET_PRIVATE (entity_view);
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view));
+    if (!gtk_tree_selection_count_selected_rows (selection))
+    {
+        return NULL;
+    }
+
+    list_sel_rows = gtk_tree_selection_get_selected_rows (selection, &priv->filter);
+    gtk_tree_model_get_iter (priv->filter,
+                                &filter_iter,
+                                (GtkTreePath *)g_list_first (list_sel_rows)->data);
+    g_list_free_full (list_sel_rows,
+                      (GDestroyNotify)gtk_tree_path_free);
+
+    gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (priv->filter),
+                                                      &iter, &filter_iter);
+    depth = 0;
+
+    while (gtk_tree_model_iter_previous (priv->list_store, &iter))
+    {
+        depth++;
+    }
+
+    child = g_node_nth_child (priv->mb_tree_current_node,
+                              depth);
+
+    return ((EtMbEntity *)child->data);
+}
 #endif /* ENABLE_MUSICBRAINZ */
diff --git a/src/mbentityview.h b/src/mbentityview.h
index 7980061..9a97569 100644
--- a/src/mbentityview.h
+++ b/src/mbentityview.h
@@ -29,6 +29,8 @@ G_BEGIN_DECLS
 
 #include <gtk/gtk.h>
 
+#include "mb_search.h"
+
 #define ET_MB_ENTITY_VIEW_TYPE (et_mb_entity_view_get_type ())
 #define ET_MB_ENTITY_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
                                                              ET_MB_ENTITY_VIEW_TYPE, \
@@ -128,6 +130,8 @@ void
 et_mb_entity_view_select_down (EtMbEntityView *entity_view);
 void
 et_mb_entity_view_clear_all (EtMbEntityView *entity_view);
+EtMbEntity *
+et_mb_entity_view_get_selected_entity (EtMbEntityView *entity_view);
 G_END_DECLS
 
 #endif /* ENABLE_MUSICBRAINZ */
diff --git a/src/musicbrainz_dialog.c b/src/musicbrainz_dialog.c
index c66da87..a7c7f5b 100644
--- a/src/musicbrainz_dialog.c
+++ b/src/musicbrainz_dialog.c
@@ -41,10 +41,29 @@
 static void
 get_first_selected_file (ET_File  **et_file);
 
+typedef enum
+{
+    ET_MB_SEARCH_TYPE_MANUAL,
+} EtMbSearchType;
+
+typedef struct
+{
+    EtMbSearchType type;
+} EtMbSearch;
+
+typedef struct
+{
+    EtMbSearch parent;
+    gchar *to_search;
+    MbEntityKind to_search_type;
+    GNode *parent_node;
+} EtMbManualSearch;
+
 typedef struct
 {
     GNode *mb_tree_root;
     GSimpleAsyncResult *async_result;
+    EtMbSearch *search;
 } MusicBrainzDialogPrivate;
 
 static MusicBrainzDialogPrivate *mb_dialog_priv;
@@ -73,6 +92,27 @@ btn_close_clicked (GtkWidget *button, gpointer data);
  * Functions *
  *************/
 
+static void
+et_musicbrainz_set_search_manual (EtMbSearch **search, gchar *to_search,
+                                  GNode *node, MbEntityKind type)
+{
+    if (*search)
+    {
+        if ((*search)->type == ET_MB_SEARCH_TYPE_MANUAL)
+        {
+            g_free (((EtMbManualSearch *)(*search))->to_search);
+        }
+
+        g_free (*search);
+    }
+
+    *search = g_malloc (sizeof (EtMbManualSearch));
+    ((EtMbManualSearch *)(*search))->to_search = g_strdup (to_search);
+    (*search)->type = ET_MB_SEARCH_TYPE_MANUAL;
+    ((EtMbManualSearch *)(*search))->parent_node = node;
+    ((EtMbManualSearch *)(*search))->to_search_type = type;
+}
+
 /*
  * manual_search_callback:
  * @source: Source Object
@@ -91,8 +131,13 @@ manual_search_callback (GObject *source, GAsyncResult *res,
     {
         g_object_unref (res);
         g_free (user_data);
-        free_mb_tree (mb_dialog_priv->mb_tree_root);
-        mb_dialog_priv->mb_tree_root = g_node_new (NULL);
+
+        if (mb_dialog_priv)
+        {
+            free_mb_tree (&mb_dialog_priv->mb_tree_root);
+            mb_dialog_priv->mb_tree_root = g_node_new (NULL);
+        }
+
         return;
     }
 
@@ -101,18 +146,17 @@ manual_search_callback (GObject *source, GAsyncResult *res,
     gtk_statusbar_push (GTK_STATUSBAR (gtk_builder_get_object (builder,
                         "statusbar")), 0, _("Searching Completed"));
     g_object_unref (res);
-    g_free (user_data);
-
     combo_box = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder,
                                                             "cbManualSearch"));
     gtk_combo_box_text_append_text (combo_box,
                                     gtk_combo_box_text_get_active_text (combo_box));
     et_music_brainz_dialog_stop_set_sensitive (FALSE);
-
-    if (exit_on_complete)
-    {
-        btn_close_clicked (NULL, NULL);
-    }
+    mb_dialog_priv->search = ET_MB_SEARCH_TYPE_MANUAL;
+    et_musicbrainz_set_search_manual (&mb_dialog_priv->search,
+                                      ((ManualSearchThreadData *)user_data)->text_to_search,
+                                      mb_dialog_priv->mb_tree_root,
+                                      ((ManualSearchThreadData *)user_data)->type);
+    g_free (user_data);
 }
 
 /*
@@ -178,7 +222,7 @@ mb5_search_error_callback (GObject *source, GAsyncResult *res,
 
     if (exit_on_complete)
     {
-        btn_close_clicked (NULL, NULL);
+        et_music_brainz_dialog_destroy (mbDialog);
     }
 }
 
@@ -278,7 +322,7 @@ btn_manual_find_clicked (GtkWidget *btn, gpointer user_data)
 
     if (g_node_first_child (mb_dialog_priv->mb_tree_root))
     {
-        free_mb_tree (mb_dialog_priv->mb_tree_root);
+        free_mb_tree (&mb_dialog_priv->mb_tree_root);
         mb_dialog_priv->mb_tree_root = g_node_new (NULL);
     }
 
@@ -388,12 +432,35 @@ tool_btn_unselect_all_clicked (GtkWidget *btn, gpointer user_data)
 static void
 tool_btn_refresh_clicked (GtkWidget *btn, gpointer user_data)
 {
+    if (!mb_dialog_priv->search)
+    {
+        return;
+    }
+
     /* TODO: Implement Refresh Operation */
     if (et_mb_entity_view_get_current_level (ET_MB_ENTITY_VIEW (entityView)) >
         1)
     {
         /* Current level is more than 1, refereshing means downloading an */
         /* entity's children */
+        et_mb_entity_view_refresh_current_level (ET_MB_ENTITY_VIEW (entityView));
+        return;
+    }
+
+    if (mb_dialog_priv->search->type == ET_MB_SEARCH_TYPE_MANUAL)
+    {
+        EtMbManualSearch *manual_search;
+        GtkWidget *entry;
+
+        manual_search = (EtMbManualSearch *)mb_dialog_priv->search;
+        et_mb_entity_view_clear_all (ET_MB_ENTITY_VIEW (entityView));
+        free_mb_tree (&mb_dialog_priv->mb_tree_root);
+        mb_dialog_priv->mb_tree_root = g_node_new (NULL);
+        entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (builder, "cbManualSearch")));
+        gtk_entry_set_text (GTK_ENTRY (entry), manual_search->to_search);
+        gtk_combo_box_set_active (GTK_COMBO_BOX (gtk_builder_get_object (builder, "cbManualSearchIn")),
+                                  manual_search->to_search_type);
+        btn_manual_find_clicked (NULL, NULL);
     }
 }
 
@@ -545,7 +612,7 @@ discid_search_callback (GObject *source, GAsyncResult *res,
     if (!g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res)))
     {
         g_object_unref (res);
-        free_mb_tree (mb_dialog_priv->mb_tree_root);
+        free_mb_tree (&mb_dialog_priv->mb_tree_root);
         mb_dialog_priv->mb_tree_root = g_node_new (NULL);
         return;
     }
@@ -769,24 +836,107 @@ et_music_brainz_dialog_stop_set_sensitive (gboolean sensitive)
                               sensitive);
 }
 
-/* FIXME: Pressing Escape while there is a search gives error */
-static gboolean
-et_music_brainz_dialog_delete_event (GtkWidget *widget, GdkEvent *event,
-                                     gpointer data)
+static void
+btn_apply_changes_clicked (GtkWidget *widget, gpointer data)
 {
-    if (gtk_widget_get_sensitive (GTK_WIDGET (gtk_builder_get_object (builder,
-                                  "btnStop"))))
+    if (mb_dialog_priv->search->type == ET_MB_SEARCH_TYPE_MANUAL)
     {
-        gtk_statusbar_push (GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")),
-                            0,
-                            _("Currently there is a search in progress. Please wait for it to exit."));
-        exit_on_complete = TRUE;
-        btn_manual_stop_clicked (NULL, NULL);
+        ET_File *et_file;
+        EtMbEntity *et_entity;
+
+        et_entity = et_mb_entity_view_get_selected_entity (ET_MB_ENTITY_VIEW (entityView));
+
+        if (!et_entity || et_entity->type != MB_ENTITY_KIND_TRACK)
+        {
+            gtk_statusbar_push (GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")),
+                                0, _("Please select a Track."));
+            return;
+        }
+
+        get_first_selected_file (&et_file);
+
+        if (et_file)
+        {
+            File_Tag *file_tag;
+            gchar string [NAME_MAX_SIZE];
+            int size;
+
+            file_tag = (File_Tag *)et_file->FileTag->data;
+            size = mb5_recording_get_title (et_entity->entity, string,
+                                            sizeof (string));
+            string [size] = '\0';
+            ET_Set_Field_File_Tag_Item (&file_tag->title, string);
+
+            //ET_Set_Field_File_Tag_Item (&file_tag->artist,
+            //ET_Set_Field_File_Tag_Item (&file_tag->album,
+ 
+            /*ET_Set_Field_File_Tag_Item (&file_tag->year,
+
+                if (cddbsettoallfields || cddbsettotrack)
+                {
+                    snprintf (buffer, sizeof (buffer), "%s",
+                              et_track_number_to_string (cddbtrackalbum->track_number));
+
+                    ET_Set_Field_File_Tag_Item(&FileTag->track,buffer);
+                }
+
+                if (cddbsettoallfields || cddbsettotracktotal)
+                {
+                    snprintf (buffer, sizeof (buffer), "%s",
+                              et_track_number_to_string (list_length));
+
+                    ET_Set_Field_File_Tag_Item(&FileTag->track_total,buffer);
+                }
+
+                if ( (cddbsettoallfields || cddbsettogenre) && (cddbtrackalbum->cddbalbum->genre || 
cddbtrackalbum->cddbalbum->category) )
+                {
+                    if (cddbtrackalbum->cddbalbum->genre && g_utf8_strlen(cddbtrackalbum->cddbalbum->genre, 
-1)>0)
+                        
ET_Set_Field_File_Tag_Item(&FileTag->genre,Cddb_Get_Id3_Genre_From_Cddb_Genre(cddbtrackalbum->cddbalbum->genre));
+                    else
+                        
ET_Set_Field_File_Tag_Item(&FileTag->genre,Cddb_Get_Id3_Genre_From_Cddb_Genre(cddbtrackalbum->cddbalbum->category));
+                }
+            }*/
+
+            /*if ( (cddbsettoallfields || cddbsettofilename) )
+            {
+                gchar *filename_generated_utf8;
+                gchar *filename_new_utf8;
+
+                // Allocation of a new FileName
+                FileName = ET_File_Name_Item_New();
+
+                // Build the filename with the path
+                snprintf (buffer, sizeof (buffer), "%s",
+                          et_track_number_to_string (cddbtrackalbum->track_number));
+
+                filename_generated_utf8 = g_strconcat(buffer," - ",cddbtrackalbum->track_name,NULL);
+                ET_File_Name_Convert_Character(filename_generated_utf8); // Replace invalid characters
+                filename_new_utf8 = ET_File_Name_Generate(*etfile,filename_generated_utf8);
+
+                ET_Set_Filename_File_Name_Item(FileName,filename_new_utf8,NULL);
+
+                g_free(filename_generated_utf8);
+                g_free(filename_new_utf8);
+            }
+
+            ET_Manage_Changes_Of_File_Data(*etfile,FileName,FileTag);
 
-        return TRUE;
+            // Then run current scanner if asked...
+            if (ScannerWindow && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(CddbRunScanner)) )
+                Scan_Select_Mode_And_Run_Scanner(*etfile);*/
+
+        }
     }
+}
 
-     return FALSE;
+void
+et_music_brainz_dialog_destroy (GtkWidget *widget)
+{
+    gtk_widget_destroy (widget);
+    g_object_unref (G_OBJECT (builder));
+    free_mb_tree (&mb_dialog_priv->mb_tree_root);
+    g_free (mb_dialog_priv);
+    mb_dialog_priv = NULL;
 }
 
 /*
@@ -819,6 +969,7 @@ et_open_musicbrainz_dialog ()
 
     mb_dialog_priv = g_malloc (sizeof (MusicBrainzDialogPrivate));
     mb_dialog_priv->mb_tree_root = g_node_new (NULL);
+    mb_dialog_priv->search = NULL;
     exit_on_complete = FALSE;
     entityView = et_mb_entity_view_new ();
     mbDialog = GTK_WIDGET (gtk_builder_get_object (builder, "mbDialog"));
@@ -826,7 +977,6 @@ et_open_musicbrainz_dialog ()
     gtk_box_pack_start (GTK_BOX (gtk_builder_get_object (builder, "centralBox")),
                         entityView, TRUE, TRUE, 2);
 
-    //g_signal_connect (mbDialog, "delete-event", G_CALLBACK (et_music_brainz_dialog_delete_event), NULL);
     cb_search = GTK_WIDGET (gtk_builder_get_object (builder, "cbManualSearch"));
     g_signal_connect (gtk_bin_get_child (GTK_BIN (cb_search)), "activate",
                       G_CALLBACK (btn_manual_find_clicked), NULL);
@@ -866,6 +1016,10 @@ et_open_musicbrainz_dialog ()
     g_signal_connect (gtk_builder_get_object (builder, "btnClose"),
                       "clicked", G_CALLBACK (btn_close_clicked),
                       NULL);
+    g_signal_connect (gtk_builder_get_object (builder, "btnApplyChanges"),
+                      "clicked", G_CALLBACK (btn_apply_changes_clicked),
+                      NULL);
+ 
     //g_signal_connect (gtk_builder_get_object (builder, "btnAutomaticSearch"),
     //                  "clicked", G_CALLBACK (btn_automatic_search_clicked),
     //                  NULL);
@@ -895,9 +1049,17 @@ et_open_musicbrainz_dialog ()
 
     gtk_widget_show_all (mbDialog);
     gtk_dialog_run (GTK_DIALOG (mbDialog));
-    gtk_widget_destroy (mbDialog);
-    g_object_unref (G_OBJECT (builder));
-    free_mb_tree (mb_dialog_priv->mb_tree_root);
-    g_free (mb_dialog_priv);
+
+    if (gtk_widget_get_sensitive (GTK_WIDGET (gtk_builder_get_object (builder,
+                                  "btnStop"))))
+    {
+        exit_on_complete = TRUE;
+        btn_manual_stop_clicked (NULL, NULL);
+        gtk_widget_hide (mbDialog);
+    }
+    else
+    {
+        et_music_brainz_dialog_destroy (mbDialog);
+    }
 }
 #endif /* ENABLE_MUSICBRAINZ */
diff --git a/src/musicbrainz_dialog.h b/src/musicbrainz_dialog.h
index 342d203..1b2503c 100644
--- a/src/musicbrainz_dialog.h
+++ b/src/musicbrainz_dialog.h
@@ -47,5 +47,7 @@ void
 et_show_status_msg_in_idle (gchar *message);
 void
 et_music_brainz_dialog_stop_set_sensitive (gboolean sensitive);
+void
+et_music_brainz_dialog_destroy (GtkWidget *widget);
 #endif /* __MUSICBRAINZ_DIALOG_H__ */
 #endif /* ENABLE_MUSICBRAINZ */



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