Index: lib/rb-util.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/lib/rb-util.c,v
retrieving revision 1.16
diff -u -u -r1.16 rb-util.c
--- lib/rb-util.c	1 Sep 2005 16:53:49 -0000	1.16
+++ lib/rb-util.c	16 Oct 2005 07:01:11 -0000
@@ -23,6 +23,7 @@
 #include <gtk/gtk.h>
 #include <string.h>
 #include <libgnomevfs/gnome-vfs.h>
+#include "rb-debug.h"
 
 static GPrivate * private_is_primary_thread;
 
@@ -380,3 +381,107 @@
 	 */
 	gdk_threads_init ();
 }
+
+gchar **
+rb_string_split_words (const gchar *string)
+{
+	/*return g_slist_prepend (NULL, g_strdup (string));*/
+
+	GSList *words, *current;
+	gunichar *unicode, *cur_write, *cur_read;
+	gchar **ret;
+	gint i, wordcount = 1;
+	gboolean new_word = TRUE;
+
+	g_return_val_if_fail (string != NULL, NULL);
+
+	cur_write = cur_read = unicode = g_utf8_to_ucs4_fast (string, -1, NULL);
+
+	/* we may fail here, we expect valid utf-8 */
+	g_return_val_if_fail (unicode != NULL, NULL);
+
+	words = g_slist_prepend (NULL, unicode);
+
+	/* now normalize this text */
+	while (*cur_read) {
+		switch (g_unichar_type (*cur_read)) {
+		case G_UNICODE_UNASSIGNED:
+			g_warning ("unassigned unicode character type found");
+			/* fall through */
+		case G_UNICODE_CONTROL:
+		case G_UNICODE_FORMAT:
+		case G_UNICODE_PRIVATE_USE:
+
+		case G_UNICODE_SURROGATE:
+		case G_UNICODE_LINE_SEPARATOR:
+		case G_UNICODE_PARAGRAPH_SEPARATOR:
+		case G_UNICODE_SPACE_SEPARATOR:
+			/* remove these and start a new word */
+			if (!new_word) {
+				/* end current word if it isn't ended yet */
+				*cur_write++ = 0;
+				new_word = TRUE;
+			}
+
+			break;
+		case G_UNICODE_COMBINING_MARK:
+		case G_UNICODE_ENCLOSING_MARK:
+		case G_UNICODE_NON_SPACING_MARK:
+		case G_UNICODE_CONNECT_PUNCTUATION:
+		case G_UNICODE_DASH_PUNCTUATION:
+		case G_UNICODE_CLOSE_PUNCTUATION:
+		case G_UNICODE_FINAL_PUNCTUATION:
+		case G_UNICODE_INITIAL_PUNCTUATION:
+		case G_UNICODE_OTHER_PUNCTUATION:
+		case G_UNICODE_OPEN_PUNCTUATION:
+			/* remove these */
+			/*break;*/
+		case G_UNICODE_LOWERCASE_LETTER:
+		case G_UNICODE_MODIFIER_LETTER:
+		case G_UNICODE_OTHER_LETTER:
+		case G_UNICODE_TITLECASE_LETTER:
+		case G_UNICODE_UPPERCASE_LETTER:
+		case G_UNICODE_DECIMAL_NUMBER:
+		case G_UNICODE_LETTER_NUMBER:
+		case G_UNICODE_OTHER_NUMBER:
+		case G_UNICODE_CURRENCY_SYMBOL:
+		case G_UNICODE_MODIFIER_SYMBOL:
+		case G_UNICODE_MATH_SYMBOL:
+		case G_UNICODE_OTHER_SYMBOL:
+			/* keep these unchanged */
+			*cur_write = *cur_read;
+			if (new_word) {
+				if (cur_write != unicode) {/* first insert has been done above */
+					words = g_slist_prepend (words, cur_write);
+					wordcount++;
+				}
+				new_word = FALSE;
+			}
+			cur_write++;
+			break;    
+		default:
+			g_warning ("unknown unicode character type found");
+			break;
+		}
+		cur_read++;
+	}
+
+	if (!new_word) {
+		*cur_write++ = 0;
+	}
+
+	ret = g_new (gchar *, wordcount + 1); 
+	current = words;
+	for (i = wordcount - 1; i >= 0; i--) {
+		ret[i] = g_ucs4_to_utf8 (current->data, -1, NULL, NULL, NULL);
+		current = g_slist_next (current);
+	}
+	ret[wordcount] = NULL;
+
+	g_slist_free (words);
+	g_free (unicode);
+
+	return ret;
+}
+
+
Index: lib/rb-util.h
===================================================================
RCS file: /cvs/gnome/rhythmbox/lib/rb-util.h,v
retrieving revision 1.12
diff -u -u -r1.12 rb-util.h
--- lib/rb-util.h	1 Sep 2005 16:53:49 -0000	1.12
+++ lib/rb-util.h	16 Oct 2005 07:01:11 -0000
@@ -23,8 +23,7 @@
 #define __RB_UTIL_H
 
 #include <stdarg.h>
