evolution-data-server r9320 - in branches/EXCHANGE_MAPI_BRANCH: addressbook/backends/mapi calendar/backends/mapi camel/providers/mapi servers/mapi



Author: msuman
Date: Mon Aug 11 10:57:15 2008
New Revision: 9320
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9320&view=rev

Log:
Initial code for rendering meeting responses, code cleanups, increment appointment seq only if modifying on organizer's calendar.

Modified:
   branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c
   branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.h
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c
   branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h

Modified: branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c	Mon Aug 11 10:57:15 2008
@@ -389,7 +389,7 @@
 	set_str_value ( E_CONTACT_FILE_AS, SPropTagArray->aulPropTag[0]);
 
 	set_str_value (E_CONTACT_FULL_NAME, PR_DISPLAY_NAME);
-	set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *)"IPM.Contact");
+	set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *)IPM_CONTACT);
 	set_str_value (E_CONTACT_FILE_AS, PR_NORMALIZED_SUBJECT);
 	set_str_value (E_CONTACT_EMAIL_1,  SPropTagArray->aulPropTag[1]);
 	set_str_value (E_CONTACT_EMAIL_1,  SPropTagArray->aulPropTag[2]);

Modified: branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.h	Mon Aug 11 10:57:15 2008
@@ -27,6 +27,7 @@
 #include <libedata-book/e-book-backend.h>
 #include <libedata-book/e-book-backend-sync.h>
 #include "exchange-mapi-connection.h"
+#include "exchange-mapi-defs.h"
 #include "exchange-mapi-utils.h"
 
 /* #include "db.h" */

Modified: branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c	Mon Aug 11 10:57:15 2008
@@ -1175,6 +1175,12 @@
 		cbdata->appt_seq = *ui32;
 	cbdata->cleanglobalid = (const struct SBinary *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BINARY, 0x0023));
 	cbdata->globalid = (const struct SBinary *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BINARY, 0x0003));
+	cbdata->username = exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_NAME);
+	cbdata->useridtype = exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_ADDRTYPE);
+	cbdata->userid = exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_EMAIL_ADDRESS);
+	cbdata->ownername = exchange_mapi_util_find_array_propval (properties, PR_SENDER_NAME);
+	cbdata->owneridtype = exchange_mapi_util_find_array_propval (properties, PR_SENDER_ADDRTYPE);
+	cbdata->ownerid = exchange_mapi_util_find_array_propval (properties, PR_SENDER_EMAIL_ADDRESS);
 
 	return TRUE;
 }
@@ -1323,6 +1329,10 @@
 			return GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED;
 	}
 
+	/* blatant HACK /me blames some stupid design in e-d-s */
+	if (e_cal_component_has_attachments (comp))
+		g_cond_signal (priv->dlock->cond);
+
 	g_object_unref (comp);
 	exchange_mapi_util_free_recipient_list (&recipients);
 	exchange_mapi_util_free_attachment_list (&attachments);
@@ -1330,6 +1340,25 @@
 	return GNOME_Evolution_Calendar_Success;
 }
 
+static gboolean
+modifier_is_organizer (ECalBackendMAPI *cbmapi, ECalComponent *comp)
+{
+	ECalComponentOrganizer org; 
+	const char *ownerid, *orgid; 
+
+	if (!e_cal_component_has_organizer(comp))
+		return TRUE;
+
+	e_cal_component_get_organizer (comp, &org);
+	if (!g_ascii_strncasecmp (org.value, "mailto:";, 7))
+		orgid = (org.value) + 7;
+	else 
+		orgid = org.value;
+	ownerid = e_cal_backend_mapi_get_owner_email (cbmapi);
+
+	return (!g_ascii_strcasecmp(orgid, ownerid) ? TRUE : FALSE);
+}
+
 static ECalBackendSyncStatus 
 e_cal_backend_mapi_modify_object (ECalBackendSync *backend, EDataCal *cal, const char *calobj, 
 				  CalObjModType mod, char **old_object, char **new_object)
@@ -1371,7 +1400,6 @@
 		return GNOME_Evolution_Calendar_OtherError;
 	}
 
-	/* FIXME: [WIP] Add support for meetings/assigned tasks */
 	if (e_cal_component_has_attendees (comp)) 
 		exchange_mapi_cal_util_fetch_recipients (comp, &recipients);
 
