# HG changeset patch # User Calin Crisan ccrisan@gmail.com # Date 1215366601 -10800 # Node ID c5005707a575d6765bdd6cbe9e017591be506950 # Parent 7fc2c317d190d090e1e071145cd9b843963cf7c7 added basic search functionality diff -r 7fc2c317d190 -r c5005707a575 src/streambrowser/gui/streambrowser_win.c --- 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 #include #include +#include #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; +} + diff -r 7fc2c317d190 -r c5005707a575 src/streambrowser/streambrowser.c --- 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()