changeset 7706:e6244f1a19a5

[gaim-migrate @ 8351] Chip did this. He implemented the application/x-im-contact MIME type for buddy list drag-n-drops. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Tue, 02 Dec 2003 23:59:23 +0000
parents 401deb1e1085
children 17756d5dcfdf
files src/gtkblist.c
diffstat 1 files changed, 240 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/gtkblist.c	Tue Dec 02 23:52:47 2003 +0000
+++ b/src/gtkblist.c	Tue Dec 02 23:59:23 2003 +0000
@@ -1103,7 +1103,91 @@
 
 		gtk_tree_path_free(sourcerow);
 	}
-
+	else if (data->target == gdk_atom_intern("application/x-im-contact",
+											 FALSE)) {
+
+		GtkTreeRowReference *ref;
+		GtkTreePath *sourcerow;
+		GtkTreeIter iter;
+		GaimBlistNode *node = NULL;
+		GaimBuddy *buddy;
+		GaimConnection *gc;
+		GValue val = {0};
+		const char *prpl_id;
+		GString *str;
+		const char *protocol;
+		char *mime_str;
+
+		ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row");
+		sourcerow = gtk_tree_row_reference_get_path(ref);
+
+		if (!sourcerow)
+			return;
+
+		gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter,
+								sourcerow);
+		gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), &iter,
+								 NODE_COLUMN, &val);
+
+		node = g_value_get_pointer(&val);
+
+		if (GAIM_BLIST_NODE_IS_CONTACT(node))
+		{
+			buddy = gaim_contact_get_priority_buddy((GaimContact *)node);
+		}
+		else if (!GAIM_BLIST_NODE_IS_BUDDY(node))
+		{
+			gtk_tree_path_free(sourcerow);
+			return;
+		}
+		else
+		{
+			buddy = (GaimBuddy *)node;
+		}
+
+		prpl_id = gaim_account_get_protocol_id(buddy->account);
+
+		gc = gaim_account_get_connection(buddy->account);
+
+		if (gc == NULL)
+		{
+			gtk_tree_path_free(sourcerow);
+			return;
+		}
+
+		protocol =
+			GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->list_icon(buddy->account,
+														   buddy);
+
+		str = g_string_new(NULL);
+		g_string_printf(str,
+			"MIME-Version: 1.0\r\n"
+			"Content-Type: application/x-im-contact\r\n"
+			"X-IM-Protocol: %s\r\n"
+			"X-IM-Username: %s\r\n",
+			protocol,
+			buddy->name);
+
+		if (buddy->alias != NULL)
+		{
+			g_string_append_printf(str,
+				"X-IM-Alias: %s\r\n",
+				buddy->alias);
+		}
+
+		str = g_string_append(str, "\r\n");
+
+		mime_str = g_string_free(str, FALSE);
+
+		gtk_selection_data_set(data,
+					gdk_atom_intern("application/x-im-contact", FALSE),
+					8, /* bits */
+					mime_str,
+					strlen(mime_str) + 1);
+
+		g_free(mime_str);
+		gtk_tree_path_free(sourcerow);
+	}
 }
 
 static void gaim_gtk_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
@@ -1259,6 +1343,161 @@
 			gaim_blist_save();
 		}
 	}
