diff pidgin/gtkimhtml.c @ 16953:ab45289d2c36

Allow saving custom smileys by right-clicking on them. And use the custom smileys only on the received messages, not for the system/etc. messages.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Wed, 09 May 2007 01:21:15 +0000
parents a32325c04158
children 53e757c37e06
line wrap: on
line diff
--- a/pidgin/gtkimhtml.c	Wed May 09 00:02:17 2007 +0000
+++ b/pidgin/gtkimhtml.c	Wed May 09 01:21:15 2007 +0000
@@ -1872,18 +1872,8 @@
 }
 
 static GdkPixbufAnimation *
-gtk_smiley_tree_image (GtkIMHtml     *imhtml,
-		       const gchar   *sml,
-		       const gchar   *text)
+gtk_smiley_get_image(GtkIMHtmlSmiley *smiley)
 {
-
-	GtkIMHtmlSmiley *smiley;
-
-	smiley = gtk_imhtml_smiley_get(imhtml,sml,text);
-
-	if (!smiley)
-		return NULL;
-
 	if (!smiley->icon && smiley->file) {
 		smiley->icon = gdk_pixbuf_animation_new_from_file(smiley->file, NULL);
 	} else if (!smiley->icon && smiley->loader) {
@@ -1895,6 +1885,21 @@
 	return smiley->icon;
 }
 
+static GdkPixbufAnimation *
+gtk_smiley_tree_image (GtkIMHtml     *imhtml,
+		       const gchar   *sml,
+		       const gchar   *text)
+{
+	GtkIMHtmlSmiley *smiley;
+
+	smiley = gtk_imhtml_smiley_get(imhtml,sml,text);
+
+	if (!smiley)
+		return NULL;
+
+	return gtk_smiley_get_image(smiley);
+}
+
 #define VALID_TAG(x)	if (!g_ascii_strncasecmp (string, x ">", strlen (x ">"))) {	\
 				*tag = g_strndup (string, strlen (x));		\
 				*len = strlen (x) + 1;				\
@@ -3363,6 +3368,29 @@
 		return FALSE; /* Let clicks go through if we didn't catch anything */
 
 }
+
+static gboolean gtk_imhtml_smiley_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlSmiley *smiley)
+{
+	GdkPixbufAnimation *anim = NULL;
+	GdkPixbuf *pix = NULL;
+	GtkIMHtmlScalable *image = NULL;
+	gboolean ret;
+	
+	if (event->type != GDK_BUTTON_RELEASE || ((GdkEventButton*)event)->button != 3)
+		return FALSE;
+
+	anim = gtk_smiley_get_image(smiley);
+	if (!anim)
+		return FALSE;
+
+	pix = gdk_pixbuf_animation_get_static_image(anim);
+	image = gtk_imhtml_image_new(pix, NULL, 0);
+	ret = gtk_imhtml_image_clicked(w, event, (GtkIMHtmlImage*)image);
+	g_object_set_data_full(G_OBJECT(w), "image-data", image, (GDestroyNotify)gtk_imhtml_image_free);
+	g_object_unref(G_OBJECT(pix));
+	return ret;
+}
+
 void gtk_imhtml_image_free(GtkIMHtmlScalable *scale)
 {
 	GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale;
@@ -4378,9 +4406,10 @@
 	GdkPixbuf *pixbuf = NULL;
 	GdkPixbufAnimation *annipixbuf = NULL;
 	GtkWidget *icon = NULL;
-	GtkTextChildAnchor *anchor;
+	GtkTextChildAnchor *anchor = NULL;
 	char *unescaped = purple_unescape_html(smiley);
 	GtkIMHtmlSmiley *imhtml_smiley = gtk_imhtml_smiley_get(imhtml, sml, unescaped);
+	GtkWidget *ebox = NULL;
 
 	if (imhtml->format_functions & GTK_IMHTML_SMILEY) {
 		annipixbuf = gtk_smiley_tree_image(imhtml, sml, unescaped);
@@ -4397,6 +4426,7 @@
 					if (anim) {
 						GdkPixbuf *pb = gdk_pixbuf_animation_get_static_image(anim);
 						gtk_image_set_from_pixbuf(image, pb);
+						g_object_unref(G_OBJECT(pb));
 					}
 				} else {
  					imhtml->num_animations++;
@@ -4407,6 +4437,12 @@
 		}
 	}
 
+	if (imhtml_smiley->flags & GTK_IMHTML_SMILEY_CUSTOM) {
+		ebox = gtk_event_box_new();
+		gtk_event_box_set_visible_window(GTK_EVENT_BOX(ebox), FALSE);
+		gtk_widget_show(ebox);
+	}
+
 	if (icon) {
 		anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter);
 		g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", g_strdup(unescaped), g_free);
@@ -4419,14 +4455,26 @@
 		g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL);
 
 		gtk_widget_show(icon);
-		gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor);
+		if (ebox)
+			gtk_container_add(GTK_CONTAINER(ebox), icon);
+		gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox ? ebox : icon, anchor);
 	} else if (imhtml_smiley != NULL && (imhtml->format_functions & GTK_IMHTML_SMILEY)) {
 		anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter);
 		imhtml_smiley->anchors = g_slist_append(imhtml_smiley->anchors, anchor);
+		if (ebox) {
+			GtkWidget *img = gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_MENU);
+			gtk_container_add(GTK_CONTAINER(ebox), img);
+			gtk_widget_show(img);
+			gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox, anchor);
+		}
 	} else {
 		gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1);
 	}
 
+	if (ebox) {
+		g_signal_connect(G_OBJECT(ebox), "event", G_CALLBACK(gtk_imhtml_smiley_clicked), imhtml_smiley);
+	}
+
 	g_free(unescaped);
 }