[evolution] Be able to save mail to event, meeting, task or memo



commit 96a85a6ecd4f65c8a52ad2242cb55edd4ca6e2a8
Author: Milan Crha <mcrha redhat com>
Date:   Fri Apr 24 20:10:29 2009 +0200

    Be able to save mail to event, meeting, task or memo
    
    	** Fix for bug #342296
---
 ChangeLog                                          |    7 +
 configure.in                                       |    3 +-
 plugins/mail-to-meeting/ChangeLog                  |   77 -----
 plugins/mail-to-meeting/Makefile.am                |   20 --
 plugins/mail-to-meeting/mail-to-meeting.c          |  185 -----------
 .../org-gnome-mail-to-meeting.eplug.xml            |   25 --
 plugins/mail-to-task/ChangeLog                     |   14 +
 plugins/mail-to-task/mail-to-task.c                |  328 ++++++++++++++------
 .../mail-to-task/org-gnome-mail-to-task.eplug.xml  |   46 +++-
 plugins/mail-to-task/org-gnome-mail-to-task.xml    |   14 +-
 10 files changed, 314 insertions(+), 405 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b0ca0b8..87d0dbe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-04-24  Milan Crha  <mcrha redhat com>
+
+	** Part of fix for bug #342296
+
+	* configure.in:	Remove 'mail-to-meeting' plugin,
+	the 'mail-to-task' plugin does this itself now.
+
 2009-04-12  Matthew Barnes  <mbarnes redhat com>
 
 	** Remove a bunch of juvenile comments.  Source code should
diff --git a/configure.in b/configure.in
index f01aeaa..462a4e7 100644
--- a/configure.in
+++ b/configure.in
@@ -1780,7 +1780,7 @@ plugins_standard_always="bbdb subject-thread save-calendar select-one-source cop
 plugins_standard="$plugins_standard_always"
 all_plugins_standard="$plugins_standard"
 
-plugins_experimental_always="folder-unsubscribe mail-to-meeting save-attachments external-editor hula-account-setup"
+plugins_experimental_always="folder-unsubscribe save-attachments external-editor hula-account-setup"
 plugins_experimental="$plugins_experimental_always $IPOD_SYNC $TNEF_ATTACHMENTS $PYTHON_PLUGIN"
 all_plugins_experimental="$plugins_experimental_always ipod-sync tnef-attachments"
 
@@ -2077,7 +2077,6 @@ plugins/bbdb/Makefile
 plugins/audio-inline/Makefile
 plugins/attachment-reminder/Makefile
 plugins/mail-notification/Makefile
-plugins/mail-to-meeting/Makefile
 plugins/mail-to-task/Makefile
 plugins/mono/Makefile
 plugins/subject-thread/Makefile
