gtk/plugins/gevolution/assoc-buddy.c

branch
gaim
changeset 20470
77693555855f
parent 11807
24a6c489e7f2
parent 14747
61aa25e4f18a
child 20471
1966704b3e42
equal deleted inserted replaced
13071:b98e72d4089a 20470:77693555855f
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 "gtkexpander.h"
24 #include "gtkgaim.h"
25 #include "gtkutils.h"
26 #include "gtkimhtml.h"
27
28 #include "debug.h"
29
30 #include "gevolution.h"
31
32 #include <stdlib.h>
33 #include <gtk/gtk.h>
34
35 enum
36 {
37 COLUMN_NAME,
38 COLUMN_DATA,
39 NUM_COLUMNS
40 };
41
42 static gint
43 delete_win_cb(GtkWidget *w, GdkEvent *event, GevoAssociateBuddyDialog *dialog)
44 {
45 gtk_widget_destroy(dialog->win);
46
47 if (dialog->contacts != NULL)
48 {
49 g_list_foreach(dialog->contacts, (GFunc)g_object_unref, NULL);
50 g_list_free(dialog->contacts);
51 }
52
53 g_object_unref(dialog->book);
54 gevo_addrbooks_model_unref(dialog->addrbooks);
55
56 g_free(dialog);
57
58 return 0;
59 }
60
61 static void
62 search_changed_cb(GtkEntry *entry, GevoAssociateBuddyDialog *dialog)
63 {
64 const char *text = gtk_entry_get_text(entry);
65 GList *l;
66
67 gtk_list_store_clear(dialog->model);
68
69 for (l = dialog->contacts; l != NULL; l = l->next)
70 {
71 EContact *contact = E_CONTACT(l->data);
72 const char *name;
73 GtkTreeIter iter;
74
75 name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
76
77 if (text != NULL && *text != '\0' && name != NULL &&
78 g_ascii_strncasecmp(name, text, strlen(text)))
79 {
80 continue;
81 }
82
83 gtk_list_store_append(dialog->model, &iter);
84
85 gtk_list_store_set(dialog->model, &iter,
86 COLUMN_NAME, name,
87 COLUMN_DATA, contact,
88 -1);
89 }
90 }
91
92 static void
93 clear_cb(GtkWidget *w, GevoAssociateBuddyDialog *dialog)
94 {
95 static gboolean lock = FALSE;
96
97 if (lock)
98 return;
99
100 lock = TRUE;
101 gtk_entry_set_text(GTK_ENTRY(dialog->search_field), "");
102 lock = FALSE;
103 }
104
105 static void
106 selected_cb(GtkTreeSelection *sel, GevoAssociateBuddyDialog *dialog)
107 {
108 GtkTreeSelection *selection;
109
110 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
111 gtk_widget_set_sensitive(dialog->assoc_button,
112 gtk_tree_selection_get_selected(selection, NULL, NULL));
113 }
114
115 static void
116 add_columns(GevoAssociateBuddyDialog *dialog)
117 {
118 GtkCellRenderer *renderer;
119 GtkTreeViewColumn *column;
120
121 /* Name column */
122 column = gtk_tree_view_column_new();
123 gtk_tree_view_column_set_title(column, _("Name"));
124 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1);
125 gtk_tree_view_column_set_sort_column_id(column, COLUMN_NAME);
126
127 renderer = gtk_cell_renderer_text_new();
128 gtk_tree_view_column_pack_start(column, renderer, TRUE);
129 gtk_tree_view_column_add_attribute(column, renderer,
130 "text", COLUMN_NAME);
131 }
132
133 static void
134 populate_treeview(GevoAssociateBuddyDialog *dialog, const gchar *uri)
135 {
136 EBook *book;
137 EBookQuery *query;
138 const char *prpl_id;
139 gboolean status;
140 GList *cards, *c;
141
142 if (dialog->book != NULL)
143 {
144 g_object_unref(dialog->book);
145 dialog->book = NULL;
146 }
147
148 if (dialog->contacts != NULL)
149 {
150 g_list_foreach(dialog->contacts, (GFunc) g_object_unref, NULL);
151 g_list_free(dialog->contacts);
152 dialog->contacts = NULL;
153 }
154
155 gtk_list_store_clear(dialog->model);
156
157 if (!gevo_load_addressbook(uri, &book, NULL))
158 {
159 gaim_debug_error("evolution",
160 "Error retrieving addressbook\n");
161
162 return;
163 }
164
165 query = e_book_query_field_exists(E_CONTACT_FULL_NAME);
166
167 if (query == NULL)
168 {
169 gaim_debug_error("evolution", "Error in creating query\n");
170
171 g_object_unref(book);
172
173 return;
174 }
175
176 status = e_book_get_contacts(book, query, &cards, NULL);
177
178 e_book_query_unref(query);
179
180 if (!status)
181 {
182 gaim_debug_error("evolution", "Error %d in getting card list\n",
183 status);
184
185 g_object_unref(book);
186
187 return;
188 }
189
190 prpl_id = gaim_account_get_protocol_id(dialog->buddy->account);
191
192 for (c = cards; c != NULL; c = c->next)
193 {
194 EContact *contact = E_CONTACT(c->data);
195 const char *name;
196 GtkTreeIter iter;
197 EContactField protocol_field = 0;
198
199 name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
200
201 gtk_list_store_append(dialog->model, &iter);
202
203 gtk_list_store_set(dialog->model, &iter,
204 COLUMN_NAME, name,
205 COLUMN_DATA, contact,
206 -1);
207
208 /* See if this user has the buddy in its list. */
209 protocol_field = gevo_prpl_get_field(dialog->buddy->account,
210 dialog->buddy);
211
212 if (protocol_field > 0)
213 {
214 GList *ims, *l;
215
216 ims = e_contact_get(contact, protocol_field);
217
218 for (l = ims; l != NULL; l = l->next)
219 {
220 if (!strcmp(l->data, dialog->buddy->name))
221 {
222 GtkTreeSelection *selection;
223
224 /* This is it. Select it. */
225 selection = gtk_tree_view_get_selection(
226 GTK_TREE_VIEW(dialog->treeview));
227
228 gtk_tree_selection_select_iter(selection, &iter);
229 break;
230 }
231 }
232 }
233 }
234
235 dialog->contacts = cards;
236 dialog->book = book;
237 }
238
239 static void
240 addrbook_change_cb(GtkComboBox *combo, GevoAssociateBuddyDialog *dialog)
241 {
242 GtkTreeIter iter;
243 const char *esource_uri;
244
245 if (!gtk_combo_box_get_active_iter(combo, &iter))
246 return;
247
248 gtk_tree_model_get(GTK_TREE_MODEL(dialog->addrbooks), &iter,
249 ADDRBOOK_COLUMN_URI, &esource_uri,
250 -1);
251
252 populate_treeview(dialog, esource_uri);
253 }
254
255 static void
256 new_person_cb(GtkWidget *w, GevoAssociateBuddyDialog *dialog)
257 {
258 gevo_new_person_dialog_show(dialog->book, NULL, dialog->buddy->account,
259 dialog->buddy->name, NULL, dialog->buddy,
260 TRUE);
261
262 delete_win_cb(NULL, NULL, dialog);
263 }
264
265 static void
266 cancel_cb(GtkWidget *w, GevoAssociateBuddyDialog *dialog)
267 {
268 delete_win_cb(NULL, NULL, dialog);
269 }
270
271 static void
272 assoc_buddy_cb(GtkWidget *w, GevoAssociateBuddyDialog *dialog)
273 {
274 GtkTreeSelection *selection;
275 GtkTreeIter iter;
276 GList *list;
277 const char *fullname;
278 EContactField protocol_field;
279 EContact *contact;
280
281 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
282
283 if (!gtk_tree_selection_get_selected(selection, NULL, &iter))
284 return;
285
286 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter,
287 COLUMN_NAME, &fullname,
288 COLUMN_DATA, &contact,
289 -1);
290
291 protocol_field = gevo_prpl_get_field(dialog->buddy->account, dialog->buddy);
292
293 if (protocol_field == 0)
294 return; /* XXX */
295
296 list = e_contact_get(contact, protocol_field);
297 list = g_list_append(list, g_strdup(dialog->buddy->name));
298
299 e_contact_set(contact, protocol_field, list);
300
301 if (!e_book_commit_contact(dialog->book, contact, NULL))
302 gaim_debug_error("evolution", "Error adding contact to book\n");
303
304 /* Free the list. */
305 g_list_foreach(list, (GFunc)g_free, NULL);
306 g_list_free(list);
307
308 delete_win_cb(NULL, NULL, dialog);
309 }
310
311 GevoAssociateBuddyDialog *
312 gevo_associate_buddy_dialog_new(GaimBuddy *buddy)
313 {
314 GevoAssociateBuddyDialog *dialog;
315 GtkWidget *button;
316 GtkWidget *sw;
317 GtkWidget *label;
318 GtkWidget *vbox;
319 GtkWidget *hbox;
320 GtkWidget *bbox;
321 GtkWidget *sep;
322 GtkWidget *expander;
323 GtkTreeSelection *selection;
324 GtkCellRenderer *cell;
325
326 g_return_val_if_fail(buddy != NULL, NULL);
327
328 dialog = g_new0(GevoAssociateBuddyDialog, 1);
329
330 dialog->buddy = buddy;
331
332 dialog->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
333 gtk_window_set_role(GTK_WINDOW(dialog->win), "assoc_buddy");
334 gtk_container_set_border_width(GTK_CONTAINER(dialog->win), 12);
335
336 g_signal_connect(G_OBJECT(dialog->win), "delete_event",
337 G_CALLBACK(delete_win_cb), dialog);
338
339 /* Setup the vbox */
340 vbox = gtk_vbox_new(FALSE, 12);
341 gtk_container_add(GTK_CONTAINER(dialog->win), vbox);
342 gtk_widget_show(vbox);
343
344 /* Add the label. */
345 label = gtk_label_new(_("Select a person from your address book to "
346 "add this buddy to, or create a new person."));
347 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
348 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
349 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
350 gtk_widget_show(label);
351
352 /* Add the search hbox */
353 hbox = gtk_hbox_new(FALSE, 6);
354 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
355 gtk_widget_show(hbox);
356
357 /* "Search" */
358 label = gtk_label_new(_("Search"));
359 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
360 gtk_widget_show(label);
361
362 /* Addressbooks */
363 dialog->addrbooks = gevo_addrbooks_model_new();
364
365 dialog->addrbooks_combo = gtk_combo_box_new_with_model(dialog->addrbooks);
366 cell = gtk_cell_renderer_text_new();
367 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dialog->addrbooks_combo),
368 cell, TRUE);
369 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dialog->addrbooks_combo),
370 cell,
371 "text", ADDRBOOK_COLUMN_NAME,
372 NULL);
373 gtk_box_pack_start(GTK_BOX(hbox), dialog->addrbooks_combo, FALSE, FALSE, 0);
374 gtk_widget_show(dialog->addrbooks_combo);
375
376
377 /* Search field */
378 dialog->search_field = gtk_entry_new();
379 gtk_box_pack_start(GTK_BOX(hbox), dialog->search_field, TRUE, TRUE, 0);
380 gtk_widget_show(dialog->search_field);
381
382 g_signal_connect(G_OBJECT(dialog->search_field), "changed",
383 G_CALLBACK(search_changed_cb), dialog);
384
385 /* Clear button */
386 button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
387 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
388 gtk_widget_show(button);
389
390 g_signal_connect(G_OBJECT(button), "clicked",
391 G_CALLBACK(clear_cb), dialog);
392
393 /* Scrolled Window */
394 sw = gtk_scrolled_window_new(0, 0);
395 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
396 GTK_POLICY_AUTOMATIC,
397 GTK_POLICY_ALWAYS);
398 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
399 GTK_SHADOW_IN);
400 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
401 gtk_widget_show(sw);
402
403 /* Create the list model for the treeview. */
404 dialog->model = gtk_list_store_new(NUM_COLUMNS,
405 G_TYPE_STRING, G_TYPE_POINTER);
406
407 /* Now for the treeview */
408 dialog->treeview = gtk_tree_view_new_with_model(
409 GTK_TREE_MODEL(dialog->model));
410 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE);
411 gtk_container_add(GTK_CONTAINER(sw), dialog->treeview);
412 gtk_widget_show(dialog->treeview);
413
414 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
415
416 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
417
418 g_signal_connect(G_OBJECT(selection), "changed",
419 G_CALLBACK(selected_cb), dialog);
420
421 add_columns(dialog);
422
423 /*
424 * Catch addressbook selection and populate treeview with the first
425 * addressbook
426 */
427 gevo_addrbooks_model_populate( dialog->addrbooks );
428 g_signal_connect(G_OBJECT(dialog->addrbooks_combo), "changed",
429 G_CALLBACK(addrbook_change_cb), dialog);
430 gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->addrbooks_combo), 0);
431
432 /* Add the expander */
433 expander = gtk_expander_new_with_mnemonic(_("User _details"));
434 gtk_box_pack_start(GTK_BOX(vbox), expander, FALSE, FALSE, 0);
435 gtk_widget_show(expander);
436
437 /*
438 * User details
439 */
440
441 /* Scrolled Window */
442 sw = gtk_scrolled_window_new(0, 0);
443 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
444 GTK_POLICY_NEVER,
445 GTK_POLICY_ALWAYS);
446 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
447 GTK_SHADOW_IN);
448 gtk_container_add(GTK_CONTAINER(expander), sw);
449 gtk_widget_show(sw);
450
451 /* Textview */
452 dialog->imhtml = gtk_imhtml_new(NULL, NULL);
453 gtk_container_add(GTK_CONTAINER(sw), dialog->imhtml);
454 gtk_widget_show(dialog->imhtml);
455
456 /* Separator. */
457 sep = gtk_hseparator_new();
458 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
459 gtk_widget_show(sep);
460
461 /* Button box */
462 bbox = gtk_hbutton_box_new();
463 gtk_box_set_spacing(GTK_BOX(bbox), 6);
464 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
465 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
466 gtk_widget_show(bbox);
467
468 /* "New Person" button */
469 button = gaim_pixbuf_button_from_stock(_("New Person"), GTK_STOCK_NEW,
470 GAIM_BUTTON_HORIZONTAL);
471 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
472 gtk_widget_show(button);
473
474 g_signal_connect(G_OBJECT(button), "clicked",
475 G_CALLBACK(new_person_cb), dialog);
476
477 /* "Cancel" button */
478 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
479 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
480 gtk_widget_show(button);
481
482 g_signal_connect(G_OBJECT(button), "clicked",
483 G_CALLBACK(cancel_cb), dialog);
484
485 /* "Associate Buddy" button */
486 button = gaim_pixbuf_button_from_stock(_("_Associate Buddy"),
487 GTK_STOCK_APPLY,
488 GAIM_BUTTON_HORIZONTAL);
489 dialog->assoc_button = button;
490 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
491 gtk_widget_set_sensitive(button, FALSE);
492 gtk_widget_show(button);
493
494 g_signal_connect(G_OBJECT(button), "clicked",
495 G_CALLBACK(assoc_buddy_cb), dialog);
496
497 /* Show it. */
498 gtk_widget_show(dialog->win);
499
500 return dialog;
501 }

mercurial