diff --git a/core/playlists/generic.c b/core/playlists/generic.c index c62f200b..f9b0f7c4 100644 --- a/core/playlists/generic.c +++ b/core/playlists/generic.c @@ -8,6 +8,10 @@ /* * Noop playlist operations. */ +void playlist_noop_clear(struct playlist *playlist) +{ +} + void playlist_noop_set_flag(struct playlist *playlist, enum queue_flags flag, bool enabled) { @@ -31,6 +35,11 @@ void playlist_generic_init(struct playlist *playlist, unsigned int flags, queue_sort(&playlist->pl_queue, COMPARE_TRACK, false); } +void playlist_generic_clear(struct playlist *playlist) +{ + queue_clear(&playlist->pl_queue); +} + bool playlist_generic_add_track(struct playlist *playlist, struct track *track) { if (queue_has(&playlist->pl_queue, track)) diff --git a/core/playlists/system.c b/core/playlists/system.c index 2cca82b2..c6ec638a 100644 --- a/core/playlists/system.c +++ b/core/playlists/system.c @@ -41,6 +41,7 @@ static bool sys_pl_generic_add(struct playlist *playlist, struct track *track) } + /* * Favorite tracks playlist operations. */ @@ -58,11 +59,18 @@ static bool sys_pl_favorites_remove(struct playlist *playlist, struct track *tra return ret; } +static void sys_pl_favorites_clear(struct playlist *playlist) +{ + playlist_generic_clear(playlist); + __sys_pl_save(); +} + static struct sys_playlist sys_favorites = { .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Favorites"), .spl_init = playlist_generic_init, .spl_add = sys_pl_favorites_add, .spl_remove = sys_pl_favorites_remove, + .spl_clear = sys_pl_favorites_clear, .spl_set_flag = playlist_generic_set_flag, .spl_sort = playlist_generic_sort, .spl_next = playlist_generic_next, @@ -83,22 +91,41 @@ static bool sys_pl_hidden_add(struct playlist *playlist, struct track *track) return ret; } -static bool sys_pl_hidden_remove(struct playlist *playlist, struct track *track) +static inline bool sys_pl_hidden_on_remove(struct playlist *playlist, + struct track *track) { bool ret = playlist_generic_remove_track(playlist, track); pl_system_add_track("Collection", track); pl_system_add_track("Unplayed", track); pl_system_add_track("Most Played", track); pl_system_add_track("Least Played", track); + return ret; +} + +static bool sys_pl_hidden_remove(struct playlist *playlist, struct track *track) +{ + bool ret = sys_pl_hidden_on_remove(playlist, track); __sys_pl_save(); return ret; } +static void sys_pl_hidden_clear(struct playlist *playlist) +{ + struct track *track; + + while (queue_size(&playlist->pl_queue) > 0) { + track = queue_at(&playlist->pl_queue, 0); + sys_pl_hidden_on_remove(playlist, track); + } + __sys_pl_save(); +} + static struct sys_playlist sys_hidden = { .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Hidden"), .spl_init = playlist_generic_init, .spl_add = sys_pl_hidden_add, .spl_remove = sys_pl_hidden_remove, + .spl_clear = sys_pl_hidden_clear, .spl_set_flag = playlist_generic_set_flag, .spl_sort = playlist_generic_sort, .spl_next = playlist_generic_next, @@ -167,6 +194,12 @@ static bool sys_pl_queued_remove(struct playlist *playlist, struct track *track) return ret; } +static void sys_pl_queued_clear(struct playlist *playlist) +{ + playlist_generic_clear(playlist); + sys_pl_queued_save(playlist); +} + static void sys_pl_queued_set_flag(struct playlist *playlist, enum queue_flags flag, bool enabled) { @@ -186,6 +219,7 @@ static struct sys_playlist sys_queued = { .spl_init = sys_pl_queued_init, .spl_add = sys_pl_queued_add, .spl_remove = sys_pl_queued_remove, + .spl_clear = sys_pl_queued_clear, .spl_set_flag = sys_pl_queued_set_flag, .spl_sort = playlist_generic_sort, .spl_next = sys_pl_queued_next, @@ -251,6 +285,7 @@ static struct sys_playlist sys_collection = { .spl_init = sys_pl_update_init, .spl_add = sys_pl_collection_add, .spl_remove = playlist_generic_remove_track, + .spl_clear = playlist_noop_clear, .spl_update = sys_pl_collection_update, .spl_set_flag = sys_pl_collection_set_flag, .spl_sort = sys_pl_collection_sort, @@ -281,6 +316,7 @@ static struct sys_playlist sys_history = { .spl_init = sys_pl_history_init, .spl_add = sys_pl_history_add, .spl_remove = playlist_generic_remove_track, + .spl_clear = playlist_noop_clear, .spl_set_flag = playlist_noop_set_flag, .spl_sort = playlist_noop_sort, .spl_next = playlist_generic_next, @@ -310,6 +346,7 @@ static struct sys_playlist sys_unplayed = { .spl_init = sys_pl_update_init, .spl_add = sys_pl_unplayed_add, .spl_remove = playlist_generic_remove_track, + .spl_clear = playlist_noop_clear, .spl_update = sys_pl_unplayed_update, .spl_set_flag = playlist_generic_set_flag, .spl_sort = playlist_generic_sort, @@ -343,6 +380,7 @@ static struct sys_playlist sys_most_played = { .spl_add = sys_pl_most_played_add, .spl_remove = playlist_generic_remove_track, .spl_update = sys_pl_most_played_update, + .spl_clear = playlist_noop_clear, .spl_set_flag = playlist_generic_set_flag, .spl_sort = playlist_generic_sort, .spl_next = playlist_generic_next, @@ -372,6 +410,7 @@ static bool sys_pl_least_played_update(struct playlist *playlist, static struct sys_playlist sys_least_played = { .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Least Played"), .spl_init = sys_pl_update_init, + .spl_clear = playlist_noop_clear, .spl_add = sys_pl_least_played_add, .spl_remove = playlist_generic_remove_track, .spl_update = sys_pl_least_played_update, @@ -456,11 +495,19 @@ static struct queue *pl_system_get_queue(const gchar *name) return sys_pl ? &sys_pl->spl_playlist.pl_queue : NULL; } -static bool pl_system_new_delete(const gchar *name) +static bool pl_system_new(const gchar *name) { return false; } +static bool pl_system_delete(const gchar *name) +{ + struct sys_playlist *sys_pl = __sys_pl_lookup(name); + if (sys_pl) + sys_pl->spl_clear(&sys_pl->spl_playlist); + return false; /* Don't remove the playlist from the sidebar. */ +} + static bool pl_system_add_track(const gchar *name, struct track *track) { struct sys_playlist *sys_pl = __sys_pl_lookup(name); @@ -506,8 +553,8 @@ static struct track *pl_system_next(const gchar *name) struct playlist_type pl_system = { .pl_get_queue = pl_system_get_queue, - .pl_new = pl_system_new_delete, - .pl_delete = pl_system_new_delete, + .pl_new = pl_system_new, + .pl_delete = pl_system_delete, .pl_add_track = pl_system_add_track, .pl_remove_track = pl_system_remove_track, .pl_update = pl_system_update, diff --git a/include/core/playlists/system.h b/include/core/playlists/system.h index e76e0a8c..f75196bd 100644 --- a/include/core/playlists/system.h +++ b/include/core/playlists/system.h @@ -24,6 +24,7 @@ struct sys_playlist { void (*spl_init)(struct playlist *, unsigned int, struct queue_ops *); bool (*spl_add)(struct playlist *, struct track *); bool (*spl_remove)(struct playlist *, struct track *); + void (*spl_clear)(struct playlist *); bool (*spl_update)(struct playlist *, struct track *); void (*spl_set_flag)(struct playlist *, enum queue_flags, bool); void (*spl_sort)(struct playlist *, enum compare_t, bool); diff --git a/include/core/playlists/type.h b/include/core/playlists/type.h index 1f870a4c..6b1c9cbb 100644 --- a/include/core/playlists/type.h +++ b/include/core/playlists/type.h @@ -57,6 +57,9 @@ struct playlist_type { }; +/* Noop playlist clear operation. */ +void playlist_noop_clear(struct playlist *); + /* Noop playlist set_flag operation. */ void playlist_noop_set_flag(struct playlist *, enum queue_flags, bool); @@ -67,6 +70,9 @@ void playlist_noop_sort(struct playlist *, enum compare_t, bool); /* Generic playlist init function. */ void playlist_generic_init(struct playlist *, unsigned int, struct queue_ops *); +/* Generic playlist clear operation. */ +void playlist_generic_clear(struct playlist *); + /* Generic playlist add track operation. */ bool playlist_generic_add_track(struct playlist *, struct track *); diff --git a/tests/core/playlists/system.c b/tests/core/playlists/system.c index 33349e22..868f55f8 100644 --- a/tests/core/playlists/system.c +++ b/tests/core/playlists/system.c @@ -40,6 +40,10 @@ g_assert_false(playlist_remove(PL_SYSTEM, name, track_get(1))); \ __test_playlist_state(name, 0, false, false) +#define __test_playlist_clear(name, ex_size, ex_track0, ex_track1) \ + g_assert_false(playlist_delete(PL_SYSTEM, name)); \ + __test_playlist_state(name, ex_size, ex_track0, ex_track1) + #define __test_playlist_update(name, ex_size, ex_track0, ex_track1) \ playlist_update(PL_SYSTEM, name); \ while (idle_run_task()) {}; \ @@ -54,6 +58,10 @@ g_assert_true(playlist_remove(PL_SYSTEM, "Hidden", track_get(0))); \ __test_playlist_state(name, ex_size, ex_track0, ex_track1) +#define __test_playlist_clear_hidden(name, ex_size, ex_track0, ex_track1) \ + __test_playlist_clear("Hidden", 0, false, false); \ + __test_playlist_state(name, ex_size, ex_track0, ex_track1); + #define __test_playlist_reinit(name, ex_size, ex_track0, ex_track1) \ do { \ struct queue *queue; \ @@ -79,6 +87,7 @@ static void test_invalid() playlist_update(PL_SYSTEM, NULL); g_assert_false(playlist_add(PL_SYSTEM, NULL, track_get(0))); g_assert_false(playlist_remove(PL_SYSTEM, NULL, track_get(0))); + g_assert_false(playlist_delete(PL_SYSTEM, NULL)); g_assert_false(playlist_has(PL_SYSTEM, NULL, track_get(0))); g_assert_cmpuint(playlist_size(PL_SYSTEM, NULL), ==, 0); @@ -98,6 +107,9 @@ static void test_favorites() __test_playlist_add("Favorites"); __test_playlist_reinit("Favorites", 2, true, true); __test_playlist_update("Favorites", 2, true, true); + __test_playlist_clear("Favorites", 0, false, false); + __test_playlist_reinit("Favorites", 0, false, false); + __test_playlist_add("Favorites"); __test_playlist_remove("Favorites"); } @@ -113,6 +125,9 @@ static void test_hidden() __test_playlist_add("Hidden"); __test_playlist_reinit("Hidden", 2, true, true); __test_playlist_update("Hidden", 2, true, true); + __test_playlist_clear("Hidden", 0, false, false); + __test_playlist_reinit("Hidden", 0, false, false); + __test_playlist_add("Hidden"); __test_playlist_remove("Hidden"); } @@ -127,6 +142,7 @@ static void test_queued() __test_playlist_random("Queued Tracks"); __test_playlist_add("Queued Tracks"); + __test_playlist_reinit("Queued Tracks", 2, true, true); g_assert(playlist_next() == track_get(0)); g_assert_cmpuint(playlist_size(PL_SYSTEM, "Queued Tracks"), ==, 1); @@ -137,6 +153,9 @@ static void test_queued() __test_playlist_add("Queued Tracks"); __test_playlist_remove("Queued Tracks"); __test_playlist_update("Queued Tracks", 0, false, false); + __test_playlist_add("Queued Tracks"); + __test_playlist_clear("Queued Tracks", 0, false, false); + __test_playlist_reinit("Queued Tracks", 0, false, false); } static void test_collection() @@ -155,6 +174,9 @@ static void test_collection() __test_playlist_reinit("Collection", 1, false, true); __test_playlist_update("Collection", 1, false, true); __test_playlist_unhide_track("Collection", 2, true, true); + __test_playlist_hide_track("Collection", 1, false, true); + __test_playlist_clear_hidden("Collection", 2, true, true); + __test_playlist_clear("Collection", 2, true, true); } static void test_history() @@ -187,6 +209,7 @@ static void test_history() g_assert_cmpuint(playlist_size(PL_SYSTEM, "History"), ==, 5); g_assert(playlist_prev() == track_get(1)); + __test_playlist_clear("History", 5, true, true); __test_playlist_remove("History"); __test_playlist_update("History", 0, false, false); } @@ -221,6 +244,9 @@ static void test_unplayed() __test_playlist_reinit("Unplayed", 1, false, true); __test_playlist_update("Unplayed", 1, false, true); __test_playlist_unhide_track("Unplayed", 2, true, true); + __test_playlist_hide_track("Unplayed", 1, false, true); + __test_playlist_clear_hidden("Unplayed", 2, true, true); + __test_playlist_clear("Unplayed", 2, true, true); } static void test_most_played() @@ -260,6 +286,9 @@ static void test_most_played() __test_playlist_reinit("Most Played", 0, false, false); __test_playlist_update("Most Played", 0, false, false); __test_playlist_unhide_track("Most Played", 1, true, false); + __test_playlist_hide_track("Most Played", 0, false, false); + __test_playlist_clear_hidden("Most Played", 1, true, false); + __test_playlist_clear("Most Played", 1, true, false); } static void test_least_played() @@ -297,6 +326,9 @@ static void test_least_played() __test_playlist_reinit("Least Played", 0, false, false); __test_playlist_update("Least Played", 0, false, false); __test_playlist_unhide_track("Least Played", 1, true, false); + __test_playlist_hide_track("Least Played", 0, false, false); + __test_playlist_clear_hidden("Least Played", 1, true, false); + __test_playlist_clear("Least Played", 1, true, false); }