Mercurial > pidgin.yaz
diff src/gtkimhtml.c @ 8962:4ff4c34b7500
[gaim-migrate @ 9736]
IM Image, WYSIWYG.
It's still somewhat buggy, although the worse problems are with oscar's
direct connect. We could always yank oscar's im image flag if we think it
will cause too many bug reports.
I made the GaimImgstore struct opque.
I modified oscar's sending function to parse im images better, and
everything seems to work. I made it write some errors to the conversation
if you try to send an image and you aren't direct connected. That's just
a hack until you can set formatting flags on a per conversation bases.
There's a scrolling bug I haven't tracked down. I think it may exist
normally and this just causes it better.
It's worth noting jabber also uses this for pics in profiles, although
I never did find a test case. Hopefully some other stuff can use this
soon too, maybe Yahoo! pics in profiles or something.
committer: Tailor Script <tailor@pidgin.im>
author | Tim Ringenbach <marv@pidgin.im> |
---|---|
date | Mon, 17 May 2004 06:47:20 +0000 |
parents | 97a1f314b051 |
children | 0a08f671b591 |
line wrap: on
line diff
--- a/src/gtkimhtml.c Mon May 17 04:39:14 2004 +0000 +++ b/src/gtkimhtml.c Mon May 17 06:47:20 2004 +0000 @@ -905,6 +905,7 @@ { GtkIMHtml *imhtml = GTK_IMHTML(object); GList *scalables; + GSList *l; g_hash_table_destroy(imhtml->smiley_data); gtk_smiley_tree_destroy(imhtml->default_smilies); @@ -923,12 +924,20 @@ scale->free(scale); } + for (l = imhtml->im_images; l; l = l->next) { + int id; + id = GPOINTER_TO_INT(l->data); + if (imhtml->funcs->image_unref) + imhtml->funcs->image_unref(id); + } + if (imhtml->clipboard_text_string) { g_free(imhtml->clipboard_text_string); g_free(imhtml->clipboard_html_string); } g_list_free(imhtml->scalables); + g_slist_free(imhtml->im_images); G_OBJECT_CLASS(parent_class)->finalize (object); } @@ -2167,34 +2176,18 @@ case 46: /* IMG (opt) */ case 59: /* IMG */ { -#if 0 -/* disabling this for now, it's easy to add it back... */ - GdkPixbuf *img = NULL; - const gchar *filename = NULL; + const char *id; + + gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); + ws[0] = '\0'; wpos = 0; if (!(imhtml->format_functions & GTK_IMHTML_IMAGE)) break; - if (images && images->data) { - img = images->data; - images = images->next; - filename = g_object_get_data(G_OBJECT(img), "filename"); - g_object_ref(G_OBJECT(img)); - } else { - img = gtk_widget_render_icon(GTK_WIDGET(imhtml), - GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_BUTTON, - "gtkimhtml-missing-image"); - } - - scalable = gtk_imhtml_image_new(img, filename); - /* NEW_BIT(NEW_SCALABLE_BIT); */ - gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); - scalable->add_to(scalable, imhtml, iter); - scalable->scale(scalable, rect.width, rect.height); - imhtml->scalables = g_list_append(imhtml->scalables, scalable); - - g_object_unref(G_OBJECT(img)); -#endif + id = gtk_imhtml_get_html_opt(tag, "ID="); + + gtk_imhtml_insert_image_at_iter(imhtml, atoi(id), iter); + break; } case 47: /* P (opt) */ case 48: /* H3 (opt) */ @@ -2486,7 +2479,7 @@ imhtml->smiley_shortcuts = allow; } -void +void gtk_imhtml_set_protocol_name(GtkIMHtml *imhtml, gchar *protocol_name) { imhtml->protocol_name = protocol_name; } @@ -2538,7 +2531,7 @@ } /* GtkIMHtmlScalable, gtk_imhtml_image, gtk_imhtml_hr */ -GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename) +GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id) { GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage)); GtkImage *image = GTK_IMAGE(gtk_image_new_from_pixbuf(img)); @@ -2553,6 +2546,7 @@ im_image->height = gdk_pixbuf_get_height(img); im_image->mark = NULL; im_image->filename = filename ? g_strdup(filename) : NULL; + im_image->id = id; g_object_ref(img); return GTK_IMHTML_SCALABLE(im_image); @@ -2733,6 +2727,7 @@ { GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; GtkWidget *box = gtk_event_box_new(); + char *tag; GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(image->image)); @@ -2740,6 +2735,10 @@ gtk_widget_show(GTK_WIDGET(image->image)); gtk_widget_show(box); + tag = g_strdup_printf("<IMG ID=\"%d\">", image->id); + g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", tag, g_free); + g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "[Image]"); + gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), box, anchor); g_signal_connect(G_OBJECT(box), "event", G_CALLBACK(gtk_imhtml_image_clicked), image); } @@ -3513,6 +3512,61 @@ g_free(unescaped); } +void gtk_imhtml_insert_image_at_iter(GtkIMHtml *imhtml, int id, GtkTextIter *iter) +{ + GdkPixbuf *pixbuf = NULL; + const char *filename = NULL; + gpointer image; + GdkRectangle rect; + GtkIMHtmlScalable *scalable = NULL; + int minus; + + if (!imhtml->funcs || !imhtml->funcs->image_get || + !imhtml->funcs->image_get_size || !imhtml->funcs->image_get_data || + !imhtml->funcs->image_get_filename || !imhtml->funcs->image_ref || + !imhtml->funcs->image_unref) + return; + + image = imhtml->funcs->image_get(id); + + if (image) { + gpointer data; + size_t len; + + data = imhtml->funcs->image_get_data(image); + len = imhtml->funcs->image_get_size(image); + + if (data && len) { + GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); + gdk_pixbuf_loader_write(loader, data, len, NULL); + pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); + if (pixbuf) + g_object_ref(G_OBJECT(pixbuf)); + gdk_pixbuf_loader_close(loader, NULL); + } + + } + + if (pixbuf) { + filename = imhtml->funcs->image_get_filename(image); + imhtml->funcs->image_ref(id); + imhtml->im_images = g_slist_prepend(imhtml->im_images, GINT_TO_POINTER(id)); + } else { + pixbuf = gtk_widget_render_icon(GTK_WIDGET(imhtml), GTK_STOCK_MISSING_IMAGE, + GTK_ICON_SIZE_BUTTON, "gtkimhtml-missing-image"); + } + + scalable = gtk_imhtml_image_new(pixbuf, filename, id); + gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); + scalable->add_to(scalable, imhtml, iter); + minus = gtk_text_view_get_left_margin(GTK_TEXT_VIEW(imhtml)) + + gtk_text_view_get_right_margin(GTK_TEXT_VIEW(imhtml)); + scalable->scale(scalable, rect.width - minus, rect.height); + imhtml->scalables = g_list_append(imhtml->scalables, scalable); + + g_object_unref(G_OBJECT(pixbuf)); +} + static const gchar *tag_to_html_start(GtkTextTag *tag) { const gchar *name; @@ -3796,3 +3850,9 @@ return g_string_free(str, FALSE); } + +void gtk_imhtml_set_funcs(GtkIMHtml *imhtml, GtkIMHtmlFuncs *f) +{ + g_return_if_fail(imhtml != NULL); + imhtml->funcs = f; +}