2016-01-01 19:58:30 -05:00
|
|
|
/*
|
|
|
|
* Copyright 2016 (c) Anna Schumaker.
|
|
|
|
*/
|
2016-05-15 19:53:59 -04:00
|
|
|
#include <core/idle.h>
|
2016-08-01 10:24:52 -04:00
|
|
|
#include <core/settings.h>
|
2016-04-27 09:25:37 -04:00
|
|
|
#include <core/string.h>
|
2016-01-01 19:58:30 -05:00
|
|
|
#include <gui/builder.h>
|
2016-08-22 10:15:09 -04:00
|
|
|
#include <gui/filter.h>
|
2016-08-26 10:19:45 -04:00
|
|
|
#include <gui/model.h>
|
2016-01-01 19:58:30 -05:00
|
|
|
#include <gui/playlist.h>
|
2016-08-25 07:44:02 -04:00
|
|
|
#include <gui/sidebar.h>
|
2016-01-01 19:58:30 -05:00
|
|
|
|
2016-08-01 10:24:52 -04:00
|
|
|
static void __playlist_update_sizes(struct queue *);
|
2016-05-15 19:46:28 -04:00
|
|
|
|
2016-08-01 10:24:52 -04:00
|
|
|
void __playlist_row_activated(GtkTreeView *treeview, GtkTreePath *path,
|
|
|
|
GtkTreeViewColumn *col, gpointer data)
|
|
|
|
{
|
2016-08-31 16:55:19 -04:00
|
|
|
gui_sidebar_filter_path_select(path);
|
|
|
|
__playlist_update_sizes(&playlist_cur()->pl_queue);
|
2016-08-01 10:24:52 -04:00
|
|
|
}
|
|
|
|
|
2016-05-03 11:20:31 -04:00
|
|
|
static bool __playlist_queue_set_size(struct queue *queue, GtkTreeIter *iter)
|
|
|
|
{
|
2016-08-26 10:19:45 -04:00
|
|
|
struct playlist *playlist = queue->q_private;
|
|
|
|
bool match = (gui_sidebar_iter_type(iter) == playlist->pl_type);
|
2016-08-25 10:58:24 -04:00
|
|
|
gchar *name = gui_sidebar_iter_name(iter);
|
2016-05-03 11:20:31 -04:00
|
|
|
|
2016-05-15 19:46:28 -04:00
|
|
|
if (match)
|
2016-08-26 10:19:45 -04:00
|
|
|
match = string_match(name, playlist->pl_name);
|
2016-05-03 11:20:31 -04:00
|
|
|
if (match)
|
2016-08-30 14:13:02 -04:00
|
|
|
gui_sidebar_iter_update(iter);
|
2016-05-03 11:20:31 -04:00
|
|
|
g_free(name);
|
|
|
|
|
|
|
|
return match;
|
|
|
|
}
|
|
|
|
|
2016-05-02 08:42:28 -04:00
|
|
|
static void __playlist_update_sizes(struct queue *queue)
|
2016-04-28 11:06:50 -04:00
|
|
|
{
|
2016-08-31 11:48:09 -04:00
|
|
|
struct playlist *playlist = queue->q_private;
|
2016-07-29 10:12:57 -04:00
|
|
|
GtkTreeModelFilter *filter;
|
2016-04-28 11:06:50 -04:00
|
|
|
GtkTreeIter parent, iter;
|
|
|
|
|
2016-08-31 11:48:09 -04:00
|
|
|
if (playlist->pl_type == PL_LIBRARY) {
|
|
|
|
gui_pl_library_update(playlist);
|
|
|
|
return;
|
2016-09-01 08:19:31 -04:00
|
|
|
} else if (playlist->pl_type == PL_ARTIST) {
|
|
|
|
gui_pl_artist_update(playlist);
|
|
|
|
return;
|
2016-09-01 09:22:59 -04:00
|
|
|
} else if (playlist->pl_type == PL_USER) {
|
|
|
|
gui_pl_user_update(playlist);
|
|
|
|
return;
|
2016-08-31 11:48:09 -04:00
|
|
|
}
|
|
|
|
|
2016-08-25 10:58:24 -04:00
|
|
|
if (!gui_sidebar_iter_first(&parent))
|
2016-04-28 11:06:50 -04:00
|
|
|
return;
|
|
|
|
|
|
|
|
do {
|
2016-05-03 11:20:31 -04:00
|
|
|
if (__playlist_queue_set_size(queue, &parent))
|
2016-07-29 10:12:57 -04:00
|
|
|
goto out;
|
2016-08-25 07:44:02 -04:00
|
|
|
if (gtk_tree_model_iter_children(gui_sidebar_model(), &iter, &parent)) {
|
2016-05-03 11:20:31 -04:00
|
|
|
do {
|
|
|
|
if (__playlist_queue_set_size(queue, &iter))
|
2016-07-29 10:12:57 -04:00
|
|
|
goto out;
|
2016-08-25 10:58:24 -04:00
|
|
|
} while (gui_sidebar_iter_next(&iter));
|
2016-05-03 11:20:31 -04:00
|
|
|
}
|
2016-08-25 10:58:24 -04:00
|
|
|
} while (gui_sidebar_iter_next(&parent));
|
2016-07-29 10:12:57 -04:00
|
|
|
|
|
|
|
out:
|
2016-08-25 07:50:16 -04:00
|
|
|
filter = gui_sidebar_filter();
|
2016-07-29 10:12:57 -04:00
|
|
|
gtk_tree_model_filter_refilter(filter);
|
2016-04-28 11:06:50 -04:00
|
|
|
}
|
|
|
|
|
2016-05-02 07:52:18 -04:00
|
|
|
static void *__playlist_init(struct queue *queue, void *data)
|
2016-01-21 09:42:37 -05:00
|
|
|
{
|
2016-05-02 08:42:28 -04:00
|
|
|
struct playlist *playlist = (struct playlist *)data;
|
2016-05-03 11:20:31 -04:00
|
|
|
|
2016-09-01 09:22:59 -04:00
|
|
|
if (playlist->pl_type == PL_ARTIST)
|
2016-09-01 08:19:31 -04:00
|
|
|
gui_pl_artist_add(playlist);
|
2016-08-26 10:19:45 -04:00
|
|
|
return playlist;
|
2016-01-21 09:42:37 -05:00
|
|
|
}
|
|
|
|
|
2016-08-22 10:15:09 -04:00
|
|
|
static void __playlist_deinit(struct queue *queue)
|
|
|
|
{
|
2016-08-26 10:19:45 -04:00
|
|
|
gui_filter_clear_search(queue->q_private);
|
2016-08-22 10:15:09 -04:00
|
|
|
}
|
|
|
|
|
2016-04-28 11:06:50 -04:00
|
|
|
static void __playlist_added(struct queue *queue, unsigned int row)
|
|
|
|
{
|
2016-08-26 10:19:45 -04:00
|
|
|
gui_model_add(queue->q_private, row);
|
2016-05-02 08:42:28 -04:00
|
|
|
__playlist_update_sizes(queue);
|
2016-04-28 11:06:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void __playlist_removed(struct queue *queue, unsigned int row)
|
|
|
|
{
|
2016-08-26 10:19:45 -04:00
|
|
|
gui_model_remove(queue->q_private, row);
|
2016-05-02 08:42:28 -04:00
|
|
|
__playlist_update_sizes(queue);
|
2016-04-28 11:06:50 -04:00
|
|
|
}
|
|
|
|
|
2016-07-28 11:57:39 -04:00
|
|
|
static void __playlist_cleared(struct queue *queue, unsigned int n)
|
|
|
|
{
|
2016-08-26 10:19:45 -04:00
|
|
|
gui_model_clear(queue->q_private, n);
|
2016-07-28 11:57:39 -04:00
|
|
|
__playlist_update_sizes(queue);
|
|
|
|
}
|
|
|
|
|
2016-08-20 21:01:19 -04:00
|
|
|
static void __playlist_updated(struct queue *queue, unsigned int n)
|
|
|
|
{
|
2016-08-26 10:19:45 -04:00
|
|
|
gui_model_update(queue->q_private, n);
|
2016-08-20 21:01:19 -04:00
|
|
|
}
|
|
|
|
|
2016-01-21 09:42:37 -05:00
|
|
|
static bool __playlist_erase(struct queue *queue, struct track *track)
|
|
|
|
{
|
2016-08-26 10:19:45 -04:00
|
|
|
struct playlist *playlist = queue->q_private;
|
|
|
|
enum playlist_type_t type = playlist->pl_type;
|
|
|
|
const gchar *name = playlist->pl_name;
|
2016-08-16 08:35:32 -04:00
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case PL_SYSTEM:
|
|
|
|
if (string_match(name, "Collection"))
|
|
|
|
name = "Hidden";
|
|
|
|
else if (!string_match(name, "Favorites") &&
|
|
|
|
!string_match(name, "Hidden") &&
|
|
|
|
!string_match(name, "Queued Tracks"))
|
|
|
|
break;
|
|
|
|
case PL_USER:
|
|
|
|
playlist_remove(type, name, track);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
|
2016-01-21 09:42:37 -05:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-05-15 19:53:59 -04:00
|
|
|
bool __gui_playlist_init_idle()
|
|
|
|
{
|
2016-07-29 10:12:57 -04:00
|
|
|
GtkTreeSelection *selection;
|
|
|
|
GtkTreeModel *filter;
|
|
|
|
GtkTreeIter iter;
|
2016-05-15 19:53:59 -04:00
|
|
|
|
2016-08-25 07:50:16 -04:00
|
|
|
filter = GTK_TREE_MODEL(gui_sidebar_filter());
|
2016-09-01 09:22:59 -04:00
|
|
|
selection = gtk_tree_view_get_selection(gui_sidebar_treeview());
|
2016-07-29 10:12:57 -04:00
|
|
|
gtk_tree_model_get_iter_first(filter, &iter);
|
|
|
|
gtk_tree_selection_select_iter(selection, &iter);
|
|
|
|
|
2016-05-15 19:53:59 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-01-01 19:58:30 -05:00
|
|
|
void gui_playlist_init()
|
|
|
|
{
|
2016-01-04 07:55:10 -05:00
|
|
|
GtkTreeIter parent;
|
2016-01-01 19:58:30 -05:00
|
|
|
|
2016-08-25 10:05:27 -04:00
|
|
|
gui_sidebar_iter_first(&parent);
|
|
|
|
gui_sidebar_iter_add(&parent, playlist_get(PL_SYSTEM, "Queued Tracks"),
|
|
|
|
"audio-x-generic");
|
|
|
|
gui_sidebar_iter_add(&parent, playlist_get(PL_SYSTEM, "Collection"),
|
|
|
|
"media-optical");
|
|
|
|
gui_sidebar_iter_add(&parent, playlist_get(PL_SYSTEM, "History"),
|
|
|
|
"document-open-recent");
|
2016-05-03 11:20:31 -04:00
|
|
|
|
2016-08-22 12:06:03 -04:00
|
|
|
/* Add "Playlists" header and playlists. */
|
2016-08-25 10:34:00 -04:00
|
|
|
gui_sidebar_iter_find(&parent, "Playlists", PL_MAX_TYPE);
|
2016-08-25 11:41:40 -04:00
|
|
|
gui_sidebar_iter_append_child(&parent, playlist_get(PL_SYSTEM, "Favorites"),
|
|
|
|
"emblem-favorite");
|
|
|
|
gui_sidebar_iter_append_child(&parent, playlist_get(PL_SYSTEM, "Hidden"),
|
|
|
|
"window-close");
|
2016-08-16 08:35:32 -04:00
|
|
|
|
2016-08-22 12:06:03 -04:00
|
|
|
/* Add "Dynamic" header. */
|
2016-08-25 10:34:00 -04:00
|
|
|
gui_sidebar_iter_find(&parent, "Dynamic", PL_MAX_TYPE);
|
2016-08-25 11:41:40 -04:00
|
|
|
gui_sidebar_iter_append_child(&parent, playlist_get(PL_SYSTEM, "Most Played"),
|
|
|
|
"go-up");
|
|
|
|
gui_sidebar_iter_append_child(&parent, playlist_get(PL_SYSTEM, "Least Played"),
|
|
|
|
"go-down");
|
|
|
|
gui_sidebar_iter_append_child(&parent, playlist_get(PL_SYSTEM, "Unplayed"),
|
|
|
|
"audio-x-generic");
|
2016-01-01 19:58:30 -05:00
|
|
|
|
2016-05-15 19:53:59 -04:00
|
|
|
idle_schedule(IDLE_SYNC, __gui_playlist_init_idle, NULL);
|
2016-08-31 08:08:26 -04:00
|
|
|
|
2016-09-01 08:19:31 -04:00
|
|
|
gui_pl_artist_init();
|
2016-09-01 09:22:59 -04:00
|
|
|
gui_pl_user_init();
|
2016-08-31 08:08:26 -04:00
|
|
|
gui_pl_library_init();
|
2016-01-01 19:58:30 -05:00
|
|
|
}
|
2016-01-04 08:15:55 -05:00
|
|
|
|
2016-08-26 09:25:17 -04:00
|
|
|
const gchar *gui_playlist_cur()
|
2016-01-04 08:15:55 -05:00
|
|
|
{
|
2016-08-26 09:25:17 -04:00
|
|
|
if (gui_model_get_playlist())
|
|
|
|
return gui_model_get_playlist()->pl_name;
|
|
|
|
return NULL;
|
2016-01-04 08:15:55 -05:00
|
|
|
}
|
2016-01-21 09:42:37 -05:00
|
|
|
|
|
|
|
struct queue_ops playlist_ops = {
|
|
|
|
.qop_init = __playlist_init,
|
2016-08-22 10:15:09 -04:00
|
|
|
.qop_deinit = __playlist_deinit,
|
2016-04-28 11:06:50 -04:00
|
|
|
.qop_added = __playlist_added,
|
2016-01-21 09:42:37 -05:00
|
|
|
.qop_erase = __playlist_erase,
|
2016-04-28 11:06:50 -04:00
|
|
|
.qop_removed = __playlist_removed,
|
2016-07-28 11:57:39 -04:00
|
|
|
.qop_cleared = __playlist_cleared,
|
2016-08-20 21:01:19 -04:00
|
|
|
.qop_updated = __playlist_updated,
|
2016-01-21 09:42:37 -05:00
|
|
|
};
|