aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Saavedra <csaavedra@igalia.com>2010-04-27 12:23:12 +0300
committerClaudio Saavedra <csaavedra@igalia.com>2010-06-01 17:45:24 +0300
commit622634ebf812dac6f93b653b575610745d60bfd8 (patch)
tree5a73d77ee467370d35ba18766e30fa3292a42701
parent40d712d9446feefd0839e84333c715d8ad3568f0 (diff)
Add and use new iconv based matching methods
These methods allow for more complete matching rules, including for example the polish Ł. Use them now in the HildonTouchSelector live search. Fixes: MB#9948 (Contact quick search entering L does not recognize Polish "Ł") Fixes: NB#165083 (Contact quick search entering L does not recognize Polish "Ł")
-rw-r--r--doc/hildon-sections.txt2
-rw-r--r--hildon/hildon-helper.c65
-rw-r--r--hildon/hildon-helper.h7
-rw-r--r--hildon/hildon-touch-selector.c14
4 files changed, 82 insertions, 6 deletions
diff --git a/doc/hildon-sections.txt b/doc/hildon-sections.txt
index 61df558..2297813 100644
--- a/doc/hildon-sections.txt
+++ b/doc/hildon-sections.txt
@@ -1334,6 +1334,8 @@ hildon_helper_set_thumb_scrollbar
hildon_format_file_size_for_display
hildon_helper_strip_string
hildon_helper_utf8_strstrcasedecomp_needle_stripped
+hildon_helper_normalize_string
+hildon_helper_smart_match
</SECTION>
<SECTION>
diff --git a/hildon/hildon-helper.c b/hildon/hildon-helper.c
index 5dd65c9..76b6596 100644
--- a/hildon/hildon-helper.c
+++ b/hildon/hildon-helper.c
@@ -37,6 +37,7 @@
#include <config.h>
#endif
+#define _GNU_SOURCE
#include <string.h>
#include "hildon-helper.h"
#include "hildon-banner.h"
@@ -731,3 +732,67 @@ hildon_helper_strip_string (const gchar *string)
return nuni;
}
+
+/**
+ * hildon_helper_normalize_string:
+ * @string: a string
+ *
+ * Transform a string into an ascii equivalent representation.
+ * This is necessary for hildon_helper_smart_match() to work properly.
+ *
+ * Returns: a newly allocated string.
+ **/
+gchar *
+hildon_helper_normalize_string (const gchar *string)
+{
+ gchar *str = g_convert (string, -1, "ascii//translit", "utf-8", NULL, NULL, NULL);
+
+ return str;
+}
+
+/**
+ * hildon_helper_smart_match:
+ * @haystack: a string where to find a match
+ * @needle: what to find
+ *
+ * Searches for the first occurence of @needle in @haystack. The search
+ * is performed only in the first alphanumeric character after a
+ * sequence of non-alphanumeric ones. This allows smart matching of words
+ * inside more complex strings.
+ *
+ * If @haystack itself doesn't start with an alphanumeric character,
+ * then the search is equivalent to strcasecmp().
+ *
+ * To make the best of this method, it is recommended that both the needle
+ * and the haystack are already normalized as ASCII strings. For this, you
+ * should call hildon_helper_normalize_string() on both strings.
+ *
+ * Returns: a pointer to the first occurence of @needle in @haystack or %NULL
+ * if not found
+ **/
+gchar *
+hildon_helper_smart_match (const gchar *haystack, const gchar *needle)
+{
+ if (haystack == NULL) return NULL;
+ if (needle == NULL) return NULL;
+ if (strlen (haystack) == 0) return NULL;
+
+ gboolean skip_separators = g_ascii_isalnum (needle[0]);
+
+ if (skip_separators) {
+ gint i = 0;
+ while (haystack[i] != '\0') {
+ while (haystack[i] != '\0' && !g_ascii_isalnum (haystack[i]))
+ i++;
+ if (g_ascii_strncasecmp (haystack + i, needle, strlen (needle)) == 0) {
+ return (gchar *)haystack + i;
+ }
+ while (g_ascii_isalnum (haystack[i]))
+ i++;
+ }
+ } else {
+ return strcasestr (haystack, needle);
+ }
+
+ return NULL;
+}
diff --git a/hildon/hildon-helper.h b/hildon/hildon-helper.h
index 8aad4b3..77e344d 100644
--- a/hildon/hildon-helper.h
+++ b/hildon/hildon-helper.h
@@ -69,6 +69,13 @@ hildon_helper_utf8_strstrcasedecomp_needle_stripped (const gchar *haystack,
gunichar *
hildon_helper_strip_string (const gchar *string);
+gchar *
+hildon_helper_normalize_string (const gchar *string);
+
+gchar *
+hildon_helper_smart_match (const gchar *haystack,
+ const gchar *needle);
+
G_END_DECLS
#endif /* __HILDON_HELPER_H__ */
diff --git a/hildon/hildon-touch-selector.c b/hildon/hildon-touch-selector.c
index 876e47f..96d09d8 100644
--- a/hildon/hildon-touch-selector.c
+++ b/hildon/hildon-touch-selector.c
@@ -1004,7 +1004,7 @@ hildon_live_search_visible_func (GtkTreeModel *model,
gpointer userdata)
{
gboolean visible = TRUE;
- gchar *string;
+ gchar *string, *string_ascii;
GSList *list_iter;
HildonTouchSelectorColumn *col;
HildonTouchSelector *selector;
@@ -1014,15 +1014,17 @@ hildon_live_search_visible_func (GtkTreeModel *model,
gint text_column = GPOINTER_TO_INT (col->priv->text_column);
gtk_tree_model_get (model, iter, text_column, &string, -1);
+ string_ascii = hildon_helper_normalize_string (string);
list_iter = selector->priv->norm_tokens;
while (visible && list_iter) {
- visible = (string != NULL &&
- hildon_helper_utf8_strstrcasedecomp_needle_stripped (string,
- (gunichar *)list_iter->data) != NULL);
+ visible = (string_ascii != NULL &&
+ hildon_helper_smart_match (string_ascii,
+ (const gchar *)list_iter->data));
list_iter = list_iter->next;
}
g_free (string);
+ g_free (string_ascii);
return visible;
}
@@ -1034,7 +1036,7 @@ on_live_search_refilter (HildonLiveSearch *livesearch,
HildonTouchSelector *selector = HILDON_TOUCH_SELECTOR (userdata);
gchar **tokens = g_strsplit (hildon_live_search_get_text (livesearch), " ", -1);
- gunichar *token;
+ gchar *token;
gint i;
if (selector->priv->norm_tokens != NULL) {
@@ -1044,7 +1046,7 @@ on_live_search_refilter (HildonLiveSearch *livesearch,
}
for (i = 0; tokens [i] != NULL; i++) {
- token = hildon_helper_strip_string (tokens[i]);
+ token = hildon_helper_normalize_string (tokens[i]);
if (token != NULL)
selector->priv->norm_tokens = g_slist_prepend (selector->priv->norm_tokens,
token);