@@ -1381,13 +1409,6 @@
 	e_cal_component_get_uid (comp, &uid);
 	rid = e_cal_component_get_recurid_as_string (comp);
 
-	cbdata.username = e_cal_backend_mapi_get_user_name (cbmapi);
-	cbdata.useridtype = "SMTP";
-	cbdata.userid = e_cal_backend_mapi_get_user_email (cbmapi);
-	cbdata.ownername = e_cal_backend_mapi_get_owner_name (cbmapi);
-	cbdata.owneridtype = "SMTP";
-	cbdata.ownerid = e_cal_backend_mapi_get_owner_email (cbmapi);
-
 	switch (priv->mode) {
 	case CAL_MODE_ANY :
 	case CAL_MODE_REMOTE :	/* when online, send the item to the server */
@@ -1408,7 +1429,15 @@
 		cbdata.is_modify = TRUE;
 
 		get_server_data (cbmapi, icalcomp, &cbdata);
-		cbdata.appt_seq += 1;
+		if (modifier_is_organizer(cbmapi, comp)) {
+			cbdata.appt_seq += 1;
+			cbdata.username = e_cal_backend_mapi_get_user_name (cbmapi);
+			cbdata.useridtype = "SMTP";
+			cbdata.userid = e_cal_backend_mapi_get_user_email (cbmapi);
+			cbdata.ownername = e_cal_backend_mapi_get_owner_name (cbmapi);
+			cbdata.owneridtype = "SMTP";
+			cbdata.ownerid = e_cal_backend_mapi_get_owner_email (cbmapi);			
+		}
 
 		status = exchange_mapi_modify_item (priv->olFolder, priv->fid, mid, 
 						exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind), 
@@ -1434,6 +1463,10 @@
 	*old_object = e_cal_component_get_as_string (cache_comp);
 	*new_object = e_cal_component_get_as_string (comp);
 
+	/* blatant HACK /me blames some stupid design in e-d-s */
+	if (e_cal_component_has_attachments (comp))
+		g_cond_signal (priv->dlock->cond);
+
 	g_object_unref (comp);
 	g_object_unref (cache_comp);
 	exchange_mapi_util_free_recipient_list (&recipients);
@@ -1593,6 +1626,10 @@
 				g_free (old_object);
 				g_free (new_object);
 				break;
+			case ICAL_METHOD_REPLY :
+				/* responses are automatically updated even as they are rendered (just like in Outlook) */
+				status = GNOME_Evolution_Calendar_Success;
+				break; 
 			default :
 				break;
 			}
@@ -1664,13 +1701,6 @@
 			if (e_cal_component_has_attachments (comp))
 				exchange_mapi_cal_util_fetch_attachments (comp, &attachments, priv->local_attachments_store);
 
-			cbdata.username = e_cal_backend_mapi_get_user_name (cbmapi);
-			cbdata.useridtype = "SMTP";
-			cbdata.userid = e_cal_backend_mapi_get_user_email (cbmapi);
-			cbdata.ownername = e_cal_backend_mapi_get_owner_name (cbmapi);
-			cbdata.owneridtype = "SMTP";
-			cbdata.ownerid = e_cal_backend_mapi_get_owner_email (cbmapi);
-
 			cbdata.comp = comp;
 			cbdata.is_modify = TRUE;
 			cbdata.msgflags = MSGFLAG_UNSENT;
@@ -1691,6 +1721,12 @@
 			}
 
 			get_server_data (cbmapi, subcomp, &cbdata);
+			cbdata.username = e_cal_backend_mapi_get_user_name (cbmapi);
+			cbdata.useridtype = "SMTP";
+			cbdata.userid = e_cal_backend_mapi_get_user_email (cbmapi);
+			cbdata.ownername = e_cal_backend_mapi_get_owner_name (cbmapi);
+			cbdata.owneridtype = "SMTP";
+			cbdata.ownerid = e_cal_backend_mapi_get_owner_email (cbmapi);
 
 			mid = exchange_mapi_create_item (olFolderOutbox, 0, 
 							exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind), 
@@ -1714,26 +1750,8 @@
 		}
 	}
 
-	if (status == GNOME_Evolution_Calendar_Success) {
-		ECalComponent *comp;
-
-		comp = e_cal_component_new ();
-
-		if (e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp))) {
-			GSList *attendee_list = NULL, *tmp;
-			e_cal_component_get_attendee_list (comp, &attendee_list);
-			/* convert this into GList */
-			for (tmp = attendee_list; tmp; tmp = g_slist_next (tmp)) {
-				const char *attendee = tmp->data;
-
-				if (attendee)
-					*users = g_list_append (*users, g_strdup (attendee));
-			}
-
-			g_object_unref (comp);
-		}
+	if (status == GNOME_Evolution_Calendar_Success)
 		*modified_calobj = g_strdup (calobj);
