changeset 5620:c9724982ce45

[gaim-migrate @ 6027] The new account dialog rocks. committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Sun, 01 Jun 2003 01:30:31 +0000
parents 117e23960e48
children f291874c418e
files src/account.c src/gtkaccount.c
diffstat 2 files changed, 136 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/account.c	Sat May 31 22:58:06 2003 +0000
+++ b/src/account.c	Sun Jun 01 01:30:31 2003 +0000
@@ -818,7 +818,7 @@
 	GList *l;
 
 	g_return_if_fail(account != NULL);
-	g_return_if_fail(new_index > 0 && new_index < g_list_length(accounts));
+	g_return_if_fail(new_index >= 0 && new_index <= g_list_length(accounts));
 
 	index = g_list_index(accounts, account);
 
--- a/src/gtkaccount.c	Sat May 31 22:58:06 2003 +0000
+++ b/src/gtkaccount.c	Sun Jun 01 01:30:31 2003 +0000
@@ -27,6 +27,15 @@
 #include "stock.h"
 #include "gtkblist.h"
 
+#ifdef _WIN32       
+# include <gdk/gdkwin32.h>
+#else
+# include <unistd.h>
+# include <gdk/gdkx.h>
+#endif
+
+#include <string.h>
+
 enum
 {
 	COLUMN_ICON,
@@ -47,6 +56,8 @@
 
 	GtkTreeViewColumn *screenname_col;
 
+	GtkTreeIter drag_iter;
+
 } AccountsDialog;
 
 static AccountsDialog *accounts_dialog = NULL;
@@ -74,6 +85,116 @@
 	}
 }
 
+static void
+__drag_data_get_cb(GtkWidget *widget, GdkDragContext *ctx,
+				   GtkSelectionData *data, guint info, guint time,
+				   AccountsDialog *dialog)
+{
+	if (data->target == gdk_atom_intern("GAIM_ACCOUNT", FALSE)) {
+		GtkTreeRowReference *ref;
+		GtkTreePath *source_row;
+		GtkTreeIter iter;
+		GaimAccount *account = NULL;
+		GValue val = {0};
+
+		ref = g_object_get_data(G_OBJECT(ctx), "gtk-tree-view-source-row");
+		source_row = gtk_tree_row_reference_get_path(ref);
+
+		if (source_row == NULL)
+			return;
+
+		gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter,
+								source_row);
+		gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter,
+								 COLUMN_DATA, &val);
+
+		dialog->drag_iter = iter;
+
+		account = g_value_get_pointer(&val);
+
+		gtk_selection_data_set(data, gdk_atom_intern("GAIM_ACCOUNT", FALSE),
+							   8, (void *)&account, sizeof(account));
+
+		gtk_tree_path_free(source_row);
+	}
+}
+
+static void
+__drag_data_received_cb(GtkWidget *widget, GdkDragContext *ctx,
+						guint x, guint y, GtkSelectionData *sd,
+						guint info, guint t, AccountsDialog *dialog)
+{
+	if (sd->target == gdk_atom_intern("GAIM_ACCOUNT", FALSE) && sd->data) {
+		size_t dest_index;
+		GaimAccount *a = NULL;
+		GtkTreePath *path = NULL;
+		GtkTreeViewDropPosition position;
+
+		memcpy(&a, sd->data, sizeof(a));
+
+		if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y,
+											  &path, &position)) {
+
+			GtkTreeIter iter;
+			GaimAccount *account;
+			GValue val = {0};
+
+			gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path);
+			gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter,
+									 COLUMN_DATA, &val);
+
+			account = g_value_get_pointer(&val);
+
+			switch (position) {
+				case GTK_TREE_VIEW_DROP_AFTER:
+				case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
+					gaim_debug(GAIM_DEBUG_MISC, "gtkaccount",
+							   "after\n");
+					gtk_list_store_move_after(dialog->model,
+											  &dialog->drag_iter, &iter);
+					dest_index = g_list_index(gaim_accounts_get_all(),
+											  account) + 1;
+					break;
+
+				case GTK_TREE_VIEW_DROP_BEFORE:
+				case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
+					gaim_debug(GAIM_DEBUG_MISC, "gtkaccount",
+							   "before\n");
+					dest_index = g_list_index(gaim_accounts_get_all(),
+											  account);
+
+					gaim_debug(GAIM_DEBUG_MISC, "gtkaccount",
+							   "iter = %p\n", &iter);
+					gaim_debug(GAIM_DEBUG_MISC, "gtkaccount",
+							   "account = %s\n",
+							   gaim_account_get_username(account));
+
+					/*
+					 * Somebody figure out why inserting before the first
+					 * account sometimes moves to the end, please :(
+					 */
+					if (dest_index == 0) {
+						gtk_list_store_move_after(dialog->model,
+												  &dialog->drag_iter, &iter);
+						gtk_list_store_swap(dialog->model, &iter,
+											&dialog->drag_iter);
+					}
+					else {
+						gtk_list_store_move_before(dialog->model,
+												   &dialog->drag_iter, &iter);
+					}
+
+					break;
+
+				default:
+					return;
+			}
+
+			gaim_accounts_reorder(a, dest_index);
+		}
+	}
+}
+
 static gint
 __window_destroy_cb(GtkWidget *w, GdkEvent *event, AccountsDialog *dialog)
 {
@@ -279,6 +400,7 @@
 {
 	GtkWidget *sw;
 	GtkWidget *treeview;
+	GtkTargetEntry gte[] = {{"GAIM_ACCOUNT", GTK_TARGET_SAME_APP, 0}};
 
 	/* Create the scrolled window. */
 	sw = gtk_scrolled_window_new(0, 0);
@@ -298,7 +420,6 @@
 	/* And now the actual treeview */
 	treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model));
 	gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
-	gtk_tree_view_set_reorderable(GTK_TREE_VIEW(treeview), TRUE);
 	gtk_tree_selection_set_mode(
 			gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)),
 			GTK_SELECTION_MULTIPLE);
@@ -310,6 +431,19 @@
 
 	__populate_accounts_list(dialog);
 
+	/* Setup DND. I wanna be an orc! */
+	gtk_tree_view_enable_model_drag_source(
+			GTK_TREE_VIEW(treeview), GDK_BUTTON1_MASK, gte,
+			2, GDK_ACTION_COPY);
+	gtk_tree_view_enable_model_drag_dest(
+			GTK_TREE_VIEW(treeview), gte, 2,
+			GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
+	g_signal_connect(G_OBJECT(treeview), "drag-data-received",
+					 G_CALLBACK(__drag_data_received_cb), dialog);
+	g_signal_connect(G_OBJECT(treeview), "drag-data-get",
+					 G_CALLBACK(__drag_data_get_cb), dialog);
+
 	return sw;
 }