changeset 17366:2284a8aad9ef

merge of '4751c73009c45ab1f2514522886dc9d36f66c7fb' and '646d2996dcbe3086c189b9eb507aeb6b1a00380d'
author Nathan Walp <nwalp@pidgin.im>
date Tue, 29 May 2007 04:43:56 +0000
parents 043a1139d4e5 (current diff) cc1b4d2e5a9b (diff)
children 837b697723c0
files
diffstat 3 files changed, 99 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/disco.c	Mon May 28 19:08:05 2007 +0000
+++ b/libpurple/protocols/jabber/disco.c	Tue May 29 04:43:56 2007 +0000
@@ -224,17 +224,17 @@
 		/* If the server supports JABBER_CAP_GOOGLE_ROSTER; we will have already requested it */
 		jabber_roster_request(js);
 	}
-	
+
 	/* Send initial presence; this will trigger receipt of presence for contacts on the roster */
 	gpresence = purple_account_get_presence(js->gc->account);
 	status = purple_presence_get_active_status(gpresence);
-	jabber_presence_send(js->gc->account, status);	
+	jabber_presence_send(js->gc->account, status);
 }
 
 static void
 jabber_disco_server_info_result_cb(JabberStream *js, xmlnode *packet, gpointer data)
 {
-  	xmlnode *query, *child;
+	xmlnode *query, *child;
 	const char *from = xmlnode_get_attrib(packet, "from");
 	const char *type = xmlnode_get_attrib(packet, "type");
 
@@ -257,7 +257,7 @@
 		return;
 	}
 
-	for (child = xmlnode_get_child(query, "identity"); child; 
+	for (child = xmlnode_get_child(query, "identity"); child;
 	     child = xmlnode_get_next_twin(child)) {
 		const char *category, *type, *name;
 		category = xmlnode_get_attrib(child, "category");
@@ -266,7 +266,7 @@
 		type = xmlnode_get_attrib(child, "type");
 		if (!type || strcmp(type, "im"))
 			continue;
-		
+
 		name = xmlnode_get_attrib(child, "name");
 		if (!name)
 			continue;
@@ -279,7 +279,7 @@
 		}
 	}
 
