core/playlist: Add a playlist_generic_resort() function
This function is called to force-sort the playlist. Additionally, we trigger the "playlist-sorted" callback to to notify the gui that playlist rows need to be updated. Additionally, I implement the gui_model_update_all() function to loop over the model and update all rows of the current playlist. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
e74c1c053c
commit
07bf09c2ad
|
@ -48,7 +48,7 @@ static bool __artist_pl_add(void *data)
|
||||||
queue_add_front(&playlist->pl_queue, TRACK(dbe));
|
queue_add_front(&playlist->pl_queue, TRACK(dbe));
|
||||||
}
|
}
|
||||||
|
|
||||||
queue_resort(&playlist->pl_queue);
|
playlist_generic_resort(playlist);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,25 @@ static int __playlist_generic_find_sort(gconstpointer a, gconstpointer b)
|
||||||
return abs(GPOINTER_TO_INT(a)) - abs(GPOINTER_TO_INT(b));
|
return abs(GPOINTER_TO_INT(a)) - abs(GPOINTER_TO_INT(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __playlist_generic_less_than(gconstpointer a, gconstpointer b,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
struct track *lhs = (struct track *)a;
|
||||||
|
struct track *rhs = (struct track *)b;
|
||||||
|
GSList *cur = (GSList *)data;
|
||||||
|
int res, field;
|
||||||
|
|
||||||
|
while (cur) {
|
||||||
|
field = GPOINTER_TO_INT(cur->data);
|
||||||
|
res = track_compare(lhs, rhs, abs(field));
|
||||||
|
if (res != 0)
|
||||||
|
break;
|
||||||
|
cur = g_slist_next(cur);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (field > 0) ? res : -res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void playlist_generic_set_callbacks(struct playlist_callbacks *cb)
|
void playlist_generic_set_callbacks(struct playlist_callbacks *cb)
|
||||||
{
|
{
|
||||||
|
@ -87,7 +106,7 @@ void playlist_generic_load(struct playlist *playlist, struct file *file,
|
||||||
}
|
}
|
||||||
playlist_clear_sort(playlist);
|
playlist_clear_sort(playlist);
|
||||||
playlist->pl_queue.q_sort = sort;
|
playlist->pl_queue.q_sort = sort;
|
||||||
queue_resort(&playlist->pl_queue);
|
playlist_generic_resort(playlist);
|
||||||
|
|
||||||
if (file_readf(file, "%m\n", &line))
|
if (file_readf(file, "%m\n", &line))
|
||||||
g_free(line);
|
g_free(line);
|
||||||
|
@ -159,7 +178,19 @@ void playlist_generic_sort(struct playlist *playlist, enum compare_t sort)
|
||||||
playlist->pl_queue.q_sort = g_slist_append(playlist->pl_queue.q_sort,
|
playlist->pl_queue.q_sort = g_slist_append(playlist->pl_queue.q_sort,
|
||||||
GINT_TO_POINTER(sort));
|
GINT_TO_POINTER(sort));
|
||||||
|
|
||||||
queue_resort(&playlist->pl_queue);
|
playlist_generic_resort(playlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
void playlist_generic_resort(struct playlist *playlist)
|
||||||
|
{
|
||||||
|
if (!playlist || !playlist->pl_queue.q_sort)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_queue_sort(&playlist->pl_queue.q_tracks, __playlist_generic_less_than,
|
||||||
|
playlist->pl_queue.q_sort);
|
||||||
|
|
||||||
|
if (callbacks)
|
||||||
|
callbacks->pl_cb_sorted(playlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct track *playlist_generic_next(struct playlist *playlist)
|
struct track *playlist_generic_next(struct playlist *playlist)
|
||||||
|
|
|
@ -52,7 +52,7 @@ static bool __lib_pl_add(void *data)
|
||||||
queue_add_front(&playlist->pl_queue, TRACK(dbe));
|
queue_add_front(&playlist->pl_queue, TRACK(dbe));
|
||||||
}
|
}
|
||||||
|
|
||||||
queue_resort(&playlist->pl_queue);
|
playlist_generic_resort(playlist);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ static bool sys_pl_update_func(void *data)
|
||||||
playlist_generic_remove_track(playlist, track);
|
playlist_generic_remove_track(playlist, track);
|
||||||
}
|
}
|
||||||
|
|
||||||
queue_resort(&playlist->pl_queue);
|
playlist_generic_resort(playlist);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,12 +246,3 @@ struct track *queue_next(struct queue *queue)
|
||||||
|
|
||||||
return __queue_selected(queue, queue->q_cur.it_pos);
|
return __queue_selected(queue, queue->q_cur.it_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void queue_resort(struct queue *queue)
|
|
||||||
{
|
|
||||||
g_queue_sort(&queue->q_tracks, track_less_than, queue->q_sort);
|
|
||||||
|
|
||||||
queue_iter_set(queue, &queue->q_cur, queue->q_cur.it_pos);
|
|
||||||
for (unsigned int i = 0; i < queue_size(queue); i++)
|
|
||||||
__queue_updated(queue, i);
|
|
||||||
}
|
|
||||||
|
|
14
gui/model.c
14
gui/model.c
|
@ -257,6 +257,13 @@ static void __gui_model_set_runtime(void)
|
||||||
g_free(len);
|
g_free(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean __gui_model_foreach_changed(GtkTreeModel *model, GtkTreePath *path,
|
||||||
|
GtkTreeIter *iter, gpointer data)
|
||||||
|
{
|
||||||
|
gtk_tree_model_row_changed(model, path, iter);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
GuiModel *gui_model_get(void)
|
GuiModel *gui_model_get(void)
|
||||||
{
|
{
|
||||||
return gui_model;
|
return gui_model;
|
||||||
|
@ -328,6 +335,13 @@ void gui_model_update(struct playlist *playlist, unsigned int row)
|
||||||
gtk_tree_path_free(path);
|
gtk_tree_path_free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gui_model_update_all(struct playlist *playlist)
|
||||||
|
{
|
||||||
|
if (cur_playlist == playlist)
|
||||||
|
gtk_tree_model_foreach(GTK_TREE_MODEL(gui_model),
|
||||||
|
__gui_model_foreach_changed, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void gui_model_set_playlist(struct playlist *playlist)
|
void gui_model_set_playlist(struct playlist *playlist)
|
||||||
{
|
{
|
||||||
if (cur_playlist)
|
if (cur_playlist)
|
||||||
|
|
|
@ -76,6 +76,7 @@ struct queue_ops playlist_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct playlist_callbacks playlist_cb = {
|
struct playlist_callbacks playlist_cb = {
|
||||||
|
.pl_cb_sorted = gui_model_update_all,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ enum playlist_save_flags {
|
||||||
#define PL_SAVE_ALL (PL_SAVE_TRACKS | PL_SAVE_METADATA)
|
#define PL_SAVE_ALL (PL_SAVE_TRACKS | PL_SAVE_METADATA)
|
||||||
|
|
||||||
struct playlist_callbacks {
|
struct playlist_callbacks {
|
||||||
|
/* Called to notify that a playlist has been sorted. */
|
||||||
|
void (*pl_cb_sorted)(struct playlist *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,8 +47,9 @@ bool playlist_generic_remove_track(struct playlist *, struct track *);
|
||||||
/* Generic playlist set_flag operation. */
|
/* Generic playlist set_flag operation. */
|
||||||
void playlist_generic_set_flag(struct playlist *, enum queue_flags, bool);
|
void playlist_generic_set_flag(struct playlist *, enum queue_flags, bool);
|
||||||
|
|
||||||
/* Generic playlist sorting operation. */
|
/* Generic playlist sorting operations. */
|
||||||
void playlist_generic_sort(struct playlist *, enum compare_t);
|
void playlist_generic_sort(struct playlist *, enum compare_t);
|
||||||
|
void playlist_generic_resort(struct playlist *);
|
||||||
|
|
||||||
/* Generic playlist next track operation. */
|
/* Generic playlist next track operation. */
|
||||||
struct track *playlist_generic_next(struct playlist *);
|
struct track *playlist_generic_next(struct playlist *);
|
||||||
|
|
|
@ -167,7 +167,4 @@ struct track *queue_selected(struct queue *, unsigned int);
|
||||||
/* Called to pick the next track from the queue. */
|
/* Called to pick the next track from the queue. */
|
||||||
struct track *queue_next(struct queue *);
|
struct track *queue_next(struct queue *);
|
||||||
|
|
||||||
/* Called to sort the queue without changing sort order. */
|
|
||||||
void queue_resort(struct queue *);
|
|
||||||
|
|
||||||
#endif /* OCARINA_CORE_QUEUE_H */
|
#endif /* OCARINA_CORE_QUEUE_H */
|
||||||
|
|
|
@ -63,6 +63,9 @@ void gui_model_clear(struct playlist *, unsigned int);
|
||||||
/* Called to update a row in the model */
|
/* Called to update a row in the model */
|
||||||
void gui_model_update(struct playlist *, unsigned int);
|
void gui_model_update(struct playlist *, unsigned int);
|
||||||
|
|
||||||
|
/* Called to update all rows in the model */
|
||||||
|
void gui_model_update_all(struct playlist *);
|
||||||
|
|
||||||
/* Called to change the queue represented by the model. */
|
/* Called to change the queue represented by the model. */
|
||||||
void gui_model_set_playlist(struct playlist *);
|
void gui_model_set_playlist(struct playlist *);
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,18 @@
|
||||||
#include <core/settings.h>
|
#include <core/settings.h>
|
||||||
#include <core/tags/tags.h>
|
#include <core/tags/tags.h>
|
||||||
|
|
||||||
|
static struct playlist *last_sort = NULL;
|
||||||
|
|
||||||
|
static void test_pl_sorted(struct playlist *playlist)
|
||||||
|
{ last_sort = playlist; }
|
||||||
|
|
||||||
static struct playlist_ops test_noop;
|
static struct playlist_ops test_noop;
|
||||||
static struct playlist_ops test_ops = {
|
static struct playlist_ops test_ops = {
|
||||||
.pl_sort = playlist_generic_sort,
|
.pl_sort = playlist_generic_sort,
|
||||||
};
|
};
|
||||||
|
static struct playlist_callbacks test_cb = {
|
||||||
|
.pl_cb_sorted = test_pl_sorted,
|
||||||
|
};
|
||||||
|
|
||||||
static void test_null()
|
static void test_null()
|
||||||
{
|
{
|
||||||
|
@ -39,6 +47,7 @@ static void test_null()
|
||||||
|
|
||||||
g_assert_false(playlist_sort(NULL, COMPARE_TRACK));
|
g_assert_false(playlist_sort(NULL, COMPARE_TRACK));
|
||||||
g_assert_false(playlist_sort(NULL, COMPARE_TRACK));
|
g_assert_false(playlist_sort(NULL, COMPARE_TRACK));
|
||||||
|
playlist_generic_resort(NULL);
|
||||||
playlist_clear_sort(NULL);
|
playlist_clear_sort(NULL);
|
||||||
|
|
||||||
playlist_generic_save(NULL, NULL, PL_SAVE_ALL);
|
playlist_generic_save(NULL, NULL, PL_SAVE_ALL);
|
||||||
|
@ -55,6 +64,7 @@ static void test_sorting()
|
||||||
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 3);
|
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 3);
|
||||||
playlist_clear_sort(&p);
|
playlist_clear_sort(&p);
|
||||||
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 0);
|
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 0);
|
||||||
|
last_sort = NULL;
|
||||||
|
|
||||||
for (i = 0; i < 13; i++) {
|
for (i = 0; i < 13; i++) {
|
||||||
track = track_get(i);
|
track = track_get(i);
|
||||||
|
@ -64,15 +74,19 @@ static void test_sorting()
|
||||||
|
|
||||||
p.pl_ops = &test_noop;
|
p.pl_ops = &test_noop;
|
||||||
g_assert_false(playlist_sort(&p, COMPARE_TRACK));
|
g_assert_false(playlist_sort(&p, COMPARE_TRACK));
|
||||||
|
g_assert_null(last_sort);
|
||||||
p.pl_ops = &test_ops;
|
p.pl_ops = &test_ops;
|
||||||
|
|
||||||
g_assert_true(playlist_sort(&p, COMPARE_TRACK));
|
g_assert_true(playlist_sort(&p, COMPARE_TRACK));
|
||||||
|
g_assert(last_sort == &p);
|
||||||
for (i = 0; i < 13; i++) {
|
for (i = 0; i < 13; i++) {
|
||||||
track = queue_at(&p.pl_queue, i);
|
track = queue_at(&p.pl_queue, i);
|
||||||
g_assert_cmpuint(track->tr_track, ==, i + 1);
|
g_assert_cmpuint(track->tr_track, ==, i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
playlist_clear_sort(&p);
|
playlist_clear_sort(&p);
|
||||||
|
playlist_generic_resort(&p);
|
||||||
|
|
||||||
g_assert_true(playlist_sort(&p, COMPARE_COUNT));
|
g_assert_true(playlist_sort(&p, COMPARE_COUNT));
|
||||||
for (i = 0; i < 13; i++) {
|
for (i = 0; i < 13; i++) {
|
||||||
track = queue_at(&p.pl_queue, i);
|
track = queue_at(&p.pl_queue, i);
|
||||||
|
@ -152,7 +166,7 @@ int main(int argc, char **argv)
|
||||||
idle_init_sync();
|
idle_init_sync();
|
||||||
settings_init();
|
settings_init();
|
||||||
tags_init();
|
tags_init();
|
||||||
playlist_init(NULL, NULL);
|
playlist_init(NULL, &test_cb);
|
||||||
while (idle_run_task()) {};
|
while (idle_run_task()) {};
|
||||||
|
|
||||||
library = library_find("tests/Music");
|
library = library_find("tests/Music");
|
||||||
|
|
|
@ -222,10 +222,9 @@ static void test_rand_select()
|
||||||
g_assert_cmpuint(queue_size(&q), ==, 0);
|
g_assert_cmpuint(queue_size(&q), ==, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
q.q_sort = g_slist_append(q.q_sort, GINT_TO_POINTER(COMPARE_TRACK));
|
||||||
for (i = 0; i < 13; i++)
|
for (i = 0; i < 13; i++)
|
||||||
queue_add(&q, track_get(i));
|
queue_add(&q, track_get(i));
|
||||||
q.q_sort = g_slist_append(q.q_sort, GINT_TO_POINTER(COMPARE_TRACK));
|
|
||||||
queue_resort(&q);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The comments below use the following notation:
|
* The comments below use the following notation:
|
||||||
|
|
|
@ -48,6 +48,10 @@ struct queue_ops test_ops = {
|
||||||
.qop_updated = test_queue_update,
|
.qop_updated = test_queue_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct playlist_callbacks test_cb = {
|
||||||
|
.pl_cb_sorted = gui_model_update_all,
|
||||||
|
};
|
||||||
|
|
||||||
struct audio_ops test_audio_ops = {
|
struct audio_ops test_audio_ops = {
|
||||||
.on_load = test_on_load,
|
.on_load = test_on_load,
|
||||||
.on_state_change = test_on_state_change,
|
.on_state_change = test_on_state_change,
|
||||||
|
@ -55,8 +59,9 @@ struct audio_ops test_audio_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct core_init_data init_data = {
|
struct core_init_data init_data = {
|
||||||
|
.playlist_cb = &test_cb,
|
||||||
.playlist_ops = &test_ops,
|
.playlist_ops = &test_ops,
|
||||||
.audio_ops = &test_audio_ops,
|
.audio_ops = &test_audio_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void test_init()
|
static void test_init()
|
||||||
|
@ -186,7 +191,7 @@ static void test_model()
|
||||||
while (idle_run_task() == true) {}
|
while (idle_run_task() == true) {}
|
||||||
g_assert_cmpuint(playlist_size(collection), ==, 13);
|
g_assert_cmpuint(playlist_size(collection), ==, 13);
|
||||||
g_assert_cmpuint(count_insert, ==, 13);
|
g_assert_cmpuint(count_insert, ==, 13);
|
||||||
queue_resort(&playlist_lookup(PL_SYSTEM, "Collection")->pl_queue);
|
playlist_generic_resort(playlist_lookup(PL_SYSTEM, "Collection"));
|
||||||
g_assert_cmpuint(count_update, ==, 13);
|
g_assert_cmpuint(count_update, ==, 13);
|
||||||
playlist_add(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(0));
|
playlist_add(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(0));
|
||||||
playlist_add(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(1));
|
playlist_add(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(1));
|
||||||
|
|
Loading…
Reference in New Issue