diff --git a/plugins/mail-to-meeting/ChangeLog b/plugins/mail-to-meeting/ChangeLog
deleted file mode 100644
index b30a1ea..0000000
--- a/plugins/mail-to-meeting/ChangeLog
+++ /dev/null
@@ -1,77 +0,0 @@
-2009-03-26  Milan Crha  <mcrha redhat com>
-
-	** Fix for bug #576696
-
-	* mail-to-meeting.c: (add_attendee_cb): Set mandatory properties.
-
-2009-01-21  Milan Crha  <mcrha redhat com>
-
-	* Makefile.am: Use also EVOLUTION_CALENDAR_CFLAGS.
-
-2008-08-27  Sankar P  <psankar novell com>
-
-License Changes
-
-	* mail-to-meeting.c:
-
-2008-08-12  Bharath Acharya  <abharath novell com>
-
-	* Makefile.am: Use NO_UNDEFINED. Link with more libraries. To generate
-	dlls on Windows.
-
-2007-11-05  Milan Crha  <mcrha redhat com>
-
-	** Fix for bug #353779
-
-	* org-gnome-mail-to-meeting.eplug.xml:
-	Allow convert more than one mail to meeting with one click.
-
-2007-06-07  Gilles Dartiguelongue  <dartigug esiee fr>
-
-	* mail-to-meeting.c: (add_attendee_cb): more compilation
-	warnings cleanup, completes bug #437584 fixes
-
-2007-04-02  Sankar P  <psankar novell com>
-
-	* Committed on behalf of Gilles Dartiguelongue <dartigug esiee fr>
-
-	* org-gnome-mail-to-meeting.eplug.xml:
-	Cleanup. 
-	Fixes part of #301149
-
-2005-05-11  Not Zed  <NotZed Ximian com>
-
-	* Makefile.am: added built_sources/cleanfiles
-
-2005-05-06  Not Zed  <NotZed Ximian com>
-
-	* Makefile.am: 
-
-	* org-gnome-mail-to-meeting.eplug.xml: s/.in/.xml/ & i18n.
-
-2005-02-24  Björn Torkelsson  <torkel acc umu se>
-
-	* org-gnome-mail-to-meeting.eplug.in: Shortened the name and added
-	a . to the end of the description.
-
-2004-11-04  Rodrigo Moya <rodrigo novell com>
-
-	* org-gnome-mail-to-meeting.eplug.in: fixed description and added
-	author's info, to display correctly on the plugin manager.
-
-2004-11-03  Not Zed  <NotZed Ximian com>
-
-	* org-gnome-mail-to-meeting.eplug.in: fix the popup id.
-
-2004-11-01  JP Rosevear  <jpr novell com>
-
-	* Makefile.am: dist .eplug.in file
-
-2004-10-29  Rodrigo Moya <rodrigo novell com>
-
-	* org-gnome-mail-to-meeting.eplug.in: fix folder view popup id and
-	use stock icon for meetings.
-
-2004-10-29  Rodrigo Moya <rodrigo novell com>
-
-	* added mail-to-meeting plugin, to convert mails to meetings.
diff --git a/plugins/mail-to-meeting/Makefile.am b/plugins/mail-to-meeting/Makefile.am
deleted file mode 100644
index f3b8f44..0000000
--- a/plugins/mail-to-meeting/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-INCLUDES =				\
-	-I$(top_srcdir)			\
-	$(EVOLUTION_CALENDAR_CFLAGS)	\
-	$(EVOLUTION_MAIL_CFLAGS)
-
- EVO_PLUGIN_RULE@
-
-plugin_DATA = org-gnome-mail-to-meeting.eplug
-plugin_LTLIBRARIES = liborg-gnome-mail-to-meeting.la
-
-liborg_gnome_mail_to_meeting_la_SOURCES = mail-to-meeting.c
-liborg_gnome_mail_to_meeting_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
-liborg_gnome_mail_to_meeting_la_LIBADD =	\
-	$(EVOLUTION_CALENDAR_LIBS)	\
-	$(EVOLUTION_MAIL_LIBS)
-
-EXTRA_DIST = org-gnome-mail-to-meeting.eplug.xml
-
-BUILT_SOURCES = $(plugin_DATA)
-CLEANFILES = $(BUILT_SOURCES)
diff --git a/plugins/mail-to-meeting/mail-to-meeting.c b/plugins/mail-to-meeting/mail-to-meeting.c
deleted file mode 100644
index a23d4d7..0000000
--- a/plugins/mail-to-meeting/mail-to-meeting.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>  
- *
- *
- * Authors:
- *		Rodrigo Moya <rodrigo ximian com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <glib/gi18n-lib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <gconf/gconf-client.h>
-#include <libecal/e-cal.h>
-#include <libedataserverui/e-source-selector-dialog.h>
-#include "camel/camel-folder.h"
-#include "camel/camel-mime-message.h"
-#include "mail/em-popup.h"
-
-static void
-add_attendee_cb (gpointer key, gpointer value, gpointer user_data)
-{
-	ECalComponentAttendee *ca;
-	const char *str, *name;
-	GSList **attendees = user_data;
-
-	if (!camel_internet_address_get (value, 0, &name, &str))
-		return;
-
-	ca = g_new0 (ECalComponentAttendee, 1);
-	ca->value = str;
-	ca->cn = name;
-	ca->cutype = ICAL_CUTYPE_INDIVIDUAL;
-	ca->status = ICAL_PARTSTAT_NEEDSACTION;
-	ca->role = ICAL_ROLE_REQPARTICIPANT;
-
-	/* FIXME: user prepend and reverse list order (GList) */
-	*attendees = g_slist_append (*attendees, ca);
-}
-
-static void
-set_attendees (ECalComponent *comp, CamelMimeMessage *message)
-{
-	GSList *attendees = NULL, *l;
-
-	g_hash_table_foreach (message->recipients, (GHFunc) add_attendee_cb, &attendees);
-	e_cal_component_set_attendee_list (comp, attendees);
-
-	for (l = attendees; l != NULL; l = l->next)
-		g_free (l->data);
-	g_slist_free (attendees);
-}
-
-static void
-set_organizer (ECalComponent *comp, CamelMimeMessage *message)
-{
-	const CamelInternetAddress *address;
-	const char *str, *name;
-	ECalComponentOrganizer organizer = {NULL, NULL, NULL, NULL};
-
-	if (message->reply_to)
-		address = message->reply_to;
-	else if (message->from)
-		address = message->from;
-	else
-		return;
-
-	if (!camel_internet_address_get (address, 0, &name, &str))
-		return;
-
-	organizer.value = str;
-	organizer.cn = name;
-	e_cal_component_set_organizer (comp, &organizer);
-}
-
-static void
-do_mail_to_meeting (EMPopupTargetSelect *t, ESource *meeting_source)
-{
-	ECal *client;
-
-	/* open the meeting client */
-	client = e_cal_new (meeting_source, E_CAL_SOURCE_TYPE_EVENT);
-	if (e_cal_open (client, FALSE, NULL)) {
-		int i;
-
-		for (i = 0; i < (t->uids ? t->uids->len : 0); i++) {
-			CamelMimeMessage *message;
-			ECalComponent *comp;
-			ECalComponentText text;
-			GSList sl;
-			char *str;
-
-			/* retrieve the message from the CamelFolder */
-			message = camel_folder_get_message (t->folder, g_ptr_array_index (t->uids, i), NULL);
-			if (!message)
-				continue;
-
-			comp = e_cal_component_new ();
-			e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT);
-			e_cal_component_set_uid (comp, camel_mime_message_get_message_id (message));
-
-			/* set the meeting's summary */
-			text.value = camel_mime_message_get_subject (message);
-			text.altrep = NULL;
-			e_cal_component_set_summary (comp, &text);
-
-			/* FIXME: a better way to get the full body */
-			str = camel_mime_message_build_mbox_from (message);
-			text.value = str;
-			sl.next = NULL;
-			sl.data = &text;
-			e_cal_component_set_description_list (comp, &sl);
-
-			g_free (str);
-
-			/* set the organizer, and the attendees */
-			set_organizer (comp, message);
-			set_attendees (comp, message);
-
-			/* save the meeting to the selected source */
-			e_cal_create_object (client, e_cal_component_get_icalcomponent (comp), NULL, NULL);
-
-			g_object_unref (comp);
-		}
-	}
-
-	/* free memory */
-	g_object_unref (client);
-}
-
-void org_gnome_mail_to_meeting (void *ep, EMPopupTargetSelect *t);
-
-void
-org_gnome_mail_to_meeting (void *ep, EMPopupTargetSelect *t)
-{
-	GtkWidget *dialog;
-	GConfClient *conf_client;
-	ESourceList *source_list;
-
-	/* ask the user which meeting list to save to */
-	conf_client = gconf_client_get_default ();
-	source_list = e_source_list_new_for_gconf (conf_client, "/apps/evolution/calendar/sources");
-
-	dialog = e_source_selector_dialog_new (NULL, source_list);
-
-	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
-		ESource *source;
-
-		/* if a source has been selected, perform the mail2meeting operation */
-		source = e_source_selector_dialog_peek_primary_selection (E_SOURCE_SELECTOR_DIALOG (dialog));
-		if (source)
-			do_mail_to_meeting (t, source);
-	}
-
-	g_object_unref (conf_client);
-	g_object_unref (source_list);
-	gtk_widget_destroy (dialog);
-}
-
-int e_plugin_lib_enable(EPluginLib *ep, int enable);
-
-int
-e_plugin_lib_enable(EPluginLib *ep, int enable)
-{
-	return 0;
-}
diff --git a/plugins/mail-to-meeting/org-gnome-mail-to-meeting.eplug.xml b/plugins/mail-to-meeting/org-gnome-mail-to-meeting.eplug.xml
deleted file mode 100644
index febad83..0000000
--- a/plugins/mail-to-meeting/org-gnome-mail-to-meeting.eplug.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0"?>
-<e-plugin-list>
-  <e-plugin
-    type="shlib"
-    id="org.gnome.evolution.plugin.mailToMeeting"
-    location="@PLUGINDIR@/liborg-gnome-mail-to-meeting SOEXT@"
-    _name="Mail to meeting">
-    <_description>A plugin which allows the creation of meetings from the contents of a mail message.</_description>
-    <author name="Rodrigo Moya" email="rodrigo novell com"/>
-
-    <!-- hook into the uri popup menu -->
-    <hook class="org.gnome.evolution.mail.popup:1.0">
-      <menu id="org.gnome.evolution.mail.folderview.popup" target="select">
-	<item
-	  type="item"
-	  path="72.mail_to_meeting"
-	  icon="stock_new-meeting"
-	  _label="Con_vert to Meeting"
-	  enable="many"
-	  visible="many"
-	  activate="org_gnome_mail_to_meeting"/>
-      </menu>
-    </hook>
-  </e-plugin>
-</e-plugin-list>
diff --git a/plugins/mail-to-task/ChangeLog b/plugins/mail-to-task/ChangeLog
index 978fe50..d2d10d1 100644
--- a/plugins/mail-to-task/ChangeLog
+++ b/plugins/mail-to-task/ChangeLog
@@ -1,3 +1,17 @@
+2009-04-24  Milan Crha  <mcrha redhat com>
+
+	** Fix for bug #342296
+
+	* org-gnome-mail-to-task.eplug.xml:
+	* org-gnome-mail-to-task.xml:
+	* mail-to-task.c: (set_attendees), (set_organizer), (do_report_error),
+	(report_error_idle), (do_mail_to_event), (mail_to_event),
+	(org_gnome_mail_to_event), (org_gnome_mail_to_event_menu),
+	(org_gnome_mail_to_meeting), (org_gnome_mail_to_meeting_menu),
+	(org_gnome_mail_to_task), (org_gnome_mail_to_task_menu),
+	(org_gnome_mail_to_memo), (org_gnome_mail_to_memo_menu):
+	Extended to be able to save mail to event, meeting, task or memo.
+
 2009-03-26  Milan Crha  <mcrha redhat com>
 
 	** Fix for bug #576696
