gui/queue: Switch over to using token matches for filtering

This patch also adds the genre field to the list of fields that can be
searched.

Implements #62: Replace filter layer with token matching
Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2016-05-19 12:29:04 -04:00 committed by Anna Schumaker
parent d16e06111d
commit 2e753b6f52
2 changed files with 29 additions and 19 deletions

View File

@ -71,14 +71,25 @@ static gboolean __queue_visible_func(GtkTreeModel *model, GtkTreeIter *iter,
gpointer data)
{
struct track *track;
unsigned int i;
gchar *token;
if (!gq_queue || (strlen(gtk_entry_get_text(GTK_ENTRY(data))) == 0))
if (!gq_queue || !gq_queue->gq_search)
return TRUE;
if (!gq_queue->gq_visible)
return FALSE;
track = gui_queue_model_iter_get_track(gq_queue->gq_model, iter);
return g_hash_table_contains(gq_queue->gq_visible, track);
for (i = 0; gq_queue->gq_search[i]; i++) {
token = gq_queue->gq_search[i];
if (!track_match_token(track, token) &&
!artist_match_token(track->tr_artist, token) &&
!album_match_token(track->tr_album, token) &&
!genre_match_token(track->tr_genre, token))
return FALSE;
}
return TRUE;
}
void __queue_filter(GtkSearchEntry *entry, gpointer data)
@ -88,21 +99,14 @@ void __queue_filter(GtkSearchEntry *entry, gpointer data)
if (!gq_queue)
return;
if (gq_queue->gq_search) {
g_free(gq_queue->gq_search);
g_strfreev(gq_queue->gq_search);
gq_queue->gq_search = NULL;
}
if (strlen(text) > 0) {
gq_queue->gq_visible = filter_search(text);
gq_queue->gq_search = g_strdup(text);
}
if (strlen(text) > 0)
gq_queue->gq_search = g_str_tokenize_and_fold(text, NULL, NULL);
gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(gq_queue->gq_filter));
gui_view_scroll();
if (gq_queue->gq_visible) {
g_hash_table_destroy(gq_queue->gq_visible);
gq_queue->gq_visible = NULL;
}
}
struct gui_queue *gui_queue_alloc(struct playlist *playlist, struct queue *queue,
@ -118,8 +122,8 @@ struct gui_queue *gui_queue_alloc(struct playlist *playlist, struct queue *queue
GTK_TREE_MODEL(gq->gq_model), NULL);
gq->gq_playlist = playlist;
gq->gq_queue = queue;
gq->gq_search = NULL;
gq->gq_visible = NULL;
gtk_tree_model_filter_set_visible_func(
GTK_TREE_MODEL_FILTER(gq->gq_filter),
__queue_visible_func,
@ -137,7 +141,7 @@ void gui_queue_free(struct queue *queue)
if (gq_queue == gq)
gui_view_set_model(NULL);
if (gq->gq_search)
g_free(gq->gq_search);
g_strfreev(gq->gq_search);
g_object_unref(gq->gq_model);
g_free(gq->gq_text);
g_free(gq);
@ -152,6 +156,7 @@ void gui_queue_show(struct gui_queue *queue)
GtkEntry *search = GTK_ENTRY(gui_builder_widget("o_search"));
GtkLabel *runtime = GTK_LABEL(gui_builder_widget("o_runtime"));
bool has_random = false, has_repeat = false, is_enabled = false;;
gchar *text;
gq_queue = queue;
@ -181,7 +186,13 @@ void gui_queue_show(struct gui_queue *queue)
gtk_widget_set_sensitive(GTK_WIDGET(view), is_enabled);
gtk_widget_set_sensitive(GTK_WIDGET(search), queue != NULL);
gtk_entry_set_text(search, (queue && queue->gq_search) ? queue->gq_search : "");
if (queue && queue->gq_search) {
text = g_strjoinv(" ", queue->gq_search);
gtk_entry_set_text(search, text);
g_free(text);
} else
gtk_entry_set_text(search, "");
}
void gui_queue_added(struct queue *queue, unsigned int row)

View File

@ -16,13 +16,12 @@ enum gui_queue_flags {
struct gui_queue {
unsigned int gq_flags;
gchar *gq_text;
gchar *gq_search;
gchar **gq_search;
GuiQueueModel *gq_model;
GtkTreeModel *gq_filter;
struct playlist *gq_playlist;
struct queue *gq_queue;
GHashTable *gq_visible;
};