changeset 7078:acd2a66e59ed

[gaim-migrate @ 7643] robot101 gave us images in notify_formatted windows. very cool. This lets what I committed earlier (which was support for images in jabber vcards) to work. committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Tue, 30 Sep 2003 18:41:28 +0000
parents 6d10bf28be0e
children 5a45833dd253
files src/gtkconv.c src/gtknotify.c src/gtkutils.c src/gtkutils.h src/util.c
diffstat 5 files changed, 97 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- a/src/gtkconv.c	Tue Sep 30 18:40:18 2003 +0000
+++ b/src/gtkconv.c	Tue Sep 30 18:41:28 2003 +0000
@@ -4344,67 +4344,8 @@
 		gaim_window_show(win);
 	}
 
-	if (flags & GAIM_MESSAGE_IMAGES) {
-		GData *attribs;
-		GdkPixbuf *broken;
-		const char *tmp, *start, *end;
-
-		broken = gtk_widget_render_icon(GTK_WIDGET(gtkconv->imhtml),
-				GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_BUTTON,
-				"gaim-missing-image");
-
-		tmp = message;
-		while (gaim_markup_find_tag("img", tmp, &start, &end, &attribs)) {
-			GaimStoredImage *image = NULL;
-			GdkPixbufLoader *loader;
-			GError *error = NULL;
-			char *id = NULL;
-
-			tmp = end + 1;
-
-			id = g_datalist_get_data(&attribs, "id");
-
-			if (id)
-				image = gaim_imgstore_get(atoi(id));
-
-			g_datalist_clear(&attribs);
-
-			if (!image) {
-				g_object_ref(G_OBJECT(broken));
-				images = g_slist_append(images, broken);
-				continue;
-			}
-
-			loader = gdk_pixbuf_loader_new();
-
-			if (!gdk_pixbuf_loader_write(loader, image->data, image->size, &error)) {
-				if (error) {
-					gaim_debug(GAIM_DEBUG_ERROR, "gtkconv",
-							"Failed to make pixbuf for IM Image: %s\n",
-							error->message);
-					g_error_free(error);
-				}
-				g_object_ref(G_OBJECT(broken));
-				images = g_slist_append(images, broken);
-			} else {
-				GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
-				if (pixbuf) {
-					if (image->filename)
-						g_object_set_data_full(G_OBJECT(pixbuf), "filename",
-								g_strdup(image->filename), g_free);
-					g_object_ref(G_OBJECT(pixbuf));
-					images = g_slist_append(images, pixbuf);
-				} else {
-					g_object_ref(G_OBJECT(broken));
-					images = g_slist_append(images, broken);
-				}
-			}
-
-			gdk_pixbuf_loader_close(loader, NULL);
-		}
-
-		g_object_unref(G_OBJECT(broken));
-	}
+	if (flags & GAIM_MESSAGE_IMAGES)
+		gaim_gtk_find_images(message, &images);
 
 	if(time(NULL) > mtime + 20*60) /* show date if older than 20 minutes */
 		strftime(mdate, sizeof(mdate), "%Y-%m-%d %H:%M:%S", localtime(&mtime));
@@ -4675,13 +4616,14 @@
 		g_free(sml_attrib);
 
 	if (images) {
-		GSList *tmp = images;
-		GdkPixbuf *pixbuf;
-		while (tmp) {
-			pixbuf = tmp->data;
-			g_object_unref(G_OBJECT(pixbuf));
-			tmp = tmp->next;
+		GSList *tmp;
+
+		for (tmp = images; tmp; tmp = tmp->next) {
+			GdkPixbuf *pixbuf = tmp->data;
+			if(pixbuf)
+				g_object_unref(pixbuf);
 		}
+
 		g_slist_free(images);
 	}
 }
--- a/src/gtknotify.c	Tue Sep 30 18:40:18 2003 +0000
+++ b/src/gtknotify.c	Tue Sep 30 18:41:28 2003 +0000
@@ -270,6 +270,7 @@
 	GtkWidget *button;
 	GtkWidget *imhtml;
 	GtkWidget *sw;
+	GSList *images = NULL;
 	int options = 0;
 	char label_text[2048];
 
@@ -340,7 +341,20 @@
 	options ^= GTK_IMHTML_NO_NEWLINE;
 	options ^= GTK_IMHTML_NO_SCROLL;
 
-	gtk_imhtml_append_text(GTK_IMHTML(imhtml), text, options);
+	gaim_gtk_find_images(text, &images);
+	gtk_imhtml_append_text_with_images(GTK_IMHTML(imhtml), text, options, images);
+
+	if (images) {
+		GSList *tmp;
+
+		for (tmp = images; tmp; tmp = tmp->next) {
+			GdkPixbuf *pixbuf = tmp->data;
+			if(pixbuf)
+				g_object_unref(pixbuf);
+		}
+
+		g_slist_free(images);
+	}
 
 	/* Show the window */
 	gtk_widget_show(window);