diff --git a/plugins/mail-to-task/mail-to-task.c b/plugins/mail-to-task/mail-to-task.c
index 8a16b92..44a7d8b 100644
--- a/plugins/mail-to-task/mail-to-task.c
+++ b/plugins/mail-to-task/mail-to-task.c
@@ -34,6 +34,7 @@
 
 #include <gconf/gconf-client.h>
 #include <libecal/e-cal.h>
+#include <libedataserver/e-account.h>
 #include <libedataserverui/e-source-selector-dialog.h>
 #include <camel/camel-folder.h>
 #include <camel/camel-medium.h>
@@ -47,17 +48,11 @@
 #include "mail/em-utils.h"
 #include "mail/em-folder-view.h"
 #include "mail/em-format-html.h"
+#include "mail/mail-config.h"
 #include "e-util/e-dialog-utils.h"
 #include <gtkhtml/gtkhtml.h>
 #include <calendar/common/authentication.h>
 
-typedef struct {
-	ECal *client;
-	struct _CamelFolder *folder;
-	GPtrArray *uids;
-	char *selected_text;
-}AsyncData;
-
 static char *
 clean_name(const unsigned char *s)
 {
@@ -79,21 +74,28 @@ clean_name(const unsigned char *s)
 }
 
 static void
-set_attendees (ECalComponent *comp, CamelMimeMessage *message)
+set_attendees (ECalComponent *comp, CamelMimeMessage *message, const char *organizer)
 {
-	GSList *attendees = NULL, *l, *to_free = NULL;
+	GSList *attendees = NULL, *to_free = NULL;
 	ECalComponentAttendee *ca;
-	const CamelInternetAddress *to, *cc, *bcc, *arr[3];
+	const CamelInternetAddress *from = NULL, *to, *cc, *bcc, *arr[4];
 	int len, i, j;
 
+	if (message->reply_to)
+		from = message->reply_to;
+	else if (message->from)
+		from = message->from;
+
 	to = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_TO);
 	cc = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_CC);
 	bcc = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_BCC);
 
