diff --git a/core/playlist.cpp b/core/playlist.cpp index d1191bae..30895d00 100644 --- a/core/playlist.cpp +++ b/core/playlist.cpp @@ -10,8 +10,7 @@ public: void clear() { - while (queue_size(this) > 0) - queue_remove(this, (unsigned)0); + queue_clear(this); } void fill(index_entry *ent) diff --git a/core/queue.c b/core/queue.c index b6fbcb72..82d3a54a 100644 --- a/core/queue.c +++ b/core/queue.c @@ -51,6 +51,13 @@ static inline void __queue_remove(struct queue *queue, struct _q_iter *it) queue->q_ops->qop_removed(queue, pos); } +static inline void __queue_clear(struct queue *queue, unsigned int n) +{ + queue->q_length = 0; + if (queue->q_ops) + queue->q_ops->qop_cleared(queue, n); +} + static inline void __queue_updated(struct queue *queue, unsigned int pos) { if (queue->q_ops) @@ -88,10 +95,9 @@ void queue_init(struct queue *queue, unsigned int flags, void queue_deinit(struct queue *queue) { - _q_clear(&queue->q_tracks); + queue_clear(queue); g_slist_free(queue->q_sort); queue->q_sort = NULL; - queue->q_length = 0; } void queue_set_flag(struct queue *queue, enum queue_flags flag) @@ -142,6 +148,14 @@ void queue_remove_all(struct queue *queue, struct track *track) } } +void queue_clear(struct queue *queue) +{ + unsigned int n = queue_size(queue); + + _q_clear(&queue->q_tracks); + __queue_clear(queue, n); +} + void queue_updated(struct queue *queue, struct track *track) { struct _q_iter it; diff --git a/gui/collection.cpp b/gui/collection.cpp index ae7df681..aa425481 100644 --- a/gui/collection.cpp +++ b/gui/collection.cpp @@ -60,6 +60,12 @@ static void collection_removed(struct queue *queue, unsigned int pos) collection_tab->on_track_removed(pos); } +static void collection_cleared(struct queue *queue, unsigned int n) +{ + if (collection_tab) + collection_tab->on_tracks_cleared(n); +} + static void collection_updated(struct queue *queue, unsigned int pos) { if (collection_tab) @@ -69,6 +75,7 @@ static void collection_updated(struct queue *queue, unsigned int pos) struct queue_ops collection_ops = { collection_added, collection_removed, + collection_cleared, collection :: save, collection_updated, }; diff --git a/gui/history.cpp b/gui/history.cpp index 866dc664..66fca0b9 100644 --- a/gui/history.cpp +++ b/gui/history.cpp @@ -45,6 +45,11 @@ static void history_removed(struct queue *queue, unsigned int pos) history_tab->on_track_removed(pos); } +static void history_cleared(struct queue *queue, unsigned int n) +{ + history_tab->on_tracks_cleared(n); +} + static void history_updated(struct queue *queue, unsigned int pos) { history_tab->on_track_updated(pos); @@ -53,6 +58,7 @@ static void history_updated(struct queue *queue, unsigned int pos) struct queue_ops history_ops = { history_added, history_removed, + history_cleared, NULL, history_updated, }; diff --git a/gui/playlist.cpp b/gui/playlist.cpp index 01f1db83..5d541d22 100644 --- a/gui/playlist.cpp +++ b/gui/playlist.cpp @@ -154,6 +154,11 @@ static void playlist_removed(struct queue *queue, unsigned int pos) p_tab->on_track_removed(pos); } +static void playlist_cleared(struct queue *queue, unsigned int n) +{ + p_tab->on_tracks_cleared(n); +} + static void playlist_updated(struct queue *queue, unsigned int pos) { p_tab->on_track_updated(pos); @@ -162,6 +167,7 @@ static void playlist_updated(struct queue *queue, unsigned int pos) struct queue_ops playlist_ops = { playlist_added, playlist_removed, + playlist_cleared, NULL, playlist_updated, }; diff --git a/gui/queue/model.cpp b/gui/queue/model.cpp index 72d7932b..529f729e 100644 --- a/gui/queue/model.cpp +++ b/gui/queue/model.cpp @@ -41,6 +41,13 @@ void QueueModel::on_row_deleted(unsigned int row) row_deleted(Gtk::TreePath(1, row)); } +void QueueModel::on_cleared(unsigned int n) +{ + increment_stamp(); + for (unsigned int i = 1; i <= n; i++) + row_deleted(Gtk::TreePath(1, n - i)); +} + void QueueModel::on_row_changed(unsigned int row) { increment_stamp(); diff --git a/gui/tabs.cpp b/gui/tabs.cpp index fed0a050..dbaece37 100644 --- a/gui/tabs.cpp +++ b/gui/tabs.cpp @@ -32,6 +32,12 @@ static void tempq_removed(struct queue *queue, unsigned int pos) deck :: write(); } +static void tempq_cleared(struct queue *queue, unsigned int n) +{ + find_tab(queue)->on_tracks_cleared(n); + deck :: write(); +} + static void tempq_updated(struct queue *queue, unsigned int pos) { find_tab(queue)->on_track_updated(pos); @@ -40,6 +46,7 @@ static void tempq_updated(struct queue *queue, unsigned int pos) struct queue_ops tempq_ops = { tempq_added, tempq_removed, + tempq_cleared, deck :: save, tempq_updated, }; @@ -106,6 +113,13 @@ void Tab :: on_track_removed(unsigned int row) tab_runtime_changed(); } +void Tab :: on_tracks_cleared(unsigned int n) +{ + tab_window->q_model->on_cleared(n); + tab_label->set_size(); + tab_runtime_changed(); +} + void Tab :: on_track_updated(unsigned int row) { tab_window->q_model->on_row_changed(row); diff --git a/include/core/queue.h b/include/core/queue.h index b7c45087..794ae826 100644 --- a/include/core/queue.h +++ b/include/core/queue.h @@ -33,6 +33,9 @@ struct queue_ops { /* Called to tell a higher layer that a track has been removed. */ void (*qop_removed)(struct queue *, unsigned int); + /* Called to tell a higher layer that the queue has been cleared. */ + void (*qop_cleared)(struct queue *, unsigned int); + /* Called to have a higher layer save the queue. */ void (*qop_save)(struct queue *, enum queue_flags); @@ -93,6 +96,9 @@ void queue_remove(struct queue *, unsigned int); /* Called to remove all instances of the track from the queue. */ void queue_remove_all(struct queue *, struct track *); +/* Called to remove all tracks from the queue. */ +void queue_clear(struct queue *); + /* Called to tell the queue that a track has been updated. */ void queue_updated(struct queue *, struct track *); diff --git a/include/gui/queue/model.h b/include/gui/queue/model.h index 49e41420..b10551ce 100644 --- a/include/gui/queue/model.h +++ b/include/gui/queue/model.h @@ -35,6 +35,7 @@ public: void on_row_inserted(unsigned int); void on_row_deleted(unsigned int); void on_row_changed(unsigned int); + void on_cleared(unsigned int); void on_path_selected(const Gtk::TreePath &); unsigned int iter_to_id(const Gtk::TreeIter &) const; unsigned int path_to_id(const Gtk::TreePath &) const; diff --git a/include/gui/tabs.h b/include/gui/tabs.h index 22721887..ef791692 100644 --- a/include/gui/tabs.h +++ b/include/gui/tabs.h @@ -39,6 +39,7 @@ public: */ void on_track_added(unsigned int); virtual void on_track_removed(unsigned int); + void on_tracks_cleared(unsigned int); void on_track_updated(unsigned int); /** diff --git a/tests/core/queue.c b/tests/core/queue.c index 733ab43a..72cbd1dd 100644 --- a/tests/core/queue.c +++ b/tests/core/queue.c @@ -10,6 +10,7 @@ unsigned int count_added = 0; unsigned int count_deleted = 0; +unsigned int count_cleared = 0; unsigned int count_flags = 0; unsigned int count_sort = 0; unsigned int count_updated = 0; @@ -25,6 +26,11 @@ static void queue_op_removed(struct queue *queue, unsigned int pos) count_deleted++; } +static void queue_op_cleared(struct queue *queue, unsigned int n) +{ + count_cleared++; +} + static void queue_op_save(struct queue *queue, enum queue_flags flag) { if (flag == Q_SAVE_FLAGS) @@ -40,10 +46,11 @@ static void queue_op_updated(struct queue *queue, unsigned int pos) static const struct queue_ops test_ops = { - queue_op_added, - queue_op_removed, - queue_op_save, - queue_op_updated, + .qop_added = queue_op_added, + .qop_removed = queue_op_removed, + .qop_cleared = queue_op_cleared, + .qop_save = queue_op_save, + .qop_updated = queue_op_updated, }; @@ -157,6 +164,7 @@ static void test_stress(unsigned int N) count_added = 0; count_deleted = 0; + count_cleared = 0; count_updated = 0; queue_init(&q, 0, &test_ops); @@ -210,15 +218,24 @@ static void test_stress(unsigned int N) /* Tracks should be removed. */ queue_unset_flag(&q, Q_REPEAT); - for (i = 0; i < ex_size; i++) { - test_loop_equal((void *)queue_next(&q), + for (i = 0; i < ex_size / 2; i++) { + track = queue_next(&q); + ex_length -= track->tr_length; + ex_size--; + + test_loop_equal((void *)track, (void *)track_get((i % 11) + 2), i); - test_loop_equal(queue_size(&q), ex_size - (i + 1), i); + test_loop_equal(queue_size(&q), ex_size, i); + test_loop_equal(q.q_length, ex_length, i); } test_loop_passed(); + queue_clear(&q); + test_equal(count_cleared, 1); + test_equal(queue_size(&q), 0); + test_equal(q.q_length, 0); + queue_deinit(&q); - test_equal(q.q_length, 0); - test_equal(queue_size(&q), 0); + test_equal(count_cleared, 2); test_equal((void *)q.q_sort, NULL); }