ocarina/gui/filter.c

114 lines
2.8 KiB
C

/*
* Copyright 2016 (c) Anna Schumaker.
*/
#include <core/string.h>
#include <gui/filter.h>
#include <gui/model.h>
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;
}