-	arr[0] = to, arr[1] = cc, arr[2] = bcc;
+	arr[0] = from; arr[1] = to; arr[2] = cc; arr[3] = bcc;
+
+	for (j = 0; j < 4; j++) {
+		if (!arr[j])
+			continue;
 
-	for(j = 0; j < 3; j++)
-	{
 		len = CAMEL_ADDRESS (arr[j])->addresses->len;
 		for (i = 0; i < len; i++) {
 			const char *name, *addr;
@@ -101,16 +103,23 @@ set_attendees (ECalComponent *comp, CamelMimeMessage *message)
 			if (camel_internet_address_get (arr[j], i, &name, &addr)) {
 				char *temp;
 
+				temp = g_strconcat ("mailto:";, addr, NULL);
+				if (organizer && g_ascii_strcasecmp (temp, organizer) == 0) {
+					/* do not add organizer twice */
+					g_free (temp);
+					continue;
+				}
+
 				ca = g_new0 (ECalComponentAttendee, 1);
 
-				temp = g_strconcat ("mailto:";, addr, NULL);
 				ca->value = temp;
-				to_free = g_slist_prepend (to_free, temp);
-
 				ca->cn = name;
 				ca->cutype = ICAL_CUTYPE_INDIVIDUAL;
 				ca->status = ICAL_PARTSTAT_NEEDSACTION;
-				if (j == 2) {
+				if (j == 0) {
+					/* From */
+					ca->role = ICAL_ROLE_CHAIR;
+				} else if (j == 2) {
 					/* BCC  */
 					ca->role = ICAL_ROLE_OPTPARTICIPANT;
 				} else {
@@ -118,6 +127,8 @@ set_attendees (ECalComponent *comp, CamelMimeMessage *message)
 					ca->role = ICAL_ROLE_REQPARTICIPANT;
 				}
 
+				to_free = g_slist_prepend (to_free, temp);
+
 				attendees = g_slist_append (attendees, ca);
 			}
 		}
@@ -125,9 +136,7 @@ set_attendees (ECalComponent *comp, CamelMimeMessage *message)
 
 	e_cal_component_set_attendee_list (comp, attendees);
 
-	for (l = attendees; l != NULL; l = l->next)
-		g_free (l->data);
-
+	g_slist_foreach (attendees, (GFunc) g_free, NULL);
 	g_slist_foreach (to_free, (GFunc) g_free, NULL);
 
 	g_slist_free (to_free);
@@ -197,30 +206,30 @@ set_description (ECalComponent *comp, CamelMimeMessage *message)
 		g_free (convert_str);
 }
 
-static void
-set_organizer (ECalComponent *comp, CamelMimeMessage *message)
+static char *
+set_organizer (ECalComponent *comp)
 {
-	const CamelInternetAddress *address;
+	EAccount *account;
 	const char *str, *name;
 	ECalComponentOrganizer organizer = {NULL, NULL, NULL, NULL};
-	char *temp;
+	char *res;
 
-	if (message->reply_to)
-		address = message->reply_to;
-	else if (message->from)
-		address = message->from;
-	else
-		return;
+	account = mail_config_get_default_account ();
+	if (!account)
+		return NULL;
 
-	if (!camel_internet_address_get (address, 0, &name, &str))
-		return;
+	str = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
+	name = e_account_get_string (account, E_ACCOUNT_ID_NAME);
+
+	if (!str)
+		return NULL;
 
-	temp = g_strconcat ("mailto:";, str, NULL);
-	organizer.value = temp;
+	res = g_strconcat ("mailto:";, str, NULL);
+	organizer.value = res;
 	organizer.cn = name;
 	e_cal_component_set_organizer (comp, &organizer);
 
-	g_free (temp);
+	return res;
 }
 
 static void
@@ -281,8 +290,47 @@ set_attachments (ECal *client, ECalComponent *comp, CamelMimeMessage *message)
 	e_cal_component_set_attachment_list (comp, list);
 }
 
+struct _report_error
+{
+	char *format;
+	char *param;
+};
+
 static gboolean
-do_mail_to_task (AsyncData *data)
+do_report_error (struct _report_error *err)
+{
+	if (err) {
+		e_notice (NULL, GTK_MESSAGE_ERROR, err->format, err->param);
+		g_free (err->format);
+		g_free (err->param);
+		g_free (err);
+	}
+
+	return FALSE;
+}
+
+static void
+report_error_idle (const char *format, const char *param)
+{
+	struct _report_error *err = g_new (struct _report_error, 1);
+
+	err->format = g_strdup (format);
+	err->param = g_strdup (param);
+
+	g_usleep (250);
+	g_idle_add ((GSourceFunc)do_report_error, err);
+}
+
+typedef struct {
+	ECal *client;
+	struct _CamelFolder *folder;
+	GPtrArray *uids;
+	char *selected_text;
+	gboolean with_attendees;
+}AsyncData;
+
+static gboolean
+do_mail_to_event (AsyncData *data)
 {
 	ECal *client = data->client;
 	struct _CamelFolder *folder = data->folder;
@@ -292,14 +340,41 @@ do_mail_to_task (AsyncData *data)
 
 	/* open the task client */
 	if (!e_cal_open (client, FALSE, &err)) {
-		e_notice (NULL, GTK_MESSAGE_ERROR, _("Cannot open calendar. %s"), err ? err->message : "");
+		report_error_idle (_("Cannot open calendar. %s"), err ? err->message : _("Unknown error."));
 	} else if (!e_cal_is_read_only (client, &readonly, &err) || readonly) {
 		if (err)
-			e_notice (NULL, GTK_MESSAGE_ERROR, "%s", err->message);
-		else
-			e_notice (NULL, GTK_MESSAGE_ERROR, _("Selected source is read only, thus cannot create task there. Select other source, please."));
+			report_error_idle ("Check readonly failed. %s", err->message);
+		else {
+			switch (e_cal_get_source_type (client)) {
+			case E_CAL_SOURCE_TYPE_EVENT:
+				report_error_idle (_("Selected source is read only, thus cannot create event there. Select other source, please."), NULL);
+				break;
+			case E_CAL_SOURCE_TYPE_TODO:
+				report_error_idle (_("Selected source is read only, thus cannot create task there. Select other source, please."), NULL);
+				break;
+			case E_CAL_SOURCE_TYPE_JOURNAL:
+				report_error_idle (_("Selected source is read only, thus cannot create memo there. Select other source, please."), NULL);
+				break;
+			default:
+				g_assert_not_reached ();
+				break;
+			}
+		}
 	} else {
 		int i;
+		ECalSourceType source_type = e_cal_get_source_type (client);
+		ECalComponentDateTime dt, dt2;
+		struct icaltimetype tt, tt2;
+
+		/* set start day of the event as today, without time - easier than looking for a calendar's time zone */
+		tt = icaltime_today ();
+		dt.value = &tt;
+		dt.tzid = NULL;
+
+		tt2 = tt;
+		icaltime_adjust (&tt2, 1, 0, 0, 0);		
+		dt2.value = &tt2;
+		dt2.tzid = NULL;
 
 		for (i = 0; i < (uids ? uids->len : 0); i++) {
 			CamelMimeMessage *message;
@@ -315,10 +390,31 @@ do_mail_to_task (AsyncData *data)
 			}
 
 			comp = e_cal_component_new ();
-			e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_TODO);
+
+			switch (source_type) {
+			case E_CAL_SOURCE_TYPE_EVENT:
+				e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT);
+				break;
+			case E_CAL_SOURCE_TYPE_TODO:
+				e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_TODO);
+				break;
+			case E_CAL_SOURCE_TYPE_JOURNAL:
+				e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_JOURNAL);
+				break;
+			default:
+				g_assert_not_reached ();
+				break;
+			}
+
 			e_cal_component_set_uid (comp, camel_mime_message_get_message_id (message));
