evolution r34981 - in branches/mbarnes-composer: . addressbook/gui/widgets calendar/gui composer mail



Author: mbarnes
Date: Sat Feb  9 21:54:02 2008
New Revision: 34981
URL: http://svn.gnome.org/viewvc/evolution?rev=34981&view=rev

Log:
Replace the composer's Bonobo interface with a straight-forward API and
adapt the addressbook and calendar to use it.  Not surprisingly, a whole
bunch of complexity falls out.

Add GConfBridge to source control and bind the "current folder" GConf key
to the HTML editor's "current folder" GObject property.

Start destroying e-msg-composer-select-file.[ch].  Clean these functions
up and move them into e-msg-composer.c.


Added:
   branches/mbarnes-composer/composer/gconf-bridge.c
   branches/mbarnes-composer/composer/gconf-bridge.h
Removed:
   branches/mbarnes-composer/composer/Composer.idl
   branches/mbarnes-composer/composer/Evolution-Composer.idl
   branches/mbarnes-composer/composer/evolution-composer.c
   branches/mbarnes-composer/composer/evolution-composer.h
   branches/mbarnes-composer/composer/listener.c
   branches/mbarnes-composer/composer/listener.h
Modified:
   branches/mbarnes-composer/addressbook/gui/widgets/Makefile.am
   branches/mbarnes-composer/addressbook/gui/widgets/eab-gui-util.c
   branches/mbarnes-composer/calendar/gui/Makefile.am
   branches/mbarnes-composer/calendar/gui/itip-utils.c
   branches/mbarnes-composer/composer/Makefile.am
   branches/mbarnes-composer/composer/e-composer-actions.c
   branches/mbarnes-composer/composer/e-composer-private.h
   branches/mbarnes-composer/composer/e-msg-composer-select-file.c
   branches/mbarnes-composer/composer/e-msg-composer-select-file.h
   branches/mbarnes-composer/composer/e-msg-composer.c
   branches/mbarnes-composer/composer/e-msg-composer.h
   branches/mbarnes-composer/configure.in
   branches/mbarnes-composer/mail/em-composer-utils.c
   branches/mbarnes-composer/mail/mail-component-factory.c

Modified: branches/mbarnes-composer/addressbook/gui/widgets/Makefile.am
==============================================================================
--- branches/mbarnes-composer/addressbook/gui/widgets/Makefile.am	(original)
+++ branches/mbarnes-composer/addressbook/gui/widgets/Makefile.am	Sat Feb  9 21:54:02 2008
@@ -16,23 +16,6 @@
 	-I$(top_builddir)/shell				\
 	$(EVOLUTION_ADDRESSBOOK_CFLAGS)
 
-CORBA_COMPOSER_SOURCE_H	=			\
-	Evolution-Composer.h
-CORBA_COMPOSER_SOURCE_C =			\
-	Evolution-Composer-common.c		\
-	Evolution-Composer-skels.c		\
-	Evolution-Composer-stubs.c
-CORBA_COMPOSER_IDL = $(srcdir)/../../../composer/Evolution-Composer.idl
-
-$(CORBA_COMPOSER_SOURCE_H): $(CORBA_COMPOSER_IDL)
-	$(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) $(CORBA_COMPOSER_IDL)
-
-$(CORBA_COMPOSER_SOURCE_C): $(CORBA_COMPOSER_SOURCE_H)
-
-CORBA_SOURCE_H = $(CORBA_COMPOSER_SOURCE_H)
-CORBA_SOURCE_C = $(CORBA_COMPOSER_SOURCE_C)
-CORBA_SOURCE = $(CORBA_SOURCE_H) $(CORBA_SOURCE_C)
-
 noinst_LTLIBRARIES =				\
 	libeabwidgets.la
 
@@ -44,7 +27,6 @@
 	eab-popup.h
 
 libeabwidgets_la_SOURCES =			\
-	$(CORBA_SOURCE)				\
 	$(MARSHAL_GENERATED)			\
 	eab-config.c				\
 	eab-contact-display.c			\
@@ -82,7 +64,7 @@
 MARSHAL_GENERATED = eab-marshal.c eab-marshal.h
 @EVO_MARSHAL_RULE@
 
-BUILT_SOURCES = $(CORBA_SOURCE) $(MARSHAL_GENERATED)
+BUILT_SOURCES = $(MARSHAL_GENERATED)
 CLEANFILES = $(BUILT_SOURCES)
 
 dist-hook:

Modified: branches/mbarnes-composer/addressbook/gui/widgets/eab-gui-util.c
==============================================================================
--- branches/mbarnes-composer/addressbook/gui/widgets/eab-gui-util.c	(original)
+++ branches/mbarnes-composer/addressbook/gui/widgets/eab-gui-util.c	Sat Feb  9 21:54:02 2008
@@ -39,6 +39,7 @@
 #include <e-util/e-icon-factory.h>
 #include "eab-contact-merging.h"
 #include <gnome.h>
+#include <composer/e-msg-composer.h>
 
 /* we link to camel for decoding quoted printable email addresses */
 #include <camel/camel-mime-utils.h>
@@ -766,174 +767,76 @@
 	addressbook_load (dest, got_book_cb, process);
 }
 
-#include <Evolution-Composer.h>
-
-#define COMPOSER_OAFID "OAFIID:GNOME_Evolution_Mail_Composer:" BASE_VERSION
-
 typedef struct {
 	EContact *contact;
 	int email_num; /* if the contact is a person (not a list), the email address to use */
 } ContactAndEmailNum;
 
 static void
-eab_send_to_contact_and_email_num_list (GList *c)
+eab_send_to_contact_and_email_num_list (GList *contact_list)
 {
-	GNOME_Evolution_Composer composer_server;
-	CORBA_Environment ev;
-	GNOME_Evolution_Composer_RecipientList *to_list, *cc_list, *bcc_list;
-	CORBA_char *subject;
-	int to_i, bcc_i;
-	GList *iter;
-	gint to_length = 0, bcc_length = 0;
+	EMsgComposer *composer;
+	EComposerHeaderTable *table;
+	GPtrArray *to_array;
+	GPtrArray *bcc_array;
+
+	union {
+		gpointer *pdata;
+		EDestination **destinations;
+	} convert;
 
-	if (c == NULL)
+	if (contact_list == NULL)
 		return;
 
-	CORBA_exception_init (&ev);
+	composer = e_msg_composer_new ();
+	table = e_msg_composer_get_header_table (composer);
 
-	composer_server = bonobo_activation_activate_from_id (COMPOSER_OAFID, 0, NULL, &ev);
+	to_array = g_ptr_array_new ();
+	bcc_array = g_ptr_array_new ();
 
-	/* Figure out how many addresses of each kind we have. */
-	for (iter = c; iter != NULL; iter = g_list_next (iter)) {
-		ContactAndEmailNum *ce = iter->data;
+	/* Sort contacts into "To" and "Bcc" destinations. */
+	while (contact_list != NULL) {
+		ContactAndEmailNum *ce = contact_list->data;
 		EContact *contact = ce->contact;
-		GList *emails = e_contact_get (contact, E_CONTACT_EMAIL);
-		if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
-			gint len = g_list_length (emails);
-			if (e_contact_get (contact, E_CONTACT_LIST_SHOW_ADDRESSES))
-				to_length += len;
-			else
-				bcc_length += len;
-		} else {
-			if (emails != NULL)
-				++to_length;
-		}
-		g_list_foreach (emails, (GFunc)g_free, NULL);
-		g_list_free (emails);
-	}
+		EDestination *destination;
 
-	/* Now I have to make a CORBA sequences that represents a recipient list with
-	   the right number of entries, for the contacts. */
-	to_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-	to_list->_maximum = to_length;
-	to_list->_length = to_length;
-	if (to_length > 0) {
-		to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (to_length);
-	}
-
-	cc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-	cc_list->_maximum = cc_list->_length = 0;
+		destination = e_destination_new ();
+		e_destination_set_contact (destination, contact, 0);
 
-	bcc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-	bcc_list->_maximum = bcc_length;
-	bcc_list->_length = bcc_length;
-	if (bcc_length > 0) {
-		bcc_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (bcc_length);
-	}
-
-	to_i = 0;
-	bcc_i = 0;
-	while (c != NULL) {
-		ContactAndEmailNum *ce = c->data;
-		EContact *contact = ce->contact;
-		int nth = ce->email_num;
-		char *name, *addr;
-		gboolean is_list, is_hidden;
-		GNOME_Evolution_Composer_Recipient *recipient;
-		GList *emails = e_contact_get (contact, E_CONTACT_EMAIL);
-		GList *iterator;
-
-		if (emails != NULL) {
-			is_list = e_contact_get (contact, E_CONTACT_IS_LIST) != NULL;
-			is_hidden = is_list && !e_contact_get (contact, E_CONTACT_LIST_SHOW_ADDRESSES);
-
-			if (is_list) {
-				for (iterator = emails; iterator; iterator = iterator->next) {
-
-					if (is_hidden) {
-						recipient = &(bcc_list->_buffer[bcc_i]);
-						++bcc_i;
-					} else {
-						recipient = &(to_list->_buffer[to_i]);
-						++to_i;
-					}
-
-					name = NULL;
-					addr = NULL;
-					if (iterator && iterator->data) {
-						/* XXX we should probably try to get the name from the attribute parameter here.. */
-						addr = g_strdup ((char*)iterator->data);
-					}
-
-					recipient->name    = CORBA_string_dup (name ? name : "");
-					recipient->address = CORBA_string_dup (addr ? addr : "");
-
-					g_free (name);
-					g_free (addr);
-				}
-			}
-			else {
-				EContactName *contact_name = e_contact_get (contact, E_CONTACT_NAME);
-				int length = g_list_length (emails);
-
-				if (is_hidden) {
-					recipient = &(bcc_list->_buffer[bcc_i]);
-					++bcc_i;
-				} else {
-					recipient = &(to_list->_buffer[to_i]);
-					++to_i;
-				}
-
-				if (nth >= length)
-					nth = 0;
-
-				if (contact_name) {
-					name = e_contact_name_to_string (contact_name);
-					e_contact_name_free (contact_name);
-				}
-				else
-					name = NULL;
-
-				addr = g_strdup (g_list_nth_data (emails, nth));
-
-
-				recipient->name    = CORBA_string_dup (name ? name : "");
-				recipient->address = CORBA_string_dup (addr ? addr : "");
-
-				g_free (name);
-				g_free (addr);
-			}
-
-			g_list_foreach (emails, (GFunc)g_free, NULL);
-			g_list_free (emails);
-		}
-
-		c = c->next;
-	}
-
-	subject = CORBA_string_dup ("");
-
-	GNOME_Evolution_Composer_setHeaders (composer_server, "", to_list, cc_list, bcc_list, subject, &ev);
-	if (ev._major != CORBA_NO_EXCEPTION) {
-		g_printerr ("gui/e-meeting-edit.c: I couldn't set the composer headers via CORBA! Aagh.\n");
-		CORBA_exception_free (&ev);
-		return;
-	}
-
-	CORBA_free (to_list);
-	CORBA_free (cc_list);
-	CORBA_free (bcc_list);
-	CORBA_free (subject);
-
-	GNOME_Evolution_Composer_show (composer_server, &ev);
-
-	if (ev._major != CORBA_NO_EXCEPTION) {
-		g_printerr ("gui/e-meeting-edit.c: I couldn't show the composer via CORBA! Aagh.\n");
-		CORBA_exception_free (&ev);
-		return;
-	}
+		if (e_destination_is_evolution_list (destination)) {
+			if (e_destination_list_show_addresses (destination))
+				g_ptr_array_add (to_array, destination);
+			else
+				g_ptr_array_add (bcc_array, destination);
+		} else
+			g_ptr_array_add (to_array, destination);
+
+		contact_list = g_list_next (contact_list);
+	}
+
+	/* Add sentinels to each array. */
+	g_ptr_array_add (to_array, NULL);
+	g_ptr_array_add (bcc_array, NULL);
+
+	/* XXX Acrobatics like this make me question whether NULL-terminated
+	 *     arrays are really the best argument type for passing a list of
+	 *     destinations to the header table. */
+
+	/* Add "To" destinations. */
+	convert.pdata = to_array->pdata;
+	e_composer_header_table_set_destinations_to (
+		table, convert.destinations);
+	g_ptr_array_free (to_array, FALSE);
+	e_destination_freev (convert.destinations);
+
+	/* Add "Bcc" destinations. */
+	convert.pdata = bcc_array->pdata;
+	e_composer_header_table_set_destinations_bcc (
+		table, convert.destinations);
+	g_ptr_array_free (bcc_array, FALSE);
+	e_destination_freev (convert.destinations);
 
-	CORBA_exception_free (&ev);
+	gtk_widget_show (GTK_WIDGET (composer));
 }
 
 static const char *
