[evolution] Add zooming and drag-and-drop to the plugin.
- From: Matthew Barnes <mbarnes src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [evolution] Add zooming and drag-and-drop to the plugin.
- Date: Tue, 10 Nov 2009 02:31:53 +0000 (UTC)
commit e13eb8a5b52c0b95f5b235c61245277230d565dc
Author: Matthew Barnes <mbarnes redhat com>
Date: Sun Nov 8 01:49:48 2009 -0500
Add zooming and drag-and-drop to the plugin.
A bunch of crusty old code in em-format-html-display.c falls out.
mail/Makefile.am | 2 -
mail/em-format-html-display.c | 277 +---------------------------
mail/em-format-html-display.h | 4 +
mail/em-format-html.c | 4 -
mail/em-icon-stream.c | 347 -----------------------------------
mail/em-icon-stream.h | 61 ------
plugins/image-inline/Makefile.am | 1 +
plugins/image-inline/image-inline.c | 165 ++++++++++++++---
8 files changed, 151 insertions(+), 710 deletions(-)
---
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 7f284e9..01d41aa 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -70,7 +70,6 @@ mailinclude_HEADERS = \
em-format-html-display.h \
em-format-html-print.h \
em-html-stream.h \
- em-icon-stream.h \
em-inline-filter.h \
em-junk.h \
em-search-context.h \
@@ -127,7 +126,6 @@ libevolution_mail_la_SOURCES = \
em-format-html-display.c \
em-format-html-print.c \
em-html-stream.c \
- em-icon-stream.c \
em-inline-filter.c \
em-junk.c \
em-search-context.c \
diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c
index de64e2b..34c146e 100644
--- a/mail/em-format-html-display.c
+++ b/mail/em-format-html-display.c
@@ -76,7 +76,6 @@
#include "e-mail-display.h"
#include "e-mail-attachment-bar.h"
#include "em-format-html-display.h"
-#include "em-icon-stream.h"
#include "em-utils.h"
#include "widgets/misc/e-attachment-button.h"
#include "widgets/misc/e-attachment-view.h"
@@ -126,7 +125,6 @@ static const gchar *smime_sign_colour[5] = {
};
static void efhd_attachment_frame(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri);
-static gboolean efhd_attachment_image(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject);
static void efhd_message_add_bar(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info);
static gboolean efhd_attachment_button (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject);
static gboolean efhd_attachment_optional (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *object);
@@ -672,58 +670,7 @@ em_format_html_display_new (void)
/* ********************************************************************** */
-static void
-efhd_image(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFormatHandler *handle)
-{
- gchar *classid;
- struct _attach_puri *info;
-
- classid = g_strdup_printf("image%s", ((EMFormat *)efh)->part_id->str);
- info = (struct _attach_puri *)em_format_add_puri((EMFormat *)efh, sizeof(*info), classid, part, efhd_attachment_frame);
- em_format_html_add_pobject(efh, sizeof(EMFormatHTMLPObject), classid, part, efhd_attachment_image);
-
- info->handle = handle;
- info->shown = TRUE;
- info->snoop_mime_type = ((EMFormat *) efh)->snoop_mime_type;
- if (camel_operation_cancel_check (NULL) || !info->puri.format || !((EMFormatHTML *)info->puri.format)->html) {
- /* some fake value, we are cancelled anyway, thus doesn't matter */
- info->fit_width = 256;
- } else {
- info->fit_width = ((GtkWidget *)((EMFormatHTML *)info->puri.format)->html)->allocation.width - 12;
- }
-
- camel_stream_printf(stream, "<td><object classid=\"%s\"></object></td>", classid);
- g_free(classid);
-}
-
-/* ********************************************************************** */
-
static EMFormatHandler type_builtin_table[] = {
-#if 0
- { (gchar *) "image/gif", (EMFormatFunc)efhd_image },
- { (gchar *) "image/jpeg", (EMFormatFunc)efhd_image },
- { (gchar *) "image/png", (EMFormatFunc)efhd_image },
- { (gchar *) "image/x-png", (EMFormatFunc)efhd_image },
- { (gchar *) "image/tiff", (EMFormatFunc)efhd_image },
- { (gchar *) "image/x-bmp", (EMFormatFunc)efhd_image },
- { (gchar *) "image/bmp", (EMFormatFunc)efhd_image },
- { (gchar *) "image/svg", (EMFormatFunc)efhd_image },
- { (gchar *) "image/x-cmu-raster", (EMFormatFunc)efhd_image },
- { (gchar *) "image/x-ico", (EMFormatFunc)efhd_image },
- { (gchar *) "image/x-portable-anymap", (EMFormatFunc)efhd_image },
- { (gchar *) "image/x-portable-bitmap", (EMFormatFunc)efhd_image },
- { (gchar *) "image/x-portable-graymap", (EMFormatFunc)efhd_image },
- { (gchar *) "image/x-portable-pixmap", (EMFormatFunc)efhd_image },
- { (gchar *) "image/x-xpixmap", (EMFormatFunc)efhd_image },
-
- /* This is where one adds those busted, non-registered types,
- that some idiot mailer writers out there decide to pull out
- of their proverbials at random. */
-
- { (gchar *) "image/jpg", (EMFormatFunc)efhd_image },
- { (gchar *) "image/pjpeg", (EMFormatFunc)efhd_image },
-#endif
-
{ (gchar *) "x-evolution/message/prefix", (EMFormatFunc)efhd_message_prefix },
{ (gchar *) "x-evolution/message/post-header", (EMFormatFunc)efhd_message_add_bar }
};
@@ -839,219 +786,6 @@ efhd_attachment_button_expanded (GtkWidget *widget,
/* ********************************************************************** */
-static void
-efhd_drag_data_get(GtkWidget *w, GdkDragContext *drag, GtkSelectionData *data, guint info, guint time, EMFormatHTMLPObject *pobject)
-{
- CamelMimePart *part = pobject->part;
- gchar *uri, *uri_crlf, *path;
- CamelStream *stream;
-
- switch (info) {
- case 0: /* mime/type request */
- stream = camel_stream_mem_new();
- /* TODO: shoudl format_format_text run on the content-object? */
- /* TODO: should we just do format_content? */
- if (camel_content_type_is (((CamelDataWrapper *)part)->mime_type, "text", "*")) {
- /* FIXME: this should be an em_utils method, it only needs a default charset param */
- em_format_format_text((EMFormat *)pobject->format, stream, (CamelDataWrapper *)part);
- } else {
- CamelDataWrapper *dw = camel_medium_get_content_object((CamelMedium *)part);
-
- camel_data_wrapper_decode_to_stream(dw, stream);
- }
-
- gtk_selection_data_set(data, data->target, 8,
- ((CamelStreamMem *)stream)->buffer->data,
- ((CamelStreamMem *)stream)->buffer->len);
- camel_object_unref(stream);
- break;
- case 1: /* text-uri-list request */
- /* Kludge around Nautilus requesting the same data many times */
- uri = g_object_get_data((GObject *)w, "e-drag-uri");
- if (uri) {
- gtk_selection_data_set(data, data->target, 8, (guchar *)uri, strlen(uri));
- return;
- }
-
- path = em_utils_temp_save_part(w, part, FALSE);
- if (path == NULL)
- return;
-
- uri = g_filename_to_uri(path, NULL, NULL);
- g_free(path);
- uri_crlf = g_strconcat(uri, "\r\n", NULL);
- g_free(uri);
- gtk_selection_data_set(data, data->target, 8, (guchar *)uri_crlf, strlen(uri_crlf));
- g_object_set_data_full((GObject *)w, "e-drag-uri", uri_crlf, g_free);
- break;
- default:
- abort();
- }
-}
-
-static void
-efhd_drag_data_delete(GtkWidget *w, GdkDragContext *drag, EMFormatHTMLPObject *pobject)
-{
- gchar *uri;
-
- uri = g_object_get_data((GObject *)w, "e-drag-uri");
- if (uri) {
- /* NB: this doesn't kill the dnd directory */
- /* NB: is this ever called? */
- /* NB even more: doesn't the e-drag-uri have \r\n
- * appended? (see efhd_drag_data_get())
- */
- gchar *filename = g_filename_from_uri (uri, NULL, NULL);
- g_unlink(filename);
- g_free(filename);
- g_object_set_data((GObject *)w, "e-drag-uri", NULL);
- }
-}
-
-static void
-efhd_write_icon_job(struct _EMFormatHTMLJob *job, gint cancelled)
-{
- EMFormatHTMLPObject *pobject;
- CamelDataWrapper *dw;
-
- if (cancelled)
- return;
-
- pobject = job->u.data;
- dw = camel_medium_get_content_object((CamelMedium *)pobject->part);
- camel_data_wrapper_decode_to_stream(dw, job->stream);
- camel_stream_close(job->stream);
-}
-
-static void
-efhd_image_resized(GtkWidget *w, GtkAllocation *event, struct _attach_puri *info)
-{
- GdkPixbuf *pb;
- gint width;
-
- if (info->fit_width == 0)
- return;
-
- width = ((GtkWidget *)((EMFormatHTML *)info->puri.format)->html)->allocation.width - 12;
- if (info->fit_width == width)
- return;
- info->fit_width = width;
-
- pb = em_icon_stream_get_image(info->puri.cid, info->fit_width, info->fit_height);
- if (pb) {
- gtk_image_set_from_pixbuf(info->image, pb);
- g_object_unref(pb);
- }
-}
-
-static void
-efhd_change_cursor(GtkWidget *w, GdkEventCrossing *event, struct _attach_puri *info)
-{
- if (info->shown && info->image) {
- if (info->fit_width != 0) {
- if (em_icon_stream_is_resized(info->puri.cid, info->fit_width, info->fit_height))
- e_cursor_set(w->window, E_CURSOR_ZOOM_IN);
-
- }
- }
-}
-
-static void
-efhd_image_fit_width(GtkWidget *widget, GdkEventButton *event, struct _attach_puri *info)
-{
- gint width;
-
- width = ((GtkWidget *)((EMFormatHTML *)info->puri.format)->html)->allocation.width - 12;
-
- if (info->shown && info->image) {
- if (info->fit_width != 0) {
- if (em_icon_stream_is_resized(info->puri.cid, info->fit_width, info->fit_height)) {
- if (info->fit_width != width) {
- info->fit_width = width;
- e_cursor_set (widget->window, E_CURSOR_ZOOM_IN);
- } else {
- info->fit_width = 0;
- e_cursor_set(widget->window, E_CURSOR_ZOOM_OUT);
- }
- }
- } else {
- info->fit_width = width;
- e_cursor_set (widget->window, E_CURSOR_ZOOM_IN);
- }
- }
-
- gtk_image_set_from_pixbuf(info->image, em_icon_stream_get_image(info->puri.cid, info->fit_width, info->fit_height));
-}
-
-/* When the puri gets freed in the formatter thread and if the image is resized, crash will happen
- See bug #333864 So while freeing the puri, we disconnect the image attach resize attached with
- the puri */
-
-static void
-efhd_image_unallocate (struct _EMFormatPURI * puri)
-{
- struct _attach_puri *info = (struct _attach_puri *) puri;
- g_signal_handlers_disconnect_by_func(info->html, efhd_image_resized, info);
-
- g_signal_handlers_disconnect_by_func(info->event_box, efhd_change_cursor, info);
- g_signal_handlers_disconnect_by_func(info->event_box, efhd_image_fit_width, info);
-}
-
-static gboolean
-efhd_attachment_image(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject)
-{
- GtkWidget *box;
- EMFormatHTMLJob *job;
- struct _attach_puri *info;
- GdkPixbuf *pixbuf;
- GtkTargetEntry drag_types[] = {
- { NULL, 0, 0 },
- { (gchar *) "text/uri-list", 0, 1 },
- };
- gchar *simple_type;
-
- info = (struct _attach_puri *)em_format_find_puri((EMFormat *)efh, pobject->classid);
-
- info->image = (GtkImage *)gtk_image_new();
- info->html = eb;
- info->puri.free = efhd_image_unallocate;
-
- pixbuf = em_icon_stream_get_image(pobject->classid, info->fit_width, info->fit_height);
- if (pixbuf) {
- gtk_image_set_from_pixbuf(info->image, pixbuf);
- g_object_unref(pixbuf);
- } else {
- job = em_format_html_job_new(efh, efhd_write_icon_job, pobject);
- job->stream = (CamelStream *)em_icon_stream_new((GtkImage *)info->image, pobject->classid, info->fit_width, info->fit_height, TRUE);
- em_format_html_job_queue(efh, job);
- }
-
- box = gtk_event_box_new();
- info->event_box = box;
- gtk_container_add((GtkContainer *)box, (GtkWidget *)info->image);
- gtk_widget_show_all(box);
- gtk_container_add((GtkContainer *)eb, box);
-
- g_signal_connect(eb, "size_allocate", G_CALLBACK(efhd_image_resized), info);
-
- simple_type = camel_content_type_simple(((CamelDataWrapper *)pobject->part)->mime_type);
- camel_strdown(simple_type);
-
- drag_types[0].target = simple_type;
- gtk_drag_source_set(box, GDK_BUTTON1_MASK, drag_types, G_N_ELEMENTS (drag_types), GDK_ACTION_COPY);
- g_free(simple_type);
-
- g_signal_connect(box, "drag-data-get", G_CALLBACK(efhd_drag_data_get), pobject);
- g_signal_connect (box, "drag-data-delete", G_CALLBACK(efhd_drag_data_delete), pobject);
-
- g_signal_connect(box, "enter-notify-event", G_CALLBACK(efhd_change_cursor), info);
- g_signal_connect(box, "button-press-event", G_CALLBACK(efhd_image_fit_width), info);
-
- g_object_set_data (G_OBJECT (box), "efh", efh);
-
- return TRUE;
-}
-
/* attachment button callback */
static gboolean
efhd_attachment_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject)
@@ -1083,8 +817,8 @@ efhd_attachment_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObje
parent = gtk_widget_get_toplevel (GTK_WIDGET (efh->html));
parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
- view = E_ATTACHMENT_VIEW (efhd->priv->attachment_view);
- gtk_widget_show (efhd->priv->attachment_view);
+ view = em_format_html_display_get_attachment_view (efhd);
+ gtk_widget_show (GTK_WIDGET (view));
store = e_attachment_view_get_store (view);
e_attachment_store_add_attachment (store, info->attachment);
@@ -1298,3 +1032,10 @@ efhd_attachment_optional(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPOb
return TRUE;
}
+EAttachmentView *
+em_format_html_display_get_attachment_view (EMFormatHTMLDisplay *html_display)
+{
+ g_return_val_if_fail (EM_IS_FORMAT_HTML_DISPLAY (html_display), NULL);
+
+ return E_ATTACHMENT_VIEW (html_display->priv->attachment_view);
+}
diff --git a/mail/em-format-html-display.h b/mail/em-format-html-display.h
index 4626598..089b361 100644
--- a/mail/em-format-html-display.h
+++ b/mail/em-format-html-display.h
@@ -26,6 +26,7 @@
#define EM_FORMAT_HTML_DISPLAY_H
#include <mail/em-format-html.h>
+#include <misc/e-attachment-view.h>
/* Standard GObject macros */
#define EM_TYPE_FORMAT_HTML_DISPLAY \
@@ -66,6 +67,9 @@ struct _EMFormatHTMLDisplayClass {
GType em_format_html_display_get_type (void);
EMFormatHTMLDisplay *
em_format_html_display_new (void);
+EAttachmentView *
+ em_format_html_display_get_attachment_view
+ (EMFormatHTMLDisplay *html_display);
G_END_DECLS
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index 29bb476..47213dc 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -2105,7 +2105,6 @@ efh_image(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFormatH
}
static EMFormatHandler type_builtin_table[] = {
-#if 0
{ (gchar *) "image/gif", (EMFormatFunc)efh_image },
{ (gchar *) "image/jpeg", (EMFormatFunc)efh_image },
{ (gchar *) "image/png", (EMFormatFunc)efh_image },
@@ -2121,7 +2120,6 @@ static EMFormatHandler type_builtin_table[] = {
{ (gchar *) "image/x-portable-graymap", (EMFormatFunc)efh_image },
{ (gchar *) "image/x-portable-pixmap", (EMFormatFunc)efh_image },
{ (gchar *) "image/x-xpixmap", (EMFormatFunc)efh_image },
-#endif
{ (gchar *) "text/enriched", (EMFormatFunc)efh_text_enriched },
{ (gchar *) "text/plain", (EMFormatFunc)efh_text_plain },
{ (gchar *) "text/html", (EMFormatFunc)efh_text_html },
@@ -2135,10 +2133,8 @@ static EMFormatHandler type_builtin_table[] = {
that some idiot mailer writers out there decide to pull out
of their proverbials at random. */
-#if 0
{ (gchar *) "image/jpg", (EMFormatFunc)efh_image },
{ (gchar *) "image/pjpeg", (EMFormatFunc)efh_image },
-#endif
/* special internal types */
diff --git a/plugins/image-inline/Makefile.am b/plugins/image-inline/Makefile.am
index 5ff7c26..d59203a 100644
--- a/plugins/image-inline/Makefile.am
+++ b/plugins/image-inline/Makefile.am
@@ -7,6 +7,7 @@ plugin_LTLIBRARIES = liborg-gnome-image-inline.la
liborg_gnome_image_inline_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
-I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
$(GNOME_PLATFORM_CFLAGS) \
$(EVOLUTION_MAIL_CFLAGS) \
$(GTKIMAGEVIEW_CFLAGS)
diff --git a/plugins/image-inline/image-inline.c b/plugins/image-inline/image-inline.c
index 81e5d92..688a7d7 100644
--- a/plugins/image-inline/image-inline.c
+++ b/plugins/image-inline/image-inline.c
@@ -31,8 +31,8 @@
#include <gtkhtml/gtkhtml-embedded.h>
#include <gtkimageview/gtkimagescrollwin.h>
-#include "mail/em-format-hook.h"
-#include "mail/em-format-html.h"
+#include <mail/em-format-hook.h>
+#include <mail/em-format-html-display.h>
static gint org_gnome_image_inline_classid;
@@ -44,13 +44,118 @@ typedef struct _ImageInlinePObject ImageInlinePObject;
struct _ImageInlinePObject {
EMFormatHTMLPObject object;
+ CamelMimePart *mime_part;
GdkPixbuf *pixbuf;
GtkWidget *widget;
};
static void
+set_drag_source (GtkImageView *image_view)
+{
+ GtkTargetEntry *targets;
+ GtkTargetList *list;
+ gint n_targets;
+
+ list = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add_uri_targets (list, 0);
+ targets = gtk_target_table_new_from_list (list, &n_targets);
+
+ gtk_drag_source_set (
+ GTK_WIDGET (image_view), GDK_BUTTON1_MASK,
+ targets, n_targets, GDK_ACTION_COPY);
+
+ gtk_target_table_free (targets, n_targets);
+ gtk_target_list_unref (list);
+}
+
+static gboolean
+button_press_press_cb (GtkImageView *image_view,
+ GdkEventButton *event,
+ ImageInlinePObject *image_object)
+{
+ if (event->type != GDK_2BUTTON_PRESS)
+ return FALSE;
+
+ if (gtk_image_view_get_zoom (image_view) < 1.0) {
+ gtk_image_view_set_zoom (image_view, 1.0);
+ gtk_drag_source_unset (GTK_WIDGET (image_view));
+ } else {
+ gtk_image_view_set_fitting (image_view, TRUE);
+ set_drag_source (image_view);
+ }
+
+ return TRUE;
+}
+
+static void
+drag_data_get_cb (GtkImageView *image_view,
+ GdkDragContext *context,
+ GtkSelectionData *selection,
+ guint info,
+ guint time,
+ ImageInlinePObject *image_object)
+{
+ EMFormatHTMLDisplay *html_display;
+ EAttachmentStore *store;
+ EAttachmentView *view;
+ EAttachment *attachment = NULL;
+ GtkTreeRowReference *reference;
+ GtkTreePath *path;
+ GList *list, *iter;
+
+ /* XXX This illustrates the lack of integration between EMFormat
+ * and EAttachment, in that we now have to search through the
+ * attachment store to find an attachment whose CamelMimePart
+ * matches ours. This allows us to defer to EAttachmentView
+ * for the drag-data-get implementation. */
+
+ html_display = EM_FORMAT_HTML_DISPLAY (image_object->object.format);
+ view = em_format_html_display_get_attachment_view (html_display);
+
+ store = e_attachment_view_get_store (view);
+ list = e_attachment_store_get_attachments (store);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ CamelMimePart *mime_part;
+
+ attachment = E_ATTACHMENT (iter->data);
+ mime_part = e_attachment_get_mime_part (attachment);
+
+ if (mime_part == image_object->mime_part) {
+ g_object_ref (attachment);
+ break;
+ }
+
+ attachment = NULL;
+ }
+
+ g_list_foreach (list, (GFunc) g_object_unref, NULL);
+ g_list_free (list);
+
+ /* Make sure we found an EAttachment to select. */
+ g_return_if_fail (E_IS_ATTACHMENT (attachment));
+
+ /* Now select its path in the attachment store. */
+
+ reference = e_attachment_get_reference (attachment);
+ g_return_if_fail (gtk_tree_row_reference_valid (reference));
+
+ path = gtk_tree_row_reference_get_path (reference);
+
+ e_attachment_view_unselect_all (view);
+ e_attachment_view_select_path (view, path);
+
+ gtk_tree_path_free (path);
+
+ /* Let EAttachmentView handle the rest. */
+
+ e_attachment_view_drag_data_get (
+ view, context, selection, info, time);
+}
+
+static void
size_allocate_cb (GtkHTMLEmbedded *embedded,
- GtkAllocation *event,
+ GtkAllocation *allocation,
ImageInlinePObject *image_object)
{
GtkWidget *widget;
@@ -58,7 +163,7 @@ size_allocate_cb (GtkHTMLEmbedded *embedded,
gint pixbuf_height;
gint widget_width;
gint widget_height;
- gdouble zoom;
+ gdouble zoom = 1.0;
widget = GTK_WIDGET (image_object->object.format->html);
widget_width = widget->allocation.width - 12;
@@ -66,9 +171,7 @@ size_allocate_cb (GtkHTMLEmbedded *embedded,
pixbuf_width = gdk_pixbuf_get_width (image_object->pixbuf);
pixbuf_height = gdk_pixbuf_get_height (image_object->pixbuf);
- if (pixbuf_width <= widget_width)
- zoom = 1.0;
- else
+ if (pixbuf_width > widget_width)
zoom = (gdouble) widget_width / pixbuf_width;
widget_width = MIN (widget_width, pixbuf_width);
@@ -85,6 +188,11 @@ org_gnome_image_inline_pobject_free (EMFormatHTMLPObject *object)
image_object = (ImageInlinePObject *) object;
+ if (image_object->mime_part != NULL) {
+ camel_object_unref (image_object->mime_part);
+ image_object->mime_part = NULL;
+ }
+
if (image_object->pixbuf != NULL) {
g_object_unref (image_object->pixbuf);
image_object->pixbuf = NULL;
@@ -97,20 +205,19 @@ org_gnome_image_inline_pobject_free (EMFormatHTMLPObject *object)
}
static void
-org_gnome_image_inline_decode (ImageInlinePObject *image_object,
- CamelMimePart *mime_part)
+org_gnome_image_inline_decode (ImageInlinePObject *image_object)
{
GdkPixbuf *pixbuf;
GdkPixbufLoader *loader;
- CamelContentType *content_type;
CamelDataWrapper *data_wrapper;
+ CamelMimePart *mime_part;
CamelMedium *medium;
CamelStream *stream;
GByteArray *array;
- gchar *mime_type;
GError *error = NULL;
array = g_byte_array_new ();
+ mime_part = image_object->mime_part;
medium = CAMEL_MEDIUM (mime_part);
/* Stream takes ownership of the byte array. */
@@ -118,17 +225,10 @@ org_gnome_image_inline_decode (ImageInlinePObject *image_object,
data_wrapper = camel_medium_get_content_object (medium);
camel_data_wrapper_decode_to_stream (data_wrapper, stream);
- content_type = camel_mime_part_get_content_type (mime_part);
- mime_type = camel_content_type_simple (content_type);
- loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, &error);
- g_free (mime_type);
-
- if (error != NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- goto exit;
- }
-
+ /* Don't trust the content type in the MIME part. It could
+ * be lying or it could be "application/octet-stream". Let
+ * the GtkPixbufLoader figure it out. */
+ loader = gdk_pixbuf_loader_new ();
gdk_pixbuf_loader_write (loader, array->data, array->len, &error);
if (error != NULL) {
@@ -150,8 +250,8 @@ org_gnome_image_inline_decode (ImageInlinePObject *image_object,
}
exit:
- camel_object_unref (mime_part);
camel_object_unref (stream);
+ g_object_unref (loader);
}
static gboolean
@@ -172,17 +272,25 @@ org_gnome_image_inline_embed (EMFormatHTML *format,
container = GTK_WIDGET (embedded);
widget = gtk_image_view_new ();
- image_view = GTK_IMAGE_VIEW (widget);
- gtk_widget_show (widget);
-
- widget = gtk_image_scroll_win_new (image_view);
gtk_container_add (GTK_CONTAINER (container), widget);
image_object->widget = g_object_ref (widget);
gtk_widget_show (widget);
+ image_view = GTK_IMAGE_VIEW (widget);
+
gtk_image_view_set_pixbuf (
image_view, image_object->pixbuf, TRUE);
+ set_drag_source (image_view);
+
+ g_signal_connect (
+ image_view, "button-press-event",
+ G_CALLBACK (button_press_press_cb), image_object);
+
+ g_signal_connect (
+ image_view, "drag-data-get",
+ G_CALLBACK (drag_data_get_cb), image_object);
+
g_signal_connect (
embedded, "size-allocate",
G_CALLBACK (size_allocate_cb), image_object);
@@ -208,9 +316,10 @@ org_gnome_image_inline_format (gpointer ep, EMFormatHookTarget *target)
org_gnome_image_inline_embed);
camel_object_ref (target->part);
+ image_object->mime_part = target->part;
image_object->object.free = org_gnome_image_inline_pobject_free;
- org_gnome_image_inline_decode (image_object, target->part);
+ org_gnome_image_inline_decode (image_object);
camel_stream_printf (
target->stream, "<object classid=%s></object>", classid);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]