+			e_cal_component_set_dtstart (comp, &dt);
 
-			/* set the task's summary */
+			if (source_type == E_CAL_SOURCE_TYPE_EVENT) {
+				/* make it an all-day event */
+				e_cal_component_set_dtend (comp, &dt2);
+			}
+
+			/* set the summary */
 			text.value = camel_mime_message_get_subject (message);
 			text.altrep = NULL;
 			e_cal_component_set_summary (comp, &text);
@@ -335,8 +431,15 @@ do_mail_to_task (AsyncData *data)
 				e_cal_component_set_description_list (comp, &sl);
 			} else
 				set_description (comp, message);
-			set_organizer (comp, message);
-			set_attendees (comp, message);
+
+			if (data->with_attendees) {
+				char *organizer;
+
+				/* set actual user as organizer, to be able to change event's properties */
+				organizer = set_organizer (comp);
+				set_attendees (comp, message, organizer);
+				g_free (organizer);
+			}
 
 			/* set attachment files */
 			set_attachments (client, comp, message);
@@ -349,7 +452,7 @@ do_mail_to_task (AsyncData *data)
 
 			/* save the task to the selected source */
 			if (!e_cal_create_object (client, icalcomp, NULL, &err)) {
-				g_warning ("Could not create object: %s", err ? err->message : "Unknown error");
+				report_error_idle (_("Could not create object. %s"), err ? err->message : _("Unknown error"));
 
 				if (err)
 					g_error_free (err);
@@ -373,9 +476,6 @@ do_mail_to_task (AsyncData *data)
 	return TRUE;
 }
 
