Index: configure.in
===================================================================
RCS file: /cvs/gnome/evolution/configure.in,v
retrieving revision 1.847
diff -u -r1.847 configure.in
--- configure.in	28 Sep 2005 08:55:59 -0000	1.847
+++ configure.in	7 Oct 2005 04:19:43 -0000
@@ -1657,6 +1657,7 @@
 views/calendar/Makefile
 views/mail/Makefile
 views/tasks/Makefile
+views/memos/Makefile
 widgets/Makefile
 widgets/e-timezone-dialog/Makefile
 widgets/menus/Makefile
@@ -1670,6 +1671,7 @@
 calendar/conduits/Makefile
 calendar/conduits/todo/Makefile
 calendar/conduits/calendar/Makefile
+calendar/conduits/memo/Makefile
 calendar/gui/Makefile
 calendar/gui/alarm-notify/Makefile
 calendar/gui/dialogs/Makefile
Index: calendar/calendar.error.xml
===================================================================
RCS file: /cvs/gnome/evolution/calendar/calendar.error.xml,v
retrieving revision 1.4
diff -u -r1.4 calendar.error.xml
--- calendar/calendar.error.xml	6 Oct 2005 18:21:51 -0000	1.4
+++ calendar/calendar.error.xml	7 Oct 2005 04:19:43 -0000
@@ -194,6 +194,13 @@
   <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
   <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
  </error>
+
+ <error id="prompt-delete-memo-list" type="question" modal="true" default="GTK_RESPONSE_CANCEL">
+  <_primary>Delete memo list '{0}'?</_primary>
+  <_secondary>This memo list will be removed permanently.</_secondary>
+  <button stock="gtk-cancel" response="GTK_RESPONSE_NO"/>
+  <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
  
  <error id="prompt-send-no-subject-calendar" type="question" default="GTK_RESPONSE_YES">
   <_primary>Are you sure you want to send the appointment without a summary?</_primary>
@@ -218,6 +225,12 @@
  <error id="prompt-no-contents-offline-tasks" type="error" default="GTK_RESPONSE_YES">
   <_primary>Error loading task list</_primary>
   <_secondary>The task list is not marked for offline usage</_secondary>
+  <button stock ="gtk-ok" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-no-contents-offline-memos" type="error" default="GTK_RESPONSE_YES">
+  <_primary>Error loading memo list</_primary>
+  <_secondary>The memo list is not marked for offline usage</_secondary>
   <button stock ="gtk-ok" response="GTK_RESPONSE_YES"/>
  </error>
 
Index: calendar/conduits/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/calendar/conduits/Makefile.am,v
retrieving revision 1.2
diff -u -r1.2 Makefile.am
--- calendar/conduits/Makefile.am	12 Jul 2000 23:34:10 -0000	1.2
+++ calendar/conduits/Makefile.am	7 Oct 2005 04:19:43 -0000
@@ -1 +1 @@
-SUBDIRS = calendar todo
+SUBDIRS = calendar memo todo
Index: calendar/gui/GNOME_Evolution_Calendar.server.in.in
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/GNOME_Evolution_Calendar.server.in.in,v
retrieving revision 1.17
diff -u -r1.17 GNOME_Evolution_Calendar.server.in.in
--- calendar/gui/GNOME_Evolution_Calendar.server.in.in	18 Jun 2005 11:31:51 -0000	1.17
+++ calendar/gui/GNOME_Evolution_Calendar.server.in.in	7 Oct 2005 04:19:45 -0000
@@ -71,6 +71,26 @@
 	<oaf_attribute name="evolution:button_sort_order" type="string" value="-8"/>
 </oaf_server>
 
+<oaf_server iid="OAFIID:GNOME_Evolution_Memos_Component:@VERSION@"
+            type="factory"
+            location="OAFIID:GNOME_Evolution_Calendar_Factory:@VERSION@">
+
+	<oaf_attribute name="repo_ids" type="stringv">
+		<item value="IDL:GNOME/Evolution/Component:@VERSION@"/>
+	</oaf_attribute>
+
+	<oaf_attribute name="evolution:component_alias" type="string" value="memos"/>
+
+	<oaf_attribute name="name" type="string" _value="Evolution's Memos component"/>
+
+	<oaf_attribute name="evolution:menu_label" type="string" _value="Memo_s"/>
+	<oaf_attribute name="evolution:menu_accelerator" type="string" value="*Control*F6"/>
+	<oaf_attribute name="evolution:button_label" type="string" _value="Memos"/>
+	<oaf_attribute name="evolution:button_tooltips" type="string" _value="Memos"/>
+        <oaf_attribute name="evolution:button_icon" type="string" value="stock_notes"/>
+	<oaf_attribute name="evolution:button_sort_order" type="string" value="-8"/>
+</oaf_server>
+
 <oaf_server iid="OAFIID:GNOME_Evolution_Calendar_CompEditorFactory:@VERSION@"
             type="factory"
             location="OAFIID:GNOME_Evolution_Calendar_Factory:@VERSION@">
Index: calendar/gui/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/Makefile.am,v
retrieving revision 1.306
diff -u -r1.306 Makefile.am
--- calendar/gui/Makefile.am	18 Aug 2005 04:33:38 -0000	1.306
+++ calendar/gui/Makefile.am	7 Oct 2005 04:19:45 -0000
@@ -75,7 +75,8 @@
 etspec_DATA =				\
 	e-calendar-table.etspec		\
 	e-meeting-time-sel.etspec	\
-	e-cal-list-view.etspec
+	e-cal-list-view.etspec		\
+	e-memo-table.etspec
 
 libevolution_calendar_la_SOURCES =		\
 	$(IDL_GENERATED)			\
@@ -103,6 +104,8 @@
 	e-alarm-list.h				\
 	e-cal-component-preview.c		\
 	e-cal-component-preview.h		\
+	e-cal-component-memo-preview.c		\
+	e-cal-component-memo-preview.h		\
 	e-cal-config.c				\
 	e-cal-config.h				\
 	e-cal-event.c				\
@@ -124,6 +127,8 @@
 	e-cal-list-view.h			\
 	e-cal-list-view-config.c		\
 	e-cal-list-view-config.h		\
+	e-cal-model-memos.c			\
+	e-cal-model-memos.h			\
 	e-calendar-table.c			\
 	e-calendar-table.h			\
 	e-calendar-table-config.c		\
@@ -165,6 +170,12 @@
 	e-meeting-types.h			\
 	e-meeting-utils.c			\
 	e-meeting-utils.h			\
+	e-memo-table.c				\
+	e-memo-table.h				\
+	e-memo-table-config.c			\
+	e-memo-table-config.h			\
+	e-memos.c				\
+	e-memos.h				\
 	e-mini-calendar-config.c		\
 	e-mini-calendar-config.h		\
 	e-pub-utils.c				\
@@ -198,6 +209,10 @@
 	itip-utils.c				\
 	itip-utils.h				\
 	main.c					\
+	memos-component.c			\
+	memos-component.h			\
+	memos-control.c				\
+	memos-control.h				\
 	migration.c				\
 	migration.h				\
 	misc.c					\
Index: calendar/gui/calendar-config-keys.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config-keys.h,v
retrieving revision 1.10
diff -u -r1.10 calendar-config-keys.h
--- calendar/gui/calendar-config-keys.h	6 Oct 2005 18:21:51 -0000	1.10
+++ calendar/gui/calendar-config-keys.h	7 Oct 2005 04:19:45 -0000
@@ -65,6 +65,11 @@
 #define CALENDAR_CONFIG_TASKS_DUE_TODAY_COLOR CALENDAR_CONFIG_PREFIX "/tasks/colors/due_today"
 #define CALENDAR_CONFIG_TASKS_OVERDUE_COLOR CALENDAR_CONFIG_PREFIX "/tasks/colors/overdue"
 
+/* Memo display settings */
+#define CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS CALENDAR_CONFIG_PREFIX "/memos/selected_memos"
+#define CALENDAR_CONFIG_PRIMARY_MEMOS CALENDAR_CONFIG_PREFIX "/memos/primary_memos"
+
+
 /* Prompt settings */
 #define CALENDAR_CONFIG_PROMPT_DELETE CALENDAR_CONFIG_PREFIX "/prompts/confirm_delete"
 #define CALENDAR_CONFIG_PROMPT_PURGE CALENDAR_CONFIG_PREFIX "/prompts/confirm_purge"
Index: calendar/gui/calendar-config.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config.c,v
retrieving revision 1.79
diff -u -r1.79 calendar-config.c
--- calendar/gui/calendar-config.c	6 Oct 2005 18:21:51 -0000	1.79
+++ calendar/gui/calendar-config.c	7 Oct 2005 04:19:45 -0000
@@ -649,6 +649,55 @@
 	gconf_client_set_int (config, CALENDAR_CONFIG_TASK_VPANE_POS, vpane_pos, NULL);
 }
 
+/***************************************/
+
+/* The current list of memo lists selected */
+GSList   *
+calendar_config_get_memos_selected (void)
+{
+	return gconf_client_get_list (config, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, NULL);
+}
+
+void
+calendar_config_set_memos_selected (GSList *selected)
+{
+	gconf_client_set_list (config, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, selected, NULL);
+}
+
+guint
+calendar_config_add_notification_memos_selected (GConfClientNotifyFunc func, gpointer data)
+{
+	guint id;
+	
+	id = gconf_client_notify_add (config, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, func, data, NULL, NULL);
+	
+	return id;
+}
+
+/* The primary memo list */
+char *
+calendar_config_get_primary_memos (void)
+{
+	return gconf_client_get_string (config, CALENDAR_CONFIG_PRIMARY_MEMOS, NULL);
+}
+
+void
+calendar_config_set_primary_memos (const char *primary_uid)
+{
+	gconf_client_set_string (config, CALENDAR_CONFIG_PRIMARY_MEMOS, primary_uid, NULL);
+}
+
+
+guint
+calendar_config_add_notification_primary_memos (GConfClientNotifyFunc func, gpointer data)
+{
+	guint id;
+	
+	id = gconf_client_notify_add (config, CALENDAR_CONFIG_PRIMARY_MEMOS, func, data, NULL, NULL);
+	
+	return id;
+}
+/***************************************/
 
 /* Whether we compress the weekend in the week/month views. */
 gboolean
Index: calendar/gui/calendar-config.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-config.h,v
retrieving revision 1.41
diff -u -r1.41 calendar-config.h
--- calendar/gui/calendar-config.h	6 Oct 2005 18:21:51 -0000	1.41
+++ calendar/gui/calendar-config.h	7 Oct 2005 04:19:45 -0000
@@ -166,6 +166,17 @@
 gint      calendar_config_get_task_vpane_pos    (void);
 void      calendar_config_set_task_vpane_pos    (gint         vpane_pos);
 
+
+/* The current list of memo lists selected */
+GSList   *calendar_config_get_memos_selected (void);
+void	  calendar_config_set_memos_selected (GSList *selected);
+guint	  calendar_config_add_notification_memos_selected (GConfClientNotifyFunc func, gpointer data);
+
+/* The primary calendar */
+char     *calendar_config_get_primary_memos (void);
+void	  calendar_config_set_primary_memos (const char *primary_uid);
+guint	  calendar_config_add_notification_primary_memos (GConfClientNotifyFunc func, gpointer data);
+
 /* Colors for the task list */
 const char *calendar_config_get_tasks_due_today_color	(void);
 void	    calendar_config_set_tasks_due_today_color	(const char *color);
Index: calendar/gui/comp-util.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/comp-util.c,v
retrieving revision 1.27
diff -u -r1.27 comp-util.c
--- calendar/gui/comp-util.c	24 Mar 2005 15:38:39 -0000	1.27
+++ calendar/gui/comp-util.c	7 Oct 2005 04:19:46 -0000
@@ -369,3 +369,22 @@
 
 	return comp;
 }
+
+ECalComponent *
+cal_comp_memo_new_with_defaults (ECal *client)
+{
+	ECalComponent *comp;
+	icalcomponent *icalcomp;
+
+	if (!e_cal_get_default_object (client, &icalcomp, NULL))
+		icalcomp = icalcomponent_new (ICAL_VJOURNAL_COMPONENT);
+	
+	comp = e_cal_component_new ();
+	if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
+		icalcomponent_free (icalcomp);
+
+		e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_JOURNAL);
+	}
+
+	return comp;
+}
Index: calendar/gui/comp-util.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/comp-util.h,v
retrieving revision 1.12
diff -u -r1.12 comp-util.h
--- calendar/gui/comp-util.h	15 Jan 2004 13:46:45 -0000	1.12
+++ calendar/gui/comp-util.h	7 Oct 2005 04:19:46 -0000
@@ -42,5 +42,6 @@
 ECalComponent *cal_comp_event_new_with_defaults (ECal *client);
 ECalComponent *cal_comp_event_new_with_current_time (ECal *client, gboolean all_day);
 ECalComponent *cal_comp_task_new_with_defaults (ECal *client);
+ECalComponent *cal_comp_memo_new_with_defaults (ECal *client);
 
 #endif
Index: calendar/gui/main.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/main.c,v
retrieving revision 1.173
diff -u -r1.173 main.c
--- calendar/gui/main.c	12 Jul 2005 04:04:10 -0000	1.173
+++ calendar/gui/main.c	7 Oct 2005 04:19:46 -0000
@@ -44,6 +44,7 @@
 #include "itip-bonobo-control.h"
 #include "tasks-control.h"
 #include "tasks-component.h"
+#include "memos-component.h"
 
 #include <e-util/e-plugin.h>
 #include <e-util/e-import.h>
@@ -57,6 +58,7 @@
 
 #define CALENDAR_COMPONENT_ID  "OAFIID:GNOME_Evolution_Calendar_Component:" BASE_VERSION
 #define TASKS_COMPONENT_ID     "OAFIID:GNOME_Evolution_Tasks_Component:" BASE_VERSION
+#define MEMOS_COMPONENT_ID     "OAFIID:GNOME_Evolution_Memos_Component:" BASE_VERSION
 #define ITIP_CONTROL_ID        "OAFIID:GNOME_Evolution_Calendar_iTip_Control:" BASE_VERSION
 #define CONFIG_CONTROL_ID      "OAFIID:GNOME_Evolution_Calendar_ConfigControl:" BASE_VERSION
 #define COMP_EDITOR_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_CompEditorFactory:" BASE_VERSION
@@ -177,6 +179,10 @@
 		return object;
 	} else if (strcmp (component_id, TASKS_COMPONENT_ID) == 0) {
 		BonoboObject *object = BONOBO_OBJECT (tasks_component_peek ());
+		bonobo_object_ref (object);
+		return object;
+	} else if (strcmp (component_id, MEMOS_COMPONENT_ID) == 0){
+		BonoboObject *object = BONOBO_OBJECT (memos_component_peek ());
 		bonobo_object_ref (object);
 		return object;
 	} else if (strcmp (component_id, ITIP_CONTROL_ID) == 0)
Index: calendar/gui/migration.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/migration.c,v
retrieving revision 1.36
diff -u -r1.36 migration.c
--- calendar/gui/migration.c	9 May 2005 08:37:47 -0000	1.36
+++ calendar/gui/migration.c	7 Oct 2005 04:19:47 -0000
@@ -997,3 +997,123 @@
 	
         return retval;
 }
+
+/********************************************************************************************************
+ *
+ * 		MEMOS
+ * 
+ ********************************************************************************************************/
+
+static void
+create_memo_sources (MemosComponent *component,
+		     ESourceList   *source_list,
+		     ESourceGroup **on_this_computer,
+		     ESourceGroup **on_the_web,
+		     ESource **personal_source)
+{
+	GSList *groups;
+	ESourceGroup *group;
+	char *base_uri, *base_uri_proto;
+
+	*on_this_computer = NULL;
+	*on_the_web = NULL;
+	*personal_source = NULL;
+	
+	base_uri = g_build_filename (memos_component_peek_base_directory (component),
+				     "memos", "local", NULL);
+
+	base_uri_proto = g_strconcat ("file://", base_uri, NULL);
+
+	groups = e_source_list_peek_groups (source_list);
+	if (groups) {
+		/* groups are already there, we need to search for things... */
+		GSList *g;
+
+		for (g = groups; g; g = g->next) {
+
+			group = E_SOURCE_GROUP (g->data);
+
+			if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group)))
+				*on_this_computer = g_object_ref (group);
+			else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group)))
+				*on_the_web = g_object_ref (group);
+		}
+	}
+
+	if (*on_this_computer) {
+		/* make sure "Personal" shows up as a source under
+		   this group */
+		GSList *sources = e_source_group_peek_sources (*on_this_computer);
+		GSList *s;
+		for (s = sources; s; s = s->next) {
+			ESource *source = E_SOURCE (s->data);
+			if (!strcmp (PERSONAL_RELATIVE_URI, e_source_peek_relative_uri (source))) {
+				*personal_source = g_object_ref (source);
+				break;
+			}
+		}
+	} else {
+		/* create the local source group */
+		group = e_source_group_new (_("On This Computer"), base_uri_proto);
+		e_source_list_add_group (source_list, group, -1);
+
+		*on_this_computer = group;
+	}
+
+	if (!*personal_source) {
+		/* Create the default Person task list */
+		ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
+		e_source_group_add_source (*on_this_computer, source, -1);
+
+		if (!calendar_config_get_primary_memos () && !calendar_config_get_memos_selected ()) {
+			GSList selected;
+
+			calendar_config_set_primary_memos (e_source_peek_uid (source));
+
+			selected.data = (gpointer)e_source_peek_uid (source);
+			selected.next = NULL;
+			calendar_config_set_memos_selected (&selected);
+		}
+
+		e_source_set_color (source, 0xBECEDD);
+		*personal_source = source;
+	}
+
+	if (!*on_the_web) {
+		/* Create the Webcal source group */
+		group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI);
+		e_source_list_add_group (source_list, group, -1);
+
+		*on_the_web = group;
+	}
+
+	g_free (base_uri_proto);
+	g_free (base_uri);
+}
+
+
+gboolean
+migrate_memos (MemosComponent *component, int major, int minor, int revision, struct _GError **err)
+{
+	ESourceGroup *on_this_computer = NULL;
+	ESourceGroup *on_the_web = NULL;
+	ESource *personal_source = NULL;
+	gboolean retval = FALSE;
+
+	/* we call this unconditionally now - create_groups either
+	   creates the groups/sources or it finds the necessary
+	   groups/sources. */
+	create_memo_sources (component, memos_component_peek_source_list (component), &on_this_computer, &on_the_web, &personal_source);
+
+	e_source_list_sync (memos_component_peek_source_list (component), NULL);
+	retval = TRUE;
+fail:
+	if (on_this_computer)
+		g_object_unref (on_this_computer);
+	if (on_the_web)
+		g_object_unref (on_the_web);
+	if (personal_source)
+		g_object_unref (personal_source);
+	
+        return retval;
+}
Index: calendar/gui/migration.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/migration.h,v
retrieving revision 1.6
diff -u -r1.6 migration.h
--- calendar/gui/migration.h	12 May 2004 03:32:19 -0000	1.6
+++ calendar/gui/migration.h	7 Oct 2005 04:19:47 -0000
@@ -26,10 +26,11 @@
 #include <libedataserver/e-source-group.h>
 #include "calendar-component.h"
 #include "tasks-component.h"
+#include "memos-component.h"
 
 struct _GError;
 
 gboolean migrate_calendars (CalendarComponent *component, int major, int minor, int revision, struct _GError **err);
 gboolean migrate_tasks (TasksComponent *component, int major, int minor, int revision, struct _GError **err);
-
+gboolean migrate_memos (MemosComponent *component, int major, int minor, int revision, struct _GError **err);
 #endif
Index: calendar/gui/print.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/print.c,v
retrieving revision 1.75
diff -u -r1.75 print.c
--- calendar/gui/print.c	1 Oct 2005 11:18:59 -0000	1.75
+++ calendar/gui/print.c	7 Oct 2005 04:19:49 -0000
@@ -2302,11 +2302,13 @@
 
 	vtype = e_cal_component_get_vtype (comp);
 
-	/* We should only be asked to print VEVENTs or VTODOs. */
+	/* We should only be asked to print VEVENTs, VTODOs, or VJOURNALs. */
 	if (vtype == E_CAL_COMPONENT_EVENT)
 		title = _("Appointment");
 	else if (vtype == E_CAL_COMPONENT_TODO)
 		title = _("Task");
+	else if (vtype == E_CAL_COMPONENT_JOURNAL)
+		title = _("Memo");
 	else
 		return;
 
Index: calendar/gui/dialogs/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/Makefile.am,v
retrieving revision 1.72
diff -u -r1.72 Makefile.am
--- calendar/gui/dialogs/Makefile.am	11 Jul 2005 08:59:38 -0000	1.72
+++ calendar/gui/dialogs/Makefile.am	7 Oct 2005 04:19:50 -0000
@@ -51,6 +51,10 @@
 	event-editor.h		\
 	event-page.c		\
 	event-page.h		\
+	memo-editor.c		\
+	memo-editor.h		\
+	memo-page.c		\
+	memo-page.h		\
 	meeting-page.c		\
 	meeting-page.h		\
 	recurrence-page.c	\
@@ -72,7 +76,7 @@
 	task-page.c		\
 	task-page.h		\
 	url-editor-dialog.c	\
-	url-editor-dialog.h	
+	url-editor-dialog.h
 
 glade_DATA =				\
 	alarm-dialog.glade		\
@@ -81,6 +85,7 @@
 	e-delegate-dialog.glade		\
 	event-page.glade		\
 	meeting-page.glade		\
+	memo-page.glade			\
 	recurrence-page.glade		\
 	schedule-page.glade		\
 	task-details-page.glade		\
Index: calendar/gui/dialogs/calendar-setup.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/calendar-setup.c,v
retrieving revision 1.38
diff -u -r1.38 calendar-setup.c
--- calendar/gui/dialogs/calendar-setup.c	24 Aug 2005 03:07:49 -0000	1.38
+++ calendar/gui/dialogs/calendar-setup.c	7 Oct 2005 04:19:50 -0000
@@ -288,6 +288,8 @@
 		else if (sdialog->source_type == E_CAL_SOURCE_TYPE_TODO)	
 
 			offline_setting = gtk_check_button_new_with_label (_("Copy task list contents locally for offline operation"));
+		else if(sdialog->source_type == E_CAL_SOURCE_TYPE_JOURNAL)
+			offline_setting = gtk_check_button_new_with_label(_("Copy memo list contents locally for offline operation"));
 
 		gtk_widget_show (offline_setting);
 		g_signal_connect (offline_setting, "toggled", G_CALLBACK (offline_status_changed_cb), sdialog);
@@ -383,6 +385,17 @@
 	{ 0 },
 };
 
+static ECalConfigItem ecmp_items[] = {
+	{ E_CONFIG_BOOK, "", NULL },
+	{ E_CONFIG_PAGE,          "00.general", N_("General") },
+	{ E_CONFIG_SECTION_TABLE, "00.general/00.source", N_("Memos List") },
+	{ E_CONFIG_ITEM_TABLE,    "00.general/00.source/00.type", NULL, eccp_get_source_type },
+	{ E_CONFIG_ITEM_TABLE,    "00.general/00.source/10.name", NULL, eccp_get_source_name },
+	{ E_CONFIG_ITEM_TABLE,    "00.general/00.source/20.color", NULL, eccp_get_source_color },
+	{ E_CONFIG_ITEM_TABLE,	  "00.general/00.source/30.offline", NULL, eccp_general_offline },
+	{ 0 },
+};
+
 /**
  * calendar_setup_edit_calendar:
  * @parent: parent window for dialog (current unused)
@@ -525,4 +538,70 @@
 calendar_setup_new_task_list (struct _GtkWindow *parent)
 {
 	calendar_setup_edit_task_list (parent, NULL);
+}
+
+void
+calendar_setup_edit_memo_list (struct _GtkWindow *parent, ESource *source)
+{
+	CalendarSourceDialog *sdialog = g_new0 (CalendarSourceDialog, 1);
+	char *xml;
+	ECalConfig *ec;
+	int i;
+	GSList *items = NULL;
+	ECalConfigTargetSource *target;
+
+	if (source) {
+		guint32 color;
+
+		sdialog->original_source = source;
+		g_object_ref (source);
+		sdialog->source_group = e_source_peek_group (source);
+		xml = e_source_to_standalone_xml (source);
+		sdialog->source = e_source_new_from_standalone_xml (xml);
+		g_free (xml);
+
+		e_source_get_color (source, &color);
+		e_source_set_color (sdialog->source, color);
+	} else {
+		GConfClient *gconf;
+		GSList *l;
+
+		sdialog->source = e_source_new ("", "");
+		gconf = gconf_client_get_default ();
+		sdialog->source_list = e_source_list_new_for_gconf (gconf, "/apps/evolution/memos/sources");
+		l = e_source_list_peek_groups (sdialog->source_list);
+		sdialog->menu_source_groups = g_slist_copy(l);
+
+		sdialog->source_group = (ESourceGroup *)sdialog->menu_source_groups->data;
+		g_object_unref (gconf);
+	}
+
+	/* HACK: doesn't work if you don't do this */
+	e_source_set_absolute_uri (sdialog->source, NULL);
+	e_source_set_group (sdialog->source, sdialog->source_group);
+
+	sdialog->source_type = E_CAL_SOURCE_TYPE_JOURNAL;
+	sdialog->config = ec = e_cal_config_new (E_CONFIG_BOOK, "org.gnome.evolution.calendar.calendarProperties");
+	for (i = 0; ecmp_items[i].path; i++)
+		items = g_slist_prepend (items, &ecmp_items[i]);
+	e_config_add_items ((EConfig *) ec, items, eccp_commit, NULL, eccp_free, sdialog);
+	e_config_add_page_check ((EConfig *) ec, NULL, eccp_check_complete, sdialog);
+
+	target = e_cal_config_target_new_source (ec, sdialog->source);
+	target->source_type = E_CAL_SOURCE_TYPE_JOURNAL;
+	e_config_set_target ((EConfig *) ec, (EConfigTarget *) target);
+
+	sdialog->window = e_config_create_window ((EConfig *)ec, NULL, _("New Memo List"));
+
+	/* forces initial validation */
+	if (!sdialog->original_source)
+		e_config_target_changed ((EConfig *)ec, E_CONFIG_TARGET_CHANGED_STATE);
+
+	return;
+}
+
+void
+calendar_setup_new_memo_list (struct _GtkWindow *parent)
+{
+	calendar_setup_edit_memo_list (parent, NULL);
 }
Index: calendar/gui/dialogs/calendar-setup.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/calendar-setup.h,v
retrieving revision 1.3
diff -u -r1.3 calendar-setup.h
--- calendar/gui/dialogs/calendar-setup.h	25 Nov 2004 14:51:18 -0000	1.3
+++ calendar/gui/dialogs/calendar-setup.h	7 Oct 2005 04:19:50 -0000
@@ -36,6 +36,9 @@
 void calendar_setup_edit_task_list (struct _GtkWindow *parent, struct _ESource *source);
 void calendar_setup_new_task_list  (struct _GtkWindow *parent);
 
+void calendar_setup_edit_memo_list (struct _GtkWindow *parent, ESource *source);
+void calendar_setup_new_memo_list (struct _GtkWindow *parent);
+
 #ifdef __cplusplus
 }
 #endif
Index: calendar/gui/dialogs/send-comp.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/send-comp.c,v
retrieving revision 1.17
diff -u -r1.17 send-comp.c
--- calendar/gui/dialogs/send-comp.c	16 May 2005 06:13:14 -0000	1.17
+++ calendar/gui/dialogs/send-comp.c	7 Oct 2005 04:19:50 -0000
@@ -90,7 +90,8 @@
 	case E_CAL_COMPONENT_TODO:
 			id = "calendar:prompt-send-no-subject-task";
 		break;
-
+	case E_CAL_COMPONENT_JOURNAL:
+			return TRUE; /* we don't do summaries directly */
 	default:
 		g_message ("send_component_prompt_subject(): "
 			   "Cannot handle object of type %d", vtype);
Index: ui/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/ui/Makefile.am,v
retrieving revision 1.25
diff -u -r1.25 Makefile.am
--- ui/Makefile.am	4 Jan 2005 19:38:07 -0000	1.25
+++ ui/Makefile.am	7 Oct 2005 04:19:52 -0000
@@ -8,6 +8,7 @@
 	evolution-mail-list.xml			\
 	evolution-mail-global.xml		\
 	evolution-mail-messagedisplay.xml	\
+	evolution-memos.xml			\
 	evolution-message-composer.xml		\
 	evolution-signature-editor.xml		\
 	evolution-subscribe.xml			\
Index: views/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/views/Makefile.am,v
retrieving revision 1.4
diff -u -r1.4 Makefile.am
--- views/Makefile.am	12 Jun 2003 21:13:33 -0000	1.4
+++ views/Makefile.am	7 Oct 2005 04:19:52 -0000
@@ -1,3 +1,3 @@
-SUBDIRS = addressbook mail tasks calendar
+SUBDIRS = addressbook mail tasks calendar memos
 
 EXTRA_DIST = ChangeLog.pre-1-4