@@ -958,75 +861,48 @@
 static void
 eab_send_contact_list_as_attachment (GList *contacts)
 {
-	GNOME_Evolution_Composer composer_server;
-	CORBA_Environment ev;
-	CORBA_char *content_type, *filename, *description;
-	GNOME_Evolution_Composer_AttachmentData *attach_data;
-	CORBA_boolean show_inline;
-	char *tempstr;
-	GNOME_Evolution_Composer_RecipientList *to_list, *cc_list, *bcc_list;
-	CORBA_char *subject;
+	EMsgComposer *composer;
+	EComposerHeaderTable *table;
+	CamelMimePart *attachment;
+	gchar *data;
 
 	if (contacts == NULL)
 		return;
 
-	CORBA_exception_init (&ev);
-
-	composer_server = bonobo_activation_activate_from_id (COMPOSER_OAFID, 0, NULL, &ev);
-
-
+	composer = e_msg_composer_new ();
+	table = e_msg_composer_get_header_table (composer);
 
-	content_type = CORBA_string_dup ("text/x-vcard");
-	filename = CORBA_string_dup ("");
+	attachment = camel_mime_part_new ();
+	data = eab_contact_list_to_string (contacts);
 
-	if (contacts->next) {
-		description = CORBA_string_dup (_("Multiple vCards"));
-	} else {
-		char *file_as = e_contact_get (E_CONTACT (contacts->data), E_CONTACT_FILE_AS);
-		tempstr = g_strdup_printf (_("vCard for %s"), file_as);
-		description = CORBA_string_dup (tempstr);
-		g_free (tempstr);
-		g_free (file_as);
-	}
+	camel_mime_part_set_content (
+		attachment, data, strlen (data), "text/x-vcard");
 
-	show_inline = FALSE;
+	if (contacts->next != NULL)
+		camel_mime_part_set_description (
+			attachment, _("Multiple vCards"));
+	else {
+		EContact *contact = contacts->data;
+		const gchar *file_as;
+		gchar *description;
 
-	tempstr = eab_contact_list_to_string (contacts);
-	attach_data = GNOME_Evolution_Composer_AttachmentData__alloc();
-	attach_data->_maximum = attach_data->_length = strlen (tempstr);
-	attach_data->_buffer = CORBA_sequence_CORBA_char_allocbuf (attach_data->_length);
-	memcpy (attach_data->_buffer, tempstr, attach_data->_length);
-	g_free (tempstr);
-
-	GNOME_Evolution_Composer_attachData (composer_server,
-					     content_type, filename, description,
-					     show_inline, attach_data,
-					     &ev);
-
-	if (ev._major != CORBA_NO_EXCEPTION) {
-		g_printerr ("gui/e-meeting-edit.c: I couldn't attach data to the composer via CORBA! Aagh.\n");
-		CORBA_exception_free (&ev);
-		return;
+		file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+		description = g_strdup_printf (_("vCard for %s"), file_as);
+		camel_mime_part_set_description (attachment, description);
+		g_free (description);
 	}
 
-	CORBA_free (content_type);
-	CORBA_free (filename);
-	CORBA_free (description);
-	CORBA_free (attach_data);
-
-	to_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-	to_list->_maximum = to_list->_length = 0;
-
-	cc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-	cc_list->_maximum = cc_list->_length = 0;
+	camel_mime_part_set_disposition (attachment, "attachment");
 
-	bcc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-	bcc_list->_maximum = bcc_list->_length = 0;
+	e_msg_composer_attach (composer, attachment);
+	camel_object_unref (attachment);
 
-	if (!contacts || contacts->next) {
-		subject = CORBA_string_dup (_("Contact information"));
-	} else {
+	if (contacts->next != NULL)
+		e_composer_header_table_set_subject (
+			table, _("Contact information"));
+	else {
 		EContact *contact = contacts->data;
+		gchar *tempstr;
 		const gchar *tempstr2;
 		gchar *tempfree = NULL;
 
@@ -1052,27 +928,14 @@
 			tempstr = g_strdup_printf (_("Contact information"));
 		else
 			tempstr = g_strdup_printf (_("Contact information for %s"), tempstr2);
-		subject = CORBA_string_dup (tempstr);
-		g_free (tempstr);
-		g_free (tempfree);
-	}
 
-	GNOME_Evolution_Composer_setHeaders (composer_server, "", to_list, cc_list, bcc_list, subject, &ev);
+		e_composer_header_table_set_subject (table, tempstr);
 
-	CORBA_free (to_list);
-	CORBA_free (cc_list);
-	CORBA_free (bcc_list);
-	CORBA_free (subject);
-
-	GNOME_Evolution_Composer_show (composer_server, &ev);
-
-	if (ev._major != CORBA_NO_EXCEPTION) {
-		g_printerr ("gui/e-meeting-edit.c: I couldn't show the composer via CORBA! Aagh.\n");
-		CORBA_exception_free (&ev);
-		return;
+		g_free (tempstr);
+		g_free (tempfree);
 	}
 
-	CORBA_exception_free (&ev);
+	gtk_widget_show (GTK_WIDGET (composer));
 }
 
 void

Modified: branches/mbarnes-composer/calendar/gui/Makefile.am
==============================================================================
--- branches/mbarnes-composer/calendar/gui/Makefile.am	(original)
+++ branches/mbarnes-composer/calendar/gui/Makefile.am	Sat Feb  9 21:54:02 2008
@@ -5,7 +5,6 @@
 ## CORBA stuff
 
 IDLS =								\
-	$(top_srcdir)/composer/Evolution-Composer.idl		\
 	$(top_srcdir)/calendar/idl/evolution-calendar.idl
 
 CALENDAR_IDL_GENERATED_H =		\
@@ -21,23 +20,6 @@
                 $(top_srcdir)/calendar/idl/evolution-calendar.idl
 $(CALENDAR_IDL_GENERATED_C): $(CALENDAR_IDL_GENERATED_H)
 
-# Message composer IDL files
-
-COMPOSER_IDL_GENERATED_H = \
-        Evolution-Composer.h
-COMPOSER_IDL_GENERATED_C =             			\
-        Evolution-Composer-common.c       		\
-        Evolution-Composer-skels.c        		\
-        Evolution-Composer-stubs.c
-COMPOSER_IDL_GENERATED = $(COMPOSER_IDL_GENERATED_C) $(COMPOSER_IDL_GENERATED_H)
-
-$(COMPOSER_IDL_GENERATED_H): $(IDLS)
-	$(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES)   \
-                $(srcdir)/../../composer/Evolution-Composer.idl
-$(COMPOSER_IDL_GENERATED_C): $(COMPOSER_IDL_GENERATED_H)
-
-IDL_GENERATED = $(CALENDAR_IDL_GENERATED) $(COMPOSER_IDL_GENERATED)
-
 # The marshallers
 MARSHAL_GENERATED = e-calendar-marshal.c e-calendar-marshal.h
 @EVO_MARSHAL_RULE@

Modified: branches/mbarnes-composer/calendar/gui/itip-utils.c
==============================================================================
--- branches/mbarnes-composer/calendar/gui/itip-utils.c	(original)
+++ branches/mbarnes-composer/calendar/gui/itip-utils.c	Sat Feb  9 21:54:02 2008
@@ -24,9 +24,6 @@
 #include <config.h>
 #endif
 
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-moniker-util.h>
 #include <glib/gi18n.h>
 #include <libedataserver/e-time-utils.h>
 #include <gtk/gtkmessagedialog.h>
@@ -41,7 +38,8 @@
 #include "itip-utils.h"
 #include <time.h>
 
-#define GNOME_EVOLUTION_COMPOSER_OAFIID "OAFIID:GNOME_Evolution_Mail_Composer:" BASE_VERSION
+#include <composer/e-msg-composer.h>
+#include <camel/camel-mime-filter-tohtml.h>
 
 static gchar *itip_methods[] = {
 	"PUBLISH",
@@ -408,36 +406,28 @@
 	return FALSE;
 }
 
-static CORBA_char *
+static gchar *
 comp_from (ECalComponentItipMethod method, ECalComponent *comp)
 {
 	ECalComponentOrganizer organizer;
 	ECalComponentAttendee *attendee;
 	GSList *attendees;
-	CORBA_char *str;
+	gchar *from;
 	char *sender = NULL;
 
 	switch (method) {
 	case E_CAL_COMPONENT_METHOD_PUBLISH:
-		return CORBA_string_dup ("");
+		return NULL;
 
 	case E_CAL_COMPONENT_METHOD_REQUEST:
-		sender = itip_get_comp_attendee (comp, NULL);
-		if (sender) {
-			str = CORBA_string_dup (sender);
-			g_free (sender);
-			return str;
-		}
+		return itip_get_comp_attendee (comp, NULL);
 
 	case E_CAL_COMPONENT_METHOD_REPLY:
 		sender = itip_get_comp_attendee (comp, NULL);
-		if (sender) {
-			str = CORBA_string_dup (sender);
-			g_free (sender);
-			return str;
-		}
+		if (sender != NULL)
+			return sender;
 		if (!e_cal_component_has_attendees (comp))
-			return CORBA_string_dup ("");
+			return NULL;
 
 	case E_CAL_COMPONENT_METHOD_CANCEL:
 
@@ -449,32 +439,40 @@
 				  _("An organizer must be set."));
 			return NULL;
 		}
-		return CORBA_string_dup (itip_strip_mailto (organizer.value));
+		return g_strdup (itip_strip_mailto (organizer.value));
 
 
 	default:
 		if (!e_cal_component_has_attendees (comp))
-			return CORBA_string_dup ("");
+			return NULL;
 
 		e_cal_component_get_attendee_list (comp, &attendees);
 		attendee = attendees->data;
-		str = CORBA_string_dup (attendee->value ? itip_strip_mailto (attendee->value) : "");
+		if (attendee->value != NULL)
+			from = g_strdup (itip_strip_mailto (attendee->value));
+		else
+			from = NULL;
 		e_cal_component_free_attendee_list (attendees);
 
-		return str;
+		return from;
 	}
 }
 
-static GNOME_Evolution_Composer_RecipientList *
+static EDestination **
 comp_to_list (ECalComponentItipMethod method, ECalComponent *comp, GList *users, gboolean reply_all)
 {
-	GNOME_Evolution_Composer_RecipientList *to_list;
-	GNOME_Evolution_Composer_Recipient *recipient;
 	ECalComponentOrganizer organizer;
 	GSList *attendees, *l;
+	GPtrArray *array = NULL;
+	EDestination *destination;
 	gint len;
  	char *sender = NULL;
 
+	union {
+		gpointer *pdata;
+		EDestination **destinations;
+	} convert;
+
 	switch (method) {
 	case E_CAL_COMPONENT_METHOD_REQUEST:
 	case E_CAL_COMPONENT_METHOD_CANCEL:
@@ -487,11 +485,6 @@
 			return NULL;
 		}
 
-		to_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-		to_list->_maximum = len;
-		to_list->_length = 0;
-		to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (len);
-
 		e_cal_component_get_organizer (comp, &organizer);
 		if (organizer.value == NULL) {
 			e_notice (NULL, GTK_MESSAGE_ERROR,
@@ -499,6 +492,8 @@
 			return NULL;
 		}
 
+		array = g_ptr_array_new ();
+
 		sender = itip_get_comp_attendee (comp, NULL);
 
 		for (l = attendees; l != NULL; l = l->next) {
@@ -518,14 +513,12 @@
 					&& !(att->rsvp) && method == E_CAL_COMPONENT_METHOD_REQUEST)
 				continue;
 
-			recipient = &(to_list->_buffer[to_list->_length]);
-			if (att->cn)
-				recipient->name = CORBA_string_dup (att->cn);
-			else
-				recipient->name = CORBA_string_dup ("");
-			recipient->address = CORBA_string_dup (itip_strip_mailto (att->value));
-
-			to_list->_length++;
+			destination = e_destination_new ();
+			if (att->cn != NULL)
+				e_destination_set_name (destination, att->cn);
+			e_destination_set_email (
+				destination, itip_strip_mailto (att->value));
+			g_ptr_array_add (array, destination);
 		}
 		g_free (sender);
 		e_cal_component_free_attendee_list (attendees);
@@ -537,19 +530,10 @@
 			e_cal_component_get_attendee_list (comp, &attendees);
 			len = g_slist_length (attendees);
 
-			if (len <= 0) {
-				to_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-				to_list->_maximum = len;
-				to_list->_length = 0;
-				to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (len);
-				e_cal_component_free_attendee_list (attendees);
-				return to_list;
-			}
+			if (len <= 0)
+				return NULL;
 
-			to_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-			to_list->_maximum = len;
-			to_list->_length = 0;
-			to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (len);
+			array = g_ptr_array_new ();
 
 			e_cal_component_get_organizer (comp, &organizer);
 			sender = itip_get_comp_attendee (comp, NULL);
@@ -557,39 +541,26 @@
 			for (l = attendees; l != NULL; l = l->next) {
 				ECalComponentAttendee *att = l->data;
 
-
-				recipient = &(to_list->_buffer[to_list->_length]);
-				if (att->cn)
-					recipient->name = CORBA_string_dup (att->cn);
-				else
-					recipient->name = CORBA_string_dup ("");
-				recipient->address = CORBA_string_dup (itip_strip_mailto (att->value));
-
-				to_list->_length++;
+				destination = e_destination_new ();
+				if (att->cn != NULL)
+					e_destination_set_name (destination, att->cn);
+				e_destination_set_email (
+					destination, itip_strip_mailto (att->value));
+				g_ptr_array_add (array, destination);
 			}
 
 			g_free (sender);
 			e_cal_component_free_attendee_list (attendees);
 
 		} else {
+			array = g_ptr_array_new ();
 
-			to_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-			to_list->_maximum = 1;
-			to_list->_length = 0;
-			to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (1);
-
-			recipient = &(to_list->_buffer[to_list->_length]);
-
+			destination = e_destination_new ();
 			e_cal_component_get_organizer (comp, &organizer);
-			if (organizer.value) {
-				recipient->name = CORBA_string_dup ("");
-				recipient->address = CORBA_string_dup (itip_strip_mailto (organizer.value));
-				to_list->_length++;
-				return to_list;
-			} else {
-				recipient->address = CORBA_string_dup ("");
-				recipient->name = CORBA_string_dup ("");
-			}
+			if (organizer.value)
+				e_destination_set_email (
+					destination, itip_strip_mailto (organizer.value));
+			g_ptr_array_add (array, destination);
 		}
 		break;
 
@@ -605,20 +576,14 @@
 			return NULL;
 		}
 
-		len = 2;
-
-		to_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-		to_list->_maximum = len;
-		to_list->_length = 0;
-		to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (len);
-		recipient = &(to_list->_buffer[0]);
-		to_list->_length++;
+		array = g_ptr_array_new ();
 
+		destination = e_destination_new ();
 		if (organizer.cn != NULL)
-			recipient->name = CORBA_string_dup (organizer.cn);
-		else
-			recipient->name = CORBA_string_dup ("");
-		recipient->address = CORBA_string_dup (itip_strip_mailto (organizer.value));
+			e_destination_set_name (destination, organizer.cn);
+		e_destination_set_email (
+			destination, itip_strip_mailto (organizer.value));
+		g_ptr_array_add (array, destination);
 
 		/* send the status to delegatee to the delegate also*/
 		e_cal_component_get_attendee_list (comp, &attendees);
@@ -632,10 +597,10 @@
 				if (!(att->delfrom && *att->delfrom))
 					break;
 
-				recipient = &(to_list->_buffer[to_list->_length]);
-				recipient->name = CORBA_string_dup ("");
-				recipient->address = CORBA_string_dup (itip_strip_mailto (att->delfrom));
-				to_list->_length++;
+				destination = e_destination_new ();
+				e_destination_set_email (
+					destination, itip_strip_mailto (att->delfrom));
+				g_ptr_array_add (array, destination);
 			}
 
 		}
@@ -646,38 +611,37 @@
 		if(users) {
 			GList *list;
 
-			len = g_list_length (users);
-			to_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-			to_list->_maximum = len;
-			to_list->_length = 0;
-			to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (len);
+			array = g_ptr_array_new ();
 
 			for (list = users; list != NULL; list = list->next) {
-				recipient = &(to_list->_buffer[to_list->_length]);
-				recipient->name = CORBA_string_dup ("");
-				recipient->address = CORBA_string_dup (list->data);
-				to_list->_length++;
+				destination = e_destination_new ();
+				e_destination_set_email (destination, list->data);
+				g_ptr_array_add (array, destination);
 			}
 
 			break;
 		}
 	default:
-		to_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-		to_list->_maximum = to_list->_length = 0;
 		break;
 	}
-	CORBA_sequence_set_release (to_list, TRUE);
 
-	return to_list;
+	if (array == NULL)
+		return NULL;
+
+	convert.pdata = array->pdata;
+	g_ptr_array_add (array, NULL);
+	g_ptr_array_free (array, FALSE);
+
+	return convert.destinations;
 }
 
-static CORBA_char *
+static gchar *
 comp_subject (ECalComponentItipMethod method, ECalComponent *comp)
 {
 	ECalComponentText caltext;
 	const char *description, *prefix = NULL;
 	GSList *alist, *l;
-	CORBA_char *subject;
+	gchar *subject;
 	char *sender;
 	ECalComponentAttendee *a = NULL;
 
@@ -767,54 +731,49 @@
 		break;
 	}
 
