Files
evolution/mail/em-html-stream.c
Matthew Barnes 08b1d0ae8e Split the interactive parts of the message display out of EMFormatHTMLDisplay
to a new GtkHTML subclass named EMailDisplay, and have EMFormatHTML create an
instance of that.  EMailDisplay will handle link clicking, mousing over URIs,
popup menus, and interactive search.  This makes EMFormatHTMLDisplay and
EMailReader more lightweight.

Clean up more of the EMFormat stack.

svn path=/branches/kill-bonobo/; revision=37346
2009-03-01 13:16:31 +00:00

182 lines
4.0 KiB
C

/*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
* Authors:
* Jeffrey Stedfast <fejj@ximian.com>
* Michael Zucchi <notzed@ximian.com>
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <gtk/gtk.h>
#include "em-html-stream.h"
#define d(x)
static EMSyncStreamClass *parent_class = NULL;
static void
emhs_cleanup (EMHTMLStream *emhs)
{
if (emhs->sync.cancel && emhs->html_stream)
gtk_html_stream_close (
emhs->html_stream, GTK_HTML_STREAM_ERROR);
emhs->html_stream = NULL;
emhs->sync.cancel = TRUE;
g_signal_handler_disconnect (emhs->html, emhs->destroy_id);
g_object_unref (emhs->html);
emhs->html = NULL;
}
static void
emhs_gtkhtml_destroy (GtkHTML *html,
EMHTMLStream *emhs)
{
emhs->sync.cancel = TRUE;
emhs_cleanup (emhs);
}
static ssize_t
emhs_sync_write (CamelStream *stream,
const char *buffer,
size_t n)
{
EMHTMLStream *emhs = EM_HTML_STREAM (stream);
if (emhs->html == NULL)
return -1;
if (emhs->html_stream == NULL)
emhs->html_stream = gtk_html_begin_full (
emhs->html, NULL, NULL, emhs->flags);
gtk_html_stream_write (emhs->html_stream, buffer, n);
return (ssize_t) n;
}
static int
emhs_sync_flush(CamelStream *stream)
{
EMHTMLStream *emhs = (EMHTMLStream *)stream;
if (emhs->html_stream == NULL)
return -1;
gtk_html_flush (emhs->html);
return 0;
}
static int
emhs_sync_close (CamelStream *stream)
{
EMHTMLStream *emhs = (EMHTMLStream *)stream;
if (emhs->html_stream == NULL)
return -1;
gtk_html_stream_close (emhs->html_stream, GTK_HTML_STREAM_OK);
emhs_cleanup (emhs);
return 0;
}
static void
em_html_stream_class_init (EMHTMLStreamClass *class)
{
EMSyncStreamClass *sync_stream_class;
parent_class = (EMSyncStreamClass *)em_sync_stream_get_type();
sync_stream_class = EM_SYNC_STREAM_CLASS (class);
sync_stream_class->sync_write = emhs_sync_write;
sync_stream_class->sync_flush = emhs_sync_flush;
sync_stream_class->sync_close = emhs_sync_close;
}
static void
em_html_stream_init (EMHTMLStream *emhs)
{
}
static void
em_html_stream_finalize (EMHTMLStream *emhs)
{
if (emhs->html_stream) {
/* set 'in finalise' flag */
camel_stream_close (CAMEL_STREAM (emhs));
}
}
CamelType
em_html_stream_get_type (void)
{
static CamelType type = CAMEL_INVALID_TYPE;
if (G_UNLIKELY (type == CAMEL_INVALID_TYPE)) {
type = camel_type_register (
em_sync_stream_get_type(),
"EMHTMLStream",
sizeof (EMHTMLStream),
sizeof (EMHTMLStreamClass),
(CamelObjectClassInitFunc) em_html_stream_class_init,
NULL,
(CamelObjectInitFunc) em_html_stream_init,
(CamelObjectFinalizeFunc) em_html_stream_finalize);
}
return type;
}
/* TODO: Could pass NULL for html_stream, and do a gtk_html_begin
on first data -> less flashing */
CamelStream *
em_html_stream_new (GtkHTML *html,
GtkHTMLStream *html_stream)
{
EMHTMLStream *new;
g_return_val_if_fail (GTK_IS_HTML (html), NULL);
new = EM_HTML_STREAM (camel_object_new (EM_HTML_STREAM_TYPE));
new->html_stream = html_stream;
new->html = g_object_ref (html);
new->flags = 0;
new->destroy_id = g_signal_connect (
html, "destroy",
G_CALLBACK (emhs_gtkhtml_destroy), new);
em_sync_stream_set_buffer_size (&new->sync, 8192);
return CAMEL_STREAM (new);
}
void
em_html_stream_set_flags (EMHTMLStream *emhs, GtkHTMLBeginFlags flags)
{
g_return_if_fail (EM_IS_HTML_STREAM (emhs));
emhs->flags = flags;
}