# HG changeset patch # User Etan Reisner # Date 1133467767 0 # Node ID af257d8679fe8c584e901b4f4bc8bf705b968f63 # Parent ecd471d1eeec11b4a473c4c76fa85d41551ff963 [gaim-migrate @ 14589] Ok, so I'm changing the semantics of gaim_account_notify_added, having it check for the existance of a buddy was breaking some jabber scenarios. So buddy checks should now be done in the prpls. I also added a gaim_account_request_add. _notify_added only notifies the user of the add, request_add notifies the user AND asks them if they want to add the buddy to their buddy list. I only updated jabber for these changes because it's the only protocol I really know at all well. So everyone PLEASE make sure that the other protocols get updated for this. That is make sure that when you expect to prompt the user to add the buddy you use _request_add instead of just using _notify_added and expecting the core to determine if it needs to prompt the user. Oh, there are also some other jabber changes which should hopefully fix some issues that people were seeing, like buddies not signing off when you unsubscribed with them, etc. Let me know if anyone notices any jabber oddities after this. committer: Tailor Script diff -r ecd471d1eeec -r af257d8679fe plugins/ChangeLog.API --- a/plugins/ChangeLog.API Thu Dec 01 19:55:35 2005 +0000 +++ b/plugins/ChangeLog.API Thu Dec 01 20:09:27 2005 +0000 @@ -64,6 +64,10 @@ void *user_data -> gpointer user_data * gaim_notify_searchresults_get_rows_count, gaim_notify_searchresults_get_columns_count: return type now guint + * gaim_account_notify_added: No longer checks if there is a GaimBuddy for + the added user, that's left up to the prpls. + See the documentation for this function and + gaim_account_request_add. Removed: * gaim_gtk_sound_{get,set}_mute() (replaced by the /gaim/gtk/sound/mute @@ -171,6 +175,9 @@ * gaim_gtk_pounce_editor_show() * GAIM_STOCK_CONNECT, GAIM_STOCK_DISCONNECT * GAIM_STOCK_PLUGIN + * gaim_account_request_add: Notifies the user that they were added to + someone's buddy list, and offers them the choice + of adding that person to their buddy list. Signals - Changed: (See the Doxygen docs for details on all signals.) * Signal propagation now stops after a handler returns a non-NULL value. diff -r ecd471d1eeec -r af257d8679fe src/account.c --- a/src/account.c Thu Dec 01 19:55:35 2005 +0000 +++ b/src/account.c Thu Dec 01 20:09:27 2005 +0000 @@ -1045,6 +1045,22 @@ ui_ops->notify_added(account, remote_user, id, alias, message); } +void +gaim_account_request_add(GaimAccount *account, const char *remote_user, + const char *id, const char *alias, + const char *message) +{ + GaimAccountUiOps *ui_ops; + + g_return_if_fail(account != NULL); + g_return_if_fail(remote_user != NULL); + + ui_ops = gaim_accounts_get_ui_ops(); + + if (ui_ops != NULL && ui_ops->request_add != NULL) + ui_ops->request_add(account, remote_user, id, alias, message); +} + static void change_password_cb(GaimAccount *account, GaimRequestFields *fields) { diff -r ecd471d1eeec -r af257d8679fe src/account.h --- a/src/account.h Thu Dec 01 19:55:35 2005 +0000 +++ b/src/account.h Thu Dec 01 20:09:27 2005 +0000 @@ -42,10 +42,15 @@ struct _GaimAccountUiOps { + /* A buddy we already have added us to their buddy list. */ void (*notify_added)(GaimAccount *account, const char *remote_user, - const char *id, const char *alias, - const char *message); + const char *id, const char *alias, + const char *message); void (*status_changed)(GaimAccount *account, GaimStatus *status); + /* Someone we don't have on our list added us. Will prompt to add them. */ + void (*request_add)(GaimAccount *account, const char *remote_user, + const char *id, const char *alis, + const char *message); }; struct _GaimAccount @@ -134,8 +139,8 @@ * Notifies the user that the account was added to a remote user's * buddy list. * - * This will present a dialog so that the local user can add the buddy, - * if not already added. + * This will present a dialog informing the user that he was added to the + * remote user's buddy list. * * @param account The account that was added. * @param remote_user The name of the user that added this account. @@ -144,10 +149,28 @@ * @param message The optional message sent from the user adding you. */ void gaim_account_notify_added(GaimAccount *account, const char *remote_user, - const char *id, const char *alias, - const char *message); + const char *id, const char *alias, + const char *message); /** + * Notifies the user that the account was addded to a remote user's buddy + * list and asks ther user if they want to add the remote user to their buddy + * list. + * + * This will present a dialog informing the local user that the remote user + * added them to the remote user's buddy list and will ask if they want to add + * the remote user to the buddy list. + * + * @param account The account that was added. + * @param remote_user The name of the user that added this account. + * @param id The optional ID of the local account. Rarely used. + * @param alias The optional alias of the user. + * @param message The optional message sent from the user adding you. + */ +void gaim_account_request_add(GaimAccount *account, const char *remote_user, + const char *id, const char *alias, + const char *message); +/** * Requests information from the user to change the account's password. * * @param account The account to change the password on. diff -r ecd471d1eeec -r af257d8679fe src/gtkaccount.c --- a/src/gtkaccount.c Thu Dec 01 19:55:35 2005 +0000 +++ b/src/gtkaccount.c Thu Dec 01 20:09:27 2005 +0000 @@ -2527,52 +2527,70 @@ free_add_user_data(data); } +static char * +make_info(GaimAccount *account, GaimConnection *gc, const char *remote_user, + const char *id, const char *alias, const char *msg) +{ + return g_strdup_printf(_("%s%s%s%s has made %s his or her buddy%s%s."), + remote_user, + (alias != NULL ? " (" : ""), + (alias != NULL ? alias : ""), + (alias != NULL ? ")" : ""), + (id != NULL + ? id + : (gaim_connection_get_display_name(gc) != NULL + ? gaim_connection_get_display_name(gc) + : gaim_account_get_username(account))), + (msg != NULL ? ": " : "."), + (msg != NULL ? msg : "")); +} + static void gaim_gtk_accounts_notify_added(GaimAccount *account, const char *remote_user, - const char *id, const char *alias, - const char *msg) + const char *id, const char *alias, + const char *msg) { char *buffer; GaimConnection *gc; GaimGtkAccountAddUserData *data; - GaimBuddy *buddy; gc = gaim_account_get_connection(account); - buddy = gaim_find_buddy(account, remote_user); - data = g_new0(GaimGtkAccountAddUserData, 1); data->account = account; data->username = g_strdup(remote_user); data->alias = (alias != NULL ? g_strdup(alias) : NULL); - buffer = g_strdup_printf(_("%s%s%s%s has made %s his or her buddy%s%s%s"), - remote_user, - (alias != NULL ? " (" : ""), - (alias != NULL ? alias : ""), - (alias != NULL ? ")" : ""), - (id != NULL - ? id - : (gaim_connection_get_display_name(gc) != NULL - ? gaim_connection_get_display_name(gc) - : gaim_account_get_username(account))), - (msg != NULL ? ": " : "."), - (msg != NULL ? msg : ""), - (buddy != NULL - ? "" - : _("\n\nDo you wish to add him or her to your buddy list?"))); - - if (buddy != NULL) - { - gaim_notify_info(NULL, NULL, buffer, NULL); - } - else - { - gaim_request_action(NULL, NULL, _("Add buddy to your list?"), - buffer, GAIM_DEFAULT_ACTION_NONE, data, 2, - _("Add"), G_CALLBACK(add_user_cb), - _("Cancel"), G_CALLBACK(free_add_user_data)); - } + buffer = make_info(account, gc, remote_user, id, alias, msg); + + gaim_notify_info(NULL, NULL, buffer, NULL); + + g_free(buffer); +} + + +static void +gaim_gtk_accounts_request_add(GaimAccount *account, const char *remote_user, + const char *id, const char *alias, + const char *msg) +{ + char *buffer; + GaimConnection *gc; + GaimGtkAccountAddUserData *data; + + gc = gaim_account_get_connection(account); + + data = g_new0(GaimGtkAccountAddUserData, 1); + data->account = account; + data->username = g_strdup(remote_user); + data->alias = (alias != NULL ? g_strdup(alias) : NULL); + + buffer = make_info(account, gc, remote_user, id, alias, msg); + + gaim_request_action(NULL, NULL, _("Add buddy to your list?"), + buffer, GAIM_DEFAULT_ACTION_NONE, data, 2, + _("Add"), G_CALLBACK(add_user_cb), + _("Cancel"), G_CALLBACK(free_add_user_data)); g_free(buffer); } @@ -2580,7 +2598,8 @@ static GaimAccountUiOps ui_ops = { gaim_gtk_accounts_notify_added, - NULL + NULL, + gaim_gtk_accounts_request_add }; GaimAccountUiOps * diff -r ecd471d1eeec -r af257d8679fe src/protocols/jabber/presence.c --- a/src/protocols/jabber/presence.c Thu Dec 01 19:55:35 2005 +0000 +++ b/src/protocols/jabber/presence.c Thu Dec 01 20:09:27 2005 +0000 @@ -171,6 +171,7 @@ } struct _jabber_add_permit { + JabberStream *js; GaimConnection *gc; char *who; }; @@ -178,11 +179,31 @@ static void authorize_add_cb(struct _jabber_add_permit *jap) { if(g_list_find(gaim_connections_get_all(), jap->gc)) { + GaimBuddy *buddy = NULL; + jabber_presence_subscription_set(jap->gc->proto_data, jap->who, "subscribed"); - if(!gaim_find_buddy(jap->gc->account, jap->who)) - gaim_account_notify_added(jap->gc->account, NULL, jap->who, NULL, NULL); + buddy = gaim_find_buddy(jap->gc->account, jap->who); + + if (buddy) { + JabberBuddy *jb = NULL; + + jb = jabber_buddy_find(jap->js, jap->who, TRUE); + + if ((jb->subscription & JABBER_SUB_TO) == 0) { + gaim_account_request_add(jap->gc->account, + jap->who, NULL, + NULL, NULL); + } else { + gaim_account_notify_added(jap->gc->account, + jap->who, NULL, + NULL, NULL); + } + } else { + gaim_account_request_add(jap->gc->account, jap->who, + NULL, NULL, NULL); + } } g_free(jap->who); @@ -291,6 +312,7 @@ from, gaim_account_get_username(js->gc->account)); jap->gc = js->gc; jap->who = g_strdup(from); + jap->js = js; gaim_request_action(js->gc, NULL, msg, NULL, GAIM_DEFAULT_ACTION_NONE, jap, 2, @@ -303,6 +325,15 @@ /* we've been allowed to see their presence, but we don't care */ jabber_id_free(jid); return; + } else if(type && !strcmp(type, "unsubscribe")) { + /* XXX I'm not sure this is the right way to handle this, it + * might be better to add "unsubscribe" to the presence status + * if lower down, but I'm not sure. */ + /* they are unsubscribing from our presence, we don't care */ + /* Well, maybe just a little, we might want/need to start + * acknowledging this (and the others) at some point. */ + jabber_id_free(jid); + return; } else { if((y = xmlnode_get_child(packet, "show"))) { char *show = xmlnode_get_data(y); @@ -493,16 +524,6 @@ } g_free(room_jid); } else { - if(state != JABBER_BUDDY_STATE_ERROR && !(jb->subscription & JABBER_SUB_TO || jb->subscription & JABBER_SUB_PENDING)) { - gaim_debug(GAIM_DEBUG_INFO, "jabber", - "got unexpected presence from %s, ignoring\n", from); - jabber_id_free(jid); - g_free(status); - if(avatar_hash) - g_free(avatar_hash); - return; - } - buddy_name = g_strdup_printf("%s%s%s", jid->node ? jid->node : "", jid->node ? "@" : "", jid->domain); if((b = gaim_find_buddy(js->gc->account, buddy_name)) == NULL) { diff -r ecd471d1eeec -r af257d8679fe src/protocols/jabber/roster.c --- a/src/protocols/jabber/roster.c Thu Dec 01 19:55:35 2005 +0000 +++ b/src/protocols/jabber/roster.c Thu Dec 01 20:09:27 2005 +0000 @@ -54,7 +54,6 @@ static void add_gaim_buddies_in_groups(JabberStream *js, const char *jid, const char *alias, GSList *groups) { - GaimPresence *presence = NULL; GSList *buddies, *g2, *l; buddies = gaim_find_buddies(js->gc->account, jid); @@ -68,10 +67,6 @@ return; } - if(buddies) { - presence = gaim_buddy_get_presence((GaimBuddy*)buddies->data); - } - while(buddies) { GaimBuddy *b = buddies->data; GaimGroup *g = gaim_buddy_get_group(b); @@ -102,10 +97,6 @@ gaim_blist_add_group(g, NULL); } - /* XXX: this hack may need to change */ - /* Is this change better? */ - b->presence = presence; - gaim_blist_add_buddy(b, NULL, g, NULL); gaim_blist_alias_buddy(b, alias); g_free(g2->data); @@ -162,7 +153,21 @@ continue; if(subscription) { - if(!strcmp(subscription, "to")) + gint me = -1; + char *jid_norm; + const char *username; + + jid_norm = g_strdup(jabber_normalize(js->gc->account, jid)); + username = gaim_account_get_username(js->gc->account); + me = g_utf8_collate(jid_norm, + jabber_normalize(js->gc->account, + username)); + + if(me == 0) + jb->subscription = JABBER_SUB_BOTH; + else if(!strcmp(subscription, "none")) + jb->subscription = JABBER_SUB_NONE; + else if(!strcmp(subscription, "to")) jb->subscription = JABBER_SUB_TO; else if(!strcmp(subscription, "from")) jb->subscription = JABBER_SUB_FROM; @@ -173,6 +178,14 @@ /* XXX: if subscription is now "from" or "none" we need to * fake a signoff, since we won't get any presence from them * anymore */ + /* YYY: I was going to use this, but I'm not sure it's necessary + * anymore, but it's here in case it is. */ + /* + if ((jb->subscription & JABBER_SUB_FROM) || + (jb->subscription & JABBER_SUB_NONE)) { + gaim_prpl_got_user_status(js->gc->account, jid, "offline", NULL); + } + */ } if(ask && !strcmp(ask, "subscribe"))