/* * Copyright 2016 (c) Anna Schumaker. */ #include #include #include static GtkTreeModelFilter *filter_model = NULL; static gchar **filter_search = 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) { struct track *track; unsigned int i, how = gtk_combo_box_get_active(gui_filter_how()); if (!filter_search) return TRUE; track = gui_model_iter_get_track(iter); for (i = 0; filter_search[i]; i++) { if (!__gui_filter_match_token(track, filter_search[i], how)) return FALSE; } return TRUE; } void __gui_filter_search_changed(GtkSearchEntry *search, gpointer data) { const gchar *text = gtk_entry_get_text(GTK_ENTRY(search)); if (!gui_model_get_playlist()) return; if (strlen(text) > 0) filter_search = g_str_tokenize_and_fold(text, NULL, NULL); gtk_tree_model_filter_refilter(gui_filter_get()); g_strfreev(filter_search); filter_search = NULL; } 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)); } 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; } 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; }