-	}
 
 	icalcomponent_free (icalcomp);
 

Modified: branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c	Mon Aug 11 10:57:15 2008
@@ -36,6 +36,7 @@
 #include <camel/camel-debug.h>
 
 #include <libmapi/libmapi.h>
+#include <exchange-mapi-defs.h>
 #include <exchange-mapi-utils.h>
 
 #include "camel-mapi-store.h"
@@ -729,14 +730,14 @@
 	item->header.size = *(glong *)(find_mapi_SPropValue_data (array, PR_MESSAGE_SIZE));
 
 	msg_class = (const char *) exchange_mapi_util_find_array_propval (array, PR_MESSAGE_CLASS);
-	if (g_str_has_prefix (msg_class, "IPM.Schedule.")) {
-		char *appointment_body_str = NULL;
+	if (g_str_has_prefix (msg_class, IPM_SCHEDULE_MEETING_PREFIX)) {
+		gchar *appointment_body_str = NULL;
 		appointment_body_str = exchange_mapi_cal_util_camel_helper (array, streams, recipients, attachments);
 
 		body = g_new0(ExchangeMAPIStream, 1);
 		body->proptag = PR_BODY;
 		body->value = g_byte_array_new ();
-		body->value = g_byte_array_append (body->value, appointment_body_str, strlen (appointment_body_str));
+		body->value = g_byte_array_append (body->value, appointment_body_str, g_utf8_strlen (appointment_body_str, -1));
 
 		item->msg.body_parts = g_slist_append (item->msg.body_parts, body);
 

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c	Mon Aug 11 10:57:15 2008
@@ -23,15 +23,15 @@
 
 
 
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
 #include <glib/gstdio.h>
 #include <fcntl.h>
 #include <libecal/e-cal-util.h>
 #include "exchange-mapi-cal-utils.h"
 
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
 #define d(x) 
 
 static void appt_build_name_id (struct mapi_nameid *nameid);
@@ -66,10 +66,10 @@
 get_partstat_from_trackstatus (uint32_t trackstatus)
 {
 	switch (trackstatus) {
-		case olMeetingTentative : return ICAL_PARTSTAT_TENTATIVE;
-		case olMeetingAccepted  : return ICAL_PARTSTAT_ACCEPTED;
-		case olMeetingDeclined  : return ICAL_PARTSTAT_DECLINED;
-		default 		: return ICAL_PARTSTAT_NEEDSACTION;
+		case olResponseAccepted  : return ICAL_PARTSTAT_ACCEPTED;
+		case olResponseTentative : return ICAL_PARTSTAT_TENTATIVE;
+		case olResponseDeclined  : return ICAL_PARTSTAT_DECLINED;
+		default 		 : return ICAL_PARTSTAT_NEEDSACTION;
 	}
 }
 
@@ -77,10 +77,10 @@
 get_trackstatus_from_partstat (icalparameter_partstat partstat)
 {
 	switch (partstat) {
-		case ICAL_PARTSTAT_ACCEPTED 	: return olMeetingAccepted;
-		case ICAL_PARTSTAT_DECLINED 	: return olMeetingDeclined;
-		case ICAL_PARTSTAT_TENTATIVE 	: 
-		default 			: return olMeetingTentative;
+		case ICAL_PARTSTAT_ACCEPTED 	: return olResponseAccepted;
+		case ICAL_PARTSTAT_TENTATIVE 	: return olResponseTentative;
+		case ICAL_PARTSTAT_DECLINED 	: return olResponseDeclined;
+		default 			: return olResponseNone;
 	}
 }
 
@@ -239,42 +239,51 @@
 void
 exchange_mapi_cal_util_fetch_recipients (ECalComponent *comp, GSList **recip_list)
 {
-	GSList *al = NULL, *l;
-	ECalComponentOrganizer organizer;
-
-	e_cal_component_get_attendee_list (comp, &al);
-	e_cal_component_get_organizer (comp, &organizer);
+	icalcomponent *icalcomp = e_cal_component_get_icalcomponent (comp);
+	icalproperty *org_prop = NULL, *att_prop = NULL; 
+	const gchar *org = NULL;
+
+	org_prop = icalcomponent_get_first_property (icalcomp, ICAL_ORGANIZER_PROPERTY);
+	org = icalproperty_get_organizer (org_prop);
+	if (!org)
+		org = "";
 
-	for (l = al; l != NULL; l = l->next) {
-		ECalComponentAttendee *attendee = (ECalComponentAttendee *)(l->data);
+	att_prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+	while (att_prop) {
 		ExchangeMAPIRecipient *recipient;
 		uint32_t val = 0;
 		const char *str = NULL;
-
-		if (!attendee->value)
-			continue;
+		icalparameter *param;
 
 		recipient = g_new0 (ExchangeMAPIRecipient, 1);
 
-		if (!g_ascii_strncasecmp (attendee->value, "mailto:";, 7)) 
-			recipient->email_id = (attendee->value) + 7;
+		str = icalproperty_get_attendee (att_prop);
+		if (!g_ascii_strncasecmp (str, "mailto:";, 7)) 
+			recipient->email_id = (str) + 7;
 		else 
-			recipient->email_id = (attendee->value);
+			recipient->email_id = (str);
 
 		/* Required properties - set them always */
 		recipient->in.req_lpProps = g_new0 (struct SPropValue, 5);
 		recipient->in.req_cValues = 5;
+
 		val = 0;
 		set_SPropValue_proptag (&(recipient->in.req_lpProps[0]), PR_SEND_INTERNET_ENCODING, (const void *)&val);
-		val = RECIP_SENDABLE | (!g_ascii_strcasecmp(attendee->value, organizer.value) ? RECIP_ORGANIZER : 0);
+
+		val = RECIP_SENDABLE | (!g_ascii_strcasecmp(str, org) ? RECIP_ORGANIZER : 0);
 		set_SPropValue_proptag (&(recipient->in.req_lpProps[1]), PR_RECIPIENTS_FLAGS, (const void *)&val);
-		val = get_trackstatus_from_partstat (attendee->status);
+
+		param = icalproperty_get_first_parameter (att_prop, ICAL_PARTSTAT_PARAMETER);
+		val = get_trackstatus_from_partstat (icalparameter_get_partstat(param));
 		set_SPropValue_proptag (&(recipient->in.req_lpProps[2]), PR_RECIPIENT_TRACKSTATUS, (const void *)&val);
-		val = get_type_from_role (attendee->role);
+
+		param = icalproperty_get_first_parameter (att_prop, ICAL_ROLE_PARAMETER);
+		val = get_type_from_role (icalparameter_get_role(param));
 		set_SPropValue_proptag (&(recipient->in.req_lpProps[3]), PR_RECIPIENT_TYPE, (const void *) &val);
-		if (attendee->cn && *(attendee->cn))
-			str = attendee->cn;
-		else 
+
+		param = icalproperty_get_first_parameter (att_prop, ICAL_CN_PARAMETER);
+		str = icalparameter_get_cn (param);
+		if (!(str && *str)) 
 			str = "";
 		set_SPropValue_proptag (&(recipient->in.req_lpProps[4]), PR_RECIPIENT_DISPLAY_NAME, (const void *)(str));
 
@@ -290,16 +299,17 @@
 		set_SPropValue_proptag (&(recipient->in.ext_lpProps[2]), PR_ADDRTYPE, (const void *)(str));
 		str = recipient->email_id;
 		set_SPropValue_proptag (&(recipient->in.ext_lpProps[3]), PR_SMTP_ADDRESS, (const void *)(str));
-		if (attendee->cn && *(attendee->cn))
-			str = attendee->cn;
-		else 
+
+		param = icalproperty_get_first_parameter (att_prop, ICAL_CN_PARAMETER);
+		str = icalparameter_get_cn (param);
+		if (!(str && *str)) 
 			str = "";
 		set_SPropValue_proptag (&(recipient->in.ext_lpProps[4]), PR_DISPLAY_NAME, (const void *)(str));
 
 		*recip_list = g_slist_append (*recip_list, recipient);
-	}
 
-	e_cal_component_free_attendee_list (al);
+		att_prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+	}
 }
 
 static void
@@ -947,52 +957,235 @@
 	g_slist_free(l);
 }
 
+#define TEMP_ATTACH_STORE ".evolution/cache/tmp"
+
+static void
+change_partstat (ECalComponent *comp, const gchar *att, const gchar *sentby, icalparameter_partstat partstat)
+{
+	icalcomponent *icalcomp = e_cal_component_get_icalcomponent (comp);
+	icalproperty *attendee; 
+
+	attendee = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+	while (attendee) {
+		const char *value = icalproperty_get_attendee (attendee);
+		if (!g_ascii_strcasecmp (value, att)) {
+			icalparameter *param = icalparameter_new_partstat (partstat);
+			icalproperty_set_parameter (attendee, param);
+			if (g_ascii_strcasecmp(att, sentby)) {
+				icalparameter *sentby_param = icalparameter_new_sentby (sentby);
+				icalproperty_set_parameter (attendee, sentby_param);
+			}
+			break;
+		}
+		attendee = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+	}
+
+	e_cal_component_set_icalcomponent (comp, icalcomp);
+}
+
+static void
+remove_other_attendees (ECalComponent *comp, const gchar *att)
+{
+	icalcomponent *icalcomp = e_cal_component_get_icalcomponent (comp);
+	icalproperty *attendee; 
+
+	attendee = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+	while (attendee) {
+		const char *value = icalproperty_get_attendee (attendee);
+		if (g_ascii_strcasecmp (value, att))
+			icalcomponent_remove_property (icalcomp, attendee);
+
+		attendee = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+	}
+
+	e_cal_component_set_icalcomponent (comp, icalcomp);
+}
+
+static gboolean
+update_cb (struct mapi_SPropValue_array *properties, const mapi_id_t fid, const mapi_id_t mid, 
+	GSList *streams, GSList *recipients, GSList *attachments, gpointer data) 
+{
+	icalcomponent_kind kind = ICAL_VEVENT_COMPONENT;
+	gchar *filename = g_build_filename (g_get_home_dir (), TEMP_ATTACH_STORE, NULL);
+	gchar *fileuri = g_filename_to_uri (filename, NULL, NULL);
+	gchar *smid = exchange_mapi_util_mapi_id_to_string (mid);
+	ECalComponent *comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, smid, properties, streams, recipients, attachments, fileuri, NULL);
+	struct cbdata *cbdata = (struct cbdata *)(data);
+	const uint32_t *ui32;
+
+	ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PR_OWNER_APPT_ID);
+	cbdata->appt_id = ui32 ? *ui32 : 0;
+	ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8201));
+	cbdata->appt_seq = ui32 ? *ui32 : 0;
+	cbdata->username = exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_NAME);
+	cbdata->useridtype = exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_ADDRTYPE);
+	cbdata->userid = exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_EMAIL_ADDRESS);
+	cbdata->ownername = exchange_mapi_util_find_array_propval (properties, PR_SENDER_NAME);
+	cbdata->owneridtype = exchange_mapi_util_find_array_propval (properties, PR_SENDER_ADDRTYPE);
+	cbdata->ownerid = exchange_mapi_util_find_array_propval (properties, PR_SENDER_EMAIL_ADDRESS);
+
+	cbdata->comp = comp; 
+
+	g_free (smid);
+	g_free (fileuri);
+	g_free (filename);
+
+	return TRUE;
+}
+
+static ECalComponent * 
+update_attendee_status (struct mapi_SPropValue_array *properties, mapi_id_t mid) 
+{
+	icalcomponent_kind kind = ICAL_VEVENT_COMPONENT;
+	mapi_id_t fid;
+	const gchar *att, *att_sentby, *addrtype;
+	icalparameter_partstat partstat = ICAL_PARTSTAT_NONE;
+	const gchar *state = (const gchar *) exchange_mapi_util_find_array_propval (properties, PR_MESSAGE_CLASS);
+	struct cbdata cbdata; 
+	gboolean status = FALSE;
+	gchar *matt, *matt_sentby;
+	uint32_t cur_seq;
+	const uint32_t *ui32;
+
+	if (!(state && *state))
+		return NULL;
+
+	if (!g_ascii_strcasecmp (state, IPM_SCHEDULE_MEETING_RESP_POS))
+		partstat = ICAL_PARTSTAT_ACCEPTED;
+	else if (!g_ascii_strcasecmp (state, IPM_SCHEDULE_MEETING_RESP_TENT))
+		partstat = ICAL_PARTSTAT_TENTATIVE;
+	else if (!g_ascii_strcasecmp (state, IPM_SCHEDULE_MEETING_RESP_NEG))
+		partstat = ICAL_PARTSTAT_DECLINED;
+	else
+		return NULL;
+
+	fid = exchange_mapi_get_default_folder_id (olFolderCalendar);
+
+	exchange_mapi_connection_fetch_item (fid, mid, 
+					cal_GetPropsList, G_N_ELEMENTS (cal_GetPropsList), 
+					exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER (kind), 
+					update_cb, &cbdata, 
+					MAPI_OPTIONS_FETCH_ALL);
+
+	att = exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_EMAIL_ADDRESS);
+	addrtype = exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_ADDRTYPE);
+	if (addrtype && !g_ascii_strcasecmp (addrtype, "EX"))
+		att = exchange_mapi_util_ex_to_smtp (att);
+
+	att_sentby = exchange_mapi_util_find_array_propval (properties, PR_SENDER_EMAIL_ADDRESS);
+	addrtype = exchange_mapi_util_find_array_propval (properties, PR_SENDER_ADDRTYPE);
+	if (addrtype && !g_ascii_strcasecmp (addrtype, "EX"))
+		att_sentby = exchange_mapi_util_ex_to_smtp (att_sentby);
+
+	matt = g_strdup_printf ("MAILTO:%s", att);
+	matt_sentby = g_strdup_printf ("MAILTO:%s", att_sentby);
+
+	change_partstat (cbdata.comp, matt, matt_sentby, partstat);
+
+	ui32 = (const uint32_t *) find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8201));
+	cur_seq = ui32 ? *ui32 : 0;
+
+	if (cbdata.appt_seq == cur_seq) {
+		gchar *filename = g_build_filename (g_get_home_dir (), TEMP_ATTACH_STORE, NULL);
+		gchar *fileuri = g_filename_to_uri (filename, NULL, NULL);
+		GSList *attachments = NULL, *recipients = NULL;
+
+		if (e_cal_component_has_attachments (cbdata.comp))
+			exchange_mapi_cal_util_fetch_attachments (cbdata.comp, &attachments, fileuri);
+
+		if (e_cal_component_has_attendees (cbdata.comp))
+			exchange_mapi_cal_util_fetch_recipients (cbdata.comp, &recipients);
+
+		cbdata.meeting_type = (recipients != NULL) ? MEETING_OBJECT : NOT_A_MEETING;
+		cbdata.msgflags = MSGFLAG_READ;
+		cbdata.is_modify = TRUE;
+		cbdata.cleanglobalid = (const struct SBinary *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BINARY, 0x0023));
+		cbdata.globalid = (const struct SBinary *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BINARY, 0x0003));
+
+		status = exchange_mapi_modify_item (olFolderCalendar, fid, mid, 
+				exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER (kind), 
+				exchange_mapi_cal_util_build_props, &cbdata, 
+				recipients, attachments, MAPI_OPTIONS_DONT_SUBMIT);
+		g_free (cbdata.props);
+
+		exchange_mapi_util_free_recipient_list (&recipients);
+		exchange_mapi_util_free_attachment_list (&attachments);
+		g_free (fileuri);
+		g_free (filename);
+
+		remove_other_attendees (cbdata.comp, matt);
+	} else { 
+		g_object_unref (cbdata.comp);
+		cbdata.comp = NULL;
+	}
+
+	g_free (matt);
+	g_free (matt_sentby);
+
+	return cbdata.comp;
+}
+
 char *
 exchange_mapi_cal_util_camel_helper (struct mapi_SPropValue_array *properties, 
 				   GSList *streams, GSList *recipients, GSList *attachments)
 {
-	ECalComponent *comp;
+	ECalComponent *comp = NULL;
 	icalcomponent_kind kind = ICAL_NO_COMPONENT;
 	icalproperty_method method = ICAL_METHOD_NONE;
 	const char *msg_class = NULL;
 	mapi_id_t mid = 0;
 	const bool *b = NULL;
 	icalcomponent *icalcomp = NULL;
-	char *str = NULL;
+	char *str = NULL, *smid = NULL;
 	char *tmp;
 
 	msg_class = (const char *) exchange_mapi_util_find_array_propval (properties, PR_MESSAGE_CLASS);
 	g_return_val_if_fail (msg_class && *msg_class, NULL);
-	if (!g_ascii_strcasecmp (msg_class, "IPM.Schedule.Meeting.Request")) {
+	if (!g_ascii_strcasecmp (msg_class, IPM_SCHEDULE_MEETING_REQUEST)) {
 		method = ICAL_METHOD_REQUEST;
 		kind = ICAL_VEVENT_COMPONENT;
-	} else if (!g_ascii_strcasecmp (msg_class, "IPM.Schedule.Meeting.Canceled")) {
+	} else if (!g_ascii_strcasecmp (msg_class, IPM_SCHEDULE_MEETING_CANCELED)) {
 		method = ICAL_METHOD_CANCEL;
 		kind = ICAL_VEVENT_COMPONENT;
+	} else if (g_str_has_prefix (msg_class, IPM_SCHEDULE_MEETING_RESP_PREFIX)) {
+		method = ICAL_METHOD_REPLY;
+		kind = ICAL_VEVENT_COMPONENT;
 	} else
 		return NULL;
 
-	comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, e_cal_component_gen_uid(), 
-							properties, streams, recipients, 
-							NULL, NULL, NULL);
-
-	b = (const bool *) find_mapi_SPropValue_data(properties, PR_PROCESSED);
-
 	check_server_for_object (properties, &mid);
+	if (method == ICAL_METHOD_REPLY) {
+		if (mid)
+	 		comp = update_attendee_status (properties, mid);
+	} else { 
+		if (mid)
+			smid = exchange_mapi_util_mapi_id_to_string (mid);
+		else 
+			smid = e_cal_component_gen_uid();
 
-	if (!(b && *b) && method != ICAL_METHOD_CANCEL)
-		update_server_object (properties, attachments, comp, &mid);
+		comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, smid, 
+							properties, streams, recipients, 
+							NULL, NULL, NULL);
 
-	tmp = exchange_mapi_util_mapi_id_to_string (mid);
-	e_cal_component_set_uid (comp, tmp);
-	g_free (tmp);
+		b = (const bool *) find_mapi_SPropValue_data(properties, PR_PROCESSED);
+		if (!(b && *b) && method != ICAL_METHOD_CANCEL)
+			update_server_object (properties, attachments, comp, &mid);
+
+		tmp = exchange_mapi_util_mapi_id_to_string (mid);
+		e_cal_component_set_uid (comp, tmp);
+		g_free (tmp);
+		g_free (smid);
+	}
 
 	icalcomp = e_cal_util_new_top_level ();
 	icalcomponent_set_method (icalcomp, method);
