From 31f1562d1435fd8b99f9b7f5b19bc93b3210bab4 Mon Sep 17 00:00:00 2001 From: Jon Trowbridge Date: Wed, 26 Sep 2001 19:40:02 +0000 Subject: Properly handle names when the individual elements (given, addition, 2001-09-26 Jon Trowbridge * backend/ebook/e-card-compare.c (e_card_compare_name_to_string): Properly handle names when the individual elements (given, addition, family) contain whitespace. (Bug #10502) * backend/ebook/e-destination.c (e_destination_set_name): Reset textrep when we change the name. (e_destination_set_email): Reset textrep when we change the email. (e_destination_get_textrep): Make sure that the textrep version of the address is properly quoted if it contains unsafe characters. (All related to bug #10796) * gui/component/select-names/e-select-names-completion.c (match_nickname): Fix nickname matching. (bug #9698) (make_match): Use e_completion_match_new when building our match, rather than ad hoc manipulation of the struct. svn path=/trunk/; revision=13158 --- addressbook/ChangeLog | 18 ++++++ addressbook/backend/ebook/e-card-compare.c | 75 ++++++++++++++++------ addressbook/backend/ebook/e-destination.c | 25 +++++--- .../select-names/e-select-names-completion.c | 32 +++++---- 4 files changed, 108 insertions(+), 42 deletions(-) (limited to 'addressbook') diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index 3d65097596..b428a1aa1a 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,21 @@ +2001-09-26 Jon Trowbridge + + * backend/ebook/e-card-compare.c (e_card_compare_name_to_string): + Properly handle names when the individual elements (given, + addition, family) contain whitespace. (Bug #10502) + + * backend/ebook/e-destination.c (e_destination_set_name): Reset + textrep when we change the name. + (e_destination_set_email): Reset textrep when we change the email. + (e_destination_get_textrep): Make sure that the textrep version of + the address is properly quoted if it contains unsafe characters. + (All related to bug #10796) + + * gui/component/select-names/e-select-names-completion.c + (match_nickname): Fix nickname matching. (bug #9698) + (make_match): Use e_completion_match_new when building our match, + rather than ad hoc manipulation of the struct. + 2001-09-26 JP Rosevear * backend/pas/pas-backend-file.c (pas_backend_file_changes): set diff --git a/addressbook/backend/ebook/e-card-compare.c b/addressbook/backend/ebook/e-card-compare.c index 7ccfae0aa7..5cdc745dba 100644 --- a/addressbook/backend/ebook/e-card-compare.c +++ b/addressbook/backend/ebook/e-card-compare.c @@ -105,40 +105,72 @@ name_fragment_match (const gchar *a, const gchar *b) ECardMatchType e_card_compare_name_to_string (ECard *card, const gchar *str) { - gchar **namev; + gchar **namev, **givenv = NULL, **addv = NULL, **familyv = NULL; gboolean matched_given = FALSE, matched_additional = FALSE, matched_family = FALSE, mismatch = FALSE; ECardMatchType match_type; - gint i; + gint match_count = 0; + gint i, j; + gchar *str_cpy, *s; g_return_val_if_fail (E_IS_CARD (card), E_CARD_MATCH_NOT_APPLICABLE); g_return_val_if_fail (card->name != NULL, E_CARD_MATCH_NOT_APPLICABLE); g_return_val_if_fail (str != NULL, E_CARD_MATCH_NOT_APPLICABLE); - namev = g_strsplit (str, " ", 0); + /* FIXME: utf-8 */ + str_cpy = s = g_strdup (str); + while (*s) { + if (*s == ',' || *s == '"') + *s = ' '; + ++s; + } + namev = g_strsplit (str_cpy, " ", 0); + g_free (str_cpy); + + if (card->name->given) + givenv = g_strsplit (card->name->given, " ", 0); + if (card->name->additional) + addv = g_strsplit (card->name->additional, " ", 0); + if (card->name->family) + familyv = g_strsplit (card->name->family, " ", 0); for (i = 0; namev[i] && !mismatch; ++i) { - - if (card->name->given - && !matched_given - && name_fragment_match (card->name->given, namev[i])) { - - matched_given = TRUE; - } else if (card->name->additional - && !matched_additional - && name_fragment_match (card->name->additional, namev[i])) { + if (*namev[i]) { - matched_additional = TRUE; - - } else if (card->name->family - && !matched_family - && !g_utf8_strcasecmp (card->name->family, namev[i])) { + mismatch = TRUE; - matched_family = TRUE; + if (mismatch && givenv) { + for (j = 0; givenv[j]; ++j) { + if (name_fragment_match (givenv[j], namev[i])) { + matched_given = TRUE; + mismatch = FALSE; + ++match_count; + break; + } + } + } - } else { + if (mismatch && addv) { + for (j = 0; addv[j]; ++j) { + if (name_fragment_match (addv[j], namev[i])) { + matched_additional = TRUE; + mismatch = FALSE; + ++match_count; + break; + } + } + } - mismatch = TRUE; + if (mismatch && familyv) { + for (j = 0; familyv[j]; ++j) { + if (!g_utf8_strcasecmp (familyv[j], namev[i])) { + matched_family = TRUE; + mismatch = FALSE; + ++match_count; + break; + } + } + } } } @@ -163,6 +195,9 @@ e_card_compare_name_to_string (ECard *card, const gchar *str) } g_strfreev (namev); + g_strfreev (givenv); + g_strfreev (addv); + g_strfreev (familyv); return match_type; } diff --git a/addressbook/backend/ebook/e-destination.c b/addressbook/backend/ebook/e-destination.c index c5287e5e6d..970057f1fe 100644 --- a/addressbook/backend/ebook/e-destination.c +++ b/addressbook/backend/ebook/e-destination.c @@ -473,6 +473,8 @@ e_destination_set_name (EDestination *dest, const gchar *name) if (changed) { g_free (dest->priv->addr); dest->priv->addr = NULL; + g_free (dest->priv->textrep); + dest->priv->textrep = NULL; e_destination_changed (dest); } } @@ -501,6 +503,8 @@ e_destination_set_email (EDestination *dest, const gchar *email) if (changed) { g_free (dest->priv->addr); dest->priv->addr = NULL; + g_free (dest->priv->textrep); + dest->priv->textrep = NULL; e_destination_changed (dest); } } @@ -812,17 +816,18 @@ e_destination_get_textrep (const EDestination *dest) if (e_destination_from_card (dest) && name != NULL) return name; - if (name && email) { - gchar *rep = g_strdup_printf ("%s <%s>", name, email); - if (dest->priv->textrep && !strcmp (rep, dest->priv->textrep)) { - g_free (rep); - } else { - g_free (dest->priv->textrep); - dest->priv->textrep = rep; - } - return dest->priv->textrep; + /* Make sure that our address gets quoted properly */ + if (name && email && dest->priv->textrep == NULL) { + CamelInternetAddress *addr = camel_internet_address_new (); + camel_internet_address_add (addr, name, email); + g_free (dest->priv->textrep); + dest->priv->textrep = camel_address_encode (CAMEL_ADDRESS (addr)); + camel_object_unref (CAMEL_OBJECT (addr)); } + if (dest->priv->textrep != NULL) + return dest->priv->textrep; + if (email) return email; @@ -908,7 +913,7 @@ static void name_and_email_simple_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure) { EDestination *dest = E_DESTINATION (closure); - + if (status == E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS && g_list_length ((GList *) cards) == 1) { ECard *card = E_CARD (cards->data); const gchar *email = e_destination_get_email (dest); diff --git a/addressbook/gui/component/select-names/e-select-names-completion.c b/addressbook/gui/component/select-names/e-select-names-completion.c index 49a3ecf4b2..1e9027e8fc 100644 --- a/addressbook/gui/component/select-names/e-select-names-completion.c +++ b/addressbook/gui/component/select-names/e-select-names-completion.c @@ -102,14 +102,13 @@ our_match_destroy (ECompletionMatch *match) static ECompletionMatch * make_match (EDestination *dest, const gchar *menu_form, double score) { - ECompletionMatch *match = g_new0 (ECompletionMatch, 1); + ECompletionMatch *match; ECard *card = e_destination_get_card (dest); - e_completion_match_construct (match); + match = e_completion_match_new (e_destination_get_name (dest), menu_form, score); e_completion_match_set_text (match, e_destination_get_name (dest), menu_form); match->sort_major = card ? floor (e_card_get_use_score (card)) : 0; - match->score = score; match->sort_minor = e_destination_get_email_num (dest); match->user_data = dest; @@ -127,8 +126,9 @@ make_match (EDestination *dest, const gchar *menu_form, double score) static gchar * sexp_nickname (ESelectNamesCompletion *comp) { - return g_strdup_printf ("(beginswith \"nickname\" \"%s\")", comp->priv->query_text); + gchar *query = g_strdup_printf ("(beginswith \"nickname\" \"%s\")", comp->priv->query_text); + return query; } static ECompletionMatch * @@ -139,19 +139,25 @@ match_nickname (ESelectNamesCompletion *comp, EDestination *dest) ECard *card = e_destination_get_card (dest); double score; - len = strlen (comp->priv->query_text); + if (card->nickname == NULL) + return NULL; - if (card->nickname - && !g_utf8_strncasecmp (comp->priv->query_text, card->nickname, len)) { - ECompletionMatch *match; + len = MIN (strlen (card->nickname), strlen (comp->priv->query_text)); + + if (card->nickname && !g_utf8_strncasecmp (comp->priv->query_text, card->nickname, len)) { + const gchar *name; gchar *str; - - score = len * 10; /* nickname gives 10 points per matching character */ + + score = len * 2; /* nickname gives 2 points per matching character */ if (len == strlen (card->nickname)) /* boost score on an exact match */ score *= 10; - str = g_strdup_printf ("(%s) %s <%s>", card->nickname, e_destination_get_name (dest), e_destination_get_email (dest)); + name = e_destination_get_name (dest); + if (name && *name) + str = g_strdup_printf ("'%s' %s <%s>", card->nickname, name, e_destination_get_email (dest)); + else + str = g_strdup_printf ("'%s' <%s>", card->nickname, e_destination_get_email (dest)); match = make_match (dest, str, score); g_free (str); @@ -565,8 +571,9 @@ book_query_score (ESelectNamesCompletion *comp, EDestination *dest) ECompletionMatch *this_match = NULL; if (book_queries[i].primary || !comp->priv->primary_only) { - if (book_queries[i].tester && e_destination_get_card (dest)) + if (book_queries[i].tester && e_destination_get_card (dest)) { this_match = book_queries[i].tester (comp, dest); + } if (this_match) { if (best_match == NULL || this_match->score > best_match->score) { @@ -1236,3 +1243,4 @@ e_select_names_completion_set_match_contact_lists (ESelectNamesCompletion *comp, g_return_if_fail (E_IS_SELECT_NAMES_COMPLETION (comp)); comp->priv->match_contact_lists = x; } + -- cgit