diff options
Diffstat (limited to 'mail')
-rw-r--r-- | mail/ChangeLog | 18 | ||||
-rw-r--r-- | mail/Makefile.am | 3 | ||||
-rw-r--r-- | mail/e-attchmt.png | bin | 0 -> 169 bytes | |||
-rw-r--r-- | mail/folder-browser-factory.c | 4 | ||||
-rw-r--r-- | mail/folder-browser.c | 47 | ||||
-rw-r--r-- | mail/folder-browser.h | 11 | ||||
-rw-r--r-- | mail/html-stream.c | 27 | ||||
-rw-r--r-- | mail/mail-component.c | 2 | ||||
-rw-r--r-- | mail/mail-display.c | 384 | ||||
-rw-r--r-- | mail/mail-display.h | 36 | ||||
-rw-r--r-- | mail/message-list.c | 153 | ||||
-rw-r--r-- | mail/message-list.h | 15 | ||||
-rw-r--r-- | mail/session.c | 8 | ||||
-rw-r--r-- | mail/test-mail.c | 8 |
14 files changed, 634 insertions, 82 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index f5e7dd91c0..7f1d86c372 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,21 @@ +2000-03-05 bertrand <bertrand@helixcode.com> + + * message-list.h: include a referrence to the parent + folder browser. + + * message-list.c (ml_value_at): use the message summary + from the + + * html-stream.c (html_stream_close): when the stream + is closed, set the html stream to NULL + (html_stream_write): don't write anything if the + html handle does not exist. + (html_stream_reset): implemented. close the current + html handle and begins a new html parser. + + * session.c (session_store_new): use static exception + here. + 2000-03-05 Christopher James Lahey <clahey@helixcode.com> * message-list.c: Added a prototype message listing. diff --git a/mail/Makefile.am b/mail/Makefile.am index 5659053b79..7fd2e98c7d 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -2,6 +2,9 @@ bin_PROGRAMS = evolution-mail test-mail providerdir = $(libdir)/evolution/camel-providers/$(VERSION) +EXTRA_DIST = e-attchmt.png +pkgdata_DATA = e-attchmt.png + INCLUDES = \ -I$(top_srcdir)/widgets \ -I$(top_srcdir)/widgets/e-text \ diff --git a/mail/e-attchmt.png b/mail/e-attchmt.png Binary files differnew file mode 100644 index 0000000000..b4bac8db67 --- /dev/null +++ b/mail/e-attchmt.png diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c index d79a6bbb25..45736e098e 100644 --- a/mail/folder-browser-factory.c +++ b/mail/folder-browser-factory.c @@ -44,9 +44,9 @@ folder_browser_factory (BonoboGenericFactory *factory, void *closure) } - /*bonobo_control_set_property_bag ( + bonobo_control_set_property_bag ( control, - FOLDER_BROWSER (folder_browser)->properties);*/ + FOLDER_BROWSER (folder_browser)->properties); return BONOBO_OBJECT (control); diff --git a/mail/folder-browser.c b/mail/folder-browser.c index 85a09395a8..b305616bf8 100644 --- a/mail/folder-browser.c +++ b/mail/folder-browser.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * folder-browser.c: Folder browser top level component * @@ -6,21 +7,26 @@ * * (C) 2000 Helix Code, Inc. */ - #include <config.h> #include <gnome.h> #include "e-util/e-util.h" #include "camel/camel-exception.h" #include "folder-browser.h" #include "session.h" +#include "message-list.h" + #define PARENT_TYPE (gtk_table_get_type ()) static GtkObjectClass *folder_browser_parent_class; + #define PROPERTY_FOLDER_URI "folder_uri" #define PROPERTY_MESSAGE_PREVIEW "message_preview" + + + static void folder_browser_destroy (GtkObject *object) { @@ -50,25 +56,38 @@ static gboolean folder_browser_load_folder (FolderBrowser *fb, const char *name) { CamelFolder *new_folder; - CamelException *ex; + CamelException ex; + gboolean new_folder_exists = FALSE; - ex = camel_exception_new (); - new_folder = camel_store_get_folder (default_session->store, name, ex); + camel_exception_init (&ex); + new_folder = camel_store_get_folder (default_session->store, name, &ex); - if (camel_exception_get_id (ex)){ - camel_exception_free (ex); + if (camel_exception_get_id (&ex)){ + printf ("Unable to get folder %s : %s\n", + name, + ex.desc?ex.desc:"unknown reason"); return FALSE; } - camel_exception_free (ex); + + /* if the folder does not exist, we don't want to show it */ + new_folder_exists = camel_folder_exists (new_folder, &ex); + if (camel_exception_get_id (&ex)) { + printf ("Unable to test for folder existence: %s\n", + ex.desc?ex.desc:"unknown reason"); + return FALSE; + } + + if (!new_folder_exists) { + gtk_object_unref (GTK_OBJECT (new_folder)); + return FALSE; + } + if (fb->folder) gtk_object_unref (GTK_OBJECT (fb->folder)); fb->folder = new_folder; - camel_folder_exists (new_folder, NULL); - printf ("In folder browser, folder = %p\n", new_folder); - message_list_set_folder (fb->message_list, new_folder); return TRUE; @@ -151,11 +170,11 @@ folder_browser_gui_init (FolderBrowser *fb) fb->message_list_w = message_list_get_widget (fb->message_list); gtk_paned_add1 (GTK_PANED (fb->vpaned), fb->message_list_w); gtk_widget_show (fb->message_list_w); -#if 0 + gtk_paned_add2 (GTK_PANED (fb->vpaned), GTK_WIDGET (fb->mail_display)); gtk_widget_show (GTK_WIDGET (fb->mail_display)); gtk_widget_show (GTK_WIDGET (fb)); -#endif + } static void @@ -177,8 +196,8 @@ my_folder_browser_init (GtkObject *object) /* * Our instance data */ - fb->message_list = MESSAGE_LIST (message_list_new ()); - fb->mail_display = MAIL_DISPLAY (mail_display_new ()); + fb->message_list = MESSAGE_LIST (message_list_new (fb)); + fb->mail_display = MAIL_DISPLAY (mail_display_new (fb)); folder_browser_properties_init (fb); folder_browser_gui_init (fb); diff --git a/mail/folder-browser.h b/mail/folder-browser.h index f845c9f98b..7692b1a20a 100644 --- a/mail/folder-browser.h +++ b/mail/folder-browser.h @@ -1,6 +1,7 @@ #ifndef _FOLDER_BROWSER_H_ #define _FOLDER_BROWSER_H_ +#include "mail-types.h" #include <gtk/gtktable.h> #include "camel/camel-stream.h" #include <bonobo/bonobo-property-bag.h> @@ -13,7 +14,8 @@ #define IS_FOLDER_BROWSER(o) (GTK_CHECK_TYPE ((o), FOLDER_BROWSER_TYPE)) #define IS_FOLDER_BROWSER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), FOLDER_BROWSER_TYPE)) -typedef struct { + +struct _FolderBrowser { GtkTable parent; BonoboPropertyBag *properties; @@ -29,12 +31,17 @@ typedef struct { MailDisplay *mail_display; GtkWidget *vpaned; gboolean preview_shown; -} FolderBrowser; + +}; + typedef struct { GtkTableClass parent_class; } FolderBrowserClass; + + + GtkType folder_browser_get_type (void); GtkWidget *folder_browser_new (void); void folder_browser_set_uri (FolderBrowser *folder_browser, diff --git a/mail/html-stream.c b/mail/html-stream.c index d3028dcdcd..31afe4bd25 100644 --- a/mail/html-stream.c +++ b/mail/html-stream.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * html-stream.c: A CamelStream class that feeds data into a GtkHTML widget * @@ -34,12 +35,32 @@ static gint html_stream_write (CamelStream *stream, const gchar *buffer, gint n) { HTMLStream *html_stream = HTML_STREAM (stream); - - gtk_html_write (html_stream->gtk_html, html_stream->gtk_html_stream, buffer, n); + + if (html_stream->gtk_html_stream) + gtk_html_write (html_stream->gtk_html, html_stream->gtk_html_stream, buffer, n); + else + n = 0; return n; } +/* + * CamelStream::Reset method + * + * Reset the html widget that is, prepare it + * for a new display + */ +static void +html_stream_reset (CamelStream *stream) +{ + HTMLStream *html_stream = HTML_STREAM (stream); + + if (html_stream->gtk_html_stream) + gtk_html_end (html_stream->gtk_html, html_stream->gtk_html_stream, GTK_HTML_STREAM_OK); + + html_stream->gtk_html_stream = gtk_html_begin (html_stream->gtk_html, ""); +} + /* * CamelStream::available method * @@ -68,6 +89,7 @@ html_stream_close (CamelStream *stream) HTMLStream *html_stream = HTML_STREAM (stream); gtk_html_end (html_stream->gtk_html, html_stream->gtk_html_stream, GTK_HTML_STREAM_OK); + html_stream->gtk_html_stream = NULL; } static void @@ -86,6 +108,7 @@ html_stream_class_init (GtkObjectClass *object_class) stream_class->read = html_stream_read; stream_class->write = html_stream_write; + stream_class->reset = html_stream_reset; stream_class->available = html_stream_available; stream_class->eos = html_stream_eos; stream_class->close = html_stream_close; diff --git a/mail/mail-component.c b/mail/mail-component.c index d1fca42e65..66d223ab2c 100644 --- a/mail/mail-component.c +++ b/mail/mail-component.c @@ -1,3 +1,5 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + /* * mail-component.c: The core of the mail component * diff --git a/mail/mail-display.c b/mail/mail-display.c index 7b0246b31c..01abcc008f 100644 --- a/mail/mail-display.c +++ b/mail/mail-display.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * mail-display.c: Mail display widget * @@ -11,24 +12,332 @@ #include "e-util/e-util.h" #include "mail-display.h" #include "html-stream.h" +#include "camel/camel-formatter.h" + +/* corba/bonobo stuff */ +#include <bonobo.h> +#include <libgnorba/gnorba.h> +#include <bonobo/bonobo-stream-memory.h> #define PARENT_TYPE (gtk_table_get_type ()) static GtkObjectClass *mail_display_parent_class; + + + + + +static gchar default_header_html_string[] = " +<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\"> +<html> +<head> + <meta name=\"GENERATOR\" content=\"Evolution Mail Component (Rhon Rhon release)\"> +</head> +<body text=\"#000000\" bgcolor=\"#999999\"> +<table CELLSPACING=0 WIDTH=\"100\%\"> +<tr> +<td><b>From: </b></td> +<td><b>To: </b></td> +</tr> + +<tr> +<td><b>Subject: </b></td> +<td><b>Cc: </b></td> +</tr> +</table> +</body> +</html> +"; + + + +static gchar default_body_html_string[] = " +<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\"> +<html> +<head> + <meta name=\"GENERATOR\" content=\"Evolution Mail Component (Rhon Rhon release)\"> +</head> +<body text=\"#000000\" bgcolor=\"#FFFFFF\"> +<center> +Nothing to display in this view +</center> +</body> +</html> +"; + + + +/* stuff to display Bonobo Components inside the html message + * body view */ +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); + /* + * 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"); + + printf ("Here\n"); + /* 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, FALSE); +} + + + +void +mail_display_set_message (MailDisplay *mail_display, + CamelMedium *medium) +{ + CamelFormatter *camel_formatter; + + /* okay, we should not create a formatter + * each time we need to display a message + * but I don't know how the formatter reacts + * to consecutive call to *_to_html - ber */ + camel_formatter = camel_formatter_new (); + + + /* + * for the moment, camel-formatter deals only with + * mime messages, but in the future, it should be + * able to deal with any medium. + * It can work on pretty much data wrapper, but in + * fact, only the medium class has the distinction + * header / body + */ + if (CAMEL_IS_MIME_MESSAGE (medium)) { + + /* + * reset the html stream to clean + * the gtkhtml widget + */ + camel_stream_reset (mail_display->body_stream); + camel_stream_reset (mail_display->headers_stream); + + /* + * convert the message into html + * and stream the result to the gtkhtml + * widgets + */ + camel_stream_write_string (mail_display->headers_stream, " +<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\"> +<html> +<head> + <meta name=\"GENERATOR\" content=\"Evolution Mail Component (Rhon Rhon release)\"> +</head> +<body text=\"#000000\" bgcolor=\"#999999\"> +<font> +");; + + camel_stream_write_string (mail_display->body_stream, " +<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\"> +<html> +<head> + <meta name=\"GENERATOR\" content=\"Evolution Mail Component (Rhon Rhon release)\"> +</head> +<body text=\"#000000\" bgcolor=\"#FFFFFF\"> +");; + + + camel_formatter_mime_message_to_html + (camel_formatter, + CAMEL_MIME_MESSAGE (medium), + mail_display->headers_stream, + mail_display->body_stream); + + + /*camel_formatter_wrapper_to_html (camel_formatter, + CAMEL_DATA_WRAPPER (medium), + mail_display->body_stream);*/ + + camel_stream_write_string (mail_display->headers_stream, " +</font> +</body> +</html> +");; + + camel_stream_write_string (mail_display->body_stream, " +</body> +</html> +");; + + camel_stream_close (mail_display->body_stream); + camel_stream_close (mail_display->headers_stream); + + } +} + + +/* generic class stuff */ + + static void mail_display_init (GtkObject *object) { MailDisplay *mail_display = MAIL_DISPLAY (object); - mail_display->html = (GtkHTML *) gtk_html_new (); - gtk_widget_show (GTK_WIDGET (mail_display->html)); + /* create the headers html widget */ + mail_display->headers_html_widget = (GtkHTML *) gtk_html_new (); + mail_display->headers_stream = html_stream_new (mail_display->headers_html_widget); + gtk_widget_show (GTK_WIDGET (mail_display->headers_html_widget)); + + /* create the body html widget */ + mail_display->body_html_widget = (GtkHTML *) gtk_html_new (); + gtk_signal_connect (GTK_OBJECT (mail_display->body_html_widget), + "object_requested", + GTK_SIGNAL_FUNC (on_object_requested), + NULL); + + mail_display->body_stream = html_stream_new (mail_display->body_html_widget); + gtk_widget_show (GTK_WIDGET (mail_display->body_html_widget)); } static void mail_display_destroy (GtkObject *object) { - MailDisplay *mail_display = MAIL_DISPLAY (object); + /* MailDisplay *mail_display = MAIL_DISPLAY (object); */ mail_display_parent_class->destroy (object); } @@ -41,28 +350,71 @@ mail_display_class_init (GtkObjectClass *object_class) } GtkWidget * -mail_display_new (void) +mail_display_new (FolderBrowser *parent_folder_browser) { MailDisplay *mail_display = gtk_type_new (mail_display_get_type ()); GtkTable *table = GTK_TABLE (mail_display); + GtkWidget *scroll_wnd; + GtkWidget* frame_wnd = NULL; + + g_assert (parent_folder_browser); + + mail_display->parent_folder_browser = parent_folder_browser; + + /* the table has table with 1 column and 2 lines */ + table->homogeneous = FALSE; + + gtk_table_resize (table, 1, 2); + gtk_widget_show (GTK_WIDGET (mail_display)); + + + /* create a scrolled window and put the headers + * html widget inside */ + scroll_wnd = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_wnd), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_NEVER); + frame_wnd = gtk_frame_new (NULL); + gtk_frame_set_shadow_type ( + GTK_FRAME (frame_wnd), GTK_SHADOW_OUT); + gtk_widget_show (scroll_wnd); + gtk_container_add (GTK_CONTAINER (frame_wnd), scroll_wnd); + gtk_widget_show (frame_wnd); + gtk_container_add (GTK_CONTAINER (scroll_wnd), + GTK_WIDGET (mail_display->headers_html_widget)); + gtk_widget_set_usize (GTK_WIDGET (scroll_wnd), -1, 50); + /* add it on the top part of the table */ + gtk_table_attach (table, GTK_WIDGET (frame_wnd), + 0, 1, 0, 1, + GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); + + + /* create a scrolled window and put the body + * html widget inside */ + scroll_wnd = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_wnd), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_ALWAYS); + + gtk_widget_show (scroll_wnd); + gtk_container_add (GTK_CONTAINER (scroll_wnd), + GTK_WIDGET (mail_display->body_html_widget)); - table->homogeneous = FALSE; - gtk_table_resize (table, 1, 2); + /* add it at the bottom part of the table */ + gtk_table_attach (table, GTK_WIDGET (scroll_wnd), + 0, 1, 1, 2, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + + /* write the default text to the html widgets */ + camel_stream_write_string (mail_display->headers_stream, default_header_html_string); + camel_stream_write_string (mail_display->body_stream, default_body_html_string); + - gtk_table_attach (table, GTK_WIDGET (mail_display->html), - 0, 1, 1, 2, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); return GTK_WIDGET (mail_display); } -CamelStream * -mail_display_get_stream (MailDisplay *mail_display) -{ - g_return_val_if_fail (mail_display != NULL, NULL); - g_return_val_if_fail (IS_MAIL_DISPLAY (mail_display), NULL); - return html_stream_new (mail_display->html); -} E_MAKE_TYPE (mail_display, "MailDisplay", MailDisplay, mail_display_class_init, mail_display_init, PARENT_TYPE); diff --git a/mail/mail-display.h b/mail/mail-display.h index cb74d5c390..804be904f8 100644 --- a/mail/mail-display.h +++ b/mail/mail-display.h @@ -1,9 +1,25 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + + + + + + + + + + + + #ifndef _MAIL_DISPLAY_H_ #define _MAIL_DISPLAY_H_ #include <gtk/gtktable.h> #include <gtkhtml/gtkhtml.h> #include "camel/camel-stream.h" +#include "camel/camel-mime-message.h" +#include "folder-browser.h" + #define MAIL_DISPLAY_TYPE (mail_display_get_type ()) #define MAIL_DISPLAY(o) (GTK_CHECK_CAST ((o), MAIL_DISPLAY_TYPE, MailDisplay)) @@ -11,19 +27,29 @@ #define IS_MAIL_DISPLAY(o) (GTK_CHECK_TYPE ((o), MAIL_DISPLAY_TYPE)) #define IS_MAIL_DISPLAY_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), MAIL_DISPLAY_TYPE)) -typedef struct { +struct _MailDisplay { GtkTable parent; - GtkHTML *html; -} MailDisplay; + FolderBrowser *parent_folder_browser; + + GtkHTML * headers_html_widget; + CamelStream * headers_stream; + + GtkHTML * body_html_widget; + CamelStream * body_stream; + +}; typedef struct { GtkTableClass parent_class; } MailDisplayClass; GtkType mail_display_get_type (void); -GtkWidget *mail_display_new (void); +GtkWidget * mail_display_new (FolderBrowser *parent_folder_browser); + +void mail_display_set_message (MailDisplay *mail_display, + CamelMedium *medium); + -CamelStream *mail_display_get_stream (MailDisplay *display); #endif /* _MAIL_DISPLAY_H_ */ diff --git a/mail/message-list.c b/mail/message-list.c index 1a5913df25..3870b412a7 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * message-list.c: Displays the messages. * Implements CORBA's Evolution::MessageList @@ -25,6 +26,7 @@ #define N_CHARS(x) (CHAR_WIDTH * (x)) #define COL_ICON_WIDTH 16 +#define COL_CHECK_BOX_WIDTH 16 #define COL_FROM_WIDTH N_CHARS(24) #define COL_FROM_WIDTH_MIN 32 #define COL_SUBJECT_WIDTH N_CHARS(30) @@ -59,18 +61,23 @@ static int ml_row_count (ETableModel *etm, void *data) { MessageList *message_list = data; - CamelException *ex; + CamelException ex; int v; if (!message_list->folder) return 0; - ex = camel_exception_new (); - v = camel_folder_get_message_count (message_list->folder, ex); - printf ("number of messages in the folder = %d\n", v); - camel_exception_free (ex); + camel_exception_init (&ex); + + v = camel_folder_get_message_count (message_list->folder, &ex); + if (camel_exception_get_id (&ex)) + v = 0; + + + /* in the case where no message is available, return 1 + * however, cause we want to be able to show a text */ + return (v ? v:1); - return v; } static void * @@ -79,17 +86,30 @@ ml_value_at (ETableModel *etm, int col, int row, void *data) static char buffer [10]; MessageList *message_list = data; CamelFolderSummary *summary; - const GArray *array; - CamelMessageInfo *info; - CamelException *ex; - CamelMimeMessage *message; + const GArray *msg_info_array; + CamelMessageInfo msg_info; + CamelException ex; + + camel_exception_init (&ex); + + summary = message_list->folder_summary; + if (!summary) + goto nothing_to_see; + + + /* retrieve the message information array */ + msg_info_array = camel_folder_summary_get_message_info_list (summary); + + /* + * in the case where it is zero message long + * display nothing + */ + if (msg_info_array->len == 0) + goto nothing_to_see; + + msg_info = g_array_index (msg_info_array, CamelMessageInfo, row); + - ex = camel_exception_new (); - summary = camel_folder_get_summary(message_list->folder, ex); - array = camel_folder_summary_get_message_info_list(summary); - info = &g_array_index(array, CamelMessageInfo, row); - /*message = camel_folder_get_message_by_uid(message_list->folder, info->uid, ex);*/ - camel_exception_free (ex); switch (col){ case COL_ONLINE_STATUS: return GINT_TO_POINTER (0); @@ -104,23 +124,23 @@ ml_value_at (ETableModel *etm, int col, int row, void *data) return GINT_TO_POINTER (0); case COL_FROM: - if ( info->sender ) - return info->sender; - else - return ""; + if (msg_info.sender) + return msg_info.sender; + else + return ""; case COL_SUBJECT: - if ( info->subject ) - return info->subject; - else - return ""; + if (msg_info.subject) + return msg_info.subject; + else + return ""; case COL_SENT: return "sent"; case COL_RECEIVE: return "receive"; - + case COL_TO: return "dudes@server"; @@ -132,6 +152,17 @@ ml_value_at (ETableModel *etm, int col, int row, void *data) g_assert_not_reached (); } return NULL; + + + nothing_to_see : + /* + * in the case there is nothing to look at, + * notice the user. + */ + if (col == COL_SUBJECT) + return "No item in this view"; + else + return NULL; } static void @@ -200,6 +231,9 @@ ml_thaw (ETableModel *etm, void *data) static void message_list_init_renderers (MessageList *message_list) { + gchar *attachment_path; + GdkPixbuf *image; + g_assert (message_list); g_assert (message_list->table_model); @@ -209,7 +243,17 @@ message_list_init_renderers (MessageList *message_list) message_list->render_online_status = e_cell_checkbox_new (); message_list->render_message_status = e_cell_checkbox_new (); - message_list->render_attachment = e_cell_checkbox_new (); +#if 1 + message_list->render_attachment = e_cell_checkbox_new (); +#else + /* + * if we want to use a pixmap, use this code + */ + attachment_path = gnome_unconditional_datadir_file ("evolution/e-attchmt.png"); + image = gdk_pixbuf_new_from_file (attachment_path); + message_list->render_attachment = e_cell_toggle_new (0, 1, &image); + g_free (attachment_path); +#endif /* * FIXME: We need a real renderer here @@ -233,19 +277,19 @@ message_list_init_header (MessageList *message_list) message_list->table_cols [COL_ONLINE_STATUS] = e_table_col_new (COL_ONLINE_STATUS, _("Online status"), - COL_ICON_WIDTH, COL_ICON_WIDTH, + COL_CHECK_BOX_WIDTH, COL_CHECK_BOX_WIDTH, message_list->render_online_status, g_int_compare, FALSE); message_list->table_cols [COL_MESSAGE_STATUS] = e_table_col_new (COL_MESSAGE_STATUS, _("Message status"), - COL_ICON_WIDTH, COL_ICON_WIDTH, + COL_CHECK_BOX_WIDTH, COL_CHECK_BOX_WIDTH, message_list->render_message_status, g_int_compare, FALSE); message_list->table_cols [COL_PRIORITY] = e_table_col_new (COL_PRIORITY, _("Priority"), - COL_ICON_WIDTH, COL_ICON_WIDTH, + COL_CHECK_BOX_WIDTH, COL_CHECK_BOX_WIDTH, message_list->render_priority, g_int_compare, FALSE); @@ -302,6 +346,9 @@ message_list_init_header (MessageList *message_list) } } + + +#if 0 static void set_header_size (GnomeCanvas *canvas, GtkAllocation *alloc) { @@ -316,7 +363,7 @@ set_content_size (GnomeCanvas *canvas, GtkAllocation *alloc) gnome_canvas_set_scroll_region (canvas, 0, 0, alloc->width, alloc->height); } -#if 0 + static GtkWidget * make_etable (MessageList *message_list) { @@ -392,7 +439,7 @@ message_list_init (GtkObject *object) * The etable */ - message_list->etable = e_table_new (message_list->header_model, message_list->table_model, "<ETableSpecification> <columns-shown> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> <column> 5 </column> <column> 6 </column> <column> 7 </column> <column> 8 </column> <column> 9 </column> </columns-shown> <grouping> <group column=\"4\" ascending=\"1\"> <leaf column=\"0\" ascending=\"1\"/> </group> </grouping> </ETableSpecification>"); + message_list->etable = e_table_new (message_list->header_model, message_list->table_model, "<ETableSpecification> <columns-shown> <column> 0 </column> <column> 1 </column> <column> 2 </column> <column> 3 </column> <column> 4 </column> <column> 5 </column> <column> 6 </column> <column> 7 </column> <column> 8 </column> <column> 9 </column> </columns-shown> <grouping> <group column=\"4\" ascending=\"1\"> <leaf column=\"5\" ascending=\"1\"/> </group> </grouping> </ETableSpecification>"); gtk_widget_show(message_list->etable); @@ -512,11 +559,13 @@ create_corba_message_list (BonoboObject *object) } BonoboObject * -message_list_new (void) +message_list_new (FolderBrowser *parent_folder_browser) { Evolution_MessageList corba_object; MessageList *message_list; + g_assert (parent_folder_browser); + message_list = gtk_type_new (message_list_get_type ()); corba_object = create_corba_message_list (BONOBO_OBJECT (message_list)); @@ -525,6 +574,8 @@ message_list_new (void) return NULL; } + message_list->parent_folder_browser = parent_folder_browser; + message_list_construct (message_list, corba_object); return BONOBO_OBJECT (message_list); @@ -535,6 +586,7 @@ message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder) { CamelException ex; gboolean folder_exists; + CamelMimeMessage *message; g_return_if_fail (message_list != NULL); g_return_if_fail (camel_folder != NULL); @@ -584,17 +636,52 @@ message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder) message_list->folder_summary = camel_folder_get_summary (camel_folder, &ex); + if (camel_exception_get_id (&ex)) { printf ("Unable to get summary: %s\n", ex.desc?ex.desc:"unknown_reason"); return; } + gtk_object_ref (GTK_OBJECT (camel_folder)); - + printf ("Modelo cambio!\n"); e_table_model_changed (message_list->table_model); + + /* FIXME : put that in a separate function */ + /* display the (first) message (in this case) */ + if (camel_folder_has_uid_capability (camel_folder)) { + const GArray *msg_info_array; + CamelMessageInfo msg_info; + + msg_info_array = camel_folder_summary_get_message_info_list + (message_list->folder_summary); + + if (msg_info_array->len > 0 ) { + msg_info = g_array_index (msg_info_array, CamelMessageInfo, 0); + + message = camel_folder_get_message_by_uid (camel_folder, + msg_info.uid, + &ex); + if (camel_exception_get_id (&ex)) { + printf ("Unable to get message: %s\n", + ex.desc?ex.desc:"unknown_reason"); + return; + } + } + + printf ("Message = %p\n", message); + if (message) + mail_display_set_message (message_list->parent_folder_browser->mail_display, + CAMEL_MEDIUM (message)); + + + + } else + g_warning ("FIXME : folder does not support UIDS\n"); + } GtkWidget * diff --git a/mail/message-list.h b/mail/message-list.h index 40cc924e24..16e60c21f0 100644 --- a/mail/message-list.h +++ b/mail/message-list.h @@ -1,6 +1,8 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ #ifndef _MESSAGE_LIST_H_ #define _MESSAGE_LIST_H_ +#include "mail-types.h" #include <bonobo/bonobo-main.h> #include <bonobo/bonobo-object.h> #include "camel/camel-folder.h" @@ -9,6 +11,8 @@ #include "e-table/e-cell-text.h" #include "e-table/e-cell-toggle.h" #include "e-table/e-cell-checkbox.h" +#include "folder-browser.h" + #define MESSAGE_LIST_TYPE (message_list_get_type ()) #define MESSAGE_LIST(o) (GTK_CHECK_CAST ((o), MESSAGE_LIST_TYPE, MessageList)) @@ -18,6 +22,7 @@ typedef struct _Renderer Renderer; + enum { COL_ONLINE_STATUS, COL_MESSAGE_STATUS, @@ -33,9 +38,13 @@ enum { COL_LAST }; -typedef struct { +struct _MessageList { BonoboObject parent; + /* the folder browser that contains the + * this message list */ + FolderBrowser *parent_folder_browser; + ETableModel *table_model; ETableHeader *header_model; ETableCol *table_cols [COL_LAST]; @@ -50,14 +59,14 @@ typedef struct { CamelFolder *folder; CamelFolderSummary *folder_summary; -} MessageList; +} ; typedef struct { BonoboObjectClass parent_class; } MessageListClass; GtkType message_list_get_type (void); -BonoboObject *message_list_new (void); +BonoboObject *message_list_new (FolderBrowser *parent_folder_browser); void message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder); GtkWidget *message_list_get_widget (MessageList *message_list); diff --git a/mail/session.c b/mail/session.c index a97b70ed26..1005d9cd4e 100644 --- a/mail/session.c +++ b/mail/session.c @@ -63,12 +63,12 @@ SessionStore * session_store_new (const char *uri) { SessionStore *ss = g_new (SessionStore, 1); - CamelException *ex; + CamelException ex; ss->session = camel_session_new (evolution_auth_callback); - ex = camel_exception_new (); - ss->store = camel_session_get_store (ss->session, uri, ex); - camel_exception_free (ex); + camel_exception_init (&ex); + ss->store = camel_session_get_store (ss->session, uri, &ex); + g_assert (ss->session); g_assert (ss->store); diff --git a/mail/test-mail.c b/mail/test-mail.c index df9bd3dbcc..3d5174bdfa 100644 --- a/mail/test-mail.c +++ b/mail/test-mail.c @@ -16,8 +16,14 @@ create_container (void) GtkWidget *window, *control; BonoboUIHandler *uih; + gdk_rgb_init (); + + gtk_widget_set_default_colormap (gdk_rgb_get_cmap ()); + gtk_widget_set_default_visual (gdk_rgb_get_visual ()); + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_widget_show (window); + gtk_widget_set_usize (GTK_WIDGET (window), 640, 480); + gtk_widget_show (GTK_WIDGET (window)); uih = bonobo_ui_handler_new (); control = bonobo_widget_new_control ("GOADID:Evolution:FolderBrowser:1.0", |