-	icalcomponent_add_component (icalcomp, icalcomponent_new_clone(e_cal_component_get_icalcomponent(comp)));
+	if (comp)
+		icalcomponent_add_component (icalcomp, 
+			icalcomponent_new_clone(e_cal_component_get_icalcomponent(comp)));
 	str = icalcomponent_as_ical_string (icalcomp);
 	icalcomponent_free (icalcomp);
-	g_object_unref (comp);
+	if (comp)
+		g_object_unref (comp);
 
 	return str;
 }
@@ -1405,7 +1598,7 @@
 		const char *mapi_tzid;
 		struct SBinary start_tz, end_tz; 
 
-		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_APPTMSGCLASS], (const void *) "IPM.Appointment");
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_APPTMSGCLASS], (const void *) IPM_APPOINTMENT);
 
 		/* Busy Status */
 		flag32 = olBusy; 	/* default */
@@ -1415,6 +1608,7 @@
 		if (cbdata->meeting_type == MEETING_CANCEL)
 			flag32 = olFree;
 		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INTENDEDBUSY], (const void *) &flag32);
+
 		if (cbdata->meeting_type == MEETING_REQUEST || cbdata->meeting_type == MEETING_REQUEST_RCVD) {
 			flag32 = olTentative;
 			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_BUSYSTATUS], (const void *) &flag32);
