# HG changeset patch # User Richard Laager # Date 1121671569 0 # Node ID 5a8bc4b1f5b601600f439b7d1ed3bf7ab9be46a1 # Parent bbb28c529be0e1fcb54acd348fad44ffc7c3be45 [gaim-migrate @ 13173] Patch #1052811, from Szilard Novaki "gevolution plugin should register a "Send Email" popup menuitem to send mail for users using gaim contact list. See the attached patch (patched for gaim-1.0.2 release)." I made a number of changes to this to simplify it. Thanks to shres and NotZed in #evolution on irc.gnome.org for their help. Other changes: - I may have squashed some leaks in existing code as I tracked down leaks in the new code. I'm not really sure. It still leaks something that I can't track down, but that happens even if you don't call any of the new code. I verified that it was happening pre-patch, so it's no worse with this feature addition. - It's not really Ximian Evolution anymore, so I changed the summary and description to remove "Ximian", leaving it just Evolution. committer: Tailor Script diff -r bbb28c529be0 -r 5a8bc4b1f5b6 COPYRIGHT --- a/COPYRIGHT Mon Jul 18 01:52:43 2005 +0000 +++ b/COPYRIGHT Mon Jul 18 07:26:09 2005 +0000 @@ -140,6 +140,7 @@ Arkadiusz Miskiewicz Andrew Molloy Matthew A. Nicholson +Szilard Novaki Novell Padraig O'Briain Christopher O'Brien (siege) diff -r bbb28c529be0 -r 5a8bc4b1f5b6 plugins/gevolution/eds-utils.c --- a/plugins/gevolution/eds-utils.c Mon Jul 18 01:52:43 2005 +0000 +++ b/plugins/gevolution/eds-utils.c Mon Jul 18 07:26:09 2005 +0000 @@ -113,3 +113,133 @@ g_object_unref(addressbooks); } + +EContact * +gevo_run_query_in_uri(const gchar *uri, EBookQuery *query) +{ + EBook *book; + gboolean status; + GList *cards; + + if (!gevo_load_addressbook(uri, &book, NULL)) + { + gaim_debug_error("evolution", + "Error retrieving addressbook\n"); + return NULL; + } + + status = e_book_get_contacts(book, query, &cards, NULL); + if (!status) + { + gaim_debug_error("evolution", "Error %d in getting card list\n", + status); + g_object_unref(book); + return NULL; + } + g_object_unref(book); + + if (cards != NULL) + { + EContact *contact = E_CONTACT(cards->data); + GList *cards2 = cards->next; + + if (cards2 != NULL) + { + /* Break off the first contact and free the rest. */ + cards->next = NULL; + cards2->prev = NULL; + g_list_foreach(cards2, (GFunc)g_object_unref, NULL); + } + + /* Free the whole list. */ + g_list_free(cards); + + return contact; + } + + return NULL; +} + +/* + * Search for a buddy in the Evolution contacts. + * + * @param buddy The buddy to search for. + * @param query An optional query. This function takes ownership of @a query, + * so callers must e_book_query_ref() it in advance (to obtain a + * second reference) if they want to reuse @a query. + */ +EContact * +gevo_search_buddy_in_contacts(GaimBuddy *buddy, EBookQuery *query) +{ + ESourceList *addressbooks; + GError *err; + EBookQuery *full_query; + GSList *groups, *g; + EContact *result; + EContactField protocol_field = gevo_prpl_get_field(buddy->account, buddy); + + if (protocol_field == 0) + return NULL; + + if (query != NULL) + { + EBookQuery *queries[2]; + + queries[0] = query; + queries[1] = e_book_query_field_test(protocol_field, E_BOOK_QUERY_IS, buddy->name); + if (queries[1] == NULL) + { + gaim_debug_error("evolution", "Error in creating protocol query\n"); + e_book_query_unref(query); + return NULL; + } + + full_query = e_book_query_and(2, queries, TRUE); + } + else + { + full_query = e_book_query_field_test(protocol_field, E_BOOK_QUERY_IS, buddy->name); + if (full_query == NULL) + { + gaim_debug_error("evolution", "Error in creating protocol query\n"); + return NULL; + } + } + + if (!e_book_get_addressbooks(&addressbooks, &err)) + { + gaim_debug_error("evolution", + "Unable to fetch list of address books.\n"); + e_book_query_unref(full_query); + if (err != NULL) + g_error_free(err); + return NULL; + } + + groups = e_source_list_peek_groups(addressbooks); + if (groups == NULL) + { + g_object_unref(addressbooks); + e_book_query_unref(full_query); + return NULL; + } + + for (g = groups; g != NULL; g = g->next) + { + GSList *sources, *s; + sources = e_source_group_peek_sources(g->data); + for (s = sources; s != NULL; s = s->next) + { + result = gevo_run_query_in_uri(e_source_get_uri(E_SOURCE(s->data)), full_query); + if (result != NULL) { + g_object_unref(addressbooks); + e_book_query_unref(full_query); + return result; + } + } + } + + g_object_unref(addressbooks); + e_book_query_unref(full_query); + return NULL; +} diff -r bbb28c529be0 -r 5a8bc4b1f5b6 plugins/gevolution/gevolution.c --- a/plugins/gevolution/gevolution.c Mon Jul 18 01:52:43 2005 +0000 +++ b/plugins/gevolution/gevolution.c Mon Jul 18 07:26:09 2005 +0000 @@ -24,6 +24,7 @@ #include "connection.h" #include "debug.h" #include "prefs.h" +#include "notify.h" #include "signals.h" #include "util.h" #include "version.h" @@ -41,6 +42,8 @@ #include #include +#include + #define GEVOLUTION_PLUGIN_ID "gtk-x11-gevolution" #define E_DATA_BOOK_FACTORY_OAF_ID \ @@ -211,6 +214,63 @@ } static void +menu_item_send_mail_activate_cb(GaimBlistNode *node, gpointer user_data) +{ + GaimBuddy *buddy = (GaimBuddy *)node; + EContact *contact; + char *mail = NULL; + + contact = gevo_search_buddy_in_contacts(buddy, NULL); + + if (contact != NULL) + { + mail = g_strdup(e_contact_get(contact, E_CONTACT_EMAIL_1)); + g_object_unref(contact); + } + else + { + GaimAccount *account = gaim_buddy_get_account(buddy); + const char *prpl_id = gaim_account_get_protocol_id(account); + + if (!strcmp(prpl_id, "prpl-msn")) + { + mail = g_strdup(gaim_normalize(account, + gaim_buddy_get_name(buddy))); + } + else if (!strcmp(prpl_id, "prpl-yahoo")) + { + mail = g_strdup_printf("%s@yahoo.com", + gaim_normalize(account, + gaim_buddy_get_name(buddy))); + } + } + + if (mail != NULL) + { + char *app = g_find_program_in_path("evolution"); + if (app != NULL) + { + char *command_line = g_strdup_printf("%s mailto:%s", app, mail); + g_free(app); + g_free(mail); + + g_spawn_command_line_async(command_line, NULL); + g_free(command_line); + } + else + { + gaim_notify_error(NULL, NULL, _("Unable to send e-mail"), + _("The evolution executable was not found in the PATH.")); + } + } + else + { + gaim_notify_error(NULL, NULL, _("Unable to send e-mail"), + _("The specified buddy was not found in the Evolution Contacts.")); + } +} + +static void blist_node_extended_menu_cb(GaimBlistNode *node, GList **menu) { GaimBlistNodeAction *act; @@ -227,6 +287,10 @@ menu_item_activate_cb, NULL, NULL); *menu = g_list_append(*menu, act); + act = gaim_blist_node_action_new(_("Send E-Mail"), + menu_item_send_mail_activate_cb, + NULL, NULL); + *menu = g_list_append(*menu, act); } } @@ -470,9 +534,9 @@ N_("Evolution Integration"), /**< name */ VERSION, /**< version */ /** summary */ - N_("Provides integration with Ximian Evolution."), + N_("Provides integration with Evolution."), /** description */ - N_("Provides integration with Ximian Evolution."), + N_("Provides integration with Evolution."), "Christian Hammond ", /**< author */ GAIM_WEBSITE, /**< homepage */ diff -r bbb28c529be0 -r 5a8bc4b1f5b6 plugins/gevolution/gevolution.h --- a/plugins/gevolution/gevolution.h Mon Jul 18 01:52:43 2005 +0000 +++ b/plugins/gevolution/gevolution.h Mon Jul 18 07:26:09 2005 +0000 @@ -127,9 +127,9 @@ GevoAssociateBuddyDialog *gevo_associate_buddy_dialog_new(GaimBuddy *buddy); - GtkTreeModel *gevo_addrbooks_model_new(void); void gevo_addrbooks_model_unref(GtkTreeModel *model); void gevo_addrbooks_model_populate(GtkTreeModel *model); +EContact *gevo_search_buddy_in_contacts(GaimBuddy *buddy, EBookQuery *query); #endif /* _GEVOLUTION_H_ */