aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);