diff --git a/gui/playlist.c b/gui/playlist.c index 1f99f54b..ca89fe5c 100644 --- a/gui/playlist.c +++ b/gui/playlist.c @@ -24,12 +24,18 @@ static void __playlist_set(GtkTreeIter *iter, const gchar *name, static void __playlist_set_size(GtkTreeIter *iter, const gchar *name) { + GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(p_store), iter); unsigned int size = playlist_size(name); const gchar *fmt = "%s\n%d track%s"; gchar *text; + if (gtk_tree_path_get_depth(path) == 1) + fmt = "%s\n%d track%s"; + text = g_strdup_printf(fmt, name, size, (size == 1) ? "" : "s"); gtk_tree_store_set(p_store, iter, P_SB_NAME, text, -1); + + gtk_tree_path_free(path); g_free(text); } @@ -45,13 +51,19 @@ static void __playlist_add(GtkTreeIter *parent, const gchar *name, static gchar *__playlist_name(GtkTreeIter *iter) { GtkTreeModel *model = GTK_TREE_MODEL(p_store); - gchar **split, *name; + gchar **split, *text, *name; - gtk_tree_model_get(model, iter, P_SB_NAME, &name, -1); - split = g_strsplit(name, "\n", 2); - name = g_strdup(split[0]); + gtk_tree_model_get(model, iter, P_SB_NAME, &text, -1); + if (!text) + return NULL; + split = g_strsplit(text, "\n", 2); + text = g_strdup(split[0]); g_strfreev(split); + + pango_parse_markup(text, -1, 0, NULL, &name, NULL, NULL); + g_free(text); + return name; } @@ -72,30 +84,62 @@ void __playlist_selection_changed(GtkTreeSelection *selection, gpointer data) } } +gboolean __playlist_on_select(GtkTreeSelection *selection, GtkTreeModel *model, + GtkTreePath *path, gboolean selected, gpointer data) +{ + struct queue *queue = NULL; + GtkTreeIter iter; + gchar *name; + + gtk_tree_model_get_iter(model, &iter, path); + + name = __playlist_name(&iter); + queue = playlist_get_queue(name); + g_free(name); + + return queue != NULL; +} + +static bool __playlist_queue_set_size(struct queue *queue, GtkTreeIter *iter) +{ + gchar *name = __playlist_name(iter); + bool match = string_match(name, gui_queue(queue)->gq_text); + + if (match) + __playlist_set_size(iter, name); + g_free(name); + + return match; +} + static void __playlist_update_sizes(struct queue *queue) { GtkTreeModel *model = GTK_TREE_MODEL(p_store); GtkTreeIter parent, iter; - gchar *name; if (!gtk_tree_model_get_iter_first(model, &parent)) return; - gtk_tree_model_iter_next(model, &parent); - if (!gtk_tree_model_iter_children(model, &iter, &parent)) - return; do { - name = __playlist_name(&iter); - if (string_match(name, gui_queue(queue)->gq_text)) - __playlist_set_size(&iter, name); - g_free(name); - } while (gtk_tree_model_iter_next(model, &iter)); + if (__playlist_queue_set_size(queue, &parent)) + return; + if (gtk_tree_model_iter_children(model, &iter, &parent)) { + do { + if (__playlist_queue_set_size(queue, &iter)) + return; + } while (gtk_tree_model_iter_next(model, &iter)); + } + } while (gtk_tree_model_iter_next(model, &parent)); } static void *__playlist_init(struct queue *queue, void *data) { struct playlist *playlist = (struct playlist *)data; - return gui_queue_alloc(queue, playlist->pl_name, 0); + unsigned int flags = 0; + + if (string_match(playlist->pl_name, "Collection")) + flags = GQ_CAN_RANDOM; + return gui_queue_alloc(queue, playlist->pl_name, flags); } static void __playlist_added(struct queue *queue, unsigned int row) @@ -112,10 +156,10 @@ static void __playlist_removed(struct queue *queue, unsigned int row) static bool __playlist_erase(struct queue *queue, struct track *track) { - /* collection_unban() and playlist_remove() handle queue changes */ - if (string_match(gui_playlist_cur(), "Hidden")) - collection_unban(track); - else + if (string_match(gui_playlist_cur(), "Collection")) + playlist_add("Hidden", track); + else if (string_match(gui_playlist_cur(), "Favorites") || + string_match(gui_playlist_cur(), "Hidden")) playlist_remove(gui_playlist_cur(), track); return false; } @@ -127,6 +171,14 @@ void gui_playlist_init() p_store = GTK_TREE_STORE(gui_builder_object("o_playlist_store")); + gtk_tree_store_insert(p_store, &parent, NULL, -1); + __playlist_set(&parent, "Collection", "media-optical"); + __playlist_set_size(&parent, "Collection"); + + gtk_tree_store_insert(p_store, &parent, NULL, -1); + __playlist_set(&parent, "History", "document-open-recent"); + __playlist_set_size(&parent, "History"); + /* Add "Playlist" header. */ gtk_tree_store_insert(p_store, &parent, NULL, -1); gtk_tree_store_insert(p_store, &parent, NULL, -1); @@ -143,7 +195,7 @@ void gui_playlist_init() gtk_tree_view_expand_all(treeview); gtk_tree_selection_set_select_function( gtk_tree_view_get_selection(treeview), - gui_sidebar_on_select, NULL, NULL); + __playlist_on_select, NULL, NULL); gtk_tree_store_insert(p_store, &parent, NULL, -1); } diff --git a/tests/gui/playlist.c b/tests/gui/playlist.c index afd29c72..b29bf8f6 100644 --- a/tests/gui/playlist.c +++ b/tests/gui/playlist.c @@ -29,31 +29,48 @@ static void test_playlist_sidebar() model = GTK_TREE_MODEL(gui_builder_object("o_playlist_store")); test_equal(gtk_tree_model_get_iter_first(model, &iter), true); - test_equal(gtk_tree_model_iter_next(model, &iter), true); - test_equal(gtk_tree_model_iter_n_children(model, &iter), 5); - path = gtk_tree_model_get_path(model, &iter); gtk_tree_selection_select_path(selection, path); + test_equal(gtk_tree_selection_count_selected_rows(selection), 1); + test_equal(gui_playlist_cur(), "Collection"); + + gtk_tree_path_next(path); + gtk_tree_selection_select_path(selection, path); + test_equal(gtk_tree_selection_count_selected_rows(selection), 1); + gtk_tree_selection_unselect_all(selection); + test_equal(gui_playlist_cur(), "History"); + + gtk_tree_path_next(path); + gtk_tree_selection_select_path(selection, path); + test_equal(gtk_tree_selection_count_selected_rows(selection), 0); + + gtk_tree_path_next(path); + gtk_tree_selection_select_path(selection, path); test_equal(gtk_tree_selection_count_selected_rows(selection), 0); gtk_tree_path_down(path); gtk_tree_selection_select_path(selection, path); + test_equal(gtk_tree_selection_count_selected_rows(selection), 1); test_equal(gui_playlist_cur(), "Favorites"); gtk_tree_path_next(path); gtk_tree_selection_select_path(selection, path); + test_equal(gtk_tree_selection_count_selected_rows(selection), 1); test_equal(gui_playlist_cur(), "Hidden"); gtk_tree_path_next(path); gtk_tree_selection_select_path(selection, path); + test_equal(gtk_tree_selection_count_selected_rows(selection), 1); test_equal(gui_playlist_cur(), "Most Played"); gtk_tree_path_next(path); gtk_tree_selection_select_path(selection, path); + test_equal(gtk_tree_selection_count_selected_rows(selection), 1); test_equal(gui_playlist_cur(), "Least Played"); gtk_tree_path_next(path); gtk_tree_selection_select_path(selection, path); + test_equal(gtk_tree_selection_count_selected_rows(selection), 1); test_equal(gui_playlist_cur(), "Unplayed"); gtk_tree_path_free(path);