@@ -1487,7 +1681,7 @@
 
 		switch (cbdata->meeting_type) {
 		case MEETING_OBJECT :
-			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) IPM_APPOINTMENT);
 
 			flag32 = e_cal_component_has_recurrences (comp) ? RecurMeet : SingleMeet; 
 			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
@@ -1509,7 +1703,7 @@
 
 			break;
 		case MEETING_REQUEST :
-			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Schedule.Meeting.Request");
+			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) IPM_SCHEDULE_MEETING_REQUEST);
 
 			flag32 = 0xFFFFFFFF;  /* no idea why this has to be -1, but that's what the docs say */
 			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
@@ -1531,7 +1725,7 @@
 
 			break;
 		case MEETING_REQUEST_RCVD :
-			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) IPM_APPOINTMENT);
 
 			flag32 = e_cal_component_has_recurrences (comp) ? RecurMeet : SingleMeet; 
 			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
@@ -1553,7 +1747,7 @@
 
 			break;
 		case MEETING_CANCEL :
-			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Schedule.Meeting.Canceled");
+			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) IPM_SCHEDULE_MEETING_CANCELED);
 
 			flag32 = 0xFFFFFFFF;  /* no idea why this has to be -1, but that's what the docs say */ 
 			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
@@ -1575,18 +1769,20 @@
 
 			break;
 		case MEETING_RESPONSE_ACCEPT : 
