aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--addressbook/ChangeLog10
-rw-r--r--addressbook/gui/merging/eab-contact-duplicate-detected.glade11
-rw-r--r--addressbook/gui/merging/eab-contact-merging.c294
3 files changed, 309 insertions, 6 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
index 1431d352ee..210a531008 100644
--- a/addressbook/ChangeLog
+++ b/addressbook/ChangeLog
@@ -1,3 +1,13 @@
+2007-04-18 Srinivasa Ragavan <sragavan@novell.com>
+
+ ** Committed Contact Merging patch from Ebby Wiselyn
+
+ * gui/merging/eab-contact-duplicate-detected.glade:
+ * gui/merging/eab-contact-merging.c: (free_lookup), (dialog_map),
+ (dropdown_changed), (mergeit), (check_if_same), (response),
+ (match_query_callback), (eab_merging_book_add_contact),
+ (eab_merging_book_commit_contact):
+
2007-04-10 Elizabeth Greene <nerdygirl_ellie@yahoo.com>
** Fix for bug #426743.
diff --git a/addressbook/gui/merging/eab-contact-duplicate-detected.glade b/addressbook/gui/merging/eab-contact-duplicate-detected.glade
index b16c1662f5..4d6b4802ad 100644
--- a/addressbook/gui/merging/eab-contact-duplicate-detected.glade
+++ b/addressbook/gui/merging/eab-contact-duplicate-detected.glade
@@ -56,6 +56,17 @@
<property name="response_id">0</property>
</widget>
</child>
+ <child>
+ <widget class="GtkButton" id="button5">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">Merge</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">2</property>
+ </widget>
+ </child>
</widget>
<packing>
<property name="padding">0</property>
diff --git a/addressbook/gui/merging/eab-contact-merging.c b/addressbook/gui/merging/eab-contact-merging.c
index a8a2917ade..2296647a11 100644
--- a/addressbook/gui/merging/eab-contact-merging.c
+++ b/addressbook/gui/merging/eab-contact-merging.c
@@ -14,12 +14,18 @@
#include "eab-contact-merging.h"
#include "eab-contact-compare.h"
#include <glade/glade.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkcombo.h>
#include <gtk/gtksignal.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkcontainer.h>
+#include <string.h>
#include "addressbook/gui/widgets/eab-contact-display.h"
#include "e-util/e-util-private.h"
+#include <libgnome/gnome-i18n.h>
+typedef struct dropdown_data dropdown_data;
typedef enum {
E_CONTACT_MERGING_ADD,
E_CONTACT_MERGING_COMMIT
@@ -28,13 +34,20 @@ typedef enum {
typedef struct {
EContactMergingOpType op;
EBook *book;
+ /*contact is the new contact which the user has tried to add to the addressbook*/
EContact *contact;
+ /*match is the duplicate contact already existing in the addressbook*/
+ EContact *match;
GList *avoid;
EBookIdCallback id_cb;
EBookCallback cb;
gpointer closure;
} EContactMergingLookup;
+struct dropdown_data {
+ EContact *match;
+ EContactField field;
+};
static void match_query_callback (EContact *contact, EContact *match, EABContactMatchType type, gpointer closure);
#define SIMULTANEOUS_MERGING_REQUESTS 20
@@ -62,7 +75,7 @@ finished_lookup (void)
while (running_merge_requests < SIMULTANEOUS_MERGING_REQUESTS) {
EContactMergingLookup *lookup;
-
+
if (!merging_queue)
break;
@@ -81,7 +94,8 @@ free_lookup (EContactMergingLookup *lookup)
g_object_unref (lookup->book);
g_object_unref (lookup->contact);
g_list_free (lookup->avoid);
-
+ if(lookup->match)
+ g_object_unref (lookup->match);
g_free (lookup);
}
@@ -130,11 +144,263 @@ cancelit (EContactMergingLookup *lookup)
}
}
+gboolean
+dialog_map (GtkWidget *window, GdkEvent *event, GtkWidget *table)
+{
+ int h, w;
+
+ /* Spacing around the table */
+ w = table->allocation.width + 30;
+ /* buttons and outer spacing */
+ h = table->allocation.height + 60;
+ if (w > 400)
+ w = 400;
+ if (h > 450)
+ h = 450;
+ gtk_widget_set_usize (window, w, h);
+}
+
static void
-response (GtkWidget *dialog, int response, EContactMergingLookup *lookup)
+dropdown_changed (GtkWidget *dropdown, dropdown_data *data)
{
+ char *str;
+ str = gtk_combo_box_get_active_text (dropdown);
+
+ if (g_ascii_strcasecmp(str, ""))
+ e_contact_set (data->match, data->field, str);
+ else
+ e_contact_set (data->match, data->field, NULL);
+ return;
+}
+
+static int
+mergeit (EContactMergingLookup *lookup)
+{
+ GtkWidget *scrolled_window, *label, *hbox, *dropdown;
+ GtkDialog *dialog;
+ GtkTable *table;
+ EContactField field;
+ char *str = NULL, *string = NULL, *string1 = NULL;
+ int num_of_email;
+ GList *email_attr_list;
+ int row = -1;
+ int value;
+
+ dialog = (GtkDialog *)(gtk_dialog_new_with_buttons (_("Merge Contact"), NULL, GTK_DIALOG_NO_SEPARATOR, NULL));
+ gtk_container_border_width (GTK_CONTAINER(dialog), 5);
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ table = (GtkTable *) gtk_table_new (20, 2, FALSE);
+ gtk_container_set_border_width ((GtkContainer *) table, 12);
+ gtk_table_set_row_spacings (table, 6);
+ gtk_table_set_col_spacings (table, 2);
+
+ gtk_dialog_add_buttons ((GtkDialog *) dialog,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ _("Merge"), GTK_RESPONSE_OK,
+ NULL);
+
+ email_attr_list = e_contact_get_attributes (lookup->match, E_CONTACT_EMAIL);
+ num_of_email = g_list_length (email_attr_list);
+
+ /*we match all the string fields of the already existing contact and the new contact.*/
+ for(field = E_CONTACT_FULL_NAME; field != (E_CONTACT_LAST_SIMPLE_STRING -1) ; field++) {
+ dropdown_data *data = NULL;
+ string = e_contact_get_const (lookup->contact, field);
+ string1 = e_contact_get_const (lookup->match, field);
+
+ /*the field must exist in the new as well as the duplicate contact*/
+ if (string && *string) {
+ /*Four email id's present, should be compared with all email id's in duplicate contact */
+ /*Merge only if number of email id's in existing contact is less than 4 */
+ if ((field == E_CONTACT_EMAIL_1 || field == E_CONTACT_EMAIL_2
+ || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) && (num_of_email < 4)) {
+ row++;
+ str = e_contact_get_const (lookup->contact, field);
+ switch(num_of_email)
+ {
+ case 0:
+ field = E_CONTACT_EMAIL_1;
+ break;
+ case 1:
+ /*New contact has email that is NOT equal to email in duplicate contact*/
+ if((str && *str) && (g_ascii_strcasecmp(e_contact_get_const (lookup->match, E_CONTACT_EMAIL_1),str))) {
+ field = E_CONTACT_EMAIL_2;
+ break;
+ }
+ else/*Either the new contact has no email OR the email already exist in the duplicate contact*/
+ continue;
+ case 2:
+ /*New contact has email and it is equal to neither of the 2 emails in the duplicate contact*/
+ if((str && *str) &&
+ (g_ascii_strcasecmp(str,e_contact_get_const (lookup->match, E_CONTACT_EMAIL_1))) &&
+ (g_ascii_strcasecmp(e_contact_get_const (lookup->match, E_CONTACT_EMAIL_2),str))) {
+ field = E_CONTACT_EMAIL_3;
+ break;
+ }
+ else
+ continue;
+ case 3:
+ /*New contact has email and it is equal to none of the 3 emails in the duplicate contact*/
+ if((str && *str) &&
+ (g_ascii_strcasecmp(e_contact_get_const (lookup->match, E_CONTACT_EMAIL_1),str)) &&
+ (g_ascii_strcasecmp(e_contact_get_const (lookup->match, E_CONTACT_EMAIL_2),str)) &&
+ (g_ascii_strcasecmp(e_contact_get_const (lookup->match, E_CONTACT_EMAIL_3),str)))
+ field = E_CONTACT_EMAIL_4;
+ else
+ continue;
+ }
+ label = gtk_label_new (_("Email"));
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX(hbox), (GtkWidget*)label, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget *)hbox, 0, 1, row, row + 1);
+
+ dropdown = gtk_combo_box_new_text();
+ gtk_combo_box_append_text (dropdown, string);
+
+ data = g_new0 (dropdown_data, 1);
+
+ gtk_combo_box_append_text (dropdown, "");
+
+ gtk_combo_box_set_active (dropdown, 0);
+ data->field = field;
+ data->match = lookup->match;
+ e_contact_set (lookup->match, field, string);
+ g_signal_connect (dropdown, "changed", G_CALLBACK(dropdown_changed), data);
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX(hbox), (GtkWidget*)dropdown, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget *)hbox, 1, 2, row, row + 1);
+ gtk_widget_show ((GtkWidget *)dropdown);
+ continue;
+ }
+ if (((field == E_CONTACT_FULL_NAME) && (!g_ascii_strcasecmp(string, string1)))) {
+ row++;
+ label = gtk_label_new (e_contact_pretty_name(field));
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX(hbox), (GtkWidget*)label, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget *)hbox, 0, 1, row, row + 1);
+
+ label = gtk_label_new (string);
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX(hbox), (GtkWidget*)label, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget*)hbox, 1, 2, row, row + 1);
+ continue;
+ }
+
+ /*for all string fields except name and email*/
+ if(!(string1 && *string1) || (g_ascii_strcasecmp(string, string1))) {
+ row++;
+ label = gtk_label_new (e_contact_pretty_name(field));
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX(hbox), (GtkWidget*)label, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget *)hbox, 0, 1, row, row + 1);
+ data = g_new0 (dropdown_data, 1);
+ dropdown = gtk_combo_box_new_text();
+ gtk_combo_box_append_text (dropdown, string);
+ e_contact_set (lookup->match, field, string);
+
+ if (string1 && *string1)
+ gtk_combo_box_append_text (dropdown, string1);
+ else
+ gtk_combo_box_append_text (dropdown, "");
+
+ gtk_combo_box_set_active (dropdown, 0);
+ data->field = field;
+ data->match = lookup->match;
+
+ if (field == E_CONTACT_NICKNAME || field == E_CONTACT_GIVEN_NAME)
+ gtk_widget_set_sensitive ((GtkWidget *)dropdown, FALSE);
+
+ g_signal_connect (dropdown, "changed", G_CALLBACK(dropdown_changed), data);
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX(hbox), (GtkWidget*)dropdown, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget *)hbox, 1, 2, row, row + 1);
+ gtk_widget_show_all ((GtkWidget *)dropdown);
+ }
+ }
+ }
+
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 420, 300);
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), GTK_WIDGET (table));
+ gtk_box_pack_start (GTK_BOX (dialog->vbox), GTK_WIDGET (scrolled_window), TRUE, TRUE, 0);
+ gtk_widget_show (scrolled_window);
+ g_signal_connect (dialog, "map-event", G_CALLBACK (dialog_map), table);
+ gtk_widget_show_all ((GtkWidget *)table);
+ gint result = gtk_dialog_run (dialog);
+
+ switch (result)
+ {
+ case GTK_RESPONSE_OK:
+ lookup->contact = lookup->match;
+ e_book_async_remove_contact (lookup->book, lookup->match, NULL, lookup);
+ e_book_async_add_contact (lookup->book, lookup->contact, final_id_cb, lookup);
+ value = 1;
+ break;
+ case GTK_RESPONSE_CANCEL:
+ value = 0;
+ break;
+ }
gtk_widget_destroy (dialog);
+ g_list_free (email_attr_list);
+ return value;
+}
+
+static gboolean
+check_if_same (EContact *contact, EContact *match)
+{
+ EContactField field;
+ GList *email_attr_list;
+ int num_of_email;
+ char *str = NULL, *string = NULL, *string1 = NULL;
+
+ for(field = E_CONTACT_FULL_NAME; field != (E_CONTACT_LAST_SIMPLE_STRING -1) ; field++) {
+ email_attr_list = e_contact_get_attributes (match, E_CONTACT_EMAIL);
+ num_of_email = g_list_length (email_attr_list);
+
+ if ((field == E_CONTACT_EMAIL_1 || field == E_CONTACT_EMAIL_2
+ || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) && (num_of_email<4)) {
+ str = e_contact_get_const (contact, field);
+ switch(num_of_email)
+ {
+ case 0:
+ return FALSE;
+ case 1:
+ if((str && *str) && (g_ascii_strcasecmp(e_contact_get_const (match, E_CONTACT_EMAIL_1),str)))
+ return FALSE;
+ case 2:
+ if((str && *str) && (g_ascii_strcasecmp(str,e_contact_get_const (match, E_CONTACT_EMAIL_1))) &&
+ (g_ascii_strcasecmp(e_contact_get_const (match, E_CONTACT_EMAIL_2),str)))
+ return FALSE;
+ case 3:
+ if((str && *str) && (g_ascii_strcasecmp(e_contact_get_const (match, E_CONTACT_EMAIL_1),str)) &&
+ (g_ascii_strcasecmp(e_contact_get_const (match, E_CONTACT_EMAIL_2),str)) &&
+ (g_ascii_strcasecmp(e_contact_get_const (match, E_CONTACT_EMAIL_3),str)))
+ return FALSE;
+ }
+ }
+ else {
+ string = e_contact_get_const (contact, field);
+ string1 = e_contact_get_const (match, field);
+ if ((string && *string) && (string1 && *string1) && (g_ascii_strcasecmp(string1,string)))
+ return FALSE;
+ /*if the field entry exist in either of the contacts,we'll have to give the choice and thus merge button should be sensitive*/
+ else if ((string && *string) && !(string1 && *string1))
+ return FALSE;
+ }
+ }
+ g_list_free (email_attr_list);
+ return TRUE;
+}
+static void
+response (GtkWidget *dialog, int response, EContactMergingLookup *lookup)
+{
+ static int merge_response;
switch (response) {
case 0:
doit (lookup);
@@ -142,10 +408,16 @@ response (GtkWidget *dialog, int response, EContactMergingLookup *lookup)
case 1:
cancelit (lookup);
break;
+ case 2:
+ merge_response = mergeit (lookup);
+ if (merge_response)
+ break;
+ return;
case GTK_RESPONSE_DELETE_EVENT:
cancelit (lookup);
break;
}
+ gtk_widget_destroy (dialog);
}
static void
@@ -153,19 +425,27 @@ match_query_callback (EContact *contact, EContact *match, EABContactMatchType ty
{
EContactMergingLookup *lookup = closure;
char *gladefile;
+ int flag;
if ((gint) type <= (gint) EAB_CONTACT_MATCH_VAGUE) {
doit (lookup);
} else {
GladeXML *ui;
-
- GtkWidget *widget;
+ GtkWidget *widget, *merge_button;
+
+ lookup->match = g_object_ref (match);
if (lookup->op == E_CONTACT_MERGING_ADD) {
+ /* Compares all the values of contacts and return true, if they match */
+ flag = check_if_same (contact, match);
gladefile = g_build_filename (EVOLUTION_GLADEDIR,
"eab-contact-duplicate-detected.glade",
NULL);
ui = glade_xml_new (gladefile, NULL, NULL);
+ merge_button = GTK_BUTTON (glade_xml_get_widget (ui, "button5"));
+ /* Merge Button not sensitive when all values are same */
+ if (flag)
+ gtk_widget_set_sensitive ((GtkWidget *)merge_button, FALSE);
g_free (gladefile);
} else if (lookup->op == E_CONTACT_MERGING_COMMIT) {
gladefile = g_build_filename (EVOLUTION_GLADEDIR,
@@ -215,6 +495,7 @@ eab_merging_book_add_contact (EBook *book,
lookup->id_cb = cb;
lookup->closure = closure;
lookup->avoid = NULL;
+ lookup->match = NULL;
add_lookup (lookup);
@@ -228,7 +509,7 @@ eab_merging_book_commit_contact (EBook *book,
gpointer closure)
{
EContactMergingLookup *lookup;
-
+
lookup = g_new (EContactMergingLookup, 1);
lookup->op = E_CONTACT_MERGING_COMMIT;
@@ -237,6 +518,7 @@ eab_merging_book_commit_contact (EBook *book,
lookup->cb = cb;
lookup->closure = closure;
lookup->avoid = g_list_append (NULL, contact);
+ lookup->match = NULL;
add_lookup (lookup);