From a2113dc378fccdc33ecd21ed035b616fb1ae6a37 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Thu, 25 Aug 2016 14:40:45 -0400 Subject: [PATCH] gui/sidebar: Add a function for inserting a playlist in sorted order Signed-off-by: Anna Schumaker --- gui/collection.c | 16 ++++++--- gui/playlist.c | 82 ++++++------------------------------------ gui/sidebar.c | 49 +++++++++++++++++++------ include/gui/playlist.h | 4 +-- include/gui/sidebar.h | 4 +++ tests/gui/sidebar.c | 19 ++++++++++ 6 files changed, 86 insertions(+), 88 deletions(-) diff --git a/gui/collection.c b/gui/collection.c index ec30db6d..9c3cad55 100644 --- a/gui/collection.c +++ b/gui/collection.c @@ -11,9 +11,14 @@ static void __collection_add(GtkFileChooser *chooser) { gchar *filename = gtk_file_chooser_get_filename(chooser); + struct playlist *playlist; + struct library *library; - if (playlist_new(PL_LIBRARY, filename)) - gui_playlist_add_library(library_lookup(filename)); + if (playlist_new(PL_LIBRARY, filename)) { + library = library_lookup(filename); + playlist = playlist_get(PL_LIBRARY, library->li_path); + gui_playlist_add_library(playlist); + } gui_idle_enable(); g_free(filename); @@ -52,9 +57,12 @@ void __collection_choose(GtkButton *button, gpointer data) bool __gui_collection_init_idle() { struct db_entry *library, *next; + struct playlist *playlist; - db_for_each(library, next, library_db_get()) - gui_playlist_add_library(LIBRARY(library)); + db_for_each(library, next, library_db_get()) { + playlist = playlist_get(PL_LIBRARY, LIBRARY(library)->li_path); + gui_playlist_add_library(playlist); + } if (library_db_get()->db_size == 0) __collection_choose(NULL, NULL); diff --git a/gui/playlist.c b/gui/playlist.c index a7480804..ab66c672 100644 --- a/gui/playlist.c +++ b/gui/playlist.c @@ -28,14 +28,6 @@ static inline void __playlist_filter_get_iter(GtkTreeIter *iter, GtkTreeIter *ch child, iter); } -static void __playlist_set(GtkTreeIter *iter, const gchar *name, - const gchar *image, enum playlist_type_t type) -{ - gtk_tree_store_set(gui_sidebar_store(), iter, P_SB_NAME, name, - P_SB_IMAGE, image, - P_SB_TYPE, type, -1); -} - static void __playlist_set_size(GtkTreeIter *iter, const gchar *name) { enum playlist_type_t type = gui_sidebar_iter_type(iter); @@ -52,15 +44,6 @@ static void __playlist_set_size(GtkTreeIter *iter, const gchar *name) g_free(text); } -static void __playlist_add(GtkTreeIter *parent, const gchar *name, - const gchar *image, enum playlist_type_t type) -{ - GtkTreeIter iter; - gtk_tree_store_insert(gui_sidebar_store(), &iter, parent, -1); - __playlist_set(&iter, name, image, type); - __playlist_set_size(&iter, name); -} - void __playlist_selection_changed(GtkTreeSelection *selection, gpointer data) { GtkTreeModel *model = gui_sidebar_model(); @@ -215,7 +198,7 @@ static void *__playlist_init(struct queue *queue, void *data) flags = GQ_CAN_RANDOM; if (p_init_done && playlist->pl_type == PL_ARTIST) { p_filter_enable = false; - gui_playlist_add_artist(artist_find(playlist->pl_name)); + gui_playlist_add_artist(playlist); p_filter_enable = true; } if (p_init_done && playlist->pl_type == PL_USER) @@ -294,7 +277,7 @@ bool __gui_playlist_init_idle() gtk_tree_view_expand_all(treeview); db_for_each(dbe, next, artist_db_get()) - gui_playlist_add_artist(ARTIST(dbe)); + gui_playlist_add_artist(ARTIST(dbe)->ar_playlist); p_filter_enable = true; p_init_done = true; @@ -349,74 +332,31 @@ gchar *gui_playlist_cur() return p_name; } -void gui_playlist_add_library(struct library *library) +void gui_playlist_add_library(struct playlist *playlist) { GtkTreeIter parent; + gui_sidebar_iter_first(&parent); - if (gui_sidebar_iter_find(&parent, "Library", PL_MAX_TYPE)) - __playlist_add(&parent, library->li_path, "folder", PL_LIBRARY); - gtk_tree_view_expand_all(gui_sidebar_treeview()); + gui_sidebar_iter_find(&parent, "Library", PL_MAX_TYPE); + gui_sidebar_iter_sort_child(&parent, playlist, "folder"); } -void gui_playlist_add_artist(struct artist *artist) +void gui_playlist_add_artist(struct playlist *playlist) { - GtkTreeIter parent, sibling, iter; - gchar *name; - bool match; + GtkTreeIter parent; gui_sidebar_iter_first(&parent); gui_sidebar_iter_find(&parent, "Collection", PL_SYSTEM); - - if (!gtk_tree_model_iter_children(gui_sidebar_model(), &sibling, &parent)) { - __playlist_add(&parent, artist->ar_name, "system-users", PL_ARTIST); - return; - } - - do { - name = gui_sidebar_iter_name(&parent); - match = g_utf8_collate(name, artist->ar_name) >= 0; - g_free(name); - - if (match) { - gtk_tree_store_insert_before(gui_sidebar_store(), &iter, &parent, &sibling); - __playlist_set(&iter, artist->ar_name, "system-users", PL_ARTIST); - __playlist_set_size(&iter, artist->ar_name); - return; - } - } while (gtk_tree_model_iter_next(gui_sidebar_model(), &sibling)); - - __playlist_add(&parent, artist->ar_name, "system-users", PL_ARTIST); + gui_sidebar_iter_sort_child(&parent, playlist, "system-users"); } void gui_playlist_add_user(struct playlist *playlist) { - GtkTreeIter parent, sibling, iter; - gchar *name; - bool match; + GtkTreeIter parent; gui_sidebar_iter_first(&parent); gui_sidebar_iter_find(&parent, "Playlists", PL_MAX_TYPE); - - if (!gtk_tree_model_iter_children(gui_sidebar_model(), &sibling, &parent)) { - __playlist_add(&parent, playlist->pl_name, "text-x-generic", PL_USER); - return; - } - - do { - name = gui_sidebar_iter_name(&parent); - match = g_utf8_collate(name, playlist->pl_name) >= 0; - match = match && !(gui_sidebar_iter_type(&sibling) == PL_SYSTEM); - g_free(name); - - if (match) { - gtk_tree_store_insert_before(gui_sidebar_store(), &iter, &parent, &sibling); - __playlist_set(&iter, playlist->pl_name, "text-x-generic", PL_USER); - __playlist_set_size(&iter, playlist->pl_name); - return; - } - } while (gtk_tree_model_iter_next(gui_sidebar_model(), &sibling)); - - __playlist_add(&parent, playlist->pl_name, "text-x-generic", PL_USER); + gui_sidebar_iter_sort_child(&parent, playlist, "text-x-generic"); } struct queue_ops playlist_ops = { diff --git a/gui/sidebar.c b/gui/sidebar.c index c6c74be6..1b95951b 100644 --- a/gui/sidebar.c +++ b/gui/sidebar.c @@ -58,6 +58,21 @@ static void __gui_sidebar_add_header(GtkTreeIter *iter, const gchar *name, g_free(formatted); } +static int __gui_sidebar_compare(GtkTreeIter *iter, const gchar *name, + enum playlist_type_t type) +{ + gchar *cur; + int ret; + + if (gui_sidebar_iter_type(iter) != type) + return gui_sidebar_iter_type(iter) - type; + + cur = gui_sidebar_iter_name(iter); + ret = g_utf8_collate(cur, name); + g_free(cur); + + return ret; +} void __gui_sidebar_resized(GtkPaned *pane, GParamSpec *pspec, gpointer data) { @@ -129,6 +144,28 @@ void gui_sidebar_iter_add(GtkTreeIter *iter, struct playlist *playlist, __gui_sidebar_set_playlist(&new, playlist, image); } +void gui_sidebar_iter_sort_child(GtkTreeIter *iter, struct playlist *playlist, + const gchar *image) +{ + GtkTreeIter child, new; + + if (!gui_sidebar_iter_down(iter, &child)) + goto out_append; + + do { + if (__gui_sidebar_compare(&child, playlist->pl_name, + playlist->pl_type) >= 0) { + gtk_tree_store_insert_before(gui_sidebar_store(), + &new, iter, &child); + __gui_sidebar_set_playlist(&new, playlist, image); + return; + } + } while (gui_sidebar_iter_next(&child)); + +out_append: + gui_sidebar_iter_append_child(iter, playlist, image); +} + void gui_sidebar_iter_append_child(GtkTreeIter *iter, struct playlist *playlist, const gchar *image) { @@ -140,18 +177,8 @@ void gui_sidebar_iter_append_child(GtkTreeIter *iter, struct playlist *playlist, gboolean gui_sidebar_iter_find(GtkTreeIter *iter, const gchar *name, enum playlist_type_t type) { - bool match; - gchar *cur; - do { - if (gui_sidebar_iter_type(iter) != type) - continue; - - cur = gui_sidebar_iter_name(iter); - match = string_match(cur, name); - g_free(cur); - - if (match) + if (__gui_sidebar_compare(iter, name, type) == 0) return TRUE; } while (gui_sidebar_iter_next(iter)); diff --git a/include/gui/playlist.h b/include/gui/playlist.h index 20368d77..487974e9 100644 --- a/include/gui/playlist.h +++ b/include/gui/playlist.h @@ -13,10 +13,10 @@ void gui_playlist_init(); gchar *gui_playlist_cur(); /* Called to add a library playlist. */ -void gui_playlist_add_library(struct library *); +void gui_playlist_add_library(struct playlist *); /* Called to add an artist playlist. */ -void gui_playlist_add_artist(struct artist *); +void gui_playlist_add_artist(struct playlist *); /* Called to add a user playlist. */ void gui_playlist_add_user(struct playlist *); diff --git a/include/gui/sidebar.h b/include/gui/sidebar.h index 36d9a042..835c9ff6 100644 --- a/include/gui/sidebar.h +++ b/include/gui/sidebar.h @@ -30,6 +30,10 @@ enum playlist_type_t gui_sidebar_iter_type(GtkTreeIter *); /* Called to add a playlist at the current iterator. */ void gui_sidebar_iter_add(GtkTreeIter *, struct playlist *, const gchar *); +/* Called to add a child playlist to the current iterator in sorted order. */ +void gui_sidebar_iter_sort_child(GtkTreeIter *, struct playlist *, + const gchar *); + /* Called to append a child playlist to the current iterator. */ void gui_sidebar_iter_append_child(GtkTreeIter *, struct playlist *, const gchar *); diff --git a/tests/gui/sidebar.c b/tests/gui/sidebar.c index 64eb81b8..9e299e89 100644 --- a/tests/gui/sidebar.c +++ b/tests/gui/sidebar.c @@ -11,6 +11,7 @@ const gchar *test_pl_names[8] = { "Collection", "", "Playlists", "", "Dynamic", "", "Library" }; +const gchar *test_dyn_names[3] = { "Least Played", "Most Played", "Unplayed" }; struct core_init_data init_data; static void test_sidebar() @@ -70,6 +71,24 @@ static void test_sidebar() g_assert_true(gui_sidebar_iter_find(&iter, "History", PL_SYSTEM)); g_assert_cmpstr_free(gui_sidebar_iter_name(&iter), ==, "History"); g_assert_cmpuint(gui_sidebar_iter_type(&iter), ==, PL_SYSTEM); + + g_assert_true(gui_sidebar_iter_find(&iter, "Dynamic", PL_MAX_TYPE)); + g_assert_false(gui_sidebar_iter_down(&iter, &child)); + gui_sidebar_iter_sort_child(&iter, playlist_get(PL_SYSTEM, "Most Played"), + NULL); + gui_sidebar_iter_sort_child(&iter, playlist_get(PL_SYSTEM, "Least Played"), + NULL); + gui_sidebar_iter_sort_child(&iter, playlist_get(PL_SYSTEM, "Unplayed"), + NULL); + g_assert_true(gui_sidebar_iter_down(&iter, &child)); + + g_assert_true(gui_sidebar_iter_down(&iter, &child)); + for (i = 0; i < 3; i++) { + g_assert_cmpstr_free(gui_sidebar_iter_name(&child), ==, + test_dyn_names[i]); + g_assert_cmpuint(gui_sidebar_iter_type(&child), ==, PL_SYSTEM); + gui_sidebar_iter_next(&child); + } } static void test_sidebar_pos()