/* * Copyright 2016 (c) Anna Schumaker. */ #include #include #include #include #include enum playlist_sidebar_columns { P_SB_IMAGE, P_SB_NAME, }; static GtkTreeStore *p_store; static gchar *p_name = NULL; static void __playlist_set(GtkTreeIter *iter, const gchar *name, const gchar *image) { gtk_tree_store_set(p_store, iter, P_SB_NAME, name, P_SB_IMAGE, image, -1); } static void __playlist_set_size(GtkTreeIter *iter, const gchar *name) { unsigned int size = playlist_size(name); const gchar *fmt = "%s\n%d track%s"; gchar *text; text = g_strdup_printf(fmt, name, size, (size == 1) ? "" : "s"); gtk_tree_store_set(p_store, iter, P_SB_NAME, text, -1); g_free(text); } static void __playlist_add(GtkTreeIter *parent, const gchar *name, const gchar *image) { GtkTreeIter iter; gtk_tree_store_insert(p_store, &iter, parent, -1); __playlist_set(&iter, name, image); __playlist_set_size(&iter, name); } static gchar *__playlist_name(GtkTreeIter *iter) { GtkTreeModel *model = GTK_TREE_MODEL(p_store); gchar **split, *name; gtk_tree_model_get(model, iter, P_SB_NAME, &name, -1); split = g_strsplit(name, "\n", 2); name = g_strdup(split[0]); g_strfreev(split); return name; } void __playlist_selection_changed(GtkTreeSelection *selection, gpointer data) { GtkStack *stack = GTK_STACK(gui_builder_widget("o_stack")); GtkTreeModel *model = GTK_TREE_MODEL(p_store); GtkTreeIter iter; if (gtk_tree_selection_get_selected(selection, &model, &iter)) { if (p_name) g_free(p_name); p_name = __playlist_name(&iter); gtk_stack_set_visible_child_name(stack, "queues"); gui_sidebar_selected(SB_PLAYLIST, gui_queue(playlist_get_queue(p_name))); } } static void __playlist_update_sizes(struct queue *queue) { GtkTreeModel *model = GTK_TREE_MODEL(p_store); GtkTreeIter parent, iter; gchar *name; if (!gtk_tree_model_get_iter_first(model, &parent)) return; gtk_tree_model_iter_next(model, &parent); if (!gtk_tree_model_iter_children(model, &iter, &parent)) return; do { name = __playlist_name(&iter); if (string_match(name, gui_queue(queue)->gq_text)) __playlist_set_size(&iter, name); g_free(name); } while (gtk_tree_model_iter_next(model, &iter)); } static void *__playlist_init(struct queue *queue, void *data) { struct playlist *playlist = (struct playlist *)data; return gui_queue_alloc(queue, playlist->pl_name, 0); } static void __playlist_added(struct queue *queue, unsigned int row) { gui_queue_added(queue, row); __playlist_update_sizes(queue); } static void __playlist_removed(struct queue *queue, unsigned int row) { gui_queue_removed(queue, row); __playlist_update_sizes(queue); } static bool __playlist_erase(struct queue *queue, struct track *track) { /* collection_unban() and playlist_remove() handle queue changes */ if (string_match(gui_playlist_cur(), "Hidden")) collection_unban(track); else playlist_remove(gui_playlist_cur(), track); return false; } void gui_playlist_init() { GtkTreeView *treeview; GtkTreeIter parent; p_store = GTK_TREE_STORE(gui_builder_object("o_playlist_store")); /* Add "Playlist" header. */ gtk_tree_store_insert(p_store, &parent, NULL, -1); gtk_tree_store_insert(p_store, &parent, NULL, -1); __playlist_set(&parent, "Playlists", "emblem-documents"); /* Add playlists. */ __playlist_add(&parent, "Favorites", "emblem-favorite"); __playlist_add(&parent, "Hidden", "window-close"); __playlist_add(&parent, "Most Played", "go-up"); __playlist_add(&parent, "Least Played", "go-down"); __playlist_add(&parent, "Unplayed", "audio-x-generic"); treeview = GTK_TREE_VIEW(gui_builder_widget("o_playlist_view")); gtk_tree_view_expand_all(treeview); gtk_tree_selection_set_select_function( gtk_tree_view_get_selection(treeview), gui_sidebar_on_select, NULL, NULL); gtk_tree_store_insert(p_store, &parent, NULL, -1); } gchar *gui_playlist_cur() { return p_name; } struct queue_ops playlist_ops = { .qop_init = __playlist_init, .qop_deinit = gui_queue_free, .qop_added = __playlist_added, .qop_erase = __playlist_erase, .qop_removed = __playlist_removed, .qop_cleared = gui_queue_cleared, .qop_updated = gui_queue_updated, };