# HG changeset patch # User Sadrul Habib Chowdhury # Date 1165389881 0 # Node ID 6cb9996fcc97cb4fe20e7cf6af3d811b9bb64b92 # Parent c18c02aeb366bf0c3f077d58c096c7bffd3719e9 [gaim-migrate @ 17901] Rename gtkblist.c:_search_func to gtkutils.c:gaim_gtk_tree_view_search_equal_func. Use this in the buddylist, the statusbox dropdown and in the plugins dialog. This can also be used in the smiley-theme-list. Process Escape and Return key-presses in the statusbox dropdown. seanegan: I hope I didn't step on your toes O:-) committer: Tailor Script diff -r c18c02aeb366 -r 6cb9996fcc97 gtk/gtkblist.c --- a/gtk/gtkblist.c Wed Dec 06 02:15:28 2006 +0000 +++ b/gtk/gtkblist.c Wed Dec 06 07:24:41 2006 +0000 @@ -3622,111 +3622,6 @@ gaim_gtk_blist_sort_method_set(val); } -/* - * "This is so dead sexy." - * "Two thumbs up." - * "Best movie of the year." - * - * This is the function that handles CTRL+F searching in the buddy list. - * It finds the top-most buddy/group/chat/whatever containing the - * entered string. - * - * It's somewhat ineffecient, because we strip all the HTML from the - * "name" column of the buddy list (because the GtkTreeModel does not - * contain the screen name in a non-markedup format). But the alternative - * is to add an extra column to the GtkTreeModel. And this function is - * used rarely, so it shouldn't matter TOO much. - */ -static gboolean -_search_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer search_data) -{ - gchar *enteredstring; - gchar *tmp; - gchar *withmarkup; - gchar *nomarkup; - gchar *normalized; - gboolean result; - size_t i; - size_t len; - PangoLogAttr *log_attrs; - gchar *word; - - if (strcasecmp(key, "Global Thermonuclear War") == 0) - { - gaim_notify_info(NULL, "WOPR", - "Wouldn't you prefer a nice game of chess?", NULL); - return FALSE; - } - - gtk_tree_model_get(model, iter, column, &withmarkup, -1); - - tmp = g_utf8_normalize(key, -1, G_NORMALIZE_DEFAULT); - enteredstring = g_utf8_casefold(tmp, -1); - g_free(tmp); - - nomarkup = gaim_markup_strip_html(withmarkup); - tmp = g_utf8_normalize(nomarkup, -1, G_NORMALIZE_DEFAULT); - g_free(nomarkup); - normalized = g_utf8_casefold(tmp, -1); - g_free(tmp); - - if (gaim_str_has_prefix(normalized, enteredstring)) - { - g_free(withmarkup); - g_free(enteredstring); - g_free(normalized); - return FALSE; - } - - - /* Use Pango to separate by words. */ - len = g_utf8_strlen(normalized, -1); - log_attrs = g_new(PangoLogAttr, len + 1); - - pango_get_log_attrs(normalized, strlen(normalized), -1, NULL, log_attrs, len + 1); - - word = normalized; - result = TRUE; - for (i = 0; i < (len - 1) ; i++) - { - if (log_attrs[i].is_word_start && - gaim_str_has_prefix(word, enteredstring)) - { - result = FALSE; - break; - } - word = g_utf8_next_char(word); - } - g_free(log_attrs); - -/* The non-Pango version. */ -#if 0 - word = normalized; - result = TRUE; - while (word[0] != '\0') - { - gunichar c = g_utf8_get_char(word); - if (!g_unichar_isalnum(c)) - { - word = g_utf8_find_next_char(word, NULL); - if (gaim_str_has_prefix(word, enteredstring)) - { - result = FALSE; - break; - } - } - else - word = g_utf8_find_next_char(word, NULL); - } -#endif - - g_free(withmarkup); - g_free(enteredstring); - g_free(normalized); - - return result; -} - static void account_modified(GaimAccount *account, GaimGtkBuddyList *gtkblist) { GList *list; @@ -4173,7 +4068,7 @@ /* Enable CTRL+F searching */ gtk_tree_view_set_search_column(GTK_TREE_VIEW(gtkblist->treeview), NAME_COLUMN); - gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(gtkblist->treeview), _search_func, NULL, NULL); + gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(gtkblist->treeview), gaim_gtk_tree_view_search_equal_func, NULL, NULL); gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sw, TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview); diff -r c18c02aeb366 -r 6cb9996fcc97 gtk/gtkplugin.c --- a/gtk/gtkplugin.c Wed Dec 06 02:15:28 2006 +0000 +++ b/gtk/gtkplugin.c Wed Dec 06 07:24:41 2006 +0000 @@ -599,6 +599,9 @@ gtk_tree_view_column_set_sort_column_id(col, 1); g_object_unref(G_OBJECT(ls)); gtk_container_add(GTK_CONTAINER(sw), event_view); + gtk_tree_view_set_search_column(GTK_TREE_VIEW(event_view), 1); + gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(event_view), + gaim_gtk_tree_view_search_equal_func, NULL, NULL); expander = gtk_expander_new(_("Plugin Details")); gtk_expander_set_use_markup(GTK_EXPANDER(expander), TRUE); diff -r c18c02aeb366 -r 6cb9996fcc97 gtk/gtkstatusbox.c --- a/gtk/gtkstatusbox.c Wed Dec 06 02:15:28 2006 +0000 +++ b/gtk/gtkstatusbox.c Wed Dec 06 07:24:41 2006 +0000 @@ -1013,6 +1013,7 @@ gaim_account_get_active_status(status_box->account)); } gtk_tree_view_set_model(GTK_TREE_VIEW(status_box->tree_view), status_box->dropdown_store); + gtk_tree_view_set_search_column(GTK_TREE_VIEW(status_box->tree_view), TEXT_COLUMN); } static gboolean combo_box_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkIMHtml *imhtml) @@ -1397,6 +1398,18 @@ buddy_icon_set_cb(value, (GtkGaimStatusBox*) data); } +static void +treeview_activate_current_selection(GtkGaimStatusBox *status_box, GtkTreePath *path) +{ + if (status_box->active_row) + gtk_tree_row_reference_free(status_box->active_row); + + status_box->active_row = gtk_tree_row_reference_new(GTK_TREE_MODEL(status_box->dropdown_store), path); + + gaim_gtk_status_box_popdown (status_box); + gtk_gaim_status_box_changed(status_box); +} + static gboolean treeview_button_release_cb(GtkWidget *widget, GdkEventButton *event, GtkGaimStatusBox *status_box) { @@ -1426,23 +1439,40 @@ event->x, event->y, &path, NULL, NULL, NULL); - - + if (!ret) return TRUE; /* clicked outside window? */ - if (status_box->active_row) - gtk_tree_row_reference_free(status_box->active_row); - - status_box->active_row = gtk_tree_row_reference_new(GTK_TREE_MODEL(status_box->dropdown_store), path); + treeview_activate_current_selection(status_box, path); gtk_tree_path_free (path); - - gaim_gtk_status_box_popdown (status_box); - gtk_gaim_status_box_changed(status_box); return TRUE; } +static gboolean +treeview_key_press_event(GtkWidget *widget, + GdkEventKey *event, GtkGaimStatusBox *box) +{ + if (box->popup_in_progress) { + if (event->keyval == GDK_Escape) { + gaim_gtk_status_box_popdown(box); + return TRUE; + } else if (event->keyval == GDK_Return) { + GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(box->tree_view)); + GtkTreeIter iter; + GtkTreePath *path; + + if (gtk_tree_selection_get_selected(sel, NULL, &iter)) { + path = gtk_tree_model_get_path(GTK_TREE_MODEL(box->dropdown_store), &iter); + treeview_activate_current_selection(box, path); + gtk_tree_path_free (path); + return TRUE; + } + } + } + return FALSE; +} + static void gtk_gaim_status_box_init (GtkGaimStatusBox *status_box) { @@ -1528,10 +1558,13 @@ status_box->column); gtk_tree_view_column_pack_start(status_box->column, icon_rend, FALSE); gtk_tree_view_column_pack_start(status_box->column, text_rend, TRUE); - gtk_tree_view_column_set_attributes(GTK_CELL_LAYOUT(status_box->column), icon_rend, "pixbuf", ICON_COLUMN, NULL); - gtk_tree_view_column_set_attributes(GTK_CELL_LAYOUT(status_box->column), text_rend, "markup", TEXT_COLUMN, NULL); + gtk_tree_view_column_set_attributes(status_box->column, icon_rend, "pixbuf", ICON_COLUMN, NULL); + gtk_tree_view_column_set_attributes(status_box->column, text_rend, "markup", TEXT_COLUMN, NULL); gtk_container_add(GTK_CONTAINER(status_box->scrolled_window), status_box->tree_view); gtk_widget_show(status_box->tree_view); + gtk_tree_view_set_search_column(GTK_TREE_VIEW(status_box->tree_view), TEXT_COLUMN); + gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(status_box->tree_view), + gaim_gtk_tree_view_search_equal_func, NULL, NULL); #if GTK_CHECK_VERSION(2, 6, 0) g_object_set(text_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); @@ -1582,6 +1615,7 @@ g_signal_connect(G_OBJECT(status_box->imhtml), "scroll_event", G_CALLBACK(imhtml_scroll_event_cb), status_box->imhtml); g_signal_connect(G_OBJECT(status_box->popup_window), "button_release_event", G_CALLBACK(treeview_button_release_cb), status_box); + g_signal_connect(G_OBJECT(status_box->popup_window), "key_press_event", G_CALLBACK(treeview_key_press_event), status_box); #if GTK_CHECK_VERSION(2,6,0) gtk_tree_view_set_row_separator_func(GTK_TREE_VIEW(status_box->tree_view), dropdown_store_row_separator_func, NULL, NULL); diff -r c18c02aeb366 -r 6cb9996fcc97 gtk/gtkutils.c --- a/gtk/gtkutils.c Wed Dec 06 02:15:28 2006 +0000 +++ b/gtk/gtkutils.c Wed Dec 06 07:24:41 2006 +0000 @@ -2964,3 +2964,111 @@ return vbox; } + +/* + * "This is so dead sexy." + * "Two thumbs up." + * "Best movie of the year." + * + * This is the function that handles CTRL+F searching in the buddy list. + * It finds the top-most buddy/group/chat/whatever containing the + * entered string. + * + * It's somewhat ineffecient, because we strip all the HTML from the + * "name" column of the buddy list (because the GtkTreeModel does not + * contain the screen name in a non-markedup format). But the alternative + * is to add an extra column to the GtkTreeModel. And this function is + * used rarely, so it shouldn't matter TOO much. + */ +gboolean gaim_gtk_tree_view_search_equal_func(GtkTreeModel *model, gint column, + const gchar *key, GtkTreeIter *iter, gpointer data) +{ + gchar *enteredstring; + gchar *tmp; + gchar *withmarkup; + gchar *nomarkup; + gchar *normalized; + gboolean result; + size_t i; + size_t len; + PangoLogAttr *log_attrs; + gchar *word; + + if (strcasecmp(key, "Global Thermonuclear War") == 0) + { + gaim_notify_info(NULL, "WOPR", + "Wouldn't you prefer a nice game of chess?", NULL); + return FALSE; + } + + gtk_tree_model_get(model, iter, column, &withmarkup, -1); + if (withmarkup == NULL) /* This is probably a separator */ + return TRUE; + + tmp = g_utf8_normalize(key, -1, G_NORMALIZE_DEFAULT); + enteredstring = g_utf8_casefold(tmp, -1); + g_free(tmp); + + nomarkup = gaim_markup_strip_html(withmarkup); + tmp = g_utf8_normalize(nomarkup, -1, G_NORMALIZE_DEFAULT); + g_free(nomarkup); + normalized = g_utf8_casefold(tmp, -1); + g_free(tmp); + + if (gaim_str_has_prefix(normalized, enteredstring)) + { + g_free(withmarkup); + g_free(enteredstring); + g_free(normalized); + return FALSE; + } + + + /* Use Pango to separate by words. */ + len = g_utf8_strlen(normalized, -1); + log_attrs = g_new(PangoLogAttr, len + 1); + + pango_get_log_attrs(normalized, strlen(normalized), -1, NULL, log_attrs, len + 1); + + word = normalized; + result = TRUE; + for (i = 0; i < (len - 1) ; i++) + { + if (log_attrs[i].is_word_start && + gaim_str_has_prefix(word, enteredstring)) + { + result = FALSE; + break; + } + word = g_utf8_next_char(word); + } + g_free(log_attrs); + +/* The non-Pango version. */ +#if 0 + word = normalized; + result = TRUE; + while (word[0] != '\0') + { + gunichar c = g_utf8_get_char(word); + if (!g_unichar_isalnum(c)) + { + word = g_utf8_find_next_char(word, NULL); + if (gaim_str_has_prefix(word, enteredstring)) + { + result = FALSE; + break; + } + } + else + word = g_utf8_find_next_char(word, NULL); + } +#endif + + g_free(withmarkup); + g_free(enteredstring); + g_free(normalized); + + return result; +} + diff -r c18c02aeb366 -r 6cb9996fcc97 gtk/gtkutils.h --- a/gtk/gtkutils.h Wed Dec 06 02:15:28 2006 +0000 +++ b/gtk/gtkutils.h Wed Dec 06 07:24:41 2006 +0000 @@ -490,8 +490,6 @@ GError **error); #endif -#endif /* _GAIM_GTKUTILS_H_ */ - /** * Set or unset a custom buddyicon for a user. * @@ -523,3 +521,17 @@ void *gaim_gtk_make_mini_dialog(GaimConnection *handle, const char* stock_id, const char *primary, const char *secondary, void *user_data, ...); + +/** + * This is a callback function to be used for Ctrl+F searching in treeviews. + * Sample Use: + * gtk_tree_view_set_search_equal_func(treeview, + * gaim_gtk_tree_view_search_equal_func, + * search_data, search_data_destroy_cb); + * + */ +gboolean gaim_gtk_tree_view_search_equal_func(GtkTreeModel *model, gint column, + const gchar *key, GtkTreeIter *iter, gpointer data); + +#endif /* _GAIM_GTKUTILS_H_ */ +