820 lines
20 KiB
C
820 lines
20 KiB
C
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
|
/*--------------------------------*-C-*---------------------------------*
|
|
*
|
|
* Copyright 2000, Matt Loper <matt@ximian.com>.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
|
|
*
|
|
*----------------------------------------------------------------------*/
|
|
|
|
#include <gnome.h>
|
|
#include <camel/camel.h>
|
|
#include <camel/camel-mime-message.h>
|
|
#include <camel/camel-stream.h>
|
|
#include <camel/camel-stream-fs.h>
|
|
#include <camel/gmime-utils.h>
|
|
#include "../../mail/html-stream.h"
|
|
#include <camel/camel-formatter.h>
|
|
|
|
/* gtkhtml stuff */
|
|
#include <gtkhtml/gtkhtml.h>
|
|
|
|
/* corba/bonobo stuff */
|
|
#include <bonobo.h>
|
|
#include <libgnorba/gnorba.h>
|
|
#include <bonobo/bonobo-stream-memory.h>
|
|
|
|
#include <widgets/e-paned/e-hpaned.h>
|
|
|
|
static void
|
|
print_usage_and_quit()
|
|
{
|
|
g_print ("Usage: message-browser [FILENAME]\n");
|
|
g_print ("Where FILENAME is the filename of a mime message ");
|
|
g_print ("in \"message/rfc822\" format.\n");
|
|
exit (0);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*
|
|
* Filling out the tree control view of a mime-message
|
|
*----------------------------------------------------------------------*/
|
|
|
|
static void
|
|
handle_tree_item (CamelDataWrapper* object, GtkWidget* tree_ctrl)
|
|
{
|
|
GtkWidget* tree_item;
|
|
gchar* label = gmime_content_field_get_mime_type (object->mime_type);
|
|
|
|
CamelDataWrapper* containee;
|
|
GtkWidget* containee_tree_item;
|
|
gchar* containee_label;
|
|
|
|
GtkWidget* subtree = NULL;
|
|
|
|
tree_item = gtk_tree_item_new_with_label (label);
|
|
gtk_object_set_data (GTK_OBJECT (tree_item),
|
|
"camel_data_wrapper", object);
|
|
gtk_tree_append (GTK_TREE (tree_ctrl), tree_item);
|
|
|
|
gtk_widget_show(tree_item);
|
|
|
|
/* If our object is a leaf, we're done */
|
|
if (!CAMEL_IS_MEDIUM (object))
|
|
return;
|
|
|
|
containee =
|
|
camel_medium_get_content_object (
|
|
CAMEL_MEDIUM (object));
|
|
|
|
g_assert (containee);
|
|
|
|
/* If it is a container, insert its contents into the tree */
|
|
containee_label = camel_data_wrapper_get_mime_type (containee);
|
|
|
|
subtree = gtk_tree_new();
|
|
|
|
containee_tree_item =
|
|
gtk_tree_item_new_with_label (containee_label);
|
|
gtk_object_set_data (GTK_OBJECT (containee_tree_item),
|
|
"camel_data_wrapper",
|
|
containee);
|
|
gtk_tree_append (GTK_TREE (subtree), containee_tree_item);
|
|
|
|
gtk_tree_item_set_subtree (GTK_TREE_ITEM(tree_item),
|
|
GTK_WIDGET (subtree));
|
|
gtk_widget_show(containee_tree_item);
|
|
|
|
if (CAMEL_IS_MULTIPART (containee))
|
|
{
|
|
CamelMultipart* multipart =
|
|
CAMEL_MULTIPART (containee);
|
|
int max_multiparts =
|
|
camel_multipart_get_number (multipart);
|
|
int i;
|
|
|
|
if (max_multiparts > 0) {
|
|
subtree = gtk_tree_new();
|
|
gtk_tree_item_set_subtree (
|
|
GTK_TREE_ITEM(containee_tree_item),
|
|
GTK_WIDGET (subtree));
|
|
}
|
|
|
|
for (i = 0; i < max_multiparts; i++) {
|
|
CamelMimeBodyPart* body_part =
|
|
camel_multipart_get_part (
|
|
multipart, i);
|
|
|
|
handle_tree_item (
|
|
CAMEL_DATA_WRAPPER (body_part),
|
|
GTK_WIDGET (subtree));
|
|
}
|
|
|
|
}
|
|
gtk_tree_item_expand (
|
|
GTK_TREE_ITEM (containee_tree_item));
|
|
gtk_tree_item_expand (GTK_TREE_ITEM (tree_item));
|
|
}
|
|
|
|
static GtkWidget*
|
|
get_gtk_html_contents_window (CamelDataWrapper* data);
|
|
|
|
static void
|
|
tree_selection_changed( GtkWidget *tree )
|
|
{
|
|
GList *i;
|
|
|
|
i = GTK_TREE_SELECTION(tree);
|
|
while (i){
|
|
gchar* name;
|
|
GtkLabel* label;
|
|
GtkWidget* item;
|
|
CamelDataWrapper* camel_data_wrapper;
|
|
|
|
/* Get a GtkWidget pointer from the list node */
|
|
item = GTK_WIDGET (i->data);
|
|
camel_data_wrapper =
|
|
gtk_object_get_data (GTK_OBJECT (item),
|
|
"camel_data_wrapper");
|
|
|
|
g_assert (camel_data_wrapper);
|
|
get_gtk_html_contents_window (camel_data_wrapper);
|
|
|
|
label = GTK_LABEL (GTK_BIN (item)->child);
|
|
gtk_label_get (label, &name);
|
|
g_print ("\t%s on level %d\n", name, GTK_TREE
|
|
(item->parent)->level);
|
|
i = i->next;
|
|
}
|
|
}
|
|
|
|
static GtkWidget*
|
|
get_message_tree_ctrl (CamelMimeMessage* message)
|
|
{
|
|
static GtkWidget* scroll_wnd = NULL;
|
|
static GtkWidget* tree_ctrl = NULL;
|
|
|
|
/* create the tree control, if it doesn't exist already */
|
|
if (!tree_ctrl) {
|
|
|
|
tree_ctrl = gtk_tree_new ();
|
|
|
|
gtk_signal_connect (GTK_OBJECT(tree_ctrl),
|
|
"selection_changed",
|
|
GTK_SIGNAL_FUNC(tree_selection_changed),
|
|
tree_ctrl);
|
|
|
|
scroll_wnd = gtk_scrolled_window_new (NULL,NULL);
|
|
|
|
gtk_scrolled_window_add_with_viewport (
|
|
GTK_SCROLLED_WINDOW(scroll_wnd),
|
|
tree_ctrl);
|
|
|
|
gtk_widget_set_usize (scroll_wnd, 225, 200);
|
|
}
|
|
else
|
|
gtk_tree_clear_items (GTK_TREE (tree_ctrl), 0, 1);
|
|
|
|
|
|
/* Recursively insert tree items in the tree */
|
|
if (message)
|
|
handle_tree_item (CAMEL_DATA_WRAPPER (message), tree_ctrl);
|
|
gtk_scrolled_window_set_policy (
|
|
GTK_SCROLLED_WINDOW (scroll_wnd),
|
|
GTK_POLICY_AUTOMATIC,
|
|
GTK_POLICY_AUTOMATIC);
|
|
return scroll_wnd;
|
|
}
|
|
|
|
static CamelMimeMessage*
|
|
filename_to_camel_msg (gchar* filename)
|
|
{
|
|
CamelMimeMessage* message;
|
|
CamelStream* input_stream;
|
|
|
|
camel_init();
|
|
|
|
input_stream = camel_stream_fs_new_with_name (
|
|
filename, CAMEL_STREAM_FS_READ);
|
|
|
|
if (!input_stream)
|
|
return NULL;
|
|
|
|
message = camel_mime_message_new ();
|
|
|
|
camel_data_wrapper_set_input_stream (
|
|
CAMEL_DATA_WRAPPER (message), input_stream);
|
|
|
|
return message;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*
|
|
* Filling out the HTML view of a mime message
|
|
*----------------------------------------------------------------------*/
|
|
|
|
static void
|
|
data_wrapper_to_html (CamelDataWrapper *msg, gchar** body_string)
|
|
{
|
|
CamelFormatter* cmf = camel_formatter_new();
|
|
CamelStream* body_stream =
|
|
camel_stream_mem_new (CAMEL_STREAM_FS_WRITE);
|
|
|
|
g_assert (body_string);
|
|
|
|
camel_formatter_wrapper_to_html (
|
|
cmf, msg, body_stream);
|
|
|
|
*body_string = g_strndup (
|
|
CAMEL_STREAM_MEM (body_stream)->buffer->data,
|
|
CAMEL_STREAM_MEM (body_stream)->buffer->len);
|
|
}
|
|
|
|
static void
|
|
mime_message_header_to_html (CamelMimeMessage *msg, gchar** header_string)
|
|
{
|
|
CamelFormatter* cmf = camel_formatter_new();
|
|
CamelStream* header_stream =
|
|
camel_stream_mem_new (CAMEL_STREAM_FS_WRITE);
|
|
|
|
g_assert (header_string);
|
|
|
|
camel_formatter_mime_message_to_html (
|
|
cmf, CAMEL_MIME_MESSAGE (msg), header_stream, NULL);
|
|
|
|
*header_string = g_strndup (
|
|
CAMEL_STREAM_MEM (header_stream)->buffer->data,
|
|
CAMEL_STREAM_MEM (header_stream)->buffer->len);
|
|
}
|
|
|
|
|
|
static void
|
|
on_link_clicked (GtkHTML *html, const gchar *url, gpointer data)
|
|
{
|
|
GtkWidget* message_box;
|
|
CamelStream *stream;
|
|
CamelStream *save_stream;
|
|
gchar tmp_buffer[4096];
|
|
gint nb_bytes_read;
|
|
|
|
gchar* message =
|
|
g_strdup_printf ("You have clicked on this link:\n%s", url);
|
|
|
|
if (sscanf (url, "camel://%p", &stream))
|
|
{
|
|
save_stream =
|
|
camel_stream_fs_new_with_name ("saved-file",
|
|
CAMEL_STREAM_FS_WRITE);
|
|
|
|
|
|
do {
|
|
|
|
/* read next chunk of text */
|
|
nb_bytes_read = camel_stream_read (stream,
|
|
tmp_buffer,
|
|
4096);
|
|
|
|
/* If there's any text, write it to the stream */
|
|
if (nb_bytes_read > 0) {
|
|
camel_stream_write (save_stream,
|
|
tmp_buffer,
|
|
nb_bytes_read);
|
|
}
|
|
|
|
|
|
} while (!camel_stream_eos (stream));
|
|
|
|
camel_stream_close (save_stream);
|
|
}
|
|
|
|
message_box = gnome_message_box_new (message,
|
|
GNOME_MESSAGE_BOX_INFO,
|
|
"Okay", NULL);
|
|
|
|
gnome_dialog_set_default (GNOME_DIALOG (message_box), 1);
|
|
gnome_dialog_run (GNOME_DIALOG (message_box));
|
|
g_free (message);
|
|
}
|
|
|
|
/*
|
|
* As a page is being loaded, gtkhtml will come across a few types of
|
|
* tags that it understands (like <img src="foo">). In these cases, it
|
|
* will simply ask us to stream the data to it.
|
|
*/
|
|
static void
|
|
on_url_data_requested (GtkHTML *html, const gchar *url, GtkHTMLStreamHandle handle, gpointer data)
|
|
{
|
|
CamelStream *stream;
|
|
|
|
printf ("url _%s_ (%p) requested\n", url, url);
|
|
|
|
if (sscanf (url, "camel://%p", &stream) == 1)
|
|
{
|
|
gchar tmp_buffer[4096];
|
|
do {
|
|
gint nb_bytes_read;
|
|
|
|
/* read next chunk of text */
|
|
nb_bytes_read = camel_stream_read (stream,
|
|
tmp_buffer,
|
|
4096);
|
|
|
|
/* If there's any text, write it to the stream */
|
|
if (nb_bytes_read > 0) {
|
|
gtk_html_write (html, handle, tmp_buffer, nb_bytes_read);
|
|
}
|
|
|
|
|
|
} while (!camel_stream_eos (stream));
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
static gboolean
|
|
hydrate_persist_stream_from_gstring (Bonobo_PersistStream persist_stream,
|
|
GString* gstr)
|
|
{
|
|
CORBA_Environment ev;
|
|
BonoboStream* mem_stream =
|
|
bonobo_stream_mem_create (gstr->str, gstr->len, TRUE, FALSE);
|
|
/*
|
|
* If the component doesn't support
|
|
* PersistStream, then we destroy the
|
|
* stream we created and bail.
|
|
*/
|
|
if (persist_stream == CORBA_OBJECT_NIL) {
|
|
gnome_warning_dialog (_("The component now claims that it "
|
|
"doesn't support PersistStream!"));
|
|
bonobo_object_unref (BONOBO_OBJECT (mem_stream));
|
|
return FALSE;
|
|
}
|
|
|
|
CORBA_exception_init (&ev);
|
|
|
|
/*
|
|
* Load the file into the component using PersistStream.
|
|
*/
|
|
Bonobo_PersistStream_load (persist_stream,
|
|
(Bonobo_Stream) bonobo_object_corba_objref (BONOBO_OBJECT (mem_stream)),
|
|
&ev);
|
|
|
|
bonobo_object_unref (BONOBO_OBJECT (mem_stream));
|
|
|
|
if (ev._major != CORBA_NO_EXCEPTION) {
|
|
gnome_warning_dialog (_("An exception occured while trying "
|
|
"to load data into the component with "
|
|
"PersistStream"));
|
|
CORBA_exception_free (&ev);
|
|
return FALSE;
|
|
}
|
|
|
|
CORBA_exception_free (&ev);
|
|
return TRUE;
|
|
}
|
|
|
|
static GString*
|
|
camel_stream_to_gstring (CamelStream* stream)
|
|
{
|
|
gchar tmp_buffer[4097];
|
|
GString *tmp_gstring = g_string_new ("");
|
|
|
|
do { /* read next chunk of text */
|
|
|
|
gint nb_bytes_read;
|
|
|
|
nb_bytes_read = camel_stream_read (stream,
|
|
tmp_buffer,
|
|
4096);
|
|
tmp_buffer [nb_bytes_read] = '\0';
|
|
|
|
/* If there's any text, append it to the gstring */
|
|
if (nb_bytes_read > 0) {
|
|
tmp_gstring = g_string_append (tmp_gstring, tmp_buffer);
|
|
}
|
|
|
|
} while (!camel_stream_eos (stream));
|
|
|
|
return tmp_gstring;
|
|
}
|
|
|
|
|
|
/*
|
|
* As a page is loaded, when gtkhtml comes across <object> tags, this
|
|
* callback is invoked. The GtkHTMLEmbedded param is a GtkContainer;
|
|
* our job in this function is to simply add a child widget to it.
|
|
*/
|
|
static void
|
|
on_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, void *unused)
|
|
{
|
|
CamelStream *stream;
|
|
GString *camel_stream_gstr;
|
|
|
|
GtkWidget *bonobo_embeddable;
|
|
BonoboObjectClient* server;
|
|
Bonobo_PersistStream persist;
|
|
CORBA_Environment ev;
|
|
gchar *uid = gtk_html_embedded_get_parameter (eb, "uid");
|
|
|
|
/* Both the classid (which specifies which bonobo object to
|
|
* fire up) and the uid (which tells us where to find data to
|
|
* persist from) must be available; if one of them isn't,
|
|
* print an error and bail. */
|
|
if (!uid || !eb->classid) {
|
|
printf ("on_object_requested: couldn't find %s%s%s\n",
|
|
uid?"a uid":"",
|
|
(!uid && !eb->classid)?" or ":"",
|
|
eb->classid?"a classid":"");
|
|
return;
|
|
}
|
|
printf ("object requested : %s\n", eb->classid);
|
|
printf ("UID = %s\n", uid);
|
|
|
|
/* Try to get a server with goadid specified by eb->classid */
|
|
bonobo_embeddable = bonobo_widget_new_subdoc (eb->classid, NULL);
|
|
server = bonobo_widget_get_server (BONOBO_WIDGET (bonobo_embeddable));
|
|
if (!server) {
|
|
printf ("Couldn't get the server for the bonobo embeddable\n");
|
|
return;
|
|
}
|
|
|
|
/* The UID should be a pointer to a CamelStream */
|
|
if (sscanf (uid, "camel://%p", &stream) != 1) {
|
|
printf ("Couldn't get a pointer from url \"%s\"\n", uid);
|
|
gtk_object_unref (GTK_OBJECT (bonobo_embeddable));
|
|
|
|
return;
|
|
}
|
|
|
|
/* Try to get a PersistStream interface from the server;
|
|
if it doesn't support that interface, bail. */
|
|
persist = (Bonobo_PersistStream) bonobo_object_client_query_interface (
|
|
server,
|
|
"IDL:Bonobo/PersistStream:1.0",
|
|
NULL);
|
|
|
|
if (persist == CORBA_OBJECT_NIL) {
|
|
gchar* msg = g_strdup_printf (
|
|
_("The %s component doesn't support PersistStream!\n"),
|
|
uid);
|
|
|
|
gnome_warning_dialog (msg);
|
|
gtk_object_unref (GTK_OBJECT (bonobo_embeddable));
|
|
|
|
return;
|
|
}
|
|
|
|
/* Hydrate the PersistStream from the CamelStream */
|
|
camel_stream_gstr = camel_stream_to_gstring (stream);
|
|
printf ("on_object_requested: The CamelStream has %d elements\n",
|
|
camel_stream_gstr->len);
|
|
hydrate_persist_stream_from_gstring (persist, camel_stream_gstr);
|
|
|
|
/* Give our new window to the container */
|
|
gtk_widget_show (bonobo_embeddable);
|
|
gtk_container_add (GTK_CONTAINER(eb), bonobo_embeddable);
|
|
|
|
/* Destroy the PersistStream object.*/
|
|
CORBA_exception_init (&ev);
|
|
Bonobo_Unknown_unref (persist, &ev);
|
|
CORBA_Object_release (persist, &ev);
|
|
CORBA_exception_free (&ev);
|
|
|
|
g_string_free (camel_stream_gstr, TRUE);
|
|
}
|
|
|
|
|
|
|
|
|
|
static GtkWidget*
|
|
get_gtk_html_contents_window (CamelDataWrapper* data)
|
|
{
|
|
static GtkWidget* frame_wnd = NULL;
|
|
static GtkWidget* scroll_wnd = NULL;
|
|
static GtkWidget* html_widget = NULL;
|
|
HTMLStream* html_stream;
|
|
gchar *body_string;
|
|
|
|
/* create the html widget and scroll window, if they haven't
|
|
already been created */
|
|
if (!html_widget) {
|
|
html_widget = gtk_html_new();
|
|
|
|
gtk_signal_connect (GTK_OBJECT (html_widget),
|
|
"link_clicked",
|
|
GTK_SIGNAL_FUNC (on_link_clicked),
|
|
NULL);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (html_widget),
|
|
"url_requested",
|
|
GTK_SIGNAL_FUNC (on_url_data_requested),
|
|
NULL);
|
|
gtk_signal_connect (GTK_OBJECT (html_widget),
|
|
"object_requested",
|
|
GTK_SIGNAL_FUNC (on_object_requested),
|
|
NULL);
|
|
|
|
scroll_wnd = gtk_scrolled_window_new (NULL, NULL);
|
|
gtk_container_add (GTK_CONTAINER (scroll_wnd), html_widget);
|
|
}
|
|
|
|
if (data) {
|
|
|
|
html_stream =
|
|
HTML_STREAM (html_stream_new (GTK_HTML (html_widget)));
|
|
|
|
/* turn the mime message into html, and
|
|
write it to the html stream */
|
|
data_wrapper_to_html (data, &body_string);
|
|
|
|
camel_stream_write (CAMEL_STREAM (html_stream),
|
|
body_string,
|
|
strlen (body_string));
|
|
|
|
camel_stream_close (CAMEL_STREAM (html_stream));
|
|
|
|
g_free (body_string);
|
|
}
|
|
|
|
|
|
if (!frame_wnd) {
|
|
|
|
frame_wnd = gtk_frame_new (NULL);
|
|
gtk_frame_set_shadow_type (
|
|
GTK_FRAME (frame_wnd), GTK_SHADOW_IN);
|
|
|
|
gtk_widget_set_usize (scroll_wnd, 500, 400);
|
|
gtk_scrolled_window_set_policy (
|
|
GTK_SCROLLED_WINDOW (scroll_wnd),
|
|
GTK_POLICY_AUTOMATIC,
|
|
GTK_POLICY_AUTOMATIC);
|
|
|
|
gtk_container_add (GTK_CONTAINER (frame_wnd), scroll_wnd);
|
|
}
|
|
|
|
return frame_wnd;
|
|
}
|
|
|
|
|
|
static GtkWidget*
|
|
get_gtk_html_header_window (CamelMimeMessage* mime_message)
|
|
{
|
|
static GtkWidget* frame_wnd = NULL;
|
|
static GtkWidget* scroll_wnd = NULL;
|
|
static GtkWidget* html_widget = NULL;
|
|
HTMLStream* html_stream;
|
|
gchar* header_string;
|
|
|
|
/* create the html widget and scroll window, if they haven't
|
|
already been created */
|
|
if (!html_widget) {
|
|
html_widget = gtk_html_new();
|
|
scroll_wnd = gtk_scrolled_window_new (NULL, NULL);
|
|
gtk_container_add (GTK_CONTAINER (scroll_wnd), html_widget);
|
|
}
|
|
|
|
if (mime_message) {
|
|
|
|
html_stream =
|
|
HTML_STREAM (html_stream_new (GTK_HTML (html_widget)));
|
|
|
|
/* turn the mime message into html, and
|
|
write it to the html stream */
|
|
mime_message_header_to_html (mime_message, &header_string);
|
|
|
|
camel_stream_write (CAMEL_STREAM (html_stream),
|
|
header_string,
|
|
strlen (header_string));
|
|
|
|
camel_stream_close (CAMEL_STREAM (html_stream));
|
|
|
|
g_free (header_string);
|
|
}
|
|
|
|
if (!frame_wnd) {
|
|
|
|
frame_wnd = gtk_frame_new (NULL);
|
|
gtk_frame_set_shadow_type (
|
|
GTK_FRAME (frame_wnd), GTK_SHADOW_OUT);
|
|
|
|
gtk_widget_set_usize (scroll_wnd, 500, 75);
|
|
gtk_scrolled_window_set_policy (
|
|
GTK_SCROLLED_WINDOW (scroll_wnd),
|
|
GTK_POLICY_AUTOMATIC,
|
|
GTK_POLICY_AUTOMATIC);
|
|
|
|
gtk_container_add (GTK_CONTAINER (frame_wnd), scroll_wnd);
|
|
}
|
|
|
|
|
|
return frame_wnd;
|
|
}
|
|
|
|
static GtkWidget*
|
|
get_gtk_html_window (CamelMimeMessage* mime_message)
|
|
{
|
|
static GtkWidget* vbox = NULL;
|
|
GtkWidget* html_header_window = NULL;
|
|
GtkWidget* html_content_window = NULL;
|
|
|
|
html_content_window =
|
|
get_gtk_html_contents_window (
|
|
CAMEL_DATA_WRAPPER (mime_message));
|
|
|
|
html_header_window =
|
|
get_gtk_html_header_window (mime_message);
|
|
|
|
if (!vbox) {
|
|
vbox = gtk_vbox_new (FALSE, 0);
|
|
|
|
gtk_box_pack_start (
|
|
GTK_BOX (vbox),
|
|
html_header_window,
|
|
TRUE, TRUE, 5);
|
|
|
|
gtk_box_pack_start (
|
|
GTK_BOX (vbox),
|
|
html_content_window,
|
|
TRUE, FALSE, 5);
|
|
}
|
|
|
|
return vbox;
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------*
|
|
* Menu callbacks and information
|
|
*----------------------------------------------------------------------*/
|
|
|
|
static gchar* fileselection_prev_file = NULL;
|
|
|
|
static void
|
|
open_ok (GtkWidget *widget, GtkFileSelection *fs)
|
|
{
|
|
int ret;
|
|
GtkWidget *error_dialog;
|
|
|
|
if (fileselection_prev_file)
|
|
g_free (fileselection_prev_file);
|
|
|
|
if(!g_file_exists (gtk_file_selection_get_filename (fs))) {
|
|
error_dialog = gnome_message_box_new (
|
|
_("File not found"),
|
|
GNOME_MESSAGE_BOX_ERROR,
|
|
GNOME_STOCK_BUTTON_OK,
|
|
NULL);
|
|
|
|
gnome_dialog_set_parent (GNOME_DIALOG (error_dialog),
|
|
GTK_WINDOW (fs));
|
|
|
|
ret = gnome_dialog_run (GNOME_DIALOG (error_dialog));
|
|
}
|
|
else {
|
|
gchar *filename = gtk_file_selection_get_filename (fs);
|
|
CamelMimeMessage* message = filename_to_camel_msg (filename);
|
|
|
|
if (message) {
|
|
fileselection_prev_file = g_strdup (filename);
|
|
get_message_tree_ctrl (message);
|
|
get_gtk_html_window (message);
|
|
}
|
|
else
|
|
gnome_message_box_new ("Couldn't load message.",
|
|
GNOME_MESSAGE_BOX_WARNING);
|
|
|
|
gtk_widget_destroy (GTK_WIDGET (fs));
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
file_menu_open_cb (GtkWidget *widget, void* data)
|
|
{
|
|
GtkFileSelection *fs;
|
|
|
|
fs = GTK_FILE_SELECTION (
|
|
gtk_file_selection_new (_("Open Mime Message")));
|
|
|
|
if (fileselection_prev_file)
|
|
gtk_file_selection_set_filename (fs, fileselection_prev_file);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked",
|
|
(GtkSignalFunc) open_ok,
|
|
fs);
|
|
|
|
gtk_signal_connect_object (GTK_OBJECT (fs->cancel_button), "clicked",
|
|
(GtkSignalFunc) gtk_widget_destroy,
|
|
GTK_OBJECT (fs));
|
|
|
|
gtk_widget_show (GTK_WIDGET (fs));
|
|
gtk_grab_add (GTK_WIDGET (fs)); /* Make it modal */
|
|
}
|
|
|
|
static void
|
|
file_menu_exit_cb (GtkWidget *widget, void *data)
|
|
{
|
|
gtk_main_quit ();
|
|
}
|
|
|
|
|
|
static GnomeUIInfo file_menu [] = {
|
|
GNOMEUIINFO_MENU_OPEN_ITEM (file_menu_open_cb, NULL),
|
|
GNOMEUIINFO_SEPARATOR,
|
|
GNOMEUIINFO_MENU_EXIT_ITEM (file_menu_exit_cb, NULL),
|
|
GNOMEUIINFO_END
|
|
};
|
|
|
|
static GnomeUIInfo main_menu[] = {
|
|
GNOMEUIINFO_MENU_FILE_TREE (file_menu),
|
|
GNOMEUIINFO_END
|
|
};
|
|
|
|
|
|
/*----------------------------------------------------------------------*
|
|
* Main()
|
|
*----------------------------------------------------------------------*/
|
|
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
/* app contains hbox, hbox contains other 2 windows */
|
|
GtkWidget* app;
|
|
GtkWidget* hpane;
|
|
GtkWidget* tree_ctrl_window;
|
|
GtkWidget* html_window;
|
|
CORBA_Environment ev;
|
|
|
|
CamelMimeMessage* message = NULL;
|
|
|
|
/* initialization */
|
|
|
|
/* Corba and Bonobo stuff */
|
|
CORBA_exception_init (&ev);
|
|
|
|
gnome_CORBA_init ("Message Browser", "1.0", &argc, argv, 0, &ev);
|
|
|
|
if (bonobo_init (gnome_CORBA_ORB (), NULL, NULL) == FALSE)
|
|
g_error ("Cannot bonobo_init");
|
|
|
|
|
|
|
|
gdk_rgb_init ();
|
|
|
|
gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
|
|
gtk_widget_set_default_visual (gdk_rgb_get_visual ());
|
|
|
|
app = gnome_app_new ("Message Browser Test", NULL);
|
|
gnome_app_create_menus (GNOME_APP (app), main_menu);
|
|
|
|
/* parse command line */
|
|
if (argc > 2 ||
|
|
(argc==2 && strstr (argv[1], "--help") != 0))
|
|
print_usage_and_quit();
|
|
if (argc == 2) {
|
|
if (strstr (argv[1], "--help") != 0)
|
|
print_usage_and_quit();
|
|
message = filename_to_camel_msg (argv[1]);
|
|
if (!message) {
|
|
g_print ("Couldn't load message.");
|
|
}
|
|
}
|
|
|
|
hpane = e_hpaned_new();
|
|
|
|
/* add the tree control view of the message*/
|
|
tree_ctrl_window = get_message_tree_ctrl (message);
|
|
e_paned_add1 (E_PANED (hpane), tree_ctrl_window);
|
|
|
|
/* add the HTML view of the message */
|
|
html_window = get_gtk_html_window (message);
|
|
e_paned_add2 (E_PANED (hpane), html_window);
|
|
|
|
/* rock n roll */
|
|
gnome_app_set_contents (GNOME_APP (app),
|
|
hpane);
|
|
gtk_widget_show_all (app);
|
|
gtk_signal_connect (GTK_OBJECT (app), "destroy",
|
|
GTK_SIGNAL_FUNC(gtk_main_quit),
|
|
&app);
|
|
if (!message)
|
|
file_menu_open_cb (NULL, NULL);
|
|
|
|
bonobo_main();
|
|
|
|
return 1;
|
|
}
|