-	if (prefix) {
-		subject = CORBA_string_alloc (strlen (description) +
-					      strlen (prefix) + 3);
-		sprintf (subject, "%s: %s", prefix, description);
-	} else
-		subject = CORBA_string_dup (description);
+	if (prefix != NULL)
+		subject = g_strdup_printf ("%s: %s", prefix, description);
+	else
+		subject = g_strdup (description);
 
 	return subject;
 }
 
-static CORBA_char *
+static gchar *
 comp_content_type (ECalComponent *comp, ECalComponentItipMethod method)
 {
-	char tmp[256];
-
-	sprintf (tmp, "text/calendar; name=\"%s\"; charset=utf-8; METHOD=%s",
-		 e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_FREEBUSY ?
-		 "freebusy.ifb" : "calendar.ics", itip_methods[method]);
-
-	return CORBA_string_dup (tmp);
-
+	return g_strdup_printf (
+		"text/calendar; name=\"%s\"; charset=utf-8; METHOD=%s",
+		e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_FREEBUSY ?
+		"freebusy.ifb" : "calendar.ics", itip_methods[method]);
 }
 
-static CORBA_char *
+static const gchar *
 comp_filename (ECalComponent *comp)
 {
-        switch (e_cal_component_get_vtype (comp)) {
-        case E_CAL_COMPONENT_FREEBUSY:
-                return CORBA_string_dup ("freebusy.ifb");
-        default:
-                return CORBA_string_dup ("calendar.ics");
-        }
+	if (e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_FREEBUSY)
+		return "freebusy.ifb";
+	else
+		return "calendar.ics";
 }
 
-static CORBA_char *
+static gchar *
 comp_description (ECalComponent *comp)
 {
-        CORBA_char *description;
+	gchar *description;
         ECalComponentDateTime dt;
         char *start = NULL, *end = NULL;
 
         switch (e_cal_component_get_vtype (comp)) {
         case E_CAL_COMPONENT_EVENT:
-                return CORBA_string_dup (_("Event information"));
+                description = g_strdup (_("Event information"));
+		break;
         case E_CAL_COMPONENT_TODO:
-                return CORBA_string_dup (_("Task information"));
+                description = g_strdup (_("Task information"));
+		break;
         case E_CAL_COMPONENT_JOURNAL:
-                return CORBA_string_dup (_("Memo information"));
+                description = g_strdup (_("Memo information"));
+		break;
         case E_CAL_COMPONENT_FREEBUSY:
                 e_cal_component_get_dtstart (comp, &dt);
                 if (dt.value)
@@ -826,20 +785,21 @@
 			end = get_label (dt.value);
 		e_cal_component_free_datetime (&dt);
 
-                if (start != NULL && end != NULL) {
-                        char *tmp;
-                        tmp = g_strdup_printf (_("Free/Busy information (%s to %s)"), start, end);
-                        description = CORBA_string_dup (tmp);
-                        g_free (tmp);
-                } else {
-                        description = CORBA_string_dup (_("Free/Busy information"));
-                }
+                if (start != NULL && end != NULL)
+			description = g_strdup_printf (
+				_("Free/Busy information (%s to %s)"),
+				start, end);
+                else
+			description = g_strdup (_("Free/Busy information"));
                 g_free (start);
                 g_free (end);
-                return description;
+		break;
         default:
-                return CORBA_string_dup (_("iCalendar information"));
+                description = g_strdup (_("iCalendar information"));
+		break;
         }
+
+	return description;
 }
 
 static gboolean
@@ -1159,84 +1119,64 @@
 	return clone;
 }
 
-static gboolean
-append_cal_attachments (GNOME_Evolution_Composer composer_server, ECalComponent
-		*comp, GSList *attach_list)
+static void
+append_cal_attachments (EMsgComposer *composer,
+                        ECalComponent *comp,
+                        GSList *attach_list)
 {
-	CORBA_char *content_type = NULL, *filename = NULL, *description = NULL;
-	CORBA_Environment ev;
-	GNOME_Evolution_Composer_AttachmentData *attach_data = NULL;
 	struct CalMimeAttach *mime_attach;
 	GSList *l;
-	gboolean retval = TRUE;
-
-	CORBA_exception_init (&ev);
 
 	for (l = attach_list; l ; l = l->next) {
+		CamelMimePart *attachment;
+
 		mime_attach = (struct CalMimeAttach *) l->data;
 
-		filename = CORBA_string_dup (mime_attach->filename ? mime_attach->filename : "");
-		content_type = CORBA_string_dup	(mime_attach->content_type);
-		description = CORBA_string_dup (mime_attach->description);
-
-		attach_data = GNOME_Evolution_Composer_AttachmentData__alloc ();
-		attach_data->_length = mime_attach->length;
-		attach_data->_maximum = attach_data->_length;
-		attach_data->_buffer = CORBA_sequence_CORBA_char_allocbuf (attach_data->_length);
-		memcpy (attach_data->_buffer, mime_attach->encoded_data, attach_data->_length);
-
-		GNOME_Evolution_Composer_attachData (composer_server,
-						     content_type, filename, description,
-						     mime_attach->disposition, attach_data,
-						     &ev);
-		if (BONOBO_EX (&ev)) {
-			g_warning ("Unable to add attachments in composer");
-			retval = FALSE;
-		}
+		attachment = camel_mime_part_new ();
+		camel_mime_part_set_content (
+			attachment, mime_attach->encoded_data,
+			mime_attach->length, mime_attach->content_type);
+		if (mime_attach->filename != NULL)
+			camel_mime_part_set_filename (
+				attachment, mime_attach->filename);
+		if (mime_attach->description != NULL)
+			camel_mime_part_set_description (
+				attachment, mime_attach->description);
+		if (mime_attach->disposition)
+			camel_mime_part_set_disposition (
+				attachment, "inline");
+		else
+			camel_mime_part_set_disposition (
+				attachment, "attachment");
+		e_msg_composer_attach (composer, attachment);
+		camel_object_unref (attachment);
 
-		CORBA_exception_free (&ev);
-		if (content_type != NULL)
-			CORBA_free (content_type);
-		if (filename != NULL)
-			CORBA_free (filename);
-		if (description != NULL)
-			CORBA_free (description);
-		if (attach_data != NULL) {
-			CORBA_free (attach_data->_buffer);
-			CORBA_free (attach_data);
-		}
 		g_free (mime_attach->filename);
 		g_free (mime_attach->content_type);
 		g_free (mime_attach->description);
 		g_free (mime_attach->encoded_data);
 	}
-
-	return retval;
 }
 
 gboolean
 itip_send_comp (ECalComponentItipMethod method, ECalComponent *send_comp,
 		ECal *client, icalcomponent *zones, GSList *attachments_list, GList *users)
 {
-	GNOME_Evolution_Composer composer_server;
+	EMsgComposer *composer;
+	EComposerHeaderTable *table;
+	EDestination **destinations;
 	ECalComponent *comp = NULL;
 	icalcomponent *top_level = NULL;
-	GNOME_Evolution_Composer_RecipientList *to_list = NULL;
-	GNOME_Evolution_Composer_RecipientList *cc_list = NULL;
-	GNOME_Evolution_Composer_RecipientList *bcc_list = NULL;
-	CORBA_char *subject = NULL, *body = NULL, *content_type = NULL;
-	CORBA_char *from = NULL, *filename = NULL, *description = NULL;
-	GNOME_Evolution_Composer_AttachmentData *attach_data = NULL;
 	char *ical_string;
-	CORBA_Environment ev;
+	gchar *from;
+	gchar *content_type;
+	gchar *subject;
 	gboolean retval = FALSE;
 
 	/* check whether backend could handle sending requests/updates */
 	if (method != E_CAL_COMPONENT_METHOD_PUBLISH && e_cal_get_save_schedules (client))
 		return TRUE;
 
-	CORBA_exception_init (&ev);
-
 	/* Give the server a chance to manipulate the comp */
 	if (method != E_CAL_COMPONENT_METHOD_PUBLISH) {
 		if (!comp_server_send (method, send_comp, client, zones, &users))
@@ -1250,46 +1190,29 @@
 		goto cleanup;
 
 	/* Recipients */
-	to_list = comp_to_list (method, comp, users, FALSE);
+	destinations = comp_to_list (method, comp, users, FALSE);
 	if (method != E_CAL_COMPONENT_METHOD_PUBLISH) {
-		if (to_list == NULL || to_list->_length == 0) {
+		if (destinations == NULL) {
 			/* We sent them all via the server */
 			retval = TRUE;
 			goto cleanup;
-		} else if (to_list == NULL || to_list->_length == 0) {
-			/* if we don't have recipients, return */
-			retval = FALSE;
-			goto cleanup;
 		}
 	}
 
-	cc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-	cc_list->_maximum = cc_list->_length = 0;
-	bcc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-	bcc_list->_maximum = bcc_list->_length = 0;
-
 	/* Subject information */
 	subject = comp_subject (method, comp);
 
 	/* From address */
 	from = comp_from (method, comp);
 
-	/* Obtain an object reference for the Composer. */
-	composer_server = bonobo_activation_activate_from_id (GNOME_EVOLUTION_COMPOSER_OAFIID, 0, NULL, &ev);
-	if (BONOBO_EX (&ev)) {
-		g_warning ("Could not activate composer: %s", bonobo_exception_get_text (&ev));
-		CORBA_exception_free (&ev);
-		return FALSE;
-	}
+	composer = e_msg_composer_new ();
+	table = e_msg_composer_get_header_table (composer);
 
-	/* Set recipients, subject */
-	GNOME_Evolution_Composer_setHeaders (composer_server, from, to_list, cc_list, bcc_list, subject, &ev);
-	if (BONOBO_EX (&ev)) {
-		g_warning ("Unable to set composer headers while sending iTip message: %s",
-			   bonobo_exception_get_text (&ev));
-		goto cleanup;
-	}
+	e_composer_header_table_set_subject (table, subject);
+	e_composer_header_table_set_account_name (table, from);
+	e_composer_header_table_set_destinations_to (table, destinations);
 
+	e_destination_freev (destinations);
 
 	/* Content type */
 	content_type = comp_content_type (comp, method);
@@ -1298,62 +1221,46 @@
 	ical_string = icalcomponent_as_ical_string (top_level);
 
 	if (e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_EVENT) {
-		GNOME_Evolution_Composer_setBody (composer_server, ical_string, content_type, &ev);
+		e_msg_composer_set_body (composer, ical_string, content_type);
 	} else {
-		GNOME_Evolution_Composer_setMultipartType (composer_server, GNOME_Evolution_Composer_MIXED, &ev);
-		if (BONOBO_EX (&ev)) {
-			g_warning ("Unable to set multipart type while sending iTip message");
-			goto cleanup;
-		}
+		CamelMimePart *attachment;
+		const gchar *filename;
+		gchar *description;
+		gchar *body;
 
 		filename = comp_filename (comp);
 		description = comp_description (comp);
 
-		GNOME_Evolution_Composer_setBody (composer_server, description, "text/plain", &ev);
-		if (BONOBO_EX (&ev)) {
-			g_warning ("Unable to set body text while sending iTip message");
-			goto cleanup;
-		}
+		body = camel_text_to_html (
+			body, CAMEL_MIME_FILTER_TOHTML_PRE, 0);
+		e_msg_composer_set_body_text (composer, body, -1);
+		g_free (body);
+
+		attachment = camel_mime_part_new ();
+		camel_mime_part_set_content (
+			attachment, ical_string,
+			strlen (ical_string), content_type);
+		if (filename != NULL && *filename != '\0')
+			camel_mime_part_set_filename (attachment, filename);
+		if (description != NULL && *description != '\0')
+			camel_mime_part_set_description (attachment, description);
+		camel_mime_part_set_disposition (attachment, "inline");
+		e_msg_composer_attach (composer, attachment);
+		camel_object_unref (attachment);
 
-		attach_data = GNOME_Evolution_Composer_AttachmentData__alloc ();
-		attach_data->_length = strlen (ical_string);
-		attach_data->_maximum = attach_data->_length;
-		attach_data->_buffer = CORBA_sequence_CORBA_char_allocbuf (attach_data->_length);
-		memcpy (attach_data->_buffer, ical_string, attach_data->_length);
-
-		GNOME_Evolution_Composer_attachData (composer_server,
-						     content_type, filename, description,
-						     TRUE, attach_data,
-						     &ev);
+		g_free (description);
 	}
 
-	if (BONOBO_EX (&ev)) {
-		g_warning ("Unable to place iTip message in composer");
-		goto cleanup;
-	}
+	append_cal_attachments (composer, comp, attachments_list);
 
-	if (attachments_list) {
-		if (append_cal_attachments (composer_server, comp, attachments_list))
-			retval = TRUE;
-	}
+	if ((method == E_CAL_COMPONENT_METHOD_PUBLISH) && !users)
+		gtk_widget_show (GTK_WIDGET (composer));
+	else
+		e_msg_composer_send (composer);
 
-	if ((method == E_CAL_COMPONENT_METHOD_PUBLISH) && !users) {
-		GNOME_Evolution_Composer_show (composer_server, &ev);
-		if (BONOBO_EX (&ev))
-			g_warning ("Unable to show the composer while sending iTip message");
-		else
-			retval = TRUE;
-	} else {
-		GNOME_Evolution_Composer_send (composer_server, &ev);
-		if (BONOBO_EX (&ev))
-			g_warning ("Unable to send iTip message");
-		else
-			retval = TRUE;
-	}
+	retval = TRUE;
 
  cleanup:
-	CORBA_exception_free (&ev);
-
 	if (comp != NULL)
 		g_object_unref (comp);
 	if (top_level != NULL)
@@ -1364,65 +1271,39 @@
 		g_list_free (users);
 	}
 
-	if (to_list != NULL)
-		CORBA_free (to_list);
-	if (cc_list != NULL)
-		CORBA_free (cc_list);
-	if (bcc_list != NULL)
-		CORBA_free (bcc_list);
-
-	if (from != NULL)
-		CORBA_free (from);
-	if (subject != NULL)
-		CORBA_free (subject);
-	if (body != NULL)
-		CORBA_free (body);
-	if (content_type != NULL)
-		CORBA_free (content_type);
-	if (filename != NULL)
-		CORBA_free (filename);
-	if (description != NULL)
-		CORBA_free (description);
-	if (attach_data != NULL) {
-		CORBA_free (attach_data->_buffer);
-		CORBA_free (attach_data);
-	}
+	g_free (from);
+	g_free (content_type);
+	g_free (subject);
 
 	return retval;
 }
 
 gboolean
-reply_to_calendar_comp (ECalComponentItipMethod method, ECalComponent *send_comp,
-		ECal *client, gboolean reply_all, icalcomponent *zones, GSList *attachments_list)
-{
-	GNOME_Evolution_Composer composer_server;
+reply_to_calendar_comp (ECalComponentItipMethod method,
+                        ECalComponent *send_comp,
+                        ECal *client,
+                        gboolean reply_all,
+                        icalcomponent *zones,
+                        GSList *attachments_list)
+{
+	EMsgComposer *composer;
+	EComposerHeaderTable *table;
+	EDestination **destinations;
 	ECalComponent *comp = NULL;
 	icalcomponent *top_level = NULL;
 	GList *users = NULL;
-	GNOME_Evolution_Composer_RecipientList *to_list = NULL;
-	GNOME_Evolution_Composer_RecipientList *cc_list = NULL;
-	GNOME_Evolution_Composer_RecipientList *bcc_list = NULL;
-	CORBA_char *subject = NULL, *content_type = NULL;
-	char tmp [256];
-	CORBA_char *from = NULL;
+	gchar *from;
+	gchar *subject;
 	char *ical_string;
-	CORBA_Environment ev;
 	gboolean retval = FALSE;
 
-	CORBA_exception_init (&ev);
-
 	/* Tidy up the comp */
 	comp = comp_compliant (method, send_comp, client, zones);
 	if (comp == NULL)
 		goto cleanup;
 
 	/* Recipients */
-	to_list = comp_to_list (method, comp, users, reply_all);
-
-	cc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-	cc_list->_maximum = cc_list->_length = 0;
-	bcc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
-	bcc_list->_maximum = bcc_list->_length = 0;
+	destinations = comp_to_list (method, comp, users, reply_all);
 
 	/* Subject information */
 	subject = comp_subject (method, comp);
@@ -1430,26 +1311,14 @@
 	/* From address */
 	from = comp_from (method, comp);
 
-	/* Obtain an object reference for the Composer. */
-	composer_server = bonobo_activation_activate_from_id (GNOME_EVOLUTION_COMPOSER_OAFIID, 0, NULL, &ev);
-	if (BONOBO_EX (&ev)) {
-		g_warning ("Could not activate composer: %s", bonobo_exception_get_text (&ev));
-		CORBA_exception_free (&ev);
-		return FALSE;
-	}
+	composer = e_msg_composer_new ();
+	table = e_msg_composer_get_header_table (composer);
 
-	/* Set recipients, subject */
-	GNOME_Evolution_Composer_setHeaders (composer_server, from, to_list, cc_list, bcc_list, subject, &ev);
-	if (BONOBO_EX (&ev)) {
-		g_warning ("Unable to set composer headers while sending iTip message: %s",
-			   bonobo_exception_get_text (&ev));
-		goto cleanup;
-	}
+	e_composer_header_table_set_subject (table, subject);
+	e_composer_header_table_set_account_name (table, from);
+	e_composer_header_table_set_destinations_to (table, destinations);
 
-
-	/* Content type */
-	sprintf (tmp, "text/plain");
-	content_type = CORBA_string_dup (tmp);
+	e_destination_freev (destinations);
 
 	top_level = comp_toplevel_with_zones (method, comp, client, zones);
 	ical_string = icalcomponent_as_ical_string (top_level);
@@ -1546,25 +1415,15 @@
 		g_string_append (body, html_description);
 		g_free (html_description);
 
-		GNOME_Evolution_Composer_setBody (composer_server, body->str, "text/html", &ev);
+		e_msg_composer_set_body_text (composer, body->str, -1);
 		g_string_free (body, TRUE);
-
-                if (BONOBO_EX (&ev)) {
-                        g_warning ("Unable to set body text while sending iTip message");
-                        goto cleanup;
-                }
-
 	}
 
+	gtk_widget_show (GTK_WIDGET (composer));
 
-	GNOME_Evolution_Composer_show (composer_server, &ev);
-	if (BONOBO_EX (&ev))
-		g_warning ("Unable to show the composer while sending iTip message");
-	else
-		retval = TRUE;
+	retval = TRUE;
 
  cleanup:
-	CORBA_exception_free (&ev);
 
 	if (comp != NULL)
 		g_object_unref (comp);
@@ -1576,19 +1435,8 @@
 		g_list_free (users);
 	}
 
-	if (to_list != NULL)
-		CORBA_free (to_list);
-	if (cc_list != NULL)
-		CORBA_free (cc_list);
-	if (bcc_list != NULL)
-		CORBA_free (bcc_list);
-
-	if (from != NULL)
-		CORBA_free (from);
-	if (subject != NULL)
-		CORBA_free (subject);
-	if (content_type != NULL)
-		CORBA_free (content_type);
+	g_free (from);
+	g_free (subject);
 
 	return retval;
 }

