changeset 2782:c5005707a575

added basic search functionality
author Calin Crisan ccrisan@gmail.com
date Sun, 06 Jul 2008 20:50:01 +0300
parents 7fc2c317d190
children 8be380729806
files src/streambrowser/gui/streambrowser_win.c src/streambrowser/streambrowser.c
diffstat 2 files changed, 109 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/streambrowser/gui/streambrowser_win.c	Thu Jul 03 17:37:11 2008 +0300
+++ b/src/streambrowser/gui/streambrowser_win.c	Sun Jul 06 20:50:01 2008 +0300
@@ -2,6 +2,7 @@
 #include <string.h>
 #include <glib.h>
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
 
 #include "../streambrowser.h"
 #include "streambrowser_win.h"
@@ -25,10 +26,13 @@
 static gboolean			on_notebook_switch_page(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data);
 static gboolean			on_tree_view_cursor_changed(GtkTreeView *tree_view, gpointer data);
 static gboolean			on_add_button_clicked(GtkButton *button, gpointer data);
+static gboolean			on_search_entry_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data);
+static gboolean			on_tree_view_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data);
 
 static streamdir_gui_t*		find_streamdir_gui_by_name(gchar *name);
 static streamdir_gui_t*		find_streamdir_gui_by_tree_view(GtkTreeView *tree_view);
 static streamdir_gui_t*		find_streamdir_gui_by_table(GtkTable *table);
+static gboolean			tree_view_search_equal_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer data);
 
 
 static GtkWidget*		notebook;
@@ -52,6 +56,7 @@
 
 	/* search entry */
 	search_entry = gtk_entry_new();
+	g_signal_connect(G_OBJECT(search_entry), "key-press-event", G_CALLBACK(on_search_entry_key_pressed), NULL);
 	gtk_widget_show(search_entry);
 	
 	GtkWidget *hbox1 = gtk_hbox_new(FALSE, 0);
@@ -211,6 +216,9 @@
 	gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(tree_view), TRUE);
 	gtk_tree_view_set_reorderable(GTK_TREE_VIEW(tree_view), TRUE);
 	gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(tree_view), FALSE);
+	gtk_tree_view_set_search_entry(GTK_TREE_VIEW(tree_view), GTK_ENTRY(search_entry));
+	gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(tree_view), tree_view_search_equal_func, NULL, NULL);
+	g_signal_connect(G_OBJECT(tree_view), "key-press-event", G_CALLBACK(on_tree_view_key_pressed), NULL);
 
 	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree_view), -1, "", cell_renderer_pixbuf, "pixbuf", 0, NULL);
 	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree_view), -1, _("Stream name"), cell_renderer_text, "text", 1, NULL);
@@ -267,6 +275,11 @@
 		return TRUE;
 	}
 	
+	if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(tree_view), path)) {
+		gtk_tree_path_free(path);
+		return TRUE;
+	}
+	
 	int category_index = indices[0];
 	
 	gtk_tree_path_free(path);
@@ -321,6 +334,53 @@
 	return TRUE;
 }
 
+static gboolean on_search_entry_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+	if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter)
+		on_add_button_clicked(GTK_BUTTON(add_button), NULL);
+	
+	/* todo: remove this
+	GtkWidget *table = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+	streamdir_gui_t *streamdir_gui = find_streamdir_gui_by_table(GTK_TABLE(table));
+	if (streamdir_gui == NULL)
+		return FALSE;
+
+	GtkWidget *tree_view = streamdir_gui->tree_view;
+	GtkTreeIter iter;
+	gboolean is_expanded = FALSE;
+	GtkTreeStore *store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view)));
+	GtkTreePath *path;
+	if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
+		return FALSE;
+		
+	while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)) {
+		path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
+		
+		if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(tree_view), path)) {
+			is_expanded = TRUE;
+			break;
+		}
+		
+		gtk_tree_path_free(path);
+	}
+
+	if (!is_expanded)
+		gtk_tree_view_set_search_column(GTK_TREE_VIEW(tree_view), );
+	else
+		gtk_tree_view_set_search_column(GTK_TREE_VIEW(tree_view), 1);
+	*/
+	
+	return FALSE;
+}
+
+static gboolean on_tree_view_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+	gtk_widget_grab_focus(search_entry);
+	on_search_entry_key_pressed(widget, event, data);
+
+	return FALSE;
+}
+
 static streamdir_gui_t *find_streamdir_gui_by_name(gchar *name)
 {
 	GList *iterator;
@@ -366,3 +426,19 @@
 	return NULL;
 }
 
