No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | eab-contact-merging.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | eab-contact-merging.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * Code for checking for duplicates when doing EContact work.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 *
18 * Authors:
19 * Christopher James Lahey <clahey@ximian.com>
20 * Chris Toshok <toshok@ximian.com>
21 *
22 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
23 *
24 */
25
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29
30 #include "eab-contact-merging.h"
31 #include "eab-contact-compare.h"
32 #include <gtk/gtk.h>
33 #include <string.h>
34 #include "addressbook/gui/widgets/eab-contact-display.h"
35 #include "e-util/e-util.h"
36 #include "e-util/e-util-private.h"
37 #include <glib/gi18n.h>
38
39 typedef struct dropdown_data dropdown_data;
40 typedef enum {
41 E_CONTACT_MERGING_ADD,
42 E_CONTACT_MERGING_COMMIT,
43 E_CONTACT_MERGING_FIND
44 } EContactMergingOpType;
45
46 typedef struct {
47 EContactMergingOpType op;
48 ESourceRegistry *registry;
49 EBookClient *book_client;
50 /*contact is the new contact which the user has tried to add to the addressbook*/
51 EContact *contact;
52 /*match is the duplicate contact already existing in the addressbook*/
53 EContact *match;
54 GList *avoid;
55 EABMergingAsyncCallback cb;
56 EABMergingIdAsyncCallback id_cb;
57 EABMergingContactAsyncCallback c_cb;
58 gpointer closure;
59 } EContactMergingLookup;
60
61 struct dropdown_data {
62 EContact *match;
63 EContactField field;
64 };
65 static void match_query_callback (EContact *contact, EContact *match, EABContactMatchType type, gpointer closure);
66
67 #define SIMULTANEOUS_MERGING_REQUESTS 20
68
69 static GList *merging_queue = NULL;
70 static gint running_merge_requests = 0;
71
72 static void
73 add_lookup (EContactMergingLookup *lookup)
74 {
75 if (running_merge_requests < SIMULTANEOUS_MERGING_REQUESTS) {
76 running_merge_requests++;
77 eab_contact_locate_match_full (
78 lookup->registry, lookup->book_client,
79 lookup->contact, lookup->avoid,
80 match_query_callback, lookup);
81 }
82 else {
83 merging_queue = g_list_append (merging_queue, lookup);
84 }
85 }
86
87 static void
88 finished_lookup (void)
89 {
90 running_merge_requests--;
91
92 while (running_merge_requests < SIMULTANEOUS_MERGING_REQUESTS) {
93 EContactMergingLookup *lookup;
94
95 if (!merging_queue)
96 break;
97
98 lookup = merging_queue->data;
99
100 merging_queue = g_list_remove_link (merging_queue, merging_queue);
101
102 running_merge_requests++;
103 eab_contact_locate_match_full (
104 lookup->registry, lookup->book_client,
105 lookup->contact, lookup->avoid,
106 match_query_callback, lookup);
107 }
108 }
109
110 static void
111 free_lookup (EContactMergingLookup *lookup)
112 {
113 g_object_unref (lookup->registry);
114 g_object_unref (lookup->book_client);
115 g_object_unref (lookup->contact);
116 g_list_free (lookup->avoid);
117 if (lookup->match)
118 g_object_unref (lookup->match);
119 g_free (lookup);
120 }
121
122 static void
123 final_id_cb (EBookClient *book_client,
124 const GError *error,
125 const gchar *id,
126 gpointer closure)
127 {
128 EContactMergingLookup *lookup = closure;
129
130 if (lookup->id_cb)
131 lookup->id_cb (
132 lookup->book_client,
133 error, id, lookup->closure);
134
135 free_lookup (lookup);
136
137 finished_lookup ();
138 }
139
140 static void
141 final_cb_as_id (EBookClient *book_client,
142 const GError *error,
143 gpointer closure)
144 {
145 EContactMergingLookup *lookup = closure;
146
147 if (lookup->id_cb)
148 lookup->id_cb (
149 lookup->book_client,
150 error, lookup->contact ?
151 e_contact_get_const (
152 lookup->contact, E_CONTACT_UID) : NULL,
153 lookup->closure);
154
155 free_lookup (lookup);
156
157 finished_lookup ();
158 }
159
160 static void
161 final_cb (EBookClient *book_client,
162 const GError *error,
163 gpointer closure)
164 {
165 EContactMergingLookup *lookup = closure;
166
167 if (lookup->cb)
168 lookup->cb (lookup->book_client, error, lookup->closure);
169
170 free_lookup (lookup);
171
172 finished_lookup ();
173 }
174
175 static void
176 modify_contact_ready_cb (GObject *source_object,
177 GAsyncResult *result,
178 gpointer user_data)
179 {
180 EBookClient *book_client = E_BOOK_CLIENT (source_object);
181 EContactMergingLookup *lookup = user_data;
182 GError *error = NULL;
183
184 g_return_if_fail (book_client != NULL);
185 g_return_if_fail (lookup != NULL);
186
187 e_book_client_modify_contact_finish (book_client, result, &error);
188
189 if (lookup->op == E_CONTACT_MERGING_ADD)
190 final_cb_as_id (book_client, error, lookup);
191 else
192 final_cb (book_client, error, lookup);
193
194 if (error)
195 g_error_free (error);
196 }
197
198 static void
199 add_contact_ready_cb (GObject *source_object,
200 GAsyncResult *result,
201 gpointer user_data)
202 {
203 EBookClient *book_client = E_BOOK_CLIENT (source_object);
204 EContactMergingLookup *lookup = user_data;
205 gchar *uid = NULL;
206 GError *error = NULL;
207
208 g_return_if_fail (book_client != NULL);
209 g_return_if_fail (lookup != NULL);
210
211 if (!e_book_client_add_contact_finish (book_client, result, &uid, &error))
212 uid = NULL;
213
214 final_id_cb (book_client, error, uid, lookup);
215
216 if (error)
217 g_error_free (error);
218 }
219
220 static void
221 doit (EContactMergingLookup *lookup,
222 gboolean force_modify)
223 {
224 if (lookup->op == E_CONTACT_MERGING_ADD) {
225 if (force_modify)
226 e_book_client_modify_contact (lookup->book_client, lookup->contact, NULL, modify_contact_ready_cb, lookup);
227 else
228 e_book_client_add_contact (lookup->book_client, lookup->contact, NULL, add_contact_ready_cb, lookup);
229 } else if (lookup->op == E_CONTACT_MERGING_COMMIT)
230 e_book_client_modify_contact (lookup->book_client, lookup->contact, NULL, modify_contact_ready_cb, lookup);
231 }
232
233 static void
234 cancelit (EContactMergingLookup *lookup)
235 {
236 GError *error = e_client_error_create (E_CLIENT_ERROR_CANCELLED, NULL);
237
238 if (lookup->op == E_CONTACT_MERGING_ADD) {
239 final_id_cb (lookup->book_client, error, NULL, lookup);
240 } else if (lookup->op == E_CONTACT_MERGING_COMMIT) {
241 final_cb (lookup->book_client, error, lookup);
242 }
243
244 g_error_free (error);
245 }
246
247 static void
248 dialog_map (GtkWidget *window,
249 GdkEvent *event,
250 GtkWidget *table)
251 {
252 GtkAllocation allocation;
253 gint h, w;
254
255 gtk_widget_get_allocation (table, &allocation);
256
257 /* Spacing around the table */
258 w = allocation.width + 30;
259 /* buttons and outer spacing */
260 h = allocation.height + 60;
261 if (w > 400)
262 w = 400;
263 if (h > 450)
264 h = 450;
265
266 gtk_widget_set_size_request (window, w, h);
267 }
268
269 static void
270 dropdown_changed (GtkWidget *dropdown,
271 dropdown_data *data)
272 {
273 gchar *str;
274 str = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (dropdown));
275
276 if (g_ascii_strcasecmp (str, ""))
277 e_contact_set (data->match, data->field, str);
278 else
279 e_contact_set (data->match, data->field, NULL);
280 return;
281 }
282
283 static void
284 remove_contact_ready_cb (GObject *source_object,
285 GAsyncResult *result,
286 gpointer user_data)
287 {
288 EBookClient *book_client = E_BOOK_CLIENT (source_object);
289 EContactMergingLookup *lookup = user_data;
290 GError *error = NULL;
291
292 g_return_if_fail (book_client != NULL);
293 g_return_if_fail (lookup != NULL);
294
295 e_book_client_remove_contact_finish (book_client, result, &error);
296
297 if (error != NULL) {
298 g_warning (
299 "%s: Failed to remove contact: %s",
300 G_STRFUNC, error->message);
301 g_error_free (error);
302 }
303
304 e_book_client_add_contact (
305 book_client, lookup->contact, NULL,
306 add_contact_ready_cb, lookup);
307 }
308
309 static gint
310 mergeit (EContactMergingLookup *lookup)
311 {
312 GtkWidget *scrolled_window, *label, *hbox, *dropdown;
313 GtkWidget *content_area;
314 GtkWidget *dialog;
315 GtkTable *table;
316 EContactField field;
317 gchar *str = NULL, *string = NULL, *string1 = NULL;
318 gint num_of_email;
319 GList *email_attr_list;
320 gint row = -1;
321 gint value = 0, result;
322
323 dialog = gtk_dialog_new ();
324 gtk_window_set_title (GTK_WINDOW (dialog), _("Merge Contact"));
325 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
326
327 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
328
329 scrolled_window = gtk_scrolled_window_new (NULL, NULL);
330 gtk_scrolled_window_set_policy (
331 GTK_SCROLLED_WINDOW (scrolled_window),
332 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
333
334 table = (GtkTable *) gtk_table_new (20, 2, FALSE);
335 gtk_container_set_border_width ((GtkContainer *) table, 12);
336 gtk_table_set_row_spacings (table, 6);
337 gtk_table_set_col_spacings (table, 2);
338
339 gtk_dialog_add_buttons (
340 GTK_DIALOG (dialog),
341 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
342 _("_Merge"), GTK_RESPONSE_OK,
343 NULL);
344
345 email_attr_list = e_contact_get_attributes (lookup->match, E_CONTACT_EMAIL);
346 num_of_email = g_list_length (email_attr_list);
347
348 /*we match all the string fields of the already existing contact and the new contact.*/
349 for (field = E_CONTACT_FULL_NAME; field != (E_CONTACT_LAST_SIMPLE_STRING -1); field++) {
350 dropdown_data *data = NULL;
351 string = (gchar *) e_contact_get_const (lookup->contact, field);
352 string1 = (gchar *) e_contact_get_const (lookup->match, field);
353
354 /*the field must exist in the new as well as the duplicate contact*/
355 if (string && *string) {
356 /*Four email id's present, should be compared with all email id's in duplicate contact */
357 /*Merge only if number of email id's in existing contact is less than 4 */
358 if ((field == E_CONTACT_EMAIL_1 || field == E_CONTACT_EMAIL_2
359 || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) && (num_of_email < 4)) {
360 EContactField use_field = field;
361 row++;
362 str = (gchar *) e_contact_get_const (lookup->contact, use_field);
363 switch (num_of_email)
364 {
365 case 0:
366 use_field = E_CONTACT_EMAIL_1;
367 break;
368 case 1:
369 /*New contact has email that is NOT equal to email in duplicate contact*/
370 if ((str && *str) && (g_ascii_strcasecmp (e_contact_get_const (lookup->match, E_CONTACT_EMAIL_1),str))) {
371 use_field = E_CONTACT_EMAIL_2;
372 break;
373 }
374 else/*Either the new contact has no email OR the email already exist in the duplicate contact */
375 continue;
376 case 2:
377 /*New contact has email and it is equal to neither of the 2 emails in the duplicate contact*/
378 if ((str && *str) &&
379 (g_ascii_strcasecmp (str,e_contact_get_const (lookup->match, E_CONTACT_EMAIL_1))) &&
380 (g_ascii_strcasecmp (e_contact_get_const (lookup->match, E_CONTACT_EMAIL_2),str))) {
381 use_field = E_CONTACT_EMAIL_3;
382 break;
383 }
384 else
385 continue;
386 case 3:
387 /*New contact has email and it is equal to none of the 3 emails in the duplicate contact*/
388 if ((str && *str) &&
389 (g_ascii_strcasecmp (e_contact_get_const (lookup->match, E_CONTACT_EMAIL_1),str)) &&
390 (g_ascii_strcasecmp (e_contact_get_const (lookup->match, E_CONTACT_EMAIL_2),str)) &&
391 (g_ascii_strcasecmp (e_contact_get_const (lookup->match, E_CONTACT_EMAIL_3),str)))
392 use_field = E_CONTACT_EMAIL_4;
393 else
394 continue;
395 }
396 label = gtk_label_new (_("Email"));
397 hbox = gtk_hbox_new (FALSE, 0);
398 gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0);
399 gtk_table_attach_defaults (table, (GtkWidget *) hbox, 0, 1, row, row + 1);
400
401 dropdown = gtk_combo_box_text_new ();
402 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), string);
403
404 data = g_new0 (dropdown_data, 1);
405
406 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), "");
407
408 gtk_combo_box_set_active (GTK_COMBO_BOX (dropdown), 0);
409 data->field = use_field;
410 data->match = lookup->match;
411 e_contact_set (lookup->match, use_field, string);
412 g_signal_connect (
413 dropdown, "changed",
414 G_CALLBACK (dropdown_changed), data);
415
416 hbox = gtk_hbox_new (FALSE, 0);
417 gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) dropdown, FALSE, FALSE, 0);
418 gtk_table_attach_defaults (table, (GtkWidget *) hbox, 1, 2, row, row + 1);
419 gtk_widget_show ((GtkWidget *) dropdown);
420 continue;
421 }
422 if (((field == E_CONTACT_FULL_NAME) && (!g_ascii_strcasecmp (string, string1)))) {
423 row++;
424 label = gtk_label_new (e_contact_pretty_name (field));
425 hbox = gtk_hbox_new (FALSE, 0);
426 gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0);
427 gtk_table_attach_defaults (table, (GtkWidget *) hbox, 0, 1, row, row + 1);
428
429 label = gtk_label_new (string);
430 hbox = gtk_hbox_new (FALSE, 0);
431 gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0);
432 gtk_table_attach_defaults (table, (GtkWidget *) hbox, 1, 2, row, row + 1);
433 continue;
434 }
435
436 /*for all string fields except name and email*/
437 if (!(string1 && *string1) || (g_ascii_strcasecmp (string, string1))) {
438 row++;
439 label = gtk_label_new (e_contact_pretty_name (field));
440 hbox = gtk_hbox_new (FALSE, 0);
441 gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0);
442 gtk_table_attach_defaults (table, (GtkWidget *) hbox, 0, 1, row, row + 1);
443 data = g_new0 (dropdown_data, 1);
444 dropdown = gtk_combo_box_text_new ();
445 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), string);
446 e_contact_set (lookup->match, field, string);
447
448 if (string1 && *string1)
449 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), string1);
450 else
451 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), "");
452
453 gtk_combo_box_set_active (GTK_COMBO_BOX (dropdown), 0);
454 data->field = field;
455 data->match = lookup->match;
456
457 if (field == E_CONTACT_NICKNAME || field == E_CONTACT_GIVEN_NAME)
458 gtk_widget_set_sensitive ((GtkWidget *) dropdown, FALSE);
459
460 g_signal_connect (
461 dropdown, "changed",
462 G_CALLBACK (dropdown_changed), data);
463
464 hbox = gtk_hbox_new (FALSE, 0);
465 gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) dropdown, FALSE, FALSE, 0);
466 gtk_table_attach_defaults (table, (GtkWidget *) hbox, 1, 2, row, row + 1);
467 gtk_widget_show_all ((GtkWidget *) dropdown);
468 }
469 }
470 }
471
472 gtk_window_set_default_size (GTK_WINDOW (dialog), 420, 300);
473 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), GTK_WIDGET (table));
474 gtk_box_pack_start (GTK_BOX (content_area), GTK_WIDGET (scrolled_window), TRUE, TRUE, 0);
475 gtk_widget_show (scrolled_window);
476 g_signal_connect (
477 dialog, "map-event",
478 G_CALLBACK (dialog_map), table);
479 gtk_widget_show_all ((GtkWidget *) table);
480 result = gtk_dialog_run (GTK_DIALOG (dialog));
481
482 switch (result) {
483 case GTK_RESPONSE_OK:
484 g_object_unref (lookup->contact);
485 lookup->contact = g_object_ref (lookup->match);
486 e_book_client_remove_contact (
487 lookup->book_client,
488 lookup->match, NULL,
489 remove_contact_ready_cb, lookup);
490 value = 1;
491 break;
492 case GTK_RESPONSE_CANCEL:
493 default:
494 value = 0;
495 break;
496 }
497 gtk_widget_destroy (dialog);
498 g_list_free_full (email_attr_list, (GDestroyNotify) e_vcard_attribute_free);
499 return value;
500 }
501
502 static gboolean
503 check_if_same (EContact *contact,
504 EContact *match)
505 {
506 EContactField field;
507 GList *email_attr_list;
508 gint num_of_email;
509 gchar *str = NULL, *string = NULL, *string1 = NULL;
510 gboolean res = TRUE;
511
512 email_attr_list = e_contact_get_attributes (match, E_CONTACT_EMAIL);
513 num_of_email = g_list_length (email_attr_list);
514
515 for (field = E_CONTACT_FULL_NAME; res && field != (E_CONTACT_LAST_SIMPLE_STRING -1); field++) {
516
517 if ((field == E_CONTACT_EMAIL_1 || field == E_CONTACT_EMAIL_2
518 || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) && (num_of_email < 4)) {
519 str = (gchar *) e_contact_get_const (contact, field);
520 switch (num_of_email)
521 {
522 case 0:
523 res = FALSE;
524 break;
525 case 1:
526 if ((str && *str) && (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_1),str)))
527 res = FALSE;
528 break;
529 case 2:
530 if ((str && *str) && (g_ascii_strcasecmp (str,e_contact_get_const (match, E_CONTACT_EMAIL_1))) &&
531 (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_2),str)))
532 res = FALSE;
533 break;
534 case 3:
535 if ((str && *str) && (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_1),str)) &&
536 (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_2),str)) &&
537 (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_3),str)))
538 res = FALSE;
539 break;
540 }
541 }
542 else {
543 string = (gchar *) e_contact_get_const (contact, field);
544 string1 = (gchar *) e_contact_get_const (match, field);
545 if ((string && *string) && (string1 && *string1) && (g_ascii_strcasecmp (string1, string))) {
546 res = FALSE;
547 break;
548 /*if the field entry exist in either of the contacts,we'll have to give the choice and thus merge button should be sensitive*/
549 } else if ((string && *string) && !(string1 && *string1)) {
550 res = FALSE;
551 break;
552 }
553 }
554 }
555
556 g_list_free_full (email_attr_list, (GDestroyNotify) e_vcard_attribute_free);
557
558 return res;
559 }
560
561 static void
562 response (GtkWidget *dialog,
563 gint response,
564 EContactMergingLookup *lookup)
565 {
566 static gint merge_response;
567
568 switch (response) {
569 case 0:
570 doit (lookup, FALSE);
571 break;
572 case 1:
573 cancelit (lookup);
574 break;
575 case 2:
576 merge_response = mergeit (lookup);
577 if (merge_response)
578 break;
579 return;
580 case GTK_RESPONSE_DELETE_EVENT:
581 cancelit (lookup);
582 break;
583 }
584
585 gtk_widget_destroy (dialog);
586 }
587
588 static void
589 match_query_callback (EContact *contact,
590 EContact *match,
591 EABContactMatchType type,
592 gpointer closure)
593 {
594 EContactMergingLookup *lookup = closure;
595 gint flag;
596 gboolean same_uids;
597
598 if (lookup->op == E_CONTACT_MERGING_FIND) {
599 if (lookup->c_cb)
600 lookup->c_cb (
601 lookup->book_client, NULL,
602 (gint) type <= (gint)
603 EAB_CONTACT_MATCH_VAGUE ? NULL : match,
604 lookup->closure);
605
606 free_lookup (lookup);
607 finished_lookup ();
608 return;
609 }
610
611 /* if had same UID, then we are editing old contact, thus force commit change to it */
612 same_uids = contact && match
613 && e_contact_get_const (contact, E_CONTACT_UID)
614 && e_contact_get_const (match, E_CONTACT_UID)
615 && g_str_equal (e_contact_get_const (contact, E_CONTACT_UID), e_contact_get_const (match, E_CONTACT_UID));
616
617 if ((gint) type <= (gint) EAB_CONTACT_MATCH_VAGUE || same_uids) {
618 doit (lookup, same_uids);
619 } else {
620 GtkBuilder *builder;
621 GtkWidget *container;
622 GtkWidget *merge_button;
623 GtkWidget *widget;
624
625 /* XXX I think we're leaking the GtkBuilder. */
626 builder = gtk_builder_new ();
627
628 lookup->match = g_object_ref (match);
629 if (lookup->op == E_CONTACT_MERGING_ADD) {
630 /* Compares all the values of contacts and return true, if they match */
631 flag = check_if_same (contact, match);
632 e_load_ui_builder_definition (
633 builder, "eab-contact-duplicate-detected.ui");
634 merge_button = e_builder_get_widget (builder, "button5");
635 /* Merge Button not sensitive when all values are same */
636 if (flag)
637 gtk_widget_set_sensitive (GTK_WIDGET (merge_button), FALSE);
638 } else if (lookup->op == E_CONTACT_MERGING_COMMIT) {
639 e_load_ui_builder_definition (
640 builder, "eab-contact-commit-duplicate-detected.ui");
641 } else {
642 doit (lookup, FALSE);
643 return;
644 }
645
646 widget = e_builder_get_widget (builder, "custom-old-contact");
647 eab_contact_display_set_mode (
648 EAB_CONTACT_DISPLAY (widget),
649 EAB_CONTACT_DISPLAY_RENDER_COMPACT);
650 eab_contact_display_set_contact (
651 EAB_CONTACT_DISPLAY (widget), match);
652
653 widget = e_builder_get_widget (builder, "custom-new-contact");
654 eab_contact_display_set_mode (
655 EAB_CONTACT_DISPLAY (widget),
656 EAB_CONTACT_DISPLAY_RENDER_COMPACT);
657 eab_contact_display_set_contact (
658 EAB_CONTACT_DISPLAY (widget), contact);
659
660 widget = e_builder_get_widget (builder, "dialog-duplicate-contact");
661
662 gtk_widget_ensure_style (widget);
663
664 container = gtk_dialog_get_action_area (GTK_DIALOG (widget));
665 gtk_container_set_border_width (GTK_CONTAINER (container), 12);
666
667 container = gtk_dialog_get_content_area (GTK_DIALOG (widget));
668 gtk_container_set_border_width (GTK_CONTAINER (container), 0);
669
670 g_signal_connect (
671 widget, "response",
672 G_CALLBACK (response), lookup);
673
674 gtk_widget_show_all (widget);
675 }
676 }
677
678 gboolean
679 eab_merging_book_add_contact (ESourceRegistry *registry,
680 EBookClient *book_client,
681 EContact *contact,
682 EABMergingIdAsyncCallback cb,
683 gpointer closure)
684 {
685 EContactMergingLookup *lookup;
686
687 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
688
689 lookup = g_new (EContactMergingLookup, 1);
690
691 lookup->op = E_CONTACT_MERGING_ADD;
692 lookup->registry = g_object_ref (registry);
693 lookup->book_client = g_object_ref (book_client);
694 lookup->contact = g_object_ref (contact);
695 lookup->id_cb = cb;
696 lookup->closure = closure;
697 lookup->avoid = NULL;
698 lookup->match = NULL;
699
700 add_lookup (lookup);
701
702 return TRUE;
703 }
704
705 gboolean
706 eab_merging_book_modify_contact (ESourceRegistry *registry,
707 EBookClient *book_client,
708 EContact *contact,
709 EABMergingAsyncCallback cb,
710 gpointer closure)
711 {
712 EContactMergingLookup *lookup;
713
714 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
715
716 lookup = g_new (EContactMergingLookup, 1);
717
718 lookup->op = E_CONTACT_MERGING_COMMIT;
719 lookup->registry = g_object_ref (registry);
720 lookup->book_client = g_object_ref (book_client);
721 lookup->contact = g_object_ref (contact);
722 lookup->cb = cb;
723 lookup->closure = closure;
724 lookup->avoid = g_list_append (NULL, contact);
725 lookup->match = NULL;
726
727 add_lookup (lookup);
728
729 return TRUE;
730 }
731
732 gboolean
733 eab_merging_book_find_contact (ESourceRegistry *registry,
734 EBookClient *book_client,
735 EContact *contact,
736 EABMergingContactAsyncCallback cb,
737 gpointer closure)
738 {
739 EContactMergingLookup *lookup;
740
741 lookup = g_new (EContactMergingLookup, 1);
742
743 lookup->op = E_CONTACT_MERGING_FIND;
744 lookup->registry = g_object_ref (registry);
745 lookup->book_client = g_object_ref (book_client);
746 lookup->contact = g_object_ref (contact);
747 lookup->c_cb = cb;
748 lookup->closure = closure;
749 lookup->avoid = g_list_append (NULL, contact);
750 lookup->match = NULL;
751
752 add_lookup (lookup);
753
754 return TRUE;
755 }