-#include <glib/gtypes.h>
-#include <glib-object.h>
+#include <glib.h>
 #include <gtk/gtkimage.h>
 #include <gtk/gtkuimanager.h>
 
@@ -49,8 +48,7 @@
 void rb_threads_init (void);
 gboolean rb_is_main_thread (void);
 
-
-
+gchar** rb_string_split_words (const gchar *string);
 
 G_END_DECLS
 
Index: rhythmdb/rhythmdb-tree.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/rhythmdb/rhythmdb-tree.c,v
retrieving revision 1.74
diff -u -u -r1.74 rhythmdb-tree.c
--- rhythmdb/rhythmdb-tree.c	29 Sep 2005 17:51:47 -0000	1.74
+++ rhythmdb/rhythmdb-tree.c	16 Oct 2005 07:01:12 -0000
@@ -404,6 +404,7 @@
 		case RHYTHMDB_PROP_HIDDEN:
 		case RHYTHMDB_PROP_PLAYBACK_ERROR:
 		case RHYTHMDB_PROP_FIRST_SEEN_STR:
+		case RHYTHMDB_PROP_SEARCH_MATCH:
 		case RHYTHMDB_NUM_PROPERTIES:
 			g_assert_not_reached ();
 			break;
@@ -715,6 +716,7 @@
 		case RHYTHMDB_PROP_HIDDEN:
 		case RHYTHMDB_PROP_PLAYBACK_ERROR:
 		case RHYTHMDB_PROP_FIRST_SEEN_STR:
+		case RHYTHMDB_PROP_SEARCH_MATCH:
 		case RHYTHMDB_NUM_PROPERTIES:
 			break;
 		}
@@ -1286,25 +1288,54 @@
 		case RHYTHMDB_QUERY_PROP_NOT_LIKE:
 		{
 			if (rhythmdb_get_property_type (db, data->propid) == G_TYPE_STRING) {
-				const char *entry_string = rhythmdb_entry_get_string (entry, data->propid);
-				gboolean islike = FALSE;
+				gboolean islike;
 
-				/* check in case the property is NULL, the value should never be NULL */
-				if (entry_string == NULL)
-					return FALSE;
+				if (data->propid == RHYTHMDB_PROP_SEARCH_MATCH) {
+					/* this is a special property, that should match several things */
+					const RhythmDBPropType props[] = {
+						RHYTHMDB_PROP_TITLE_FOLDED,
+						RHYTHMDB_PROP_ALBUM_FOLDED,
+						RHYTHMDB_PROP_ARTIST_FOLDED,
+						RHYTHMDB_PROP_GENRE_FOLDED
+					};
+					gchar **current, **words;
+					int i;
+
+					words = g_value_get_boxed (data->val);
+					islike = TRUE;
+
+					for (current = words; *current != NULL; current++) {
+						gboolean word_found = FALSE;
+
+						for (i = 0; i < G_N_ELEMENTS (props); i++) {
+							const char *entry_string = rhythmdb_entry_get_string (entry, props[i]);
+							if (entry_string && (strstr (entry_string, *current) != NULL)) {
+								/* the word was found, go to the next one */	
+								word_found = TRUE;
+								break;
+							}
+						}
+						if (!word_found) {
+							/* the word wasn't in any of the properties*/
+							islike = FALSE;
+							break;
+						}
+					}
+				} else {
+					const gchar *value_string = g_value_get_string (data->val);
+					const char *entry_string = rhythmdb_entry_get_string (entry, data->propid);
 
-				islike = (strstr (entry_string, g_value_get_string (data->val)) != NULL);
-				if (data->type == RHYTHMDB_QUERY_PROP_LIKE) {
-					if (!islike)
-						return FALSE;
-					else
-						continue;
-				} else if (data->type == RHYTHMDB_QUERY_PROP_NOT_LIKE) {
-					if (islike)
+					/* check in case the property is NULL, the value should never be NULL */
+					if (entry_string == NULL)
 						return FALSE;
-					else
-						continue;
+
+					islike = (strstr (entry_string, value_string) != NULL);
 				}
+
+				if ((data->type == RHYTHMDB_QUERY_PROP_LIKE) ^ islike)
+					return FALSE;
+				else
+					continue;
 				break;
 			} 
 			/* Fall through */
Index: rhythmdb/rhythmdb.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/rhythmdb/rhythmdb.c,v
retrieving revision 1.119
diff -u -u -r1.119 rhythmdb.c
--- rhythmdb/rhythmdb.c	11 Oct 2005 11:16:07 -0000	1.119
+++ rhythmdb/rhythmdb.c	16 Oct 2005 07:01:12 -0000
@@ -2774,6 +2774,7 @@
 			ENUM_ENTRY (RHYTHMDB_PROP_PLAYBACK_ERROR, "Playback error string (gchararray) [playback-error]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_HIDDEN, "Visibility (gboolean) [visibility]"),
 			ENUM_ENTRY (RHYTHMDB_PROP_FIRST_SEEN_STR, "Time Added to Library (gchararray) [first-seen-str]"),
+			ENUM_ENTRY (RHYTHMDB_PROP_SEARCH_MATCH, "Search matching key (gchararray) [search-match]"),
 			{ 0, 0, 0 }
 		};
 		g_assert ((sizeof (values) / sizeof (values[0]) - 1) == RHYTHMDB_NUM_PROPERTIES);
@@ -3074,6 +3075,22 @@
 				g_value_take_string (data->val, folded);
 				break;
 			}
+			case RHYTHMDB_PROP_SEARCH_MATCH:
+			{
+				const char *orig = g_value_get_string (data->val);
+				char *folded = g_utf8_casefold (orig, -1);
+				char **words = rb_string_split_words (folded);
+
+				g_free (folded);
+				g_value_unset (data->val);
+				g_value_init (data->val, G_TYPE_STRV);
+				g_value_take_boxed (data->val, words);
+				break;
+			}
+			default:
+				/* do nothing */
+				break;
 		}
 	}
 }
