diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/gevolution/add_buddy_dialog.c	Tue Jan 13 01:45:32 2004 +0000
@@ -0,0 +1,650 @@
+/*
+ * Evolution integration plugin for Gaim
+ *
+ * Copyright (C) 2003 Christian Hammond.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#include "gtkinternal.h"
+#include "gtkblist.h"
+#include "gtkutils.h"
+
+#include "debug.h"
+
+#include "gevolution.h"
+
+#include <stdlib.h>
+#include <bonobo/bonobo-main.h>
+#include <libebook/e-book.h>
+#include <libebook/e-book-async.h>
+#include <libedataserver/e-source-list.h>
+
+enum
+{
+	COLUMN_NAME,
+	COLUMN_PRPL_ICON,
+	COLUMN_USERNAME,
+	COLUMN_DATA,
+	NUM_COLUMNS
+};
+
+static gint
+delete_win_cb(GtkWidget *w, GdkEvent *event, GevoAddBuddyDialog *dialog)
+{
+	gtk_widget_destroy(dialog->win);
+
+	g_list_foreach(dialog->contacts, (GFunc)g_object_unref, NULL);
+
+	if (dialog->contacts != NULL)
+		g_list_free(dialog->contacts);
+
+	if (dialog->book != NULL)
+		g_object_unref(dialog->book);
+
+	if (dialog->username != NULL)
+		g_free(dialog->username);
+
+	g_free(dialog);
+
+	return 0;
+}
+
+static void
+new_person_cb(GtkWidget *w, GevoAddBuddyDialog *dialog)
+{
+	const char *group_name;
+
+	group_name =
+		gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(dialog->group_combo)->entry));
+
+	gevo_new_person_dialog_show(NULL, dialog->account, NULL,
+								(*group_name ? group_name : NULL),
+								NULL, FALSE);
+
+	delete_win_cb(NULL, NULL, dialog);
+}
+
+static void
+cancel_cb(GtkWidget *w, GevoAddBuddyDialog *dialog)
+{
+	delete_win_cb(NULL, NULL, dialog);
+}
+
+static void
+select_buddy_cb(GtkWidget *w, GevoAddBuddyDialog *dialog)
+{
+	GtkTreeSelection *selection;
+	GtkTreeIter iter;
+	const char *group_name;
+	const char *fullname;
+	const char *username;
+	EContact *contact;
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
+
+	gtk_tree_selection_get_selected(selection, NULL, &iter);
+
+	gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter,
+					   COLUMN_NAME, &fullname,
+					   COLUMN_USERNAME, &username,
+					   COLUMN_DATA, &contact,
+					   -1);
+
+	group_name =
+		gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(dialog->group_combo)->entry));
+
+	if (username == NULL || *username == '\0')
+	{
+		gevo_new_person_dialog_show(NULL, dialog->account, NULL,
+									(*group_name ? group_name : NULL),
+									NULL, FALSE);
+	}
+	else
+	{
+		gevo_add_buddy(dialog->account, group_name, username, fullname);
+	}
+
+	delete_win_cb(NULL, NULL, dialog);
+}
+
+static void
+populate_address_books(GevoAddBuddyDialog *dialog)
+{
+	GtkWidget *item;
+	GtkWidget *menu;
+#if notyet
+	ESourceList *addressbooks;
+	GList *groups, *g;
+#endif
+
+	menu =
+		gtk_option_menu_get_menu(GTK_OPTION_MENU(dialog->addressbooks_menu));
+
+	item = gtk_menu_item_new_with_label(_("Local Addressbook"));
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+	gtk_widget_show(item);
+
+#if notyet
+	if (!e_book_get_addressbooks(&addressbooks, NULL))
+	{
+		gaim_debug_error("evolution",
+						 "Unable to fetch list of address books.\n");
+
+		item = gtk_menu_item_new_with_label(_("None"));
+		gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+		gtk_widget_show(item);
+
+		return;
+	}
+
+	groups = e_source_list_peek_groups(list);
+
+	if (groups == NULL)
+	{
+		item = gtk_menu_item_new_with_label(_("None"));
+		gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+		gtk_widget_show(item);
+
+		return;
+	}
+
+	for (g = groups; g != NULL; g = g->next)
+	{
+		GList *sources, *s;
+
+		sources = e_source_group_peek_sources(g->data);
+
+		for (p = sources; p != NULL; p = p->next)
+		{
+			ESource *source = E_SOURCE(p->data);
+
+			item = gtk_menu_item_new_with_label(e_source_peek_name(source));
+			gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+			gtk_widget_show(item);
+		}
+	}
+#endif
+}
+
+static void
+add_columns(GevoAddBuddyDialog *dialog)
+{
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *column;
+
+	/* Name column */
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_column_set_title(column, _("Name"));
+	gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1);
+	gtk_tree_view_column_set_sort_column_id(column, COLUMN_NAME);
+
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_column_pack_start(column, renderer, TRUE);
+	gtk_tree_view_column_add_attribute(column, renderer,
+									   "text", COLUMN_NAME);
+
+	/* Account column */
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_column_set_title(column, _("Instant Messaging"));
+	gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1);
+	gtk_tree_view_column_set_sort_column_id(column, COLUMN_USERNAME);
+
+	/* Protocol icon */
+	renderer = gtk_cell_renderer_pixbuf_new();
+	gtk_tree_view_column_pack_start(column, renderer, FALSE);
+	gtk_tree_view_column_add_attribute(column, renderer,
+									   "pixbuf", COLUMN_PRPL_ICON);
+
+	/* Account name */
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_column_pack_start(column, renderer, TRUE);
+	gtk_tree_view_column_add_attribute(column, renderer,
+									   "text", COLUMN_USERNAME);
+}
+
+static void
+add_ims(GevoAddBuddyDialog *dialog, EContact *contact, const char *name,
+		GList *list, const char *id)
+{
+	GaimAccount *account = NULL;
+	GList *l;
+	GtkTreeIter iter;
+	GdkPixbuf *pixbuf, *icon = NULL;
+
+	if (list == NULL)
+		return;
+
+	for (l = gaim_connections_get_all(); l != NULL; l = l->next)
+	{
+		GaimConnection *gc = (GaimConnection *)l->data;
+
+		account = gaim_connection_get_account(gc);
+
+		if (!strcmp(gaim_account_get_protocol_id(account), id))
+			break;
+
+		account = NULL;
+	}
+
+	if (account == NULL)
+		return;
+
+	pixbuf = create_prpl_icon(account);
+
+	if (pixbuf != NULL)
+		icon = gdk_pixbuf_scale_simple(pixbuf, 16, 16,
+									   GDK_INTERP_BILINEAR);
+
+	for (l = list; l != NULL; l = l->next)
+	{
+		char *account_name = (char *)l->data;
+
+		if (account_name == NULL)
+			continue;
+
+		if (gaim_find_buddy(dialog->account, account_name) != NULL)
+			continue;
+
+		gtk_list_store_append(dialog->model, &iter);
+
+		gtk_list_store_set(dialog->model, &iter,
+						   COLUMN_NAME, name,
+						   COLUMN_PRPL_ICON, icon,
+						   COLUMN_USERNAME, account_name,
+						   COLUMN_DATA, contact,
+						   -1);
+
+		if (!strcmp(gaim_account_get_protocol_id(account),
+					gaim_account_get_protocol_id(dialog->account)) &&
+			dialog->username != NULL &&
+			!strcmp(account_name, dialog->username))
+		{
+			GtkTreeSelection *selection;
+
+			/* This is it. Select it. */
+			selection = gtk_tree_view_get_selection(
+				GTK_TREE_VIEW(dialog->treeview));
+
+			gtk_tree_selection_select_iter(selection, &iter);
+		}
+	}
+
+	if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf));
+	if (icon != NULL)   g_object_unref(G_OBJECT(icon));
+
+	g_list_foreach(list, (GFunc)g_free, NULL);
+	g_list_free(list);
+}
+
+static void
+populate_treeview(GevoAddBuddyDialog *dialog)
+{
+	EBookQuery *query;
+	EBook *book;
+	gboolean status;
+	GList *cards, *c;
+
+	if (!gevo_load_addressbook(&book, NULL))
+	{
+		gaim_debug_error("evolution",
+						 "Error retrieving default addressbook\n");
+
+		return;
+	}
+
+	query = e_book_query_field_exists(E_CONTACT_FULL_NAME);
+
+	if (query == NULL)
+	{
+		gaim_debug_error("evolution", "Error in creating query\n");
+
+		g_object_unref(book);
+
+		return;
+	}
+
+	status = e_book_get_contacts(book, query, &cards, NULL);
+
+	e_book_query_unref(query);
+
+	if (!status)
+	{
+		gaim_debug_error("evolution", "Error %d in getting card list\n",
+						 status);
+
+		g_object_unref(book);
+
+		return;
+	}
+
+	for (c = cards; c != NULL; c = c->next)
+	{
+		EContact *contact = E_CONTACT(c->data);
+		const char *name;
+		GList *aims, *jabbers, *yahoos, *msns, *icqs;
+
+		name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
+
+		aims    = e_contact_get(contact, E_CONTACT_IM_AIM);
+		jabbers = e_contact_get(contact, E_CONTACT_IM_JABBER);
+		yahoos  = e_contact_get(contact, E_CONTACT_IM_YAHOO);
+		msns    = e_contact_get(contact, E_CONTACT_IM_MSN);
+		icqs    = e_contact_get(contact, E_CONTACT_IM_ICQ);
+
+		if (aims == NULL && jabbers == NULL && yahoos == NULL &&
+			msns == NULL && icqs == NULL)
+		{
+			GtkTreeIter iter;
+
+			gtk_list_store_append(dialog->model, &iter);
+
+			gtk_list_store_set(dialog->model, &iter,
+							   COLUMN_NAME, name,
+							   COLUMN_DATA, contact,
+							   -1);
+		}
+		else
+		{
+			add_ims(dialog, contact, name, aims,    "prpl-oscar");
+			add_ims(dialog, contact, name, jabbers, "prpl-jabber");
+			add_ims(dialog, contact, name, yahoos,  "prpl-yahoo");
+			add_ims(dialog, contact, name, msns,    "prpl-msn");
+			add_ims(dialog, contact, name, icqs,    "prpl-oscar");
+		}
+	}
+
+	dialog->contacts = cards;
+	dialog->book = book;
+}
+
+static void
+selected_cb(GtkTreeSelection *sel, GevoAddBuddyDialog *dialog)
+{
+	gtk_widget_set_sensitive(dialog->select_button, TRUE);
+}
+
+static void
+search_changed_cb(GtkEntry *entry, GevoAddBuddyDialog *dialog)
+{
+	const char *text = gtk_entry_get_text(entry);
+	GList *l;
+
+	gtk_list_store_clear(dialog->model);
+
+	for (l = dialog->contacts; l != NULL; l = l->next)
+	{
+		EContact *contact = E_CONTACT(l->data);
+		const char *name;
+		GList *aims, *jabbers, *yahoos, *msns, *icqs;
+
+		name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
+
+		if (text != NULL && *text != '\0' && name != NULL &&
+			g_ascii_strncasecmp(name, text, strlen(text)))
+		{
+			continue;
+		}
+
+		aims    = e_contact_get(contact, E_CONTACT_IM_AIM);
+		jabbers = e_contact_get(contact, E_CONTACT_IM_JABBER);
+		yahoos  = e_contact_get(contact, E_CONTACT_IM_YAHOO);
+		msns    = e_contact_get(contact, E_CONTACT_IM_MSN);
+		icqs    = e_contact_get(contact, E_CONTACT_IM_ICQ);
+
+		if (aims == NULL && jabbers == NULL && yahoos == NULL &&
+			msns == NULL && icqs == NULL)
+		{
+			GtkTreeIter iter;
+
+			gtk_list_store_append(dialog->model, &iter);
+
+			gtk_list_store_set(dialog->model, &iter,
+							   COLUMN_NAME, name,
+							   COLUMN_DATA, contact,
+							   -1);
+		}
+		else
+		{
+			add_ims(dialog, contact, name, aims,    "prpl-oscar");
+			add_ims(dialog, contact, name, jabbers, "prpl-jabber");
+			add_ims(dialog, contact, name, yahoos,  "prpl-yahoo");
+			add_ims(dialog, contact, name, msns,    "prpl-msn");
+			add_ims(dialog, contact, name, icqs,    "prpl-oscar");
+		}
+	}
+}
+
+static void
+clear_cb(GtkWidget *w, GevoAddBuddyDialog *dialog)
+{
+	static gboolean lock = FALSE;
+
+	if (lock)
+		return;
+
+	lock = TRUE;
+	gtk_entry_set_text(GTK_ENTRY(dialog->search_field), "");
+	lock = FALSE;
+}
+
+void
+gevo_add_buddy_dialog_show(GaimAccount *account, const char *username,
+						   const char *group, const char *alias)
+{
+	GevoAddBuddyDialog *dialog;
+	GtkWidget *button;
+	GtkWidget *sw;
+	GtkWidget *label;
+	GtkWidget *vbox;
+	GtkWidget *hbox;
+	GtkWidget *bbox;
+	GtkWidget *menu;
+	GtkWidget *sep;
+	GtkTreeSelection *selection;
+
+	dialog = g_new0(GevoAddBuddyDialog, 1);
+
+	dialog->account =
+		(account != NULL
+		 ? account
+		 : gaim_connection_get_account(gaim_connections_get_all()->data));
+
+	if (username != NULL)
+		dialog->username = g_strdup(username);
+
+	dialog->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+	gtk_window_set_role(GTK_WINDOW(dialog->win), "add_buddy");
+	gtk_container_set_border_width(GTK_CONTAINER(dialog->win), 12);
+	gtk_widget_set_size_request(dialog->win, -1, 400);
+
+	g_signal_connect(G_OBJECT(dialog->win), "delete_event",
+					 G_CALLBACK(delete_win_cb), dialog);
+
+	/* Setup the vbox */
+	vbox = gtk_vbox_new(FALSE, 12);
+	gtk_container_add(GTK_CONTAINER(dialog->win), vbox);
+	gtk_widget_show(vbox);
+
+	/* Add the label. */
+	label = gtk_label_new(_("Select a person from your address book below, "
+							"or add a new person."));
+	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
+	gtk_widget_show(label);
+
+	/* Add the search hbox */
+	hbox = gtk_hbox_new(FALSE, 6);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
+	gtk_widget_show(hbox);
+
+	/* "Search" */
+	label = gtk_label_new(_("Search"));
+	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+	gtk_widget_show(label);
+
+	/* Addressbooks */
+	dialog->addressbooks_menu = gtk_option_menu_new();
+	menu = gtk_menu_new();
+	gtk_option_menu_set_menu(GTK_OPTION_MENU(dialog->addressbooks_menu), menu);
+
+	populate_address_books(dialog);
+
+	gtk_option_menu_set_history(GTK_OPTION_MENU(dialog->addressbooks_menu), 0);
+
+	gtk_box_pack_start(GTK_BOX(hbox), dialog->addressbooks_menu,
+					   FALSE, FALSE, 0);
+	gtk_widget_show(dialog->addressbooks_menu);
+
+	/* Search field */
+	dialog->search_field = gtk_entry_new();
+	gtk_box_pack_start(GTK_BOX(hbox), dialog->search_field, TRUE, TRUE, 0);
+	gtk_widget_show(dialog->search_field);
+
+	g_signal_connect(G_OBJECT(dialog->search_field), "changed",
+					 G_CALLBACK(search_changed_cb), dialog);
+
+	/* Clear button */
+	button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
+	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+	gtk_widget_show(button);
+
+	g_signal_connect(G_OBJECT(button), "clicked",
+					 G_CALLBACK(clear_cb), dialog);
+
+	/* Scrolled Window */
+	sw = gtk_scrolled_window_new(0, 0);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+								   GTK_POLICY_AUTOMATIC,
+								   GTK_POLICY_ALWAYS);
+	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
+										GTK_SHADOW_IN);
+	gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
+	gtk_widget_show(sw);
+
+	/* Create the list model for the treeview. */
+	dialog->model = gtk_list_store_new(NUM_COLUMNS,
+									   G_TYPE_STRING, GDK_TYPE_PIXBUF,
+									   G_TYPE_STRING, G_TYPE_POINTER);
+
+	/* Now for the treeview */
+	dialog->treeview =
+		gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model));
+	gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE);
+	gtk_container_add(GTK_CONTAINER(sw), dialog->treeview);
+	gtk_widget_show(dialog->treeview);
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
+
+	gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+	g_signal_connect(G_OBJECT(selection), "changed",
+					 G_CALLBACK(selected_cb), dialog);
+
+	add_columns(dialog);
+
+	populate_treeview(dialog);
+
+	/* Group box */
+	hbox = gtk_hbox_new(FALSE, 6);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+	gtk_widget_show(hbox);
+
+	label = gtk_label_new(_("Group:"));
+	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+	gtk_widget_show(label);
+
+	dialog->group_combo = gtk_combo_new();
+	gtk_combo_set_popdown_strings(GTK_COMBO(dialog->group_combo),
+								  gevo_get_groups());
+	gtk_box_pack_start(GTK_BOX(hbox), dialog->group_combo, TRUE, TRUE, 0);
+	gtk_widget_show(dialog->group_combo);
+
+	/* Cool. Now we only have a little left... */
+
+	/* Separator. */
+	sep = gtk_hseparator_new();
+	gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
+	gtk_widget_show(sep);
+
+	/* Button box */
+	bbox = gtk_hbutton_box_new();
+	gtk_box_set_spacing(GTK_BOX(bbox), 6);
+	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+	gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
+	gtk_widget_show(bbox);
+
+	/* "New Person" button */
+	button = gaim_pixbuf_button_from_stock(_("New Person"), GTK_STOCK_NEW,
+										   GAIM_BUTTON_HORIZONTAL);
+	gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
+	gtk_widget_show(button);
+
+	g_signal_connect(G_OBJECT(button), "clicked",
+					 G_CALLBACK(new_person_cb), dialog);
+
+	/* "Cancel" button */
+	button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+	gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
+	gtk_widget_show(button);
+
+	g_signal_connect(G_OBJECT(button), "clicked",
+					 G_CALLBACK(cancel_cb), dialog);
+
+	/* "Select Buddy" button */
+	button = gaim_pixbuf_button_from_stock(_("Select Buddy"), GTK_STOCK_APPLY,
+										   GAIM_BUTTON_HORIZONTAL);
+	dialog->select_button = button;
+	gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
+	gtk_widget_set_sensitive(button, FALSE);
+	gtk_widget_show(button);
+
+	g_signal_connect(G_OBJECT(button), "clicked",
+					 G_CALLBACK(select_buddy_cb), dialog);
+
+	/* Show it. */
+	gtk_widget_show(dialog->win);
+}
+
+void
+gevo_add_buddy_dialog_add_person(GevoAddBuddyDialog *dialog,
+								 EContact *contact, const char *name,
+								 GaimAccount *account, const char *screenname)
+{
+	GdkPixbuf *pixbuf, *icon = NULL;
+	GtkTreeIter iter;
+
+	pixbuf = create_prpl_icon(account);
+
+	if (pixbuf != NULL)
+		icon = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR);
+
+	gtk_list_store_append(dialog->model, &iter);
+
+	gtk_list_store_set(dialog->model, &iter,
+					   COLUMN_NAME, name,
+					   COLUMN_PRPL_ICON, icon,
+					   COLUMN_DATA, contact,
+					   COLUMN_USERNAME, screenname,
+					   -1);
+
+	if (contact != NULL)
+		dialog->contacts = g_list_append(dialog->contacts, contact);
+
+	if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf));
+	if (icon != NULL)   g_object_unref(G_OBJECT(icon));
+}