Migrate certificates, icons, logs to XDG dirs
[pidgin-git.git] / pidgin / plugins / gevolution / assoc-buddy.c
blobf723c85243c5aa0cc80ee01129b008a317c981b7
1 /*
2 * Evolution integration plugin for Purple
4 * Copyright (C) 2003 Christian Hammond.
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02111-1301, USA.
21 #include "internal.h"
22 #include "gtkblist.h"
23 #include "pidgin.h"
25 #include "gtk3compat.h"
26 #include "gtkutils.h"
28 #include "debug.h"
30 #include "gevolution.h"
32 #include <stdlib.h>
33 #include <gtk/gtk.h>
35 enum
37 COLUMN_NAME,
38 COLUMN_DATA,
39 NUM_COLUMNS
42 static gint
43 delete_win_cb(GtkWidget *w, GdkEvent *event, GevoAssociateBuddyDialog *dialog)
45 gtk_widget_destroy(dialog->win);
47 if (dialog->contacts != NULL)
49 g_list_foreach(dialog->contacts, (GFunc)g_object_unref, NULL);
50 g_list_free(dialog->contacts);
53 g_object_unref(dialog->book);
54 gevo_addrbooks_model_unref(dialog->addrbooks);
56 g_free(dialog);
58 return 0;
61 static void
62 search_changed_cb(GtkEntry *entry, GevoAssociateBuddyDialog *dialog)
64 const char *text = gtk_entry_get_text(entry);
65 GList *l;
67 gtk_list_store_clear(dialog->model);
69 for (l = dialog->contacts; l != NULL; l = l->next)
71 EContact *contact = E_CONTACT(l->data);
72 const char *name;
73 GtkTreeIter iter;
75 name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
77 if (text != NULL && *text != '\0' && name != NULL &&
78 g_ascii_strncasecmp(name, text, strlen(text)))
80 continue;
83 gtk_list_store_append(dialog->model, &iter);
85 gtk_list_store_set(dialog->model, &iter,
86 COLUMN_NAME, name,
87 COLUMN_DATA, contact,
88 -1);
92 static void
93 clear_cb(GtkWidget *w, GevoAssociateBuddyDialog *dialog)
95 static gboolean lock = FALSE;
97 if (lock)
98 return;
100 lock = TRUE;
101 gtk_entry_set_text(GTK_ENTRY(dialog->search_field), "");
102 lock = FALSE;
105 static void
106 selected_cb(GtkTreeSelection *sel, GevoAssociateBuddyDialog *dialog)
108 GtkTreeSelection *selection;
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));
115 static void
116 add_columns(GevoAssociateBuddyDialog *dialog)
118 GtkCellRenderer *renderer;
119 GtkTreeViewColumn *column;
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);
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);
133 static void
134 populate_treeview(GevoAssociateBuddyDialog *dialog, const gchar *uid)
136 EBook *book;
137 EBookQuery *query;
138 gboolean status;
139 GList *cards, *c;
140 GError *err = NULL;
142 if (dialog->book != NULL)
144 g_object_unref(dialog->book);
145 dialog->book = NULL;
148 if (dialog->contacts != NULL)
150 g_list_foreach(dialog->contacts, (GFunc) g_object_unref, NULL);
151 g_list_free(dialog->contacts);
152 dialog->contacts = NULL;
155 gtk_list_store_clear(dialog->model);
157 if (!gevo_load_addressbook(uid, &book, &err)) {
158 purple_debug_error("evolution",
159 "Error retrieving addressbook: %s\n", err->message);
160 g_error_free(err);
162 return;
165 query = e_book_query_field_exists(E_CONTACT_FULL_NAME);
167 if (query == NULL)
169 purple_debug_error("evolution", "Error in creating query\n");
171 g_object_unref(book);
173 return;
176 status = e_book_get_contacts(book, query, &cards, NULL);
178 e_book_query_unref(query);
180 if (!status)
182 purple_debug_error("evolution", "Error %d in getting card list\n",
183 status);
185 g_object_unref(book);
187 return;
190 for (c = cards; c != NULL; c = c->next)
192 EContact *contact = E_CONTACT(c->data);
193 const char *name;
194 GtkTreeIter iter;
195 EContactField protocol_field = 0;
197 name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
199 gtk_list_store_append(dialog->model, &iter);
201 gtk_list_store_set(dialog->model, &iter,
202 COLUMN_NAME, name,
203 COLUMN_DATA, contact,
204 -1);
206 /* See if this user has the buddy in its list. */
207 protocol_field = gevo_protocol_get_field(
208 purple_buddy_get_account(dialog->buddy),
209 dialog->buddy);
211 if (protocol_field > 0)
213 GList *ims, *l;
215 ims = e_contact_get(contact, protocol_field);
217 for (l = ims; l != NULL; l = l->next)
219 if (!strcmp(l->data,
220 purple_buddy_get_name(dialog->buddy)))
222 GtkTreeSelection *selection;
224 /* This is it. Select it. */
225 selection = gtk_tree_view_get_selection(
226 GTK_TREE_VIEW(dialog->treeview));
228 gtk_tree_selection_select_iter(selection, &iter);
229 break;
235 dialog->contacts = cards;
236 dialog->book = book;
239 static void
240 addrbook_change_cb(GtkComboBox *combo, GevoAssociateBuddyDialog *dialog)
242 GtkTreeIter iter;
243 const char *esource_uid;
245 if (!gtk_combo_box_get_active_iter(combo, &iter))
246 return;
248 gtk_tree_model_get(GTK_TREE_MODEL(dialog->addrbooks), &iter,
249 ADDRBOOK_COLUMN_UID, &esource_uid, -1);
251 populate_treeview(dialog, esource_uid);
254 static void
255 new_person_cb(GtkWidget *w, GevoAssociateBuddyDialog *dialog)
257 gevo_new_person_dialog_show(dialog->book, NULL,
258 purple_buddy_get_account(dialog->buddy),
259 purple_buddy_get_name(dialog->buddy),
260 NULL, dialog->buddy, TRUE);
262 delete_win_cb(NULL, NULL, dialog);
265 static void
266 cancel_cb(GtkWidget *w, GevoAssociateBuddyDialog *dialog)
268 delete_win_cb(NULL, NULL, dialog);
271 static void
272 assoc_buddy_cb(GtkWidget *w, GevoAssociateBuddyDialog *dialog)
274 GtkTreeSelection *selection;
275 GtkTreeIter iter;
276 GList *list;
277 const char *fullname;
278 EContactField protocol_field;
279 EContact *contact;
281 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
283 if (!gtk_tree_selection_get_selected(selection, NULL, &iter))
284 return;
286 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter,
287 COLUMN_NAME, &fullname,
288 COLUMN_DATA, &contact,
289 -1);
291 protocol_field = gevo_protocol_get_field(
292 purple_buddy_get_account(dialog->buddy), dialog->buddy);
294 if (protocol_field == 0)
295 return; /* XXX */
297 list = e_contact_get(contact, protocol_field);
298 list = g_list_append(list,
299 g_strdup(purple_buddy_get_name(dialog->buddy)));
301 e_contact_set(contact, protocol_field, list);
303 if (!e_book_commit_contact(dialog->book, contact, NULL))
304 purple_debug_error("evolution", "Error adding contact to book\n");
306 /* Free the list. */
307 g_list_foreach(list, (GFunc)g_free, NULL);
308 g_list_free(list);
310 delete_win_cb(NULL, NULL, dialog);
313 GevoAssociateBuddyDialog *
314 gevo_associate_buddy_dialog_new(PurpleBuddy *buddy)
316 GevoAssociateBuddyDialog *dialog;
317 GtkWidget *button;
318 GtkWidget *label;
319 GtkWidget *vbox;
320 GtkWidget *hbox;
321 GtkWidget *bbox;
322 GtkWidget *sep;
323 GtkTreeSelection *selection;
324 GtkCellRenderer *cell;
326 g_return_val_if_fail(buddy != NULL, NULL);
328 dialog = g_new0(GevoAssociateBuddyDialog, 1);
330 dialog->buddy = buddy;
332 dialog->win = pidgin_create_window(NULL, PIDGIN_HIG_BORDER, "assoc_buddy", TRUE);
334 g_signal_connect(G_OBJECT(dialog->win), "delete_event",
335 G_CALLBACK(delete_win_cb), dialog);
337 /* Setup the vbox */
338 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
339 gtk_container_add(GTK_CONTAINER(dialog->win), vbox);
340 gtk_widget_show(vbox);
342 /* Add the label. */
343 label = gtk_label_new(_("Select a person from your address book to "
344 "add this buddy to, or create a new person."));
345 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
346 gtk_label_set_xalign(GTK_LABEL(label), 0);
347 gtk_label_set_yalign(GTK_LABEL(label), 0);
348 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
349 gtk_widget_show(label);
351 /* Add the search hbox */
352 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
353 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
354 gtk_widget_show(hbox);
356 /* "Search" */
357 label = gtk_label_new(_("Search"));
358 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
359 gtk_widget_show(label);
361 /* Addressbooks */
362 dialog->addrbooks = gevo_addrbooks_model_new();
364 dialog->addrbooks_combo = gtk_combo_box_new_with_model(dialog->addrbooks);
365 cell = gtk_cell_renderer_text_new();
366 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dialog->addrbooks_combo),
367 cell, TRUE);
368 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dialog->addrbooks_combo),
369 cell,
370 "text", ADDRBOOK_COLUMN_NAME,
371 NULL);
372 gtk_box_pack_start(GTK_BOX(hbox), dialog->addrbooks_combo, FALSE, FALSE, 0);
373 gtk_widget_show(dialog->addrbooks_combo);
376 /* Search field */
377 dialog->search_field = gtk_entry_new();
378 gtk_box_pack_start(GTK_BOX(hbox), dialog->search_field, TRUE, TRUE, 0);
379 gtk_widget_show(dialog->search_field);
381 g_signal_connect(G_OBJECT(dialog->search_field), "changed",
382 G_CALLBACK(search_changed_cb), dialog);
384 /* Clear button */
385 button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
386 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
387 gtk_widget_show(button);
389 g_signal_connect(G_OBJECT(button), "clicked",
390 G_CALLBACK(clear_cb), dialog);
392 /* Create the list model for the treeview. */
393 dialog->model = gtk_list_store_new(NUM_COLUMNS,
394 G_TYPE_STRING, G_TYPE_POINTER);
396 /* Now for the treeview */
397 dialog->treeview = gtk_tree_view_new_with_model(
398 GTK_TREE_MODEL(dialog->model));
399 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE);
400 gtk_box_pack_start(GTK_BOX(vbox),
401 pidgin_make_scrollable(dialog->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1),
402 TRUE, TRUE, 0);
403 gtk_widget_show(dialog->treeview);
405 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
407 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
409 g_signal_connect(G_OBJECT(selection), "changed",
410 G_CALLBACK(selected_cb), dialog);
412 add_columns(dialog);
415 * Catch addressbook selection and populate treeview with the first
416 * addressbook
418 gevo_addrbooks_model_populate( dialog->addrbooks );
419 g_signal_connect(G_OBJECT(dialog->addrbooks_combo), "changed",
420 G_CALLBACK(addrbook_change_cb), dialog);
421 gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->addrbooks_combo), 0);
423 /* Separator. */
424 sep = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
425 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
426 gtk_widget_show(sep);
428 /* Button box */
429 bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
430 gtk_box_set_spacing(GTK_BOX(bbox), 6);
431 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
432 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
433 gtk_widget_show(bbox);
435 /* "New Person" button */
436 button = pidgin_pixbuf_button_from_stock(_("New Person"), GTK_STOCK_NEW,
437 PIDGIN_BUTTON_HORIZONTAL);
438 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
439 gtk_widget_show(button);
441 g_signal_connect(G_OBJECT(button), "clicked",
442 G_CALLBACK(new_person_cb), dialog);
444 /* "Cancel" button */
445 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
446 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
447 gtk_widget_show(button);
449 g_signal_connect(G_OBJECT(button), "clicked",
450 G_CALLBACK(cancel_cb), dialog);
452 /* "Associate Buddy" button */
453 button = pidgin_pixbuf_button_from_stock(_("_Associate Buddy"),
454 GTK_STOCK_APPLY,
455 PIDGIN_BUTTON_HORIZONTAL);
456 dialog->assoc_button = button;
457 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
458 gtk_widget_set_sensitive(button, FALSE);
459 gtk_widget_show(button);
461 g_signal_connect(G_OBJECT(button), "clicked",
462 G_CALLBACK(assoc_buddy_cb), dialog);
464 /* Show it. */
465 gtk_widget_show(dialog->win);
467 return dialog;