Modified: branches/mbarnes-composer/composer/Makefile.am
==============================================================================
--- branches/mbarnes-composer/composer/Makefile.am	(original)
+++ branches/mbarnes-composer/composer/Makefile.am	Sat Feb  9 21:54:02 2008
@@ -1,32 +1,3 @@
-## CORBA stuff
-
-IDLS =				\
-	Evolution-Composer.idl	\
-	Composer.idl
-
-IDL_GENERATED =			\
-	Composer.h		\
-	Composer-common.c	\
-	Composer-skels.c	\
-	Composer-stubs.c
-
-HTML_EDITOR_GENERATED =		\
-	Editor.h		\
-	Editor-common.c	\
-	Editor-skels.c	\
-	Editor-stubs.c
-
-$(IDL_GENERATED): $(IDLS)
-	$(ORBIT_IDL) -I $(srcdir) -I $(datadir)/idl $(IDL_INCLUDES) \
-		$(srcdir)/Composer.idl
-
-Editor-commmon.c: $(GTKHTML_DATADIR)/Editor.idl
-
-$(HTML_EDITOR_GENERATED): $(GTKHTML_DATADIR)/Editor.idl
-	$(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) -I $(GTKHTML_DATADIR)/gtkhtml $(GTKHTML_DATADIR)/Editor.idl
-
-##
-
 error_DATA = mail-composer.error
 errordir = $(privdatadir)/errors
 
@@ -80,10 +51,8 @@
 	e-msg-composer-select-file.h		\
 	e-msg-composer.c			\
 	e-msg-composer.h			\
-	evolution-composer.c			\
-	evolution-composer.h			\
-	listener.c				\
-	listener.h
+	gconf-bridge.c				\
+	gconf-bridge.h
 
 EXTRA_DIST =					\
 	mail-composer.error.xml			\

Modified: branches/mbarnes-composer/composer/e-composer-actions.c
==============================================================================
--- branches/mbarnes-composer/composer/e-composer-actions.c	(original)
+++ branches/mbarnes-composer/composer/e-composer-actions.c	Sat Feb  9 21:54:02 2008
@@ -101,16 +101,14 @@
 action_save_draft_cb (GtkAction *action,
                       EMsgComposer *composer)
 {
-	g_signal_emit_by_name (composer, "save-draft", FALSE);
-	e_msg_composer_unset_changed (composer);
-	e_msg_composer_unset_autosaved (composer);
+	e_msg_composer_save_draft (composer);
 }
 
 static void
 action_send_cb (GtkAction *action,
                 EMsgComposer *composer)
 {
-	g_signal_emit_by_name (composer, "send");
+	e_msg_composer_send (composer);
 }
 
 static void

Modified: branches/mbarnes-composer/composer/e-composer-private.h
==============================================================================
--- branches/mbarnes-composer/composer/e-composer-private.h	(original)
+++ branches/mbarnes-composer/composer/e-composer-private.h	Sat Feb  9 21:54:02 2008
@@ -4,6 +4,7 @@
 #include "e-composer-common.h"
 
 #include <glib/gi18n.h>
+#include <gtkhtml-editor.h>
 
 #include "e-msg-composer.h"
 #include "e-composer-actions.h"
@@ -64,10 +65,6 @@
 	guint notify_id;
 
 	gboolean send_invoked;
-
-	GtkWidget *saveas;	/* saveas async file requester */
-	GtkWidget *load;	/* same for load - not used */
-
 };
 
 G_END_DECLS

Modified: branches/mbarnes-composer/composer/e-msg-composer-select-file.c
==============================================================================
--- branches/mbarnes-composer/composer/e-msg-composer-select-file.c	(original)
+++ branches/mbarnes-composer/composer/e-msg-composer-select-file.c	Sat Feb  9 21:54:02 2008
@@ -44,160 +44,55 @@
 #include "e-msg-composer.h"
 #include "e-attachment-bar.h"
 
-enum {
-	SELECTOR_MODE_MULTI    = (1 << 0),
-	SELECTOR_MODE_SAVE     = (1 << 1),
-	SELECTOR_SHOW_INLINE = 1<<2
-};
-
-/* this is a mess */
-
-static GtkWidget*
-get_selector(struct _EMsgComposer *composer, const char *title, guint32 flags)
+void
+e_msg_composer_select_file_attachments (EMsgComposer *composer,
+                                        EMsgComposerSelectAttachFunc func)
 {
-	GtkWidget *selection;
-	GtkWidget *showinline = NULL;
-	GList *icon_list;
-	const char *path;
-
-	path = e_msg_composer_get_attach_path (composer);
-
-	if (flags & SELECTOR_MODE_SAVE)
-		selection = gtk_file_chooser_dialog_new (title,
-							 NULL,
-							 GTK_FILE_CHOOSER_ACTION_SAVE,
-							 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-							 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
-							 NULL);
-	else
-		selection = gtk_file_chooser_dialog_new (title,
-							 NULL,
-							 GTK_FILE_CHOOSER_ACTION_OPEN,
-							 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-							 _("A_ttach"), GTK_RESPONSE_OK,
-							 NULL);
-
-	gtk_dialog_set_default_response (GTK_DIALOG (selection), GTK_RESPONSE_OK);
-	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (selection), FALSE);
-
-	if ((flags & SELECTOR_MODE_SAVE) == 0)
-		gtk_file_chooser_set_select_multiple ((GtkFileChooser *) selection, (flags & SELECTOR_MODE_MULTI));
-
-	/* restore last path used */
-	if (!path)
-		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (selection), g_get_home_dir ());
-	else
-		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (selection), path);
-
-        if (flags & SELECTOR_SHOW_INLINE) {
-		showinline = gtk_check_button_new_with_mnemonic (_("_Suggest automatic display of attachment"));
-		gtk_widget_show (showinline);
-		gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (selection), showinline);
-		g_object_set_data((GObject *)selection, "show-inline", showinline);
-        }
-
-	gtk_window_set_transient_for ((GtkWindow *) selection, (GtkWindow *) composer);
-	gtk_window_set_wmclass ((GtkWindow *) selection, "fileselection", "Evolution:composer");
-	gtk_window_set_modal ((GtkWindow *) selection, FALSE);
-
-	icon_list = e_icon_factory_get_icon_list ("mail-message-new");
-	if (icon_list) {
-		gtk_window_set_icon_list (GTK_WINDOW (selection), icon_list);
-		g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
-		g_list_free (icon_list);
-	}
-
-	return selection;
-}
+	GtkWidget *dialog;
+	GtkWidget *option;
+	GSList *uris;
+	gboolean active;
+	gint response;
+
+	dialog = gtk_file_chooser_dialog_new (
+		_("Insert Attachment"), GTK_WINDOW (composer),
+		GTK_FILE_CHOOSER_ACTION_OPEN,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		_("A_ttach"), GTK_RESPONSE_OK,
+		NULL);
+
+	gtk_dialog_set_default_response (
+		GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+	gtk_file_chooser_set_local_only (
+		GTK_FILE_CHOOSER (dialog), FALSE);
+	gtk_file_chooser_set_select_multiple (
+		GTK_FILE_CHOOSER (dialog), TRUE);
+	gtk_window_set_icon_name (
+		GTK_WINDOW (dialog), "mail-message-new");
+
+	option = gtk_check_button_new_with_mnemonic (
+		_("_Suggest automatic display of attachment"));
+	gtk_widget_show (option);
+	gtk_file_chooser_set_extra_widget (
+		GTK_FILE_CHOOSER (dialog), option);
+
+	response = gtkhtml_editor_file_chooser_dialog_run (
+		GTKHTML_EDITOR (composer), dialog);
+
+	if (response != GTK_RESPONSE_OK)
+		goto exit;
+
+	uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
+	active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (option));
+
+	func (composer, uris, active);
 
-static void
-select_file_response(GtkWidget *selector, guint response, struct _EMsgComposer *composer)
-{
-	if (response == GTK_RESPONSE_OK) {
-		const char *name;
-		char *path;
-		EMsgComposerSelectFileFunc func = g_object_get_data((GObject *)selector, "callback");
-
-		name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (selector));
-		path = g_path_get_dirname (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (selector)));
-		e_msg_composer_set_attach_path (composer, path);
-		g_free (path);
+	e_msg_composer_show_attachments_ui (composer);
 
-		func(composer, name);
-	}
+	g_slist_foreach (uris, (GFunc) g_free, NULL);
+	g_slist_free (uris);
 
-	gtk_widget_destroy(selector);
-}
+exit:
 
-/**
- * e_msg_composer_select_file:
- * @composer: a composer
- * @w: widget pointer, so same dialog is not re-shown
- * @func: callback invoked if the user selected a file
- * @title: the title for the file selection dialog box
- * @save: whether the file selection box should be shown in save mode or not
- *
- * This pops up a file selection dialog box with the given title
- * and allows the user to select a single file.
- *
- **/
-void e_msg_composer_select_file(struct _EMsgComposer *composer, GtkWidget **w, EMsgComposerSelectFileFunc func, const char *title, int save)
-{
-	if (*w) {
-		gtk_window_present((GtkWindow *)*w);
-		return;
-	}
-
-	*w = get_selector (composer, title, save ? SELECTOR_MODE_SAVE : 0);
-	g_signal_connect(*w, "response", G_CALLBACK(select_file_response), composer);
-	g_signal_connect(*w, "destroy", G_CALLBACK(gtk_widget_destroyed), w);
-	g_object_set_data((GObject *)*w, "callback", func);
-	gtk_widget_show(*w);
-}
-
-
-static void
-select_attach_response(GtkWidget *selector, guint response, struct _EMsgComposer *composer)
-{
-	if (response == GTK_RESPONSE_OK) {
-		GSList *names;
-		EMsgComposerSelectAttachFunc func = g_object_get_data((GObject *)selector, "callback");
-		GtkToggleButton *showinline = g_object_get_data((GObject *)selector, "show-inline");
-		char *path = NULL;
-
-		char *filename = NULL;
-		names = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (selector));
-		filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (selector));
-		if (filename) {
-			path = g_path_get_dirname (filename);
-			g_free (filename);
-		}
-		if (path)
-			e_msg_composer_set_attach_path (composer, path);
-		g_free (path);
-
-		func(composer, names, gtk_toggle_button_get_active(showinline));
-
-		e_msg_composer_show_attachments_ui (composer);
-
-
-		g_slist_foreach(names, (GFunc)g_free, NULL);
-		g_slist_free(names);
-	}
-
-	gtk_widget_destroy(selector);
-}
-
-void e_msg_composer_select_file_attachments(struct _EMsgComposer *composer, GtkWidget **w, EMsgComposerSelectAttachFunc func)
-{
-	if (*w) {
-		gtk_window_present((GtkWindow *)*w);
-		return;
-	}
-
-	*w = get_selector (composer, _("Insert Attachment"), SELECTOR_MODE_MULTI|SELECTOR_SHOW_INLINE);
-	g_signal_connect(*w, "response", G_CALLBACK(select_attach_response), composer);
-	g_signal_connect(*w, "destroy", G_CALLBACK(gtk_widget_destroyed), w);
-	g_object_set_data((GObject *)*w, "callback", func);
-	gtk_widget_show(*w);
+	gtk_widget_destroy (dialog);
 }

