Bug 650670 - Duplicate entries when contact is in several address books
This commit is contained in:
@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user