-void org_gnome_mail_to_task (void *ep, EMPopupTargetSelect *t);
-void org_gnome_mail_to_task_menu (EPlugin *ep, EMMenuTargetSelect *target);
-
 static void
 copy_uids (char *uid, GPtrArray *uid_array)
 {
@@ -430,18 +530,37 @@ get_selected_text (EMFolderView *emfv)
 }
 
 static void
-convert_to_task (GPtrArray *uid_array, struct _CamelFolder *folder, EMFolderView *emfv)
+mail_to_event (ECalSourceType source_type, gboolean with_attendees, GPtrArray *uids, CamelFolder *folder, EMFolderView *emfv)
 {
-	GConfClient *conf_client;
-	GtkWidget *dialog = NULL;
+	GPtrArray *uid_array = NULL;
+	ESourceList *source_list = NULL;
 	gboolean done = FALSE;
-	ESourceList *source_list;
 	GSList *groups, *p;
 	ESource *source = NULL;
+	GError *error = NULL;
+
+	g_return_if_fail (uids != NULL);
+	g_return_if_fail (folder != NULL);
+	g_return_if_fail (emfv != NULL);
 
-	conf_client = gconf_client_get_default ();
-	source_list = e_source_list_new_for_gconf (conf_client, "/apps/evolution/tasks/sources");
+	if (uids->len > 0) {
+		uid_array = g_ptr_array_new ();
+		g_ptr_array_foreach (uids, (GFunc)copy_uids, (gpointer) uid_array);
+	} else {
+		/* nothing selected */
+		return;
+	}
 
+	if (!e_cal_get_sources (&source_list, source_type, &error)) {
+		e_notice (NULL, GTK_MESSAGE_ERROR, _("Cannot get source list. %s"), error ? error->message : _("Unknown error."));
+
+		if (error)
+			g_error_free (error);
+
+		return;
+	}
+
+	/* Check if there is only one writeable source, if so do not ask user to pick it */
 	groups = e_source_list_peek_groups (source_list);
 	for (p = groups; p != NULL && !done; p = p->next) {
 		ESourceGroup *group = E_SOURCE_GROUP (p->data);
@@ -464,31 +583,31 @@ convert_to_task (GPtrArray *uid_array, struct _CamelFolder *folder, EMFolderView
 	}
 	
 	if (!source) {
+		GtkWidget *dialog;
+
 		/* ask the user which tasks list to save to */
 		dialog = e_source_selector_dialog_new (NULL, source_list);
 
 		if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
 			source = e_source_selector_dialog_peek_primary_selection (E_SOURCE_SELECTOR_DIALOG (dialog));
+
+		gtk_widget_destroy (dialog);
 	}
 
-	/* if a source has been selected, perform the mail2task operation */
 	if (source) {
+		/* if a source has been selected, perform the mail2event operation */
 		ECal *client = NULL;
 		AsyncData *data = NULL;
 		GThread *thread = NULL;
-		GError *error = NULL;
 
-		client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO);
+		client = auth_new_cal_from_source (source, source_type);
 		if (!client) {
 			char *uri = e_source_get_uri (source);
 
-			g_warning ("Could not create the client: %s\n", uri);
+			e_notice (NULL, GTK_MESSAGE_ERROR, "Could not create the client: %s", uri);
 
 			g_free (uri);
 			g_object_unref (source_list);
-			g_object_unref (conf_client);
-			if (dialog)
-				gtk_widget_destroy (dialog);
 			return;
 		}
 
@@ -497,64 +616,87 @@ convert_to_task (GPtrArray *uid_array, struct _CamelFolder *folder, EMFolderView
 		data->client = client;
 		data->folder = folder;
 		data->uids = uid_array;
+		data->with_attendees = with_attendees;
 
 		if (uid_array->len == 1)
 			data->selected_text = get_selected_text (emfv);
 		else
 			data->selected_text = NULL;
 
-		thread = g_thread_create ((GThreadFunc) do_mail_to_task, data, FALSE, &error);
+		thread = g_thread_create ((GThreadFunc) do_mail_to_event, data, FALSE, &error);
 		if (!thread) {
 			g_warning (G_STRLOC ": %s", error->message);
 			g_error_free (error);
 		}
 	}
 
-	g_object_unref (conf_client);
 	g_object_unref (source_list);
-	if (dialog)
-		gtk_widget_destroy (dialog);
+}
+
+/* ************************************************************************* */
+
+int e_plugin_lib_enable (EPluginLib *ep, int enable);
+void org_gnome_mail_to_event (void *ep, EMPopupTargetSelect *t);
+void org_gnome_mail_to_event_menu (EPlugin *ep, EMMenuTargetSelect *t);
+void org_gnome_mail_to_meeting (void *ep, EMPopupTargetSelect *t);
+void org_gnome_mail_to_meeting_menu (EPlugin *ep, EMMenuTargetSelect *t);
+void org_gnome_mail_to_task (void *ep, EMPopupTargetSelect *t);
+void org_gnome_mail_to_task_menu (EPlugin *ep, EMMenuTargetSelect *t);
+void org_gnome_mail_to_memo (void *ep, EMPopupTargetSelect *t);
+void org_gnome_mail_to_memo_menu (EPlugin *ep, EMMenuTargetSelect *t);
+
+int
+e_plugin_lib_enable (EPluginLib *ep, int enable)
+{
+	return 0;
 }
 
 void
-org_gnome_mail_to_task (void *ep, EMPopupTargetSelect *t)
+org_gnome_mail_to_event (void *ep, EMPopupTargetSelect *t)
 {
-	GPtrArray *uid_array = NULL;
+	mail_to_event (E_CAL_SOURCE_TYPE_EVENT, FALSE, t->uids, t->folder, (EMFolderView *) t->target.widget);
+}
 
-	if (t->uids->len > 0) {
-		/* FIXME Some how in the thread function the values inside t->uids gets freed
-		   and are corrupted which needs to be fixed, this is sought of work around fix for
-		   the gui inresponsiveness */
-		uid_array = g_ptr_array_new ();
-		g_ptr_array_foreach (t->uids, (GFunc)copy_uids, (gpointer) uid_array);
-	} else {
-		return;
-	}
+void
+org_gnome_mail_to_event_menu (EPlugin *ep, EMMenuTargetSelect *t)
+{
+	mail_to_event (E_CAL_SOURCE_TYPE_EVENT, FALSE, t->uids, t->folder, (EMFolderView *) t->target.widget);
+}
 
-	convert_to_task (uid_array, t->folder, (EMFolderView *) t->target.widget);
+void
+org_gnome_mail_to_meeting (void *ep, EMPopupTargetSelect *t)
+{
+	mail_to_event (E_CAL_SOURCE_TYPE_EVENT, TRUE, t->uids, t->folder, (EMFolderView *) t->target.widget);
 }
 
-void org_gnome_mail_to_task_menu (EPlugin *ep, EMMenuTargetSelect *t)
+void
+org_gnome_mail_to_meeting_menu (EPlugin *ep, EMMenuTargetSelect *t)
 {
-	GPtrArray *uid_array = NULL;
+	mail_to_event (E_CAL_SOURCE_TYPE_EVENT, TRUE, t->uids, t->folder, (EMFolderView *) t->target.widget);
+}
 
-	if (t->uids->len > 0) {
-		/* FIXME Some how in the thread function the values inside t->uids gets freed
-		   and are corrupted which needs to be fixed, this is sought of work around fix for
-		   the gui inresponsiveness */
-		uid_array = g_ptr_array_new ();
-		g_ptr_array_foreach (t->uids, (GFunc)copy_uids, (gpointer) uid_array);
-	} else {
-		return;
-	}
+void
+org_gnome_mail_to_task (void *ep, EMPopupTargetSelect *t)
+{
+	mail_to_event (E_CAL_SOURCE_TYPE_TODO, TRUE, t->uids, t->folder, (EMFolderView *) t->target.widget);
+}
 
-	convert_to_task (uid_array, t->folder, (EMFolderView *) t->target.widget);
+void
+org_gnome_mail_to_task_menu (EPlugin *ep, EMMenuTargetSelect *t)
+{
+	mail_to_event (E_CAL_SOURCE_TYPE_TODO, TRUE, t->uids, t->folder, (EMFolderView *) t->target.widget);
 }
 
-int e_plugin_lib_enable(EPluginLib *ep, int enable);
+void
+org_gnome_mail_to_memo (void *ep, EMPopupTargetSelect *t)
+{
+	/* do not set organizer and attendees for memos */
+	mail_to_event (E_CAL_SOURCE_TYPE_JOURNAL, FALSE, t->uids, t->folder, (EMFolderView *) t->target.widget);
+}
 
-int
-e_plugin_lib_enable(EPluginLib *ep, int enable)
+void
+org_gnome_mail_to_memo_menu (EPlugin *ep, EMMenuTargetSelect *t)
 {
-	return 0;
+	/* do not set organizer and attendees for memos */
+	mail_to_event (E_CAL_SOURCE_TYPE_JOURNAL, FALSE, t->uids, t->folder, (EMFolderView *) t->target.widget);
 }
diff --git a/plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml b/plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml
index 22df4c6..7421005 100644
--- a/plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml
+++ b/plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml
@@ -13,12 +13,36 @@
       <menu id="org.gnome.evolution.mail.folderview.popup" target="select">
 	<item
 	  type="item"
-	  path="71.mail_to_task"
+	  path="70.mail_to_event1"
+	  icon="appointment-new"
+	  _label="Convert to an _Event"
+	  enable="many"
+	  visible="many"
+	  activate="org_gnome_mail_to_event"/>
+	<item
+	  type="item"
+	  path="70.mail_to_event2"
+	  icon="stock_new-meeting"
+	  _label="Convert to a _Meeting"
+	  enable="many"
+	  visible="many"
+	  activate="org_gnome_mail_to_meeting"/>
+	<item
+	  type="item"
+	  path="70.mail_to_event3"
 	  icon="stock_todo"
-	  _label="Con_vert to Task"
+	  _label="Convert to a _Task"
 	  enable="many"
 	  visible="many"
 	  activate="org_gnome_mail_to_task"/>
+	<item
+	  type="item"
+	  path="70.mail_to_event4"
+	  icon="stock_insert-note"
+	  _label="Convert to a Mem_o"
+	  enable="many"
+	  visible="many"
+	  activate="org_gnome_mail_to_memo"/>
       </menu>
     </hook>
     <hook class="org.gnome.evolution.mail.bonobomenu:1.0">
@@ -27,10 +51,28 @@
 	<ui file="@PLUGINDIR@/org-gnome-mail-to-task.xml"/>
 	<item
 	  type="item"
+	  verb="ConvertEvent"
+	  path="/commands/ConvertEvent"
+	  enable="many"
+	  activate="org_gnome_mail_to_event_menu"/>
+	<item
+	  type="item"
+	  verb="ConvertMeeting"
+	  path="/commands/ConvertMeeting"
+	  enable="many"
+	  activate="org_gnome_mail_to_meeting_menu"/>
+	<item
+	  type="item"
 	  verb="ConvertTask"
 	  path="/commands/ConvertTask"
 	  enable="many"
 	  activate="org_gnome_mail_to_task_menu"/>
+	<item
+	  type="item"
+	  verb="ConvertMemo"
+	  path="/commands/ConvertMemo"
+	  enable="many"
+	  activate="org_gnome_mail_to_memo_menu"/>
       </menu>
     </hook>
     
diff --git a/plugins/mail-to-task/org-gnome-mail-to-task.xml b/plugins/mail-to-task/org-gnome-mail-to-task.xml
index 6b8033c..98accf4 100644
--- a/plugins/mail-to-task/org-gnome-mail-to-task.xml
+++ b/plugins/mail-to-task/org-gnome-mail-to-task.xml
@@ -1,15 +1,27 @@
 <Root>
   <commands>
-    <cmd name="ConvertTask" _label="Con_vert to Task"
+    <cmd name="ConvertEvent" _label="Convert to an _Event"
+      _tip="Convert the selected message to a new event"
+      pixtype="stock" pixname="appointment-new"/>
+    <cmd name="ConvertMeeting" _label="Convert to a _Meeting"
+      _tip="Convert the selected message to a new meeting"
+      pixtype="stock" pixname="stock_new-meeting"/>
+    <cmd name="ConvertTask" _label="Convert to a _Task"
       _tip="Convert the selected message to a new task"
       pixtype="stock" pixname="stock_todo"/>
+    <cmd name="ConvertMemo" _label="Convert to a Mem_o"
+      _tip="Convert the selected message to a new memo"
+      pixtype="stock" pixname="stock_insert-note"/>
   </commands>
 
   <menu>
     <placeholder name="MessagePlaceholder">	  
       <submenu name="Message">
 	  <separator f="" name="emaillist5"/>
+	  <menuitem name="ConvertEvent" verb=""/>
+	  <menuitem name="ConvertMeeting" verb=""/>
 	  <menuitem name="ConvertTask" verb=""/>
+	  <menuitem name="ConvertMemo" verb=""/>
       </submenu>
    </placeholder>
   </menu>



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