changeset 29383:9af18bfb16aa

Add support for dropping an image on the Custom Smiley window to add that image. Based on theme DND, but I wonder if someone knows how to get it to accept only image-formats.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sun, 07 Feb 2010 08:41:47 +0000
parents b066ad9bbcc3
children acf7f7637669
files ChangeLog pidgin/gtksmiley.c
diffstat 2 files changed, 101 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Feb 07 08:22:11 2010 +0000
+++ b/ChangeLog	Sun Feb 07 08:41:47 2010 +0000
@@ -52,6 +52,7 @@
 	* Correctly handle a multiline text field being required in a
 	  request form.  (Thanks to Florian Zeitz for finding this problem)
 	* Search friends by email-addresses in the buddy list. (Luoh Ren-Shan)
+	* Allow dropping an image on Custom Smiley window to add a new one.
 
 	Finch:
 	* Rebindable 'move-first' and 'move-last' actions for tree widgets. So
--- a/pidgin/gtksmiley.c	Sun Feb 07 08:22:11 2010 +0000
+++ b/pidgin/gtksmiley.c	Sun Feb 07 08:41:47 2010 +0000
@@ -685,11 +685,106 @@
 	smiley_edit_iter(data, iter);
 }
 
+static void
+smiley_got_url(PurpleUtilFetchUrlData *url_data, gpointer user_data,
+		const gchar *smileydata, size_t len, const gchar *error_message)
+{
+	SmileyManager *dialog = user_data;
+	FILE *f;
+	gchar *path;
+	size_t wc;
+	GError *err = NULL;
+	PidginSmiley *ps;
+	GdkPixbuf *image;
+
+	if ((error_message != NULL) || (len == 0)) {
+		return;
+	}
+
+	f = purple_mkstemp(&path, TRUE);
+	wc = fwrite(smileydata, len, 1, f);
+	if (wc != 1) {
+		purple_debug_warning("smiley_got_url", "Unable to write smiley data.\n");
+		fclose(f);
+		g_unlink(path);
+		g_free(path);
+		return;
+	}
+	fclose(f);
+
+	image = gdk_pixbuf_new_from_file(path, &err);
+	g_unlink(path);
+	g_free(path);
+	if (err) {
+		g_error_free(err);
+		return;
+	}
+
+	ps = pidgin_smiley_edit(dialog->window, NULL);
+	pidgin_smiley_editor_set_image(ps, image);
+	pidgin_smiley_editor_set_data(ps, g_memdup(smileydata, len), len);
+}
+
+static void
+smiley_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
+		GtkSelectionData *sd, guint info, guint t, gpointer user_data)
+{
+	SmileyManager *dialog = user_data;
+	gchar *name = g_strchomp((gchar *)sd->data);
+
+	if ((sd->length >= 0) && (sd->format == 8)) {
+		/* Well, it looks like the drag event was cool.
+		 * Let's do something with it */
+
+		if (!g_ascii_strncasecmp(name, "file://", 7)) {
+			GError *converr = NULL;
+			gchar *tmp;
+			PidginSmiley *ps;
+			/* It looks like we're dealing with a local file. Let's
+			 * just try and read it */
+			if(!(tmp = g_filename_from_uri(name, NULL, &converr))) {
+				purple_debug_error("smiley dnd", "%s\n",
+						   (converr ? converr->message :
+							"g_filename_from_uri error"));
+				return;
+			}
+			ps = pidgin_smiley_edit(dialog->window, NULL);
+			do_add_file_cb(tmp, ps);
+			if (gtk_image_get_pixbuf(GTK_IMAGE(ps->smiley_image)) == NULL)
+				gtk_dialog_response(GTK_DIALOG(ps->parent), GTK_RESPONSE_CANCEL);
+			g_free(tmp);
+		} else if (!g_ascii_strncasecmp(name, "http://", 7)) {
+			/* Oo, a web drag and drop. This is where things
+			 * will start to get interesting */
+			purple_util_fetch_url(name, TRUE, NULL, FALSE, smiley_got_url, dialog);
+		} else if (!g_ascii_strncasecmp(name, "https://", 8)) {
+			/* purple_util_fetch_url() doesn't support HTTPS */
+			char *tmp = g_strdup(name + 1);
+			tmp[0] = 'h';
+			tmp[1] = 't';
+			tmp[2] = 't';
+			tmp[3] = 'p';
+
+			purple_util_fetch_url(tmp, TRUE, NULL, FALSE, smiley_got_url, dialog);
+			g_free(tmp);
+		}
+
+		gtk_drag_finish(dc, TRUE, FALSE, t);
+	}
+
+	gtk_drag_finish(dc, FALSE, FALSE, t);
+}
+
 static GtkWidget *smiley_list_create(SmileyManager *dialog)
 {
 	GtkWidget *sw;
 	GtkWidget *treeview;
 	GtkTreeSelection *sel;
+	GtkTargetEntry te[3] = {
+		{"text/plain", 0, 0},
+		{"text/uri-list", 0, 1},
+		{"STRING", 0, 2}
+	};
 
 	sw = gtk_scrolled_window_new(NULL, NULL);
 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
@@ -720,6 +815,11 @@
 	g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(smile_selected_cb), dialog);
 	g_signal_connect(G_OBJECT(treeview), "row_activated", G_CALLBACK(smiley_edit_cb), dialog);
 
+	gtk_drag_dest_set(treeview,
+	                  GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
+	                  te, G_N_ELEMENTS(te), GDK_ACTION_COPY | GDK_ACTION_MOVE);
+	g_signal_connect(G_OBJECT(treeview), "drag_data_received", G_CALLBACK(smiley_dnd_recv), dialog);
+
 	gtk_widget_show(treeview);
 
 	add_columns(treeview, dialog);