# HG changeset patch # User Nathan Walp # Date 1064947288 0 # Node ID acd2a66e59edcf2ea1056b05785eeb463b2f5c1c # Parent 6d10bf28be0ef61df34a3bd3067ea62be5cd2a73 [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 diff -r 6d10bf28be0e -r acd2a66e59ed src/gtkconv.c --- 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); } } diff -r 6d10bf28be0e -r acd2a66e59ed src/gtknotify.c --- 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); diff -r 6d10bf28be0e -r acd2a66e59ed src/gtkutils.c --- 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 #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); + } +} diff -r 6d10bf28be0e -r acd2a66e59ed src/gtkutils.h --- 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 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. * diff -r 6d10bf28be0e -r acd2a66e59ed src/util.c --- 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;