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_resort(&playlist->pl_queue);
|
||||
playlist_generic_resort(playlist);
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -87,7 +106,7 @@ void playlist_generic_load(struct playlist *playlist, struct file *file,
|
|||
}
|
||||
playlist_clear_sort(playlist);
|
||||
playlist->pl_queue.q_sort = sort;
|
||||
queue_resort(&playlist->pl_queue);
|
||||
playlist_generic_resort(playlist);
|
||||
|
||||
if (file_readf(file, "%m\n", &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,
|
||||
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)
|
||||
|
|
|
@ -52,7 +52,7 @@ static bool __lib_pl_add(void *data)
|
|||
queue_add_front(&playlist->pl_queue, TRACK(dbe));
|
||||
}
|
||||
|
||||
queue_resort(&playlist->pl_queue);
|
||||
playlist_generic_resort(playlist);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ static bool sys_pl_update_func(void *data)
|
|||
playlist_generic_remove_track(playlist, track);
|
||||
}
|
||||
|
||||
queue_resort(&playlist->pl_queue);
|
||||
playlist_generic_resort(playlist);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -246,12 +246,3 @@ struct track *queue_next(struct queue *queue)
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return gui_model;
|
||||
|
@ -328,6 +335,13 @@ void gui_model_update(struct playlist *playlist, unsigned int row)
|
|||
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)
|
||||
{
|
||||
if (cur_playlist)
|
||||
|
|
|
@ -76,6 +76,7 @@ struct queue_ops playlist_ops = {
|
|||
};
|
||||
|
||||
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)
|
||||
|
||||
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. */
|
||||
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_resort(struct playlist *);
|
||||
|
||||
/* Generic playlist next track operation. */
|
||||
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. */
|
||||
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 */
|
||||
|
|
|
@ -63,6 +63,9 @@ void gui_model_clear(struct playlist *, unsigned int);
|
|||
/* Called to update a row in the model */
|
||||
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. */
|
||||
void gui_model_set_playlist(struct playlist *);
|
||||
|
||||
|
|
|
@ -6,10 +6,18 @@
|
|||
#include <core/settings.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_ops = {
|
||||
.pl_sort = playlist_generic_sort,
|
||||
};
|
||||
static struct playlist_callbacks test_cb = {
|
||||
.pl_cb_sorted = test_pl_sorted,
|
||||
};
|
||||
|
||||
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));
|
||||
playlist_generic_resort(NULL);
|
||||
playlist_clear_sort(NULL);
|
||||
|
||||
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);
|
||||
playlist_clear_sort(&p);
|
||||
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 0);
|
||||
last_sort = NULL;
|
||||
|
||||
for (i = 0; i < 13; i++) {
|
||||
track = track_get(i);
|
||||
|
@ -64,15 +74,19 @@ static void test_sorting()
|
|||
|
||||
p.pl_ops = &test_noop;
|
||||
g_assert_false(playlist_sort(&p, COMPARE_TRACK));
|
||||
g_assert_null(last_sort);
|
||||
p.pl_ops = &test_ops;
|
||||
|
||||
g_assert_true(playlist_sort(&p, COMPARE_TRACK));
|
||||
g_assert(last_sort == &p);
|
||||
for (i = 0; i < 13; i++) {
|
||||
track = queue_at(&p.pl_queue, i);
|
||||
g_assert_cmpuint(track->tr_track, ==, i + 1);
|
||||
}
|
||||
|
||||
playlist_clear_sort(&p);
|
||||
playlist_generic_resort(&p);
|
||||
|
||||
g_assert_true(playlist_sort(&p, COMPARE_COUNT));
|
||||
for (i = 0; i < 13; i++) {
|
||||
track = queue_at(&p.pl_queue, i);
|
||||
|
@ -152,7 +166,7 @@ int main(int argc, char **argv)
|
|||
idle_init_sync();
|
||||
settings_init();
|
||||
tags_init();
|
||||
playlist_init(NULL, NULL);
|
||||
playlist_init(NULL, &test_cb);
|
||||
while (idle_run_task()) {};
|
||||
|
||||
library = library_find("tests/Music");
|
||||
|
|
|
@ -222,10 +222,9 @@ static void test_rand_select()
|
|||
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++)
|
||||
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:
|
||||
|
|
|
@ -48,6 +48,10 @@ struct queue_ops test_ops = {
|
|||
.qop_updated = test_queue_update,
|
||||
};
|
||||
|
||||
struct playlist_callbacks test_cb = {
|
||||
.pl_cb_sorted = gui_model_update_all,
|
||||
};
|
||||
|
||||
struct audio_ops test_audio_ops = {
|
||||
.on_load = test_on_load,
|
||||
.on_state_change = test_on_state_change,
|
||||
|
@ -55,8 +59,9 @@ struct audio_ops test_audio_ops = {
|
|||
};
|
||||
|
||||
struct core_init_data init_data = {
|
||||
.playlist_cb = &test_cb,
|
||||
.playlist_ops = &test_ops,
|
||||
.audio_ops = &test_audio_ops,
|
||||
.audio_ops = &test_audio_ops,
|
||||
};
|
||||
|
||||
static void test_init()
|
||||
|
@ -186,7 +191,7 @@ static void test_model()
|
|||
while (idle_run_task() == true) {}
|
||||
g_assert_cmpuint(playlist_size(collection), ==, 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);
|
||||
playlist_add(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(0));
|
||||
playlist_add(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(1));
|
||||
|
|
Loading…
Reference in New Issue