+	else if (sd->target == gdk_atom_intern("application/x-im-contact",
+										   FALSE) && sd->data)
+	{
+		GaimGroup *group = NULL;
+		GtkTreePath *path = NULL;
+		GtkTreeViewDropPosition position;
+		char *protocol = NULL;
+		char *username = NULL;
+		char *alias = NULL;
+		char *contact_str;
+		char *c, *s;
+
+		if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget),
+											  x, y, &path, &position))
+		{
+			GtkTreeIter iter;
+			GaimBlistNode *node;
+			GValue val = {0};
+
+			gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel),
+									&iter, path);
+			gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel),
+									  &iter, NODE_COLUMN, &val);
+			node = g_value_get_pointer(&val);
+
+			if (GAIM_BLIST_NODE_IS_BUDDY(node))
+			{
+				group = (GaimGroup *)node->parent->parent;
+			}
+			else if (GAIM_BLIST_NODE_IS_CHAT(node) ||
+					 GAIM_BLIST_NODE_IS_CONTACT(node))
+			{
+				group = (GaimGroup *)node->parent;
+			}
+			else if (GAIM_BLIST_NODE_IS_GROUP(node))
+			{
+				group = (GaimGroup *)node;
+			}
+		}
+
+		contact_str = g_strndup(sd->data, sd->length);
+
+		s = contact_str;
+
+		while (*s != '\r' && *s != '\n' && *s != '\0')
+		{
+			char *key, *value;
+
+			key = s;
+
+			/* Grab the key */
+			while (*s != '\r' && *s != '\n' && *s != '\0' && *s != ' ')
+				s++;
+
+			if (*s == '\r') s++;
+
+			if (*s == '\n')
+			{
+				s++;
+				continue;
+			}
+
+			if (*s != '\0') *s++ = '\0';
+
+			/* Clear past any whitespace */
+			while (*s != '\0' && *s == ' ')
+				s++;
+
+			/* Now let's grab until the end of the line. */
+			value = s;
+
+			while (*s != '\r' && *s != '\n' && *s != '\0')
+				s++;
+
+			if (*s == '\r') *s++ = '\0';
+			if (*s == '\n') *s++ = '\0';
+
+			if ((c = strchr(key, ':')) != NULL)
+			{
+				if (!g_ascii_strcasecmp(key, "X-IM-Username:"))
+					username = g_strdup(value);
+				else if (!g_ascii_strcasecmp(key, "X-IM-Protocol:"))
+					protocol = g_strdup(value);
+				else if (!g_ascii_strcasecmp(key, "X-IM-Alias:"))
+					alias = g_strdup(value);
+			}
+		}
+
+		if (username != NULL && protocol != NULL)
+		{
+			GaimAccount *account = NULL;
+			GList *l;
+			const char *protoname;
+
+			for (l = gaim_connections_get_all(); l != NULL; l = l->next)
+			{
+				GaimConnection *gc = (GaimConnection *)l->data;
+				account = gaim_connection_get_account(gc);
+
+				protoname =
+					GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->list_icon(account,
+																   NULL);
+
+				if (!strcmp(protoname, protocol))
+					break;
+
+				account = NULL;
+			}
+
+			/* Special case for AIM and ICQ */
+			if (account == NULL && (!strcmp(protocol, "aim") ||
+									!strcmp(protocol, "icq")))
+			{
+
+				for (l = gaim_connections_get_all(); l != NULL; l = l->next)
+				{
+					GaimConnection *gc = (GaimConnection *)l->data;
+					account = gaim_connection_get_account(gc);
+
+					protoname =
+						GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->list_icon(account,
+																	   NULL);
+
+					if (!strcmp(protoname, "aim") || !strcmp(protoname, "icq"))
+						break;
+
+					account = NULL;
+				}				
+			}
+
+			if (account == NULL)
+			{
+				gaim_notify_error(NULL, NULL,
+					_("You are not currently signed on with an account that "
+					  "can add that buddy."), NULL);
+			}
+			else
+			{
+				gaim_blist_request_add_buddy(account, username,
+											 (group ? group->name : NULL),
+											 alias);
+			}
+		}
+
+		if (username != NULL) g_free(username);
+		if (protocol != NULL) g_free(protocol);
+		if (alias    != NULL) g_free(alias);
+
+		g_free(contact_str);
+
+		if (path != NULL)
+			gtk_tree_path_free(path);
+
+		gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
+	}
 }
 
 static void gaim_gtk_blist_paint_tip(GtkWidget *widget, GdkEventExpose *event, GaimBlistNode *node)