[evolution-data-server] Make Search ignore accents for address book summary searches



commit 98a073183a796839a6dfd52769230ae919c809ab
Author: Milan Crha <mcrha redhat com>
Date:   Fri Apr 24 18:28:57 2009 +0200

    Make Search ignore accents for address book summary searches
    
    	** Partial fix for bug #343505
    
            * libedataserver/e-data-server-util.h: (e_util_utf8_remove_accents):
            * libedataserver/e-data-server-util.c: (e_util_utf8_remove_accents):
            Helper function to remove accents from a UTF-8 string.
    
            * libedata-book/e-book-backend-summary.c: (contains_helper),
            (func_contains), (is_helper), (endswith_helper), (beginswith_helper):
            * libedata-book/e-book-backend-sexp.c: (chars_to_unistring_lowercase),
            (is_helper), (endswith_helper), (beginswith_helper), (exists_helper),
            (func_exists): Compare texts without accents.
---
 ChangeLog                                          |    8 ++
 addressbook/ChangeLog                              |   10 +++
 addressbook/libedata-book/e-book-backend-sexp.c    |   75 ++++++++++++++++----
 addressbook/libedata-book/e-book-backend-summary.c |   73 +++++++++++++++----
 libedataserver/e-data-server-util.c                |   32 ++++++++
 libedataserver/e-data-server-util.h                |    1 +
 6 files changed, 169 insertions(+), 30 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index cb708ce..f960478 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-04-24  Milan Crha  <mcrha redhat com>
+
+	** Part of fix for bug #343505
+
+	* libedataserver/e-data-server-util.h: (e_util_utf8_remove_accents):
+	* libedataserver/e-data-server-util.c: (e_util_utf8_remove_accents):
+	Helper function to remove accents from a UTF-8 string.
+
 2009-04-21  Wang Xin  <jedy wang sun com>
 
 	** Fix for bug #578210
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
index 488f687..8de637b 100644
--- a/addressbook/ChangeLog
+++ b/addressbook/ChangeLog
@@ -1,3 +1,13 @@
+2009-04-24  Milan Crha  <mcrha redhat com>
+
+	** Fix for bug #343505
+
+	* libedata-book/e-book-backend-summary.c: (contains_helper),
+	(func_contains), (is_helper), (endswith_helper), (beginswith_helper):
+	* libedata-book/e-book-backend-sexp.c: (chars_to_unistring_lowercase),
+	(is_helper), (endswith_helper), (beginswith_helper), (exists_helper),
+	(func_exists): Compare texts without accents.
+
 2009-03-04  Jeff Cai <jeff cai sun com>
 
 	* libebook/e-contact.c: (n_setter): 
diff --git a/addressbook/libedata-book/e-book-backend-sexp.c b/addressbook/libedata-book/e-book-backend-sexp.c
index debd0e3..8872e5e 100644
--- a/addressbook/libedata-book/e-book-backend-sexp.c
+++ b/addressbook/libedata-book/e-book-backend-sexp.c
@@ -445,13 +445,17 @@ try_contains_word (const gchar *s1, GSList *word)
    returns newly allocated GString
 */
 static GString *
-chars_to_unistring_lowercase (const char *str)
+chars_to_unistring_lowercase (const char *pstr)
 {
 	GString *res;
 	gunichar unich;
-	gchar *p;
+	gchar *p, *str;
 
-	if (str == NULL)
+	if (pstr == NULL)
+		return NULL;
+
+	str = e_util_utf8_remove_accents (pstr);
+	if (!str)
 		return NULL;
 
 	res = g_string_new ("");
@@ -460,6 +464,8 @@ chars_to_unistring_lowercase (const char *str)
 		g_string_append_unichar (res, g_unichar_tolower (unich));
 	}
 
+	g_free (str);
+
 	/* it was invalid unichar string */
 	if (p == NULL) {
 		g_string_free (res, TRUE);
@@ -572,12 +578,22 @@ func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data
 }
 
 static char *
-is_helper (const char *s1, const char *s2)
+is_helper (const char *ps1, const char *ps2)
 {
+	char *s1, *s2, *res;
+
+	s1 = e_util_utf8_remove_accents (ps1);
+	s2 = e_util_utf8_remove_accents (ps2);
+
 	if (!e_util_utf8_strcasecmp (s1, s2))
-		return (char*)s1;
+		res = (char*)ps1;
 	else
-		return NULL;
+		res = NULL;
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
 }
 
 static ESExpResult *
@@ -589,15 +605,23 @@ func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
 }
 
 static char *
-endswith_helper (const char *s1, const char *s2)
+endswith_helper (const char *ps1, const char *ps2)
 {
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+	char *res;
 	glong s1len = g_utf8_strlen (s1, -1);
 	glong s2len = g_utf8_strlen (s2, -1);
 
 	if (s1len < s2len)
-		return NULL;
+		res = NULL;
+	else
+		res = (char *)e_util_utf8_strstrcase (g_utf8_offset_to_pointer (s1, s1len - s2len), s2);
+
+	g_free (s1);
+	g_free (s2);
 
-	return (char *)e_util_utf8_strstrcase (g_utf8_offset_to_pointer (s1, s1len - s2len), s2);
+	return res;
 }
 
 static ESExpResult *
@@ -609,14 +633,22 @@ func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data
 }
 
 static char *
-beginswith_helper (const char *s1, const char *s2)
+beginswith_helper (const char *ps1, const char *ps2)
 {
-	char *p;
+	char *p, *res;
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+
 	if ((p = (char*) e_util_utf8_strstrcase(s1, s2))
 	    && (p == s1))
-		return p;
+		res = (char *)ps1;
 	else
-		return NULL;
+		res = NULL;
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
 }
 
 static ESExpResult *
