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-04-27 09:25:37 -04:00
|
|
|
#include <core/string.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-09-03 11:19:32 -04:00
|
|
|
#include <gui/treeview.h>
|
2016-08-25 07:44:02 -04:00
|
|
|
#include <gui/sidebar.h>
|
2016-01-01 19:58:30 -05:00
|
|
|
|
2016-09-02 10:02:58 -04:00
|
|
|
static void (*update_size[PL_MAX_TYPE])(struct playlist *) = {
|
|
|
|
[PL_SYSTEM] = gui_pl_system_update,
|
|
|
|
[PL_ARTIST] = gui_pl_artist_update,
|
|
|
|
[PL_LIBRARY] = gui_pl_library_update,
|
|
|
|
[PL_USER] = gui_pl_user_update,
|
|
|
|
};
|
2016-05-15 19:46:28 -04:00
|
|
|
|
2017-04-04 11:24:56 -04:00
|
|
|
static void (*select_playlist[PL_MAX_TYPE])(struct playlist *) = {
|
|
|
|
[PL_SYSTEM] = gui_pl_system_select,
|
|
|
|
[PL_ARTIST] = gui_pl_artist_select,
|
|
|
|
[PL_LIBRARY] = gui_pl_library_select,
|
|
|
|
[PL_USER] = gui_pl_user_select,
|
|
|
|
};
|
|
|
|
|
2016-09-02 10:02:58 -04:00
|
|
|
static inline void __gui_playlist_update_size(struct playlist *playlist)
|
2016-08-01 10:24:52 -04:00
|
|
|
{
|
2016-09-02 10:02:58 -04:00
|
|
|
update_size[playlist->pl_type](playlist);
|
2016-05-03 11:20:31 -04:00
|
|
|
}
|
|
|
|
|
2016-09-22 11:32:40 -04:00
|
|
|
static void __gui_playlist_alloc(struct playlist *playlist)
|
|
|
|
{
|
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-01-21 09:42:37 -05:00
|
|
|
}
|
|
|
|
|
2016-09-21 09:36:44 -04:00
|
|
|
static void __gui_playlist_added(struct playlist *playlist, struct track *track)
|
2016-04-28 11:06:50 -04:00
|
|
|
{
|
2016-09-21 09:36:44 -04:00
|
|
|
gui_model_add(playlist, track);
|
|
|
|
__gui_playlist_update_size(playlist);
|
|
|
|
}
|
|
|
|
|
2016-09-21 08:15:47 -04:00
|
|
|
static void __gui_playlist_removed(struct playlist *playlist, struct track *track,
|
|
|
|
unsigned int n)
|
2016-04-28 11:06:50 -04:00
|
|
|
{
|
2016-09-21 08:15:47 -04:00
|
|
|
gui_model_remove(playlist, track, n);
|
2016-09-20 14:38:46 -04:00
|
|
|
__gui_playlist_update_size(playlist);
|
2016-04-28 11:06:50 -04:00
|
|
|
}
|
|
|
|
|
2016-09-03 10:03:40 -04:00
|
|
|
|
2016-09-17 09:30:11 -04:00
|
|
|
struct playlist_callbacks playlist_cb = {
|
2016-09-22 11:32:40 -04:00
|
|
|
.pl_cb_alloc = __gui_playlist_alloc,
|
2016-09-21 09:36:44 -04:00
|
|
|
.pl_cb_added = __gui_playlist_added,
|
2016-09-20 14:38:46 -04:00
|
|
|
.pl_cb_removed = __gui_playlist_removed,
|
2016-09-20 11:01:32 -04:00
|
|
|
.pl_cb_updated = gui_model_update,
|
2016-09-17 09:30:11 -04:00
|
|
|
};
|
|
|
|
|
2016-09-03 10:03:40 -04:00
|
|
|
|
2016-09-03 11:19:32 -04:00
|
|
|
static void __gui_playlist_add_selected_to(struct playlist *playlist)
|
|
|
|
{
|
|
|
|
GList *cur, *list = NULL;
|
|
|
|
struct track *track;
|
|
|
|
|
|
|
|
if (!playlist)
|
|
|
|
return;
|
|
|
|
|
|
|
|
list = gui_treeview_list_selected_tracks();
|
|
|
|
cur = g_list_first(list);
|
|
|
|
while (cur) {
|
|
|
|
track = (struct track *)cur->data;
|
2016-09-10 12:08:11 -04:00
|
|
|
playlist_add(playlist, track);
|
2016-09-03 11:19:32 -04:00
|
|
|
cur = g_list_next(cur);
|
|
|
|
}
|
|
|
|
g_list_free(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
void __gui_playlist_add_favorites(GtkMenuItem *item, gpointer data)
|
|
|
|
{
|
2016-09-12 13:49:27 -04:00
|
|
|
__gui_playlist_add_selected_to(playlist_lookup(PL_SYSTEM, "Favorites"));
|
2016-09-03 11:19:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void __gui_playlist_add_hidden(GtkMenuItem *item, gpointer data)
|
|
|
|
{
|
2016-09-12 13:49:27 -04:00
|
|
|
__gui_playlist_add_selected_to(playlist_lookup(PL_SYSTEM, "Hidden"));
|
2016-09-03 11:19:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void __gui_playlist_add_user(GtkMenuItem *item, gpointer data)
|
|
|
|
{
|
|
|
|
__gui_playlist_add_selected_to(gui_pl_user_add_dialog());
|
|
|
|
}
|
|
|
|
|
2016-09-03 12:49:15 -04:00
|
|
|
void __gui_playlist_add_other(GtkMenuItem *item, gpointer data)
|
|
|
|
{
|
|
|
|
__gui_playlist_add_selected_to(data);
|
|
|
|
}
|
|
|
|
|
2016-09-03 11:19:32 -04:00
|
|
|
void __gui_playlist_add_queued(GtkMenuItem *item, gpointer data)
|
|
|
|
{
|
2016-09-12 13:49:27 -04:00
|
|
|
__gui_playlist_add_selected_to(playlist_lookup(PL_SYSTEM, "Queued Tracks"));
|
2016-09-03 11:19:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void __gui_playlist_delete(GtkMenuItem *item, gpointer data)
|
|
|
|
{
|
|
|
|
struct playlist *playlist = gui_model_get_playlist();
|
|
|
|
GList *cur, *list = NULL;
|
|
|
|
struct track *track;
|
|
|
|
|
|
|
|
if (!playlist)
|
|
|
|
return;
|
|
|
|
|
|
|
|
list = gui_treeview_list_selected_tracks();
|
|
|
|
cur = g_list_first(list);
|
|
|
|
while (cur) {
|
|
|
|
track = (struct track *)cur->data;
|
2016-09-10 13:11:18 -04:00
|
|
|
playlist_remove(playlist, track);
|
2016-09-03 11:19:32 -04:00
|
|
|
cur = g_list_next(cur);
|
|
|
|
}
|
|
|
|
g_list_free(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
void __gui_playlist_keypress(GtkTreeView *treeview, GdkEventKey *event,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
switch (event->keyval) {
|
|
|
|
case GDK_KEY_f:
|
|
|
|
__gui_playlist_add_favorites(NULL, NULL);
|
|
|
|
break;
|
|
|
|
case GDK_KEY_h:
|
|
|
|
__gui_playlist_add_hidden(NULL, NULL);
|
|
|
|
break;
|
|
|
|
case GDK_KEY_p:
|
|
|
|
__gui_playlist_add_user(NULL, NULL);
|
|
|
|
break;
|
|
|
|
case GDK_KEY_q:
|
|
|
|
__gui_playlist_add_queued(NULL, NULL);
|
|
|
|
break;
|
|
|
|
case GDK_KEY_Delete:
|
|
|
|
__gui_playlist_delete(NULL, NULL);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-03 12:49:15 -04:00
|
|
|
static GtkWidget *__gui_playlist_build_submenu(void)
|
|
|
|
{
|
|
|
|
struct playlist *playlist;
|
|
|
|
GList *list = gui_pl_user_list();
|
|
|
|
GList *cur = g_list_first(list);
|
|
|
|
GtkWidget *submenu, *item;
|
|
|
|
|
|
|
|
if (!list)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
submenu = gtk_menu_new();
|
|
|
|
while (cur) {
|
|
|
|
playlist = (struct playlist *)cur->data;
|
|
|
|
item = gtk_menu_item_new_with_label(playlist->pl_name);
|
|
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item);
|
|
|
|
g_signal_connect(item, "activate",
|
|
|
|
G_CALLBACK(__gui_playlist_add_other),
|
|
|
|
playlist);
|
|
|
|
cur = g_list_next(cur);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_widget_show_all(submenu);
|
|
|
|
g_list_free(list);
|
|
|
|
return submenu;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool __gui_playlist_button_press(GtkTreeView *treeview, GdkEventButton *event,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
GtkWidget *submenu;
|
|
|
|
|
|
|
|
if (event->button != GDK_BUTTON_SECONDARY)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
submenu = __gui_playlist_build_submenu();
|
|
|
|
gtk_menu_item_set_submenu(gui_rc_add_to_other(), submenu);
|
|
|
|
gtk_widget_set_visible(GTK_WIDGET(gui_rc_add_to_other()),
|
|
|
|
submenu != NULL);
|
|
|
|
|
|
|
|
gui_treeview_select_path_at_pos(event->x, event->y);
|
|
|
|
gtk_menu_popup_at_pointer(gui_rc_menu(), (GdkEvent *)event);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-09-03 10:03:40 -04:00
|
|
|
void __gui_playlist_row_activated(GtkTreeView *treeview, GtkTreePath *path,
|
|
|
|
GtkTreeViewColumn *col, gpointer data)
|
|
|
|
{
|
2016-09-12 16:02:46 -04:00
|
|
|
struct playlist *prev = playlist_current();
|
2016-09-03 10:03:40 -04:00
|
|
|
|
|
|
|
gui_sidebar_filter_path_select(path);
|
|
|
|
__gui_playlist_update_size(prev);
|
2016-09-12 16:02:46 -04:00
|
|
|
__gui_playlist_update_size(playlist_current());
|
2016-09-03 10:03:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void __gui_playlist_row_collapsed(GtkTreeView *treeview, GtkTreeIter *iter,
|
|
|
|
GtkTreePath *path, gpointer data)
|
|
|
|
{
|
|
|
|
gui_sidebar_filter_row_expanded(iter, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void __gui_playlist_row_expanded(GtkTreeView *treeview, GtkTreeIter *iter,
|
|
|
|
GtkTreePath *path, gpointer data)
|
|
|
|
{
|
|
|
|
gui_sidebar_filter_row_expanded(iter, true);
|
|
|
|
}
|
|
|
|
|
2016-05-15 19:53:59 -04:00
|
|
|
bool __gui_playlist_init_idle()
|
|
|
|
{
|
2016-09-12 16:02:46 -04:00
|
|
|
struct playlist *playlist = playlist_current();
|
2017-04-04 11:24:56 -04:00
|
|
|
GtkTreeModel *filter = GTK_TREE_MODEL(gui_sidebar_filter());
|
|
|
|
GtkTreeIter iter;
|
2016-05-15 19:53:59 -04:00
|
|
|
|
2016-07-29 10:12:57 -04:00
|
|
|
gtk_tree_model_get_iter_first(filter, &iter);
|
2017-04-04 10:23:12 -04:00
|
|
|
do {
|
|
|
|
gui_sidebar_filter_set_expand(&iter);
|
|
|
|
} while (gtk_tree_model_iter_next(filter, &iter));
|
|
|
|
|
2017-04-04 11:24:56 -04:00
|
|
|
select_playlist[playlist->pl_type](playlist);
|
2016-05-15 19:53:59 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-01-01 19:58:30 -05:00
|
|
|
void gui_playlist_init()
|
|
|
|
{
|
2016-09-02 09:22:14 -04:00
|
|
|
gui_pl_system_init();
|
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-09-02 09:22:14 -04:00
|
|
|
|
|
|
|
idle_schedule(IDLE_SYNC, __gui_playlist_init_idle, NULL);
|
2016-01-01 19:58:30 -05:00
|
|
|
}
|