changeset 15116:6cb9996fcc97

[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 <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Wed, 06 Dec 2006 07:24:41 +0000
parents c18c02aeb366
children 2bec32a6f303
files gtk/gtkblist.c gtk/gtkplugin.c gtk/gtkstatusbox.c gtk/gtkutils.c gtk/gtkutils.h
diffstat 5 files changed, 171 insertions(+), 119 deletions(-) [+]
line wrap: on
line diff
--- 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);
--- 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(_("<b>Plugin Details</b>"));
 	gtk_expander_set_use_markup(GTK_EXPANDER(expander), TRUE);
--- 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);
--- 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;
+}
+
--- 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_ */
+