changeset 12285:af257d8679fe

[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 <tailor@pidgin.im>
author Etan Reisner <pidgin@unreliablesource.net>
date Thu, 01 Dec 2005 20:09:27 +0000
parents ecd471d1eeec
children 255e6912607b
files plugins/ChangeLog.API src/account.c src/account.h src/gtkaccount.c src/protocols/jabber/presence.c src/protocols/jabber/roster.c
diffstat 6 files changed, 160 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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)
 {
--- 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.
--- 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 *
--- 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) {
--- 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"))