Modified: branches/mbarnes-composer/composer/e-msg-composer-select-file.h
==============================================================================
--- branches/mbarnes-composer/composer/e-msg-composer-select-file.h	(original)
+++ branches/mbarnes-composer/composer/e-msg-composer-select-file.h	Sat Feb  9 21:54:02 2008
@@ -24,13 +24,10 @@
 #ifndef E_MSG_COMPOSER_SELECT_FILE_H
 #define E_MSG_COMPOSER_SELECT_FILE_H
 
+#include "e-msg-composer.h"
 
-struct _EMsgComposer;
+typedef void (*EMsgComposerSelectAttachFunc)(EMsgComposer *composer, GSList *names, int isinline);
 
-typedef void (*EMsgComposerSelectFileFunc)(struct _EMsgComposer *composer, const char *filename);
-typedef void (*EMsgComposerSelectAttachFunc)(struct _EMsgComposer *composer, GSList *names, int isinline);
-
-void e_msg_composer_select_file(struct _EMsgComposer *composer, GtkWidget **w, EMsgComposerSelectFileFunc func, const char *title, int save);
-void e_msg_composer_select_file_attachments(struct _EMsgComposer *composer, GtkWidget **, EMsgComposerSelectAttachFunc func);
+void e_msg_composer_select_file_attachments(EMsgComposer *composer, EMsgComposerSelectAttachFunc func);
 
 #endif /* E_MSG_COMPOSER_SELECT_FILE_H */

Modified: branches/mbarnes-composer/composer/e-msg-composer.c
==============================================================================
--- branches/mbarnes-composer/composer/e-msg-composer.c	(original)
+++ branches/mbarnes-composer/composer/e-msg-composer.c	Sat Feb  9 21:54:02 2008
@@ -116,19 +116,15 @@
 #include "e-composer-private.h"
 #include "e-composer-header-table.h"
 #include "e-msg-composer-select-file.h"
+#include "gconf-bridge.h"
 
 #include "evolution-shell-component-utils.h"
 #include <e-util/e-icon-factory.h>
 
-#include "Editor.h"
-#include "listener.h"
-
 #ifdef HAVE_XFREE
 #include <X11/XF86keysym.h>
 #endif
 
-#define GNOME_GTKHTML_EDITOR_CONTROL_ID "OAFIID:GNOME_GtkHTML_Editor:" GTKHTML_API_VERSION
-
 #define COMPOSER_CURRENT_FOLDER_KEY "/apps/evolution/mail/composer/current_folder"
 
 #define d(x)
@@ -1120,27 +1116,6 @@
 				 FALSE);
 }
 
-static void
-prepare_engine (EMsgComposer *composer)
-{
-	GConfClient *client;
-	gchar *path;
-
-	/* FIXME Move this to msg_composer_init () */
-
-	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
-
-	client = gconf_client_get_default ();
-	path = gconf_client_get_string (
-		client, COMPOSER_CURRENT_FOLDER_KEY, NULL);
-	g_object_unref (client);
-
-	/* change it only if we have set path before */
-	if (path && *path)
-		e_msg_composer_set_attach_path (composer, path);
-	g_free (path);
-}
-
 /**
  * e_msg_composer_set_attach_path
  * Attach path is used to be preset when choosing files. This function ensures same path
@@ -1172,20 +1147,6 @@
 	gtkhtml_editor_set_current_folder (GTKHTML_EDITOR (composer), path);
 }
 
-/**
- * e_msg_composer_get_attach_path
- * Last path, if any, used to select file.
- * @param composer Composer.
- * @return Last used path, or NULL when not set yet.
- **/
-const gchar *
-e_msg_composer_get_attach_path (EMsgComposer *composer)
-{
-	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);
-
-	return gtkhtml_editor_get_current_folder (GTKHTML_EDITOR (composer));
-}
-
 static gchar *
 encode_signature_name (const gchar *name)
 {
@@ -1466,17 +1427,41 @@
 }
 
 static void
-saveas_response (EMsgComposer *composer, const gchar *name)
-{
-	save (composer, name);
-}
-
-static void
 saveas (EMsgComposer *composer)
 {
-	EMsgComposerPrivate *p = composer->priv;
+	GtkWidget *dialog;
+	gchar *filename;
+	gint response;
+
+	dialog = gtk_file_chooser_dialog_new (
+		_("Save as..."), GTK_WINDOW (composer),
+		GTK_FILE_CHOOSER_ACTION_SAVE,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		GTK_STOCK_SAVE, GTK_RESPONSE_OK,
+		NULL);
+
+	gtk_dialog_set_default_response (
+		GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+	gtk_file_chooser_set_local_only (
+		GTK_FILE_CHOOSER (dialog), FALSE);
+	gtk_window_set_icon_name (
+		GTK_WINDOW (dialog), "mail-message-new");
+
+	response = gtkhtml_editor_file_chooser_dialog_run (
+		GTKHTML_EDITOR (composer), dialog);
+
+	if (response != GTK_RESPONSE_OK)
+		goto exit;
+
+	filename = gtk_file_chooser_get_filename (
+		GTK_FILE_CHOOSER (dialog));
+
+	save (composer, filename);
+
+	g_free (filename);
 
-	e_msg_composer_select_file (composer, &p->saveas, saveas_response, _("Save as..."), TRUE);
+exit:
+	gtk_widget_destroy (dialog);
 }
 
 static void
@@ -1658,9 +1643,8 @@
 	EMsgComposer *composer = E_MSG_COMPOSER (data);
 	EMsgComposerPrivate *p = composer->priv;
 	EMsgComposer *toplevel = E_MSG_COMPOSER (gtk_widget_get_toplevel (GTK_WIDGET (p->attachment_bar)));
-	GtkWidget **attachment_selector = e_attachment_bar_get_selector (E_ATTACHMENT_BAR(p->attachment_bar));
 
-	e_msg_composer_select_file_attachments (toplevel, attachment_selector, add_to_bar);
+	e_msg_composer_select_file_attachments (toplevel, add_to_bar);
 }
 
 static void
@@ -2034,15 +2018,15 @@
 		active = account->pgp_always_sign &&
 			(!account->pgp_no_imip_sign || !p->mime_type ||
 			g_ascii_strncasecmp (p->mime_type, "text/calendar", 13) != 0);
-		gtk_toggle_action (action, active);
+		gtk_toggle_action_set_active (action, active);
 
 		action = GTK_TOGGLE_ACTION (ACTION (SMIME_SIGN));
 		active = account->smime_sign_default;
-		gtk_toggle_action (action, active);
+		gtk_toggle_action_set_active (action, active);
 
 		action = GTK_TOGGLE_ACTION (ACTION (SMIME_ENCRYPT));
 		active = account->smime_encrypt_default;
-		gtk_toggle_action (action, active);
+		gtk_toggle_action_set_active (action, active);
 
 		update_auto_recipients (table, UPDATE_AUTO_CC, account->always_cc ? account->cc_addrs : NULL);
 		update_auto_recipients (table, UPDATE_AUTO_BCC, account->always_bcc ? account->bcc_addrs : NULL);
@@ -2483,23 +2467,6 @@
 	}
 #endif
 
