changeset 29385:acf7f7637669

merge of '147a2b8b067bccc514ecf55f2a4454f6df40e9bb' and '3b462776d19577ac9844ac289becb8e1626d9dd9'
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sun, 07 Feb 2010 08:43:26 +0000
parents ad4960c2df28 (current diff) 9af18bfb16aa (diff)
children e1dd357fc494
files
diffstat 3 files changed, 107 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Feb 07 08:31:41 2010 +0000
+++ b/ChangeLog	Sun Feb 07 08:43:26 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:31:41 2010 +0000
+++ b/pidgin/gtksmiley.c	Sun Feb 07 08:43:26 2010 +0000
@@ -74,7 +74,8 @@
 static void
 pidgin_smiley_destroy(PidginSmiley *smiley)
 {
-	g_object_set_data(G_OBJECT(smiley->smiley), "edit-dialog", NULL);
+	if (smiley->smiley)
+		g_object_set_data(G_OBJECT(smiley->smiley), "edit-dialog", NULL);
 	gtk_widget_destroy(smiley->parent);
 	g_free(smiley->filename);
 	if (smiley->custom_pixbuf)
@@ -403,7 +404,8 @@
 			smiley ? GTK_STOCK_SAVE : GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT,
 			NULL);
 	s->parent = window;
-	g_object_set_data(G_OBJECT(smiley), "edit-dialog", window);
+	if (smiley)
+		g_object_set_data(G_OBJECT(smiley), "edit-dialog", window);
 
 	gtk_container_set_border_width(GTK_CONTAINER(window), PIDGIN_HIG_BORDER);
 
@@ -505,7 +507,7 @@
 }
 
 void
-pidgin_smiley_editor_set_data(PidginSmiley *editor, gpointer *data, gsize datasize)
+pidgin_smiley_editor_set_data(PidginSmiley *editor, gpointer data, gsize datasize)
 {
 	editor->data = data;
 	editor->datasize = datasize;
@@ -683,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),
@@ -718,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);
--- a/pidgin/gtksmiley.h	Sun Feb 07 08:31:41 2010 +0000
+++ b/pidgin/gtksmiley.h	Sun Feb 07 08:43:26 2010 +0000
@@ -109,6 +109,6 @@
  *
  * @since 2.6.0
  */
-void pidgin_smiley_editor_set_data(PidginSmiley *editor, gpointer *data, gsize datasize);
+void pidgin_smiley_editor_set_data(PidginSmiley *editor, gpointer data, gsize datasize);
 
 #endif /* PIDGIN_GTKSMILEY_H */