-	for (child = xmlnode_get_child(query, "feature"); child; 
+	for (child = xmlnode_get_child(query, "feature"); child;
 	     child = xmlnode_get_next_twin(child)) {
 		const char *var;
 		var = xmlnode_get_attrib(child, "var");
@@ -324,11 +324,16 @@
 	for(child = xmlnode_get_child(query, "item"); child;
 			child = xmlnode_get_next_twin(child)) {
 		JabberIq *iq;
-		const char *jid;
+		const char *jid, *node;
 
 		if(!(jid = xmlnode_get_attrib(child, "jid")))
 			continue;
 
+		/* we don't actually care about the specific nodes,
+		 * so we won't query them */
+		if((node = xmlnode_get_attrib(child, "node")))
+			continue;
+
 		iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info");
 		xmlnode_set_attrib(iq->node, "to", jid);
 		jabber_iq_send(iq);
--- a/libpurple/protocols/jabber/presence.c	Mon May 28 19:08:05 2007 +0000
+++ b/libpurple/protocols/jabber/presence.c	Tue May 29 04:43:56 2007 +0000
@@ -106,11 +106,12 @@
 		return;
 
 	disconnected = purple_account_is_disconnected(account);
-	primitive = purple_status_type_get_primitive(purple_status_get_type(status));
 
 	if(disconnected)
 		return;
 
+	primitive = purple_status_type_get_primitive(purple_status_get_type(status));
+
 	gc = purple_account_get_connection(account);
 	js = gc->proto_data;
 
--- a/libpurple/protocols/jabber/si.c	Mon May 28 19:08:05 2007 +0000
+++ b/libpurple/protocols/jabber/si.c	Tue May 29 04:43:56 2007 +0000
@@ -26,6 +26,7 @@
 #include "cipher.h"
 #include "debug.h"
 #include "ft.h"
+#include "request.h"
 #include "network.h"
 #include "notify.h"
 
@@ -769,6 +770,36 @@
 	}
 }
 
+static void resource_select_cancel_cb(PurpleXfer *xfer, PurpleRequestFields *fields)
+{
+	purple_xfer_cancel_local(xfer);
+}
+
+static void do_transfer_send(PurpleXfer *xfer, const char *resource)
+{
+	JabberSIXfer *jsx = xfer->data;
+	char **who_v = g_strsplit(xfer->who, "/", 2);
+	char *who;
+
+	who = g_strdup_printf("%s/%s", who_v[0], resource);
+	g_strfreev(who_v);
+	g_free(xfer->who);
+	xfer->who = who;
+	jabber_disco_info_do(jsx->js, who,
+			jabber_si_xfer_send_disco_cb, xfer);
+}
+
+static void resource_select_ok_cb(PurpleXfer *xfer, PurpleRequestFields *fields)
+{
+	PurpleRequestField *field = purple_request_fields_get_field(fields, "resource");
+	int selected_id = purple_request_field_choice_get_value(field);
+	GList *labels = purple_request_field_choice_get_labels(field);
+
+	const char *selected_label = g_list_nth_data(labels, selected_id);
+
+	do_transfer_send(xfer, selected_label);
+}
+
 static void jabber_si_xfer_init(PurpleXfer *xfer)
 {
 	JabberSIXfer *jsx = xfer->data;
@@ -776,26 +807,65 @@
 	if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
 		JabberBuddy *jb;
 		JabberBuddyResource *jbr = NULL;
+		char *resource;
+
+		if(NULL != (resource = jabber_get_resource(xfer->who))) {
+			/* they've specified a resource, no need to ask or
+			 * default or anything, just do it */
+
+			do_transfer_send(xfer, resource);
+			g_free(resource);
+		}
 
 		jb = jabber_buddy_find(jsx->js, xfer->who, TRUE);
-		/* XXX */
-		if(!jb)
-			return;
+
+		if(!jb || !jb->resources) {
+			/* no resources online, we're trying to send to someone
+			 * whose presence we're not subscribed to, or
+			 * someone who is offline.  Let's inform the user */
+			char *msg;
 
-		/* XXX: for now, send to the first resource available */
-		if(jb->resources != NULL) {
-			char **who_v = g_strsplit(xfer->who, "/", 2);
-			char *who;
+			if(!jb) {
+				msg = g_strdup_printf(_("Unable to send file to %s, invalid JID"), xfer->who);
+			} else if(jb->subscription & JABBER_SUB_TO) {
+				msg = g_strdup_printf(_("Unable to send file to %s, user is not online"), xfer->who);
+			} else {
+				msg = g_strdup_printf(_("Unable to send file to %s, not subscribed to user presence"), xfer->who);
+			}
+
+			purple_notify_error(jsx->js->gc, _("File Send Failed"), _("File Send Failed"), msg);
+			g_free(msg);
+		} else if(g_list_length(jb->resources) == 1) {
+			/* only 1 resource online (probably our most common case)
+			 * so no need to ask who to send to */
+			jbr = jb->resources->data;
+
+			do_transfer_send(xfer, jbr->name);
 
-			jbr = jabber_buddy_find_resource(jb, NULL);
-			who = g_strdup_printf("%s/%s", who_v[0], jbr->name);
-			g_strfreev(who_v);
-			g_free(xfer->who);
-			xfer->who = who;
-			jabber_disco_info_do(jsx->js, who,
-					jabber_si_xfer_send_disco_cb, xfer);
 		} else {
-			return; /* XXX: ick */
+			/* we've got multiple resources, we need to pick one to send to */
+			GList *l;
+			char *msg = g_strdup_printf(_("Please select which resource of %s you would like to send a file to"), xfer->who);
+			PurpleRequestFields *fields = purple_request_fields_new();
+			PurpleRequestField *field = purple_request_field_choice_new("resource", _("Resource"), 0);
+			PurpleRequestFieldGroup *group = purple_request_field_group_new(NULL);
+
+			for(l = jb->resources; l; l = l->next)
+			{
+				jbr = l->data;
+
+				purple_request_field_choice_add(field, jbr->name);
+			}
+
+			purple_request_field_group_add_field(group, field);
+
+			purple_request_fields_add_group(fields, group);
+
+			purple_request_fields(jsx->js->gc, _("Select a Resource"), msg, NULL, fields,
+					_("Send File"), G_CALLBACK(resource_select_ok_cb), _("Cancel"), G_CALLBACK(resource_select_cancel_cb),
+					jsx->js->gc->account, xfer->who, NULL, xfer);
+
+			g_free(msg);
 		}
 	} else {
 		xmlnode *si, *feature, *x, *field, *value;