Index: ChangeLog.owens
===================================================================
RCS file: ChangeLog.owens
diff -N ChangeLog.owens
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ChangeLog.owens	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,3 @@
+2005-07-25  Nathan Owens <pianocomp81@yahoo.com>
+	* configure.in: Add views/memos/Makefile,
+	calendar/conduits/memo/Makefile to Makefile list
Index: calendar/ChangeLog.owens
===================================================================
RCS file: calendar/ChangeLog.owens
diff -N calendar/ChangeLog.owens
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/ChangeLog.owens	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,31 @@
+2005-07-25  Nathan Owens <pianocomp81@yahoo.com>
+	* calendar.error.xml: Added strings for memos
+	* calendar/conduits/Makefile.am: added 'memo' to SUBDIRS
+	* calendar/conduits/memo/*: initial memo conduit
+	* calendar/gui/calendar-config.[ch]: (calendar_config_get_memos_selected)
+	(calendar_config_set_memos_selected) (calendar_config_add_notification_memos_selected): 
+	gconf get/set for memos lists
+	* calendar/gui/calendar-config-keys.h: added gconf keys for Memos component
+	* calendar/gui/comp-util.[ch] (cal_comp_memo_new_with_defaults): added function
+	to create memo component with defaults
+	* calendar/gui/e-cal-component-memo-preview.[ch]: initial file for preview of a memo
+	* calendar/gui/e-cal-model-memos.[ch]: initial model for the memos component.
+	* calendar/gui/e-memos.[ch]: initial memos base
+	* calendar/gui/e-memo-table.[ch]: initial view for memos component
+	* calendar/gui/e-memo-table.etspec: etspec for memos e-table
+	* calendar/gui/e-memo-table-config.[ch]: initial configuration for memos e-table view
+	* calendar/gui/GNOME_Evolution_Calendar.server.in.in: added Memos component
+	* calendar/gui/main.c: added initialization code for Memos component
+	* calendar/gui/Makefile.am: added entries for new files for Memos component
+	* calendar/gui/memos-component.[ch]: Memos component base code
+	* calendar/gui/memos-control.[ch]: initial user control code. Used for printing,
+	copying, etc.
+	* calendar/gui/migration.c: added migration for memos component - also takes care
+	of initialization for the first time the Memos component is run.
+	* calendar/gui/dialogs/calendar-setup.[ch]: added code to create a new Memo List
+	* calendar/gui/dialogs/Makefile.am: added files for build
+	* calendar/gui/dialogs/memo-editor.[ch]: initial memo editor
+	* calendar/gui/dialogs/memo-page.[ch]: page in editor for editing a memo
+	* calendar/gui/dialogs/memo-page.glade: glade file for memo-editor-page
+	* calendar/gui/dialogs/send-comp.c: added E_CAL_COMPONENT_JOURNAL support for Memo
+	component
Index: calendar/conduits/memo/Makefile.am
===================================================================
RCS file: calendar/conduits/memo/Makefile.am
diff -N calendar/conduits/memo/Makefile.am
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/conduits/memo/Makefile.am	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,37 @@
+INCLUDES = 					\
+	-I$(top_srcdir)/e-util			\
+	-I$(top_builddir)/e-util		\
+	-I$(top_srcdir)/widgets/misc		\
+	-I$(top_builddir)/widgets/misc		\
+	$(EVOLUTION_CALENDAR_CONDUIT_CFLAGS)
+
+# Memo Conduit
+privconduit_LTLIBRARIES = libememo_conduit.la
+
+libememo_conduit_la_SOURCES = 	\
+	memo-conduit.c
+
+libememo_conduit_la_LDFLAGS = -module -avoid-version
+libememo_conduit_la_LIBADD = 						\
+	$(top_builddir)/e-util/libeutil.la				\
+	$(top_builddir)/e-util/libeconduit.la		 		\
+	$(top_builddir)/widgets/misc/libemiscwidgets.la		 	\
+	$(EVOLUTION_CALENDAR_CONDUIT_LIBS)
+
+e-memo-$(BASE_VERSION).conduit: e-memo.conduit.in
+	sed -e 's^\@privconduitdir\@^$(privconduitdir)^g' 			\
+	    -e 's^\@datadir\@^$(datadir)^g' 				\
+	    -e 's^\@BASE_VERSION\@^$(BASE_VERSION)^g' 			\
+	    $< > $@
+
+conduitdir = $(datadir)/gnome-pilot/conduits/
+conduit_DATA = e-memo-$(BASE_VERSION).conduit
+
+BUILT_SOURCES = $(conduit_DATA)
+CLEANFILES = $(BUILT_SOURCES)
+
+EXTRA_DIST = \
+	e-memo.conduit.in
+
+dist-hook:
+	cd $(distdir); rm -f $(BUILT_SOURCES)
Index: calendar/conduits/memo/e-memo.conduit.in
===================================================================
RCS file: calendar/conduits/memo/e-memo.conduit.in
diff -N calendar/conduits/memo/e-memo.conduit.in
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/conduits/memo/e-memo.conduit.in	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,8 @@
+<gnome-pilot-conduit version="1.0">
+	<conduit id="e_memo_conduit" type="shlib" location="@privconduitdir@/libememo_conduit.so"/>
+	<name value="EMemos"/>
+	<conduit-attribute name="description" value="Synchronizes Memo List with Evolution @BASE_VERSION@"/>
+	<conduit-attribute name="default-synctype" value="synchronize"/>
+	<conduit-attribute name="valid-synctypes" value="synchronize copy_from_pilot copy_to_pilot"/>
+     	<conduit-attribute name="settings" value="TRUE"/>
+</gnome-pilot-conduit>
Index: calendar/conduits/memo/memo-conduit.c
===================================================================
RCS file: calendar/conduits/memo/memo-conduit.c
diff -N calendar/conduits/memo/memo-conduit.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/conduits/memo/memo-conduit.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,1445 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Evolution calendar - Memo Conduit
+ *
+ * Copyright (C) 1998 Free Software Foundation
+ * Copyright (C) 2000 Ximian, Inc.
+ *
+ * Authors: Eskil Heyn Olsen <deity@eskil.dk> 
+ *          JP Rosevear <jpr@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define G_LOG_DOMAIN "ememoconduit"
+
+#include <libecal/e-cal-types.h>
+#include <libecal/e-cal.h>
+#include <libecal/e-cal-time-util.h>
+#include <libedataserver/e-categories.h>
+#include <pi-source.h>
+#include <pi-socket.h>
+#include <pi-dlp.h>
+#include <pi-memo.h>
+#include <libical/icaltypes.h>
+#include <gpilotd/gnome-pilot-conduit.h>
+#include <gpilotd/gnome-pilot-conduit-sync-abs.h>
+#include <libgpilotdCM/gnome-pilot-conduit-management.h>
+#include <libgpilotdCM/gnome-pilot-conduit-config.h>
+#include <e-pilot-map.h>
+#include <e-pilot-settings.h>
+#include <e-pilot-util.h>
+#include <e-config-listener.h>
+
+GnomePilotConduit * conduit_get_gpilot_conduit (guint32);
+void conduit_destroy_gpilot_conduit (GnomePilotConduit*);
+
+#define CONDUIT_VERSION "0.1.6"
+
+#define DEBUG_MEMOCONDUIT 1
+/* #undef DEBUG_MEMOCONDUIT */
+
+#ifdef DEBUG_MEMOCONDUIT
+#define LOG(x) x
+#else
+#define LOG(x)
+#endif
+
+#define WARN g_warning
+#define INFO g_message
+
+typedef struct _EMemoLocalRecord EMemoLocalRecord;
+typedef struct _EMemoConduitCfg EMemoConduitCfg;
+typedef struct _EMemoConduitGui EMemoConduitGui;
+typedef struct _EMemoConduitContext EMemoConduitContext;
+
+/* Local Record */
+struct _EMemoLocalRecord {
+	/* The stuff from gnome-pilot-conduit-standard-abs.h
+	   Must be first in the structure, or instances of this
+	   structure cannot be used by gnome-pilot-conduit-standard-abs.
+	*/
+	GnomePilotDesktopRecord local;
+
+	/* The corresponding Comp object */
+	ECalComponent *comp;
+
+        /* pilot-link memo structure */
+	struct Memo *memo;
+};
+
+int lastDesktopUniqueID;
+
+static void
+memoconduit_destroy_record (EMemoLocalRecord *local) 
+{
+	g_object_unref (local->comp);
+	free_Memo (local->memo);
+	g_free (local->memo);	
+	g_free (local);
+}
+
+/* Configuration */
+struct _EMemoConduitCfg {
+	guint32 pilot_id;
+	GnomePilotConduitSyncType  sync_type;
+
+	ESourceList *source_list;
+	ESource *source;
+	gboolean secret;
+	gint priority;
+
+	gchar *last_uri;
+};
+
+static EMemoConduitCfg *
+memoconduit_load_configuration (guint32 pilot_id) 
+{
+	EMemoConduitCfg *c;
+	GnomePilotConduitManagement *management;
+	GnomePilotConduitConfig *config;
+	gchar prefix[256];
+
+
+	g_snprintf (prefix, 255, "/gnome-pilot.d/e-memo-conduit/Pilot_%u/",
+		    pilot_id);
+	
+	c = g_new0 (EMemoConduitCfg,1);
+	g_assert (c != NULL);
+
+	c->pilot_id = pilot_id;
+
+	management = gnome_pilot_conduit_management_new ("e_memo_conduit", GNOME_PILOT_CONDUIT_MGMT_ID);
+	gtk_object_ref (GTK_OBJECT (management));
+	gtk_object_sink (GTK_OBJECT (management));
+	config = gnome_pilot_conduit_config_new (management, pilot_id);
+	gtk_object_ref (GTK_OBJECT (config));
+	gtk_object_sink (GTK_OBJECT (config));
+	if (!gnome_pilot_conduit_config_is_enabled (config, &c->sync_type))
+		c->sync_type = GnomePilotConduitSyncTypeNotSet;
+	gtk_object_unref (GTK_OBJECT (config));
+	gtk_object_unref (GTK_OBJECT (management));
+	
+	/* Custom settings */
+	gnome_config_push_prefix (prefix);
+	
+	if (!e_cal_get_sources (&c->source_list, E_CAL_SOURCE_TYPE_JOURNAL, NULL))
+		c->source_list = NULL;
+	if (c->source_list) {
+		c->source = e_pilot_get_sync_source (c->source_list);
+		if (!c->source)
+			c->source = e_source_list_peek_source_any (c->source_list);
+		if (c->source) {
+			g_object_ref (c->source);
+		} else {
+			g_object_unref (c->source_list);
+			c->source_list = NULL;
+		}
+	}
+	
+	c->secret = gnome_config_get_bool ("secret=FALSE");
+	c->priority = gnome_config_get_int ("priority=3");
+	c->last_uri = gnome_config_get_string ("last_uri");
+
+	gnome_config_pop_prefix ();
+
+	return c;
+}
+
+static void
+memoconduit_save_configuration (EMemoConduitCfg *c) 
+{
+	gchar prefix[256];
+
+	g_snprintf (prefix, 255, "/gnome-pilot.d/e-memo-conduit/Pilot_%u/",
+		    c->pilot_id);
+
+	gnome_config_push_prefix (prefix);
+	e_pilot_set_sync_source (c->source_list, c->source);
+	gnome_config_set_bool ("secret", c->secret);
+	gnome_config_set_int ("priority", c->priority);
+	gnome_config_set_string ("last_uri", c->last_uri);
+	gnome_config_pop_prefix ();
+
+	gnome_config_sync ();
+	gnome_config_drop_all ();
+}
+
+static EMemoConduitCfg*
+memoconduit_dupe_configuration (EMemoConduitCfg *c) 
+{
+	EMemoConduitCfg *retval;
+
+	g_return_val_if_fail (c != NULL, NULL);
+
+	retval = g_new0 (EMemoConduitCfg, 1);
+	retval->sync_type = c->sync_type;
+	retval->pilot_id = c->pilot_id;
+
+	if (c->source_list)
+		retval->source_list = g_object_ref (c->source_list);
+	if (c->source)
+		retval->source = g_object_ref (c->source);
+	retval->secret = c->secret;
+	retval->priority = c->priority;
+	retval->last_uri = g_strdup (c->last_uri);
+
+	return retval;
+}
+
+static void 
+memoconduit_destroy_configuration (EMemoConduitCfg *c) 
+{
+	g_return_if_fail (c != NULL);
+
+	g_object_unref (c->source_list);
+	g_object_unref (c->source);
+	g_free (c->last_uri);
+	g_free (c);
+}
+
+/* Context */
+struct _EMemoConduitContext {
+	GnomePilotDBInfo *dbi;
+
+	EMemoConduitCfg *cfg;
+	EMemoConduitCfg *new_cfg;
+	GtkWidget *ps;
+	
+	struct MemoAppInfo ai;
+
+	ECal *client;
+
+	icaltimezone *timezone;
+	ECalComponent *default_comp;
+	GList *comps;
+	GList *changed;
+	GHashTable *changed_hash;
+	GList *locals;
+	
+	EPilotMap *map;
+};
+
+static EMemoConduitContext *
+e_memo_context_new (guint32 pilot_id) 
+{
+	EMemoConduitContext *ctxt = g_new0 (EMemoConduitContext, 1);
+	
+	ctxt->cfg = memoconduit_load_configuration (pilot_id);
+	ctxt->new_cfg = memoconduit_dupe_configuration (ctxt->cfg);
+	ctxt->ps = NULL;
+	ctxt->client = NULL;
+	ctxt->timezone = NULL;
+	ctxt->default_comp = NULL;
+	ctxt->comps = NULL;
+	ctxt->changed_hash = NULL;
+	ctxt->changed = NULL;
+	ctxt->locals = NULL;
+	ctxt->map = NULL;
+
+	return ctxt;
+}
+
+static gboolean
+e_memo_context_foreach_change (gpointer key, gpointer value, gpointer data) 
+{
+	g_free (key);
+	
+	return TRUE;
+}
+
+static void
+e_memo_context_destroy (EMemoConduitContext *ctxt)
+{
+	GList *l;
+	
+	g_return_if_fail (ctxt != NULL);
+
+	if (ctxt->cfg != NULL)
+		memoconduit_destroy_configuration (ctxt->cfg);
+	if (ctxt->new_cfg != NULL)
+		memoconduit_destroy_configuration (ctxt->new_cfg);
+	
+	if (ctxt->client != NULL)
+		g_object_unref (ctxt->client);
+
+	if (ctxt->default_comp != NULL)
+		g_object_unref (ctxt->default_comp);
+	if (ctxt->comps != NULL) {
+		for (l = ctxt->comps; l; l = l->next)
+			g_object_unref (l->data);
+		g_list_free (ctxt->comps);
+	}
+
+	if (ctxt->changed_hash != NULL) {
+		g_hash_table_foreach_remove (ctxt->changed_hash, e_memo_context_foreach_change, NULL);
+		g_hash_table_destroy (ctxt->changed_hash);
+	}
+
+	if (ctxt->locals != NULL) {
+		for (l = ctxt->locals; l != NULL; l = l->next)
+			memoconduit_destroy_record (l->data);
+		g_list_free (ctxt->locals);
+	}
+	
+	if (ctxt->changed != NULL)
+		e_cal_free_change_list (ctxt->changed);
+	
+	if (ctxt->map != NULL)
+		e_pilot_map_destroy (ctxt->map);
+
+	g_free (ctxt);
+}
+
+/* Debug routines */
+static char *
+print_local (EMemoLocalRecord *local)
+{
+	static char buff[ 64 ];
+
+	if (local == NULL) {
+		sprintf (buff, "[NULL]");
+		return buff;
+	}
+
+	if (local->memo && local->memo->text) {
+		g_snprintf (buff, 64, "['%s']",
+			    local->memo->text ?
+			    local->memo->text : "");
+		return buff;
+	}
+
+	return "";
+}
+
+static char *print_remote (GnomePilotRecord *remote)
+{
+	static char buff[ 64 ];
+	struct Memo memo;
+
+	if (remote == NULL) {
+		sprintf (buff, "[NULL]");
+		return buff;
+	}
+
+	memset (&memo, 0, sizeof (struct Memo));
+	unpack_Memo (&memo, remote->record, remote->length);
+
+	g_snprintf (buff, 64, "['%s']",
+		    memo.text ?
+		    memo.text : "");
+
+	free_Memo (&memo);
+	
+	return buff;
+}
+
+static int
+start_calendar_server (EMemoConduitContext *ctxt)
+{
+	g_return_val_if_fail (ctxt != NULL, -2);
+
+	if (ctxt->cfg->source) {
+		ctxt->client = e_cal_new (ctxt->cfg->source, E_CAL_SOURCE_TYPE_JOURNAL);
+		if (!e_cal_open (ctxt->client, TRUE, NULL)) 
+			return -1;
+	} else if (!e_cal_open_default (&ctxt->client, E_CAL_SOURCE_TYPE_JOURNAL, NULL, NULL, NULL)) {
+		return -1;
+	}
+
+	return 0;
+}
+
+static icaltimezone *
+get_default_timezone (void)
+{
+	EConfigListener *listener;
+	icaltimezone *timezone = NULL;
+	char *location;
+
+	listener = e_config_listener_new ();
+
+	location = e_config_listener_get_string_with_default (listener,
+		"/apps/evolution/calendar/display/timezone", "UTC", NULL);
+	if (!location || !location[0]) {
+		g_free (location);
+		location = g_strdup ("UTC");
+	}
+	
+	timezone = icaltimezone_get_builtin_timezone (location);
+	g_free (location);
+
+	g_object_unref (listener);
+
+	return timezone;	
+}
+
+static char *
+map_name (EMemoConduitContext *ctxt) 
+{
+	char *filename;
+	
+	filename = g_strdup_printf ("%s/.evolution/memos/local/system/pilot-map-memo-%d.xml", g_get_home_dir (), ctxt->cfg->pilot_id);
+	
+	return filename;
+}
+
+static GList *
+next_changed_item (EMemoConduitContext *ctxt, GList *changes) 
+{
+	ECalChange *ccc;
+	GList *l;
+	
+	for (l = changes; l != NULL; l = l->next) {
+		const char *uid;
+
+		ccc = l->data;
+		
+		e_cal_component_get_uid (ccc->comp, &uid);
+		if (g_hash_table_lookup (ctxt->changed_hash, uid))
+			return l;
+	}
+	
+	return NULL;
+}
+
+static void
+compute_status (EMemoConduitContext *ctxt, EMemoLocalRecord *local, const char *uid)
+{
+	ECalChange *ccc;
+
+	local->local.archived = FALSE;
+	local->local.secret = FALSE;
+
+	ccc = g_hash_table_lookup (ctxt->changed_hash, uid);
+	
+	if (ccc == NULL) {
+		local->local.attr = GnomePilotRecordNothing;
+		return;
+	}
+	
+	switch (ccc->type) {
+	case E_CAL_CHANGE_ADDED:
+		local->local.attr = GnomePilotRecordNew;
+		break;	
+	case E_CAL_CHANGE_MODIFIED:
+		local->local.attr = GnomePilotRecordModified;
+		break;
+	case E_CAL_CHANGE_DELETED:
+		local->local.attr = GnomePilotRecordDeleted;
+		break;
+	}
+}
+
+static GnomePilotRecord
+local_record_to_pilot_record (EMemoLocalRecord *local,
+			      EMemoConduitContext *ctxt)
+{
+	GnomePilotRecord p;
+	static char record[0xffff];
+
+	g_assert (local->comp != NULL);
+	g_assert (local->memo != NULL );
+	
+	LOG (g_message ( "local_record_to_pilot_record\n" ));
+
+	p.ID = local->local.ID;
+	p.category = local->local.category;
+	p.attr = local->local.attr;
+	p.archived = local->local.archived;
+	p.secret = local->local.secret;
+
+	/* Generate pilot record structure */
+	p.record = record;
+	p.length = pack_Memo (local->memo, p.record, 0xffff);
+
+	return p;	
+}
+
+/*
+ * Adds a category to the category app info structure (name and ID),
+ * sets category->renamed[i] to true if possible to rename.
+ * 
+ * This will be packed and written to the app info block during post_sync.
+ */
+ 
+static int
+add_category_if_possible(char *cat_to_add, struct CategoryAppInfo *category)
+{
+	int i, j;
+	int retval = 0; /* 0 is the Unfiled category */
+	LOG(fprintf(stderr, "add_category_if_possible: called\n"));
+	
+	for(i=0; i<16; i++){
+		/* if strlen is 0, then the category is empty
+		   the PalmOS doesn't let 0-length strings for
+		   categories */
+		LOG(fprintf(stderr, "add_category_if_possible: calling strlen, i==%d\n", i));
+		if(strlen(category->name[i]) == 0){
+			int cat_to_add_len;
+			LOG(fprintf(stderr, "add_category_if_possible: strlen == 0\n"));
+			
+			cat_to_add_len = strlen(cat_to_add);
+			LOG(fprintf(stderr, "add_category_if_possible: cat_to_add_len: %d\n",
+					cat_to_add_len));
+			retval = i;
+			
+			/* only 15 characters for category, 16th is
+			 * '\0' can't do direct mem transfer due to
+			 * declaration type
+			 */
+			LOG(fprintf(stderr, "add_category_if_possible: copying first 15 of category\n"));
+			for(j=0; j<cat_to_add_len; j++){
+				category->name[i][j] = cat_to_add[j];
+			}
+			LOG(fprintf(stderr,
+				"add_category_if_possible: setting from %d to i==15 to \\0\n",
+				cat_to_add_len));
+
+			for(j=cat_to_add_len; j<16; j++)
+				category->name[i][j] = '\0';
+			
+			LOG(fprintf(stderr, "add_category_if_possible: setting ID[%d] to %d\n",
+				category->ID[i], lastDesktopUniqueID));
+			category->ID[i] = lastDesktopUniqueID;
+			lastDesktopUniqueID++;
+			
+			LOG(fprintf(stderr, "add_category_if_possible: setting renamed[%d] to TRUE\n", i));
+			category->renamed[i] = TRUE;
+			
+			LOG(g_message("*** adding category '%s', ID %d ***",
+				category->name[i], category->ID[i]));
+			break;
+		}
+	}
+	
+	if(retval == 0){
+		LOG(g_message("*** not adding category - category list already full ***"));
+	}
+	
+	return retval;
+}
+
+/*
+ * converts a ECalComponent object to a EMemoLocalRecord
+ */
+static void
+local_record_from_comp (EMemoLocalRecord *local, ECalComponent *comp, EMemoConduitContext *ctxt) 
+{
+	const char *uid;
+	GSList *d_list = NULL;
+	ECalComponentText *description;
+	ECalComponentClassification classif;
+	
+	LOG (g_message ( "local_record_from_comp\n" ));
+
+	g_return_if_fail (local != NULL);
+	g_return_if_fail (comp != NULL);
+
+	local->comp = comp;
+	g_object_ref (comp);
+
+	LOG(fprintf(stderr, "local_record_from_comp: calling e_cal_component_get_uid\n"));
+	e_cal_component_get_uid (local->comp, &uid);
+	LOG(fprintf(stderr, "local_record_from_comp: got UID - %s, calling e_pilot_map_lookup_pid\n", uid));
+	local->local.ID = e_pilot_map_lookup_pid (ctxt->map, uid, TRUE);
+	LOG(fprintf(stderr, "local_record_from_comp: local->local.ID == %lu\n", local->local.ID));
+
+	compute_status (ctxt, local, uid);
+	
+	LOG(fprintf(stderr, "local_record_from_comp: local->local.attr: %d\n", local->local.attr));
+
+	local->memo = g_new0 (struct Memo,1);
+
+	/* Don't overwrite the category */
+	if (local->local.ID != 0) {
+		char record[0xffff];
+		int cat = 0;
+		
+		LOG(fprintf(stderr, "local_record_from_comp: calling dlp_ReadRecordById\n"));
+		if (dlp_ReadRecordById (ctxt->dbi->pilot_socket, 
+					ctxt->dbi->db_handle,
+					local->local.ID, &record, 
+					NULL, NULL, NULL, &cat) > 0) {
+			local->local.category = cat;
+		}
+		LOG(fprintf(stderr, "local_record_from_comp: done calling dlp_ReadRecordById\n"));
+	}
+	
+	/*
+	 * Grab category from existing category list in ctxt->ai.category
+	 */
+	if(local->local.category == 0){
+		GSList *categ_list_head, *categ_list_cur;
+		int cat = -1;
+		int i;
+		
+		LOG(fprintf(stderr, "local_record_from_comp: trying to set category"));
+		LOG(fprintf(stderr, "local_record_from_comp: calling e_cal_component_get_categories_list\n"));
+		
+		e_cal_component_get_categories_list(comp, &categ_list_head);
+		LOG(fprintf(stderr, "local_record_from_comp: got list, setting categ_list_cur to head\n"));
+		
+		categ_list_cur = categ_list_head;
+		while (categ_list_cur && cat == -1)
+		{	
+			LOG(fprintf(stderr, "local_record_from_comp: iterating, data == %s",
+				(char *)categ_list_cur->data));
+			for(i=0; i<16; i++){
+				LOG(fprintf(stderr, "local_record_from_comp: i == %d\n", i));
+				if(strcmp((char *)categ_list_cur->data,
+					  ctxt->ai.category.name[i]) == 0){
+					cat = i;
+					LOG(fprintf(stderr, "local_record_from_comp: found category, name: %s\n",
+							ctxt->ai.category.name[i]));
+					break;
+				}
+			}
+			
+			LOG(fprintf(stderr, "local_record_from_comp: calling g_slist_next\n"));
+			categ_list_cur = g_slist_next(categ_list_cur);
+		}
+		
+		if(cat != -1){
+			LOG(fprintf(stderr, "local_record_from_comp: setting category\n"));
+			local->local.category = cat;
+		}
+		else if(categ_list_head != NULL){
+			local->local.category =
+				add_category_if_possible(
+					(char *)(categ_list_head->data),
+					&(ctxt->ai.category));
+		}
+	}
+
+	/* STOP: don't replace these with g_strdup, since free_Memo
+	   uses free to deallocate */
+
+	e_cal_component_get_description_list (comp, &d_list);
+	if (d_list) {
+		description = (ECalComponentText *) d_list->data;
+		if (description && description->value){
+			local->memo->text = e_pilot_utf8_to_pchar (description->value);
+		}
+		else{
+			local->memo->text = NULL;
+		}
+	} else {
+		local->memo->text = NULL;
+	}
+	
+	e_cal_component_get_classification (comp, &classif);
+
+	if (classif == E_CAL_COMPONENT_CLASS_PRIVATE)
+		local->local.secret = 1;
+	else
+		local->local.secret = 0;
+
+	local->local.archived = 0;
+}
+
+static void 
+local_record_from_uid (EMemoLocalRecord *local,
+		       const char *uid,
+		       EMemoConduitContext *ctxt)
+{
+	ECalComponent *comp;
+	icalcomponent *icalcomp;
+	GError *error = NULL;
+
+	g_assert(local!=NULL);
+	
+	LOG(g_message("local_record_from_uid\n"));
+
+	if (e_cal_get_object (ctxt->client, uid, NULL, &icalcomp, &error)) {
+		comp = e_cal_component_new ();
+		if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
+			g_object_unref (comp);
+			icalcomponent_free (icalcomp);
+			return;
+		}
+
+		local_record_from_comp (local, comp, ctxt);
+		g_object_unref (comp);
+	} else if (error->code == E_CALENDAR_STATUS_OBJECT_NOT_FOUND) {
+		comp = e_cal_component_new ();
+		e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_JOURNAL);
+		e_cal_component_set_uid (comp, uid);
+		local_record_from_comp (local, comp, ctxt);
+		g_object_unref (comp);
+	} else {
+		INFO ("Object did not exist");
+	}
+
+	g_clear_error (&error);
+}
+
+
+static ECalComponent *
+comp_from_remote_record (GnomePilotConduitSyncAbs *conduit,
+			 GnomePilotRecord *remote,
+			 ECalComponent *in_comp,
+			 icaltimezone *timezone,
+			 struct MemoAppInfo *ai)
+{
+	ECalComponent *comp;
+	struct Memo memo;
+	struct icaltimetype now;
+	icaltimezone *utc_zone;
+	char *txt, *txt2, *txt3;
+	char *category;
+	int i;
+	
+	g_return_val_if_fail (remote != NULL, NULL);
+
+	memset (&memo, 0, sizeof (struct Memo));
+	unpack_Memo (&memo, remote->record, remote->length);
+
+	utc_zone = icaltimezone_get_utc_timezone ();
+	now = icaltime_from_timet_with_zone (time (NULL), FALSE, 
+					     utc_zone);
+
+	if (in_comp == NULL) {
+		comp = e_cal_component_new ();
+		e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_JOURNAL);
+		e_cal_component_set_created (comp, &now);
+	} else {
+		comp = e_cal_component_clone (in_comp);
+	}
+
+	e_cal_component_set_last_modified (comp, &now);
+	
+	/* The iCal description field */
+	if (!memo.text) {
+		e_cal_component_set_comment_list (comp, NULL);
+		e_cal_component_set_summary(comp, NULL);
+	} else {
+		int idxToUse = -1, ntext = strlen(memo.text);
+		gboolean foundNL = FALSE;
+		GSList l;
+		ECalComponentText text, sumText;
+
+		for(i = 0; i<ntext && i<50; i++){
+			if(memo.text[i] == '\n'){
+				idxToUse = i;
+				foundNL = TRUE;
+				break;
+			}
+		}
+		
+		if(foundNL == FALSE){
+			if(ntext > 50){
+				txt2 = g_strndup(memo.text, 50);
+			}
+			else{
+				txt2 = g_strdup(memo.text);
+				
+			}
+		}
+		else{
+			txt2 = g_strndup(memo.text, idxToUse); /* cuts off '\n' */
+			
+		}
+
+		sumText.value = txt3 = e_pilot_utf8_from_pchar(txt2);
+		sumText.altrep = NULL;
+
+		text.value = txt = e_pilot_utf8_from_pchar (memo.text);
+		text.altrep = NULL;
+		l.data = &text;
+		l.next = NULL;
+
+		e_cal_component_set_summary(comp, &sumText);
+		e_cal_component_set_description_list (comp, &l);
+		free (txt);
+		g_free(txt2);
+		free(txt3);
+	} 
+
+
+	e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_NONE);
+
+	if (remote->secret)
+		e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PRIVATE);
+	else
+		e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PUBLIC);
+	
+	
+	/* set the category properly */
+	category = ai->category.name[remote->category];
+	
+	/* TODO The Memos editor page and search bar are not updated until
+	  a restart of the evolution client */
+	if(e_categories_exist(category) == FALSE){
+		/* add if it doesn't exist */
+		e_categories_add(category, NULL, NULL, TRUE);
+	}
+	
+	e_cal_component_set_categories(comp, category);
+
+	e_cal_component_commit_sequence (comp);
+	
+	free_Memo(&memo);
+
+	return comp;
+}
+
+static void
+check_for_slow_setting (GnomePilotConduit *c, EMemoConduitContext *ctxt)
+{
+	GnomePilotConduitStandard *conduit = GNOME_PILOT_CONDUIT_STANDARD (c);
+	int map_count;
+	const char *uri;
+	
+	/* If there are no objects or objects but no log */
+	map_count = g_hash_table_size (ctxt->map->pid_map);
+	if (map_count == 0)
+		gnome_pilot_conduit_standard_set_slow (conduit, TRUE);
+
+	/* Or if the URI's don't match */
+	uri = e_cal_get_uri (ctxt->client);
+	LOG (g_message ( "  Current URI %s (%s)\n", uri, ctxt->cfg->last_uri ? ctxt->cfg->last_uri : "<NONE>" ));
+	if (ctxt->cfg->last_uri != NULL && (strcmp (ctxt->cfg->last_uri, uri) != 0)) {
+		gnome_pilot_conduit_standard_set_slow (conduit, TRUE);
+		e_pilot_map_clear (ctxt->map);
+	}
+
+	if (gnome_pilot_conduit_standard_get_slow (conduit)) {
+		ctxt->map->write_touched_only = TRUE;
+		LOG (g_message ( "    doing slow sync\n" ));
+	} else {
+		LOG (g_message ( "    doing fast sync\n" ));
+	}	
+}
+
+/* Pilot syncing callbacks */
+static gint
+pre_sync (GnomePilotConduit *conduit,
+	  GnomePilotDBInfo *dbi,
+	  EMemoConduitContext *ctxt)
+{
+	GnomePilotConduitSyncAbs *abs_conduit;
+	GList *l;
+	int len;
+	unsigned char *buf;
+	char *filename, *change_id;
+	icalcomponent *icalcomp;
+	gint num_records, add_records = 0, mod_records = 0, del_records = 0;
+
+	abs_conduit = GNOME_PILOT_CONDUIT_SYNC_ABS (conduit);
+
+	LOG (g_message ( "---------------------------------------------------------\n" ));
+	LOG (g_message ( "pre_sync: Memo Conduit v.%s", CONDUIT_VERSION ));
+	g_message ("Memo Conduit v.%s", CONDUIT_VERSION);
+
+	ctxt->dbi = dbi;	
+	ctxt->client = NULL;
+	
+	if (start_calendar_server (ctxt) != 0) {
+		WARN(_("Could not start evolution-data-server"));
+		gnome_pilot_conduit_error (conduit, _("Could not start evolution-data-server"));
+		return -1;
+	}
+
+	/* Get the timezone */
+	ctxt->timezone = get_default_timezone ();
+	if (ctxt->timezone == NULL)
+		return -1;
+	LOG (g_message ( "  Using timezone: %s", icaltimezone_get_tzid (ctxt->timezone) ));
+
+	/* Set the default timezone on the backend. */
+	if (ctxt->timezone && !e_cal_set_default_timezone (ctxt->client, ctxt->timezone, NULL))
+		return -1;
+	
+	/* Get the default component */
+	if (!e_cal_get_default_object (ctxt->client, &icalcomp, NULL))
+		return -1;
+	
+	ctxt->default_comp = e_cal_component_new ();
+	if (!e_cal_component_set_icalcomponent (ctxt->default_comp, icalcomp)) {
+		g_object_unref (ctxt->default_comp);
+		icalcomponent_free (icalcomp);
+		return -1;
+	}
+	
+	/* Load the uid <--> pilot id map */
+	filename = map_name (ctxt);
+	e_pilot_map_read (filename, &ctxt->map);
+	g_free (filename);
+
+	/* Get the local database */
+	if (!e_cal_get_object_list_as_comp (ctxt->client, "#t", &ctxt->comps, NULL))
+		return -1;
+	
+	/* Count and hash the changes */
+	change_id = g_strdup_printf ("pilot-sync-evolution-memo-%d", ctxt->cfg->pilot_id);
+	if (!e_cal_get_changes (ctxt->client, change_id, &ctxt->changed, NULL))
+		return -1;
+	
+	ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal);
+	g_free (change_id);
+	
+	for (l = ctxt->changed; l != NULL; l = l->next) {
+		ECalChange *ccc = l->data;
+		const char *uid;
+		
+		e_cal_component_get_uid (ccc->comp, &uid);
+		if (!e_pilot_map_uid_is_archived (ctxt->map, uid)) {
+			
+			g_hash_table_insert (ctxt->changed_hash, g_strdup (uid), ccc);
+			
+			switch (ccc->type) {
+			case E_CAL_CHANGE_ADDED:
+				add_records++;
+				break;
+			case E_CAL_CHANGE_MODIFIED:
+				mod_records++;
+				break;
+			case E_CAL_CHANGE_DELETED:
+				del_records++;
+				break;
+			}
+		} else if (ccc->type == E_CAL_CHANGE_DELETED) {
+			e_pilot_map_remove_by_uid (ctxt->map, uid);
+		}
+	}
+
+	/* Set the count information */
+	num_records = g_list_length (ctxt->comps);
+	gnome_pilot_conduit_sync_abs_set_num_local_records(abs_conduit, num_records);
+	gnome_pilot_conduit_sync_abs_set_num_new_local_records (abs_conduit, add_records);
+	gnome_pilot_conduit_sync_abs_set_num_updated_local_records (abs_conduit, mod_records);
+	gnome_pilot_conduit_sync_abs_set_num_deleted_local_records(abs_conduit, del_records);
+	
+	g_message("num_records: %d\nadd_records: %d\nmod_records: %d\ndel_records: %d\n",
+		num_records, add_records, mod_records, del_records);
+
+	buf = (unsigned char*)g_malloc (0xffff);
+	len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0,
+			      (unsigned char *)buf, 0xffff);
+	
+	if (len < 0) {
+		WARN (_("Could not read pilot's Memo application block"));
+		WARN ("dlp_ReadAppBlock(...) = %d", len);
+		gnome_pilot_conduit_error (conduit,
+					   _("Could not read pilot's Memo application block"));
+		return -1;
+	}
+	unpack_MemoAppInfo (&(ctxt->ai), buf, len);
+	g_free (buf);
+	
+	lastDesktopUniqueID = 128;
+
+	check_for_slow_setting (conduit, ctxt);
+	if (ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyToPilot
+	    || ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyFromPilot)
+		ctxt->map->write_touched_only = TRUE;
+	
+	return 0;
+}
+
+static gint
+post_sync (GnomePilotConduit *conduit,
+	   GnomePilotDBInfo *dbi,
+	   EMemoConduitContext *ctxt)
+{
+	GList *changed;
+	gchar *filename, *change_id;
+	unsigned char *buf;
+	int dlpRetVal, len;
+
+	buf = (unsigned char*)g_malloc (0xffff);
+	
+	len = pack_MemoAppInfo (&(ctxt->ai), buf, 0xffff);
+	
+	dlpRetVal = dlp_WriteAppBlock (dbi->pilot_socket, dbi->db_handle, 
+			      (unsigned char *)buf, len);
+	
+	g_free (buf);
+			      
+	if (dlpRetVal < 0) {
+		WARN (_("Could not write pilot's Memo application block"));
+		WARN ("dlp_WriteAppBlock(...) = %d", dlpRetVal);
+		gnome_pilot_conduit_error (conduit,
+					   _("Could not write pilot's Memo application block"));
+		return -1;
+	}
+	
+
+	LOG (g_message ( "post_sync: Memo Conduit v.%s", CONDUIT_VERSION ));
+
+	g_free (ctxt->cfg->last_uri);
+	ctxt->cfg->last_uri = g_strdup (e_cal_get_uri (ctxt->client));
+	memoconduit_save_configuration (ctxt->cfg);
+	
+	filename = map_name (ctxt);
+	e_pilot_map_write (filename, ctxt->map);
+	g_free (filename);
+
+	/* FIX ME ugly hack - our changes musn't count, this does introduce
+	 * a race condition if anyone changes a record elsewhere during sycnc
+         */
+	change_id = g_strdup_printf ("pilot-sync-evolution-memo-%d", ctxt->cfg->pilot_id);
+	if (e_cal_get_changes (ctxt->client, change_id, &changed, NULL))
+		e_cal_free_change_list (changed);
+	g_free (change_id);
+	
+	LOG (g_message ( "---------------------------------------------------------\n" ));
+
+	return 0;
+}
+
+static gint
+set_pilot_id (GnomePilotConduitSyncAbs *conduit,
+	      EMemoLocalRecord *local,
+	      guint32 ID,
+	      EMemoConduitContext *ctxt)
+{
+	const char *uid;
+
+	LOG (g_message ( "set_pilot_id: setting to %d\n", ID ));
+	
+	e_cal_component_get_uid (local->comp, &uid);
+	e_pilot_map_insert (ctxt->map, ID, uid, FALSE);
+
+        return 0;
+}
+
+static gint
+set_status_cleared (GnomePilotConduitSyncAbs *conduit,
+		    EMemoLocalRecord *local,
+		    EMemoConduitContext *ctxt)
+{
+	const char *uid;
+	
+	LOG (g_message ( "set_status_cleared: clearing status\n" ));
+	
+	e_cal_component_get_uid (local->comp, &uid);
+	g_hash_table_remove (ctxt->changed_hash, uid);
+	
+        return 0;
+}
+
+static gint
+for_each (GnomePilotConduitSyncAbs *conduit,
+	  EMemoLocalRecord **local,
+	  EMemoConduitContext *ctxt)
+{
+	static GList *comps, *iterator;
+	static int count;
+
+	g_return_val_if_fail (local != NULL, -1);
+
+	if (*local == NULL) {
+		LOG (g_message ( "beginning for_each" ));
+
+		comps = ctxt->comps;
+		count = 0;
+		
+		if (comps != NULL) {
+			LOG (g_message ( "for_each: iterating over %d records", g_list_length (comps)));
+
+			*local = g_new0 (EMemoLocalRecord, 1);
+			LOG(fprintf(stderr, "for_each: calling local_record_from_comp\n"));
+			local_record_from_comp (*local, comps->data, ctxt);
+			LOG(fprintf(stderr, "for_each: calling g_list_prepend\n"));
+			g_list_prepend (ctxt->locals, *local);
+			LOG(fprintf(stderr, "for_each: setting iterator = comps\n"));
+			iterator = comps;
+		} else {
+			LOG (g_message ( "no events" ));
+			(*local) = NULL;
+			return 0;
+		}
+	} else {
+		count++;
+		LOG(fprintf(stderr, "for_each: calling g_list_next (else part)\n"));
+		if (g_list_next (iterator)) {
+			iterator = g_list_next (iterator);
+			LOG(fprintf(stderr, "for_each: creating EMemoLocalRecord\n"));
+			*local = g_new0 (EMemoLocalRecord, 1);
+			LOG(fprintf(stderr, "for_each: calling local_record_from_comp\n"));
+			local_record_from_comp (*local, iterator->data, ctxt);
+			LOG(fprintf(stderr, "for_each: calling g_list_prepend\n"));
+			g_list_prepend (ctxt->locals, *local);
+		} else {
+			LOG (g_message ( "for_each ending" ));
+
+			/* Tell the pilot the iteration is over */
+			*local = NULL;
+
+			return 0;
+		}
+	}
+
+	return 0;
+}
+
+static gint
+for_each_modified (GnomePilotConduitSyncAbs *conduit,
+		   EMemoLocalRecord **local,
+		   EMemoConduitContext *ctxt)
+{
+	static GList *iterator;
+	static int count;
+
+	g_return_val_if_fail (local != NULL, 0);
+
+	if (*local == NULL) {
+		LOG (g_message ( "for_each_modified beginning\n" ));
+		
+		iterator = ctxt->changed;
+		
+		count = 0;
+	
+		LOG (g_message ( "iterating over %d records", g_hash_table_size (ctxt->changed_hash) ));
+		
+		iterator = next_changed_item (ctxt, iterator);
+		if (iterator != NULL) {
+			ECalChange *ccc = iterator->data;
+			LOG(fprintf(stderr, "for_each_modified: creating EMemoLocalRecord\n"));
+			*local = g_new0 (EMemoLocalRecord, 1);
+			LOG(fprintf(stderr, "for_each_modified: calling local_record_from_comp\n"));
+			local_record_from_comp (*local, ccc->comp, ctxt);
+			LOG(fprintf(stderr, "for_each_modified: calling g_list_prepend\n"));
+			g_list_prepend (ctxt->locals, *local);
+		} else {
+			LOG (g_message ( "no events" ));
+
+			*local = NULL;
+		}
+	} else {
+		count++;
+		LOG(fprintf(stderr, "for_each_modified: calling g_list_next\n"));
+		iterator = g_list_next (iterator);
+		LOG(fprintf(stderr, "for_each_modified: calling next_changed_item\n"));
+		if (iterator && (iterator = next_changed_item (ctxt, iterator))) {
+			ECalChange *ccc = iterator->data;
+			LOG(fprintf(stderr, "for_each_modified: calling EMemoLocalRecord\n"));
+			*local = g_new0 (EMemoLocalRecord, 1);
+			LOG(fprintf(stderr, "for_each_modified: calling local_record_from_comp\n"));
+			local_record_from_comp (*local, ccc->comp, ctxt);
+			LOG(fprintf(stderr, "for_each_modified: calling g_list_prepend\n"));
+			g_list_prepend (ctxt->locals, *local);
+		} else {
+			LOG (g_message ( "for_each_modified ending" ));
+
+			/* Signal the iteration is over */
+			*local = NULL;
+		}
+	}
+
+	return 0;
+}
+
+static gint
+compare (GnomePilotConduitSyncAbs *conduit,
+	 EMemoLocalRecord *local,
+	 GnomePilotRecord *remote,
+	 EMemoConduitContext *ctxt)
+{
+	/* used by the quick compare */
+	GnomePilotRecord local_pilot;
+	int retval = 0;
+
+	LOG (g_message ("compare: local=%s remote=%s...\n",
+			print_local (local), print_remote (remote)));
+
+	g_return_val_if_fail (local!=NULL,-1);
+	g_return_val_if_fail (remote!=NULL,-1);
+
+	local_pilot = local_record_to_pilot_record (local, ctxt);
+
+	if (remote->length != local_pilot.length
+	    || memcmp (local_pilot.record, remote->record, remote->length))
+		retval = 1;
+
+	if (retval == 0)
+		LOG (g_message ( "    equal" ));
+	else
+		LOG (g_message ( "    not equal" ));
+	
+	return retval;
+}
+
+static gint
+add_record (GnomePilotConduitSyncAbs *conduit,
+	    GnomePilotRecord *remote,
+	    EMemoConduitContext *ctxt)
+{
+	ECalComponent *comp;
+	char *uid;
+	int retval = 0;
+	
+	g_return_val_if_fail (remote != NULL, -1);
+
+	LOG (g_message ( "add_record: adding %s to desktop\n", print_remote (remote) ));
+
+	comp = comp_from_remote_record (conduit, remote, ctxt->default_comp, ctxt->timezone, &(ctxt->ai));
+
+	/* Give it a new UID otherwise it will be the uid of the default comp */
+	uid = e_cal_component_gen_uid ();
+	e_cal_component_set_uid (comp, uid);
+
+	if (!e_cal_create_object (ctxt->client, e_cal_component_get_icalcomponent (comp), NULL, NULL))
+		return -1;
+
+	e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE);
+
+	g_object_unref (comp);
+
+	return retval;
+}
+
+static gint
+replace_record (GnomePilotConduitSyncAbs *conduit,
+		EMemoLocalRecord *local,
+		GnomePilotRecord *remote,
+		EMemoConduitContext *ctxt)
+{
+	ECalComponent *new_comp;
+	int retval = 0;
+	
+	g_return_val_if_fail (remote != NULL, -1);
+
+	LOG (g_message ("replace_record: replace %s with %s\n",
+			print_local (local), print_remote (remote)));
+
+	new_comp = comp_from_remote_record (conduit, remote, local->comp, ctxt->timezone, &(ctxt->ai));
+	g_object_unref (local->comp);
+	local->comp = new_comp;
+
+	if (!e_cal_modify_object (ctxt->client, e_cal_component_get_icalcomponent (new_comp), 
+				       CALOBJ_MOD_ALL, NULL))
+		return -1;
+
+	return retval;
+}
+
+static gint
+delete_record (GnomePilotConduitSyncAbs *conduit,
+	       EMemoLocalRecord *local,
+	       EMemoConduitContext *ctxt)
+{
+	const char *uid;
+
+	g_return_val_if_fail (local != NULL, -1);
+	g_return_val_if_fail (local->comp != NULL, -1);
+
+	e_cal_component_get_uid (local->comp, &uid);
+
+	LOG (g_message ( "delete_record: deleting %s", uid ));
+
+	e_pilot_map_remove_by_uid (ctxt->map, uid);
+	/* FIXME Error handling */
+	e_cal_remove_object (ctxt->client, uid, NULL);
+	
+        return 0;
+}
+
+static gint
+archive_record (GnomePilotConduitSyncAbs *conduit,
+		EMemoLocalRecord *local,
+		gboolean archive,
+		EMemoConduitContext *ctxt)
+{
+	const char *uid;
+	int retval = 0;
+	
+	g_return_val_if_fail (local != NULL, -1);
+
+	LOG (g_message ( "archive_record: %s\n", archive ? "yes" : "no" ));
+
+	e_cal_component_get_uid (local->comp, &uid);
+	e_pilot_map_insert (ctxt->map, local->local.ID, uid, archive);
+	
+        return retval;
+}
+
+static gint
+match (GnomePilotConduitSyncAbs *conduit,
+       GnomePilotRecord *remote,
+       EMemoLocalRecord **local,
+       EMemoConduitContext *ctxt)
+{
+	const char *uid;
+	
+	LOG (g_message ("match: looking for local copy of %s\n",
+			print_remote (remote)));	
+	
+	g_return_val_if_fail (local != NULL, -1);
+	g_return_val_if_fail (remote != NULL, -1);
+
+	*local = NULL;
+	uid = e_pilot_map_lookup_uid (ctxt->map, remote->ID, TRUE);
+	
+	if (!uid)
+		return 0;
+
+	LOG (g_message ( "  matched\n" ));
+	
+	*local = g_new0 (EMemoLocalRecord, 1);
+	local_record_from_uid (*local, uid, ctxt);
+	
+	return 0;
+}
+
+static gint
+free_match (GnomePilotConduitSyncAbs *conduit,
+	    EMemoLocalRecord *local,
+	    EMemoConduitContext *ctxt)
+{
+	LOG (g_message ( "free_match: freeing\n" ));
+
+	g_return_val_if_fail (local != NULL, -1);
+
+	memoconduit_destroy_record (local);
+
+	return 0;
+}
+
+static gint
+prepare (GnomePilotConduitSyncAbs *conduit,
+	 EMemoLocalRecord *local,
+	 GnomePilotRecord *remote,
+	 EMemoConduitContext *ctxt)
+{
+	LOG (g_message ( "prepare: encoding local %s\n", print_local (local) ));
+
+	*remote = local_record_to_pilot_record (local, ctxt);
+
+	return 0;
+}
+
+/* Pilot Settings Callbacks */
+static void
+fill_widgets (EMemoConduitContext *ctxt)
+{
+	if (ctxt->cfg->source)
+		e_pilot_settings_set_source (E_PILOT_SETTINGS (ctxt->ps), 
+					     ctxt->cfg->source);
+	e_pilot_settings_set_secret (E_PILOT_SETTINGS (ctxt->ps),
+				     ctxt->cfg->secret);
+}
+
+static gint
+create_settings_window (GnomePilotConduit *conduit,
+			GtkWidget *parent,
+			EMemoConduitContext *ctxt)
+{
+	LOG (g_message ( "create_settings_window" ));
+	
+	if (!ctxt->cfg->source_list)	
+		return -1;
+
+	ctxt->ps = e_pilot_settings_new (ctxt->cfg->source_list);
+
+	gtk_container_add (GTK_CONTAINER (parent), ctxt->ps);
+	gtk_widget_show (ctxt->ps);
+
+	fill_widgets (ctxt);
+	
+	return 0;
+}
+
+static void
+display_settings (GnomePilotConduit *conduit, EMemoConduitContext *ctxt)
+{
+	LOG (g_message ( "display_settings" ));
+	
+	fill_widgets (ctxt);
+}
+
+static void
+save_settings    (GnomePilotConduit *conduit, EMemoConduitContext *ctxt)
+{
+	LOG (g_message ( "save_settings" ));
+
+	if (ctxt->new_cfg->source)
+		g_object_unref (ctxt->new_cfg->source);
+	ctxt->new_cfg->source = e_pilot_settings_get_source (E_PILOT_SETTINGS (ctxt->ps));
+	g_object_ref (ctxt->new_cfg->source);
+	ctxt->new_cfg->secret = e_pilot_settings_get_secret (E_PILOT_SETTINGS (ctxt->ps));
+	
+	memoconduit_save_configuration (ctxt->new_cfg);
+}
+
+static void
+revert_settings  (GnomePilotConduit *conduit, EMemoConduitContext *ctxt)
+{
+	LOG (g_message ( "revert_settings" ));
+
+	memoconduit_save_configuration (ctxt->cfg);
+	memoconduit_destroy_configuration (ctxt->new_cfg);
+	ctxt->new_cfg = memoconduit_dupe_configuration (ctxt->cfg);
+}
+
+GnomePilotConduit *
+conduit_get_gpilot_conduit (guint32 pilot_id)
+{
+	GtkObject *retval;
+	EMemoConduitContext *ctxt;
+
+	LOG (g_message ( "in memo's conduit_get_gpilot_conduit\n" ));
+
+	retval = gnome_pilot_conduit_sync_abs_new ("MemoDB", 0x6D656D6F);
+	g_assert (retval != NULL);
+	
+	ctxt = e_memo_context_new (pilot_id);
+	gtk_object_set_data (GTK_OBJECT (retval), "memoconduit_context", ctxt);
+
+	gtk_signal_connect (retval, "pre_sync", (GtkSignalFunc) pre_sync, ctxt);
+	gtk_signal_connect (retval, "post_sync", (GtkSignalFunc) post_sync, ctxt);
+
+  	gtk_signal_connect (retval, "set_pilot_id", (GtkSignalFunc) set_pilot_id, ctxt);
+  	gtk_signal_connect (retval, "set_status_cleared", (GtkSignalFunc) set_status_cleared, ctxt);
+
+  	gtk_signal_connect (retval, "for_each", (GtkSignalFunc) for_each, ctxt);
+  	gtk_signal_connect (retval, "for_each_modified", (GtkSignalFunc) for_each_modified, ctxt);
+  	gtk_signal_connect (retval, "compare", (GtkSignalFunc) compare, ctxt);
+
+  	gtk_signal_connect (retval, "add_record", (GtkSignalFunc) add_record, ctxt);
+  	gtk_signal_connect (retval, "replace_record", (GtkSignalFunc) replace_record, ctxt);
+  	gtk_signal_connect (retval, "delete_record", (GtkSignalFunc) delete_record, ctxt);
+  	gtk_signal_connect (retval, "archive_record", (GtkSignalFunc) archive_record, ctxt);
+
+  	gtk_signal_connect (retval, "match", (GtkSignalFunc) match, ctxt);
+  	gtk_signal_connect (retval, "free_match", (GtkSignalFunc) free_match, ctxt);
+
+  	gtk_signal_connect (retval, "prepare", (GtkSignalFunc) prepare, ctxt);
+
+	/* Gui Settings */
+	gtk_signal_connect (retval, "create_settings_window", (GtkSignalFunc) create_settings_window, ctxt);
+	gtk_signal_connect (retval, "display_settings", (GtkSignalFunc) display_settings, ctxt);
+	gtk_signal_connect (retval, "save_settings", (GtkSignalFunc) save_settings, ctxt);
+	gtk_signal_connect (retval, "revert_settings", (GtkSignalFunc) revert_settings, ctxt);
+
+	return GNOME_PILOT_CONDUIT (retval);
+}
+
+void
+conduit_destroy_gpilot_conduit (GnomePilotConduit *conduit)
+{ 
+	GtkObject *obj = GTK_OBJECT (conduit);
+	EMemoConduitContext *ctxt;
+	
+	ctxt = gtk_object_get_data (obj, "memoconduit_context");
+	e_memo_context_destroy (ctxt);
+
+	gtk_object_destroy (obj);
+}
Index: calendar/gui/e-cal-component-memo-preview.c
===================================================================
RCS file: calendar/gui/e-cal-component-memo-preview.c
diff -N calendar/gui/e-cal-component-memo-preview.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-cal-component-memo-preview.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,374 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-tasks.c
+ *
+ * Copyright (C) 2001-2003  Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Federico Mena Quintero <federico@ximian.com>
+ *	    Damon Chaplin <damon@ximian.com>
+ *          Rodrigo Moya <rodrigo@ximian.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gnome.h>
+#include <gtk/gtk.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <libecal/e-cal-time-util.h>
+#include <libedataserver/e-categories.h>
+#include <gtkhtml/gtkhtml.h>
+#include <gtkhtml/gtkhtml-stream.h>
+#include <e-util/e-time-utils.h>
+#include <e-util/e-categories-config.h>
+#include "calendar-config.h"
+#include "e-cal-component-memo-preview.h"
+
+struct _ECalComponentMemoPreviewPrivate {
+	GtkWidget *html;
+
+	icaltimezone *zone;
+};
+
+G_DEFINE_TYPE (ECalComponentMemoPreview, e_cal_component_memo_preview, GTK_TYPE_TABLE);
+
+
+static void
+on_link_clicked (GtkHTML *html, const char *url, gpointer data)
+{
+        GError *err = NULL;
+
+        gnome_url_show (url, &err);
+
+	if (err) {
+		g_warning ("gnome_url_show: %s", err->message);
+                g_error_free (err);
+        }
+}
+
+static void
+on_url_cb (GtkHTML *html, const char *url, gpointer data)
+{
+#if 0
+	char *msg;
+	ECalComponentMemoPreview *preview = data;
+
+	if (url && *url) {
+		msg = g_strdup_printf (_("Click to open %s"), url);
+		e_calendar_table_set_status_message (e_tasks_get_calendar_table (tasks), msg);
+		g_free (msg);
+	} else
+		e_calendar_table_set_status_message (e_tasks_get_calendar_table (tasks), NULL);
+#endif
+}
+
+/* Callback used when the user selects a URL in the HTML widget */
+static void
+url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointer data)
+{
+	if (!strncmp ("file:///", url, strlen ("file:///"))) {
+		GnomeVFSHandle *handle;
+		GnomeVFSResult result;
+		char buffer[4096];
+
+		if (gnome_vfs_open (&handle, url, GNOME_VFS_OPEN_READ) == GNOME_VFS_OK) {
+			do {
+				GnomeVFSFileSize bread;
+
+				result = gnome_vfs_read (handle, buffer, sizeof (buffer), &bread);
+				if (result == GNOME_VFS_OK)
+					gtk_html_stream_write (stream, buffer, bread);
+			} while (result == GNOME_VFS_OK);
+
+			gnome_vfs_close (handle);
+		}
+	}
+}
+
+/* Converts a time_t to a string, relative to the specified timezone */
+static char *
+timet_to_str_with_zone (ECalComponentDateTime *dt, ECal *ecal, icaltimezone *default_zone)
+{
+	struct icaltimetype itt;
+	icaltimezone *zone;
+        struct tm tm;
+        char buf[256];                                                                                              
+
+	if (dt->tzid) {
+		/* If we can't find the zone, we'll guess its "local" */
+		if (!e_cal_get_timezone (ecal, dt->tzid, &zone, NULL))
+			zone = NULL;
+	} else if (dt->value->is_utc) {
+		zone = icaltimezone_get_utc_timezone ();
+	} else {
+		zone = NULL;
+	}
+	
+	
+	itt = *dt->value;
+	if (zone)
+		icaltimezone_convert_time (&itt, zone, default_zone);
+        tm = icaltimetype_to_tm (&itt);
+                                                                                              
+        e_time_format_date_and_time (&tm, calendar_config_get_24_hour_format (),
+                                     FALSE, FALSE, buf, sizeof (buf));
+
+	return g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
+}
+
+static void
+write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone *default_zone)
+{
+	ECalComponentText text;
+	ECalComponentDateTime dt;
+	gchar *str;
+	GSList *l;
+	icalproperty_status status;
+	const char *location;
+	int *priority_value;
+	gboolean one_added = FALSE;
+
+	g_return_if_fail (E_IS_CAL_COMPONENT (comp));
+
+	gtk_html_stream_printf (stream,
+				"<HTML><BODY>");
+
+	/* write icons for the categories */
+	e_cal_component_get_categories_list (comp, &l);
+	if (l) {
+		GSList *node;
+		GString *str = g_string_new ("");
+		
+		
+		gtk_html_stream_printf(stream, "<H3>Categories: ");
+
+		for (node = l; node != NULL; node = node->next) {
+			const char *icon_file;
+
+			icon_file = e_categories_get_icon_file_for ((const char *) node->data);
+			if (icon_file && g_file_test(icon_file, G_FILE_TEST_EXISTS)) {
+				gtk_html_stream_printf (stream, "<IMG ALT=\"%s\" SRC=\"file://%s\">",
+							(const char *) node->data, icon_file);
+				one_added = TRUE;
+			}
+			else{
+				if(one_added == FALSE){
+					g_string_append_printf (str, "%s", (const char *) node->data);
+					one_added = TRUE;
+				}
+				else{
+					g_string_append_printf (str, ", %s", (const char *) node->data);
+				}
+			}
+		}
+		
+		gtk_html_stream_printf(stream, str->str);
+		
+		gtk_html_stream_printf(stream, "</H3>");
+
+		e_cal_component_free_categories_list (l);
+	}
+
+	/* Start table */
+	gtk_html_stream_printf (stream, "<TABLE BORDER=\"0\" WIDTH=\"80%%\">"
+				"<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"15%%\"></TD></TR>");	
+
+
+	/* write description and URL */
+	gtk_html_stream_printf (stream, "<TR><TD COLSPAN=\"2\"><HR></TD></TR>");
+
+	e_cal_component_get_description_list (comp, &l);
+	if (l) {
+		GSList *node;
+
+		gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Memo:"));
+
+		gtk_html_stream_printf (stream, "<TD>");
+
+		for (node = l; node != NULL; node = node->next) {
+			gint i, j;
+			GString *str = g_string_new ("");
+
+			text = * (ECalComponentText *) node->data;
+			for (i = 0, j=0; i < strlen (text.value ? text.value : 0); i++, j++) {
+				if (text.value[i] == '\n'){
+					str = g_string_append (str, "<BR>");
+				}
+				else if (text.value[i] == '<')
+					str = g_string_append (str, "&lt;");
+				else if (text.value[i] == '>')
+					str = g_string_append (str, "&gt;");
+				else
+					str = g_string_append_c (str, text.value[i]);
+			}
+
+			gtk_html_stream_printf (stream, str->str);
+			g_string_free (str, TRUE);
+		}
+
+		gtk_html_stream_printf (stream, "</TD></TR>");
+
+		e_cal_component_free_text_list (l);
+	}
+
+	/* URL */
+	e_cal_component_get_url (comp, (const char **) &str);
+	if (str) {
+		gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Web Page:"));
+		gtk_html_stream_printf (stream, "<TD><A HREF=\"%s\">%s</A></TD></TR>", str, str);
+	}
+	
+	gtk_html_stream_printf (stream, "</TABLE>");
+
+	/* close document */
+	gtk_html_stream_printf (stream, "</BODY></HTML>");
+}
+
+static void
+e_cal_component_memo_preview_init (ECalComponentMemoPreview *preview)
+{
+	ECalComponentMemoPreviewPrivate *priv;
+	GtkWidget *scroll;
+	
+	priv = g_new0 (ECalComponentMemoPreviewPrivate, 1);
+	preview->priv = priv;
+
+	priv->html = gtk_html_new ();
+	gtk_html_set_default_content_type (GTK_HTML (priv->html), "charset=utf-8");
+	gtk_html_load_empty (GTK_HTML (priv->html));
+
+	g_signal_connect (G_OBJECT (priv->html), "url_requested",
+			  G_CALLBACK (url_requested_cb), NULL);
+	g_signal_connect (G_OBJECT (priv->html), "link_clicked",
+			  G_CALLBACK (on_link_clicked), preview);
+	g_signal_connect (G_OBJECT (priv->html), "on_url",
+			  G_CALLBACK (on_url_cb), preview);
+
+	scroll = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+					GTK_POLICY_AUTOMATIC,
+					GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
+
+	gtk_container_add (GTK_CONTAINER (scroll), priv->html);
+	gtk_container_add (GTK_CONTAINER (preview), scroll);
+	gtk_widget_show_all (scroll);
+	
+	priv->zone = icaltimezone_get_utc_timezone ();
+}
+
+static void
+e_cal_component_memo_preview_destroy (GtkObject *object)
+{
+	ECalComponentMemoPreview *preview;
+	ECalComponentMemoPreviewPrivate *priv;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (object));
+
+	preview = E_CAL_COMPONENT_MEMO_PREVIEW (object);
+	priv = preview->priv;
+
+	if (priv) {
+
+		g_free (priv);
+		preview->priv = NULL;
+	}
+
+	if (GTK_OBJECT_CLASS (e_cal_component_memo_preview_parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (e_cal_component_memo_preview_parent_class)->destroy) (object);
+}
+
+static void
+e_cal_component_memo_preview_class_init (ECalComponentMemoPreviewClass *klass)
+{
+	GtkObjectClass *object_class;
+	
+	object_class = (GtkObjectClass *) klass;
+	
+	object_class->destroy = e_cal_component_memo_preview_destroy;
+}
+
+GtkWidget *
+e_cal_component_memo_preview_new (void)
+{
+	ECalComponentMemoPreview *preview;
+
+	preview = g_object_new (e_cal_component_memo_preview_get_type (), NULL);
+
+	return GTK_WIDGET (preview);
+}
+
+icaltimezone *
+e_cal_component_memo_preview_get_default_timezone (ECalComponentMemoPreview *preview)
+{
+	ECalComponentMemoPreviewPrivate *priv;
+	
+	g_return_val_if_fail (preview != NULL, NULL);
+	g_return_val_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview), NULL);
+
+	priv = preview->priv;
+
+	return priv->zone;
+}
+
+void
+e_cal_component_memo_preview_set_default_timezone (ECalComponentMemoPreview *preview, icaltimezone *zone)
+{
+	ECalComponentMemoPreviewPrivate *priv;
+	
+	g_return_if_fail (preview != NULL);
+	g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview));
+	g_return_if_fail (zone != NULL);
+
+	priv = preview->priv;
+	
+	priv->zone = zone;
+}
+
+void
+e_cal_component_memo_preview_display (ECalComponentMemoPreview *preview, ECal *ecal, ECalComponent *comp)
+{
+	ECalComponentMemoPreviewPrivate *priv;
+	GtkHTMLStream *stream;
+
+	g_return_if_fail (preview != NULL);
+	g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview));
+	g_return_if_fail (comp != NULL);
+	g_return_if_fail (E_IS_CAL_COMPONENT (comp));
+
+	priv = preview->priv;
+	
+	stream = gtk_html_begin (GTK_HTML (priv->html));
+	write_html (stream, ecal, comp, priv->zone);
+	gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
+}
+
+void
+e_cal_component_memo_preview_clear (ECalComponentMemoPreview *preview)
+{
+	ECalComponentMemoPreviewPrivate *priv;
+
+	g_return_if_fail (preview != NULL);
+	g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview));
+	
+	priv = preview->priv;
+	
+	gtk_html_load_empty (GTK_HTML (priv->html));
+}
+
Index: calendar/gui/e-cal-component-memo-preview.h
===================================================================
RCS file: calendar/gui/e-cal-component-memo-preview.h
diff -N calendar/gui/e-cal-component-memo-preview.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-cal-component-memo-preview.h	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,66 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-cal-component-memo-preview.h
+ *
+ * Copyright (C) 2004  Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Federico Mena Quintero <federico@ximian.com>
+ *	    Damon Chaplin <damon@ximian.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ */
+
+#ifndef _E_CAL_COMPONENT_MEMO_PREVIEW_H_
+#define _E_CAL_COMPONENT_MEMO_PREVIEW_H_
+
+#include <gtk/gtktable.h>
+#include <libecal/e-cal.h>
+
+#define E_TYPE_CAL_COMPONENT_MEMO_PREVIEW            (e_cal_component_memo_preview_get_type ())
+#define E_CAL_COMPONENT_MEMO_PREVIEW(obj)            (GTK_CHECK_CAST ((obj), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW, ECalComponentMemoPreview))
+#define E_CAL_COMPONENT_MEMO_PREVIEW_CLASS(klass)    (GTK_CHECK_CAST_CLASS ((klass), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW, \
+				                 ECalComponentMemoPreviewClass))
+#define E_IS_CAL_COMPONENT_MEMO_PREVIEW(obj)         (GTK_CHECK_TYPE ((obj), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW))
+#define E_IS_CAL_COMPONENT_MEMO_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW))
+
+typedef struct _ECalComponentMemoPreview	ECalComponentMemoPreview;
+typedef struct _ECalComponentMemoPreviewClass	ECalComponentMemoPreviewClass;
+typedef struct _ECalComponentMemoPreviewPrivate	ECalComponentMemoPreviewPrivate;
+
+struct _ECalComponentMemoPreview {
+	GtkTable table;
+
+	/* Private data */
+	ECalComponentMemoPreviewPrivate *priv;
+};
+
+struct _ECalComponentMemoPreviewClass {
+	GtkTableClass parent_class;
+
+	/* Notification signals */
+	void (* selection_changed) (ECalComponentMemoPreview *preview, int n_selected);
+};
+
+
+GtkType    e_cal_component_memo_preview_get_type        (void);
+GtkWidget *e_cal_component_memo_preview_new             (void);
+
+icaltimezone *e_cal_component_memo_preview_get_default_timezone (ECalComponentMemoPreview *preview);
+void e_cal_component_memo_preview_set_default_timezone (ECalComponentMemoPreview *preview, icaltimezone *zone);
+
+void e_cal_component_memo_preview_display             (ECalComponentMemoPreview *preview, ECal *ecal, ECalComponent *comp);
+void e_cal_component_memo_preview_clear             (ECalComponentMemoPreview *preview);
+
+#endif /* _E_CAL_COMPONENT_MEMO_PREVIEW_H_ */
Index: calendar/gui/e-cal-model-memos.c
===================================================================
RCS file: calendar/gui/e-cal-model-memos.c
diff -N calendar/gui/e-cal-model-memos.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-cal-model-memos.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,259 @@
+/* Evolution memos - Data model for ETable
+ *
+ * Copyright (C) 2000 Ximian, Inc.
+ * Copyright (C) 2000 Ximian, Inc.
+ *
+ * Authors: Rodrigo Moya <rodrigo@ximian.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <libgnome/gnome-i18n.h>
+#include "e-cal-model-memos.h"
+#include "e-cell-date-edit-text.h"
+#include "misc.h"
+
+#define d(x) (x)
+
+struct _ECalModelMemosPrivate {
+};
+
+static void e_cal_model_memos_finalize (GObject *object);
+
+static int ecmm_column_count (ETableModel *etm);
+static void *ecmm_value_at (ETableModel *etm, int col, int row);
+static void ecmm_set_value_at (ETableModel *etm, int col, int row, const void *value);
+static gboolean ecmm_is_cell_editable (ETableModel *etm, int col, int row);
+static void *ecmm_duplicate_value (ETableModel *etm, int col, const void *value);
+static void ecmm_free_value (ETableModel *etm, int col, void *value);
+static void *ecmm_initialize_value (ETableModel *etm, int col);
+static gboolean ecmm_value_is_empty (ETableModel *etm, int col, const void *value);
+static char *ecmm_value_to_string (ETableModel *etm, int col, const void *value);
+
+static void ecmm_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data,
+					    ETableModel *source_model, gint row);
+
+G_DEFINE_TYPE (ECalModelMemos, e_cal_model_memos, E_TYPE_CAL_MODEL);
+
+static void
+e_cal_model_memos_class_init (ECalModelMemosClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	ETableModelClass *etm_class = E_TABLE_MODEL_CLASS (klass);
+	ECalModelClass *model_class = E_CAL_MODEL_CLASS (klass);
+
+	object_class->finalize = e_cal_model_memos_finalize;
+
+	etm_class->column_count = ecmm_column_count;
+	etm_class->value_at = ecmm_value_at;
+	etm_class->set_value_at = ecmm_set_value_at;
+	etm_class->is_cell_editable = ecmm_is_cell_editable;
+	etm_class->duplicate_value = ecmm_duplicate_value;
+	etm_class->free_value = ecmm_free_value;
+	etm_class->initialize_value = ecmm_initialize_value;
+	etm_class->value_is_empty = ecmm_value_is_empty;
+	etm_class->value_to_string = ecmm_value_to_string;
+
+	model_class->fill_component_from_model = ecmm_fill_component_from_model;
+}
+
+static void
+e_cal_model_memos_init (ECalModelMemos *model)
+{
+	ECalModelMemosPrivate *priv;
+
+	priv = g_new0 (ECalModelMemosPrivate, 1);
+	model->priv = priv;
+
+	e_cal_model_set_component_kind (E_CAL_MODEL (model), ICAL_VJOURNAL_COMPONENT);
+}
+
+static void
+e_cal_model_memos_finalize (GObject *object)
+{
+	ECalModelMemosPrivate *priv;
+	ECalModelMemos *model = (ECalModelMemos *) object;
+
+	g_return_if_fail (E_IS_CAL_MODEL_MEMOS (model));
+
+	priv = model->priv;
+	if (priv) {
+		g_free (priv);
+		model->priv = NULL;
+	}
+
+	if (G_OBJECT_CLASS (e_cal_model_memos_parent_class)->finalize)
+		G_OBJECT_CLASS (e_cal_model_memos_parent_class)->finalize (object);
+}
+
+/* ETableModel methods */
+static int
+ecmm_column_count (ETableModel *etm)
+{
+	return E_CAL_MODEL_MEMOS_FIELD_LAST;
+}
+
+static void *
+ecmm_value_at (ETableModel *etm, int col, int row)
+{
+	ECalModelComponent *comp_data;
+	ECalModelMemosPrivate *priv;
+	ECalModelMemos *model = (ECalModelMemos *) etm;
+
+	g_return_val_if_fail (E_IS_CAL_MODEL_MEMOS (model), NULL);
+
+	priv = model->priv;
+
+	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_MEMOS_FIELD_LAST, NULL);
+	g_return_val_if_fail (row >= 0 && row < e_table_model_row_count (etm), NULL);
+
+	if (col < E_CAL_MODEL_FIELD_LAST)
+		return E_TABLE_MODEL_CLASS (e_cal_model_memos_parent_class)->value_at (etm, col, row);
+
+	comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
+	if (!comp_data)
+		return "";
+
+	return "";
+}
+
+
+static void
+ecmm_set_value_at (ETableModel *etm, int col, int row, const void *value)
+{
+	ECalModelComponent *comp_data;
+	ECalModelMemos *model = (ECalModelMemos *) etm;
+
+	g_return_if_fail (E_IS_CAL_MODEL_MEMOS (model));
+	g_return_if_fail (col >= 0 && col < E_CAL_MODEL_MEMOS_FIELD_LAST);
+	g_return_if_fail (row >= 0 && row < e_table_model_row_count (etm));
+
+	if (col < E_CAL_MODEL_FIELD_LAST) {
+		E_TABLE_MODEL_CLASS (e_cal_model_memos_parent_class)->set_value_at (etm, col, row, value);
+		return;
+	}
+
+	comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
+	if (!comp_data){
+		g_warning("couldn't get component data: row == %d", row);
+		return;
+	}
+
+	/* TODO ask about mod type */
+	if (!e_cal_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) {
+		g_warning (G_STRLOC ": Could not modify the object!");
+		
+		/* TODO Show error dialog */
+	}
+}
+
+static gboolean
+ecmm_is_cell_editable (ETableModel *etm, int col, int row)
+{
+	ECalModelMemos *model = (ECalModelMemos *) etm;
+	gboolean retval = FALSE;
+
+	g_return_val_if_fail (E_IS_CAL_MODEL_MEMOS (model), FALSE);
+	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_MEMOS_FIELD_LAST, FALSE);
+	g_return_val_if_fail (row >= -1 || (row >= 0 && row < e_table_model_row_count (etm)), FALSE);
+
+	if(col == E_CAL_MODEL_FIELD_SUMMARY)
+		retval = FALSE;
+	else if (col < E_CAL_MODEL_FIELD_LAST)
+		retval = E_TABLE_MODEL_CLASS (e_cal_model_memos_parent_class)->is_cell_editable (etm, col, row);
+
+	return retval;
+}
+
+static void *
+ecmm_duplicate_value (ETableModel *etm, int col, const void *value)
+{
+	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_MEMOS_FIELD_LAST, NULL);
+
+	if (col < E_CAL_MODEL_FIELD_LAST)
+		return E_TABLE_MODEL_CLASS (e_cal_model_memos_parent_class)->duplicate_value (etm, col, value);
+
+	return NULL;
+}
+
+static void
+ecmm_free_value (ETableModel *etm, int col, void *value)
+{
+	g_return_if_fail (col >= 0 && col < E_CAL_MODEL_MEMOS_FIELD_LAST);
+
+	if (col < E_CAL_MODEL_FIELD_LAST) {
+		E_TABLE_MODEL_CLASS (e_cal_model_memos_parent_class)->free_value (etm, col, value);
+		return;
+	}
+}
+
+static void *
+ecmm_initialize_value (ETableModel *etm, int col)
+{
+	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_MEMOS_FIELD_LAST, NULL);
+
+	if (col < E_CAL_MODEL_FIELD_LAST)
+		return E_TABLE_MODEL_CLASS (e_cal_model_memos_parent_class)->initialize_value (etm, col);
+
+	return NULL;
+}
+
+static gboolean
+ecmm_value_is_empty (ETableModel *etm, int col, const void *value)
+{
+	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_MEMOS_FIELD_LAST, TRUE);
+
+	if (col < E_CAL_MODEL_FIELD_LAST)
+		return E_TABLE_MODEL_CLASS (e_cal_model_memos_parent_class)->value_is_empty (etm, col, value);
+
+	return TRUE;
+}
+
+static char *
+ecmm_value_to_string (ETableModel *etm, int col, const void *value)
+{
+	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_MEMOS_FIELD_LAST, g_strdup (""));
+
+	if (col < E_CAL_MODEL_FIELD_LAST)
+		return E_TABLE_MODEL_CLASS (e_cal_model_memos_parent_class)->value_to_string (etm, col, value);
+
+	return g_strdup ("");
+}
+
+/* ECalModel class methods */
+
+static void
+ecmm_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data,
+				ETableModel *source_model, gint row)
+{
+	g_return_if_fail (E_IS_CAL_MODEL_MEMOS (model));
+	g_return_if_fail (comp_data != NULL);
+	g_return_if_fail (E_IS_TABLE_MODEL (source_model));
+
+}
+
+/**
+ * e_cal_model_memos_new
+ */
+ECalModelMemos *
+e_cal_model_memos_new (void)
+{
+	return g_object_new (E_TYPE_CAL_MODEL_MEMOS, NULL);
+}
Index: calendar/gui/e-cal-model-memos.h
===================================================================
RCS file: calendar/gui/e-cal-model-memos.h
diff -N calendar/gui/e-cal-model-memos.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-cal-model-memos.h	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,59 @@
+/* Evolution memo - Data model for ETable
+ *
+ * Copyright (C) 2000 Ximian, Inc.
+ * Copyright (C) 2000 Ximian, Inc.
+ *
+ * Authors: Rodrigo Moya <rodrigo@ximian.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef E_CAL_MODEL_MEMOS_H
+#define E_CAL_MODEL_MEMOS_H
+
+#include "e-cal-model.h"
+
+G_BEGIN_DECLS
+
+#define E_TYPE_CAL_MODEL_MEMOS            (e_cal_model_memos_get_type ())
+#define E_CAL_MODEL_MEMOS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_MODEL_MEMOS, ECalModelMemo))
+#define E_CAL_MODEL_MEMOS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_MODEL_MEMOS, ECalModelMemoClass))
+#define E_IS_CAL_MODEL_MEMOS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_MODEL_MEMOS))
+#define E_IS_CAL_MODEL_MEMOS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_MODEL_MEMOS))
+
+typedef struct _ECalModelMemosPrivate ECalModelMemosPrivate;
+
+typedef enum {
+	/* If you add new items here or reorder them, you have to update the
+	   .etspec files for the tables using this model */
+	E_CAL_MODEL_MEMOS_FIELD_LAST = E_CAL_MODEL_FIELD_LAST
+
+} ECalModelMemoField;
+
+typedef struct {
+	ECalModel model;
+	ECalModelMemosPrivate *priv;
+} ECalModelMemos;
+
+typedef struct {
+	ECalModelClass parent_class;
+} ECalModelMemosClass;
+
+GType          e_cal_model_memos_get_type (void);
+ECalModelMemos *e_cal_model_memos_new (void);
+
+G_END_DECLS
+
+#endif
Index: calendar/gui/e-memo-table-config.c
===================================================================
RCS file: calendar/gui/e-memo-table-config.c
diff -N calendar/gui/e-memo-table-config.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-memo-table-config.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,241 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* 
+ * Author : 
+ *  JP Rosevear <jpr@ximian.com>
+ *  Nathan Owens <pianocomp81@yahoo.com>
+ *
+ * Copyright 2003, Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or 
+ * modify it under the terms of version 2 of the GNU General Public 
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include "calendar-config.h"
+#include "e-memo-table-config.h"
+
+struct _EMemoTableConfigPrivate {
+	EMemoTable *table;
+	
+	GList *notifications;
+};
+
+G_DEFINE_TYPE (EMemoTableConfig, e_memo_table_config, G_TYPE_OBJECT);
+
+/* Property IDs */
+enum props {
+	PROP_0,
+	PROP_TABLE
+};
+
+static void
+e_memo_table_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+	EMemoTableConfig *table_config;
+	EMemoTableConfigPrivate *priv;
+
+	table_config = E_MEMO_TABLE_CONFIG (object);
+	priv = table_config->priv;
+	
+	switch (property_id) {
+	case PROP_TABLE:
+		e_memo_table_config_set_table (table_config, g_value_get_object (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+e_memo_table_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+	EMemoTableConfig *table_config;
+	EMemoTableConfigPrivate *priv;
+
+	table_config = E_MEMO_TABLE_CONFIG (object);
+	priv = table_config->priv;
+	
+	switch (property_id) {
+	case PROP_TABLE:
+		g_value_set_object (value, e_memo_table_config_get_table (table_config));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+e_memo_table_config_dispose (GObject *object)
+{
+	EMemoTableConfig *table_config = E_MEMO_TABLE_CONFIG (object);
+	EMemoTableConfigPrivate *priv;
+	
+	priv = table_config->priv;
+
+	e_memo_table_config_set_table (table_config, NULL);
+	
+	if (G_OBJECT_CLASS (e_memo_table_config_parent_class)->dispose)
+		G_OBJECT_CLASS (e_memo_table_config_parent_class)->dispose (object);
+}
+
+static void
+e_memo_table_config_finalize (GObject *object)
+{
+	EMemoTableConfig *table_config = E_MEMO_TABLE_CONFIG (object);
+	EMemoTableConfigPrivate *priv;
+	
+	priv = table_config->priv;
+
+	g_free (priv);
+	
+	if (G_OBJECT_CLASS (e_memo_table_config_parent_class)->finalize)
+		G_OBJECT_CLASS (e_memo_table_config_parent_class)->finalize (object);
+}
+
+static void
+e_memo_table_config_class_init (EMemoTableConfigClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	GParamSpec *spec;
+
+	/* Method override */
+	gobject_class->set_property = e_memo_table_config_set_property;
+	gobject_class->get_property = e_memo_table_config_get_property;
+	gobject_class->dispose = e_memo_table_config_dispose;
+	gobject_class->finalize = e_memo_table_config_finalize;
+
+	spec = g_param_spec_object ("table", NULL, NULL, e_memo_table_get_type (),
+				    G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
+	g_object_class_install_property (gobject_class, PROP_TABLE, spec);
+}
+
+static void
+e_memo_table_config_init (EMemoTableConfig *table_config)
+{
+	table_config->priv = g_new0 (EMemoTableConfigPrivate, 1);
+
+}
+
+EMemoTableConfig *
+e_memo_table_config_new (EMemoTable *table)
+{
+	EMemoTableConfig *table_config;
+	
+	table_config = g_object_new (e_memo_table_config_get_type (), "table", table, NULL);
+
+	return table_config;
+}
+
+EMemoTable *
+e_memo_table_config_get_table (EMemoTableConfig *table_config) 
+{
+	EMemoTableConfigPrivate *priv;
+
+	g_return_val_if_fail (table_config != NULL, NULL);
+	g_return_val_if_fail (E_IS_MEMO_TABLE_CONFIG (table_config), NULL);
+
+	priv = table_config->priv;
+	
+	return priv->table;
+}
+
+static void
+set_timezone (EMemoTable *table) 
+{
+	ECalModel *model;
+	icaltimezone *zone;
+	
+	zone = calendar_config_get_icaltimezone ();
+	model = e_memo_table_get_model (table);
+	if (model)
+		e_cal_model_set_timezone (model, zone);
+}
+
+static void
+timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{
+	EMemoTableConfig *table_config = data;
+	EMemoTableConfigPrivate *priv;
+	
+	priv = table_config->priv;
+	
+	set_timezone (priv->table);
+}
+
+static void
+set_twentyfour_hour (EMemoTable *table) 
+{
+	ECalModel *model;
+	gboolean use_24_hour;
+
+	use_24_hour = calendar_config_get_24_hour_format ();
+
+	model = e_memo_table_get_model (table);
+	if (model)
+		e_cal_model_set_use_24_hour_format (model, use_24_hour);
+}
+
+static void
+twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{
+	EMemoTableConfig *table_config = data;
+	EMemoTableConfigPrivate *priv;
+	
+	priv = table_config->priv;
+	
+	set_twentyfour_hour (priv->table);
+}
+
+void
+e_memo_table_config_set_table (EMemoTableConfig *table_config, EMemoTable *table) 
+{
+	EMemoTableConfigPrivate *priv;
+	guint not;
+	GList *l;
+	
+	g_return_if_fail (table_config != NULL);
+	g_return_if_fail (E_IS_MEMO_TABLE_CONFIG (table_config));
+
+	priv = table_config->priv;
+	
+	if (priv->table) {
+		g_object_unref (priv->table);
+		priv->table = NULL;
+	}
+	
+	for (l = priv->notifications; l; l = l->next)
+		calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
+
+	g_list_free (priv->notifications);
+	priv->notifications = NULL;
+
+	/* If the new view is NULL, return right now */
+	if (!table)
+		return;
+	
+	priv->table = g_object_ref (table);
+
+	/* Time zone */
+	set_timezone (table);
+	
+	not = calendar_config_add_notification_timezone (timezone_changed_cb, table_config);
+	priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
+
+	/* 24 Hour format */
+	set_twentyfour_hour (table);	
+
+	not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, table_config);
+	priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
+}
Index: calendar/gui/e-memo-table-config.h
===================================================================
RCS file: calendar/gui/e-memo-table-config.h
diff -N calendar/gui/e-memo-table-config.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-memo-table-config.h	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* 
+ * Author : 
+ *  JP Rosevear <jpr@ximian.com>
+ *  Nathan Owens <pianocomp81@yahoo.com>
+ *
+ * Copyright 2003, Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or 
+ * modify it under the terms of version 2 of the GNU General Public 
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#ifndef _E_MEMO_TABLE_CONFIG_H_
+#define _E_MEMO_TABLE_CONFIG_H_
+
+#include "e-memo-table.h"
+
+G_BEGIN_DECLS
+
+#define E_MEMO_TABLE_CONFIG(obj)          GTK_CHECK_CAST (obj, e_memo_table_config_get_type (), EMemoTableConfig)
+#define E_MEMO_TABLE_CONFIG_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, e_memo_table_config_get_type (), EMemoTableConfigClass)
+#define E_IS_MEMO_TABLE_CONFIG(obj)       GTK_CHECK_TYPE (obj, e_memo_table_config_get_type ())
+        
+typedef struct _EMemoTableConfig        EMemoTableConfig;
+typedef struct _EMemoTableConfigClass   EMemoTableConfigClass;
+typedef struct _EMemoTableConfigPrivate EMemoTableConfigPrivate;
+
+struct _EMemoTableConfig {
+	GObject parent;
+
+	EMemoTableConfigPrivate *priv;
+};
+
+struct _EMemoTableConfigClass {
+	GObjectClass parent_class;
+};
+
+GType          e_memo_table_config_get_type (void);
+EMemoTableConfig *e_memo_table_config_new (EMemoTable *table);
+EMemoTable *e_memo_table_config_get_table (EMemoTableConfig *view_config);
+void e_memo_table_config_set_table (EMemoTableConfig *view_config, EMemoTable *table);
+
+G_END_DECLS
+
+#endif
Index: calendar/gui/e-memo-table.c
===================================================================
RCS file: calendar/gui/e-memo-table.c
diff -N calendar/gui/e-memo-table.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-memo-table.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,1029 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * Authors :
+ *  Damon Chaplin <damon@ximian.com>
+ *  Rodrigo Moya <rodrigo@ximian.com>
+ *  Nathan Owens <pianocomp81@yahoo.com>
+ *
+ * Copyright 2000, 2001, 2002, 2003 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+/*
+ * EMemoTable - displays the ECalComponent objects in a table (an ETable).
+ * Used for memos.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <gnome.h>
+#include <widgets/misc/e-gui-utils.h>
+#include <table/e-cell-checkbox.h>
+#include <table/e-cell-toggle.h>
+#include <table/e-cell-text.h>
+#include <table/e-cell-combo.h>
+#include <e-util/e-dialog-utils.h>
+#include <widgets/misc/e-cell-date-edit.h>
+#include <widgets/misc/e-cell-percent.h>
+
+#include "calendar-config.h"
+#include "dialogs/delete-comp.h"
+#include "dialogs/delete-error.h"
+#include "dialogs/memo-editor.h"
+#include "e-cal-model-memos.h"
+#include "e-memo-table.h"
+#include "e-cell-date-edit-text.h"
+#include "e-comp-editor-registry.h"
+#include "print.h"
+#include <e-util/e-icon-factory.h>
+#include "e-cal-popup.h"
+
+
+extern ECompEditorRegistry *comp_editor_registry;
+
+static void e_memo_table_class_init		(EMemoTableClass *klass);
+static void e_memo_table_init			(EMemoTable	*memo_table);
+static void e_memo_table_destroy		(GtkObject	*object);
+
+static void e_memo_table_on_double_click	(ETable		*table,
+						 gint		 row,
+						 gint		 col,
+						 GdkEvent	*event,
+						 EMemoTable *memo_table);
+static gint e_memo_table_show_popup_menu    	(ETable *table,
+						 GdkEvent *gdk_event,
+						 EMemoTable *memo_table);
+
+static gint e_memo_table_on_right_click		(ETable		*table,
+						 gint		 row,
+						 gint		 col,
+						 GdkEvent       *event,
+						 EMemoTable *memo_table);
+static gboolean e_memo_table_on_popup_menu  	(GtkWidget *widget,
+						 gpointer data);
+
+static gint e_memo_table_on_key_press		(ETable		*table,
+						 gint		 row,
+						 gint		 col,
+						 GdkEventKey	*event,
+						 EMemoTable *memo_table);
+
+static ECalModelComponent *get_selected_comp (EMemoTable *memo_table);
+static void open_memo (EMemoTable *memo_table, ECalModelComponent *comp_data);
+
+/* Signal IDs */
+enum {
+	USER_CREATED,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+/* The icons to represent the task. */
+#define E_MEMO_MODEL_NUM_ICONS	2
+static const char* icon_names[E_MEMO_MODEL_NUM_ICONS] = {
+	"stock_notes", "stock_insert-note"
+};
+static GdkPixbuf* icon_pixbufs[E_MEMO_MODEL_NUM_ICONS] = { 0 };
+
+static GdkAtom clipboard_atom = GDK_NONE;
+
+G_DEFINE_TYPE (EMemoTable, e_memo_table, GTK_TYPE_TABLE);
+
+
+static void
+e_memo_table_class_init (EMemoTableClass *klass)
+{
+	GtkObjectClass *object_class;
+	GtkWidgetClass *widget_class;
+
+	object_class = (GtkObjectClass *) klass;
+	widget_class = (GtkWidgetClass *) klass;
+
+	/* Method override */
+	object_class->destroy		= e_memo_table_destroy;
+
+	signals[USER_CREATED] =
+		g_signal_new ("user_created",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (EMemoTableClass, user_created),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
+
+	/* clipboard atom */
+	if (!clipboard_atom)
+		clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
+}
+
+/* Comparison function for the task-sort column.  Sorts by due date and then by
+ * priority.
+ *
+ * FIXME: Does this ever get called?? It doesn't seem to.
+ * I specified that the table should be sorted by this column, but it still
+ * never calls this function.
+ * Also, this assumes it is passed pointers to ECalComponents, but I think it
+ * may just be passed pointers to the 2 cell values.
+ */
+/*
+static gint
+task_compare_cb (gconstpointer a, gconstpointer b)
+{
+	ECalComponent *ca, *cb;
+	ECalComponentDateTime due_a, due_b;
+	int *prio_a, *prio_b;
+	int retval;
+
+	ca = E_CAL_COMPONENT (a);
+	cb = E_CAL_COMPONENT (b);
+
+	e_cal_component_get_due (ca, &due_a);
+	e_cal_component_get_due (cb, &due_b);
+	e_cal_component_get_priority (ca, &prio_a);
+	e_cal_component_get_priority (cb, &prio_b);
+
+	if (due_a.value && due_b.value) {
+		int v;
+
+		/* FIXME: TIMEZONES. But currently we have no way to get the
+		   ECal, so we can't get the timezone. *
+		v = icaltime_compare (*due_a.value, *due_b.value);
+
+		if (v == 0)
+			retval = compare_priorities (prio_a, prio_b);
+		else
+			retval = v;
+	} else if (due_a.value)
+		retval = -1;
+	else if (due_b.value)
+		retval = 1;
+	else
+		retval = compare_priorities (prio_a, prio_b);
+
+	e_cal_component_free_datetime (&due_a);
+	e_cal_component_free_datetime (&due_b);
+
+	if (prio_a)
+		e_cal_component_free_priority (prio_a);
+
+	if (prio_b)
+		e_cal_component_free_priority (prio_b);
+
+	return retval;
+}
+*/
+
+static void
+row_appended_cb (ECalModel *model, EMemoTable *memo_table) 
+{
+	g_signal_emit (memo_table, signals[USER_CREATED], 0);
+}
+
+static void
+e_memo_table_init (EMemoTable *memo_table)
+{
+	GtkWidget *table;
+	ETable *e_table;
+	ECell *cell;
+	ETableExtras *extras;
+	gint i;
+	AtkObject *a11y;
+
+	/* Create the model */
+
+	memo_table->model = (ECalModel *) e_cal_model_memos_new ();
+	g_signal_connect (memo_table->model, "row_appended", G_CALLBACK (row_appended_cb), memo_table);
+
+	/* Create the header columns */
+
+	extras = e_table_extras_new();
+
+	/*
+	 * Normal string fields.
+	 */
+	cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+	g_object_set (G_OBJECT (cell),
+		      "bg_color_column", E_CAL_MODEL_FIELD_COLOR,
+		      NULL);
+
+	e_table_extras_add_cell (extras, "calstring", cell);
+
+
+
+	/* Create pixmaps */
+
+	if (!icon_pixbufs[0])
+		for (i = 0; i < E_MEMO_MODEL_NUM_ICONS; i++) {
+			icon_pixbufs[i] = e_icon_factory_get_icon (icon_names[i], E_ICON_SIZE_LIST);
+		}
+
+	cell = e_cell_toggle_new (0, E_MEMO_MODEL_NUM_ICONS, icon_pixbufs);
+	e_table_extras_add_cell(extras, "icon", cell);
+	e_table_extras_add_pixbuf(extras, "icon", icon_pixbufs[0]);
+
+	/* Create the table */
+
+	table = e_table_scrolled_new_from_spec_file (E_TABLE_MODEL (memo_table->model),
+						     extras,
+						     EVOLUTION_ETSPECDIR "/e-memo-table.etspec",
+						     NULL);
+	/* FIXME: this causes a message from GLib about 'extras' having only a floating
+	   reference */
+	/* g_object_unref (extras); */
+
+	memo_table->etable = table;
+	gtk_table_attach (GTK_TABLE (memo_table), table, 0, 1, 0, 1,
+			  GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+	gtk_widget_show (table);
+
+
+	e_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (table));
+	g_signal_connect (e_table, "double_click", G_CALLBACK (e_memo_table_on_double_click), memo_table);
+	g_signal_connect (e_table, "right_click", G_CALLBACK (e_memo_table_on_right_click), memo_table);
+	g_signal_connect (e_table, "key_press", G_CALLBACK (e_memo_table_on_key_press), memo_table);
+	g_signal_connect (e_table, "popup_menu", G_CALLBACK (e_memo_table_on_popup_menu), memo_table);
+	
+	a11y = gtk_widget_get_accessible (GTK_WIDGET(e_table));
+	if (a11y)
+		atk_object_set_name (a11y, _("Memo Table"));
+}
+
+
+/**
+ * e_memo_table_new:
+ * @Returns: a new #EMemoTable.
+ *
+ * Creates a new #EMemoTable.
+ **/
+GtkWidget *
+e_memo_table_new (void)
+{
+	GtkWidget *memo_table;
+
+	memo_table = GTK_WIDGET (g_object_new (e_memo_table_get_type (), NULL));
+
+	return memo_table;
+}
+
+
+/**
+ * e_memo_table_get_model:
+ * @memo_table: A calendar table.
+ * 
+ * Queries the calendar data model that a calendar table is using.
+ * 
+ * Return value: A memo model.
+ **/
+ECalModel *
+e_memo_table_get_model (EMemoTable *memo_table)
+{
+	g_return_val_if_fail (memo_table != NULL, NULL);
+	g_return_val_if_fail (E_IS_MEMO_TABLE (memo_table), NULL);
+
+	return memo_table->model;
+}
+
+
+static void
+e_memo_table_destroy (GtkObject *object)
+{
+	EMemoTable *memo_table;
+
+	memo_table = E_MEMO_TABLE (object);
+
+	if (memo_table->model) {
+		g_object_unref (memo_table->model);
+		memo_table->model = NULL;
+	}
+
+	GTK_OBJECT_CLASS (e_memo_table_parent_class)->destroy (object);
+}
+
+/**
+ * e_memo_table_get_table:
+ * @memo_table: A calendar table.
+ * 
+ * Queries the #ETable widget that the calendar table is using.
+ * 
+ * Return value: The #ETable widget that the calendar table uses to display its
+ * data.
+ **/
+ETable *
+e_memo_table_get_table (EMemoTable *memo_table)
+{
+	g_return_val_if_fail (memo_table != NULL, NULL);
+	g_return_val_if_fail (E_IS_MEMO_TABLE (memo_table), NULL);
+
+	return e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
+}
+
+void
+e_memo_table_open_selected (EMemoTable *memo_table)
+{
+	ECalModelComponent *comp_data;
+
+	comp_data = get_selected_comp (memo_table);
+	if (comp_data != NULL)
+		open_memo (memo_table, comp_data);
+}
+
+/* Used from e_table_selected_row_foreach(); puts the selected row number in an
+ * int pointed to by the closure data.
+ */
+static void
+get_selected_row_cb (int model_row, gpointer data)
+{
+	int *row;
+
+	row = data;
+	*row = model_row;
+}
+
+/* 
+ * Returns the component that is selected in the table; only works if there is
+ * one and only one selected row.
+ */
+static ECalModelComponent *
+get_selected_comp (EMemoTable *memo_table)
+{
+	ETable *etable;
+	int row;
+
+	etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
+	if (e_table_selected_count (etable) != 1)
+		return NULL;
+
+	row = -1;
+	e_table_selected_row_foreach (etable,
+				      get_selected_row_cb,
+				      &row);
+	g_assert (row != -1);
+
+	return e_cal_model_get_component_at (memo_table->model, row);
+}
+
+struct get_selected_uids_closure {
+	EMemoTable *memo_table;
+	GSList *objects;
+};
+
+/* Used from e_table_selected_row_foreach(), builds a list of the selected UIDs */
+static void
+add_uid_cb (int model_row, gpointer data)
+{
+	struct get_selected_uids_closure *closure;
+	ECalModelComponent *comp_data;
+
+	closure = data;
+
+	comp_data = e_cal_model_get_component_at (closure->memo_table->model, model_row);
+
+	closure->objects = g_slist_prepend (closure->objects, comp_data);
+}
+
+static GSList *
+get_selected_objects (EMemoTable *memo_table)
+{
+	struct get_selected_uids_closure closure;
+	ETable *etable;
+
+	closure.memo_table = memo_table;
+	closure.objects = NULL;
+
+	etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
+	e_table_selected_row_foreach (etable, add_uid_cb, &closure);
+
+	return closure.objects;
+}
+
+/* Deletes all of the selected components in the table */
+static void
+delete_selected_components (EMemoTable *memo_table)
+{
+	GSList *objs, *l;
+
+	objs = get_selected_objects (memo_table);
+
+	e_memo_table_set_status_message (memo_table, _("Deleting selected objects"));
+
+	for (l = objs; l; l = l->next) {
+		ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
+		GError *error = NULL;
+		
+		e_cal_remove_object (comp_data->client, 
+				     icalcomponent_get_uid (comp_data->icalcomp), &error);
+		delete_error_dialog (error, E_CAL_COMPONENT_JOURNAL);
+		g_clear_error (&error);
+	}
+
+	e_memo_table_set_status_message (memo_table, NULL);
+
+	g_slist_free (objs);
+}
+
+/**
+ * e_memo_table_get_selected:
+ * @cal_table: 
+ * 
+ * Get the currently selected ECalModelComponent's on the table.
+ * 
+ * Return value: A GSList of the components, which should be
+ * g_slist_free'd when finished with.
+ **/
+GSList *
+e_memo_table_get_selected (EMemoTable *memo_table)
+{
+	return get_selected_objects(memo_table);
+}
+
+/**
+ * e_memo_table_delete_selected:
+ * @memo_table: A memo table.
+ * 
+ * Deletes the selected components in the table; asks the user first.
+ **/
+void
+e_memo_table_delete_selected (EMemoTable *memo_table)
+{
+	ETable *etable;
+	int n_selected;
+	ECalModelComponent *comp_data;
+	ECalComponent *comp = NULL;
+
+	g_return_if_fail (memo_table != NULL);
+	g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+
+	etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
+
+	n_selected = e_table_selected_count (etable);
+	if (n_selected <= 0)
+		return;
+
+	if (n_selected == 1)
+		comp_data = get_selected_comp (memo_table);
+	else
+		comp_data = NULL;
+
+	/* FIXME: this may be something other than a TODO component */
+
+	if (comp_data) {
+		comp = e_cal_component_new ();
+		e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
+	}
+	
+	if (delete_component_dialog (comp, FALSE, n_selected, E_CAL_COMPONENT_JOURNAL,
+				     GTK_WIDGET (memo_table)))
+		delete_selected_components (memo_table);
+
+	/* free memory */
+	if (comp)
+		g_object_unref (comp);
+}
+
+/**
+ * e_memo_table_cut_clipboard:
+ * @memo_table: A calendar table.
+ *
+ * Cuts selected tasks in the given calendar table
+ */
+void
+e_memo_table_cut_clipboard (EMemoTable *memo_table)
+{
+	g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+
+	e_memo_table_copy_clipboard (memo_table);
+	delete_selected_components (memo_table);
+}
+
+/* callback for e_table_selected_row_foreach */
+static void
+copy_row_cb (int model_row, gpointer data)
+{
+	EMemoTable *memo_table;
+	ECalModelComponent *comp_data;
+	gchar *comp_str;
+	icalcomponent *child;
+
+	memo_table = E_MEMO_TABLE (data);
+
+	g_return_if_fail (memo_table->tmp_vcal != NULL);
+
+	comp_data = e_cal_model_get_component_at (memo_table->model, model_row);
+	if (!comp_data)
+		return;
+
+	/* add timezones to the VCALENDAR component */
+	e_cal_util_add_timezones_from_component (memo_table->tmp_vcal, comp_data->icalcomp);
+
+	/* add the new component to the VCALENDAR component */
+	comp_str = icalcomponent_as_ical_string (comp_data->icalcomp);
+	child = icalparser_parse_string (comp_str);
+	if (child) {
+		icalcomponent_add_component (memo_table->tmp_vcal,
+					     icalcomponent_new_clone (child));
+		icalcomponent_free (child);
+	}
+}
+
+/**
+ * e_memo_table_copy_clipboard:
+ * @memo_table: A calendar table.
+ *
+ * Copies selected tasks into the clipboard
+ */
+void
+e_memo_table_copy_clipboard (EMemoTable *memo_table)
+{
+	ETable *etable;
+	char *comp_str;
+	
+	g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+
+	/* create temporary VCALENDAR object */
+	memo_table->tmp_vcal = e_cal_util_new_top_level ();
+
+	etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable));
+	e_table_selected_row_foreach (etable, copy_row_cb, memo_table);
+	comp_str = icalcomponent_as_ical_string (memo_table->tmp_vcal);
+	gtk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (memo_table), clipboard_atom),
+				(const char *) comp_str,
+				g_utf8_strlen (comp_str, -1));
+	
+	/* free memory */
+	icalcomponent_free (memo_table->tmp_vcal);
+	memo_table->tmp_vcal = NULL;
+}
+
+static void
+clipboard_get_text_cb (GtkClipboard *clipboard, const gchar *text, EMemoTable *memo_table)
+{
+	icalcomponent *icalcomp;
+	char *uid;
+	ECalComponent *comp;
+	ECal *client;
+	icalcomponent_kind kind;
+
+	g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+
+	if (!text || !*text)
+		return;
+
+	icalcomp = icalparser_parse_string (text);
+	if (!icalcomp)
+		return;
+
+	/* check the type of the component */
+	kind = icalcomponent_isa (icalcomp);
+	if (kind != ICAL_VCALENDAR_COMPONENT &&
+	    kind != ICAL_VJOURNAL_COMPONENT) {
+		return;
+	}
+
+	client = e_cal_model_get_default_client (memo_table->model);
+	
+	e_memo_table_set_status_message (memo_table, _("Updating objects"));
+
+	if (kind == ICAL_VCALENDAR_COMPONENT) {
+		icalcomponent_kind child_kind;
+		icalcomponent *subcomp;
+		icalcomponent *vcal_comp;
+
+		vcal_comp = icalcomp;
+		subcomp = icalcomponent_get_first_component (
+			vcal_comp, ICAL_ANY_COMPONENT);
+		while (subcomp) {
+			child_kind = icalcomponent_isa (subcomp);
+			if (child_kind == ICAL_VJOURNAL_COMPONENT) {
+				ECalComponent *tmp_comp;
+
+				uid = e_cal_component_gen_uid ();
+				tmp_comp = e_cal_component_new ();
+				e_cal_component_set_icalcomponent (
+					tmp_comp, icalcomponent_new_clone (subcomp));
+				e_cal_component_set_uid (tmp_comp, uid);
+				free (uid);
+
+				/* FIXME should we convert start/due/complete times? */
+				/* FIXME Error handling */
+				e_cal_create_object (client, e_cal_component_get_icalcomponent (tmp_comp), NULL, NULL);
+
+				g_object_unref (tmp_comp);
+			}
+			subcomp = icalcomponent_get_next_component (
+				vcal_comp, ICAL_ANY_COMPONENT);
+		}
+	}
+	else {
+		comp = e_cal_component_new ();
+		e_cal_component_set_icalcomponent (comp, icalcomp);
+		uid = e_cal_component_gen_uid ();
+		e_cal_component_set_uid (comp, (const char *) uid);
+		free (uid);
+
+		e_cal_create_object (client, e_cal_component_get_icalcomponent (comp), NULL, NULL);
+
+		g_object_unref (comp);
+	}
+
+	e_memo_table_set_status_message (memo_table, NULL);
+}
+
+/**
+ * e_memo_table_paste_clipboard:
+ * @memo_table: A calendar table.
+ *
+ * Pastes tasks currently in the clipboard into the given calendar table
+ */
+void
+e_memo_table_paste_clipboard (EMemoTable *memo_table)
+{
+	g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+
+	gtk_clipboard_request_text (gtk_widget_get_clipboard (GTK_WIDGET (memo_table), clipboard_atom),
+				    (GtkClipboardTextReceivedFunc) clipboard_get_text_cb, memo_table);
+}
+
+/* Opens a task in the task editor */
+static void
+open_memo (EMemoTable *memo_table, ECalModelComponent *comp_data)
+{
+	CompEditor *medit;
+	const char *uid;
+	
+	uid = icalcomponent_get_uid (comp_data->icalcomp);
+
+	medit = e_comp_editor_registry_find (comp_editor_registry, uid);
+	if (medit == NULL) {
+		ECalComponent *comp;
+
+		medit = COMP_EDITOR (memo_editor_new (comp_data->client));
+
+		comp = e_cal_component_new ();
+		e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
+		comp_editor_edit_comp (medit, comp);
+		
+		e_comp_editor_registry_add (comp_editor_registry, medit, FALSE);
+	}
+	
+	comp_editor_focus (medit);
+}
+
+/* Opens the task in the specified row */
+static void
+open_memo_by_row (EMemoTable *memo_table, int row)
+{
+	ECalModelComponent *comp_data;
+
+	comp_data = e_cal_model_get_component_at (memo_table->model, row);
+	open_memo (memo_table, comp_data);
+}
+
+static void
+e_memo_table_on_double_click (ETable *table,
+			      gint row, 
+			      gint col,
+			      GdkEvent *event,
+			      EMemoTable *memo_table)
+{
+	open_memo_by_row (memo_table, row);
+}
+
+
+static void
+e_memo_table_on_open_memo (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	EMemoTable *memo_table = E_MEMO_TABLE (data);
+	ECalModelComponent *comp_data;
+
+	comp_data = get_selected_comp (memo_table);
+	if (comp_data)
+		open_memo (memo_table, comp_data);
+}
+
+static void
+e_memo_table_on_save_as (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	EMemoTable *memo_table = E_MEMO_TABLE (data);
+	ECalModelComponent *comp_data;
+	char *filename;
+	char *ical_string;
+	FILE *file;
+
+	comp_data = get_selected_comp (memo_table);
+	if (comp_data == NULL)
+		return;
+	
+	filename = e_file_dialog_save (_("Save as..."));
+	if (filename == NULL)
+		return;
+	
+	ical_string = e_cal_get_component_as_string (comp_data->client, comp_data->icalcomp);
+	if (ical_string == NULL) {
+		g_warning ("Couldn't convert item to a string");
+		return;
+	}
+	
+	file = fopen (filename, "w");
+	if (file == NULL) {
+		g_warning ("Couldn't save item");
+		return;
+	}
+	
+	fprintf (file, ical_string);
+	g_free (ical_string);
+	fclose (file);
+}
+
+static void
+e_memo_table_on_print_memo (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	EMemoTable *memo_table = E_MEMO_TABLE (data);
+	ECalModelComponent *comp_data;
+	ECalComponent *comp;
+
+	comp_data = get_selected_comp (memo_table);
+	if (comp_data == NULL)
+		return;
+	
+	comp = e_cal_component_new ();
+	e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
+	print_comp (comp, comp_data->client, FALSE);
+
+	g_object_unref (comp);
+}
+
+static void
+e_memo_table_on_cut (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	EMemoTable *memo_table = E_MEMO_TABLE (data);
+
+	e_memo_table_cut_clipboard (memo_table);
+}
+
+static void
+e_memo_table_on_copy (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	EMemoTable *memo_table = E_MEMO_TABLE (data);
+
+	e_memo_table_copy_clipboard (memo_table);
+}
+
+static void
+e_memo_table_on_paste (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	EMemoTable *memo_table = E_MEMO_TABLE (data);
+	
+	e_memo_table_paste_clipboard (memo_table);
+}
+
+static void
+e_memo_table_on_forward (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	EMemoTable *memo_table = E_MEMO_TABLE (data);
+	ECalModelComponent *comp_data;
+
+	comp_data = get_selected_comp (memo_table);
+	if (comp_data) {
+		ECalComponent *comp;
+
+		comp = e_cal_component_new ();
+		e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
+		itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL);
+
+		g_object_unref (comp);
+	}
+}
+
+/* Opens the URL of the memo */
+static void
+open_url_cb (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	EMemoTable *memo_table = E_MEMO_TABLE (data);
+	ECalModelComponent *comp_data;
+	icalproperty *prop;
+
+	comp_data = get_selected_comp (memo_table);
+	if (!comp_data)
+		return;
+
+	prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY);
+	if (!prop)
+		return;
+
+	gnome_url_show (icalproperty_get_url (prop), NULL);
+}
+
+/* Callback for the "delete tasks" menu item */
+static void
+delete_cb (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	EMemoTable *memo_table = E_MEMO_TABLE (data);
+
+	e_memo_table_delete_selected (memo_table);
+}
+
+static EPopupItem memos_popup_items [] = {
+	{ E_POPUP_ITEM, "00.open", N_("_Open"), e_memo_table_on_open_memo, NULL, GTK_STOCK_OPEN, E_CAL_POPUP_SELECT_ONE },
+	{ E_POPUP_ITEM, "05.openweb", N_("Open _Web Page"), open_url_cb, NULL, NULL, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_HASURL },
+	{ E_POPUP_ITEM, "10.saveas", N_("_Save As..."), e_memo_table_on_save_as, NULL, GTK_STOCK_SAVE_AS, E_CAL_POPUP_SELECT_ONE },
+	{ E_POPUP_ITEM, "20.print", N_("_Print..."), e_memo_table_on_print_memo, NULL, GTK_STOCK_PRINT, E_CAL_POPUP_SELECT_ONE },
+
+	{ E_POPUP_BAR, "30.bar" },
+	
+	{ E_POPUP_ITEM, "40.cut", N_("C_ut"), e_memo_table_on_cut, NULL, GTK_STOCK_CUT, 0, E_CAL_POPUP_SELECT_EDITABLE },
+	{ E_POPUP_ITEM, "50.copy", N_("_Copy"), e_memo_table_on_copy, NULL, GTK_STOCK_COPY, 0, 0 },
+	{ E_POPUP_ITEM, "60.paste", N_("_Paste"), e_memo_table_on_paste, NULL, GTK_STOCK_PASTE, 0, E_CAL_POPUP_SELECT_EDITABLE },
+
+	{ E_POPUP_BAR, "70.bar" },
+
+	{ E_POPUP_ITEM, "80.forward", N_("_Forward as iCalendar"), e_memo_table_on_forward, NULL, "stock_mail-forward", E_CAL_POPUP_SELECT_ONE },
+
+	{ E_POPUP_BAR, "90.bar" },
+
+	{ E_POPUP_ITEM, "a0.delete", N_("_Delete"), delete_cb, NULL, GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_EDITABLE },
+	{ E_POPUP_ITEM, "b0.deletemany", N_("_Delete Selected Memos"), delete_cb, NULL, GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_MANY, E_CAL_POPUP_SELECT_EDITABLE },
+};
+
+static void
+emt_popup_free(EPopup *ep, GSList *items, void *data)
+{
+	g_slist_free(items);
+}
+
+static gint
+e_memo_table_show_popup_menu (ETable *table,
+				GdkEvent *gdk_event,
+				EMemoTable *memo_table)
+{
+	GtkMenu *menu;
+	GSList *selection, *l, *menus = NULL;
+	GPtrArray *events;
+	ECalPopup *ep;
+	ECalPopupTargetSelect *t;
+	int i;
+
+	selection = get_selected_objects (memo_table);
+	if (!selection)
+		return TRUE;
+
+	/** @HookPoint-ECalPopup: Tasks Table Context Menu
+	 * @Id: org.gnome.evolution.tasks.table.popup
+	 * @Class: org.gnome.evolution.calendar.popup:1.0
+	 * @Target: ECalPopupTargetSelect
+	 *
+	 * The context menu on the tasks table.
+	 */
+	ep = e_cal_popup_new("org.gnome.evolution.memos.table.popup");
+
+	events = g_ptr_array_new();
+	for (l=selection;l;l=g_slist_next(l))
+		g_ptr_array_add(events, e_cal_model_copy_component_data((ECalModelComponent *)l->data));
+	g_slist_free(selection);
+
+	t = e_cal_popup_target_new_select(ep, memo_table->model, events);
+	t->target.widget = (GtkWidget *)memo_table;
+
+	for (i=0;i<sizeof(memos_popup_items)/sizeof(memos_popup_items[0]);i++)
+		menus = g_slist_prepend(menus, &memos_popup_items[i]);
+	e_popup_add_items((EPopup *)ep, menus, NULL, emt_popup_free, memo_table);
+
+	menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0);
+
+	gtk_menu_popup(menu, NULL, NULL, NULL, NULL, gdk_event?gdk_event->button.button:0,
+		       gdk_event?gdk_event->button.time:gtk_get_current_event_time());
+
+	return TRUE;
+}
+
+static gint
+e_memo_table_on_right_click (ETable *table,
+				 gint row,
+				 gint col,
+				 GdkEvent *event,
+				 EMemoTable *memo_table)
+{
+	return e_memo_table_show_popup_menu (table, event, memo_table);
+}
+
+static gboolean
+e_memo_table_on_popup_menu (GtkWidget *widget, gpointer data)
+{
+	ETable *table = E_TABLE(widget);
+	g_return_val_if_fail(table, FALSE);
+
+	return e_memo_table_show_popup_menu (table, NULL,
+						 E_MEMO_TABLE(data));
+}
+
+static gint
+e_memo_table_on_key_press (ETable *table,
+			       gint row,
+			       gint col,
+			       GdkEventKey *event,
+			       EMemoTable *memo_table)
+{
+	if (event->keyval == GDK_Delete) {
+		delete_cb (NULL, NULL, memo_table);
+		return TRUE;
+	} else if ((event->keyval == GDK_o)
+		   &&(event->state & GDK_CONTROL_MASK)) {
+		open_memo_by_row (memo_table, row);
+		return TRUE;	
+	}
+
+	return FALSE;
+}
+
+/* Loads the state of the table (headers shown etc.) from the given file. */
+void
+e_memo_table_load_state	(EMemoTable *memo_table,
+			 gchar		*filename)
+{
+	struct stat st;
+
+	g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+
+	if (stat (filename, &st) == 0 && st.st_size > 0
+	    && S_ISREG (st.st_mode)) {
+		e_table_load_state (e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)), filename);
+	}
+}
+
+
+/* Saves the state of the table (headers shown etc.) to the given file. */
+void
+e_memo_table_save_state (EMemoTable	*memo_table,
+			 gchar		*filename)
+{
+	g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+
+	e_table_save_state (e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)),
+			    filename);
+}
+
+#ifdef TRANSLATORS_ONLY
+
+static char *test[] = {
+    N_("Click to add a memo")
+};
+
+#endif
+
+/* Displays messages on the status bar */
+#define EVOLUTION_MEMOS_PROGRESS_IMAGE "stock_notes"
+static GdkPixbuf *progress_icon = NULL;
+
+void
+e_memo_table_set_activity_handler (EMemoTable *memo_table, EActivityHandler *activity_handler)
+{
+	g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+
+	memo_table->activity_handler = activity_handler;
+}
+
+void
+e_memo_table_set_status_message (EMemoTable *memo_table, const gchar *message)
+{
+        g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+
+	if (!memo_table->activity_handler)
+		return;
+	
+        if (!message || !*message) {
+		if (memo_table->activity_id != 0) {
+			e_activity_handler_operation_finished (memo_table->activity_handler, memo_table->activity_id);
+			memo_table->activity_id = 0;
+		}
+        } else if (memo_table->activity_id == 0) {
+                char *client_id = g_strdup_printf ("%p", memo_table);
+		
+                if (progress_icon == NULL)
+                        progress_icon = e_icon_factory_get_icon (EVOLUTION_MEMOS_PROGRESS_IMAGE, E_ICON_SIZE_STATUS);
+
+                memo_table->activity_id = e_activity_handler_operation_started (memo_table->activity_handler, client_id,
+									        progress_icon, message, TRUE);
+
+                g_free (client_id);
+        } else {
+                e_activity_handler_operation_progressing (memo_table->activity_handler, memo_table->activity_id, message, -1.0);
+	}
+}
Index: calendar/gui/e-memo-table.etspec
===================================================================
RCS file: calendar/gui/e-memo-table.etspec
diff -N calendar/gui/e-memo-table.etspec
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-memo-table.etspec	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,13 @@
+<ETableSpecification click-to-add="false" _click-to-add-message="Click to add a memo" draw-grid="true">
+  <ETableColumn model_col= "8" _title="Summary" expansion="3.0" minimum_width="10" resizable="true" cell="calstring" compare="string" priority="10"/>
+  <ETableColumn model_col="19" _title="Memo sort" cell="task-sort" compare="memo-sort" priority="-4"/>
+  <ETableColumn model_col="7" pixbuf="icon" _title="Type" expansion="1.0" minimum_width="16" resizable="false" cell="icon" compare="integer" priority="-4"/>
+  <ETableColumn model_col="0" _title="Categories" cell="calstring" compare="string" expansion="1.0" minimum_width="10" resizable="true" priority="-2"/>
+
+  <ETableState>
+    <column source="1"/>
+    <column source="0"/>
+    <column source="2"/>
+    <grouping></grouping>
+  </ETableState>
+</ETableSpecification>
Index: calendar/gui/e-memo-table.h
===================================================================
RCS file: calendar/gui/e-memo-table.h
diff -N calendar/gui/e-memo-table.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-memo-table.h	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,106 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* 
+ * Author : 
+ *  Damon Chaplin <damon@ximian.com>
+ *  Nathan Owens <pianocomp81@yahoo.com>
+ *
+ * Copyright 2000, Ximian, Inc.
+ * Copyright 2000, Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or 
+ * modify it under the terms of version 2 of the GNU General Public 
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+#ifndef _E_MEMO_TABLE_H_
+#define _E_MEMO_TABLE_H_
+
+#include <gtk/gtktable.h>
+#include <table/e-table-scrolled.h>
+#include <widgets/misc/e-cell-date-edit.h>
+#include "e-activity-handler.h"
+#include "e-cal-model.h"
+
+G_BEGIN_DECLS
+
+/*
+ * EMemoTable - displays the iCalendar objects in a table (an ETable).
+ * Used for memo events and tasks.
+ */
+
+
+#define E_MEMO_TABLE(obj)          GTK_CHECK_CAST (obj, e_memo_table_get_type (), EMemoTable)
+#define E_MEMO_TABLE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, e_memo_table_get_type (), EMemoTableClass)
+#define E_IS_MEMO_TABLE(obj)       GTK_CHECK_TYPE (obj, e_memo_table_get_type ())
+
+
+typedef struct _EMemoTable       EMemoTable;
+typedef struct _EMemoTableClass  EMemoTableClass;
+
+
+struct _EMemoTable {
+	GtkTable table;
+
+	/* The model that we use */
+	ECalModel *model;
+
+	GtkWidget *etable;
+
+	/* Fields used for cut/copy/paste */
+	icalcomponent *tmp_vcal;
+
+	/* Activity ID for the EActivityHandler (i.e. the status bar).  */
+	EActivityHandler *activity_handler;
+	guint activity_id;
+};
+
+struct _EMemoTableClass {
+	GtkTableClass parent_class;
+
+	/* Notification signals */
+	void (* user_created) (EMemoTable *memo_table);
+};
+
+
+GtkType	   e_memo_table_get_type (void);
+GtkWidget* e_memo_table_new	(void);
+
+ECalModel *e_memo_table_get_model (EMemoTable *memo_table);
+
+ETable    *e_memo_table_get_table (EMemoTable *memo_table);
+
+void       e_memo_table_open_selected (EMemoTable *memo_table);
+void       e_memo_table_delete_selected (EMemoTable *memo_table);
+
+GSList    *e_memo_table_get_selected (EMemoTable *memo_table);
+
+/* Clipboard related functions */
+void       e_memo_table_cut_clipboard       (EMemoTable *memo_table);
+void       e_memo_table_copy_clipboard      (EMemoTable *memo_table);
+void       e_memo_table_paste_clipboard     (EMemoTable *memo_table);
+
+/* These load and save the state of the table (headers shown etc.) to/from
+   the given file. */
+void	   e_memo_table_load_state		(EMemoTable *memo_table,
+						 gchar		*filename);
+void	   e_memo_table_save_state		(EMemoTable *memo_table,
+						 gchar		*filename);
+
+void       e_memo_table_set_activity_handler (EMemoTable *memo_table,
+					      EActivityHandler *activity_handler);
+void       e_memo_table_set_status_message (EMemoTable *memo_table,
+					    const gchar *message);
+
+G_END_DECLS
+
+#endif /* _E_MEMO_TABLE_H_ */
Index: calendar/gui/e-memos.c
===================================================================
RCS file: calendar/gui/e-memos.c
diff -N calendar/gui/e-memos.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-memos.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,1174 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-memos.c
+ *
+ * Copyright (C) 2001-2003  Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Federico Mena Quintero <federico@ximian.com>
+ *	    Damon Chaplin <damon@ximian.com>
+ *          Rodrigo Moya <rodrigo@ximian.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gnome.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <table/e-table-scrolled.h>
+#include <widgets/menus/gal-view-instance.h>
+#include <widgets/menus/gal-view-factory-etable.h>
+#include <widgets/menus/gal-view-etable.h>
+
+#include "e-util/e-error.h"
+#include "e-util/e-categories-config.h"
+#include "e-util/e-config-listener.h"
+#include "e-util/e-time-utils.h"
+#include "shell/e-user-creatable-items-handler.h"
+#include <libecal/e-cal-time-util.h>
+#include <libedataserver/e-url.h>
+#include <libedataserver/e-categories.h>
+#include "widgets/menus/gal-view-menus.h"
+#include "dialogs/delete-error.h"
+#include "e-calendar-marshal.h"
+#include "calendar-config.h"
+#include "cal-search-bar.h"
+#include "calendar-component.h"
+#include "comp-util.h"
+#include "e-memo-table-config.h"
+#include "misc.h"
+#include "memos-component.h"
+#include "e-cal-component-memo-preview.h"
+#include "e-memos.h"
+#include "common/authentication.h"
+
+
+/* Private part of the GnomeCalendar structure */
+struct _EMemosPrivate {
+	/* The memo lists for display */
+	GHashTable *clients;
+	GList *clients_list;
+	ECal *default_client;
+
+	ECalView *query;
+	
+	EConfigListener *config_listener;
+	
+	/* The EMemoTable showing the memos. */
+	GtkWidget   *memos_view;
+	EMemoTableConfig *memos_view_config;
+	
+	/* Calendar search bar for memos */
+	GtkWidget *search_bar;
+
+	/* Paned widget */
+	GtkWidget *paned;
+
+	/* The preview */
+	GtkWidget *preview;
+	
+	gchar *current_uid;
+	char *sexp;
+	guint update_timeout;
+	
+	/* View instance and the view menus handler */
+	GalViewInstance *view_instance;
+	GalViewMenus *view_menus;
+
+	GList *notifications;
+};
+
+static void setup_widgets (EMemos *memos);
+static void e_memos_destroy (GtkObject *object);
+static void update_view (EMemos *memos);
+
+static void config_categories_changed_cb (EConfigListener *config_listener, const char *key, gpointer user_data);
+static void backend_error_cb (ECal *client, const char *message, gpointer data);
+
+/* Signal IDs */
+enum {
+	SELECTION_CHANGED,
+	SOURCE_ADDED,
+	SOURCE_REMOVED,
+	LAST_SIGNAL
+};
+
+enum DndTargetType {
+	TARGET_VCALENDAR
+};
+
+static GtkTargetEntry list_drag_types[] = {
+	{ "text/calendar",                0, TARGET_VCALENDAR },
+	{ "text/x-calendar",              0, TARGET_VCALENDAR }
+};
+static const int num_list_drag_types = sizeof (list_drag_types) / sizeof (list_drag_types[0]);
+
+static guint e_memos_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (EMemos, e_memos, GTK_TYPE_TABLE);
+
+/* Callback used when the cursor changes in the table */
+static void
+table_cursor_change_cb (ETable *etable, int row, gpointer data)
+{
+	EMemos *memos;
+	EMemosPrivate *priv;
+	ECalModel *model;
+	ECalModelComponent *comp_data;
+	ECalComponent *comp;
+	const char *uid;
+
+	int n_selected;
+
+	memos = E_MEMOS (data);
+	priv = memos->priv;
+
+	n_selected = e_table_selected_count (etable);
+	
+	/* update the HTML widget */
+	if (n_selected != 1) {
+		e_cal_component_memo_preview_clear (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview));
+
+		return;
+	}
+	
+	model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
+	
+	comp_data = e_cal_model_get_component_at (model, e_table_get_cursor_row (etable));
+	comp = e_cal_component_new ();
+	e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
+
+	e_cal_component_memo_preview_display (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview), comp_data->client, comp);
+	
+	e_cal_component_get_uid (comp, &uid);
+	if (priv->current_uid)
+		g_free (priv->current_uid);
+	priv->current_uid = g_strdup (uid);
+	
+	g_object_unref (comp);
+}
+
+/* Callback used when the selection changes in the table. */
+static void
+table_selection_change_cb (ETable *etable, gpointer data)
+{
+	EMemos *memos;
+	int n_selected;
+
+	memos = E_MEMOS (data);
+
+	n_selected = e_table_selected_count (etable);
+	gtk_signal_emit (GTK_OBJECT (memos), e_memos_signals[SELECTION_CHANGED],
+			 n_selected);
+}
+
+static void
+user_created_cb (GtkWidget *view, EMemos *memos)
+{
+	EMemosPrivate *priv;	
+	ECal *ecal;
+	ECalModel *model;
+	
+	priv = memos->priv;
+
+	model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
+	ecal = e_cal_model_get_default_client (model);
+
+	e_memos_add_memo_source (memos, e_cal_get_source (ecal));
+}
+
+/* Callback used when the sexp in the search bar changes */
+static void
+search_bar_sexp_changed_cb (CalSearchBar *cal_search, const char *sexp, gpointer data)
+{
+	EMemos *memos;
+	EMemosPrivate *priv;
+
+	memos = E_MEMOS (data);
+	priv = memos->priv;
+
+	if (priv->sexp)
+		g_free (priv->sexp);
+	
+	priv->sexp = g_strdup (sexp);
+	
+	update_view (memos);
+}
+
+/* Callback used when the selected category in the search bar changes */
+static void
+search_bar_category_changed_cb (CalSearchBar *cal_search, const char *category, gpointer data)
+{
+	EMemos *memos;
+	EMemosPrivate *priv;
+	ECalModel *model;
+
+	memos = E_MEMOS (data);
+	priv = memos->priv;
+
+	model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
+	e_cal_model_set_default_category (model, category);
+}
+
+static gboolean
+vpaned_resized_cb (GtkWidget *widget, GdkEventButton *event, EMemos *memos)
+{
+	calendar_config_set_task_vpane_pos (gtk_paned_get_position (GTK_PANED (widget)));
+
+	return FALSE;
+}
+
+static void
+set_timezone (EMemos *memos) 
+{
+	EMemosPrivate *priv;
+	icaltimezone *zone;
+	GList *l;
+	
+	priv = memos->priv;
+	
+	zone = calendar_config_get_icaltimezone ();
+	for (l = priv->clients_list; l != NULL; l = l->next) {
+		ECal *client = l->data;
+
+		if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED)
+			/* FIXME Error checking */
+			e_cal_set_default_timezone (client, zone, NULL);
+	}
+
+	if (priv->default_client && e_cal_get_load_state (priv->default_client) == E_CAL_LOAD_LOADED)
+		/* FIXME Error checking */
+		e_cal_set_default_timezone (priv->default_client, zone, NULL);
+
+	if (priv->preview)
+		e_cal_component_memo_preview_set_default_timezone (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview), zone);
+}
+
+static void
+timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{
+	EMemos *memos = data;
+	
+	set_timezone (memos);
+}
+
+static void
+update_view (EMemos *memos)
+{
+	EMemosPrivate *priv;
+	ECalModel *model;
+	char *real_sexp = NULL;
+	char *new_sexp = NULL;
+	
+	priv = memos->priv;
+
+	model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
+		
+	e_cal_model_set_search_query (model, priv->sexp);
+	
+	e_cal_component_memo_preview_clear (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview));
+}
+
+static gboolean
+update_view_cb (EMemos *memos)
+{	
+	update_view (memos);
+
+	return TRUE;
+}
+
+static void
+model_row_changed_cb (ETableModel *etm, int row, gpointer data)
+{
+	EMemos *memos;
+	EMemosPrivate *priv;
+	ECalModelComponent *comp_data;
+
+	memos = E_MEMOS (data);
+	priv = memos->priv;
+
+	if (priv->current_uid) {
+		const char *uid;
+
+		comp_data = e_cal_model_get_component_at (E_CAL_MODEL (etm), row);
+		if (comp_data) {
+			uid = icalcomponent_get_uid (comp_data->icalcomp);
+			if (!strcmp (uid ? uid : "", priv->current_uid)) {
+				ETable *etable;
+
+				etable = e_table_scrolled_get_table (
+					E_TABLE_SCROLLED (E_MEMO_TABLE (priv->memos_view)->etable));
+				table_cursor_change_cb (etable, 0, memos);
+			}
+		}
+	}
+}
+
+static void
+setup_config (EMemos *memos)
+{
+	EMemosPrivate *priv;
+	guint not;
+
+	priv = memos->priv;
+	
+	/* Timezone */
+	set_timezone (memos);
+	
+	not = calendar_config_add_notification_timezone (timezone_changed_cb, memos);
+	priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
+}
+
+static void
+table_drag_data_get (ETable             *table,
+		     int                 row,
+		     int                 col,
+		     GdkDragContext     *context,
+		     GtkSelectionData   *selection_data,
+		     guint               info,
+		     guint               time,
+		     EMemos             *memos)
+{
+	EMemosPrivate *priv;
+	ECalModelComponent *comp_data;
+
+	priv = memos->priv;
+
+	if (priv->current_uid) {
+		ECalModel *model;
+
+		model = e_memo_table_get_model (
+			E_MEMO_TABLE (priv->memos_view));
+
+		comp_data = e_cal_model_get_component_at (model, row);
+
+		if (info == TARGET_VCALENDAR) {
+			/* we will pass an icalcalendar component for both types */
+			char *comp_str;
+			icalcomponent *vcal;
+		
+			vcal = e_cal_util_new_top_level ();
+			e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp);
+			icalcomponent_add_component (
+			        vcal,
+				icalcomponent_new_clone (comp_data->icalcomp));
+
+			comp_str = icalcomponent_as_ical_string (vcal);
+			if (comp_str) {
+				gtk_selection_data_set (selection_data, selection_data->target,
+							8, comp_str, strlen (comp_str));
+			}
+			icalcomponent_free (vcal);
+		}
+	}
+}
+
+static void 
+table_drag_data_delete (ETable         *table,
+			int             row,
+			int             col,
+			GdkDragContext *context,
+			EMemos         *memos)
+{
+	EMemosPrivate *priv;
+	ECalModelComponent *comp_data;
+	ECalModel *model;
+	gboolean read_only = TRUE;
+	
+	priv = memos->priv;
+	
+	model = e_memo_table_get_model (
+		E_MEMO_TABLE (priv->memos_view));
+	comp_data = e_cal_model_get_component_at (model, row);
+
+	e_cal_is_read_only (comp_data->client, &read_only, NULL);
+	if (read_only)
+		return;
+
+	e_cal_remove_object (comp_data->client, icalcomponent_get_uid (comp_data->icalcomp), NULL);
+}
+
+#define E_MEMOS_TABLE_DEFAULT_STATE					\
+	"<?xml version=\"1.0\"?>"					\
+	"<ETableState>"							\
+	"<column source=\"1\"/>"					\
+	"<column source=\"0\"/>"					\
+	"<column source=\"2\"/>"					\
+	"<grouping></grouping>"						\
+	"</ETableState>"
+
+static void
+pane_realized (GtkWidget *widget, EMemos *memos)
+{
+	gtk_paned_set_position ((GtkPaned *)widget, calendar_config_get_task_vpane_pos ());
+}
+
+static void
+setup_widgets (EMemos *memos)
+{
+	EMemosPrivate *priv;
+	ETable *etable;
+	ECalModel *model;
+
+	priv = memos->priv;
+
+	priv->search_bar = cal_search_bar_new (CAL_SEARCH_TASKS_DEFAULT);
+	g_signal_connect (priv->search_bar, "sexp_changed",
+			  G_CALLBACK (search_bar_sexp_changed_cb), memos);
+	g_signal_connect (priv->search_bar, "category_changed",
+			  G_CALLBACK (search_bar_category_changed_cb), memos);
+	
+	/* TODO Why doesn't this work?? */
+	config_categories_changed_cb (priv->config_listener, "/apps/evolution/general/category_master_list", memos);
+
+	gtk_table_attach (GTK_TABLE (memos), priv->search_bar, 0, 1, 0, 1,
+			  GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0, 0);
+	gtk_widget_show (priv->search_bar);
+
+	/* add the paned widget for the memo list and memo detail areas */
+	priv->paned = gtk_vpaned_new ();
+	g_signal_connect (priv->paned, "realize", G_CALLBACK (pane_realized), memos);
+
+	g_signal_connect (G_OBJECT (priv->paned), "button_release_event",
+			  G_CALLBACK (vpaned_resized_cb), memos);
+	gtk_table_attach (GTK_TABLE (memos), priv->paned, 0, 1, 1, 2,
+			  GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+	gtk_widget_show (priv->paned);
+
+	/* create the memo list */
+	priv->memos_view = e_memo_table_new ();
+	priv->memos_view_config = e_memo_table_config_new (E_MEMO_TABLE (priv->memos_view));
+	
+	g_signal_connect (priv->memos_view, "user_created", G_CALLBACK (user_created_cb), memos);
+
+	etable = e_table_scrolled_get_table (
+		E_TABLE_SCROLLED (E_MEMO_TABLE (priv->memos_view)->etable));
+	e_table_set_state (etable, E_MEMOS_TABLE_DEFAULT_STATE);
+	
+	gtk_paned_add1 (GTK_PANED (priv->paned), priv->memos_view);
+	gtk_widget_show (priv->memos_view);
+
+
+	e_table_drag_source_set (etable, GDK_BUTTON1_MASK,
+				 list_drag_types, num_list_drag_types,
+				 GDK_ACTION_MOVE|GDK_ACTION_COPY|GDK_ACTION_ASK);
+	
+	g_signal_connect (etable, "table_drag_data_get",
+			  G_CALLBACK(table_drag_data_get), memos);
+	g_signal_connect (etable, "table_drag_data_delete",
+			  G_CALLBACK(table_drag_data_delete), memos);
+
+	g_signal_connect (etable, "cursor_change", G_CALLBACK (table_cursor_change_cb), memos);
+	g_signal_connect (etable, "selection_change", G_CALLBACK (table_selection_change_cb), memos);
+
+	/* Timeout check to hide completed items */
+	priv->update_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_view_cb, memos, NULL);
+
+	/* create the memo detail */
+	priv->preview = e_cal_component_memo_preview_new ();
+	e_cal_component_memo_preview_set_default_timezone (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview), calendar_config_get_icaltimezone ());
+	gtk_paned_add2 (GTK_PANED (priv->paned), priv->preview);
+	gtk_widget_show (priv->preview);
+
+	model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
+	g_signal_connect (G_OBJECT (model), "model_row_changed",
+			  G_CALLBACK (model_row_changed_cb), memos);
+}
+
+/* Class initialization function for the gnome calendar */
+static void
+e_memos_class_init (EMemosClass *klass)
+{
+	GtkObjectClass *object_class;
+
+	object_class = (GtkObjectClass *) klass;
+
+	e_memos_signals[SELECTION_CHANGED] =
+		gtk_signal_new ("selection_changed",
+				GTK_RUN_LAST,
+				G_TYPE_FROM_CLASS (object_class), 
+				GTK_SIGNAL_OFFSET (EMemosClass, selection_changed),
+				gtk_marshal_NONE__INT,
+				GTK_TYPE_NONE, 1,
+				GTK_TYPE_INT);
+
+	e_memos_signals[SOURCE_ADDED] =
+		g_signal_new ("source_added",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (EMemosClass, source_added),
+			      NULL, NULL,
+			      e_calendar_marshal_VOID__OBJECT,
+			      G_TYPE_NONE,
+			      1,
+			      G_TYPE_OBJECT);
+
+	e_memos_signals[SOURCE_REMOVED] =
+		g_signal_new ("source_removed",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (EMemosClass, source_removed),
+			      NULL, NULL,
+			      e_calendar_marshal_VOID__OBJECT,
+			      G_TYPE_NONE,
+			      1,
+			      G_TYPE_OBJECT);
+
+	object_class->destroy = e_memos_destroy;
+
+	klass->selection_changed = NULL;
+	klass->source_added = NULL;
+	klass->source_removed = NULL;
+}
+
+
+static void
+config_categories_changed_cb (EConfigListener *config_listener, const char *key, gpointer user_data)
+{
+	GList *cat_list;
+	GPtrArray *cat_array;
+	EMemosPrivate *priv;
+	EMemos *memos = user_data;
+
+	priv = memos->priv;
+
+	cat_array = g_ptr_array_new ();
+	cat_list = e_categories_get_list ();
+	while (cat_list != NULL) {
+		if (e_categories_is_searchable ((const char *) cat_list->data))
+			g_ptr_array_add (cat_array, cat_list->data);
+		cat_list = g_list_remove (cat_list, cat_list->data);
+	}
+
+	cal_search_bar_set_categories (CAL_SEARCH_BAR(priv->search_bar), cat_array);
+
+	g_ptr_array_free (cat_array, TRUE);
+}
+
+/* Object initialization function for the gnome calendar */
+static void
+e_memos_init (EMemos *memos)
+{
+	EMemosPrivate *priv;
+	
+	priv = g_new0 (EMemosPrivate, 1);
+	memos->priv = priv;
+
+	setup_config (memos);
+	setup_widgets (memos);
+	
+	priv->config_listener = e_config_listener_new ();
+	g_signal_connect (priv->config_listener, "key_changed", G_CALLBACK (config_categories_changed_cb), memos);
+
+	priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);	
+	priv->query = NULL;
+	priv->view_instance = NULL;
+	priv->view_menus = NULL;
+	priv->current_uid = NULL;
+	priv->sexp = g_strdup ("#t");
+	priv->default_client = NULL;
+	update_view (memos);
+}
+
+/* Callback used when the set of categories changes in the calendar client */
+/* TODO this was actually taken out of tasks in 2.3.x
+ *      config_categories doesn't work, but this may - trying with memos*/
+/*
+static void
+client_categories_changed_cb (ECal *client, GPtrArray *categories, gpointer data)
+{
+	EMemos *memos;
+	EMemosPrivate *priv;
+
+	memos = E_MEMOS (data);
+	priv = memos->priv;
+
+	cal_search_bar_set_categories (CAL_SEARCH_BAR (priv->search_bar), categories);
+}
+*/
+
+GtkWidget *
+e_memos_new (void)
+{
+	EMemos *memos;
+
+	memos = g_object_new (e_memos_get_type (), NULL);
+
+	return GTK_WIDGET (memos);
+}
+
+
+void
+e_memos_set_ui_component (EMemos *memos,
+			  BonoboUIComponent *ui_component)
+{
+	g_return_if_fail (E_IS_MEMOS (memos));
+	g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component));
+
+	e_search_bar_set_ui_component (E_SEARCH_BAR (memos->priv->search_bar), ui_component);
+}
+
+
+static void
+e_memos_destroy (GtkObject *object)
+{
+	EMemos *memos;
+	EMemosPrivate *priv;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (E_IS_MEMOS (object));
+
+	memos = E_MEMOS (object);
+	priv = memos->priv;
+
+	if (priv) {
+		GList *l;
+
+		/* unset the config listener */
+		if (priv->config_listener) {
+			g_signal_handlers_disconnect_matched (priv->config_listener,
+							      G_SIGNAL_MATCH_DATA,
+							      0, 0, NULL, NULL, memos);
+			g_object_unref (priv->config_listener);
+			priv->config_listener = NULL;
+		}
+		
+		/* disconnect from signals on all the clients */
+		for (l = priv->clients_list; l != NULL; l = l->next) {
+			g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA,
+							      0, 0, NULL, NULL, memos);
+		}
+
+		g_hash_table_destroy (priv->clients);
+		g_list_free (priv->clients_list);
+
+		if (priv->default_client)
+			g_object_unref (priv->default_client);
+		priv->default_client = NULL;
+
+		if (priv->current_uid) {
+			g_free (priv->current_uid);
+			priv->current_uid = NULL;
+		}
+	
+		if (priv->sexp) {
+			g_free (priv->sexp);
+			priv->sexp = NULL;
+		}
+
+		if (priv->update_timeout) {
+			g_source_remove (priv->update_timeout);
+			priv->update_timeout = 0;
+		}
+	
+		if (priv->memos_view_config) {
+			g_object_unref (priv->memos_view_config);
+			priv->memos_view_config = NULL;
+		}
+		
+		for (l = priv->notifications; l; l = l->next)
+			calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
+		priv->notifications = NULL;
+
+		g_free (priv);
+		memos->priv = NULL;
+	}
+
+	if (GTK_OBJECT_CLASS (e_memos_parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (e_memos_parent_class)->destroy) (object);
+}
+
+static void
+set_status_message (EMemos *memos, const char *message, ...)
+{
+	EMemosPrivate *priv;
+	va_list args;
+	char sz[2048], *msg_string = NULL;
+
+	if (message) {
+		va_start (args, message);
+		vsnprintf (sz, sizeof sz, message, args);
+		va_end (args);
+		msg_string = sz;
+	}
+
+	priv = memos->priv;
+	
+	e_memo_table_set_status_message (E_MEMO_TABLE (priv->memos_view), msg_string);
+}
+
+/* Callback from the calendar client when an error occurs in the backend */
+static void
+backend_error_cb (ECal *client, const char *message, gpointer data)
+{
+	EMemos *memos;
+	EMemosPrivate *priv;
+	char *errmsg;
+	char *urinopwd;
+
+	memos = E_MEMOS (data);
+	priv = memos->priv;
+
+	urinopwd = get_uri_without_password (e_cal_get_uri (client));
+	errmsg = g_strdup_printf (_("Error on %s:\n %s"), urinopwd, message);
+	gnome_error_dialog_parented (errmsg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (memos))));
+	g_free (errmsg);
+	g_free (urinopwd);
+}
+
+/* Callback from the calendar client when the backend dies */
+static void
+backend_died_cb (ECal *client, gpointer data)
+{
+	EMemos *memos;
+	EMemosPrivate *priv;
+	ESource *source;
+	
+	memos = E_MEMOS (data);
+	priv = memos->priv;
+
+	source = g_object_ref (e_cal_get_source (client));
+
+	priv->clients_list = g_list_remove (priv->clients_list, client);
+	g_hash_table_remove (priv->clients,  e_source_peek_uid (source));
+
+	gtk_signal_emit (GTK_OBJECT (memos), e_memos_signals[SOURCE_REMOVED], source);
+
+	e_memo_table_set_status_message (E_MEMO_TABLE (e_memos_get_calendar_table (memos)), NULL);
+	
+	e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (memos))),
+		     "calendar:memos-crashed", NULL);
+	
+	g_object_unref (source);
+}
+
+/* Callback from the calendar client when the calendar is opened */
+static void
+client_cal_opened_cb (ECal *ecal, ECalendarStatus status, EMemos *memos)
+{
+	ECalModel *model;
+	ESource *source;
+	EMemosPrivate *priv;
+
+	priv = memos->priv;
+
+	source = e_cal_get_source (ecal);
+
+	switch (status) {
+	case E_CALENDAR_STATUS_OK :
+		g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, client_cal_opened_cb, NULL);
+
+		set_status_message (memos, _("Loading memos"));
+		model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
+		e_cal_model_add_client (model, ecal);
+
+		set_timezone (memos);
+		set_status_message (memos, NULL);
+		break;
+	case E_CALENDAR_STATUS_BUSY :
+		break;
+	case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
+		e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (memos))), "calendar:prompt-no-contents-offline-memos", NULL);
+		break;
+	default :
+		/* Make sure the source doesn't disappear on us */
+		g_object_ref (source);
+
+		priv->clients_list = g_list_remove (priv->clients_list, ecal);
+		g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA,
+						      0, 0, NULL, NULL, memos);
+
+		/* Do this last because it unrefs the client */
+		g_hash_table_remove (priv->clients,  e_source_peek_uid (source));
+
+		gtk_signal_emit (GTK_OBJECT (memos), e_memos_signals[SOURCE_REMOVED], source);
+
+		set_status_message (memos, NULL);
+		g_object_unref (source);
+
+		break;
+	}
+}
+
+static void
+default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, EMemos *memos)
+{
+	ECalModel *model;
+	ESource *source;
+	EMemosPrivate *priv;
+
+	priv = memos->priv;
+
+	source = e_cal_get_source (ecal);
+
+	switch (status) {
+	case E_CALENDAR_STATUS_OK :
+		g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, default_client_cal_opened_cb, NULL);
+		model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
+		
+		set_timezone (memos);
+		e_cal_model_set_default_client (model, ecal);
+		set_status_message (memos, NULL);
+		break;
+	case E_CALENDAR_STATUS_BUSY:
+		break;
+	default :
+		/* Make sure the source doesn't disappear on us */
+		g_object_ref (source);
+
+		priv->clients_list = g_list_remove (priv->clients_list, ecal);
+		g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA,
+						      0, 0, NULL, NULL, memos);
+
+		/* Do this last because it unrefs the client */
+		g_hash_table_remove (priv->clients,  e_source_peek_uid (source));
+
+		gtk_signal_emit (GTK_OBJECT (memos), e_memos_signals[SOURCE_REMOVED], source);
+
+		set_status_message (memos, NULL);
+		g_object_unref (priv->default_client);
+		priv->default_client = NULL;
+		g_object_unref (source);
+
+		break;
+	}
+}
+
+typedef void (*open_func) (ECal *, ECalendarStatus, EMemos *);
+
+static gboolean
+open_ecal (EMemos *memos, ECal *cal, gboolean only_if_exists, open_func of)
+{
+	EMemosPrivate *priv;
+
+	priv = memos->priv;
+	
+	set_status_message (memos, _("Opening memos at %s"), e_cal_get_uri (cal));
+
+	g_signal_connect (G_OBJECT (cal), "cal_opened", G_CALLBACK (of), memos);
+	e_cal_open_async (cal, only_if_exists);
+
+	return TRUE;
+}
+
+void
+e_memos_open_memo			(EMemos		*memos)
+{
+	EMemoTable *cal_table;
+                                                                                
+	cal_table = e_memos_get_calendar_table (memos);
+	e_memo_table_open_selected (cal_table);
+}
+
+void
+e_memos_new_memo (EMemos *memos)
+{
+	/* used for click_to_add ?? Can't figure out anything else it's used for */
+}
+
+gboolean
+e_memos_add_memo_source (EMemos *memos, ESource *source)
+{
+	EMemosPrivate *priv;
+	ECal *client;
+	const char *uid;
+
+	g_return_val_if_fail (memos != NULL, FALSE);
+	g_return_val_if_fail (E_IS_MEMOS (memos), FALSE);
+	g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
+
+	priv = memos->priv;
+
+	uid = e_source_peek_uid (source);
+	client = g_hash_table_lookup (priv->clients, uid);
+	if (client) {
+		/* We already have it */
+
+		return TRUE;
+	} else {
+		ESource *default_source;
+		
+		if (priv->default_client) {
+			default_source = e_cal_get_source (priv->default_client);
+		
+			/* We don't have it but the default client is it */
+			if (!strcmp (e_source_peek_uid (default_source), uid))
+				client = g_object_ref (priv->default_client);
+		}
+
+		/* Create a new one */
+		if (!client) {
+			client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
+			if (!client)
+				return FALSE;
+		}
+	}
+
+	g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), memos);
+/*	g_signal_connect (G_OBJECT (client), "categories_changed", G_CALLBACK (client_categories_changed_cb), memos); */
+	g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), memos);
+
+	/* add the client to internal structure */	
+	g_hash_table_insert (priv->clients, g_strdup (uid) , client);
+	priv->clients_list = g_list_prepend (priv->clients_list, client);
+
+	gtk_signal_emit (GTK_OBJECT (memos), e_memos_signals[SOURCE_ADDED], source);
+
+	open_ecal (memos, client, FALSE, client_cal_opened_cb);
+
+	return TRUE;
+}
+
+gboolean
+e_memos_remove_memo_source (EMemos *memos, ESource *source)
+{
+	EMemosPrivate *priv;
+	ECal *client;
+	ECalModel *model;
+	const char *uid;
+
+	g_return_val_if_fail (memos != NULL, FALSE);
+	g_return_val_if_fail (E_IS_MEMOS (memos), FALSE);
+	g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
+
+	priv = memos->priv;
+
+	uid = e_source_peek_uid (source);
+	client = g_hash_table_lookup (priv->clients, uid);
+	if (!client) 
+		return TRUE;
+	
+
+	priv->clients_list = g_list_remove (priv->clients_list, client);
+	g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA,
+					      0, 0, NULL, NULL, memos);	
+
+	model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view));
+	e_cal_model_remove_client (model, client);
+
+	g_hash_table_remove (priv->clients, uid);
+       
+
+	gtk_signal_emit (GTK_OBJECT (memos), e_memos_signals[SOURCE_REMOVED], source);
+
+	return TRUE;
+}
+
+gboolean
+e_memos_set_default_source (EMemos *memos, ESource *source)
+{
+	EMemosPrivate *priv;
+	ECal *ecal;
+	
+	g_return_val_if_fail (memos != NULL, FALSE);
+	g_return_val_if_fail (E_IS_MEMOS (memos), FALSE);
+	g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
+
+	priv = memos->priv;
+
+	ecal = g_hash_table_lookup (priv->clients, e_source_peek_uid (source));
+
+	if (priv->default_client)
+		g_object_unref (priv->default_client);
+
+	if (ecal) {
+		priv->default_client = g_object_ref (ecal);
+	} else {
+		priv->default_client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
+		if (!priv->default_client)
+			return FALSE;
+	}
+
+	open_ecal (memos, priv->default_client, FALSE, default_client_cal_opened_cb);
+
+	return TRUE;
+}
+
+ECal *
+e_memos_get_default_client (EMemos *memos)
+{
+	EMemosPrivate *priv;
+	
+	g_return_val_if_fail (memos != NULL, NULL);
+	g_return_val_if_fail (E_IS_MEMOS (memos), NULL);
+
+	priv = memos->priv;
+
+	return e_cal_model_get_default_client (e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view)));	
+}
+
+
+/**
+ * e_memos_delete_selected:
+ * @memos: A memos control widget.
+ * 
+ * Deletes the selected memos in the memo list.
+ **/
+void
+e_memos_delete_selected (EMemos *memos)
+{
+	EMemosPrivate *priv;
+	EMemoTable *cal_table;
+
+	g_return_if_fail (memos != NULL);
+	g_return_if_fail (E_IS_MEMOS (memos));
+
+	priv = memos->priv;
+
+	cal_table = E_MEMO_TABLE (priv->memos_view);
+	set_status_message (memos, _("Deleting selected objects..."));
+	e_memo_table_delete_selected (cal_table);
+	set_status_message (memos, NULL);
+
+	e_cal_component_memo_preview_clear (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview));
+}
+
+
+/* Callback used from the view collection when we need to display a new view */
+static void
+display_view_cb (GalViewInstance *instance, GalView *view, gpointer data)
+{
+	EMemos *memos;
+
+	memos = E_MEMOS (data);
+
+	if (GAL_IS_VIEW_ETABLE (view)) {
+		gal_view_etable_attach_table (GAL_VIEW_ETABLE (view), e_table_scrolled_get_table (E_TABLE_SCROLLED (E_MEMO_TABLE (memos->priv->memos_view)->etable)));
+	}
+
+	gtk_paned_set_position ((GtkPaned *)memos->priv->paned, calendar_config_get_task_vpane_pos ());
+}
+
+/**
+ * e_memos_setup_view_menus:
+ * @memos: A memos widget.
+ * @uic: UI controller to use for the menus.
+ * 
+ * Sets up the #GalView menus for a memos control.  This function should be
+ * called from the Bonobo control activation callback for this memos control.
+ * Also, the menus should be discarded using e_memos_discard_view_menus().
+ */
+void
+e_memos_setup_view_menus (EMemos *memos, BonoboUIComponent *uic)
+{
+	EMemosPrivate *priv;
+	GalViewFactory *factory;
+	ETableSpecification *spec;
+	char *dir;
+	static GalViewCollection *collection = NULL;
+
+	g_return_if_fail (memos != NULL);
+	g_return_if_fail (E_IS_MEMOS (memos));
+	g_return_if_fail (uic != NULL);
+	g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic));
+
+	priv = memos->priv;
+
+	g_return_if_fail (priv->view_instance == NULL);
+
+	g_assert (priv->view_instance == NULL);
+	g_assert (priv->view_menus == NULL);
+
+	/* Create the view instance */
+
+	if (collection == NULL) {
+		collection = gal_view_collection_new ();
+
+		gal_view_collection_set_title (collection, _("Memos"));
+
+		dir = g_build_filename (memos_component_peek_base_directory (memos_component_peek ()), 
+					"memos", "views", NULL);
+	
+		gal_view_collection_set_storage_directories (collection,
+							     EVOLUTION_GALVIEWSDIR "/memos/",
+							     dir);
+		g_free (dir);
+
+		/* Create the views */
+
+		spec = e_table_specification_new ();
+		e_table_specification_load_from_file (spec, 
+						      EVOLUTION_ETSPECDIR "/e-memo-table.etspec");
+
+		factory = gal_view_factory_etable_new (spec);
+		g_object_unref (spec);
+		gal_view_collection_add_factory (collection, factory);
+		g_object_unref (factory);
+
+		/* Load the collection and create the menus */
+
+		gal_view_collection_load (collection);
+	}
+
+	priv->view_instance = gal_view_instance_new (collection, NULL);
+
+	priv->view_menus = gal_view_menus_new (priv->view_instance);
+	gal_view_menus_apply (priv->view_menus, uic, NULL);
+	g_signal_connect (priv->view_instance, "display_view", G_CALLBACK (display_view_cb), memos);
+	display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), memos);
+}
+
+/**
+ * e_memos_discard_view_menus:
+ * @memos: A memos widget.
+ * 
+ * Discards the #GalView menus used by a memos control.  This function should be
+ * called from the Bonobo control deactivation callback for this memos control.
+ * The menus should have been set up with e_memos_setup_view_menus().
+ **/
+void
+e_memos_discard_view_menus (EMemos *memos)
+{
+	EMemosPrivate *priv;
+
+	g_return_if_fail (memos != NULL);
+	g_return_if_fail (E_IS_MEMOS (memos));
+
+	priv = memos->priv;
+
+	g_return_if_fail (priv->view_instance != NULL);
+
+	g_assert (priv->view_instance != NULL);
+	g_assert (priv->view_menus != NULL);
+
+	g_object_unref (priv->view_instance);
+	priv->view_instance = NULL;
+
+	g_object_unref (priv->view_menus);
+	priv->view_menus = NULL;
+}
+
+/**
+ * e_memos_get_calendar_table:
+ * @memos: A memos widget.
+ * 
+ * Queries the #EMemoTable contained in a memos widget.
+ * 
+ * Return value: The #EMemoTable that the memos widget uses to display its
+ * information.
+ **/
+EMemoTable *
+e_memos_get_calendar_table (EMemos *memos)
+{
+	EMemosPrivate *priv;
+
+	g_return_val_if_fail (memos != NULL, NULL);
+	g_return_val_if_fail (E_IS_MEMOS (memos), NULL);
+
+	priv = memos->priv;
+	return E_MEMO_TABLE (priv->memos_view);
+}
Index: calendar/gui/e-memos.h
===================================================================
RCS file: calendar/gui/e-memos.h
diff -N calendar/gui/e-memos.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-memos.h	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,87 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-memos.h
+ *
+ * Copyright (C) 2001  Ximian, Inc.
+ * Copyright (C) 2001  Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Federico Mena Quintero <federico@ximian.com>
+ *	    Damon Chaplin <damon@ximian.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ */
+
+#ifndef _E_MEMOS_H_
+#define _E_MEMOS_H_
+
+#include <bonobo/bonobo-ui-component.h>
+#include <gtk/gtktable.h>
+#include <libedataserver/e-source.h>
+#include <libecal/e-cal.h>
+#include "e-memo-table.h"
+
+#define E_TYPE_MEMOS            (e_memos_get_type ())
+#define E_MEMOS(obj)            (GTK_CHECK_CAST ((obj), E_TYPE_MEMOS, EMemos))
+#define E_MEMOS_CLASS(klass)    (GTK_CHECK_CAST_CLASS ((klass), E_TYPE_MEMOS, \
+				 EMemosClass))
+#define E_IS_MEMOS(obj)         (GTK_CHECK_TYPE ((obj), E_TYPE_MEMOS))
+#define E_IS_MEMOS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_MEMOS))
+
+typedef struct _EMemos EMemos;
+typedef struct _EMemosClass EMemosClass;
+typedef struct _EMemosPrivate EMemosPrivate;
+
+struct _EMemos {
+	GtkTable table;
+
+	/* Private data */
+	EMemosPrivate *priv;
+};
+
+struct _EMemosClass {
+	GtkTableClass parent_class;
+
+	/* Notification signals */
+	void (* selection_changed) (EMemos *memos, int n_selected);
+        void (* source_added)      (EMemos *memos, ESource *source);
+        void (* source_removed)    (EMemos *memos, ESource *source);
+};
+
+
+GtkType    e_memos_get_type        (void);
+GtkWidget *e_memos_construct       (EMemos *memos);
+
+GtkWidget *e_memos_new             (void);
+
+void       e_memos_set_ui_component  (EMemos            *memos,
+				      BonoboUIComponent *ui_component);
+
+gboolean   e_memos_add_memo_source (EMemos *memos, ESource *source);
+gboolean   e_memos_remove_memo_source (EMemos *memos, ESource *source);
+gboolean   e_memos_set_default_source (EMemos *memos, ESource *source);
+ECal      *e_memos_get_default_client    (EMemos *memos);
+
+void       e_memos_open_memo         (EMemos		*memos);
+void       e_memos_new_memo          (EMemos            *memos);
+void       e_memos_complete_selected (EMemos            *memos);
+void       e_memos_delete_selected   (EMemos            *memos);
+
+
+void e_memos_setup_view_menus (EMemos *memos, BonoboUIComponent *uic);
+void e_memos_discard_view_menus (EMemos *memos);
+
+EMemoTable *e_memos_get_calendar_table (EMemos *memos);
+
+#endif /* _E_MEMOS_H_ */
Index: calendar/gui/memos-component.c
===================================================================
RCS file: calendar/gui/memos-component.c
diff -N calendar/gui/memos-component.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/memos-component.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,1330 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* memos-component.c
+ *
+ * Copyright (C) 2003  Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Rodrigo Moya <rodrigo@ximian.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <bonobo/bonobo-control.h>
+#include <bonobo/bonobo-i18n.h>
+#include <bonobo/bonobo-exception.h>
+#include <gconf/gconf-client.h>
+#include <libecal/e-cal.h>
+#include <libedataserverui/e-source-selector.h>
+#include <shell/e-user-creatable-items-handler.h>
+#include "e-cal-model.h"
+#include "e-memos.h"
+#include "memos-component.h"
+#include "memos-control.h"
+#include "e-comp-editor-registry.h"
+#include "migration.h"
+#include "comp-util.h"
+#include "calendar-config.h"
+#include "e-cal-popup.h"
+#include "common/authentication.h"
+#include "dialogs/calendar-setup.h"
+#include "dialogs/comp-editor.h"
+#include "dialogs/copy-source-dialog.h"
+#include "dialogs/memo-editor.h"
+#include "widgets/misc/e-info-label.h"
+#include "e-util/e-icon-factory.h"
+#include "e-util/e-error.h"
+#include "calendar-component.h"
+
+#define CREATE_MEMO_ID               "memo"
+#define CREATE_MEMO_LIST_ID          "memo-list"
+
+enum DndTargetType {
+	DND_TARGET_TYPE_CALENDAR_LIST,
+};
+#define CALENDAR_TYPE "text/calendar"
+#define XCALENDAR_TYPE "text/x-calendar"
+#define WEB_BASE_URI "webcal://"
+#define PERSONAL_RELATIVE_URI "system"
+
+static GtkTargetEntry drag_types[] = {
+	{ CALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST },
+	{ XCALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST }
+};
+static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]);
+
+#define PARENT_TYPE bonobo_object_get_type ()
+
+static BonoboObjectClass *parent_class = NULL;
+
+/* Memos should have their own registry */
+extern ECompEditorRegistry *comp_editor_registry;
+
+
+typedef struct _MemosComponentView
+{
+	ESourceList *source_list;
+	
+	GSList *source_selection;
+	
+	EMemos *memos;
+	ETable *table;
+	ETableModel *model;
+
+	EInfoLabel *info_label;
+	GtkWidget *source_selector;
+	
+	BonoboControl *view_control;
+	BonoboControl *sidebar_control;
+	BonoboControl *statusbar_control;
+
+	GList *notifications;
+
+	EUserCreatableItemsHandler *creatable_items_handler;
+
+	EActivityHandler *activity_handler;
+} MemosComponentView;
+
+struct _MemosComponentPrivate {
+	char *base_directory;
+	char *config_directory;
+
+	ESourceList *source_list;
+	GSList *source_selection;
+
+	GList *views;
+	
+	ECal *create_ecal;
+	
+	GList *notifications;
+};
+
+/* #define d(x) x */
+#define d(x)
+
+static void
+ensure_sources (MemosComponent *component)
+{
+	GSList *groups;
+	ESourceList *source_list;
+	ESourceGroup *group;
+	ESourceGroup *on_this_computer;
+	ESourceGroup *on_the_web;
+	ESource *personal_source;
+	char *base_uri, *base_uri_proto;
+
+	on_this_computer = NULL;
+	on_the_web = NULL;
+	personal_source = NULL;
+
+	if (!e_cal_get_sources (&source_list, E_CAL_SOURCE_TYPE_JOURNAL, NULL)) {
+		g_warning ("Could not get memo source list from GConf!");
+		return;
+	}
+
+	base_uri = g_build_filename (memos_component_peek_base_directory (component),
+				     "memos", "local",
+				     NULL);
+
+	base_uri_proto = g_strconcat ("file://", base_uri, NULL);
+
+	groups = e_source_list_peek_groups (source_list);
+	if (groups) {
+		/* groups are already there, we need to search for things... */
+		GSList *g;
+
+		for (g = groups; g; g = g->next) {
+
+			group = E_SOURCE_GROUP (g->data);
+
+			/* compare only file:// part. If user home dir name changes we do not want to create 
+			   one more group  */
+
+			if (!on_this_computer && !strncmp (base_uri_proto, e_source_group_peek_base_uri (group), 7))
+				on_this_computer = group;
+			else if (!on_the_web && !strcmp (WEB_BASE_URI, e_source_group_peek_base_uri (group)))
+				on_the_web = group;
+		}
+	}
+
+	if (on_this_computer) {
+		/* make sure "Personal" shows up as a source under
+		   this group */
+		GSList *sources = e_source_group_peek_sources (on_this_computer);
+		GSList *s;
+		for (s = sources; s; s = s->next) {
+			ESource *source = E_SOURCE (s->data);
+			if (!strcmp (PERSONAL_RELATIVE_URI, e_source_peek_relative_uri (source))) {
+				personal_source = source;
+				break;
+			}
+		}
+		/* Make sure we have the correct base uri. This can change when user's
+		   homedir name changes */
+		if (strcmp (base_uri_proto, e_source_group_peek_base_uri (on_this_computer))) {
+		    e_source_group_set_base_uri (on_this_computer, base_uri_proto);
+
+		    /* *sigh* . We shouldn't  need this sync call here as set_base_uri
+		       call results in synching to gconf, but that happens in idle loop
+		       and too late to prevent user seeing "Can not Open ... because of invalid uri" error.*/
+		    e_source_list_sync (source_list,NULL);
+		}
+	}
+	else {
+		/* create the local source group */
+		group = e_source_group_new (_("On This Computer"), base_uri_proto);
+		e_source_list_add_group (source_list, group, -1);
+
+		on_this_computer = group;
+	}
+
+	if (!personal_source) {
+		/* Create the default Person addressbook */
+		ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
+		e_source_group_add_source (on_this_computer, source, -1);
+
+		if (!calendar_config_get_primary_memos () && !calendar_config_get_memos_selected ()) {
+			GSList selected;
+
+			calendar_config_set_primary_memos (e_source_peek_uid (source));
+
+			selected.data = (gpointer)e_source_peek_uid (source);
+			selected.next = NULL;
+			calendar_config_set_memos_selected (&selected);
+		}
+
+		e_source_set_color (source, 0xBECEDD);
+		personal_source = source;
+	}
+
+	if (!on_the_web) {
+		/* Create the LDAP source group */
+		group = e_source_group_new (_("On The Web"), WEB_BASE_URI);
+		e_source_list_add_group (source_list, group, -1);
+
+		on_the_web = group;
+	}
+
+	component->priv->source_list = source_list;
+	g_free (base_uri_proto);
+	g_free (base_uri);
+}
+
+/* Utility functions.  */
+/* FIXME Some of these are duplicated from calendar-component.c */
+static gboolean
+is_in_selection (GSList *selection, ESource *source)
+{
+	GSList *l;
+	
+	for (l = selection; l; l = l->next) {
+		ESource *selected_source = l->data;
+		
+		if (!strcmp (e_source_peek_uid (selected_source), e_source_peek_uid (source)))
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+is_in_uids (GSList *uids, ESource *source)
+{
+	GSList *l;
+	
+	for (l = uids; l; l = l->next) {
+		const char *uid = l->data;
+		
+		if (!strcmp (uid, e_source_peek_uid (source)))
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void
+update_uris_for_selection (MemosComponentView *component_view)
+{
+	GSList *selection, *l, *uids_selected = NULL;
+	
+	selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector));
+	
+	for (l = component_view->source_selection; l; l = l->next) {
+		ESource *old_selected_source = l->data;
+
+		if (!is_in_selection (selection, old_selected_source))
+			e_memos_remove_memo_source (component_view->memos, old_selected_source);
+	}	
+	
+	for (l = selection; l; l = l->next) {
+		ESource *selected_source = l->data;
+		
+		e_memos_add_memo_source (component_view->memos, selected_source);
+		uids_selected = g_slist_append (uids_selected, (char *)e_source_peek_uid (selected_source));
+	}
+
+	e_source_selector_free_selection (component_view->source_selection);
+	component_view->source_selection = selection;
+
+	/* Save the selection for next time we start up */
+	calendar_config_set_memos_selected (uids_selected);
+	g_slist_free (uids_selected);
+}
+
+static void
+update_uri_for_primary_selection (MemosComponentView *component_view)
+{
+	ESource *source;
+	EMemoTable *cal_table;
+	ETable *etable;
+
+	source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
+	if (!source)
+		return;
+
+	/* Set the default */
+	e_memos_set_default_source (component_view->memos, source);
+
+	cal_table = e_memos_get_calendar_table (component_view->memos);
+	etable = e_memo_table_get_table (cal_table);
+
+	memos_control_sensitize_commands (component_view->view_control, component_view->memos, e_table_selected_count (etable));
+	
+	/* Save the selection for next time we start up */
+	calendar_config_set_primary_memos (e_source_peek_uid (source));
+}
+
+static void
+update_selection (MemosComponentView *component_view)
+{
+	GSList *selection, *uids_selected, *l;
+	
+	d(g_message("memos-component.c: update_selection called");)
+
+	/* Get the selection in gconf */
+	uids_selected = calendar_config_get_memos_selected ();
+
+	/* Remove any that aren't there any more */
+	selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector));
+
+	for (l = selection; l; l = l->next) {
+		ESource *source = l->data;
+
+		if (!is_in_uids (uids_selected, source)) 
+			e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
+	}
+	
+	e_source_selector_free_selection (selection);
+
+	/* Make sure the whole selection is there */
+	for (l = uids_selected; l; l = l->next) {
+		char *uid = l->data;
+		ESource *source;
+
+		source = e_source_list_peek_source_by_uid (component_view->source_list, uid);
+		if (source) 
+			e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
+		
+		g_free (uid);
+	}
+	g_slist_free (uids_selected);
+}
+
+static void
+update_primary_selection (MemosComponentView *component_view)
+{
+	ESource *source = NULL;
+	char *uid;
+
+	uid = calendar_config_get_primary_memos ();
+	if (uid) {
+		source = e_source_list_peek_source_by_uid (component_view->source_list, uid);
+		g_free (uid);
+	}
+	
+	if (source) {
+		e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source);
+	} else {
+		/* Try to create a default if there isn't one */
+		source = e_source_list_peek_source_any (component_view->source_list);
+		if (source)
+			e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source);
+	}
+
+}
+
+
+/* Callbacks.  */
+/* TODO: doesn't work! */
+static void
+copy_memo_list_cb (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	MemosComponentView *component_view = data;
+	ESource *selected_source;
+	
+	selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
+	if (!selected_source)
+		return;
+
+	copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source, E_CAL_SOURCE_TYPE_JOURNAL);
+}
+
+static void
+delete_memo_list_cb (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	MemosComponentView *component_view = data;
+	ESource *selected_source;
+	ECal *cal;
+	char *uri;
+
+	selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
+	if (!selected_source)
+		return;
+
+	if (e_error_run((GtkWindow *)gtk_widget_get_toplevel(ep->target->widget),
+			"calendar:prompt-delete-memo-list", e_source_peek_name(selected_source)) != GTK_RESPONSE_YES)
+		return;
+
+	/* first, ask the backend to remove the memo list */
+	uri = e_source_get_uri (selected_source);
+	cal = e_cal_model_get_client_for_uri (
+		e_memo_table_get_model (E_MEMO_TABLE (e_memos_get_calendar_table (component_view->memos))),
+		uri);
+	if (!cal)
+		cal = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_JOURNAL);
+	g_free (uri);
+	if (cal) {
+		if (e_cal_remove (cal, NULL)) {
+			if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (component_view->source_selector),
+								  selected_source)) {
+				e_memos_remove_memo_source (component_view->memos, selected_source);
+				e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector),
+								   selected_source);
+			}
+			
+			e_source_group_remove_source (e_source_peek_group (selected_source), selected_source);
+			e_source_list_sync (component_view->source_list, NULL);
+		}
+	}
+}
+
+static void
+new_memo_list_cb (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	calendar_setup_new_memo_list (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)));
+}
+
+static void
+edit_memo_list_cb (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	MemosComponentView *component_view = data;
+	ESource *selected_source;
+
+	selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
+	if (!selected_source)
+		return;
+
+	calendar_setup_edit_memo_list (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source);
+}
+
+static EPopupItem emc_source_popups[] = {
+	{ E_POPUP_ITEM, "10.new", N_("New Memo List"), new_memo_list_cb, NULL, "stock_notes", 0, 0 },
+	{ E_POPUP_ITEM, "15.copy", N_("Copy"), copy_memo_list_cb, NULL, "stock_folder-copy", 0, E_CAL_POPUP_SOURCE_PRIMARY },
+	{ E_POPUP_ITEM, "20.delete", N_("Delete"), delete_memo_list_cb, NULL, "stock_delete", 0, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY },
+	{ E_POPUP_ITEM, "30.properties", N_("Properties..."), edit_memo_list_cb, NULL, "stock_folder-properties", 0, E_CAL_POPUP_SOURCE_PRIMARY },
+};
+
+static void
+emc_source_popup_free(EPopup *ep, GSList *list, void *data)
+{
+	g_slist_free(list);
+}
+
+static gboolean
+popup_event_cb(ESourceSelector *selector, ESource *insource, GdkEventButton *event, MemosComponentView *component_view)
+{
+	ECalPopup *ep;
+	ECalPopupTargetSource *t;
+	GSList *menus = NULL;
+	int i;
+	GtkMenu *menu;
+
+	/** @HookPoint-ECalPopup: Memos Source Selector Context Menu
+	 * @Id: org.gnome.evolution.memos.source.popup
+	 * @Class: org.gnome.evolution.calendar.popup:1.0
+	 * @Target: ECalPopupTargetSource
+	 *
+	 * The context menu on the source selector in the memos window.
+	 */
+	ep = e_cal_popup_new("org.gnome.evolution.memos.source.popup");
+	t = e_cal_popup_target_new_source(ep, selector);
+	t->target.widget = (GtkWidget *)component_view->memos;
+
+	for (i=0;i<sizeof(emc_source_popups)/sizeof(emc_source_popups[0]);i++)
+		menus = g_slist_prepend(menus, &emc_source_popups[i]);
+
+	e_popup_add_items((EPopup *)ep, menus, NULL,emc_source_popup_free, component_view);
+
+	menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0);
+	gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time());
+
+	return TRUE;
+}
+
+static void
+source_selection_changed_cb (ESourceSelector *selector, MemosComponentView *component_view)
+{
+	update_uris_for_selection (component_view);
+}
+
+static void
+primary_source_selection_changed_cb (ESourceSelector *selector, MemosComponentView *component_view)
+{
+	update_uri_for_primary_selection (component_view);
+}
+
+static void
+source_added_cb (EMemos *memos, ESource *source, MemosComponentView *component_view)
+{
+	e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
+}
+
+static void
+source_removed_cb (EMemos *memos, ESource *source, MemosComponentView *component_view)
+{
+	e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source);
+}
+
+static void
+set_info (MemosComponentView *component_view)
+{
+	GString *message = g_string_new ("");
+	int rows, selected_rows;
+	
+	rows = e_table_model_row_count (component_view->model);
+	selected_rows =  e_table_selected_count (component_view->table);
+
+	g_string_append_printf(message, ngettext("%d memo", "%d memos", rows), rows);
+	if (selected_rows > 0)
+		g_string_append_printf(message, ngettext(", %d selected", ", %d selected", selected_rows), selected_rows);
+
+	e_info_label_set_info (component_view->info_label, _("Memos"), message->str);
+
+	g_string_free (message, TRUE);
+}
+
+static void
+table_selection_change_cb (ETableModel *etm, MemosComponentView *component_view)
+{
+	set_info (component_view);
+}
+
+static void
+model_changed_cb (ETableModel *etm, MemosComponentView *component_view)
+{
+	set_info (component_view);
+}
+
+static void
+model_rows_inserted_cb (ETableModel *etm, int row, int count, MemosComponentView *component_view)
+{
+	set_info (component_view);
+}
+
+static void
+model_rows_deleted_cb (ETableModel *etm, int row, int count, MemosComponentView *component_view)
+{
+	set_info (component_view);
+}
+
+/* Evolution::Component CORBA methods */
+
+static void
+impl_upgradeFromVersion (PortableServer_Servant servant,
+			 CORBA_short major,
+			 CORBA_short minor,
+			 CORBA_short revision,
+			 CORBA_Environment *ev)
+{
+	GError *err = NULL;
+	MemosComponent *component = MEMOS_COMPONENT (bonobo_object_from_servant (servant));
+
+	if (!migrate_memos(component, major, minor, revision, &err)) {
+		GNOME_Evolution_Component_UpgradeFailed *failedex;
+
+		failedex = GNOME_Evolution_Component_UpgradeFailed__alloc();
+		failedex->what = CORBA_string_dup(_("Failed upgrading memos."));
+		failedex->why = CORBA_string_dup(err->message);
+		CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex);
+	}
+
+	if (err)
+		g_error_free(err);
+}
+
+static gboolean
+selector_tree_drag_drop (GtkWidget *widget, 
+			 GdkDragContext *context, 
+			 int x, 
+			 int y, 
+			 guint time, 
+			 CalendarComponent *component)
+{
+	GtkTreeViewColumn *column;
+	int cell_x;
+	int cell_y;
+	GtkTreePath *path;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gpointer data;
+	
+	if (!gtk_tree_view_get_path_at_pos  (GTK_TREE_VIEW (widget), x, y, &path, 
+					     &column, &cell_x, &cell_y))
+		return FALSE;
+	
+	
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+
+	if (!gtk_tree_model_get_iter (model, &iter, path)) {
+		gtk_tree_path_free (path);
+		return FALSE;
+	}
+
+	gtk_tree_model_get (model, &iter, 0, &data, -1);
+	
+	if (E_IS_SOURCE_GROUP (data)) {
+		g_object_unref (data);
+		gtk_tree_path_free (path);
+		return FALSE;
+	}
+	
+	gtk_tree_path_free (path);
+	return TRUE;
+}
+	
+static gboolean
+selector_tree_drag_motion (GtkWidget *widget,
+			   GdkDragContext *context,
+			   int x,
+			   int y,
+			   guint time,
+			   gpointer user_data)
+{
+	GtkTreePath *path = NULL;
+	gpointer data = NULL;
+	GtkTreeViewDropPosition pos;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GdkDragAction action = GDK_ACTION_DEFAULT;
+	
+	if (!gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget),
+						x, y, &path, &pos))
+		goto finish;
+	
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+	
+	if (!gtk_tree_model_get_iter (model, &iter, path))
+		goto finish;
+	
+	gtk_tree_model_get (model, &iter, 0, &data, -1);
+
+	if (E_IS_SOURCE_GROUP (data) || e_source_get_readonly (data))
+		goto finish;
+	
+	gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW (widget), path, GTK_TREE_VIEW_DROP_INTO_OR_BEFORE);
+	action = context->suggested_action;
+
+ finish:
+	if (path)
+		gtk_tree_path_free (path);
+	if (data)
+		g_object_unref (data);
+
+	gdk_drag_status (context, action, time);
+	return TRUE;
+}
+
+static gboolean
+update_single_object (ECal *client, icalcomponent *icalcomp)
+{
+	char *uid;
+	icalcomponent *tmp_icalcomp;
+
+	d(g_message("memos-component.c: update_single_object called");)
+
+	uid = (char *) icalcomponent_get_uid (icalcomp);
+	
+	if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, NULL))
+		return e_cal_modify_object (client, icalcomp, CALOBJ_MOD_ALL, NULL);
+
+	return e_cal_create_object (client, icalcomp, &uid, NULL);	
+}
+
+static gboolean
+update_objects (ECal *client, icalcomponent *icalcomp)
+{
+	icalcomponent *subcomp;
+	icalcomponent_kind kind;
+	
+	d(g_message("memos-component.c: update_objects called");)
+
+	kind = icalcomponent_isa (icalcomp);
+	if (kind == ICAL_VJOURNAL_COMPONENT)
+		return update_single_object (client, icalcomp);
+	else if (kind != ICAL_VCALENDAR_COMPONENT)
+		return FALSE;
+
+	subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT);
+	while (subcomp) {
+		gboolean success;
+		
+		kind = icalcomponent_isa (subcomp);
+		if (kind == ICAL_VTIMEZONE_COMPONENT) {
+			icaltimezone *zone;
+
+			zone = icaltimezone_new ();
+			icaltimezone_set_component (zone, subcomp);
+
+			success = e_cal_add_timezone (client, zone, NULL);
+			icaltimezone_free (zone, 1);
+			if (!success)
+				return success;
+		} else if (kind == ICAL_VJOURNAL_COMPONENT) {
+			success = update_single_object (client, subcomp);
+			if (!success)
+				return success;
+		}
+
+		subcomp = icalcomponent_get_next_component (icalcomp, ICAL_ANY_COMPONENT);
+	}
+
+	return TRUE;
+}
+
+static void
+selector_tree_drag_data_received (GtkWidget *widget, 
+				  GdkDragContext *context, 
+				  gint x, 
+				  gint y, 
+				  GtkSelectionData *data,
+				  guint info,
+				  guint time,
+				  gpointer user_data)
+{
+	GtkTreePath *path = NULL;
+	GtkTreeViewDropPosition pos;
+	gpointer source = NULL;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean success = FALSE;
+	icalcomponent *icalcomp = NULL;
+	ECal *client = NULL;
+
+	if (!gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget),
+						x, y, &path, &pos))
+		goto finish;
+	
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+	
+	if (!gtk_tree_model_get_iter (model, &iter, path))
+		goto finish;
+       
+	
+	gtk_tree_model_get (model, &iter, 0, &source, -1);
+
+	if (E_IS_SOURCE_GROUP (source) || e_source_get_readonly (source))
+		goto finish;
+
+	icalcomp = icalparser_parse_string (data->data);
+	
+	if (icalcomp) {
+		char * uid;
+
+		/* FIXME deal with GDK_ACTION_ASK */
+		if (context->action == GDK_ACTION_COPY) {
+			uid = e_cal_component_gen_uid ();
+			icalcomponent_set_uid (icalcomp, uid);
+		}
+
+		client = auth_new_cal_from_source (source, 
+						   E_CAL_SOURCE_TYPE_JOURNAL);
+		
+		if (client) {
+			if (e_cal_open (client, TRUE, NULL)) {
+				success = TRUE;
+				update_objects (client, icalcomp);
+			}
+			
+			g_object_unref (client);
+		}
+		
+		icalcomponent_free (icalcomp);
+	}
+
+ finish:
+	if (source)
+		g_object_unref (source);
+	if (path)
+		gtk_tree_path_free (path);
+
+	gtk_drag_finish (context, success, context->action == GDK_ACTION_MOVE, time);
+}	
+
+static void
+selector_tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, gpointer data)
+{
+	gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW (widget), 
+					NULL, GTK_TREE_VIEW_DROP_BEFORE);
+}
+
+
+static void
+control_activate_cb (BonoboControl *control, gboolean activate, gpointer data)
+{
+	MemosComponentView *component_view = data;
+
+	if (activate) {
+		BonoboUIComponent *uic;
+		uic = bonobo_control_get_ui_component (component_view->view_control);
+		
+		e_user_creatable_items_handler_activate (component_view->creatable_items_handler, uic);
+	}	
+}
+
+static void
+config_create_ecal_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{	
+	MemosComponent *component = data;
+	MemosComponentPrivate *priv;
+	
+	priv = component->priv;
+
+	g_object_unref (priv->create_ecal);
+	priv->create_ecal = NULL;
+	
+	priv->notifications = g_list_remove (priv->notifications, GUINT_TO_POINTER (id));
+}
+
+static ECal *
+setup_create_ecal (MemosComponent *component, MemosComponentView *component_view) 
+{
+	MemosComponentPrivate *priv;
+	ESource *source = NULL;
+	char *uid;
+	guint not;
+	
+	priv = component->priv;
+
+	if (component_view) {
+		ECal *default_ecal;
+
+		default_ecal = e_memos_get_default_client (component_view->memos);
+		if (default_ecal)
+			return default_ecal;
+	}
+	
+	if (priv->create_ecal)
+		return priv->create_ecal; 
+	
+	/* Get the current primary calendar, or try to set one if it doesn't already exist */
+	uid = calendar_config_get_primary_memos ();
+	if (uid) {
+		source = e_source_list_peek_source_by_uid (priv->source_list, uid);
+		g_free (uid);
+
+		priv->create_ecal = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
+	}
+
+	if (!priv->create_ecal) {
+		/* Try to create a default if there isn't one */
+		source = e_source_list_peek_source_any (priv->source_list);
+		if (source)
+			priv->create_ecal = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
+	}
+		
+	if (priv->create_ecal) {
+
+		if (!e_cal_open (priv->create_ecal, FALSE, NULL)) {
+			GtkWidget *dialog;
+			
+			dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+							 GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
+							 _("Unable to open the memo list '%s' for creating events and meetings"), 
+							   e_source_peek_name (source));
+			gtk_dialog_run (GTK_DIALOG (dialog));
+			gtk_widget_destroy (dialog);
+
+			return NULL;
+		}
+
+	} else {
+		GtkWidget *dialog;
+			
+		dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+						 GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
+						 _("There is no calendar available for creating memos"));
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+
+		return NULL;
+	}		
+
+	/* Handle the fact it may change on us */
+	not = calendar_config_add_notification_primary_memos (config_create_ecal_changed_cb, 
+							      component);
+	priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
+
+	/* Save the primary source for use elsewhere */
+	calendar_config_set_primary_memos (e_source_peek_uid (source));
+
+	return priv->create_ecal ;
+}
+
+static gboolean
+create_new_memo (MemosComponent *memo_component, gboolean is_assigned, MemosComponentView *component_view)
+{
+	ECal *ecal;
+	MemosComponentPrivate *priv;
+	ECalComponent *comp;
+	MemoEditor *editor;
+	
+	priv = memo_component->priv;
+	
+	ecal = setup_create_ecal (memo_component, component_view);
+	if (!ecal)
+		return FALSE;
+
+	editor = memo_editor_new (ecal);
+	comp = cal_comp_memo_new_with_defaults (ecal);
+
+	comp_editor_edit_comp (COMP_EDITOR (editor), comp);
+	comp_editor_focus (COMP_EDITOR (editor));
+
+	e_comp_editor_registry_add (comp_editor_registry, COMP_EDITOR (editor), TRUE);
+
+	return TRUE;
+}
+
+static void
+create_local_item_cb (EUserCreatableItemsHandler *handler, const char *item_type_name, void *data)
+{
+	MemosComponent *memos_component = data;
+	MemosComponentPrivate *priv;
+	MemosComponentView *component_view = NULL;
+	GList *l;
+	
+	priv = memos_component->priv;
+	
+	for (l = priv->views; l; l = l->next) {
+		component_view = l->data;
+
+		if (component_view->creatable_items_handler == handler)
+			break;
+		
+		component_view = NULL;
+	}
+	
+	if (strcmp (item_type_name, CREATE_MEMO_ID) == 0) {
+		create_new_memo (memos_component, FALSE, component_view);
+	}
+	else if (strcmp (item_type_name, CREATE_MEMO_LIST_ID) == 0) {
+		calendar_setup_new_memo_list (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (component_view->memos))));
+	}
+}
+
+static MemosComponentView *
+create_component_view (MemosComponent *memos_component)
+{
+	MemosComponentPrivate *priv;
+	MemosComponentView *component_view;
+	GtkWidget *selector_scrolled_window, *vbox;
+	GtkWidget *statusbar_widget;
+	AtkObject *a11y;
+	
+	priv = memos_component->priv;
+
+	/* Create the calendar component view */
+	component_view = g_new0 (MemosComponentView, 1);
+	
+	/* Add the source lists */
+	component_view->source_list = g_object_ref (priv->source_list);
+	
+	/* Create sidebar selector */
+	component_view->source_selector = e_source_selector_new (memos_component->priv->source_list);
+	e_source_selector_set_select_new ((ESourceSelector *)component_view->source_selector, TRUE);
+	a11y = gtk_widget_get_accessible (GTK_WIDGET (component_view->source_selector));
+	atk_object_set_name (a11y, _("Memo Source Selector"));
+
+	g_signal_connect (component_view->source_selector, "drag-motion", G_CALLBACK (selector_tree_drag_motion), 
+			  memos_component);
+	g_signal_connect (component_view->source_selector, "drag-leave", G_CALLBACK (selector_tree_drag_leave), 
+			  memos_component);
+	g_signal_connect (component_view->source_selector, "drag-drop", G_CALLBACK (selector_tree_drag_drop), 
+			  memos_component);
+	g_signal_connect (component_view->source_selector, "drag-data-received", 
+			  G_CALLBACK (selector_tree_drag_data_received), memos_component);
+
+	gtk_drag_dest_set(component_view->source_selector, GTK_DEST_DEFAULT_ALL, drag_types,
+			  num_drag_types, GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
+	gtk_widget_show (component_view->source_selector);
+
+	selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+	gtk_container_add (GTK_CONTAINER (selector_scrolled_window), component_view->source_selector);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (selector_scrolled_window),
+					GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (selector_scrolled_window),
+					     GTK_SHADOW_IN);
+	gtk_widget_show (selector_scrolled_window);
+
+	component_view->info_label = (EInfoLabel *)e_info_label_new("stock_insert-note");
+	e_info_label_set_info(component_view->info_label, _("Memos"), "");
+	gtk_widget_show (GTK_WIDGET (component_view->info_label));
+
+	vbox = gtk_vbox_new(FALSE, 0);
+	gtk_box_pack_start(GTK_BOX (vbox), GTK_WIDGET (component_view->info_label), FALSE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX (vbox), selector_scrolled_window, TRUE, TRUE, 0);
+	gtk_widget_show (vbox);
+
+	component_view->sidebar_control = bonobo_control_new (vbox);
+
+	/* Create main view */
+	component_view->view_control = memos_control_new ();
+	if (!component_view->view_control) {
+		/* FIXME free memory */
+
+		return NULL;
+	}
+
+	component_view->memos = (EMemos *) bonobo_control_get_widget (component_view->view_control);
+	component_view->table = e_memo_table_get_table (e_memos_get_calendar_table (component_view->memos));
+	component_view->model = E_TABLE_MODEL (e_memo_table_get_model (e_memos_get_calendar_table (component_view->memos)));
+
+	/* This signal is thrown if backends die - we update the selector */
+	g_signal_connect (component_view->memos, "source_added", 
+			  G_CALLBACK (source_added_cb), component_view);
+	g_signal_connect (component_view->memos, "source_removed", 
+			  G_CALLBACK (source_removed_cb), component_view);
+
+	/* Create status bar */
+	statusbar_widget = e_task_bar_new ();
+	component_view->activity_handler = e_activity_handler_new ();
+	e_activity_handler_attach_task_bar (component_view->activity_handler, E_TASK_BAR (statusbar_widget));
+	gtk_widget_show (statusbar_widget);
+
+	component_view->statusbar_control = bonobo_control_new (statusbar_widget);
+	
+	e_memo_table_set_activity_handler (e_memos_get_calendar_table (component_view->memos), component_view->activity_handler);
+	
+	/* connect after setting the initial selections, or we'll get unwanted calls
+	   to calendar_control_sensitize_calendar_commands */
+	g_signal_connect (component_view->source_selector, "selection_changed",
+			  G_CALLBACK (source_selection_changed_cb), component_view);
+	g_signal_connect (component_view->source_selector, "primary_selection_changed",
+			  G_CALLBACK (primary_source_selection_changed_cb), component_view);
+	g_signal_connect (component_view->source_selector, "popup_event",
+			  G_CALLBACK (popup_event_cb), component_view);
+
+	/* Set up the "new" item handler */
+	component_view->creatable_items_handler = e_user_creatable_items_handler_new ("memos", create_local_item_cb, memos_component);
+	g_signal_connect (component_view->view_control, "activate", G_CALLBACK (control_activate_cb), component_view);
+
+	/* We use this to update the component information */
+	set_info (component_view);
+	g_signal_connect (component_view->table, "selection_change",
+			  G_CALLBACK (table_selection_change_cb), component_view);
+	g_signal_connect (component_view->model, "model_changed", 
+			  G_CALLBACK (model_changed_cb), component_view);
+	g_signal_connect (component_view->model, "model_rows_inserted",
+			  G_CALLBACK (model_rows_inserted_cb), component_view);
+	g_signal_connect (component_view->model, "model_rows_deleted",
+			  G_CALLBACK (model_rows_deleted_cb), component_view);
+
+	/* Load the selection from the last run */
+	update_selection (component_view);	
+	update_primary_selection (component_view);
+
+	return component_view;
+}
+
+static void
+destroy_component_view (MemosComponentView *component_view)
+{	
+	GList *l;
+	
+	if (component_view->source_list)
+		g_object_unref (component_view->source_list);
+
+	if (component_view->source_selection)
+		e_source_selector_free_selection (component_view->source_selection);
+	
+	for (l = component_view->notifications; l; l = l->next)
+		calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
+	g_list_free (component_view->notifications);
+
+	if (component_view->creatable_items_handler)
+		g_object_unref (component_view->creatable_items_handler);
+
+	if (component_view->activity_handler)
+		g_object_unref (component_view->activity_handler);
+
+	g_free (component_view);
+}
+
+static void
+view_destroyed_cb (gpointer data, GObject *where_the_object_was)
+{
+	MemosComponent *memos_component = data;
+	MemosComponentPrivate *priv;
+	GList *l;
+	
+	priv = memos_component->priv;
+
+	for (l = priv->views; l; l = l->next) {
+		MemosComponentView *component_view = l->data;
+		
+		if (G_OBJECT (component_view->view_control) == where_the_object_was) {
+			priv->views = g_list_remove (priv->views, component_view);
+			destroy_component_view (component_view);
+
+			break;
+		}
+	}
+}
+
+static void
+impl_createControls (PortableServer_Servant servant,
+		     Bonobo_Control *corba_sidebar_control,
+		     Bonobo_Control *corba_view_control,
+		     Bonobo_Control *corba_statusbar_control,
+		     CORBA_Environment *ev)
+{
+	MemosComponent *component = MEMOS_COMPONENT (bonobo_object_from_servant (servant));
+	MemosComponentPrivate *priv;
+	MemosComponentView *component_view;
+	
+	priv = component->priv;
+
+	/* Create the calendar component view */
+	component_view = create_component_view (component);
+	if (!component_view) {
+		/* FIXME Should we describe the problem in a control? */
+		bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
+
+		return;
+	}
+
+	g_object_weak_ref (G_OBJECT (component_view->view_control), view_destroyed_cb, component);
+	priv->views = g_list_append (priv->views, component_view);
+	
+	/* Return the controls */
+	*corba_sidebar_control = CORBA_Object_duplicate (BONOBO_OBJREF (component_view->sidebar_control), ev);
+	*corba_view_control = CORBA_Object_duplicate (BONOBO_OBJREF (component_view->view_control), ev);
+	*corba_statusbar_control = CORBA_Object_duplicate (BONOBO_OBJREF (component_view->statusbar_control), ev);
+}
+
+static GNOME_Evolution_CreatableItemTypeList *
+impl__get_userCreatableItems (PortableServer_Servant servant,
+			      CORBA_Environment *ev)
+{
+	GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc ();
+
+	list->_length  = 2;
+	list->_maximum = list->_length;
+	list->_buffer  = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length);
+
+	CORBA_sequence_set_release (list, FALSE);
+
+	list->_buffer[0].id = CREATE_MEMO_ID;
+	list->_buffer[0].description = _("New memo");
+	list->_buffer[0].menuDescription = _("_Memo");
+	list->_buffer[0].tooltip = _("Create a new memo");
+	list->_buffer[0].menuShortcut = 'o';
+	list->_buffer[0].iconName = "stock_insert-note";
+	list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
+
+	list->_buffer[1].id = CREATE_MEMO_LIST_ID;
+	list->_buffer[1].description = _("New memo list");
+	list->_buffer[1].menuDescription = _("Memo l_ist");
+	list->_buffer[1].tooltip = _("Create a new memo list");
+	list->_buffer[1].menuShortcut = 'i';
+	list->_buffer[1].iconName = "stock_notes";
+	list->_buffer[1].type = GNOME_Evolution_CREATABLE_FOLDER;
+
+	return list;
+}
+
+static void
+impl_requestCreateItem (PortableServer_Servant servant,
+			const CORBA_char *item_type_name,
+			CORBA_Environment *ev)
+{
+	MemosComponent *memos_component = MEMOS_COMPONENT (bonobo_object_from_servant (servant));
+	MemosComponentPrivate *priv;
+	
+	priv = memos_component->priv;	
+	
+	if (strcmp (item_type_name, CREATE_MEMO_ID) == 0) {
+		if (!create_new_memo (memos_component, FALSE, NULL))
+			bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
+	}
+	else if (strcmp (item_type_name, CREATE_MEMO_LIST_ID) == 0) {
+		/* FIXME Should we use the last opened window? */
+		calendar_setup_new_memo_list (NULL);
+	}
+	else {
+		bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType);
+	}
+}
+
+/* GObject methods.  */
+
+static void
+impl_dispose (GObject *object)
+{
+	MemosComponent *memos_component = MEMOS_COMPONENT (object);
+	MemosComponentPrivate *priv = memos_component->priv;
+	GList *l;
+	
+	if (priv->source_list != NULL) {
+		g_object_unref (priv->source_list);
+		priv->source_list = NULL;
+	}
+	if (priv->source_selection != NULL) {
+		e_source_selector_free_selection (priv->source_selection);
+		priv->source_selection = NULL;
+	}
+
+	if (priv->create_ecal) {
+		g_object_unref (priv->create_ecal);
+		priv->create_ecal = NULL;
+	}
+
+	for (l = priv->views; l; l = l->next) {
+		MemosComponentView *component_view = l->data;
+	
+		g_object_weak_unref (G_OBJECT (component_view->view_control), view_destroyed_cb, memos_component);
+	}
+	g_list_free (priv->views);
+	priv->views = NULL;
+
+	for (l = priv->notifications; l; l = l->next)
+		calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
+	g_list_free (priv->notifications);
+	priv->notifications = NULL;
+
+	(* G_OBJECT_CLASS (parent_class)->dispose) (object);
+}
+
+static void
+impl_finalize (GObject *object)
+{
+	MemosComponentPrivate *priv = MEMOS_COMPONENT (object)->priv;
+	GList *l;
+	
+	for (l = priv->views; l; l = l->next) {
+		MemosComponentView *component_view = l->data;
+		
+		destroy_component_view (component_view);
+	}
+	g_list_free (priv->views);
+
+	g_free (priv->base_directory);
+	g_free (priv->config_directory);
+	g_free (priv);
+
+	(* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+static void
+memos_component_class_init (MemosComponentClass *klass)
+{
+	POA_GNOME_Evolution_Component__epv *epv = &klass->epv;
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	epv->upgradeFromVersion      = impl_upgradeFromVersion;
+	epv->createControls          = impl_createControls;
+	epv->_get_userCreatableItems = impl__get_userCreatableItems;
+	epv->requestCreateItem       = impl_requestCreateItem;
+
+	object_class->dispose = impl_dispose;
+	object_class->finalize = impl_finalize;
+}
+
+static void
+memos_component_init (MemosComponent *component, MemosComponentClass *klass)
+{
+	MemosComponentPrivate *priv;
+
+	priv = g_new0 (MemosComponentPrivate, 1);
+	
+	printf("priv (MemosComponentnPrivate) == %p\n", priv);
+
+	priv->base_directory = g_build_filename (g_get_home_dir (), ".evolution", NULL);
+	priv->config_directory = g_build_filename (g_get_home_dir (),
+						   ".evolution", "memos", "config",
+						   NULL);
+
+	component->priv = priv;
+	ensure_sources (component);
+}
+
+/* Public API */
+
+MemosComponent *
+memos_component_peek (void)
+{
+	static MemosComponent *component = NULL;
+
+	if (component == NULL) {
+		component = g_object_new (memos_component_get_type (), NULL);
+
+		if (e_mkdir_hier (component->priv->config_directory, 0777) != 0) {
+			g_warning (G_STRLOC ": Cannot create directory %s: %s",
+				   component->priv->config_directory, g_strerror (errno));
+			g_object_unref (component);
+			component = NULL;
+		}
+	}
+
+	return component;
+}
+
+const char *
+memos_component_peek_base_directory (MemosComponent *component)
+{
+	return component->priv->base_directory;
+}
+
+const char *
+memos_component_peek_config_directory (MemosComponent *component)
+{
+	return component->priv->config_directory;
+}
+
+ESourceList *
+memos_component_peek_source_list (MemosComponent *component)
+{
+	return component->priv->source_list;	
+}
+
+BONOBO_TYPE_FUNC_FULL (MemosComponent, GNOME_Evolution_Component, PARENT_TYPE, memos_component)
Index: calendar/gui/memos-component.h
===================================================================
RCS file: calendar/gui/memos-component.h
diff -N calendar/gui/memos-component.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/memos-component.h	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,64 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* memos-component.h
+ *
+ * Copyright (C) 2003  Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Rodrigo Moya <rodrigo@ximian.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ */
+
+#ifndef _MEMOS_COMPONENT_H_
+#define _MEMOS_COMPONENT_H_
+
+#include <bonobo/bonobo-object.h>
+#include <libedataserver/e-source-list.h>
+#include <widgets/misc/e-activity-handler.h>
+#include "Evolution.h"
+
+
+#define MEMOS_TYPE_COMPONENT			(memos_component_get_type ())
+#define MEMOS_COMPONENT(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), MEMOS_TYPE_COMPONENT, MemosComponent))
+#define MEMOS_COMPONENT_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), MEMOS_TYPE_COMPONENT, MemosComponentClass))
+#define MEMOS_IS_COMPONENT(obj)			(G_TYPE_CHECK_INSTANCE_TYPE ((obj), MEMOS_TYPE_COMPONENT))
+#define MEMOS_IS_COMPONENT_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE ((obj), MEMOS_TYPE_COMPONENT))
+
+
+typedef struct _MemosComponent        MemosComponent;
+typedef struct _MemosComponentPrivate MemosComponentPrivate;
+typedef struct _MemosComponentClass   MemosComponentClass;
+
+struct _MemosComponent {
+	BonoboObject parent;
+
+	MemosComponentPrivate *priv;
+};
+
+struct _MemosComponentClass {
+	BonoboObjectClass parent_class;
+
+	POA_GNOME_Evolution_Component__epv epv;
+};
+
+
+GType             memos_component_get_type  (void);
+MemosComponent   *memos_component_peek  (void);
+
+const char       *memos_component_peek_base_directory (MemosComponent *component);
+const char       *memos_component_peek_config_directory (MemosComponent *component);
+ESourceList      *memos_component_peek_source_list (MemosComponent *component);
+
+#endif /* _MEMOS_COMPONENT_H_ */
Index: calendar/gui/memos-control.c
===================================================================
RCS file: calendar/gui/memos-control.c
diff -N calendar/gui/memos-control.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/memos-control.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,361 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* memos-control.c
+ *
+ * Copyright (C) 2000, 2001, 2002, 2003  Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Damon Chaplin <damon@ximian.com>
+ *	    Ettore Perazzoli
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtksignal.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkcheckbutton.h>
+#include <gtk/gtkmessagedialog.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-util.h>
+#include <libgnomeui/gnome-dialog.h>
+#include <libgnomeui/gnome-dialog-util.h>
+#include <libgnomeui/gnome-stock-icons.h>
+#include <libgnomeprint/gnome-print.h>
+#include <libgnomeprint/gnome-print-paper.h>
+#include <libgnomeprint/gnome-print-job.h>
+#include <libgnomeprintui/gnome-print-job-preview.h>
+#include <libgnomeprintui/gnome-print-paper-selector.h>
+#include <libgnomeprintui/gnome-print-preview.h>
+#include <libgnomeprintui/gnome-print-dialog.h>
+#include <bonobo/bonobo-control.h>
+#include <bonobo/bonobo-ui-util.h>
+#include <e-util/e-dialog-utils.h>
+#include <e-util/e-print.h>
+
+#include "calendar-config.h"
+#include "e-memos.h"
+#include "e-memo-table.h"
+#include "print.h"
+#include "memos-control.h"
+#include "evolution-shell-component-utils.h"
+
+#define FIXED_MARGIN                            .05
+
+
+static void memos_control_activate_cb		(BonoboControl		*control,
+						 gboolean		 activate,
+						 gpointer		 user_data);
+static void memos_control_open_memo_cmd		(BonoboUIComponent	*uic,
+						 gpointer		 data,
+						 const char		*path);
+static void memos_control_new_memo_cmd		(BonoboUIComponent	*uic,
+						 gpointer		 data,
+						 const char		*path);
+static void memos_control_cut_cmd               (BonoboUIComponent      *uic,
+						 gpointer                data,
+						 const gchar            *path);
+static void memos_control_copy_cmd              (BonoboUIComponent      *uic,
+						 gpointer                data,
+						 const gchar            *path);
+static void memos_control_paste_cmd             (BonoboUIComponent      *uic,
+						 gpointer                data,
+						 const gchar            *path);
+static void memos_control_delete_cmd		(BonoboUIComponent	*uic,
+						 gpointer		 data,
+						 const char		*path);
+static void memos_control_print_cmd		(BonoboUIComponent	*uic,
+						 gpointer		 data,
+						 const char		*path);
+static void memos_control_print_preview_cmd	(BonoboUIComponent	*uic,
+						 gpointer		 data,
+						 const char		*path);
+
+
+
+BonoboControl *
+memos_control_new (void)
+{
+	BonoboControl *control;
+	GtkWidget *memos;
+
+	memos = e_memos_new ();
+	if (!memos)
+		return NULL;
+	gtk_widget_show (memos);
+
+	control = bonobo_control_new (memos);
+	if (!control) {
+		gtk_widget_destroy (memos);
+		g_message ("control_factory_fn(): could not create the control!");
+		return NULL;
+	}
+
+	g_signal_connect (control, "activate", G_CALLBACK (memos_control_activate_cb), memos);
+
+	return control;
+}
+
+
+static void
+memos_control_activate_cb		(BonoboControl		*control,
+					 gboolean		 activate,
+					 gpointer		 user_data)
+{
+	EMemos *memos;
+
+	memos = E_MEMOS (user_data);
+
+	if (activate)
+		memos_control_activate (control, memos);
+	else
+		memos_control_deactivate (control, memos);
+}
+
+/* Sensitizes the UI Component menu/toolbar commands based on the number of
+ * selected memos.
+ */
+void
+memos_control_sensitize_commands (BonoboControl *control, EMemos *memos, int n_selected)
+{
+	BonoboUIComponent *uic;
+	gboolean read_only = TRUE;
+	ECal *ecal;
+	ECalModel *model;
+
+	uic = bonobo_control_get_ui_component (control);
+	g_assert (uic != NULL);
+
+	if (bonobo_ui_component_get_container (uic) == CORBA_OBJECT_NIL)
+		return;
+
+	model = e_memo_table_get_model (e_memos_get_calendar_table (memos));
+	ecal = e_cal_model_get_default_client (model);
+	if (ecal)
+		e_cal_is_read_only (ecal, &read_only, NULL);
+
+	bonobo_ui_component_set_prop (uic, "/commands/MemosOpenMemo", "sensitive",
+				      n_selected != 1 ? "0" : "1",
+				      NULL);
+	bonobo_ui_component_set_prop (uic, "/commands/MemosCut", "sensitive",
+				      n_selected == 0 || read_only ? "0" : "1",
+				      NULL);
+	bonobo_ui_component_set_prop (uic, "/commands/MemosCopy", "sensitive",
+				      n_selected == 0 ? "0" : "1",
+				      NULL);
+	bonobo_ui_component_set_prop (uic, "/commands/MemosPaste", "sensitive",
+				      read_only ? "0" : "1",
+				      NULL);
+	bonobo_ui_component_set_prop (uic, "/commands/MemosDelete", "sensitive",
+				      n_selected == 0 || read_only ? "0" : "1",
+				      NULL);
+}
+
+/* Callback used when the selection in the table changes */
+static void
+selection_changed_cb (EMemos *memos, int n_selected, gpointer data)
+{
+	BonoboControl *control;
+
+	control = BONOBO_CONTROL (data);
+
+	memos_control_sensitize_commands (control, memos, n_selected);
+}
+
+static BonoboUIVerb verbs [] = {
+	BONOBO_UI_VERB ("MemosOpenMemo", memos_control_open_memo_cmd),
+	BONOBO_UI_VERB ("MemosNewMemo", memos_control_new_memo_cmd),
+	BONOBO_UI_VERB ("MemosCut", memos_control_cut_cmd),
+	BONOBO_UI_VERB ("MemosCopy", memos_control_copy_cmd),
+	BONOBO_UI_VERB ("MemosPaste", memos_control_paste_cmd),
+	BONOBO_UI_VERB ("MemosDelete", memos_control_delete_cmd),
+	BONOBO_UI_VERB ("MemosPrint", memos_control_print_cmd),
+	BONOBO_UI_VERB ("MemosPrintPreview", memos_control_print_preview_cmd),
+
+	BONOBO_UI_VERB_END
+};
+
+void
+memos_control_activate (BonoboControl *control, EMemos *memos)
+{
+	Bonobo_UIContainer remote_uih;
+	BonoboUIComponent *uic;
+	int n_selected;
+	EMemoTable *cal_table;
+	ETable *etable;
+
+	uic = bonobo_control_get_ui_component (control);
+	g_assert (uic != NULL);
+
+	remote_uih = bonobo_control_get_remote_ui_container (control, NULL);
+	bonobo_ui_component_set_container (uic, remote_uih, NULL);
+	bonobo_object_release_unref (remote_uih, NULL);
+
+	e_memos_set_ui_component (memos, uic);
+
+	bonobo_ui_component_add_verb_list_with_data (uic, verbs, memos);
+
+	bonobo_ui_component_freeze (uic, NULL);
+
+	bonobo_ui_util_set_ui (uic, PREFIX,
+			       EVOLUTION_UIDIR "/evolution-memos.xml",
+			       "evolution-memos",
+			       NULL);
+
+	e_memos_setup_view_menus (memos, uic);
+
+	/* Signals from the memos widget; also sensitize the menu items as appropriate */
+
+	g_signal_connect (memos, "selection_changed", G_CALLBACK (selection_changed_cb), control);
+
+	cal_table = e_memos_get_calendar_table (memos);
+	etable = e_memo_table_get_table (cal_table);
+	n_selected = e_table_selected_count (etable);
+
+	memos_control_sensitize_commands (control, memos, n_selected);
+
+	bonobo_ui_component_thaw (uic, NULL);
+}
+
+
+void
+memos_control_deactivate (BonoboControl *control, EMemos *memos)
+{
+	BonoboUIComponent *uic = bonobo_control_get_ui_component (control);
+
+	g_assert (uic != NULL);
+
+	e_memos_set_ui_component (memos, NULL);
+
+	e_memos_discard_view_menus (memos);
+
+	/* Stop monitoring the "selection_changed" signal */
+	g_signal_handlers_disconnect_matched (memos, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, control);
+
+	bonobo_ui_component_rm (uic, "/", NULL);
+ 	bonobo_ui_component_unset_container (uic, NULL);
+}
+
+static void memos_control_open_memo_cmd		(BonoboUIComponent	*uic,
+						 gpointer		 data,
+						 const char		*path)
+{
+	EMemos *memos;
+
+	memos = E_MEMOS (data);
+	e_memos_open_memo (memos);
+}
+
+static void
+memos_control_new_memo_cmd		(BonoboUIComponent	*uic,
+					 gpointer		 data,
+					 const char		*path)
+{
+	EMemos *memos;
+
+	memos = E_MEMOS (data);
+	e_memos_new_memo (memos);
+}
+
+static void
+memos_control_cut_cmd                   (BonoboUIComponent      *uic,
+					 gpointer                data,
+					 const char             *path)
+{
+	EMemos *memos;
+	EMemoTable *cal_table;
+
+	memos = E_MEMOS (data);
+	cal_table = e_memos_get_calendar_table (memos);
+	e_memo_table_cut_clipboard (cal_table);
+}
+
+static void
+memos_control_copy_cmd                  (BonoboUIComponent      *uic,
+					 gpointer                data,
+					 const char             *path)
+{
+	EMemos *memos;
+	EMemoTable *cal_table;
+
+	memos = E_MEMOS (data);
+	cal_table = e_memos_get_calendar_table (memos);
+	e_memo_table_copy_clipboard (cal_table);
+}
+
+static void
+memos_control_paste_cmd                 (BonoboUIComponent      *uic,
+					 gpointer                data,
+					 const char             *path)
+{
+	EMemos *memos;
+	EMemoTable *cal_table;
+
+	memos = E_MEMOS (data);
+	cal_table = e_memos_get_calendar_table (memos);
+	e_memo_table_paste_clipboard (cal_table);
+}
+
+static void
+memos_control_delete_cmd		(BonoboUIComponent	*uic,
+					 gpointer		 data,
+					 const char		*path)
+{
+	EMemos *memos;
+
+	memos = E_MEMOS (data);
+	e_memos_delete_selected (memos);
+}
+
+
+static void
+print_memos (EMemos *memos, gboolean preview)
+{
+	EMemoTable *cal_table;
+	ETable *etable;
+
+	cal_table = e_memos_get_calendar_table (memos);
+	etable = e_memo_table_get_table (E_MEMO_TABLE (cal_table));
+
+	print_table (etable, _("Print Memos"), _("Memos"), preview);
+}
+
+/* File/Print callback */
+static void
+memos_control_print_cmd (BonoboUIComponent *uic,
+			 gpointer data,
+			 const char *path)
+{
+	EMemos *memos;
+
+	memos = E_MEMOS (data);
+
+	print_memos (memos, FALSE);
+}
+
+static void
+memos_control_print_preview_cmd (BonoboUIComponent *uic,
+				 gpointer data,
+				 const char *path)
+{
+	EMemos *memos;
+
+	memos = E_MEMOS (data);
+
+	print_memos (memos, TRUE);
+}
+
Index: calendar/gui/memos-control.h
===================================================================
RCS file: calendar/gui/memos-control.h
diff -N calendar/gui/memos-control.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/memos-control.h	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,35 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* memos-control.h
+ *
+ * Copyright (C) 2000, 2001, 2002, 2003  Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Federico Mena Quintero <federico@ximian.com>
+ *	    Damon Chaplin <damon@ximian.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ */
+
+#ifndef _MEMOS_CONTROL_H_
+#define _MEMOS_CONTROL_H_
+
+#include "e-memos.h"
+
+BonoboControl *memos_control_new                (void);
+void           memos_control_activate           (BonoboControl *control, EMemos *memos);
+void           memos_control_deactivate         (BonoboControl *control, EMemos *memos);
+void           memos_control_sensitize_commands (BonoboControl *control, EMemos *memos, int n_selected);
+
+#endif /* _MEMOS_CONTROL_H_ */
Index: calendar/gui/dialogs/memo-editor.c
===================================================================
RCS file: calendar/gui/dialogs/memo-editor.c
diff -N calendar/gui/dialogs/memo-editor.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/dialogs/memo-editor.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,285 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Evolution calendar - Memo editor dialog
+ *
+ * Copyright (C) 2000 Ximian, Inc.
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Authors: Miguel de Icaza <miguel@ximian.com>
+ *          Federico Mena-Quintero <federico@ximian.com>
+ *          Seth Alves <alves@hungry.com>
+ *          JP Rosevear <jpr@ximian.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glade/glade.h>
+#include <libgnome/gnome-i18n.h>
+
+#include "memo-page.h"
+#include "cancel-comp.h"
+#include "memo-editor.h"
+
+struct _MemoEditorPrivate {
+	MemoPage *memo_page;
+	
+	gboolean updating;	
+};
+
+static void memo_editor_set_e_cal (CompEditor *editor, ECal *client);
+static void memo_editor_edit_comp (CompEditor *editor, ECalComponent *comp);
+static gboolean memo_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method);
+static void memo_editor_finalize (GObject *object);
+
+static void refresh_memo_cmd (GtkWidget *widget, gpointer data);
+static void cancel_memo_cmd (GtkWidget *widget, gpointer data);
+static void forward_cmd (GtkWidget *widget, gpointer data);
+
+static void model_row_change_insert_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);
+static void model_row_delete_cb (GtkTreeModel *model, GtkTreePath *path, gpointer data);
+
+G_DEFINE_TYPE (MemoEditor, memo_editor, TYPE_COMP_EDITOR);
+
+
+
+/**
+ * memo_editor_get_type:
+ *
+ * Registers the #MemoEditor class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the #MemoEditor class.
+ **/
+
+/* Class initialization function for the event editor */
+static void
+memo_editor_class_init (MemoEditorClass *klass)
+{
+	GObjectClass *object_class;
+	CompEditorClass *editor_class;
+
+	object_class = (GObjectClass *) klass;
+	editor_class = (CompEditorClass *) klass;
+
+	editor_class->set_e_cal = memo_editor_set_e_cal;
+	editor_class->edit_comp = memo_editor_edit_comp;
+	editor_class->send_comp = memo_editor_send_comp;
+
+	object_class->finalize = memo_editor_finalize;
+}
+
+static void
+init_widgets (MemoEditor *me)
+{
+	MemoEditorPrivate *priv;
+
+	priv = me->priv;
+}
+
+static void
+client_changed_cb (CompEditorPage *page, ECal *client, gpointer user_data)
+{
+/*	set_menu_sens (MEMO_EDITOR (user_data)); */
+}
+
+/* Object initialization function for the memo editor */
+static void
+memo_editor_init (MemoEditor *te)
+{
+	MemoEditorPrivate *priv;
+	
+	priv = g_new0 (MemoEditorPrivate, 1);
+	te->priv = priv;
+
+	priv->updating = FALSE;	
+
+	/* TODO add help stuff */
+/*	comp_editor_set_help_section (COMP_EDITOR (te), "usage-calendar-memo"); */
+}
+
+MemoEditor *
+memo_editor_construct (MemoEditor *me, ECal *client)
+{
+	MemoEditorPrivate *priv;
+	
+	gboolean read_only = FALSE;
+	
+	priv = me->priv;
+
+	priv->memo_page = memo_page_new ();
+	g_object_ref (priv->memo_page);
+	gtk_object_sink (GTK_OBJECT (priv->memo_page));
+	comp_editor_append_page (COMP_EDITOR (me), 
+				 COMP_EDITOR_PAGE (priv->memo_page),
+				 _("Memo"));
+	g_signal_connect (G_OBJECT (priv->memo_page), "client_changed",
+			  G_CALLBACK (client_changed_cb), me);
+
+	if (!e_cal_is_read_only (client, &read_only, NULL))
+		read_only = TRUE;
+
+	comp_editor_set_e_cal (COMP_EDITOR (me), client);
+
+	init_widgets (me);
+
+	return me;
+}
+
+static void
+memo_editor_set_e_cal (CompEditor *editor, ECal *client)
+{
+	MemoEditor *te;
+	MemoEditorPrivate *priv;
+
+	te = MEMO_EDITOR (editor);
+	priv = te->priv;
+
+	if (COMP_EDITOR_CLASS (memo_editor_parent_class)->set_e_cal)
+		COMP_EDITOR_CLASS (memo_editor_parent_class)->set_e_cal (editor, client);
+}
+
+static void
+memo_editor_edit_comp (CompEditor *editor, ECalComponent *comp)
+{
+	MemoEditor *me;
+	MemoEditorPrivate *priv;
+	ECalComponentOrganizer organizer;
+	ECal *client;
+	
+	me = MEMO_EDITOR (editor);
+	priv = me->priv;
+
+	priv->updating = TRUE;
+
+	if (COMP_EDITOR_CLASS (memo_editor_parent_class)->edit_comp)
+		COMP_EDITOR_CLASS (memo_editor_parent_class)->edit_comp (editor, comp);
+
+	client = comp_editor_get_e_cal (COMP_EDITOR (editor));
+
+	priv->updating = FALSE;
+}
+
+static gboolean
+memo_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method)
+{
+	MemoEditor *me = MEMO_EDITOR (editor);
+	MemoEditorPrivate *priv;
+	ECalComponent *comp = NULL;
+
+	priv = me->priv;
+
+	if (COMP_EDITOR_CLASS (memo_editor_parent_class)->send_comp)
+		return COMP_EDITOR_CLASS (memo_editor_parent_class)->send_comp (editor, method);
+
+	return FALSE;
+}
+
+/* Destroy handler for the event editor */
+static void
+memo_editor_finalize (GObject *object)
+{
+	MemoEditor *me;
+	MemoEditorPrivate *priv;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (IS_MEMO_EDITOR (object));
+
+	me = MEMO_EDITOR (object);
+	priv = me->priv;
+
+	if (priv->memo_page) {
+		g_object_unref (priv->memo_page);
+		priv->memo_page = NULL;
+	}
+	
+	g_free (priv);
+
+	if (G_OBJECT_CLASS (memo_editor_parent_class)->finalize)
+		(* G_OBJECT_CLASS (memo_editor_parent_class)->finalize) (object);
+}
+
+/**
+ * memo_editor_new:
+ * @client: an ECal
+ *
+ * Creates a new event editor dialog.
+ *
+ * Return value: A newly-created event editor dialog, or NULL if the event
+ * editor could not be created.
+ **/
+MemoEditor *
+memo_editor_new (ECal *client)
+{
+	MemoEditor *me;
+
+	me = g_object_new (TYPE_MEMO_EDITOR, NULL);
+	return memo_editor_construct (me, client);
+}
+
+static void
+refresh_memo_cmd (GtkWidget *widget, gpointer data)
+{
+	MemoEditor *me = MEMO_EDITOR (data);
+
+	comp_editor_send_comp (COMP_EDITOR (me), E_CAL_COMPONENT_METHOD_REFRESH);
+}
+
+static void
+cancel_memo_cmd (GtkWidget *widget, gpointer data)
+{
+	MemoEditor *me = MEMO_EDITOR (data);
+	ECalComponent *comp;
+	
+	comp = comp_editor_get_current_comp (COMP_EDITOR (me));
+	if (cancel_component_dialog ((GtkWindow *) me,
+				     comp_editor_get_e_cal (COMP_EDITOR (me)), comp, FALSE)) {
+		comp_editor_send_comp (COMP_EDITOR (me), E_CAL_COMPONENT_METHOD_CANCEL);
+		comp_editor_delete_comp (COMP_EDITOR (me));
+	}
+}
+
+static void
+forward_cmd (GtkWidget *widget, gpointer data)
+{
+	MemoEditor *me = MEMO_EDITOR (data);
+	
+	if (comp_editor_save_comp (COMP_EDITOR (me), TRUE))
+		comp_editor_send_comp (COMP_EDITOR (me), E_CAL_COMPONENT_METHOD_PUBLISH);
+}
+
+static void
+model_changed (MemoEditor *me)
+{
+	if (!me->priv->updating) {
+		comp_editor_set_changed (COMP_EDITOR (me), TRUE);
+		comp_editor_set_needs_send (COMP_EDITOR (me), TRUE);
+	}	
+}
+
+static void
+model_row_change_insert_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
+{
+	model_changed (MEMO_EDITOR (data));
+}
+
+static void
+model_row_delete_cb (GtkTreeModel *model, GtkTreePath *path, gpointer data)
+{
+	model_changed (MEMO_EDITOR (data));
+}
Index: calendar/gui/dialogs/memo-editor.h
===================================================================
RCS file: calendar/gui/dialogs/memo-editor.h
diff -N calendar/gui/dialogs/memo-editor.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/dialogs/memo-editor.h	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,59 @@
+/* Evolution calendar - Task editor dialog
+ *
+ * Copyright (C) 2000 Ximian, Inc.
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Authors: Miguel de Icaza <miguel@ximian.com>
+ *          Federico Mena-Quintero <federico@ximian.com>
+ *          Seth Alves <alves@hungry.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __MEMO_EDITOR_H__
+#define __MEMO_EDITOR_H__
+
+#include <gtk/gtkobject.h>
+#include "comp-editor.h"
+
+#define TYPE_MEMO_EDITOR            (memo_editor_get_type ())
+#define MEMO_EDITOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MEMO_EDITOR, MemoEditor))
+#define MEMO_EDITOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MEMO_EDITOR,	\
+				      MemoEditorClass))
+#define IS_MEMO_EDITOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MEMO_EDITOR))
+#define IS_MEMO_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MEMO_EDITOR))
+
+typedef struct _MemoEditor MemoEditor;
+typedef struct _MemoEditorClass MemoEditorClass;
+typedef struct _MemoEditorPrivate MemoEditorPrivate;
+
+struct _MemoEditor {
+	CompEditor parent;
+
+	/* Private data */
+	MemoEditorPrivate *priv;
+};
+
+struct _MemoEditorClass {
+	CompEditorClass parent_class;
+};
+
+GtkType     memo_editor_get_type       (void);
+MemoEditor *memo_editor_construct      (MemoEditor *te,
+					ECal  *client);
+MemoEditor *memo_editor_new            (ECal  *client);
+
+
+#endif /* __MEMO_EDITOR_H__ */
Index: calendar/gui/dialogs/memo-page.c
===================================================================
RCS file: calendar/gui/dialogs/memo-page.c
diff -N calendar/gui/dialogs/memo-page.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/dialogs/memo-page.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,618 @@
+/* Evolution calendar - Main page of the memo editor dialog
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Authors: Federico Mena-Quintero <federico@ximian.com>
+ *          Miguel de Icaza <miguel@ximian.com>
+ *          Seth Alves <alves@hungry.com>
+ *          JP Rosevear <jpr@ximian.com>
+ *          Nathan Owens <pianocomp81@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtktextview.h>
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkmessagedialog.h>
+#include <libgnome/gnome-i18n.h>
+#include <glade/glade.h>
+#include <libedataserverui/e-source-option-menu.h>
+#include <widgets/misc/e-dateedit.h>
+
+#include "common/authentication.h"
+#include "e-util/e-dialog-widgets.h"
+#include "e-util/e-categories-config.h"
+#include "../calendar-config.h"
+#include "comp-editor.h"
+#include "comp-editor-util.h"
+#include "e-send-options-utils.h"
+#include "memo-page.h"
+
+
+/* Private part of the TaskPage structure */
+struct _MemoPagePrivate {
+	/* Glade XML data */
+	GladeXML *xml;
+
+	/* Widgets from the Glade file */
+	GtkWidget *main;
+
+	GtkWidget *memo_content;
+
+	GtkWidget *classification;
+
+	GtkWidget *categories_btn;
+	GtkWidget *categories;
+
+	GtkWidget *source_selector;
+
+	gboolean updating;
+};
+
+static const int classification_map[] = {
+	E_CAL_COMPONENT_CLASS_PUBLIC,
+	E_CAL_COMPONENT_CLASS_PRIVATE,
+	E_CAL_COMPONENT_CLASS_CONFIDENTIAL,
+	-1
+};
+
+
+
+static void memo_page_finalize (GObject *object);
+
+static GtkWidget *memo_page_get_widget (CompEditorPage *page);
+static void memo_page_focus_main_widget (CompEditorPage *page);
+static gboolean memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp);
+static gboolean memo_page_fill_component (CompEditorPage *page, ECalComponent *comp);
+
+G_DEFINE_TYPE (MemoPage, memo_page, TYPE_COMP_EDITOR_PAGE);
+
+
+
+/**
+ * memo_page_get_type:
+ * 
+ * Registers the #TaskPage class if necessary, and returns the type ID
+ * associated to it.
+ * 
+ * Return value: The type ID of the #TaskPage class.
+ **/
+
+/* Class initialization function for the memo page */
+static void
+memo_page_class_init (MemoPageClass *klass)
+{
+	CompEditorPageClass *editor_page_class;
+	GObjectClass *object_class;
+
+	editor_page_class = (CompEditorPageClass *) klass;
+	object_class = (GObjectClass *) klass;
+
+	editor_page_class->get_widget = memo_page_get_widget;
+	editor_page_class->focus_main_widget = memo_page_focus_main_widget;
+	editor_page_class->fill_widgets = memo_page_fill_widgets;
+	editor_page_class->fill_component = memo_page_fill_component;
+	
+	object_class->finalize = memo_page_finalize;
+}
+
+/* Object initialization function for the memo page */
+static void
+memo_page_init (MemoPage *tpage)
+{
+	MemoPagePrivate *priv;
+
+	priv = g_new0 (MemoPagePrivate, 1);
+	tpage->priv = priv;
+
+	priv->xml = NULL;
+
+	priv->main = NULL;
+	priv->memo_content = NULL;
+	priv->classification = NULL;
+	priv->categories_btn = NULL;
+	priv->categories = NULL;
+
+	priv->updating = FALSE;
+}
+
+/* Destroy handler for the memo page */
+static void
+memo_page_finalize (GObject *object)
+{
+	MemoPage *tpage;
+	MemoPagePrivate *priv;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (IS_MEMO_PAGE (object));
+
+	tpage = MEMO_PAGE (object);
+	priv = tpage->priv;
+
+	if (priv->main)
+		gtk_widget_unref (priv->main);
+
+	if (priv->xml) {
+		g_object_unref (priv->xml);
+		priv->xml = NULL;
+	}
+
+	g_free (priv);
+	tpage->priv = NULL;
+
+	if (G_OBJECT_CLASS (memo_page_parent_class)->finalize)
+		(* G_OBJECT_CLASS (memo_page_parent_class)->finalize) (object);
+}
+
+
+
+/* get_widget handler for the task page */
+static GtkWidget *
+memo_page_get_widget (CompEditorPage *page)
+{
+	MemoPage *tpage;
+	MemoPagePrivate *priv;
+
+	tpage = MEMO_PAGE (page);
+	priv = tpage->priv;
+
+	return priv->main;
+}
+
+/* focus_main_widget handler for the memo page */
+static void
+memo_page_focus_main_widget (CompEditorPage *page)
+{
+	MemoPage *tpage;
+	MemoPagePrivate *priv;
+
+	tpage = MEMO_PAGE (page);
+	priv = tpage->priv;
+
+	gtk_widget_grab_focus (priv->memo_content);
+}
+
+/* Fills the widgets with default values */
+static void
+clear_widgets (MemoPage *tpage)
+{
+	MemoPagePrivate *priv;
+
+	priv = tpage->priv;
+
+	/* memo content */
+	gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->memo_content)), "", 0);
+
+	/* Classification */
+	e_dialog_option_menu_set (priv->classification, E_CAL_COMPONENT_CLASS_PRIVATE, classification_map);
+
+	/* Categories */
+	e_dialog_editable_set (priv->categories, NULL);
+}
+
+/* Decode the radio button group for classifications */
+static ECalComponentClassification
+classification_get (GtkWidget *widget)
+{
+	return e_dialog_option_menu_get (widget, classification_map);
+}
+
+static void
+sensitize_widgets (MemoPage *mpage)
+{
+	gboolean read_only;
+	MemoPagePrivate *priv;
+	
+	priv = mpage->priv;
+
+	if (!e_cal_is_read_only (COMP_EDITOR_PAGE (mpage)->client, &read_only, NULL))
+		read_only = TRUE;
+	
+	gtk_widget_set_sensitive (priv->memo_content, !read_only);
+	gtk_widget_set_sensitive (priv->classification, !read_only);
+	gtk_widget_set_sensitive (priv->categories_btn, !read_only);
+	gtk_entry_set_editable (GTK_ENTRY (priv->categories), !read_only);
+}
+
+/* fill_widgets handler for the memo page */
+static gboolean
+memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp)
+{
+	MemoPage *tpage;
+	MemoPagePrivate *priv;
+	ECalComponentClassification cl;
+	GSList *l;
+	const char *categories;
+	ESource *source;
+
+	tpage = MEMO_PAGE (page);
+	priv = tpage->priv;
+
+	priv->updating = TRUE;
+	
+	/* Clean the screen */
+	clear_widgets (tpage);
+
+	e_cal_component_get_description_list (comp, &l);
+	if (l && l->data) {
+		ECalComponentText *dtext;
+		
+		dtext = l->data;
+		gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->memo_content)),
+					  dtext->value ? dtext->value : "", -1);
+	} else {
+		gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->memo_content)),
+					  "", 0);
+	}
+	e_cal_component_free_text_list (l);
+
+	/* Classification. */
+	e_cal_component_get_classification (comp, &cl);
+
+	switch (cl) {
+	case E_CAL_COMPONENT_CLASS_PUBLIC:
+	case E_CAL_COMPONENT_CLASS_PRIVATE:
+	case E_CAL_COMPONENT_CLASS_CONFIDENTIAL:
+		break;
+	default:
+		/* default to PUBLIC */
+		cl = E_CAL_COMPONENT_CLASS_PUBLIC;
+                break;
+	}
+	e_dialog_option_menu_set (priv->classification, cl, classification_map);
+
+	/* Categories */
+	e_cal_component_get_categories (comp, &categories);
+	e_dialog_editable_set (priv->categories, categories);
+
+	/* Source */
+	source = e_cal_get_source (page->client);
+	e_source_option_menu_select (E_SOURCE_OPTION_MENU (priv->source_selector), source);
+
+	priv->updating = FALSE;
+
+	sensitize_widgets (tpage);
+
+	return TRUE;
+}
+
+/* fill_component handler for the memo page */
+static gboolean
+memo_page_fill_component (CompEditorPage *page, ECalComponent *comp)
+{
+	MemoPage *tpage;
+	MemoPagePrivate *priv;
+	char *cat, *str;
+	int i;
+	GtkTextBuffer *text_buffer;
+	GtkTextIter text_iter_start, text_iter_end;
+
+	tpage = MEMO_PAGE (page);
+	priv = tpage->priv;
+	text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->memo_content));
+
+	/* Memo Content */
+
+	gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start);
+	gtk_text_buffer_get_end_iter   (text_buffer, &text_iter_end);
+	str = gtk_text_buffer_get_text (text_buffer, &text_iter_start, &text_iter_end, FALSE);
+
+	if (!str || strlen (str) == 0){
+		e_cal_component_set_description_list (comp, NULL);
+		e_cal_component_set_summary(comp, NULL);
+	}
+	else {
+		int idxToUse = -1, nstr = strlen(str);
+		gboolean foundNL = FALSE;
+		GSList l;
+		ECalComponentText text, sumText;
+		char *txt;
+
+		for(i = 0; i<nstr && i<50; i++){
+			if(str[i] == '\n'){
+				idxToUse = i;
+				foundNL = TRUE;
+				break;
+			}
+		}
+		
+		if(foundNL == FALSE){
+			if(nstr > 50){
+				sumText.value = txt = g_strndup(str, 50);
+			}
+			else{
+				sumText.value = txt = g_strdup(str);
+			}
+		}
+		else{
+			sumText.value = txt = g_strndup(str, idxToUse); /* cuts off '\n' */
+		}
+		
+		sumText.altrep = NULL;
+
+		text.value = str;
+		text.altrep = NULL;
+		l.data = &text;
+		l.next = NULL;
+
+		e_cal_component_set_summary(comp, &sumText);
+		e_cal_component_set_description_list (comp, &l);
+		
+		g_free(txt);
+	}
+
+	if (str)
+		g_free (str);
+
+	/* Classification. */
+	e_cal_component_set_classification (comp, classification_get (priv->classification));
+
+	/* Categories */
+	cat = e_dialog_editable_get (priv->categories);
+	str = comp_editor_strip_categories (cat);
+	if (cat)
+		g_free (cat);
+
+	e_cal_component_set_categories (comp, str);
+
+	if (str)
+		g_free (str);
+
+	return TRUE;
+}
+
+
+
+
+/* Gets the widgets from the XML file and returns if they are all available. */
+static gboolean
+get_widgets (MemoPage *tpage)
+{
+	CompEditorPage *page = COMP_EDITOR_PAGE (tpage);
+	MemoPagePrivate *priv;
+	GSList *accel_groups;
+	GtkWidget *toplevel;
+
+	priv = tpage->priv;
+
+#define GW(name) glade_xml_get_widget (priv->xml, name)
+
+	priv->main = GW ("memo-page");
+	if (!priv->main){
+		g_warning("couldn't find memo-page!");
+		return FALSE;
+	}
+
+	/* Get the GtkAccelGroup from the toplevel window, so we can install
+	   it when the notebook page is mapped. */
+	toplevel = gtk_widget_get_toplevel (priv->main);
+	accel_groups = gtk_accel_groups_from_object (G_OBJECT (toplevel));
+	if (accel_groups) {
+		page->accel_group = accel_groups->data;
+		gtk_accel_group_ref (page->accel_group);
+	}
+
+	gtk_widget_ref (priv->main);
+	gtk_container_remove (GTK_CONTAINER (priv->main->parent), priv->main);
+
+	priv->memo_content = GW ("memo_content");
+
+	priv->classification = GW ("classification");
+
+	priv->categories_btn = GW ("categories-button");
+	priv->categories = GW ("categories");
+
+	priv->source_selector = GW ("source");
+
+#undef GW
+
+	return (priv->classification
+		&& priv->memo_content
+		&& priv->categories_btn
+		&& priv->categories);
+}
+
+/* Callback used when the categories button is clicked; we must bring up the
+ * category list dialog.
+ */
+static void
+categories_clicked_cb (GtkWidget *button, gpointer data)
+{
+	MemoPage *tpage;
+	MemoPagePrivate *priv;
+	GtkWidget *entry;
+
+	tpage = MEMO_PAGE (data);
+	priv = tpage->priv;
+
+	entry = priv->categories;
+	e_categories_config_open_dialog_for_entry (GTK_ENTRY (entry));
+}
+
+/* This is called when any field is changed; it notifies upstream. */
+static void
+field_changed_cb (GtkWidget *widget, gpointer data)
+{
+	MemoPage *tpage;
+	MemoPagePrivate *priv;
+	
+	tpage = MEMO_PAGE (data);
+	priv = tpage->priv;
+	
+	if (!priv->updating)
+		comp_editor_page_notify_changed (COMP_EDITOR_PAGE (tpage));
+}
+
+static void
+source_changed_cb (GtkWidget *widget, ESource *source, gpointer data)
+{
+	MemoPage *tpage;
+	MemoPagePrivate *priv;
+
+	tpage = MEMO_PAGE (data);
+	priv = tpage->priv;
+
+	if (!priv->updating) {
+		ECal *client;
+
+		client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
+		if (!client || !e_cal_open (client, FALSE, NULL)) {
+			GtkWidget *dialog;
+
+			if (client)
+				g_object_unref (client);
+
+			e_source_option_menu_select (E_SOURCE_OPTION_MENU (priv->source_selector),
+						     e_cal_get_source (COMP_EDITOR_PAGE (tpage)->client));
+
+			dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+							 GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
+							 _("Unable to open memos in '%s'."),
+							 e_source_peek_name (source));
+			gtk_dialog_run (GTK_DIALOG (dialog));
+			gtk_widget_destroy (dialog);
+		} else {
+			comp_editor_notify_client_changed (
+				COMP_EDITOR (gtk_widget_get_toplevel (priv->main)),
+				client);
+			sensitize_widgets (tpage);
+		}
+	}
+}
+
+/* Hooks the widget signals */
+static gboolean
+init_widgets (MemoPage *tpage)
+{
+	MemoPagePrivate *priv;
+	GtkTextBuffer *text_buffer;
+
+	priv = tpage->priv;
+
+	/* Memo Content */
+	text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->memo_content));
+
+	gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->memo_content), GTK_WRAP_WORD);
+
+	/* Categories button */
+	g_signal_connect((priv->categories_btn), "clicked",
+			    G_CALLBACK (categories_clicked_cb), tpage);
+
+	/* Source selector */
+	g_signal_connect((priv->source_selector), "source_selected",
+			 G_CALLBACK (source_changed_cb), tpage);
+
+	/* Connect the default signal handler to use to make sure the "changed"
+	   field gets set whenever a field is changed. */
+
+	/* Belongs to priv->memo_content */
+	g_signal_connect ((text_buffer), "changed",
+			  G_CALLBACK (field_changed_cb), tpage);
+
+	g_signal_connect((priv->classification), "changed",
+			    G_CALLBACK (field_changed_cb), tpage);
+	g_signal_connect((priv->categories), "changed",
+			    G_CALLBACK (field_changed_cb), tpage);
+	
+	return TRUE;
+}
+
+
+/**
+ * memo_page_construct:
+ * @tpage: An memo page.
+ * 
+ * Constructs an memo page by loading its Glade data.
+ * 
+ * Return value: The same object as @tpage, or NULL if the widgets could not be
+ * created.
+ **/
+MemoPage *
+memo_page_construct (MemoPage *tpage)
+{
+	MemoPagePrivate *priv;
+
+	priv = tpage->priv;
+
+	priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/memo-page.glade",
+				   NULL, NULL);
+	if (!priv->xml) {
+		g_message ("memo_page_construct(): "
+			   "Could not load the Glade XML file!");
+		return NULL;
+	}
+
+	if (!get_widgets (tpage)) {
+		g_message ("memo_page_construct(): "
+			   "Could not find all widgets in the XML file!");
+		return NULL;
+	}
+
+	if (!init_widgets (tpage)) {
+		g_message ("memo_page_construct(): " 
+			   "Could not initialize the widgets!");
+		return NULL;
+	}
+
+	return tpage;
+}
+
+/**
+ * memo_page_new:
+ * 
+ * Creates a new memo page.
+ * 
+ * Return value: A newly-created task page, or NULL if the page could
+ * not be created.
+ **/
+MemoPage *
+memo_page_new (void)
+{
+	MemoPage *tpage;
+
+	tpage = gtk_type_new (TYPE_MEMO_PAGE);
+	if (!memo_page_construct (tpage)) {
+		g_object_unref (tpage);
+		return NULL;
+	}
+
+	return tpage;
+}
+
+GtkWidget *memo_page_create_source_option_menu (void);
+
+GtkWidget *
+memo_page_create_source_option_menu (void)
+{
+	GtkWidget   *menu;
+	GConfClient *gconf_client;
+	ESourceList *source_list;
+
+	gconf_client = gconf_client_get_default ();
+	source_list = e_source_list_new_for_gconf (gconf_client, "/apps/evolution/memos/sources");
+
+	menu = e_source_option_menu_new (source_list);
+	g_object_unref (source_list);
+
+	gtk_widget_show (menu);
+	return menu;
+}
Index: calendar/gui/dialogs/memo-page.glade
===================================================================
RCS file: calendar/gui/dialogs/memo-page.glade
diff -N calendar/gui/dialogs/memo-page.glade
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/dialogs/memo-page.glade	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,323 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="memo-toplevel">
+  <property name="title" translatable="yes">window1</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+
+  <child>
+    <widget class="GtkVBox" id="memo-page">
+      <property name="border_width">12</property>
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">6</property>
+
+      <child>
+	<widget class="GtkLabel" id="label21">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Basics&lt;/span&gt;</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">True</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">0</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="hbox7">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label22">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes"></property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">12</property>
+	      <property name="ypad">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkTable" id="table3">
+	      <property name="visible">True</property>
+	      <property name="n_rows">4</property>
+	      <property name="n_columns">2</property>
+	      <property name="homogeneous">False</property>
+	      <property name="row_spacing">6</property>
+	      <property name="column_spacing">12</property>
+	      
+	      <child>
+		<widget class="GtkLabel" id="label100">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Classi_fication:</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">classification</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox10">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkOptionMenu" id="classification">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="history">0</property>
+
+		      <child>
+			<widget class="GtkMenu" id="menu1">
+
+			  <child>
+			    <widget class="GtkMenuItem" id="public1">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Public</property>
+			      <property name="use_underline">True</property>
+			    </widget>
+			  </child>
+
+			  <child>
+			    <widget class="GtkMenuItem" id="private1">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Private</property>
+			      <property name="use_underline">True</property>
+			    </widget>
+			  </child>
+
+			  <child>
+			    <widget class="GtkMenuItem" id="confidential1">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Confidential</property>
+			      <property name="use_underline">True</property>
+			    </widget>
+			  </child>
+			</widget>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label23">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Group:</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">12</property>
+		      <property name="ypad">0</property>
+		      <property name="mnemonic_widget">source</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="Custom" id="source">
+		      <property name="visible">True</property>
+		      <property name="creation_function">memo_page_create_source_option_menu</property>
+		      <property name="int1">0</property>
+		      <property name="int2">0</property>
+		      <property name="last_modification_time">Thu, 13 Jan 2004 22:00:00 GMT</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options">fill</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkButton" id="categories-button">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label" translatable="yes">Ca_tegories...</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">2</property>
+		  <property name="bottom_attach">3</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="categories">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char" translatable="yes">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">2</property>
+		  <property name="bottom_attach">3</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="scrolledwindow1">
+		  <property name="visible">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="shadow_type">GTK_SHADOW_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <widget class="GtkTextView" id="memo_content">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="editable">True</property>
+		      <property name="overwrite">False</property>
+		      <property name="accepts_tab">True</property>
+		      <property name="justification">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap_mode">GTK_WRAP_WORD</property>
+		      <property name="cursor_visible">True</property>
+		      <property name="pixels_above_lines">0</property>
+		      <property name="pixels_below_lines">0</property>
+		      <property name="pixels_inside_wrap">0</property>
+		      <property name="left_margin">0</property>
+		      <property name="right_margin">0</property>
+		      <property name="indent">0</property>
+		      <property name="text" translatable="yes"></property>
+		    </widget>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">3</property>
+		  <property name="bottom_attach">4</property>
+		  <property name="x_options">expand|shrink|fill</property>
+		  <property name="y_options">expand|shrink|fill</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label18">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">_Memo Content:</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_CENTER</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">memo content</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">3</property>
+		  <property name="bottom_attach">4</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options">fill</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
Index: calendar/gui/dialogs/memo-page.h
===================================================================
RCS file: calendar/gui/dialogs/memo-page.h
diff -N calendar/gui/dialogs/memo-page.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/dialogs/memo-page.h	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,56 @@
+/* Evolution calendar - Main page of the memo editor dialog
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Authors: Federico Mena-Quintero <federico@ximian.com>
+ *          Miguel de Icaza <miguel@ximian.com>
+ *          Seth Alves <alves@hungry.com>
+ *          JP Rosevear <jpr@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MEMO_PAGE_H
+#define MEMO_PAGE_H
+
+#include "comp-editor-page.h"
+
+G_BEGIN_DECLS
+
+#define TYPE_MEMO_PAGE            (memo_page_get_type ())
+#define MEMO_PAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MEMO_PAGE, MemoPage))
+#define MEMO_PAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MEMO_PAGE, MemoPageClass))
+#define IS_MEMO_PAGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MEMO_PAGE))
+#define IS_MEMO_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), TYPE_MEMO_PAGE))
+
+typedef struct _MemoPagePrivate MemoPagePrivate;
+
+typedef struct {
+	CompEditorPage page;
+
+	/* Private data */
+	MemoPagePrivate *priv;
+} MemoPage;
+
+typedef struct {
+	CompEditorPageClass parent_class;
+} MemoPageClass;
+
+GtkType   memo_page_get_type  (void);
+MemoPage *memo_page_construct (MemoPage *epage);
+MemoPage *memo_page_new       (void);
+
+G_END_DECLS
+
+#endif
Index: ui/ChangeLog.owens
===================================================================
RCS file: ui/ChangeLog.owens
diff -N ui/ChangeLog.owens
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ui/ChangeLog.owens	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,3 @@
+2005-07-25  Nathan Owens <pianocomp81@yahoo.com
+	* evolution-memos.xml: added menus for memos component
+	* Makefile.am: added evolution-memos.xml to build files
Index: ui/evolution-memos.xml
===================================================================
RCS file: ui/evolution-memos.xml
diff -N ui/evolution-memos.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ui/evolution-memos.xml	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,56 @@
+<Root>
+  <commands>
+    <cmd name="MemosOpenMemo" _tip="View the selected memo" accel="*Control*o"/>
+    <cmd name="MemosPrint" _tip="Print the list of memos" pixtype="stock" pixname="gtk-print"
+	 accel="*Control*p"/>
+    <cmd name="MemosPrintPreview" _tip="Previews the list of memos to be printed" pixtype="stock" pixname="gtk-print-preview"/>
+
+    <cmd name="MemosCut" _tip="Cut selected memo" accel="*Control*x" pixtype="stock" pixname="gtk-cut"/>
+    <cmd name="MemosCopy" _tip="Copy selected memo" accel="*Control*c" pixtype="stock" pixname="gtk-copy"/>
+    <cmd name="MemosPaste" _tip="Paste memo from the clipboard" accel="*Control*v" pixtype="stock" pixname="gtk-paste"/>
+    <cmd name="MemosDelete" _tip="Delete selected memos" accel="*Control*d" sensitive="0"
+         pixtype="stock" pixname="gtk-delete"/>
+
+  </commands>
+  
+  <menu>
+    <submenu name="File">
+      <placeholder name="FileOps">
+        <menuitem name="OpenMemo" verb="MemosOpenMemo" _label="_Open Memo"/>
+      </placeholder>
+      <placeholder name="Print">
+	<menuitem name="PrintPreview" verb="MemosPrintPreview" _label="Print Pre_view"/>
+
+	<menuitem name="Print" verb="MemosPrint" accel="*Control*p" _label="_Print..."/>
+      </placeholder>
+
+    </submenu>
+
+    <submenu name="Edit" _label="_Edit">
+      <placeholder name="EditPlaceholder">
+        <menuitem name="MemosCut" verb="" _label="C_ut"/>
+        <menuitem name="MemosCopy" verb="" _label="_Copy"/>
+        <menuitem name="MemosPaste" verb="" _label="_Paste"/>
+        
+		<separator/>
+        
+		<menuitem name="MemosDelete" verb="" _label="_Delete"/>
+      </placeholder>
+    </submenu>
+
+  </menu>
+
+  <dockitem name="Toolbar">
+    <toolitem name="Cut" _label="Cut" verb="MemosCut"/>
+    <toolitem name="Copy" _label="Copy" verb="MemosCopy"/>
+    <toolitem name="Paste" _label="Paste" verb="MemosPaste"/>
+
+    <separator/>
+
+    <toolitem name="Print" _label="Print" verb="MemosPrint"/>
+
+    <toolitem name="Delete" _label="Delete" verb="MemosDelete"/>
+
+  </dockitem>
+
+</Root>
Index: views/ChangeLog.owens
===================================================================
RCS file: views/ChangeLog.owens
diff -N views/ChangeLog.owens
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views/ChangeLog.owens	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,5 @@
+2005-07-25  Nathan Owens <pianocomp81@yahoo.com>
+	
+	* Makefile.am: added memos directory
+	* views/memos/*: added galview.xml, Makefile.am, Memos.galview for
+	initial Memos component
Index: views/memos/Makefile.am
===================================================================
RCS file: views/memos/Makefile.am
diff -N views/memos/Makefile.am
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views/memos/Makefile.am	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,3 @@
+memosviewsdir = $(viewsdir)/memos
+memosviews_DATA = Memos.galview galview.xml
+EXTRA_DIST = $(memosviews_DATA)
Index: views/memos/Memos.galview
===================================================================
RCS file: views/memos/Memos.galview
diff -N views/memos/Memos.galview
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views/memos/Memos.galview	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<ETableState state-version="0.100000">
+  <column source="1"/>
+  <column source="0"/>
+  <column source="2"/>
+  <grouping></grouping>
+</ETableState>
Index: views/memos/galview.xml
===================================================================
RCS file: views/memos/galview.xml
diff -N views/memos/galview.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views/memos/galview.xml	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<GalViewCollection default-view="Memos">
+  <GalView id="Memos" _title="_Memos" filename="Memos.galview" type="etable"/>
+</GalViewCollection>