+static gboolean tree_view_search_equal_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer data)
+{
+	GValue value = {0, };
+	gboolean ret;
+	
+	gtk_tree_model_get_value(model, iter, column, &value);
+	const gchar *string = g_value_get_string(&value);
+	
+	// todo: why do I get "warning: implicit declaration" for strcasestr !?
+	ret = ((char *) strcasestr(string, key) == NULL);
+	
+	g_value_unset(&value);
+
+	return ret;
+}
+
--- a/src/streambrowser/streambrowser.c	Thu Jul 03 17:37:11 2008 +0300
+++ b/src/streambrowser/streambrowser.c	Sun Jul 06 20:50:01 2008 +0300
@@ -242,20 +242,41 @@
 	}
 	else
 		if (update_thread_count > 0) {
-			debug("another %d streamdir updates are pending, this request will be queued\n", update_thread_count);
+			int i;
+			gboolean exists = FALSE;
+			update_thread_data_t *update_thread_data;
 			
 			g_mutex_lock(update_thread_mutex);
-			
-			update_thread_data_t *update_thread_data = g_malloc(sizeof(update_thread_data_t));
+			for (i = 0; i < g_queue_get_length(update_thread_data_queue); i++) {
+				update_thread_data = g_queue_peek_nth(update_thread_data_queue, i);
+				if (update_thread_data->streamdir == streamdir &&
+						update_thread_data->category == category &&
+						update_thread_data->streaminfo == streaminfo) {
+					exists = TRUE;
+					break;
+				}
+			}
+			g_mutex_unlock(update_thread_mutex);
+
+			if (!exists) {
+				debug("another %d streamdir updates are pending, this request will be queued\n", update_thread_count);
 			
-			update_thread_data->streamdir = streamdir;
-			update_thread_data->category = category;
-			update_thread_data->streaminfo = streaminfo;
-			g_queue_push_tail(update_thread_data_queue, update_thread_data);
+				g_mutex_lock(update_thread_mutex);
+			
+				update_thread_data = g_malloc(sizeof(update_thread_data_t));
 			
-			update_thread_count++;
+				update_thread_data->streamdir = streamdir;
+				update_thread_data->category = category;
+				update_thread_data->streaminfo = streaminfo;
+				g_queue_push_tail(update_thread_data_queue, update_thread_data);
+			
+				update_thread_count++;
 
-			g_mutex_unlock(update_thread_mutex);
+				g_mutex_unlock(update_thread_mutex);
+			}
+			else {
+				debug("this request is already present in the queue, dropping\n");			
+			}
 		}
 		else {
 			update_thread_data_t *data = g_malloc(sizeof(update_thread_data_t));
@@ -264,7 +285,7 @@
 			data->category = category;
 			data->streaminfo = streaminfo;
 
-			g_thread_create((GThreadFunc) update_thread_core, data, TRUE, NULL);
+			g_thread_create((GThreadFunc) update_thread_core, data, FALSE, NULL);
 		}
 }
 
@@ -276,7 +297,7 @@
 
 	/* update a streaminfo - that is - add this streaminfo to playlist */
 	if (data->streaminfo != NULL) {
-		 streaminfo_add_to_playlist(data->streaminfo);
+		streaminfo_add_to_playlist(data->streaminfo);
 	}
 	/* update a category */
 	else if (data->category != NULL) {
@@ -342,7 +363,7 @@
 	}
 	debug("stream playlist '%s' successfuly downloaded to '%s'\n", streaminfo->playlist_url, PLAYLIST_TEMP_FILE);
 	
-	aud_playlist_add(aud_playlist_get_active(), PLAYLIST_TEMP_FILE);
+	aud_playlist_add_url(aud_playlist_get_active(), PLAYLIST_TEMP_FILE);
 }
 
 static void on_plugin_services_menu_item_click()