/* * Copyright 2016 (c) Anna Schumaker. */ #include #include #include #include #include #include static struct gui_queue *gq_queue = NULL; static void __queue_set_runtime(struct gui_queue *queue) { gchar *len; if (queue != gq_queue) return; len = string_sec2str_long(queue->gq_queue->q_length); gtk_label_set_text(GTK_LABEL(gui_builder_widget("o_runtime")), len); g_free(len); } static void __queue_toggle_flag(bool active, GtkWidget *widget, enum queue_flags flag) { if (gq_queue == NULL) return; /* * Some GTK themes have trouble with toggle buttons, * so let's help users by changing image sensitivity. */ if (active) queue_set_flag(gq_queue->gq_queue, flag); else queue_unset_flag(gq_queue->gq_queue, flag); gtk_widget_set_sensitive(widget, active); } void __queue_random(GtkToggleButton *button, gpointer data) { __queue_toggle_flag(gtk_toggle_button_get_active(button), gtk_button_get_image(GTK_BUTTON(button)), Q_RANDOM); if (gq_queue->gq_playlist) { playlist_set_random(gq_queue->gq_playlist->pl_type, gq_queue->gq_playlist->pl_name, gtk_toggle_button_get_active(button)); } } void __queue_repeat(GtkToggleButton *button, gpointer data) { __queue_toggle_flag(gtk_toggle_button_get_active(button), gtk_button_get_image(GTK_BUTTON(button)), Q_REPEAT); } void __queue_disabled(GtkSwitch *enabled, GParamSpec *pspec, gpointer data) { __queue_toggle_flag(gtk_switch_get_active(enabled), gui_builder_widget("o_treeview"), Q_ENABLED); } static gboolean __queue_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { struct track *track; unsigned int i; gchar *token; if (!gq_queue || !gq_queue->gq_search) return TRUE; track = gui_queue_model_iter_get_track(gq_queue->gq_model, iter); 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) { const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry)); if (!gq_queue) return; if (gq_queue->gq_search) { g_strfreev(gq_queue->gq_search); gq_queue->gq_search = NULL; } 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(); } struct gui_queue *gui_queue_alloc(struct playlist *playlist, struct queue *queue, const gchar *text, unsigned int flags) { struct gui_queue *gq = g_malloc(sizeof(struct gui_queue)); gq->gq_flags = flags; gq->gq_text = g_strdup(text); gq->gq_search = NULL; gq->gq_model = gui_queue_model_new(queue); gq->gq_filter = gtk_tree_model_filter_new( GTK_TREE_MODEL(gq->gq_model), NULL); gq->gq_playlist = playlist; gq->gq_queue = queue; gq->gq_search = NULL; gtk_tree_model_filter_set_visible_func( GTK_TREE_MODEL_FILTER(gq->gq_filter), __queue_visible_func, gui_builder_object("o_search"), NULL); return gq; } void gui_queue_free(struct queue *queue) { struct gui_queue *gq = gui_queue(queue); queue->q_private = NULL; if (gq_queue == gq) gui_view_set_model(NULL); if (gq->gq_search) g_strfreev(gq->gq_search); g_object_unref(gq->gq_model); g_free(gq->gq_text); g_free(gq); } void gui_queue_show(struct gui_queue *queue) { GtkTreeView *view = GTK_TREE_VIEW(gui_builder_widget("o_treeview")); GtkButton *random = GTK_BUTTON(gui_builder_widget("o_random")); GtkButton *repeat = GTK_BUTTON(gui_builder_widget("o_repeat")); GtkSwitch *enabled = GTK_SWITCH(gui_builder_widget("o_enable")); 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; gtk_widget_set_sensitive(GTK_WIDGET(random), gui_queue_can_random(queue)); gtk_widget_set_sensitive(GTK_WIDGET(repeat), gui_queue_can_repeat(queue)); gtk_widget_set_sensitive(GTK_WIDGET(enabled), gui_queue_can_disable(queue)); if (queue) { has_random = queue_has_flag(queue->gq_queue, Q_RANDOM); has_repeat = queue_has_flag(queue->gq_queue, Q_REPEAT); is_enabled = queue_has_flag(queue->gq_queue, Q_ENABLED); gui_view_set_model(GTK_TREE_MODEL_FILTER(queue->gq_filter)); __queue_set_runtime(queue); } else gtk_label_set_text(runtime, ""); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(random), has_random); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat), has_repeat); gtk_switch_set_active(GTK_SWITCH(enabled), is_enabled); /* * Some GTK themes have trouble with toggle buttons, * so let's help users know what the current state is. */ gtk_widget_set_sensitive(gtk_button_get_image(random), has_random); gtk_widget_set_sensitive(gtk_button_get_image(repeat), has_repeat); gtk_widget_set_sensitive(GTK_WIDGET(view), is_enabled); gtk_widget_set_sensitive(GTK_WIDGET(search), queue != NULL); 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) { gui_queue_model_add(gui_queue(queue)->gq_model, row); __queue_set_runtime(gui_queue(queue)); } void gui_queue_removed(struct queue *queue, unsigned int row) { gui_queue_model_remove(gui_queue(queue)->gq_model, row); __queue_set_runtime(gui_queue(queue)); } void gui_queue_cleared(struct queue *queue, unsigned int n) { gui_queue_model_clear(gui_queue(queue)->gq_model, n); __queue_set_runtime(gui_queue(queue)); } void gui_queue_updated(struct queue *queue, unsigned int row) { gui_queue_model_update(gui_queue(queue)->gq_model, row); __queue_set_runtime(gui_queue(queue)); }