comparison plugins/gevolution/add_buddy_dialog.c @ 8089:35db601609e3

[gaim-migrate @ 8788] Gaim-Evolution Buddy List-Addressbook syncronocity by our very own Chip X. Eightysix. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Tue, 13 Jan 2004 01:45:32 +0000
parents
children a5ec9e73f46d
comparison
equal deleted inserted replaced
8088:a86784e3b98c 8089:35db601609e3
1 /*
2 * Evolution integration plugin for Gaim
3 *
4 * Copyright (C) 2003 Christian Hammond.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21 #include "gtkinternal.h"
22 #include "gtkblist.h"
23 #include "gtkutils.h"
24
25 #include "debug.h"
26
27 #include "gevolution.h"
28
29 #include <stdlib.h>
30 #include <bonobo/bonobo-main.h>
31 #include <libebook/e-book.h>
32 #include <libebook/e-book-async.h>
33 #include <libedataserver/e-source-list.h>
34
35 enum
36 {
37 COLUMN_NAME,
38 COLUMN_PRPL_ICON,
39 COLUMN_USERNAME,
40 COLUMN_DATA,
41 NUM_COLUMNS
42 };
43
44 static gint
45 delete_win_cb(GtkWidget *w, GdkEvent *event, GevoAddBuddyDialog *dialog)
46 {
47 gtk_widget_destroy(dialog->win);
48
49 g_list_foreach(dialog->contacts, (GFunc)g_object_unref, NULL);
50
51 if (dialog->contacts != NULL)
52 g_list_free(dialog->contacts);
53
54 if (dialog->book != NULL)
55 g_object_unref(dialog->book);
56
57 if (dialog->username != NULL)
58 g_free(dialog->username);
59
60 g_free(dialog);
61
62 return 0;
63 }
64
65 static void
66 new_person_cb(GtkWidget *w, GevoAddBuddyDialog *dialog)
67 {
68 const char *group_name;
69
70 group_name =
71 gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(dialog->group_combo)->entry));
72
73 gevo_new_person_dialog_show(NULL, dialog->account, NULL,
74 (*group_name ? group_name : NULL),
75 NULL, FALSE);
76
77 delete_win_cb(NULL, NULL, dialog);
78 }
79
80 static void
81 cancel_cb(GtkWidget *w, GevoAddBuddyDialog *dialog)
82 {
83 delete_win_cb(NULL, NULL, dialog);
84 }
85
86 static void
87 select_buddy_cb(GtkWidget *w, GevoAddBuddyDialog *dialog)
88 {
89 GtkTreeSelection *selection;
90 GtkTreeIter iter;
91 const char *group_name;
92 const char *fullname;
93 const char *username;
94 EContact *contact;
95
96 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
97
98 gtk_tree_selection_get_selected(selection, NULL, &iter);
99
100 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter,
101 COLUMN_NAME, &fullname,
102 COLUMN_USERNAME, &username,
103 COLUMN_DATA, &contact,
104 -1);
105
106 group_name =
107 gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(dialog->group_combo)->entry));
108
109 if (username == NULL || *username == '\0')
110 {
111 gevo_new_person_dialog_show(NULL, dialog->account, NULL,
112 (*group_name ? group_name : NULL),
113 NULL, FALSE);
114 }
115 else
116 {
117 gevo_add_buddy(dialog->account, group_name, username, fullname);
118 }
119
120 delete_win_cb(NULL, NULL, dialog);
121 }
122
123 static void
124 populate_address_books(GevoAddBuddyDialog *dialog)
125 {
126 GtkWidget *item;
127 GtkWidget *menu;
128 #if notyet
129 ESourceList *addressbooks;
130 GList *groups, *g;
131 #endif
132
133 menu =
134 gtk_option_menu_get_menu(GTK_OPTION_MENU(dialog->addressbooks_menu));
135
136 item = gtk_menu_item_new_with_label(_("Local Addressbook"));
137 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
138 gtk_widget_show(item);
139
140 #if notyet
141 if (!e_book_get_addressbooks(&addressbooks, NULL))
142 {
143 gaim_debug_error("evolution",
144 "Unable to fetch list of address books.\n");
145
146 item = gtk_menu_item_new_with_label(_("None"));
147 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
148 gtk_widget_show(item);
149
150 return;
151 }
152
153 groups = e_source_list_peek_groups(list);
154
155 if (groups == NULL)
156 {
157 item = gtk_menu_item_new_with_label(_("None"));
158 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
159 gtk_widget_show(item);
160
161 return;
162 }
163
164 for (g = groups; g != NULL; g = g->next)
165 {
166 GList *sources, *s;
167
168 sources = e_source_group_peek_sources(g->data);
169
170 for (p = sources; p != NULL; p = p->next)
171 {
172 ESource *source = E_SOURCE(p->data);
173
174 item = gtk_menu_item_new_with_label(e_source_peek_name(source));
175 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
176 gtk_widget_show(item);
177 }
178 }
179 #endif
180 }
181
182 static void
183 add_columns(GevoAddBuddyDialog *dialog)
184 {
185 GtkCellRenderer *renderer;
186 GtkTreeViewColumn *column;
187
188 /* Name column */
189 column = gtk_tree_view_column_new();
190 gtk_tree_view_column_set_title(column, _("Name"));
191 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1);
192 gtk_tree_view_column_set_sort_column_id(column, COLUMN_NAME);
193
194 renderer = gtk_cell_renderer_text_new();
195 gtk_tree_view_column_pack_start(column, renderer, TRUE);
196 gtk_tree_view_column_add_attribute(column, renderer,
197 "text", COLUMN_NAME);
198
199 /* Account column */
200 column = gtk_tree_view_column_new();
201 gtk_tree_view_column_set_title(column, _("Instant Messaging"));
202 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1);
203 gtk_tree_view_column_set_sort_column_id(column, COLUMN_USERNAME);
204
205 /* Protocol icon */
206 renderer = gtk_cell_renderer_pixbuf_new();
207 gtk_tree_view_column_pack_start(column, renderer, FALSE);
208 gtk_tree_view_column_add_attribute(column, renderer,
209 "pixbuf", COLUMN_PRPL_ICON);
210
211 /* Account name */
212 renderer = gtk_cell_renderer_text_new();
213 gtk_tree_view_column_pack_start(column, renderer, TRUE);
214 gtk_tree_view_column_add_attribute(column, renderer,
215 "text", COLUMN_USERNAME);
216 }
217
218 static void
219 add_ims(GevoAddBuddyDialog *dialog, EContact *contact, const char *name,
220 GList *list, const char *id)
221 {
222 GaimAccount *account = NULL;
223 GList *l;
224 GtkTreeIter iter;
225 GdkPixbuf *pixbuf, *icon = NULL;
226
227 if (list == NULL)
228 return;
229
230 for (l = gaim_connections_get_all(); l != NULL; l = l->next)
231 {
232 GaimConnection *gc = (GaimConnection *)l->data;
233
234 account = gaim_connection_get_account(gc);
235
236 if (!strcmp(gaim_account_get_protocol_id(account), id))
237 break;
238
239 account = NULL;
240 }
241
242 if (account == NULL)
243 return;
244
245 pixbuf = create_prpl_icon(account);
246
247 if (pixbuf != NULL)
248 icon = gdk_pixbuf_scale_simple(pixbuf, 16, 16,
249 GDK_INTERP_BILINEAR);
250
251 for (l = list; l != NULL; l = l->next)
252 {
253 char *account_name = (char *)l->data;
254
255 if (account_name == NULL)
256 continue;
257
258 if (gaim_find_buddy(dialog->account, account_name) != NULL)
259 continue;
260
261 gtk_list_store_append(dialog->model, &iter);
262
263 gtk_list_store_set(dialog->model, &iter,
264 COLUMN_NAME, name,
265 COLUMN_PRPL_ICON, icon,
266 COLUMN_USERNAME, account_name,
267 COLUMN_DATA, contact,
268 -1);
269
270 if (!strcmp(gaim_account_get_protocol_id(account),
271 gaim_account_get_protocol_id(dialog->account)) &&
272 dialog->username != NULL &&
273 !strcmp(account_name, dialog->username))
274 {
275 GtkTreeSelection *selection;
276
277 /* This is it. Select it. */
278 selection = gtk_tree_view_get_selection(
279 GTK_TREE_VIEW(dialog->treeview));
280
281 gtk_tree_selection_select_iter(selection, &iter);
282 }
283 }
284
285 if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf));
286 if (icon != NULL) g_object_unref(G_OBJECT(icon));
287
288 g_list_foreach(list, (GFunc)g_free, NULL);
289 g_list_free(list);
290 }
291
292 static void
293 populate_treeview(GevoAddBuddyDialog *dialog)
294 {
295 EBookQuery *query;
296 EBook *book;
297 gboolean status;
298 GList *cards, *c;
299
300 if (!gevo_load_addressbook(&book, NULL))
301 {
302 gaim_debug_error("evolution",
303 "Error retrieving default addressbook\n");
304
305 return;
306 }
307
308 query = e_book_query_field_exists(E_CONTACT_FULL_NAME);
309
310 if (query == NULL)
311 {
312 gaim_debug_error("evolution", "Error in creating query\n");
313
314 g_object_unref(book);
315
316 return;
317 }
318
319 status = e_book_get_contacts(book, query, &cards, NULL);
320
321 e_book_query_unref(query);
322
323 if (!status)
324 {
325 gaim_debug_error("evolution", "Error %d in getting card list\n",
326 status);
327
328 g_object_unref(book);
329
330 return;
331 }
332
333 for (c = cards; c != NULL; c = c->next)
334 {
335 EContact *contact = E_CONTACT(c->data);
336 const char *name;
337 GList *aims, *jabbers, *yahoos, *msns, *icqs;
338
339 name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
340
341 aims = e_contact_get(contact, E_CONTACT_IM_AIM);
342 jabbers = e_contact_get(contact, E_CONTACT_IM_JABBER);
343 yahoos = e_contact_get(contact, E_CONTACT_IM_YAHOO);
344 msns = e_contact_get(contact, E_CONTACT_IM_MSN);
345 icqs = e_contact_get(contact, E_CONTACT_IM_ICQ);
346
347 if (aims == NULL && jabbers == NULL && yahoos == NULL &&
348 msns == NULL && icqs == NULL)
349 {
350 GtkTreeIter iter;
351
352 gtk_list_store_append(dialog->model, &iter);
353
354 gtk_list_store_set(dialog->model, &iter,
355 COLUMN_NAME, name,
356 COLUMN_DATA, contact,
357 -1);
358 }
359 else
360 {
361 add_ims(dialog, contact, name, aims, "prpl-oscar");
362 add_ims(dialog, contact, name, jabbers, "prpl-jabber");
363 add_ims(dialog, contact, name, yahoos, "prpl-yahoo");
364 add_ims(dialog, contact, name, msns, "prpl-msn");
365 add_ims(dialog, contact, name, icqs, "prpl-oscar");
366 }
367 }
368
369 dialog->contacts = cards;
370 dialog->book = book;
371 }
372
373 static void
374 selected_cb(GtkTreeSelection *sel, GevoAddBuddyDialog *dialog)
375 {
376 gtk_widget_set_sensitive(dialog->select_button, TRUE);
377 }
378
379 static void
380 search_changed_cb(GtkEntry *entry, GevoAddBuddyDialog *dialog)
381 {
382 const char *text = gtk_entry_get_text(entry);
383 GList *l;
384
385 gtk_list_store_clear(dialog->model);
386
387 for (l = dialog->contacts; l != NULL; l = l->next)
388 {
389 EContact *contact = E_CONTACT(l->data);
390 const char *name;
391 GList *aims, *jabbers, *yahoos, *msns, *icqs;
392
393 name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
394
395 if (text != NULL && *text != '\0' && name != NULL &&
396 g_ascii_strncasecmp(name, text, strlen(text)))
397 {
398 continue;
399 }
400
401 aims = e_contact_get(contact, E_CONTACT_IM_AIM);
402 jabbers = e_contact_get(contact, E_CONTACT_IM_JABBER);
403 yahoos = e_contact_get(contact, E_CONTACT_IM_YAHOO);
404 msns = e_contact_get(contact, E_CONTACT_IM_MSN);
405 icqs = e_contact_get(contact, E_CONTACT_IM_ICQ);
406
407 if (aims == NULL && jabbers == NULL && yahoos == NULL &&
408 msns == NULL && icqs == NULL)
409 {
410 GtkTreeIter iter;
411
412 gtk_list_store_append(dialog->model, &iter);
413
414 gtk_list_store_set(dialog->model, &iter,
415 COLUMN_NAME, name,
416 COLUMN_DATA, contact,
417 -1);
418 }
419 else
420 {
421 add_ims(dialog, contact, name, aims, "prpl-oscar");
422 add_ims(dialog, contact, name, jabbers, "prpl-jabber");
423 add_ims(dialog, contact, name, yahoos, "prpl-yahoo");
424 add_ims(dialog, contact, name, msns, "prpl-msn");
425 add_ims(dialog, contact, name, icqs, "prpl-oscar");
426 }
427 }
428 }
429
430 static void
431 clear_cb(GtkWidget *w, GevoAddBuddyDialog *dialog)
432 {
433 static gboolean lock = FALSE;
434
435 if (lock)
436 return;
437
438 lock = TRUE;
439 gtk_entry_set_text(GTK_ENTRY(dialog->search_field), "");
440 lock = FALSE;
441 }
442
443 void
444 gevo_add_buddy_dialog_show(GaimAccount *account, const char *username,
445 const char *group, const char *alias)
446 {
447 GevoAddBuddyDialog *dialog;
448 GtkWidget *button;
449 GtkWidget *sw;
450 GtkWidget *label;
451 GtkWidget *vbox;
452 GtkWidget *hbox;
453 GtkWidget *bbox;
454 GtkWidget *menu;
455 GtkWidget *sep;
456 GtkTreeSelection *selection;
457
458 dialog = g_new0(GevoAddBuddyDialog, 1);
459
460 dialog->account =
461 (account != NULL
462 ? account
463 : gaim_connection_get_account(gaim_connections_get_all()->data));
464
465 if (username != NULL)
466 dialog->username = g_strdup(username);
467
468 dialog->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
469 gtk_window_set_role(GTK_WINDOW(dialog->win), "add_buddy");
470 gtk_container_set_border_width(GTK_CONTAINER(dialog->win), 12);
471 gtk_widget_set_size_request(dialog->win, -1, 400);
472
473 g_signal_connect(G_OBJECT(dialog->win), "delete_event",
474 G_CALLBACK(delete_win_cb), dialog);
475
476 /* Setup the vbox */
477 vbox = gtk_vbox_new(FALSE, 12);
478 gtk_container_add(GTK_CONTAINER(dialog->win), vbox);
479 gtk_widget_show(vbox);
480
481 /* Add the label. */
482 label = gtk_label_new(_("Select a person from your address book below, "
483 "or add a new person."));
484 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
485 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
486 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
487 gtk_widget_show(label);
488
489 /* Add the search hbox */
490 hbox = gtk_hbox_new(FALSE, 6);
491 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
492 gtk_widget_show(hbox);
493
494 /* "Search" */
495 label = gtk_label_new(_("Search"));
496 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
497 gtk_widget_show(label);
498
499 /* Addressbooks */
500 dialog->addressbooks_menu = gtk_option_menu_new();
501 menu = gtk_menu_new();
502 gtk_option_menu_set_menu(GTK_OPTION_MENU(dialog->addressbooks_menu), menu);
503
504 populate_address_books(dialog);
505
506 gtk_option_menu_set_history(GTK_OPTION_MENU(dialog->addressbooks_menu), 0);
507
508 gtk_box_pack_start(GTK_BOX(hbox), dialog->addressbooks_menu,
509 FALSE, FALSE, 0);
510 gtk_widget_show(dialog->addressbooks_menu);
511
512 /* Search field */
513 dialog->search_field = gtk_entry_new();
514 gtk_box_pack_start(GTK_BOX(hbox), dialog->search_field, TRUE, TRUE, 0);
515 gtk_widget_show(dialog->search_field);
516
517 g_signal_connect(G_OBJECT(dialog->search_field), "changed",
518 G_CALLBACK(search_changed_cb), dialog);
519
520 /* Clear button */
521 button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
522 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
523 gtk_widget_show(button);
524
525 g_signal_connect(G_OBJECT(button), "clicked",
526 G_CALLBACK(clear_cb), dialog);
527
528 /* Scrolled Window */
529 sw = gtk_scrolled_window_new(0, 0);
530 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
531 GTK_POLICY_AUTOMATIC,
532 GTK_POLICY_ALWAYS);
533 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
534 GTK_SHADOW_IN);
535 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
536 gtk_widget_show(sw);
537
538 /* Create the list model for the treeview. */
539 dialog->model = gtk_list_store_new(NUM_COLUMNS,
540 G_TYPE_STRING, GDK_TYPE_PIXBUF,
541 G_TYPE_STRING, G_TYPE_POINTER);
542
543 /* Now for the treeview */
544 dialog->treeview =
545 gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model));
546 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE);
547 gtk_container_add(GTK_CONTAINER(sw), dialog->treeview);
548 gtk_widget_show(dialog->treeview);
549
550 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
551
552 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
553
554 g_signal_connect(G_OBJECT(selection), "changed",
555 G_CALLBACK(selected_cb), dialog);
556
557 add_columns(dialog);
558
559 populate_treeview(dialog);
560
561 /* Group box */
562 hbox = gtk_hbox_new(FALSE, 6);
563 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
564 gtk_widget_show(hbox);
565
566 label = gtk_label_new(_("Group:"));
567 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
568 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
569 gtk_widget_show(label);
570
571 dialog->group_combo = gtk_combo_new();
572 gtk_combo_set_popdown_strings(GTK_COMBO(dialog->group_combo),
573 gevo_get_groups());
574 gtk_box_pack_start(GTK_BOX(hbox), dialog->group_combo, TRUE, TRUE, 0);
575 gtk_widget_show(dialog->group_combo);
576
577 /* Cool. Now we only have a little left... */
578
579 /* Separator. */
580 sep = gtk_hseparator_new();
581 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
582 gtk_widget_show(sep);
583
584 /* Button box */
585 bbox = gtk_hbutton_box_new();
586 gtk_box_set_spacing(GTK_BOX(bbox), 6);
587 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
588 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
589 gtk_widget_show(bbox);
590
591 /* "New Person" button */
592 button = gaim_pixbuf_button_from_stock(_("New Person"), GTK_STOCK_NEW,
593 GAIM_BUTTON_HORIZONTAL);
594 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
595 gtk_widget_show(button);
596
597 g_signal_connect(G_OBJECT(button), "clicked",
598 G_CALLBACK(new_person_cb), dialog);
599
600 /* "Cancel" button */
601 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
602 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
603 gtk_widget_show(button);
604
605 g_signal_connect(G_OBJECT(button), "clicked",
606 G_CALLBACK(cancel_cb), dialog);
607
608 /* "Select Buddy" button */
609 button = gaim_pixbuf_button_from_stock(_("Select Buddy"), GTK_STOCK_APPLY,
610 GAIM_BUTTON_HORIZONTAL);
611 dialog->select_button = button;
612 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
613 gtk_widget_set_sensitive(button, FALSE);
614 gtk_widget_show(button);
615
616 g_signal_connect(G_OBJECT(button), "clicked",
617 G_CALLBACK(select_buddy_cb), dialog);
618
619 /* Show it. */
620 gtk_widget_show(dialog->win);
621 }
622
623 void
624 gevo_add_buddy_dialog_add_person(GevoAddBuddyDialog *dialog,
625 EContact *contact, const char *name,
626 GaimAccount *account, const char *screenname)
627 {
628 GdkPixbuf *pixbuf, *icon = NULL;
629 GtkTreeIter iter;
630
631 pixbuf = create_prpl_icon(account);
632
633 if (pixbuf != NULL)
634 icon = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR);
635
636 gtk_list_store_append(dialog->model, &iter);
637
638 gtk_list_store_set(dialog->model, &iter,
639 COLUMN_NAME, name,
640 COLUMN_PRPL_ICON, icon,
641 COLUMN_DATA, contact,
642 COLUMN_USERNAME, screenname,
643 -1);
644
645 if (contact != NULL)
646 dialog->contacts = g_list_append(dialog->contacts, contact);
647
648 if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf));
649 if (icon != NULL) g_object_unref(G_OBJECT(icon));
650 }