--- a/src/gtkutils.c	Tue Sep 30 18:40:18 2003 +0000
+++ b/src/gtkutils.c	Tue Sep 30 18:41:28 2003 +0000
@@ -33,6 +33,7 @@
 #include <gdk/gdkkeysyms.h>
 
 #include "debug.h"
+#include "imgstore.h"
 #include "notify.h"
 #include "prefs.h"
 #include "prpl.h"
@@ -1049,3 +1050,54 @@
 		break;
 	}
 }
+
+void gaim_gtk_find_images(const char *message, GSList **list) {
+	GData *attribs;
+	const char *tmp, *start, *end;
+
+	tmp = message;
+	while (gaim_markup_find_tag("img", tmp, &start, &end, &attribs)) {
+		GaimStoredImage *image = NULL;
+		GdkPixbufLoader *loader = NULL;
+		GdkPixbuf *pixbuf = NULL;
+		GError *error = NULL;
+		char *id = g_datalist_get_data(&attribs, "id");
+
+		tmp = end + 1;
+
+		if (id)
+			image = gaim_imgstore_get(atoi(id));
+
+		g_datalist_clear(&attribs);
+
+		if (!image) {
+			*list = g_slist_append(*list, NULL);
+			continue;
+		}
+
+		loader = gdk_pixbuf_loader_new();
+
+		if (gdk_pixbuf_loader_write(loader, image->data, image->size, &error)
+			&& (pixbuf = gdk_pixbuf_loader_get_pixbuf(loader))) {
+
+			if (image->filename)
+				g_object_set_data_full(G_OBJECT(pixbuf), "filename",
+					g_strdup(image->filename), g_free);
+			g_object_ref(G_OBJECT(pixbuf));
+			*list = g_slist_append(*list, pixbuf);
+		} else {
+			if (error) {
+				gaim_debug(GAIM_DEBUG_ERROR, "gtkutils",
+						"Failed to make pixbuf from image store: %s\n",
+						error->message);
+				g_error_free(error);
+			} else {
+				gaim_debug(GAIM_DEBUG_ERROR, "gtkutils",
+						"Failed to make pixbuf from image store: unknown reason\n");
+			}
+			*list = g_slist_append(*list, NULL);
+		}
+
+		gdk_pixbuf_loader_close(loader, NULL);
+	}
+}
--- a/src/gtkutils.h	Tue Sep 30 18:40:18 2003 +0000
+++ b/src/gtkutils.h	Tue Sep 30 18:41:28 2003 +0000
@@ -259,6 +259,18 @@
 gboolean gaim_gtk_check_if_dir(const char *path, GtkFileSelection *filesel);
 
 /**
+ * Parses a message to find <IMG> tags with valid ID attributes that
+ * refer to images in Gaim's image store, and load them into a list
+ * of GdkPixbufs. Image tags with missing ID paramaters, or those that
+ * refer to images that are not in the store will have a corresponding
+ * NULL entry on the list.
+ *
+ * @param message The message to parse for image tags.
+ * @param list    A pointer to the GSList of GdkPixbufs that will be created.
+ */
+void gaim_gtk_find_images(const char *message, GSList **list);
+
+/**
  * Stylizes the specified text using HTML, according to the current
  * font options.
  *
--- a/src/util.c	Tue Sep 30 18:40:18 2003 +0000
+++ b/src/util.c	Tue Sep 30 18:41:28 2003 +0000
@@ -1003,7 +1003,7 @@
 	gboolean found = FALSE;
 	gboolean in_tag = FALSE;
 	gboolean in_attr = FALSE;
-	gboolean in_quotes = FALSE;
+	char *in_quotes = NULL;
 	size_t needlelen = strlen(needle);
 
 	g_datalist_init(&attribs);
@@ -1013,7 +1013,7 @@
 			if (in_quotes) {
 				const char *close = cur;
 
-				while (*close && *close != '"')
+				while (*close && *close != *in_quotes)
 					close++;
 
 				/* if we got the close quote, store the value and carry on from    *
@@ -1030,7 +1030,7 @@
 						name = NULL;
 					}
 
-					in_quotes = FALSE;
+					in_quotes = NULL;
 					cur = close + 1;
 				} else {
 					cur = close;
@@ -1038,7 +1038,8 @@
 			} else if (in_attr) {
 				const char *close = cur;
 
-				while (*close && *close != '>' && *close != '"' && *close != ' ' && *close != '=')
+				while (*close && *close != '>' && *close != '"' &&
+						*close != '\'' && *close != ' ' && *close != '=')
 					close++;
 
 				/* if we got the equals, store the name of the attribute. if we got
@@ -1047,7 +1048,8 @@
 				 * so we can get outta here */
 				switch (*close) {
 				case '"':
-					in_quotes = TRUE;
+				case '\'':
+					in_quotes = close;
 				case '=':
 					{
 						size_t len = close - cur;
@@ -1082,7 +1084,8 @@
 					*end = cur;
 					break;
 				case '"':
-					in_quotes = TRUE;
+				case '\'':
+					in_quotes = cur;
 				default:
 					cur++;
 					break;