+
Index: rhythmdb/rhythmdb.h
===================================================================
RCS file: /cvs/gnome/rhythmbox/rhythmdb/rhythmdb.h,v
retrieving revision 1.50
diff -u -u -r1.50 rhythmdb.h
--- rhythmdb/rhythmdb.h	27 Sep 2005 05:05:39 -0000	1.50
+++ rhythmdb/rhythmdb.h	16 Oct 2005 07:01:12 -0000
@@ -101,6 +101,7 @@
 	RHYTHMDB_PROP_HIDDEN,
 	RHYTHMDB_PROP_PLAYBACK_ERROR,
 	RHYTHMDB_PROP_FIRST_SEEN_STR,
+	RHYTHMDB_PROP_SEARCH_MATCH,
 	
 	RHYTHMDB_NUM_PROPERTIES
 } RhythmDBPropType;
Index: sources/rb-library-source.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/sources/rb-library-source.c,v
retrieving revision 1.120
diff -u -u -r1.120 rb-library-source.c
--- sources/rb-library-source.c	27 Sep 2005 11:30:24 -0000	1.120
+++ sources/rb-library-source.c	16 Oct 2005 07:01:16 -0000
@@ -1401,19 +1401,7 @@
 	if (source->priv->search_text) {
 		GPtrArray *subquery = rhythmdb_query_parse (source->priv->db,
 							    RHYTHMDB_QUERY_PROP_LIKE,
-							    RHYTHMDB_PROP_GENRE_FOLDED,
-							    source->priv->search_text,
-							    RHYTHMDB_QUERY_DISJUNCTION,
-							    RHYTHMDB_QUERY_PROP_LIKE,
-							    RHYTHMDB_PROP_ARTIST_FOLDED,
-							    source->priv->search_text,
-							    RHYTHMDB_QUERY_DISJUNCTION,
-							    RHYTHMDB_QUERY_PROP_LIKE,
-							    RHYTHMDB_PROP_ALBUM_FOLDED,
-							    source->priv->search_text,
-							    RHYTHMDB_QUERY_DISJUNCTION,
-							    RHYTHMDB_QUERY_PROP_LIKE,
-							    RHYTHMDB_PROP_TITLE_FOLDED,
+							    RHYTHMDB_PROP_SEARCH_MATCH,
 							    source->priv->search_text,
 							    RHYTHMDB_QUERY_END);
 		rhythmdb_query_append (source->priv->db,
