From ad3e56250ed3e3562bc27670315aca6c94f65c46 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Thu, 1 Sep 2016 09:22:59 -0400 Subject: [PATCH] gui/playlists/user: Split into a new file and add a unit test Signed-off-by: Anna Schumaker --- gui/playlist.c | 35 ++---------- gui/playlists/user.c | 90 ++++++++++++++++++++++++++++++ gui/view.c | 35 ++---------- include/gui/playlist.h | 4 +- include/gui/playlists/user.h | 19 +++++++ tests/gui/playlist.c | 2 +- tests/gui/playlists/.gitignore | 1 + tests/gui/playlists/CMakeLists.txt | 1 + tests/gui/playlists/user.c | 77 +++++++++++++++++++++++++ 9 files changed, 201 insertions(+), 63 deletions(-) create mode 100644 gui/playlists/user.c create mode 100644 include/gui/playlists/user.h create mode 100644 tests/gui/playlists/user.c diff --git a/gui/playlist.c b/gui/playlist.c index 2397017e..dcf6b7cf 100644 --- a/gui/playlist.c +++ b/gui/playlist.c @@ -10,9 +10,6 @@ #include #include -static bool p_filter_enable = true; -static bool p_init_done = false; - static void __playlist_update_sizes(struct queue *); void __playlist_row_activated(GtkTreeView *treeview, GtkTreePath *path, @@ -49,6 +46,9 @@ static void __playlist_update_sizes(struct queue *queue) } else if (playlist->pl_type == PL_ARTIST) { gui_pl_artist_update(playlist); return; + } else if (playlist->pl_type == PL_USER) { + gui_pl_user_update(playlist); + return; } if (!gui_sidebar_iter_first(&parent)) @@ -74,10 +74,8 @@ static void *__playlist_init(struct queue *queue, void *data) { struct playlist *playlist = (struct playlist *)data; - if (p_init_done && playlist->pl_type == PL_ARTIST) + if (playlist->pl_type == PL_ARTIST) gui_pl_artist_add(playlist); - if (p_init_done && playlist->pl_type == PL_USER) - gui_playlist_add_user(playlist); return playlist; } @@ -134,28 +132,15 @@ static bool __playlist_erase(struct queue *queue, struct track *track) bool __gui_playlist_init_idle() { - struct db_entry *dbe, *next; GtkTreeSelection *selection; - GtkTreeView *treeview; GtkTreeModel *filter; GtkTreeIter iter; filter = GTK_TREE_MODEL(gui_sidebar_filter()); - treeview = gui_sidebar_treeview(); - selection = gtk_tree_view_get_selection(treeview); + selection = gtk_tree_view_get_selection(gui_sidebar_treeview()); gtk_tree_model_get_iter_first(filter, &iter); gtk_tree_selection_select_iter(selection, &iter); - p_filter_enable = false; - db_for_each(dbe, next, pl_user_db_get()) - gui_playlist_add_user(&USER_PLAYLIST(dbe)->pl_playlist); - gtk_tree_view_expand_all(treeview); - - db_for_each(dbe, next, artist_db_get()) - gui_pl_artist_add(ARTIST(dbe)->ar_playlist); - p_filter_enable = true; - - p_init_done = true; return true; } @@ -190,6 +175,7 @@ void gui_playlist_init() idle_schedule(IDLE_SYNC, __gui_playlist_init_idle, NULL); gui_pl_artist_init(); + gui_pl_user_init(); gui_pl_library_init(); } @@ -200,15 +186,6 @@ const gchar *gui_playlist_cur() return NULL; } -void gui_playlist_add_user(struct playlist *playlist) -{ - GtkTreeIter parent; - - gui_sidebar_iter_first(&parent); - gui_sidebar_iter_find(&parent, "Playlists", PL_MAX_TYPE); - gui_sidebar_iter_sort_child(&parent, playlist, "text-x-generic"); -} - struct queue_ops playlist_ops = { .qop_init = __playlist_init, .qop_deinit = __playlist_deinit, diff --git a/gui/playlists/user.c b/gui/playlists/user.c new file mode 100644 index 00000000..1a897f13 --- /dev/null +++ b/gui/playlists/user.c @@ -0,0 +1,90 @@ +/* + * Copyright 2016 (c) Anna Schumaker. + */ +#include +#include +#include +#include +#include + +static bool __gui_pl_user_header(GtkTreeIter *iter) +{ + if (gui_sidebar_iter_first(iter)) + return gui_sidebar_iter_find(iter, "Playlists", PL_MAX_TYPE); + return false; +} + +static bool __gui_pl_user_init_idle() +{ + struct db_entry *user, *next; + struct playlist *playlist; + GtkTreeIter iter; + + if (!__gui_pl_user_header(&iter)) + return false; + + db_for_each(user, next, pl_user_db_get()) { + playlist = &USER_PLAYLIST(user)->pl_playlist; + gui_sidebar_iter_sort_child(&iter, playlist, "text-x-generic"); + } + + return true; +} + +void gui_pl_user_init() +{ + idle_schedule(IDLE_SYNC, __gui_pl_user_init_idle, NULL); +} + +struct playlist *gui_pl_user_add(const gchar *name) +{ + struct playlist *playlist; + GtkTreeIter iter; + + if (!__gui_pl_user_header(&iter)) + return NULL; + if (!playlist_new(PL_USER, name)) + return NULL; + + playlist = playlist_get(PL_USER, name); + gui_sidebar_iter_sort_child(&iter, playlist, "text-x-generic"); + return playlist; +} + +struct playlist *gui_pl_user_add_dialog(void) +{ + unsigned int flags = GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL; + GtkWidget *entry, *dialog, *content; + struct playlist *playlist = NULL; + + entry = gtk_entry_new(); + dialog = gtk_dialog_new_with_buttons("New Playlist Name?", + gui_window(), flags, + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_OK"), GTK_RESPONSE_ACCEPT, + NULL); + content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); + gtk_entry_set_activates_default(GTK_ENTRY(entry), true); + gtk_container_add(GTK_CONTAINER(content), entry); + gtk_widget_show_all(dialog); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) + playlist = gui_pl_user_add(gtk_entry_get_text(GTK_ENTRY(entry))); + gtk_widget_destroy(dialog); + + return playlist; +} + +void gui_pl_user_update(struct playlist *playlist) +{ + GtkTreeIter iter, child; + + if (!__gui_pl_user_header(&iter)) + return; + if (!gui_sidebar_iter_down(&iter, &child)) + return; + if (gui_sidebar_iter_find(&child, playlist->pl_name, playlist->pl_type)) + gui_sidebar_iter_update(&child); +} diff --git a/gui/view.c b/gui/view.c index 3d97c7a8..3ca83e63 100644 --- a/gui/view.c +++ b/gui/view.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -42,36 +43,11 @@ static void __view_delete_selection(GtkTreeSelection *selection) g_list_free_full(rows, (GDestroyNotify) gtk_tree_path_free); } -static gchar *__view_get_new_playlist_name(void) -{ - unsigned int flags = GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL; - GtkWidget *entry, *dialog, *content; - gchar *text = NULL; - - entry = gtk_entry_new(); - dialog = gtk_dialog_new_with_buttons("New Playlist Name?", - gui_window(), flags, - _("_Cancel"), GTK_RESPONSE_CANCEL, - _("_OK"), GTK_RESPONSE_ACCEPT, - NULL); - content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); - gtk_entry_set_activates_default(GTK_ENTRY(entry), true); - gtk_container_add(GTK_CONTAINER(content), entry); - gtk_widget_show_all(dialog); - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) - text = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry))); - gtk_widget_destroy(dialog); - - return text; -} - static void __view_process_selection(GtkTreeView *treeview, unsigned int keyval) { GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview); struct view_add_data vad_data; - gchar *text = NULL; + struct playlist *playlist; switch (keyval) { case GDK_KEY_f: @@ -82,15 +58,14 @@ static void __view_process_selection(GtkTreeView *treeview, unsigned int keyval) &vad_data); break; case GDK_KEY_p: - text = __view_get_new_playlist_name(); - if (!text || !playlist_new(PL_USER, text)) + playlist = gui_pl_user_add_dialog(); + if (!playlist) break; vad_data.vad_type = PL_USER; - vad_data.vad_name = text; + vad_data.vad_name = playlist->pl_name; gtk_tree_selection_selected_foreach(selection, __view_add_to_playlist, &vad_data); - g_free(text); break; case GDK_KEY_q: vad_data.vad_type = PL_SYSTEM; diff --git a/include/gui/playlist.h b/include/gui/playlist.h index 0e0ce663..fa834d84 100644 --- a/include/gui/playlist.h +++ b/include/gui/playlist.h @@ -6,6 +6,7 @@ #include #include #include +#include /* Called to initialize the GUI playlist code. */ void gui_playlist_init(); @@ -13,9 +14,6 @@ void gui_playlist_init(); /* Called to get the currently selected playlist. */ const gchar *gui_playlist_cur(); -/* Called to add a user playlist. */ -void gui_playlist_add_user(struct playlist *); - /* Playlist operations passed to core_init() */ extern struct queue_ops playlist_ops; diff --git a/include/gui/playlists/user.h b/include/gui/playlists/user.h new file mode 100644 index 00000000..2d2085a0 --- /dev/null +++ b/include/gui/playlists/user.h @@ -0,0 +1,19 @@ +/* + * Copyright 2015 (c) Anna Schumaker. + */ +#ifndef OCARINA_GUI_PLAYLISTS_USER_H +#define OCARINA_GUI_PLAYLISTS_USER_H + +/* Called to initialize GUI user playlists. */ +void gui_pl_user_init(); + +/* Called to add a user playlist. */ +struct playlist *gui_pl_user_add(const gchar *); + +/* Called to add a user playlist (with dialog prompt). */ +struct playlist *gui_pl_user_add_dialog(void); + +/* Called to update a user playlist. */ +void gui_pl_user_update(struct playlist *); + +#endif /* OCARINA_GUI_PLAYLISTS_USER_H */ diff --git a/tests/gui/playlist.c b/tests/gui/playlist.c index b70591d6..27db0977 100644 --- a/tests/gui/playlist.c +++ b/tests/gui/playlist.c @@ -36,7 +36,7 @@ static void test_playlist_sidebar() playlist_add(PL_SYSTEM, "Favorites", track_get(0)); playlist_add(PL_SYSTEM, "Hidden", track_get(1)); - playlist_new(PL_USER, "Test"); + gui_pl_user_add("Test"); playlist_add(PL_USER, "Test", track_get(0)); gtk_tree_model_filter_refilter(gui_sidebar_filter()); gtk_tree_view_expand_all(treeview); diff --git a/tests/gui/playlists/.gitignore b/tests/gui/playlists/.gitignore index 672f7a25..508a7eb4 100644 --- a/tests/gui/playlists/.gitignore +++ b/tests/gui/playlists/.gitignore @@ -1,2 +1,3 @@ artist +user library diff --git a/tests/gui/playlists/CMakeLists.txt b/tests/gui/playlists/CMakeLists.txt index 1bbe485c..8ea70e49 100644 --- a/tests/gui/playlists/CMakeLists.txt +++ b/tests/gui/playlists/CMakeLists.txt @@ -5,4 +5,5 @@ function(gui_playlist_unit_test name) endfunction() gui_playlist_unit_test(Artist) +gui_playlist_unit_test(User) gui_playlist_unit_test(Library) diff --git a/tests/gui/playlists/user.c b/tests/gui/playlists/user.c new file mode 100644 index 00000000..6820daad --- /dev/null +++ b/tests/gui/playlists/user.c @@ -0,0 +1,77 @@ +/* + * Copyright 2016 (c) Anna Schumaker. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct core_init_data init_data = { + .playlist_ops = &playlist_ops, +}; + +static void test_user() +{ + GtkTreeModel *model = gui_sidebar_model(); + GtkTreeIter iter, child; + + gui_sidebar_iter_first(&iter); + gui_sidebar_iter_find(&iter, "Playlists", PL_MAX_TYPE); + g_assert_true(gtk_tree_model_iter_has_child(model, &iter)); + g_assert_cmpuint(gtk_tree_model_iter_n_children(model, &iter), ==, 2); + + g_assert_nonnull(gui_pl_user_add("Test 2")); + g_assert_nonnull(gui_pl_user_add("Test 1")); + g_assert_cmpuint(gtk_tree_model_iter_n_children(model, &iter), ==, 4); + g_assert_null(gui_pl_user_add("Test 1")); + g_assert_null(gui_pl_user_add("Test 2")); + g_assert_cmpuint(gtk_tree_model_iter_n_children(model, &iter), ==, 4); + + g_assert_true(gui_sidebar_iter_down(&iter, &child)); + g_assert_cmpstr_free(gui_sidebar_iter_name(&child), ==, "Favorites"); + g_assert_cmpuint(gui_sidebar_iter_type(&child), ==, PL_SYSTEM); + + g_assert_true(gui_sidebar_iter_next(&child)); + g_assert_cmpstr_free(gui_sidebar_iter_name(&child), ==, "Hidden"); + g_assert_cmpuint(gui_sidebar_iter_type(&child), ==, PL_SYSTEM); + + g_assert_true(gui_sidebar_iter_next(&child)); + g_assert_cmpstr_free(gui_sidebar_iter_name(&child), ==, "Test 1"); + g_assert_cmpuint(gui_sidebar_iter_type(&child), ==, PL_USER); + + g_assert_true(gui_sidebar_iter_next(&child)); + g_assert_cmpstr_free(gui_sidebar_iter_name(&child), ==, "Test 2"); + g_assert_cmpuint(gui_sidebar_iter_type(&child), ==, PL_USER); +} + +int main(int argc, char **argv) +{ + int ret; + + gtk_init(&argc, NULL); + core_init(&argc, &argv, &init_data); + gui_builder_init("share/ocarina/ocarina.ui"); + gui_model_init(); + gui_filter_init(); + gui_treeview_init(); + gui_sidebar_init(); + gui_playlist_init(); + playlist_new(PL_LIBRARY, "tests/Music/Hyrule Symphony"); + while (idle_run_task()) {} + + g_test_init(&argc, &argv, NULL); + g_test_add_func("/Gui/Playlists/User", test_user); + ret = g_test_run(); + + core_deinit(); + gui_treeview_deinit(); + gui_filter_deinit(); + gui_model_deinit(); + gui_builder_deinit(); + return ret; +}