-	if (p->load) {
-		gtk_widget_destroy (p->load);
-		p->load = NULL;
-	}
-
-	if (p->saveas) {
-		gtk_widget_destroy (p->saveas);
-		p->saveas = NULL;
-	}
-
-#if 0 /* GTKHTML-EDITOR */
-	if (p->uic) {
-		bonobo_object_unref (BONOBO_OBJECT (p->uic));
-		p->uic = NULL;
-	}
-#endif
-
 	/* FIXME?  I assume the Bonobo widget will get destroyed
 	   normally?  */
 	if (p->address_dialog != NULL) {
@@ -2670,6 +2637,10 @@
 	editor_class->paste_clipboard = msg_composer_paste_clipboard;
 	editor_class->select_all = msg_composer_select_all;
 
+	/* These callbacks are in the mail component. */
+	class->send = em_utils_composer_send_cb;
+	class->save_draft = em_utils_composer_save_draft_cb;
+
 	signals[SEND] =
 		g_signal_new ("send",
 			      E_TYPE_MSG_COMPOSER,
@@ -2975,9 +2946,8 @@
 {
 	EAttachmentBar *bar = data;
 	EMsgComposer *toplevel = E_MSG_COMPOSER (gtk_widget_get_toplevel (GTK_WIDGET (bar)));
-	GtkWidget **attachment_selector = e_attachment_bar_get_selector (E_ATTACHMENT_BAR(bar));
 
-	e_msg_composer_select_file_attachments (toplevel, attachment_selector, add_to_bar);
+	e_msg_composer_select_file_attachments (toplevel, add_to_bar);
 }
 
 static void
@@ -3307,7 +3277,9 @@
 #endif /* GTKHTML-EDITOR */
 	gtk_widget_show (vbox);
 
-	prepare_engine (composer);
+	gconf_bridge_bind_property (
+		gconf_bridge_get (), COMPOSER_CURRENT_FOLDER_KEY,
+		G_OBJECT (composer), "current-folder");
 
 #if 0 /* GTKHTML-EDITOR */
 	/* The engine would have the GtkHTML widget stored in "html-widget"
@@ -4140,6 +4112,37 @@
 	return composer;
 }
 
+/**
+ * e_msg_composer_send:
+ * @composer: an #EMsgComposer
+ *
+ * Send the message in @composer.
+ **/
+void
+e_msg_composer_send (EMsgComposer *composer)
+{
+	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+	g_signal_emit (composer, signals[SEND], 0);
+}
+
+/**
+ * e_msg_composer_save_draft:
+ * @composer: an #EMsgComposer
+ *
+ * Save the message in @composer to the selected account's Drafts folder.
+ **/
+void
+e_msg_composer_save_draft (EMsgComposer *composer)
+{
+	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+	g_signal_emit (composer, signals[SAVE_DRAFT], 0, FALSE);
+
+	/* XXX This should be elsewhere. */
+	e_msg_composer_unset_changed (composer);
+	e_msg_composer_unset_autosaved (composer);
+}
 
 static GList *
 add_recipients (GList *list, const gchar *recips)

Modified: branches/mbarnes-composer/composer/e-msg-composer.h
==============================================================================
--- branches/mbarnes-composer/composer/e-msg-composer.h	(original)
+++ branches/mbarnes-composer/composer/e-msg-composer.h	Sat Feb  9 21:54:02 2008
@@ -31,7 +31,6 @@
 #include <gtkhtml-editor.h>
 
 #include "e-composer-header-table.h"
-#include "Editor.h"
 
 /* Standard GObject macros */
 #define E_TYPE_MSG_COMPOSER \
@@ -87,6 +86,10 @@
 EMsgComposer            *e_msg_composer_new_from_url                     (const gchar        *url);
 EMsgComposer            *e_msg_composer_new_redirect                     (CamelMimeMessage  *message,
 									  const gchar        *resent_from);
+
+void		e_msg_composer_send		(EMsgComposer *composer);
+void		e_msg_composer_save_draft	(EMsgComposer *composer);
+
 void			e_msg_composer_show_attachments_ui		 (EMsgComposer *composer);
 
 void                     e_msg_composer_set_alternative                  (EMsgComposer      *composer,
@@ -175,9 +178,6 @@
 
 struct _EAttachmentBar*          e_msg_composer_get_attachment_bar                (EMsgComposer *composer);
 
-void                     e_msg_composer_set_attach_path                  (EMsgComposer *composer, const gchar *path);
-const gchar *            e_msg_composer_get_attach_path                  (EMsgComposer *composer);
-
 G_END_DECLS
 
 #endif /* ___E_MSG_COMPOSER_H__ */

Added: branches/mbarnes-composer/composer/gconf-bridge.c
==============================================================================
--- (empty file)
+++ branches/mbarnes-composer/composer/gconf-bridge.c	Sat Feb  9 21:54:02 2008
@@ -0,0 +1,1249 @@
+/* 
+ * (C) 2005 OpenedHand Ltd.
+ *
+ * Author: Jorn Baayen <jorn openedhand com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtkmessagedialog.h>
+#include <string.h>
+
+#include "gconf-bridge.h"
+
+struct _GConfBridge {
+        GConfClient *client;
+        
+        GHashTable *bindings;
+};
+
+/* The data structures for the different kinds of bindings */
+typedef enum {
+        BINDING_PROP,
+        BINDING_WINDOW,
+        BINDING_LIST_STORE
+} BindingType;
+
+typedef struct {
+        BindingType type;
+        guint id;
+        
+        gboolean delayed_mode;
+
+        char *key;
+        guint val_notify_id;
+        GSList *val_changes; /* List of changes made to GConf value,
+                                that have not received change notification
+                                yet. */
+
+        GObject *object;
+        GParamSpec *prop;
+        gulong prop_notify_id;
+
+        guint sync_timeout_id; /* Used in delayed mode */
+} PropBinding;
+
+typedef struct {
+        BindingType type;
+        guint id;
+
+        gboolean bind_size;
+        gboolean bind_pos;
+
+        char *key_prefix;
+
+        GtkWindow *window;
+        gulong configure_event_id;
+        gulong unmap_id;
+        guint sync_timeout_id;
+} WindowBinding;
+
+typedef struct {
+        BindingType type;
+        guint id;
+
+        char *key;
+        guint val_notify_id;
+        GSList *val_changes; /* List of changes made to GConf value,
+                                that have not received change notification
+                                yet. */
+
+        GtkListStore *list_store;
+        guint row_inserted_id;
+        guint row_changed_id;
+        guint row_deleted_id;
+        guint rows_reordered_id;
+
+        guint sync_idle_id;
+} ListStoreBinding;
+
+/* Some trickery to be able to treat the data structures generically */
+typedef union {
+        BindingType      type;
+
+        PropBinding      prop_binding;
+        WindowBinding    window_binding;
+        ListStoreBinding list_store_binding;
+} Binding;
+
+/* Function prototypes */
+static void
+unbind (Binding *binding);
+
+#if !HAVE_DECL_GCONF_VALUE_COMPARE /* Not in headers in GConf < 2.13 */
+int gconf_value_compare (const GConfValue *value_a,
+                         const GConfValue *value_b);
+#endif
+
+static GConfBridge *bridge = NULL; /* Global GConfBridge object */
+
+/* Free up all resources allocated by the GConfBridge. Called on exit. */
+static void
+destroy_bridge (void)
+{
+        g_hash_table_destroy (bridge->bindings);
+        g_object_unref (bridge->client);
+
+        g_free (bridge);
+}
+
+/**
+ * gconf_bridge_get
+ *
+ * Returns the #GConfBridge. This is a singleton object.
+ *
+ * Return value: The #GConfBridge.
+ **/
+GConfBridge *
+gconf_bridge_get (void)
+{
+        if (bridge)
+                return bridge;
+
+        gconf_bridge_install_default_error_handler ();
+
+        bridge = g_new (GConfBridge, 1);
+
+        bridge->client = gconf_client_get_default ();
+        bridge->bindings = g_hash_table_new_full (NULL, NULL, NULL,
+                                                  (GDestroyNotify) unbind);
+
+        g_atexit (destroy_bridge);
+
+        return bridge;
+}
+
+/**
+ * gconf_bridge_get_client
+ * @bridge: A #GConfBridge
+ *
+ * Returns the #GConfClient used by @bridge. This is the same #GConfClient 
+ * as returned by gconf_client_get_default().
+ *
+ * Return value: A #GConfClient.
+ **/
+GConfClient *
+gconf_bridge_get_client (GConfBridge *bridge)
+{
+        g_return_val_if_fail (bridge != NULL, NULL);
+
+        return bridge->client;
+}
+
+/* Generate an ID for a new binding */
+static guint
+new_id (void)
+{
+        static guint id_counter = 0;
+
+        id_counter++;
+
+        return id_counter;
+}
+
+/*
+ * Property bindings
+ */
+
+/* Syncs a value from GConf to an object property */
+static void
+prop_binding_sync_pref_to_prop (PropBinding *binding,
+                                GConfValue  *pref_value)
+{
+        GValue src_value, value;
+        
+        /* Make sure we don't enter an infinite synchronizing loop */
+        g_signal_handler_block (binding->object, binding->prop_notify_id);
+
+        memset (&src_value, 0, sizeof (GValue));
+
+        /* First, convert GConfValue to GValue */
+        switch (pref_value->type) {
+        case GCONF_VALUE_STRING:
+                g_value_init (&src_value, G_TYPE_STRING);
+                g_value_set_string (&src_value,
+                                    gconf_value_get_string (pref_value));
+                break;
+        case GCONF_VALUE_INT:
+                g_value_init (&src_value, G_TYPE_INT);
+                g_value_set_int (&src_value,
+                                 gconf_value_get_int (pref_value));
+                break;
+        case GCONF_VALUE_BOOL:
+                g_value_init (&src_value, G_TYPE_BOOLEAN);
+                g_value_set_boolean (&src_value,
+                                     gconf_value_get_bool (pref_value));
+                break;
+        case GCONF_VALUE_FLOAT:
+                g_value_init (&src_value, G_TYPE_FLOAT);
+                g_value_set_float (&src_value,
+                                   gconf_value_get_float (pref_value));
+                break;
+        default:
+                g_warning ("prop_binding_sync_pref_to_prop: Unhandled value "
+                           "type '%d'.\n", pref_value->type);
+
+                return;
+        }
+
+        /* Then convert to the type expected by the object, if necessary */
+        memset (&value, 0, sizeof (GValue));
+        g_value_init (&value,
+                      G_PARAM_SPEC_VALUE_TYPE (binding->prop));
+
+        if (src_value.g_type != value.g_type) {
+                if (!g_value_transform (&src_value, &value)) {
+                        g_warning ("prop_binding_sync_pref_to_prop: Failed to "
+                                   "transform a \"%s\" to a \"%s\".",
+                                   g_type_name (src_value.g_type),
+                                   g_type_name (value.g_type));
+                        
+                        goto done;
+                }
+
+                g_object_set_property (binding->object,
+                                       binding->prop->name, &value);
+        } else {
+                g_object_set_property (binding->object,
+                                       binding->prop->name, &src_value);
+        }
+        
+done:
+        g_value_unset (&src_value);
+        g_value_unset (&value);
+
+        g_signal_handler_unblock (binding->object, binding->prop_notify_id);
+}
+
+/* Syncs an object property to GConf */
+static void
+prop_binding_sync_prop_to_pref (PropBinding *binding)
+{
+        GValue value;
+        GConfValue *gconf_value;
+
+        memset (&value, 0, sizeof (GValue));
+
+        g_value_init (&value,
+                      G_PARAM_SPEC_VALUE_TYPE (binding->prop));
+        g_object_get_property (binding->object,
+                               binding->prop->name,
+                               &value);
+
+        switch (value.g_type) {
+        case G_TYPE_STRING:
+                gconf_value = gconf_value_new (GCONF_VALUE_STRING);
+                gconf_value_set_string (gconf_value,
+                                        g_value_get_string (&value));
+                break;
+        case G_TYPE_INT:
+                gconf_value = gconf_value_new (GCONF_VALUE_INT);
+                gconf_value_set_int (gconf_value,
+                                     g_value_get_int (&value));
+                break;
+        case G_TYPE_UINT:
+                gconf_value = gconf_value_new (GCONF_VALUE_INT);
+                gconf_value_set_int (gconf_value,
+                                     g_value_get_uint (&value));
+                break;
+        case G_TYPE_LONG:
+                gconf_value = gconf_value_new (GCONF_VALUE_INT);
+                gconf_value_set_int (gconf_value,
+                                     g_value_get_long (&value));
+                break;
+        case G_TYPE_ULONG:
+                gconf_value = gconf_value_new (GCONF_VALUE_INT);
+                gconf_value_set_int (gconf_value,
+                                     g_value_get_ulong (&value));
+                break;
+        case G_TYPE_INT64:
+                gconf_value = gconf_value_new (GCONF_VALUE_INT);
+                gconf_value_set_int (gconf_value,
+                                     g_value_get_int64 (&value));
+                break;
+        case G_TYPE_UINT64:
+                gconf_value = gconf_value_new (GCONF_VALUE_INT);
+                gconf_value_set_int (gconf_value,
+                                     g_value_get_uint64 (&value));
+                break;
+        case G_TYPE_CHAR:
+                gconf_value = gconf_value_new (GCONF_VALUE_INT);
+                gconf_value_set_int (gconf_value,
+                                     g_value_get_char (&value));
+                break;
+        case G_TYPE_UCHAR:
+                gconf_value = gconf_value_new (GCONF_VALUE_INT);
+                gconf_value_set_int (gconf_value,
+                                     g_value_get_uchar (&value));
+                break;
+        case G_TYPE_ENUM:
+                gconf_value = gconf_value_new (GCONF_VALUE_INT);
+                gconf_value_set_int (gconf_value,
+                                     g_value_get_enum (&value));
+                break;
+        case G_TYPE_BOOLEAN:
+                gconf_value = gconf_value_new (GCONF_VALUE_BOOL);
+                gconf_value_set_bool (gconf_value,
+                                      g_value_get_boolean (&value));
+                break;
+        case G_TYPE_DOUBLE:
+                gconf_value = gconf_value_new (GCONF_VALUE_FLOAT);
+#ifdef HAVE_CORBA_GCONF
+                /* FIXME we cast to a float explicitly as CORBA GConf
+                 * uses doubles in its API, but treats them as floats
+                 * when transporting them over CORBA. See #322837 */
+                gconf_value_set_float (gconf_value,
+                                       (float) g_value_get_double (&value));
+#else
+                gconf_value_set_float (gconf_value,
+                                       g_value_get_double (&value));
+#endif
+                break;
+        case G_TYPE_FLOAT:
+                gconf_value = gconf_value_new (GCONF_VALUE_FLOAT);
+                gconf_value_set_float (gconf_value,
+                                       g_value_get_float (&value));
+                break;
+        default:
+                if (g_type_is_a (value.g_type, G_TYPE_ENUM)) {
+                        gconf_value = gconf_value_new (GCONF_VALUE_INT);
+                        gconf_value_set_int (gconf_value,
+                                             g_value_get_enum (&value));
+                } else {
+                        g_warning ("prop_binding_sync_prop_to_pref: "
+                                   "Unhandled value type '%s'.\n",
+                                   g_type_name (value.g_type));
+
+                        goto done;
+                }
+
+                break;
+        }
+
+        /* Set to GConf */
+        gconf_client_set (bridge->client, binding->key, gconf_value, NULL);
+
+        /* Store until change notification comes in, so that we are able
+         * to ignore it */
+        binding->val_changes = g_slist_append (binding->val_changes,
+                                               gconf_value);
+
+done:
+        g_value_unset (&value);
+}
+
+/* Called when a GConf value bound to an object property has changed */
+static void
+prop_binding_pref_changed (GConfClient *client,
+                           guint        cnxn_id,
+                           GConfEntry  *entry,
+                           gpointer     user_data)
+{
+        GConfValue *gconf_value;
+        PropBinding *binding;
+        GSList *l;
+
+        gconf_value = gconf_entry_get_value (entry);
+        if (!gconf_value)
+                return; /* NULL means that the value has been unset */
+
+        binding = (PropBinding *) user_data;
+
+        /* Check that this notification is not caused by sync_prop_to_pref() */
+        l = g_slist_find_custom (binding->val_changes,
+                                 gconf_value,
+                                 (GCompareFunc) gconf_value_compare);
+        if (l) {
+                gconf_value_free (l->data);
+
+                binding->val_changes = g_slist_delete_link
+                        (binding->val_changes, l);
+
+                return;
+        }
+
+        prop_binding_sync_pref_to_prop (binding, gconf_value);
+}
+
+/* Performs a scheduled prop-to-pref sync for a prop binding in 
+ * delay mode */
+static gboolean
+prop_binding_perform_scheduled_sync (PropBinding *binding)
+{
+        prop_binding_sync_prop_to_pref (binding);
+
+        binding->sync_timeout_id = 0;
+
+        g_object_unref (binding->object);
+        
+        return FALSE;
+}
+
+#define PROP_BINDING_SYNC_DELAY 100 /* Delay for bindings with "delayed"
+                                       set to TRUE, in ms */
+
+/* Called when an object property has changed */
+static void
+prop_binding_prop_changed (GObject     *object,
+                           GParamSpec  *param_spec,
+                           PropBinding *binding)
+{
+        if (binding->delayed_mode) {
+                /* Just schedule a sync */
+                if (binding->sync_timeout_id == 0) {
+                        /* We keep a reference on the object as long as
+                         * we haven't synced yet to make sure we don't
+                         * lose any data */
+                        g_object_ref (binding->object);
+
+                        binding->sync_timeout_id =
+                                g_timeout_add
+                                        (PROP_BINDING_SYNC_DELAY,
+                                         (GSourceFunc)
+                                            prop_binding_perform_scheduled_sync,
+                                         binding);
+                }
+        } else {
+                /* Directly sync */
+                prop_binding_sync_prop_to_pref (binding);
+        }
+}
+
+/* Called when an object is destroyed */
+static void
+prop_binding_object_destroyed (gpointer user_data,
+                               GObject *where_the_object_was)
+{
+        PropBinding *binding;
+
+        binding = (PropBinding *) user_data;
+        binding->object = NULL; /* Don't do anything with the object
+                                   at unbind() */
+        
+        g_hash_table_remove (bridge->bindings,
+                             GUINT_TO_POINTER (binding->id));
+}
+
+/**
+ * gconf_bridge_bind_property_full
+ * @bridge: A #GConfBridge
+ * @key: A GConf key to be bound
+ * @object: A #GObject
+ * @prop: The property of @object to be bound
+ * @delayed_sync: TRUE if there should be a delay between property changes
+ * and syncs to GConf. Set to TRUE when binding to a rapidly-changing
+ * property, for example the "value" property on a #GtkAdjustment.
+ *
+ * Binds @key to @prop, causing them to have the same value at all times.
+ *
+ * The types of @key and @prop should be compatible. Floats and doubles, and
+ * ints, uints, longs, unlongs, int64s, uint64s, chars, uchars and enums
+ * can be matched up. Booleans and strings can only be matched to their
+ * respective types.
+ *
+ * On calling this function the current value of @key will be set to @prop.
+ *
+ * Return value: The ID of the new binding.
+ **/
+guint
+gconf_bridge_bind_property_full (GConfBridge *bridge,
+                                 const char  *key,
+                                 GObject     *object,
+                                 const char  *prop,
+                                 gboolean     delayed_sync)
+{
+        GParamSpec *pspec;
+        PropBinding *binding;
+        char *signal;
+        GConfValue *val;
+
+        g_return_val_if_fail (bridge != NULL, 0);
+        g_return_val_if_fail (key != NULL, 0);
+        g_return_val_if_fail (G_IS_OBJECT (object), 0);
+        g_return_val_if_fail (prop != NULL, 0);
+
+        /* First, try to fetch the propertys GParamSpec off the object */
+        pspec = g_object_class_find_property
+                                (G_OBJECT_GET_CLASS (object), prop);
+        if (G_UNLIKELY (pspec == NULL)) {
+                g_warning ("gconf_bridge_bind_property_full: A property \"%s\" "
+                           "was not found. Please make sure you are passing "
+                           "the right property name.", prop);
+
+                return 0;
+        }
+
+        /* GParamSpec found: All good, create new binding. */
+        binding = g_new (PropBinding, 1);
+
+        binding->type = BINDING_PROP;
+        binding->id = new_id ();
+        binding->delayed_mode = delayed_sync;
+        binding->val_changes = NULL;
+        binding->key = g_strdup (key);
+        binding->object = object;
+        binding->prop = pspec;
+        binding->sync_timeout_id = 0;
+        
+        /* Watch GConf key */
+        binding->val_notify_id =
+                gconf_client_notify_add (bridge->client, key,
+                                         prop_binding_pref_changed,
+                                         binding, NULL, NULL);
+
+        /* Connect to property change notifications */
+        signal = g_strconcat ("notify::", prop, NULL);
+        binding->prop_notify_id =
+                g_signal_connect (object, signal,
+                                  G_CALLBACK (prop_binding_prop_changed),
+                                  binding);
+        g_free (signal);
+
+        /* Sync object to value from GConf, if set */
+        val = gconf_client_get (bridge->client, key, NULL);
+        if (val) {
+                prop_binding_sync_pref_to_prop (binding, val);
+                gconf_value_free (val);
+        }
+
+        /* Handle case where watched object gets destroyed */
+        g_object_weak_ref (object,
+                           prop_binding_object_destroyed, binding);
+
+        /* Insert binding */
+        g_hash_table_insert (bridge->bindings,
+                             GUINT_TO_POINTER (binding->id), binding);
+
+        /* Done */
+        return binding->id;
+}
+
+/* Unbinds a property binding */
+static void
+prop_binding_unbind (PropBinding *binding)
+{
+        if (binding->delayed_mode && binding->sync_timeout_id > 0) {
+                /* Perform any scheduled syncs */
+                g_source_remove (binding->sync_timeout_id);
+                        
+                /* The object will still be around as we have
+                 * a reference */
+                prop_binding_perform_scheduled_sync (binding);
+        }
+
+        gconf_client_notify_remove (bridge->client,
+                                    binding->val_notify_id);
+        g_free (binding->key);
+
+        while (binding->val_changes) {
+                gconf_value_free (binding->val_changes->data);
+
+                binding->val_changes = g_slist_delete_link
+                        (binding->val_changes, binding->val_changes);
+        }
+
+        /* The object might have been destroyed .. */
+        if (binding->object) {
+                g_signal_handler_disconnect (binding->object,
+                                             binding->prop_notify_id);
+
+                g_object_weak_unref (binding->object,
+                                     prop_binding_object_destroyed, binding);
+        }
+}
+
+/*
+ * Window bindings
+ */
+
+/* Performs a scheduled dimensions-to-prefs sync for a window binding */
+static gboolean
+window_binding_perform_scheduled_sync (WindowBinding *binding)
+{
+        if (binding->bind_size) {
+                int width, height;
+                char *key;
+                GdkWindowState state;
+
+                state = gdk_window_get_state (GTK_WIDGET (binding->window)->window);
+
+                if (state & GDK_WINDOW_STATE_MAXIMIZED) {
+                        key = g_strconcat (binding->key_prefix, "_maximized", NULL);
+                        gconf_client_set_bool (bridge->client, key, TRUE, NULL);
+                        g_free (key);
+                } else {
+                        gtk_window_get_size (binding->window, &width, &height);
+
+                        key = g_strconcat (binding->key_prefix, "_width", NULL);
+                        gconf_client_set_int (bridge->client, key, width, NULL);
+                        g_free (key);
+
+                        key = g_strconcat (binding->key_prefix, "_height", NULL);
+                        gconf_client_set_int (bridge->client, key, height, NULL);
+                        g_free (key);
+
+                        key = g_strconcat (binding->key_prefix, "_maximized", NULL);
+                        gconf_client_set_bool (bridge->client, key, FALSE, NULL);
+                        g_free (key);
+                }
+        }
+
+        if (binding->bind_pos) {
+                int x, y;
+                char *key;
+
+                gtk_window_get_position (binding->window, &x, &y);
+
+                key = g_strconcat (binding->key_prefix, "_x", NULL);
+                gconf_client_set_int (bridge->client, key, x, NULL);
+                g_free (key);
+
+                key = g_strconcat (binding->key_prefix, "_y", NULL);
+                gconf_client_set_int (bridge->client, key, y, NULL);
+                g_free (key);
+        }
+
+        binding->sync_timeout_id = 0;
+
+        return FALSE;
+}
+
+#define WINDOW_BINDING_SYNC_DELAY 1000 /* Delay before syncing new window
+                                          dimensions to GConf, in ms */
+
+/* Called when the window han been resized or moved */
+static gboolean
+window_binding_configure_event_cb (GtkWindow         *window,
+                                   GdkEventConfigure *event,
+                                   WindowBinding     *binding)
+{
+        /* Schedule a sync */
+        if (binding->sync_timeout_id == 0) {
+                binding->sync_timeout_id =
+                        g_timeout_add (WINDOW_BINDING_SYNC_DELAY,
+                                       (GSourceFunc)
+                                          window_binding_perform_scheduled_sync,
+                                       binding);
+        }
+
+        return FALSE;
+}
+
+/* Called when the window state is being changed */
+static gboolean
+window_binding_state_event_cb (GtkWindow           *window,
+                               GdkEventWindowState *event,
+                               WindowBinding       *binding)
+{
+        window_binding_perform_scheduled_sync (binding);
+
+        return FALSE;
+}
+
+/* Called when the window is being unmapped */
+static gboolean
+window_binding_unmap_cb (GtkWindow     *window,
+                         WindowBinding *binding)
+{
+        /* Force sync */
+        if (binding->sync_timeout_id > 0)
+                g_source_remove (binding->sync_timeout_id);
+
+        window_binding_perform_scheduled_sync (binding);
+
+        return FALSE;
+}
+
+/* Called when a window is destroyed */
+static void
+window_binding_window_destroyed (gpointer user_data,
+                                 GObject *where_the_object_was)
+{
+        WindowBinding *binding;
+
+        binding = (WindowBinding *) user_data;
+        binding->window = NULL; /* Don't do anything with the window
+                                   at unbind() */
+        
+        g_hash_table_remove (bridge->bindings,
+                             GUINT_TO_POINTER (binding->id));
+}
+
+/**
+ * gconf_bridge_bind_window
+ * @bridge: A #GConfBridge
+ * @key_prefix: The prefix of the GConf keys
+ * @window: A #GtkWindow
+ * @bind_size: TRUE to bind the size of @window
+ * @bind_pos: TRUE to bind the position of @window
+ * 
+ * On calling this function @window will be resized to the values
+ * specified by "@key_prefix<!-- -->_width" and "@key_prefix<!-- -->_height"
+ * and maximixed if "@key_prefix<!-- -->_maximized is TRUE if
+ * @bind_size is TRUE, and moved to the values specified by
+ * "@key_prefix<!-- -->_x" and "@key_prefix<!-- -->_y" if @bind_pos is TRUE.
+ * The respective GConf values will be updated when the window is resized
+ * and/or moved.
+ *
+ * Return value: The ID of the new binding.
+ **/
+guint
+gconf_bridge_bind_window (GConfBridge *bridge,
+                          const char  *key_prefix,
+                          GtkWindow   *window,
+                          gboolean     bind_size,
+                          gboolean     bind_pos)
+{
+        WindowBinding *binding;
+
+        g_return_val_if_fail (bridge != NULL, 0);
+        g_return_val_if_fail (key_prefix != NULL, 0);
+        g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
+
+        /* Create new binding. */
+        binding = g_new (WindowBinding, 1);
+
+        binding->type = BINDING_WINDOW;
+        binding->id = new_id ();
+        binding->bind_size = bind_size;
+        binding->bind_pos = bind_pos;
+        binding->key_prefix = g_strdup (key_prefix);
+        binding->window = window;
+        binding->sync_timeout_id = 0;
+
+        /* Set up GConf keys & sync window to GConf values */
+        if (bind_size) {
+                char *key;
+                GConfValue *width_val, *height_val, *maximized_val;
+
+                key = g_strconcat (key_prefix, "_width", NULL);
+                width_val = gconf_client_get (bridge->client, key, NULL);
+                g_free (key);
+
+                key = g_strconcat (key_prefix, "_height", NULL);
+                height_val = gconf_client_get (bridge->client, key, NULL);
+                g_free (key);
+
+                key = g_strconcat (key_prefix, "_maximized", NULL);
+                maximized_val = gconf_client_get (bridge->client, key, NULL);
+                g_free (key);
+
+                if (width_val && height_val) {
+                        gtk_window_resize (window,
+                                           gconf_value_get_int (width_val),
+                                           gconf_value_get_int (height_val));
+
+                        gconf_value_free (width_val);
+                        gconf_value_free (height_val);
+                } else if (width_val) {
+                        gconf_value_free (width_val);
+                } else if (height_val) {
+                        gconf_value_free (height_val);
+                }
+
+                if (maximized_val) {
+                        if (gconf_value_get_bool (maximized_val)) {
+                                gtk_window_maximize (window);
+                        }
+                        gconf_value_free (maximized_val);
+                }
+        }
+
+        if (bind_pos) {
+                char *key;
+                GConfValue *x_val, *y_val;
+                
+                key = g_strconcat (key_prefix, "_x", NULL);
+                x_val = gconf_client_get (bridge->client, key, NULL);
+                g_free (key);
+
+                key = g_strconcat (key_prefix, "_y", NULL);
+                y_val = gconf_client_get (bridge->client, key, NULL);
+                g_free (key);
+
+                if (x_val && y_val) {
+                        gtk_window_move (window,
+                                         gconf_value_get_int (x_val),
+                                         gconf_value_get_int (y_val));
+
+                        gconf_value_free (x_val);
+                        gconf_value_free (y_val);
+                } else if (x_val) {
+                        gconf_value_free (x_val);
+                } else if (y_val) {
+                        gconf_value_free (y_val);
+                }
+        }
+
+        /* Connect to window size change notifications */
+        binding->configure_event_id =
+                g_signal_connect (window,
+                                  "configure-event",
+                                  G_CALLBACK
+                                        (window_binding_configure_event_cb),
+                                  binding);
+
+        binding->configure_event_id =
+                g_signal_connect (window,
+                                  "window_state_event",
+                                  G_CALLBACK
+                                        (window_binding_state_event_cb),
+                                  binding);
+        binding->unmap_id =
+                g_signal_connect (window,
+                                  "unmap",
+                                  G_CALLBACK (window_binding_unmap_cb),
+                                  binding);
+
+        /* Handle case where window gets destroyed */
+        g_object_weak_ref (G_OBJECT (window),
+                           window_binding_window_destroyed, binding);
+
+        /* Insert binding */
+        g_hash_table_insert (bridge->bindings,
+                             GUINT_TO_POINTER (binding->id), binding);
+
+        /* Done */
+        return binding->id;
+}
+
+/* Unbinds a window binding */
+static void
+window_binding_unbind (WindowBinding *binding)
+{
+        if (binding->sync_timeout_id > 0)
+                g_source_remove (binding->sync_timeout_id);
+
+        g_free (binding->key_prefix);
+
+        /* The window might have been destroyed .. */
+        if (binding->window) {
+                g_signal_handler_disconnect (binding->window,
+                                             binding->configure_event_id);
+                g_signal_handler_disconnect (binding->window,
+                                             binding->unmap_id);
+
+                g_object_weak_unref (G_OBJECT (binding->window),
+                                     window_binding_window_destroyed, binding);
+        }
+}
+
+/*
+ * List store bindings
+ */
+
+/* Fills a GtkListStore with the string list from @value */
+static void
+list_store_binding_sync_pref_to_store (ListStoreBinding *binding,
+                                       GConfValue       *value)
+{
+        GSList *list, *l;
+        GtkTreeIter iter;
+
+        /* Make sure we don't enter an infinite synchronizing loop */
+        g_signal_handler_block (binding->list_store,
+                                binding->row_inserted_id);
+        g_signal_handler_block (binding->list_store,
+                                binding->row_deleted_id);
+        
+        gtk_list_store_clear (binding->list_store);
+
+        list = gconf_value_get_list (value);
+        for (l = list; l; l = l->next) {
+                GConfValue *l_value;
+                const char *string;
+
+                l_value = (GConfValue *) l->data;
+                string = gconf_value_get_string (l_value);
+
+                gtk_list_store_insert_with_values (binding->list_store,
+                                                   &iter, -1,
+                                                   0, string,
+                                                   -1);
+        }
+
+        g_signal_handler_unblock (binding->list_store,
+                                  binding->row_inserted_id);
+        g_signal_handler_unblock (binding->list_store,
+                                  binding->row_deleted_id);
+}
+
+/* Sets a GConf value to the contents of a GtkListStore */
+static gboolean
+list_store_binding_sync_store_to_pref (ListStoreBinding *binding)
+{
+        GtkTreeModel *tree_model;
+        GtkTreeIter iter;
+        GSList *list;
+        int res;
+        GConfValue *gconf_value;
+
+        tree_model = GTK_TREE_MODEL (binding->list_store);
+
+        /* Build list */
+        list = NULL;
+        res = gtk_tree_model_get_iter_first (tree_model, &iter);
+        while (res) {
+                char *string;
+                GConfValue *tmp_value;
+
+                gtk_tree_model_get (tree_model, &iter,
+                                    0, &string, -1);
+
+                tmp_value = gconf_value_new (GCONF_VALUE_STRING);
+                gconf_value_set_string (tmp_value, string);
+
+                list = g_slist_append (list, tmp_value);
+
+                res = gtk_tree_model_iter_next (tree_model, &iter);
+        }
+
+        /* Create value */
+        gconf_value = gconf_value_new (GCONF_VALUE_LIST);
+        gconf_value_set_list_type (gconf_value, GCONF_VALUE_STRING);
+        gconf_value_set_list_nocopy (gconf_value, list);
+
+        /* Set */
+        gconf_client_set (bridge->client, binding->key, gconf_value, NULL);
+
+        /* Store until change notification comes in, so that we are able
+         * to ignore it */
+        binding->val_changes = g_slist_append (binding->val_changes,
+                                               gconf_value);
+
+        binding->sync_idle_id = 0;
+
+        g_object_unref (binding->list_store);
+
+        return FALSE;
+}
+
+/* Pref changed: sync */
+static void
+list_store_binding_pref_changed (GConfClient *client,
+                                 guint        cnxn_id,
+                                 GConfEntry  *entry,
+                                 gpointer     user_data)
+{
+        GConfValue *gconf_value;
+        ListStoreBinding *binding;
+        GSList *l;
+
+        gconf_value = gconf_entry_get_value (entry);
+        if (!gconf_value)
+                return; /* NULL means that the value has been unset */
+
+        binding = (ListStoreBinding *) user_data;
+
+        /* Check that this notification is not caused by
+         * sync_store_to_pref() */
+        l = g_slist_find_custom (binding->val_changes,
+                                 gconf_value,
+                                 (GCompareFunc) gconf_value_compare);
+        if (l) {
+                gconf_value_free (l->data);
+
+                binding->val_changes = g_slist_delete_link
+                        (binding->val_changes, l);
+
+                return;
+        }
+
+        list_store_binding_sync_pref_to_store (binding, gconf_value);
+}
+
+/* Called when an object is destroyed */
+static void
+list_store_binding_store_destroyed (gpointer user_data,
+                                    GObject *where_the_object_was)
+{
+        ListStoreBinding *binding;
+
+        binding = (ListStoreBinding *) user_data;
+        binding->list_store = NULL; /* Don't do anything with the store
+                                       at unbind() */
+        
+        g_hash_table_remove (bridge->bindings,
+                             GUINT_TO_POINTER (binding->id));
+}
+
+/* List store changed: Sync */
+static void
+list_store_binding_store_changed_cb (ListStoreBinding *binding)
+{
+        if (binding->sync_idle_id == 0) {
+                g_object_ref (binding->list_store);
+
+                binding->sync_idle_id = g_idle_add
+                        ((GSourceFunc) list_store_binding_sync_store_to_pref,
+                         binding);
+        }
+}
+
+/**
+ * gconf_bridge_bind_string_list_store
+ * @bridge: A #GConfBridge
+ * @key: A GConf key to be bound
+ * @list_store: A #GtkListStore
+ * 
+ * On calling this function single string column #GtkListStore @list_store
+ * will be kept synchronized with the GConf string list value pointed to by
+ * @key. On calling this function @list_store will be populated with the
+ * strings specified by the value of @key.
+ *
+ * Return value: The ID of the new binding.
+ **/
+guint
+gconf_bridge_bind_string_list_store (GConfBridge  *bridge,
+                                     const char   *key,
+                                     GtkListStore *list_store)
+{
+        GtkTreeModel *tree_model;
+        gboolean have_one_column, is_string_column;
+        ListStoreBinding *binding;
+        GConfValue *val;
+
+        g_return_val_if_fail (bridge != NULL, 0);
+        g_return_val_if_fail (key != NULL, 0);
+        g_return_val_if_fail (GTK_IS_LIST_STORE (list_store), 0);
+
+        /* Check list store suitability */
+        tree_model = GTK_TREE_MODEL (list_store);
+        have_one_column = (gtk_tree_model_get_n_columns (tree_model) == 1);
+        is_string_column = (gtk_tree_model_get_column_type
+                                        (tree_model, 0) == G_TYPE_STRING);
+        if (G_UNLIKELY (!have_one_column || !is_string_column)) {
+                g_warning ("gconf_bridge_bind_string_list_store: Only "
+                           "GtkListStores with exactly one string column are "
+                           "supported.");
+
+                return 0;
+        }
+
+        /* Create new binding. */
+        binding = g_new (ListStoreBinding, 1);
+
+        binding->type = BINDING_LIST_STORE;
+        binding->id = new_id ();
+        binding->key = g_strdup (key);
+        binding->val_changes = NULL;
+        binding->list_store = list_store;
+        binding->sync_idle_id = 0;
+
+        /* Watch GConf key */
+        binding->val_notify_id =
+                gconf_client_notify_add (bridge->client, key,
+                                         list_store_binding_pref_changed,
+                                         binding, NULL, NULL);
+
+        /* Connect to ListStore change notifications */
+        binding->row_inserted_id =
+                g_signal_connect_swapped (list_store, "row-inserted",
+                                          G_CALLBACK
+                                          (list_store_binding_store_changed_cb),
+                                          binding);
+        binding->row_changed_id =
+                g_signal_connect_swapped (list_store, "row-inserted",
+                                          G_CALLBACK
+                                          (list_store_binding_store_changed_cb),
+                                          binding);
+        binding->row_deleted_id =
+                g_signal_connect_swapped (list_store, "row-inserted",
+                                          G_CALLBACK
+                                          (list_store_binding_store_changed_cb),
+                                          binding);
+        binding->rows_reordered_id =
+                g_signal_connect_swapped (list_store, "row-inserted",
+                                          G_CALLBACK
+                                          (list_store_binding_store_changed_cb),
+                                          binding);
+
+        /* Sync object to value from GConf, if set */
+        val = gconf_client_get (bridge->client, key, NULL);
+        if (val) {
+                list_store_binding_sync_pref_to_store (binding, val);
+                gconf_value_free (val);
+        }
+
+        /* Handle case where watched object gets destroyed */
+        g_object_weak_ref (G_OBJECT (list_store),
+                           list_store_binding_store_destroyed, binding);
+
+        /* Insert binding */
+        g_hash_table_insert (bridge->bindings,
+                             GUINT_TO_POINTER (binding->id), binding);
+
+        /* Done */
+        return binding->id;
+}
+
+/* Unbinds a list store binding */
+static void
+list_store_binding_unbind (ListStoreBinding *binding)
+{
+        /* Perform any scheduled syncs */
+        if (binding->sync_idle_id > 0) {
+                g_source_remove (binding->sync_idle_id);
+
+                /* The store will still be around as we added a reference */
+                list_store_binding_sync_store_to_pref (binding);
+        }
+
+        g_free (binding->key);
+
+        while (binding->val_changes) {
+                gconf_value_free (binding->val_changes->data);
+
+                binding->val_changes = g_slist_delete_link
+                        (binding->val_changes, binding->val_changes);
+        }
+
+        /* The store might have been destroyed .. */
+        if (binding->list_store) {
+                g_signal_handler_disconnect (binding->list_store,
+                                             binding->row_inserted_id);
+                g_signal_handler_disconnect (binding->list_store,
+                                             binding->row_changed_id);
+                g_signal_handler_disconnect (binding->list_store,
+                                             binding->row_deleted_id);
+                g_signal_handler_disconnect (binding->list_store,
+                                             binding->rows_reordered_id);
+
+                g_object_weak_unref (G_OBJECT (binding->list_store),
+                                     list_store_binding_store_destroyed,
+                                     binding);
+        }
+}
+
+/*
+ * Generic unbinding
+ */
+
+/* Unbinds a binding */
+static void
+unbind (Binding *binding)
+{
+        /* Call specialized unbinding function */
+        switch (binding->type) {
+        case BINDING_PROP:
+                prop_binding_unbind ((PropBinding *) binding);
+                break;
+        case BINDING_WINDOW:
+                window_binding_unbind ((WindowBinding *) binding);
+                break;
+        case BINDING_LIST_STORE:
+                list_store_binding_unbind ((ListStoreBinding *) binding);
+                break;
+        default:
+                g_warning ("Unknown binding type '%d'\n", binding->type);
+                break;
+        }
+
+        g_free (binding);
+}
+
+/**
+ * gconf_bridge_unbind
+ * @bridge: A #GConfBridge
+ * @binding_id: The ID of the binding to be removed
+ *
+ * Removes the binding with ID @binding_id.
+ **/
+void
+gconf_bridge_unbind (GConfBridge *bridge,
+                     guint        binding_id)
+{
+        g_return_if_fail (bridge != NULL);
+        g_return_if_fail (binding_id > 0);
+
+        /* This will trigger the hash tables value destruction
+         * function, which will take care of further cleanup */
+        g_hash_table_remove (bridge->bindings, 
+                             GUINT_TO_POINTER (binding_id));
+}
+
+/*
+ * Error handling
+ */
+
+/* This is the same dialog as used in eel */
+static void
+error_handler (GConfClient *client,
+               GError      *error)
+{
+        static gboolean shown_dialog = FALSE;
+
+        g_warning ("GConf error:\n  %s", error->message);
+
+        if (!shown_dialog) {
+                char *message;
+                GtkWidget *dlg;
+
+                message = g_strdup_printf (_("GConf error: %s"),
+                                           error->message);
+                dlg = gtk_message_dialog_new (NULL, 0,
+                                              GTK_MESSAGE_ERROR,
+                                              GTK_BUTTONS_OK,
+                                              message);
+                g_free (message);
+
+                gtk_message_dialog_format_secondary_text
+                        (GTK_MESSAGE_DIALOG (dlg),
+                         _("All further errors shown only on terminal."));
+                gtk_window_set_title (GTK_WINDOW (dlg), "");
+
+                gtk_dialog_run (GTK_DIALOG (dlg));
+
+                gtk_widget_destroy (dlg);
+
+                shown_dialog = TRUE;
+	}
+}
+
+/**
+ * gconf_bridge_install_default_error_handler
+ *
+ * Sets up the default error handler. Any unhandled GConf errors will
+ * automatically be handled by presenting the user an error dialog.
+ **/
+void
+gconf_bridge_install_default_error_handler (void)
+{
+        gconf_client_set_global_default_error_handler (error_handler);
+}

Added: branches/mbarnes-composer/composer/gconf-bridge.h
==============================================================================
--- (empty file)
+++ branches/mbarnes-composer/composer/gconf-bridge.h	Sat Feb  9 21:54:02 2008
@@ -0,0 +1,117 @@
+/* 
+ * (C) 2005 OpenedHand Ltd.
+ *
+ * Author: Jorn Baayen <jorn openedhand com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GCONF_BRIDGE_H__
+#define __GCONF_BRIDGE_H__
+
+#include <gconf/gconf-client.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkliststore.h>
+
+G_BEGIN_DECLS
+
+void gconf_bridge_install_default_error_handler (void);
+
+typedef struct _GConfBridge GConfBridge;
+
+GConfBridge *gconf_bridge_get                    (void);
+
+GConfClient *gconf_bridge_get_client             (GConfBridge  *bridge);
+
+guint        gconf_bridge_bind_property_full     (GConfBridge  *bridge,
+                                                  const char   *key,
+                                                  GObject      *object,
+                                                  const char   *prop,
+                                                  gboolean      delayed_sync);
+
+/**
+ * gconf_bridge_bind_property
+ * @bridge: A #GConfBridge
+ * @key: A GConf key to be bound
+ * @object: A #GObject
+ * @prop: The property of @object to be bound
+ *
+ * Binds @key to @prop without delays, causing them to have the same value at all times. See
+ * #gconf_bridge_bind_property_full for more details.
+ *
+ **/
+#define gconf_bridge_bind_property(bridge, key, object, prop) \
+        gconf_bridge_bind_property_full ((bridge), (key), \
+                                         (object), (prop), FALSE)
+
+/**
+ * gconf_bridge_bind_property_delayed
+ * @bridge: A #GConfBridge
+ * @key: A GConf key to be bound
+ * @object: A #GObject
+ * @prop: The property of @object to be bound
+ *
+ * Binds @key to @prop with a delay, causing them to have the same value at all
+ * times. See #gconf_bridge_bind_property_full for more details.
+ **/
+#define gconf_bridge_bind_property_delayed(bridge, key, object, prop) \
+        gconf_bridge_bind_property_full ((bridge), (key), \
+                                         (object), (prop), TRUE)
+
+guint        gconf_bridge_bind_window            (GConfBridge  *bridge,
+                                                  const char   *key_prefix,
+                                                  GtkWindow    *window,
+                                                  gboolean      bind_size,
+                                                  gboolean      bind_pos);
+
+/**
+ * gconf_bridge_bind_window_size
+ * @bridge: A #GConfBridge
+ * @key_prefix: The prefix of the GConf keys
+ * @window: A #GtkWindow
+ * 
+ * On calling this function @window will be resized to the values specified by
+ * "@key_prefix<!-- -->_width" and "@key_prefix<!-- -->_height".  The respective
+ * GConf values will be updated when the window is resized. See
+ * #gconf_bridge_bind_window for more details.
+ **/
+#define gconf_bridge_bind_window_size(bridge, key_prefix, window) \
+        gconf_bridge_bind_window ((bridge), (key_prefix), (window), TRUE, FALSE)
+
+/**
+ * gconf_bridge_bind_window_pos
+ * @bridge: A #GConfBridge
+ * @key_prefix: The prefix of the GConf keys
+ * @window: A #GtkWindow
+ * 
+ * On calling this function @window will be moved to the values specified by
+ * "@key_prefix<!-- -->_x" and "@key_prefix<!-- -->_y". The respective GConf
+ * values will be updated when the window is moved. See
+ * #gconf_bridge_bind_window for more details.
+ **/
+#define gconf_bridge_bind_window_pos(bridge, key_prefix, window) \
+        gconf_bridge_bind_window ((bridge), (key_prefix), (window), FALSE, TRUE)
+
+guint        gconf_bridge_bind_string_list_store (GConfBridge  *bridge,
+                                                  const char   *key,
+                                                  GtkListStore *list_store);
+
+void         gconf_bridge_unbind                 (GConfBridge  *bridge,
+                                                  guint         binding_id);
+
+G_END_DECLS
+
+#endif /* __GCONF_BRIDGE_H__ */

Modified: branches/mbarnes-composer/configure.in
==============================================================================
--- branches/mbarnes-composer/configure.in	(original)
+++ branches/mbarnes-composer/configure.in	Sat Feb  9 21:54:02 2008
@@ -1496,7 +1496,7 @@
 
 dnl --- evolution-addressbook flags
 
-EVOLUTION_ADDRESSBOOK_DEPS="libbonoboui-2.0 libglade-2.0 libgnomeui-2.0 gnome-vfs-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE"
+EVOLUTION_ADDRESSBOOK_DEPS="libbonoboui-2.0 libglade-2.0 libgnomeui-2.0 gnome-vfs-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE gtkhtml-editor"
 
 EVO_SET_COMPILE_FLAGS(EVOLUTION_ADDRESSBOOK, $EVOLUTION_ADDRESSBOOK_DEPS)
 AC_SUBST(EVOLUTION_ADDRESSBOOK_CFLAGS)
@@ -1525,7 +1525,7 @@
 AC_SUBST(LIBSOUP_CFLAGS)
 AC_SUBST(LIBSOUP_LIBS)
 
-EVO_SET_COMPILE_FLAGS(EVOLUTION_CALENDAR, libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gnome-vfs-module-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libecal-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE $HAL_REQUIREMENT $libnotify)
+EVO_SET_COMPILE_FLAGS(EVOLUTION_CALENDAR, libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gnome-vfs-module-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libecal-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE $HAL_REQUIREMENT $libnotify gtkhtml-editor)
 AC_SUBST(EVOLUTION_CALENDAR_CFLAGS)
 AC_SUBST(EVOLUTION_CALENDAR_LIBS)
 

Modified: branches/mbarnes-composer/mail/em-composer-utils.c
==============================================================================
--- branches/mbarnes-composer/mail/em-composer-utils.c	(original)
+++ branches/mbarnes-composer/mail/em-composer-utils.c	Sat Feb  9 21:54:02 2008
@@ -593,8 +593,13 @@
 }
 
 void
-em_composer_utils_setup_callbacks (EMsgComposer *composer, CamelFolder *folder, const char *uid,
-				   guint32 flags, guint32 set, CamelFolder *drafts, const char *drafts_uid)
+em_composer_utils_setup_callbacks (EMsgComposer *composer,
+                                   CamelFolder *folder,
+                                   const char *uid,
+				   guint32 flags,
+                                   guint32 set,
+                                   CamelFolder *drafts,
+                                   const char *drafts_uid)
 {
 	struct emcs_t *emcs;
 
@@ -614,9 +619,6 @@
 		emcs->drafts_uid = g_strdup (drafts_uid);
 	}
 
-	g_signal_connect (composer, "send", G_CALLBACK (em_utils_composer_send_cb), emcs);
-	g_signal_connect (composer, "save-draft", G_CALLBACK (em_utils_composer_save_draft_cb), emcs);
-
 	g_object_weak_ref ((GObject *) composer, (GWeakNotify) composer_destroy_cb, emcs);
 }
 

Modified: branches/mbarnes-composer/mail/mail-component-factory.c
==============================================================================
--- branches/mbarnes-composer/mail/mail-component-factory.c	(original)
+++ branches/mbarnes-composer/mail/mail-component-factory.c	Sat Feb  9 21:54:02 2008
@@ -24,8 +24,6 @@
 #include <config.h>
 #endif
 
-#include "em-composer-utils.h"
-#include "evolution-composer.h"
 #include "mail-component.h"
 #include "em-account-prefs.h"
 #include "em-mailer-prefs.h"
@@ -55,7 +53,6 @@
 
 #define FACTORY_ID	"OAFIID:GNOME_Evolution_Mail_Factory:" BASE_VERSION
 #define COMPONENT_ID	"OAFIID:GNOME_Evolution_Mail_Component:" BASE_VERSION
-#define COMPOSER_ID	"OAFIID:GNOME_Evolution_Mail_Composer:" BASE_VERSION
 #define FOLDER_INFO_ID	"OAFIID:GNOME_Evolution_FolderInfo:" BASE_VERSION
 
 static BonoboObject *
@@ -72,9 +69,6 @@
 		   || strcmp (component_id, EM_MAILER_PREFS_CONTROL_ID) == 0
 		   || strcmp (component_id, EM_COMPOSER_PREFS_CONTROL_ID) == 0) {
 		return mail_config_control_factory_cb (factory, component_id, CORBA_OBJECT_NIL);
-	} else if (strcmp(component_id, COMPOSER_ID) == 0) {
-		/* FIXME: how to remove need for callbacks, probably make the composer more tightly integrated with mail */
-		return (BonoboObject *) evolution_composer_new (em_utils_composer_send_cb, em_utils_composer_save_draft_cb);
 	}
 
 	o = mail_importer_factory_cb(factory, component_id, NULL);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]