changeset 4702:cb5b23dfd82b

[gaim-migrate @ 5013] Started on buddy list drag-n-drop. This will be useful mostly for editing the buddy list but I decided to sleep before doing that. You can drag a buddy into a conversation window now, though. Which is cool. But, even that's not complete yet. I'll have fun tomorrow. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Tue, 11 Mar 2003 07:57:53 +0000
parents ac7ca2bd6d4f
children e4dda06a3143
files src/buddy.c src/gtkconv.c src/prefs.c
diffstat 3 files changed, 72 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/buddy.c	Tue Mar 11 03:59:42 2003 +0000
+++ b/src/buddy.c	Tue Mar 11 07:57:53 2003 +0000
@@ -178,6 +178,7 @@
 	GtkTreeIter iter;
 	GtkWidget *menu, *menuitem;
 	GtkWidget *image;
+	GtkTreeSelection *sel;
 	GList *list;
 	struct prpl *prpl;
 
@@ -232,7 +233,12 @@
 	
 	gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, event->time);
 
-	return FALSE;
+#if (1)  /* This code only exists because GTK doesn't work.  If we return FALSE here, as would be normal
+	  * the event propoagates down and somehow gets interpreted as the start of a drag event. */
+	sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv));
+	gtk_tree_selection_select_path(sel, path);
+	return TRUE;
+#endif
 }
 
 static void gaim_gtk_blist_reordered_cb(GtkTreeModel *model,
@@ -284,6 +290,43 @@
 	}
 }
 
+static void gaim_gtk_blist_drag_data_get_cb (GtkWidget *widget,
+					     GdkDragContext *dc,
+					     GtkSelectionData *data,
+					     guint info,
+					     guint time,
+					     gpointer *null)
+{
+	if (data->target == gdk_atom_intern("GAIM_BUDDY", FALSE)) {
+		GtkTreeRowReference *ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row");
+		GtkTreePath *sourcerow = gtk_tree_row_reference_get_path(ref);
+		GtkTreeIter iter;
+		GaimBlistNode *node = NULL;
+		GValue val = {0};
+		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_BUDDY(node)) 
+			gtk_selection_data_set (data,
+						gdk_atom_intern ("GAIM_BUDDY", FALSE),
+						8, /* bits */
+						(void*)&node,
+						sizeof (node));
+	}
+		
+}
+
+static void gaim_gtk_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
+			  GtkSelectionData *sd, guint info, guint t)
+{	
+	if (sd->target == gdk_atom_intern("GAIM_BUDDY", FALSE)) {
+		struct buddy *b = NULL;
+		GtkTreePath *path = NULL;
+		memcpy(&b, sd->data, sizeof(b));
+		gtk_tree_view_get_dest_row_at_pos(widget, x, y, &path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
+	}
+}
+
 /***************************************************
  *            Crap                                 *
  ***************************************************/
@@ -553,6 +596,8 @@
 	node->ui_data = g_new0(struct gaim_gtk_blist_node, 1);
 }
 
+enum {DRAG_BUDDY, DRAG_ROW};
+
 static void gaim_gtk_blist_show(struct gaim_buddy_list *list)
 {
 	GtkItemFactory *ift;
@@ -561,6 +606,8 @@
 	GtkWidget *sw;
 	GtkWidget *button;
 	GtkSizeGroup *sg;
+ 	GtkTargetEntry gte[] = {{"GAIM_BUDDY", GTK_TARGET_SAME_APP, DRAG_ROW},
+				{"application/x-im-contact", 0, DRAG_BUDDY}};
 
 	if (gtkblist) {
 		gtk_widget_show(gtkblist->window);
@@ -600,10 +647,17 @@
 
 	gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, 
 						 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER);
-	/* This is broken because GTK is broken
- 	g_signal_connect(G_OBJECT(gtkblist->treemodel), "row-reordered", gaim_gtk_blist_reordered_cb, NULL); */
- 
+
 	gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel));
+	
+	/* Set up dnd */
+	gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(gtkblist->treeview), GDK_BUTTON1_MASK, gte,
+					       2, GDK_ACTION_COPY);
+	gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(gtkblist->treeview), gte, 2, 
+					     GDK_ACTION_COPY | GDK_ACTION_MOVE);
+	g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-received", gaim_gtk_blist_drag_data_rcv_cb, NULL);
+	g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-get", gaim_gtk_blist_drag_data_get_cb, NULL);
+	
 
 	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gtkblist->treeview), FALSE);
 
--- a/src/gtkconv.c	Tue Mar 11 03:59:42 2003 +0000
+++ b/src/gtkconv.c	Tue Mar 11 07:57:53 2003 +0000
@@ -3198,10 +3198,16 @@
 
 static void
 conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
-			  GtkSelectionData *sd, guint info, guint t, gpointer data)
+			  GtkSelectionData *sd, guint info, guint t)
 {
-	do_error_dialog("MWAHAHAHA! I AM A TROLL! I AM GOING TO EAT YOU!",
-					NULL, GAIM_WARNING);
+	if (sd->target == gdk_atom_intern("GAIM_BUDDY", FALSE)) {
+		struct buddy *b = NULL;
+		memcpy(&b, sd->data, sizeof(b));
+		gaim_conversation_new(GAIM_CONV_IM, b->account, b->name);
+	}
+
+		/* do_error_dialog("MWAHAHAHA! I AM A TROLL! I AM GOING TO EAT YOU!",
+		   NULL, GAIM_WARNING); */
 }
 
 /**************************************************************************
@@ -3335,8 +3341,9 @@
 static const GtkTargetEntry te[] =
 {
 	{"text/plain", 0, 0},
-	{"text/uri-list", 1, 0},
-	{"STRING", 2, 0}
+	{"text/uri-list", 0, 1},
+	{"GAIM_BUDDY", 0, 2},
+	{"STRING", 0, 3}
 };
 
 static void
@@ -3407,8 +3414,7 @@
 						  GDK_ACTION_COPY);
 		gtk_drag_dest_set(gtkconv->imhtml,
 						  GTK_DEST_DEFAULT_MOTION |
-						  GTK_DEST_DEFAULT_HIGHLIGHT |
-						  GTK_DEST_DEFAULT_DROP,
+				                  GTK_DEST_DEFAULT_DROP,
 						  te, sizeof(te) / sizeof(GtkTargetEntry),
 						  GDK_ACTION_DEFAULT | GDK_ACTION_COPY | GDK_ACTION_MOVE);
 		gtk_drag_dest_set(gtkconv->entry,
--- a/src/prefs.c	Tue Mar 11 03:59:42 2003 +0000
+++ b/src/prefs.c	Tue Mar 11 07:57:53 2003 +0000
@@ -344,7 +344,7 @@
 	GtkTreeSelection *sel;
 	GtkTreePath *path = NULL;
 	GtkWidget *label;
-	GtkTargetEntry te[3] = {{"text/plain", 0, 0},{"text/uri-list", 1, 0},{"STRING", 2, 0}};
+	GtkTargetEntry te[3] = {{"text/plain", 0, 0},{"text/uri-list", 0, 1},{"STRING", 0, 2}};
 
 	ret = gtk_vbox_new(FALSE, 18);
 	gtk_container_set_border_width (GTK_CONTAINER (ret), 12);