comparison gtk/plugins/gevolution/add_buddy_dialog.c @ 14191:009db0b357b5

This is a hand-crafted commit to migrate across subversion revisions 16854:16861, due to some vagaries of the way the original renames were done. Witness that monotone can do in one revision what svn had to spread across several.
author Ethan Blanton <elb@pidgin.im>
date Sat, 16 Dec 2006 04:59:55 +0000
parents
children 972ff6ca923f
comparison
equal deleted inserted replaced
14190:366be2ce35a7 14191:009db0b357b5
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 "internal.h"
22 #include "gtkblist.h"
23 #include "gtkgaim.h"
24 #include "gtkutils.h"
25
26 #include "debug.h"
27
28 #include "gevolution.h"
29
30 #include <stdlib.h>
31
32 enum
33 {
34 COLUMN_NAME,
35 COLUMN_PRPL_ICON,
36 COLUMN_USERNAME,
37 COLUMN_DATA,
38 NUM_COLUMNS
39 };
40
41 static gint
42 delete_win_cb(GtkWidget *w, GdkEvent *event, GevoAddBuddyDialog *dialog)
43 {
44 gtk_widget_destroy(dialog->win);
45
46 if (dialog->contacts != NULL)
47 {
48 g_list_foreach(dialog->contacts, (GFunc)g_object_unref, NULL);
49 g_list_free(dialog->contacts);
50 }
51
52 if (dialog->book != NULL)
53 g_object_unref(dialog->book);
54
55 gevo_addrbooks_model_unref(dialog->addrbooks);
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(dialog->book, NULL, dialog->account, dialog->username,
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(dialog->book, NULL, dialog->account, dialog->username,
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 add_columns(GevoAddBuddyDialog *dialog)
125 {
126 GtkCellRenderer *renderer;
127 GtkTreeViewColumn *column;
128
129 /* Name column */
130 column = gtk_tree_view_column_new();
131 gtk_tree_view_column_set_title(column, _("Name"));
132 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1);
133 gtk_tree_view_column_set_sort_column_id(column, COLUMN_NAME);
134
135 renderer = gtk_cell_renderer_text_new();
136 gtk_tree_view_column_pack_start(column, renderer, TRUE);
137 gtk_tree_view_column_add_attribute(column, renderer,
138 "text", COLUMN_NAME);
139
140 /* Account column */
141 column = gtk_tree_view_column_new();
142 gtk_tree_view_column_set_title(column, _("Instant Messaging"));
143 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1);
144 gtk_tree_view_column_set_sort_column_id(column, COLUMN_USERNAME);
145
146 /* Protocol icon */
147 renderer = gtk_cell_renderer_pixbuf_new();
148 gtk_tree_view_column_pack_start(column, renderer, FALSE);
149 gtk_tree_view_column_add_attribute(column, renderer,
150 "pixbuf", COLUMN_PRPL_ICON);
151
152 /* Account name */
153 renderer = gtk_cell_renderer_text_new();
154 gtk_tree_view_column_pack_start(column, renderer, TRUE);
155 gtk_tree_view_column_add_attribute(column, renderer,
156 "text", COLUMN_USERNAME);
157 }
158
159 static void
160 add_ims(GevoAddBuddyDialog *dialog, EContact *contact, const char *name,
161 GList *list, const char *id)
162 {
163 GaimAccount *account = NULL;
164 GList *l;
165 GtkTreeIter iter;
166 GdkPixbuf *pixbuf;
167
168 if (list == NULL)
169 return;
170
171 for (l = gaim_connections_get_all(); l != NULL; l = l->next)
172 {
173 GaimConnection *gc = (GaimConnection *)l->data;
174
175 account = gaim_connection_get_account(gc);
176
177 if (!strcmp(gaim_account_get_protocol_id(account), id))
178 break;
179
180 account = NULL;
181 }
182
183 if (account == NULL)
184 return;
185
186 pixbuf = gaim_gtk_create_prpl_icon(account, 0.5);
187
188 for (l = list; l != NULL; l = l->next)
189 {
190 char *account_name = (char *)l->data;
191
192 if (account_name == NULL)
193 continue;
194
195 if (gaim_find_buddy(dialog->account, account_name) != NULL)
196 continue;
197
198 gtk_list_store_append(dialog->model, &iter);
199
200 gtk_list_store_set(dialog->model, &iter,
201 COLUMN_NAME, name,
202 COLUMN_PRPL_ICON, pixbuf,
203 COLUMN_USERNAME, account_name,
204 COLUMN_DATA, contact,
205 -1);
206
207 if (!strcmp(gaim_account_get_protocol_id(account),
208 gaim_account_get_protocol_id(dialog->account)) &&
209 dialog->username != NULL &&
210 !strcmp(account_name, dialog->username))
211 {
212 GtkTreeSelection *selection;
213
214 /* This is it. Select it. */
215 selection = gtk_tree_view_get_selection(
216 GTK_TREE_VIEW(dialog->treeview));
217
218 gtk_tree_selection_select_iter(selection, &iter);
219 }
220 }
221
222 if (pixbuf != NULL)
223 g_object_unref(G_OBJECT(pixbuf));
224
225 g_list_foreach(list, (GFunc)g_free, NULL);
226 g_list_free(list);
227 }
228
229 static void
230 populate_treeview(GevoAddBuddyDialog *dialog, const gchar *uri)
231 {
232 EBookQuery *query;
233 EBook *book;
234 gboolean status;
235 GList *cards, *c;
236
237 if (dialog->book != NULL)
238 {
239 g_object_unref(dialog->book);
240 dialog->book = NULL;
241 }
242
243 if (dialog->contacts != NULL)
244 {
245 g_list_foreach(dialog->contacts, (GFunc)g_object_unref, NULL);
246 g_list_free(dialog->contacts);
247 dialog->contacts = NULL;
248 }
249
250 gtk_list_store_clear(dialog->model);
251
252 if (!gevo_load_addressbook(uri, &book, NULL))
253 {
254 gaim_debug_error("evolution",
255 "Error retrieving default addressbook\n");
256
257 return;
258 }
259
260 query = e_book_query_field_exists(E_CONTACT_FULL_NAME);
261
262 if (query == NULL)
263 {
264 gaim_debug_error("evolution", "Error in creating query\n");
265
266 g_object_unref(book);
267
268 return;
269 }
270
271 status = e_book_get_contacts(book, query, &cards, NULL);
272
273 e_book_query_unref(query);
274
275 if (!status)
276 {
277 gaim_debug_error("evolution", "Error %d in getting card list\n",
278 status);
279
280 g_object_unref(book);
281
282 return;
283 }
284
285 for (c = cards; c != NULL; c = c->next)
286 {
287 EContact *contact = E_CONTACT(c->data);
288 const char *name;
289 GList *aims, *jabbers, *yahoos, *msns, *icqs, *novells;
290
291 name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
292
293 aims = e_contact_get(contact, E_CONTACT_IM_AIM);
294 jabbers = e_contact_get(contact, E_CONTACT_IM_JABBER);
295 yahoos = e_contact_get(contact, E_CONTACT_IM_YAHOO);
296 msns = e_contact_get(contact, E_CONTACT_IM_MSN);
297 icqs = e_contact_get(contact, E_CONTACT_IM_ICQ);
298 novells = e_contact_get(contact, E_CONTACT_IM_GROUPWISE);
299
300 if (aims == NULL && jabbers == NULL && yahoos == NULL &&
301 msns == NULL && icqs == NULL && novells == NULL)
302 {
303 GtkTreeIter iter;
304
305 gtk_list_store_append(dialog->model, &iter);
306
307 gtk_list_store_set(dialog->model, &iter,
308 COLUMN_NAME, name,
309 COLUMN_DATA, contact,
310 -1);
311 }
312 else
313 {
314 add_ims(dialog, contact, name, aims, "prpl-oscar");
315 add_ims(dialog, contact, name, jabbers, "prpl-jabber");
316 add_ims(dialog, contact, name, yahoos, "prpl-yahoo");
317 add_ims(dialog, contact, name, msns, "prpl-msn");
318 add_ims(dialog, contact, name, icqs, "prpl-oscar");
319 add_ims(dialog, contact, name, novells, "prpl-novell");
320 }
321 }
322
323 dialog->contacts = cards;
324 dialog->book = book;
325 }
326
327 static void
328 addrbook_change_cb(GtkComboBox *combo, GevoAddBuddyDialog *dialog)
329 {
330 GtkTreeIter iter;
331 const char *esource_uri;
332
333 if (!gtk_combo_box_get_active_iter(combo, &iter))
334 return;
335
336 gtk_tree_model_get(GTK_TREE_MODEL(dialog->addrbooks), &iter,
337 ADDRBOOK_COLUMN_URI, &esource_uri,
338 -1);
339
340 populate_treeview(dialog, esource_uri);
341 }
342
343 static void
344 selected_cb(GtkTreeSelection *sel, GevoAddBuddyDialog *dialog)
345 {
346 gtk_widget_set_sensitive(dialog->select_button, TRUE);
347 }
348
349 static void
350 search_changed_cb(GtkEntry *entry, GevoAddBuddyDialog *dialog)
351 {
352 const char *text = gtk_entry_get_text(entry);
353 GList *l;
354
355 gtk_list_store_clear(dialog->model);
356
357 for (l = dialog->contacts; l != NULL; l = l->next)
358 {
359 EContact *contact = E_CONTACT(l->data);
360 const char *name;
361 GList *aims, *jabbers, *yahoos, *msns, *icqs, *novells;
362
363 name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
364
365 if (text != NULL && *text != '\0' && name != NULL &&
366 g_ascii_strncasecmp(name, text, strlen(text)))
367 {
368 continue;
369 }
370
371 aims = e_contact_get(contact, E_CONTACT_IM_AIM);
372 jabbers = e_contact_get(contact, E_CONTACT_IM_JABBER);
373 yahoos = e_contact_get(contact, E_CONTACT_IM_YAHOO);
374 msns = e_contact_get(contact, E_CONTACT_IM_MSN);
375 icqs = e_contact_get(contact, E_CONTACT_IM_ICQ);
376 novells = e_contact_get(contact, E_CONTACT_IM_GROUPWISE);
377
378 if (aims == NULL && jabbers == NULL && yahoos == NULL &&
379 msns == NULL && icqs == NULL && novells == NULL)
380 {
381 GtkTreeIter iter;
382
383 gtk_list_store_append(dialog->model, &iter);
384
385 gtk_list_store_set(dialog->model, &iter,
386 COLUMN_NAME, name,
387 COLUMN_DATA, contact,
388 -1);
389 }
390 else
391 {
392 add_ims(dialog, contact, name, aims, "prpl-oscar");
393 add_ims(dialog, contact, name, jabbers, "prpl-jabber");
394 add_ims(dialog, contact, name, yahoos, "prpl-yahoo");
395 add_ims(dialog, contact, name, msns, "prpl-msn");
396 add_ims(dialog, contact, name, icqs, "prpl-oscar");
397 add_ims(dialog, contact, name, novells, "prpl-novell");
398 }
399 }
400 }
401
402 static void
403 clear_cb(GtkWidget *w, GevoAddBuddyDialog *dialog)
404 {
405 static gboolean lock = FALSE;
406
407 if (lock)
408 return;
409
410 lock = TRUE;
411 gtk_entry_set_text(GTK_ENTRY(dialog->search_field), "");
412 lock = FALSE;
413 }
414
415 void
416 gevo_add_buddy_dialog_show(GaimAccount *account, const char *username,
417 const char *group, const char *alias)
418 {
419 GevoAddBuddyDialog *dialog;
420 GtkWidget *button;
421 GtkWidget *sw;
422 GtkWidget *label;
423 GtkWidget *vbox;
424 GtkWidget *hbox;
425 GtkWidget *bbox;
426 GtkWidget *sep;
427 GtkTreeSelection *selection;
428 GtkCellRenderer *cell;
429
430 dialog = g_new0(GevoAddBuddyDialog, 1);
431
432 dialog->account =
433 (account != NULL
434 ? account
435 : gaim_connection_get_account(gaim_connections_get_all()->data));
436
437 if (username != NULL)
438 dialog->username = g_strdup(username);
439
440 dialog->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
441 gtk_window_set_role(GTK_WINDOW(dialog->win), "add_buddy");
442 gtk_window_set_title(GTK_WINDOW(dialog->win), _("Add Buddy"));
443 gtk_container_set_border_width(GTK_CONTAINER(dialog->win), 12);
444 gtk_widget_set_size_request(dialog->win, -1, 400);
445
446 g_signal_connect(G_OBJECT(dialog->win), "delete_event",
447 G_CALLBACK(delete_win_cb), dialog);
448
449 /* Setup the vbox */
450 vbox = gtk_vbox_new(FALSE, 12);
451 gtk_container_add(GTK_CONTAINER(dialog->win), vbox);
452 gtk_widget_show(vbox);
453
454 /* Add the label. */
455 label = gtk_label_new(_("Select a person from your address book below, "
456 "or add a new person."));
457 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
458 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
459 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
460 gtk_widget_show(label);
461
462 /* Add the search hbox */
463 hbox = gtk_hbox_new(FALSE, 6);
464 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
465 gtk_widget_show(hbox);
466
467 /* "Search" */
468 label = gtk_label_new(_("Search"));
469 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
470 gtk_widget_show(label);
471
472 /* Addressbooks */
473 dialog->addrbooks = gevo_addrbooks_model_new();
474
475 dialog->addrbooks_combo = gtk_combo_box_new_with_model(
476 dialog->addrbooks);
477 cell = gtk_cell_renderer_text_new();
478 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dialog->addrbooks_combo),
479 cell, TRUE);
480 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dialog->addrbooks_combo),
481 cell,
482 "text", ADDRBOOK_COLUMN_NAME,
483 NULL);
484 gtk_box_pack_start(GTK_BOX(hbox), dialog->addrbooks_combo, FALSE,
485 FALSE, 0);
486 gtk_widget_show(dialog->addrbooks_combo);
487
488 /* Search field */
489 dialog->search_field = gtk_entry_new();
490 gtk_box_pack_start(GTK_BOX(hbox), dialog->search_field, TRUE, TRUE, 0);
491 gtk_widget_show(dialog->search_field);
492
493 g_signal_connect(G_OBJECT(dialog->search_field), "changed",
494 G_CALLBACK(search_changed_cb), dialog);
495
496 /* Clear button */
497 button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
498 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
499 gtk_widget_show(button);
500
501 g_signal_connect(G_OBJECT(button), "clicked",
502 G_CALLBACK(clear_cb), dialog);
503
504 /* Scrolled Window */
505 sw = gtk_scrolled_window_new(0, 0);
506 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
507 GTK_POLICY_AUTOMATIC,
508 GTK_POLICY_ALWAYS);
509 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
510 GTK_SHADOW_IN);
511 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
512 gtk_widget_show(sw);
513
514 /* Create the list model for the treeview. */
515 dialog->model = gtk_list_store_new(NUM_COLUMNS,
516 G_TYPE_STRING, GDK_TYPE_PIXBUF,
517 G_TYPE_STRING, G_TYPE_POINTER);
518
519 /* Now for the treeview */
520 dialog->treeview =
521 gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model));
522 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE);
523 gtk_container_add(GTK_CONTAINER(sw), dialog->treeview);
524 gtk_widget_show(dialog->treeview);
525
526 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
527
528 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
529
530 g_signal_connect(G_OBJECT(selection), "changed",
531 G_CALLBACK(selected_cb), dialog);
532
533 add_columns(dialog);
534
535 /*
536 * Catch addressbook selection and populate treeview with the first
537 * addressbook
538 */
539 gevo_addrbooks_model_populate(dialog->addrbooks);
540 g_signal_connect(G_OBJECT(dialog->addrbooks_combo), "changed",
541 G_CALLBACK(addrbook_change_cb), dialog);
542 gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->addrbooks_combo), 0);
543
544 /* Group box */
545 hbox = gtk_hbox_new(FALSE, 6);
546 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
547 gtk_widget_show(hbox);
548
549 label = gtk_label_new(_("Group:"));
550 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
551 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
552 gtk_widget_show(label);
553
554 dialog->group_combo = gtk_combo_new();
555 gtk_combo_set_popdown_strings(GTK_COMBO(dialog->group_combo),
556 gevo_get_groups());
557 gtk_box_pack_start(GTK_BOX(hbox), dialog->group_combo, TRUE, TRUE, 0);
558 gtk_widget_show(dialog->group_combo);
559
560 /* Cool. Now we only have a little left... */
561
562 /* Separator. */
563 sep = gtk_hseparator_new();
564 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
565 gtk_widget_show(sep);
566
567 /* Button box */
568 bbox = gtk_hbutton_box_new();
569 gtk_box_set_spacing(GTK_BOX(bbox), 6);
570 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
571 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
572 gtk_widget_show(bbox);
573
574 /* "New Person" button */
575 button = gaim_pixbuf_button_from_stock(_("New Person"), GTK_STOCK_NEW,
576 GAIM_BUTTON_HORIZONTAL);
577 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
578 gtk_widget_show(button);
579
580 g_signal_connect(G_OBJECT(button), "clicked",
581 G_CALLBACK(new_person_cb), dialog);
582
583 /* "Cancel" button */
584 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
585 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
586 gtk_widget_show(button);
587
588 g_signal_connect(G_OBJECT(button), "clicked",
589 G_CALLBACK(cancel_cb), dialog);
590
591 /* "Select Buddy" button */
592 button = gaim_pixbuf_button_from_stock(_("Select Buddy"), GTK_STOCK_APPLY,
593 GAIM_BUTTON_HORIZONTAL);
594 dialog->select_button = button;
595 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
596 gtk_widget_set_sensitive(button, FALSE);
597 gtk_widget_show(button);
598
599 g_signal_connect(G_OBJECT(button), "clicked",
600 G_CALLBACK(select_buddy_cb), dialog);
601
602 /* Show it. */
603 gtk_widget_show(dialog->win);
604 }
605
606 void
607 gevo_add_buddy_dialog_add_person(GevoAddBuddyDialog *dialog,
608 EContact *contact, const char *name,
609 GaimAccount *account, const char *screenname)
610 {
611 GdkPixbuf *pixbuf;
612 GtkTreeIter iter;
613
614 pixbuf = gaim_gtk_create_prpl_icon(account, 0.5);
615
616 gtk_list_store_append(dialog->model, &iter);
617
618 gtk_list_store_set(dialog->model, &iter,
619 COLUMN_NAME, name,
620 COLUMN_PRPL_ICON, pixbuf,
621 COLUMN_DATA, contact,
622 COLUMN_USERNAME, screenname,
623 -1);
624
625 if (contact != NULL)
626 dialog->contacts = g_list_append(dialog->contacts, contact);
627
628 if (pixbuf != NULL)
629 g_object_unref(G_OBJECT(pixbuf));
630 }