-			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+		case MEETING_RESPONSE_DECLINE : 
+		case MEETING_RESPONSE_TENTATIVE : 
+			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) IPM_SCHEDULE_MEETING_RESP_POS);
 
-			flag32 = RespAccept; 
+			flag32 = 0xFFFFFFFF;  /* no idea why this has to be -1, but that's what the docs say */ 
 			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
 
-			flag32 = 0x0171;
+			flag32 = 0x1C61;
 			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
-/*
-			flag32 = ???;
+
+			flag32 = asfNone;
 			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_STATEFLAGS], (const void *) &flag32);
-*/
-			flag32 = mtgRequest; 
+
+			flag32 = mtgEmpty; 
 			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_TYPE], (const void *) &flag32);
 
 			flag32 = olResponseAccepted;
@@ -1595,7 +1791,7 @@
 			break;
 		case NOT_A_MEETING :
 		default :
-			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) IPM_APPOINTMENT);
 
 			flag32 = e_cal_component_has_recurrences (comp) ? RecurAppt : SingleAppt; 
 			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
@@ -1629,7 +1825,7 @@
 	} else if (kind == ICAL_VTODO_COMPONENT) {
 		double d;
 
-		set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Task");
+		set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) IPM_TASK);
 
 		/* Context menu flags */ /* FIXME: for assigned tasks */
 		flag32 = 0x0110; 
