Bug 650670 - Duplicate entries when contact is in several address books

This commit is contained in:
Milan Crha
2014-10-23 15:19:10 +02:00
parent 08b2f8686d
commit 05cdd2aee5

View File

@ -63,6 +63,8 @@ struct _ENameSelectorEntryPrivate {
/* For asynchronous operations. */
GQueue cancellables;
GHashTable *known_contacts; /* gchar * ~> 1 */
};
enum {
@ -207,6 +209,11 @@ name_selector_entry_dispose (GObject *object)
priv->contact_store = NULL;
}
if (priv->known_contacts) {
g_hash_table_destroy (priv->known_contacts);
priv->known_contacts = NULL;
}
g_slist_foreach (priv->user_query_fields, (GFunc) g_free, NULL);
g_slist_free (priv->user_query_fields);
priv->user_query_fields = NULL;
@ -373,6 +380,77 @@ e_name_selector_entry_class_init (ENameSelectorEntryClass *class)
G_TYPE_NONE, 1, G_TYPE_POINTER);
}
static gchar *
describe_contact (EContact *contact)
{
GString *description;
const gchar *str;
GList *emails, *link;
g_return_val_if_fail (E_IS_CONTACT (contact), NULL);
emails = e_contact_get (contact, E_CONTACT_EMAIL);
/* Cannot merge one contact with multiple addresses with another contact */
if (!e_contact_get (contact, E_CONTACT_IS_LIST) && emails && emails->next) {
deep_free_list (emails);
return NULL;
}
description = g_string_new ("");
if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
g_string_append (description, "list\n");
} else {
g_string_append (description, "indv\n");
}
str = e_contact_get_const (contact, E_CONTACT_FILE_AS);
g_string_append (description, str ? str : "");
g_string_append (description, "\n");
str = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
g_string_append (description, str ? str : "");
g_string_append (description, "\n");
emails = e_contact_get (contact, E_CONTACT_EMAIL);
emails = g_list_sort (emails, (GCompareFunc) g_ascii_strcasecmp);
for (link = emails; link; link = g_list_next (link)) {
str = link->data;
g_string_append (description, str ? str : "");
g_string_append (description, "\n");
}
deep_free_list (emails);
return g_string_free (description, FALSE);
}
static gboolean
is_duplicate_contact_and_remember (ENameSelectorEntry *nsentry,
EContact *contact)
{
gchar *description;
g_return_val_if_fail (E_IS_NAME_SELECTOR_ENTRY (nsentry), FALSE);
g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
description = describe_contact (contact);
if (!description) {
/* Might be a contact with multiple addresses */
return FALSE;
}
if (g_hash_table_lookup (nsentry->priv->known_contacts, description)) {
g_free (description);
return TRUE;
}
g_hash_table_insert (nsentry->priv->known_contacts, description, GINT_TO_POINTER (1));
return FALSE;
}
/* Remove unquoted commas and control characters from string */
static gchar *
sanitize_string (const gchar *string)
@ -1179,6 +1257,7 @@ clear_completion_model (ENameSelectorEntry *name_selector_entry)
return;
e_contact_store_set_query (name_selector_entry->priv->contact_store, NULL);
g_hash_table_remove_all (name_selector_entry->priv->known_contacts);
priv->is_completing = FALSE;
}
@ -1202,6 +1281,8 @@ update_completion_model (ENameSelectorEntry *name_selector_entry)
cue_str = get_entry_substring (name_selector_entry, range_start, range_end);
set_completion_query (name_selector_entry, cue_str);
g_free (cue_str);
g_hash_table_remove_all (name_selector_entry->priv->known_contacts);
} else {
/* N/A; Clear completion model */
clear_completion_model (name_selector_entry);
@ -2198,6 +2279,9 @@ generate_contact_rows (EContactStore *contact_store,
if (!contact_uid)
return 0; /* Can happen with broken databases */
if (is_duplicate_contact_and_remember (name_selector_entry, contact))
return 0;
if (e_contact_get (contact, E_CONTACT_IS_LIST))
return 1;
@ -3259,6 +3343,7 @@ e_name_selector_entry_init (ENameSelectorEntry *name_selector_entry)
name_selector_entry->priv->minimum_query_length = 3;
name_selector_entry->priv->show_address = FALSE;
name_selector_entry->priv->known_contacts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
/* Edit signals */