@@ -627,6 +659,21 @@ func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *da
 	return entry_compare (ctx, f, argc, argv, beginswith_helper);
 }
 
+static char *
+exists_helper (const char *ps1, const char *ps2)
+{
+	char *res;
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+
+	res = (char *)e_util_utf8_strstrcase (s1, s2);
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
+}
+
 static ESExpResult *
 func_exists(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
 {
@@ -660,7 +707,7 @@ func_exists(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
 				}
 				else if (info->prop_type == PROP_TYPE_LIST) {
 				/* the special searches that match any of the list elements */
-					truth = info->list_compare (ctx->contact, "", (char *(*)(const char*, const char*)) e_util_utf8_strstrcase);
+					truth = info->list_compare (ctx->contact, "", exists_helper);
 				}
 
 				break;
diff --git a/addressbook/libedata-book/e-book-backend-summary.c b/addressbook/libedata-book/e-book-backend-summary.c
index 455f690..079ccd4 100644
--- a/addressbook/libedata-book/e-book-backend-summary.c
+++ b/addressbook/libedata-book/e-book-backend-summary.c
@@ -1076,21 +1076,45 @@ do_compare (EBookBackendSummary *summary, struct _ESExp *f, int argc,
 	return r;
 }
 
+static char *
+contains_helper (const char *ps1, const char *ps2)
+{
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+	char *res;
+
+	res = (char *) e_util_utf8_strstrcase (s1, s2);
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
+}
+
 static ESExpResult *
 func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
 {
 	EBookBackendSummary *summary = data;
 
-	return do_compare (summary, f, argc, argv, (char *(*)(const char*, const char*)) e_util_utf8_strstrcase);
+	return do_compare (summary, f, argc, argv, contains_helper);
 }
 
 static char *
-is_helper (const char *s1, const char *s2)
+is_helper (const char *ps1, const char *ps2)
 {
-	if (!e_util_utf8_strcasecmp(s1, s2))
-		return (char*)s1;
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+	char *res;
+
+	if (!e_util_utf8_strcasecmp (s1, s2))
+		res = (char*)ps1;
 	else
-		return NULL;
+		res = NULL;
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
 }
 
 static ESExpResult *
@@ -1102,14 +1126,23 @@ func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
 }
 
 static char *
-endswith_helper (const char *s1, const char *s2)
+endswith_helper (const char *ps1, const char *ps2)
 {
-	char *p;
-	if ((p = (char*)e_util_utf8_strstrcase(s1, s2))
-	    && (strlen(p) == strlen(s2)))
-		return p;
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+	char *res;
+	glong s1len = g_utf8_strlen (s1, -1);
+	glong s2len = g_utf8_strlen (s2, -1);
+
+	if (s1len < s2len)
+		res = NULL;
 	else
-		return NULL;
+		res = (char *)e_util_utf8_strstrcase (g_utf8_offset_to_pointer (s1, s1len - s2len), s2);
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
 }
 
 static ESExpResult *
@@ -1121,14 +1154,22 @@ func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data
 }
 
 static char *
-beginswith_helper (const char *s1, const char *s2)
+beginswith_helper (const char *ps1, const char *ps2)
 {
-	char *p;
-	if ((p = (char*)e_util_utf8_strstrcase(s1, s2))
+	char *p, *res;
+	char *s1 = e_util_utf8_remove_accents (ps1);
+	char *s2 = e_util_utf8_remove_accents (ps2);
+
+	if ((p = (char*) e_util_utf8_strstrcase(s1, s2))
 	    && (p == s1))
-		return p;
+		res = (char *)ps1;
 	else
-		return NULL;
+		res = NULL;
+
+	g_free (s1);
+	g_free (s2);
+
+	return res;
 }
 
 static ESExpResult *
diff --git a/libedataserver/e-data-server-util.c b/libedataserver/e-data-server-util.c
index bab33cd..ce4e445 100644
--- a/libedataserver/e-data-server-util.c
+++ b/libedataserver/e-data-server-util.c
@@ -285,6 +285,38 @@ e_util_utf8_strcasecmp (const gchar *s1, const gchar *s2)
 }
 
 /**
+ * e_util_utf8_remove_accents:
+ *
+ * Returns newly allocates string, copy of 'str', without accents.
+ **/
+gchar *
+e_util_utf8_remove_accents (const char *str)
+{
+	char *res;
+	int i, j;
+
+	if (!str)
+		return NULL;
+
+	res = g_utf8_normalize (str, -1, G_NORMALIZE_NFD);
+	if (!res)
+		return g_strdup (str);
+
+	for (i = 0, j = 0; res [i]; i++) {
+		if ((unsigned char)res[i] != 0xCC || res [i + 1] == 0) {
+			res [j] = res [i];
+			j++;
+		} else {
+			i++;
+		}
+	}
+
+	res [j] = 0;
+
+	return res;
+}
+
+/**
  * e_strftime:
  * @s: The string array to store the result in.
  * @max: The size of array @s.
diff --git a/libedataserver/e-data-server-util.h b/libedataserver/e-data-server-util.h
index 211612b..bd0cc41 100644
--- a/libedataserver/e-data-server-util.h
+++ b/libedataserver/e-data-server-util.h
@@ -40,6 +40,7 @@ gchar       *e_util_unicode_get_utf8 (const gchar *text, gunichar *out);
 const gchar *e_util_utf8_strstrcase (const gchar *haystack, const gchar *needle);
 const gchar *e_util_utf8_strstrcasedecomp (const gchar *haystack, const gchar *needle);
 int	     e_util_utf8_strcasecmp (const gchar *s1, const gchar *s2);
+gchar       *e_util_utf8_remove_accents (const char *str);
 guint64      e_util_pthread_id (pthread_t t);
 void         e_filename_make_safe (gchar *string);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]