@@ -1679,7 +1875,7 @@
 		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_TASK_ISRECURRING], (const void *) &b);
 
 	} else if (kind == ICAL_VJOURNAL_COMPONENT) {
-		set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.StickyNote");
+		set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) IPM_STICKYNOTE);
 
 		/* Context menu flags */
 		flag32 = 0x0110; 

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c	Mon Aug 11 10:57:15 2008
@@ -47,11 +47,13 @@
 #define DISABLE_VERBOSE_LOG() 	global_mapi_ctx->dumpdata = FALSE;
 #endif
 
+//#if 0
 #define LOGALL()
 #define LOGNONE()
 
 #define ENABLE_VERBOSE_LOG()
 #define DISABLE_VERBOSE_LOG()
+//#endif 
 
 /* Specifies READ/WRITE sizes to be used while handling attachment streams */
 #define ATTACH_MAX_READ_SIZE  0x1000

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h	Mon Aug 11 10:57:15 2008
@@ -159,6 +159,7 @@
 } OlMeetingStatus;
 
 typedef enum {
+    asfNone = 0,
     asfMeeting = 1,
     asfReceived = 2,
     asfCanceled = 4
@@ -246,6 +247,19 @@
 } OlRecurrencePatternType;
 
 
+#define IPM_CONTACT 				"IPM.Contact"
+#define IPM_APPOINTMENT 			"IPM.Appointment"
+#define IPM_SCHEDULE_MEETING_PREFIX 		"IPM.Schedule.Meeting."
+#define IPM_SCHEDULE_MEETING_REQUEST 		"IPM.Schedule.Meeting.Request"
+#define IPM_SCHEDULE_MEETING_CANCELED 		"IPM.Schedule.Meeting.Canceled"
+#define IPM_SCHEDULE_MEETING_RESP_PREFIX 	"IPM.Schedule.Meeting.Resp."
+#define IPM_SCHEDULE_MEETING_RESP_POS 		"IPM.Schedule.Meeting.Resp.Pos"
+#define IPM_SCHEDULE_MEETING_RESP_TENT 		"IPM.Schedule.Meeting.Resp.Tent"
+#define IPM_SCHEDULE_MEETING_RESP_NEG 		"IPM.Schedule.Meeting.Resp.Neg"
+#define IPM_TASK 				"IPM.Task"
+#define IPM_STICKYNOTE 				"IPM.StickyNote"
+
+
 G_END_DECLS
 
 #endif



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