/* * Copyright 2016 (c) Anna Schumaker. */ #include #include #include #include static GtkTreeModelFilter *filter_model = NULL; static inline GtkTreePath *__gui_filter_convert_path(GtkTreePath *path) { return gtk_tree_model_filter_convert_path_to_child_path(filter_model, path); } static inline gboolean __gui_filter_match_token(struct track *track, const gchar *token, unsigned int how) { switch (how) { case GUI_FILTER_ALBUM: return album_match_token(track->tr_album, token); case GUI_FILTER_ARTIST: return artist_match_token(track->tr_album->al_artist, token); case GUI_FILTER_GENRE: return genre_match_token(track->tr_album->al_genre, token); case GUI_FILTER_TITLE: return track_match_token(track, token); case GUI_FILTER_DEFAULT: return track_match_token(track, token) || album_match_token(track->tr_album, token) || artist_match_token(track->tr_album->al_artist, token) || genre_match_token(track->tr_album->al_genre, token); default: return false; } } static gboolean __gui_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { unsigned int i, how = gtk_combo_box_get_active(gui_filter_how()); gchar **search = gui_model_get_playlist()->pl_search; struct track *track; if (!search) return TRUE; track = gui_model_iter_get_track(iter); for (i = 0; search[i]; i++) { if (!__gui_filter_match_token(track, search[i], how)) return FALSE; } return TRUE; } void __gui_filter_search_changed(GtkSearchEntry *search, gpointer data) { playlist_set_search(gui_model_get_playlist(), gtk_entry_get_text(GTK_ENTRY(search))); gtk_tree_model_filter_refilter(gui_filter_get()); } void __gui_filter_how_changed(int n) { __gui_filter_search_changed(gui_filter_search(), NULL); } void gui_filter_init() { GtkTreeModel *model = GTK_TREE_MODEL(gui_model_get()); GtkTreeModel *filter = gtk_tree_model_filter_new(model, NULL); filter_model = GTK_TREE_MODEL_FILTER(filter); gtk_tree_model_filter_set_visible_func(filter_model, __gui_filter_visible_func, NULL, NULL); } void gui_filter_deinit() { g_object_unref(G_OBJECT(filter_model)); } void gui_filter_set_playlist(struct playlist *playlist) { gchar **search = playlist ? (gchar **)playlist->pl_search : NULL; gchar *text = search ? g_strjoinv(" ", search) : g_strdup(""); gui_model_set_playlist(playlist); gtk_entry_set_text(GTK_ENTRY(gui_filter_search()), text); g_free(text); } GtkTreeModelFilter *gui_filter_get() { return filter_model; } struct track *gui_filter_path_get_track(GtkTreePath *path) { GtkTreePath *real = __gui_filter_convert_path(path); struct track *track = real ? gui_model_path_get_track(real) : NULL; gtk_tree_path_free(real); return track; } void gui_filter_path_load_track(GtkTreePath *path) { struct track *track = gui_filter_path_get_track(path); unsigned int index = gtk_tree_path_get_indices(path)[0]; audio_load(track); playlist_current_set(gui_model_get_playlist(), index); } unsigned int gui_filter_path_get_index(GtkTreePath *path) { GtkTreePath *real = __gui_filter_convert_path(path); unsigned int ret = gtk_tree_path_get_indices(real)[0]; gtk_tree_path_free(real); return ret; } GtkTreePath *gui_filter_path_from_index(unsigned int index) { GtkTreePath *real, *path; real = gtk_tree_path_new_from_indices(index, -1); path = gtk_tree_model_filter_convert_child_path_to_path(filter_model, real); gtk_tree_path_free(real); return path; }