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



Author: msuman
Date: Mon Jul 28 09:43:05 2008
New Revision: 9208
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9208&view=rev

Log:
Handle meeting cancelations, API change for check_restriction, don't create object on server if required conditions are not satisfied.

Modified:
   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-cal-utils.h
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-utils.c

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 Jul 28 09:43:05 2008
@@ -1160,30 +1160,6 @@
 		return status;
 }
 
-static uint32_t
-get_new_appt_id (ECalBackendMAPI *cbmapi)
-{
-	ECalBackendMAPIPrivate *priv = cbmapi->priv;
-	struct mapi_SRestriction res;
-	struct SPropValue sprop;
-	uint32_t id, count = 0x1;
-
-	res.rt = RES_PROPERTY;
-	res.res.resProperty.relop = RELOP_EQ;
-	res.res.resProperty.ulPropTag = PR_OWNER_APPT_ID;
-
-	while (count) {
-		id = g_random_int ();
-		if (id) {
-			set_SPropValue_proptag (&sprop, PR_OWNER_APPT_ID, (const void *) &id);
-			cast_mapi_SPropValue (&(res.res.resProperty.lpProp), &sprop);
-			count = exchange_mapi_util_check_restriction (priv->fid, &res);
-		}
-	}
-
-	return id;
-}
-
 static gboolean 
 capture_req_props (struct mapi_SPropValue_array *properties, const mapi_id_t fid, const mapi_id_t mid, 
 		   GSList *streams, GSList *recipients, GSList *attachments, gpointer data)
@@ -1312,7 +1288,7 @@
 			cbdata.is_modify = FALSE;
 			cbdata.msgflags = MSGFLAG_READ;
 			cbdata.meeting_type = (recipients != NULL) ? MEETING_OBJECT : NOT_A_MEETING;
-			cbdata.appt_id = get_new_appt_id (cbmapi);
+			cbdata.appt_id = exchange_mapi_cal_util_get_new_appt_id (priv->fid);
 			cbdata.appt_seq = 0;
 			e_cal_component_get_uid (comp, &compuid);
 			exchange_mapi_cal_util_generate_globalobjectid (TRUE, compuid, &globalid);
@@ -1567,10 +1543,73 @@
 static ECalBackendSyncStatus 
 e_cal_backend_mapi_receive_objects (ECalBackendSync *backend, EDataCal *cal, const char *calobj)
 {
+	ECalBackendSyncStatus status = GNOME_Evolution_Calendar_OtherError;
+	ECalBackendMAPI *cbmapi;
+	ECalBackendMAPIPrivate *priv;
+	icalcomponent_kind kind;
+	icalcomponent *icalcomp;
 
-	return GNOME_Evolution_Calendar_Success;
+	cbmapi = E_CAL_BACKEND_MAPI (backend);
+	priv = cbmapi->priv;
+	kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
+
+	g_return_val_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), GNOME_Evolution_Calendar_InvalidObject);
+	g_return_val_if_fail (calobj != NULL, GNOME_Evolution_Calendar_InvalidObject);
+
+	if (priv->mode == CAL_MODE_LOCAL)
+		return GNOME_Evolution_Calendar_RepositoryOffline;
+
+	/* check the component for validity */
+	icalcomp = icalparser_parse_string (calobj);
+	if (!icalcomp)
+		return GNOME_Evolution_Calendar_InvalidObject;
+
+	if (icalcomponent_isa (icalcomp) == ICAL_VCALENDAR_COMPONENT) {
+		gboolean stop = FALSE;
+		icalproperty_method method = icalcomponent_get_method (icalcomp);
+		icalcomponent *subcomp = icalcomponent_get_first_component (icalcomp, kind);
+		while (subcomp && !stop) {
+			ECalComponent *comp = e_cal_component_new ();
+			gchar *rid = NULL; 
+			const char *uid;
+			gchar *old_object = NULL, *new_object = NULL; 
+
+			e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (subcomp));
+
+			/* FIXME: Add support for recurrences */
+			if (e_cal_component_has_recurrences (comp)) {
+				g_object_unref (comp);
+				return GNOME_Evolution_Calendar_OtherError;
+			}
+
+			e_cal_component_get_uid (comp, &uid);
+			rid = e_cal_component_get_recurid_as_string (comp);
+
+			switch (method) {
+			case ICAL_METHOD_CANCEL :
+				status = e_cal_backend_mapi_remove_object (backend, cal, uid, rid, CALOBJ_MOD_THIS, &old_object, &new_object);
+				if (status != GNOME_Evolution_Calendar_Success)
+					stop = TRUE;
+				g_free (old_object);
+				g_free (new_object);
+				break;
+			default :
+				break;
+			}
+
+			g_free (rid);
+			g_object_unref (comp);
+
+			subcomp = icalcomponent_get_next_component (icalcomp,
+								    e_cal_backend_get_kind (E_CAL_BACKEND (backend)));
+		}
+	}
+
+	return status;
 }
 
+
+
 static ECalBackendSyncStatus 
 e_cal_backend_mapi_send_objects (ECalBackendSync *backend, EDataCal *cal, const char *calobj, 
 				 GList **users, char **modified_calobj)
@@ -1617,7 +1656,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);
 				method = icalcomponent_get_method (icalcomp);
@@ -1640,8 +1678,12 @@
 				cbdata.meeting_type = MEETING_REQUEST;
 				cbdata.msgflags = MSGFLAG_UNSENT ;
 				break;
+			case ICAL_METHOD_CANCEL : 
+				cbdata.meeting_type = MEETING_CANCEL;
+				cbdata.msgflags = MSGFLAG_UNSENT ;
+				break;
 			case ICAL_METHOD_RESPONSE : 
-				cbdata.meeting_type = MEETING_RESPONSE;
+				cbdata.meeting_type = MEETING_RESPONSE_ACCEPT;
 				cbdata.msgflags = MSGFLAG_UNSENT;
 				break;
 			default :
@@ -1673,7 +1715,6 @@
 								    e_cal_backend_get_kind (E_CAL_BACKEND (backend)));
 		}
 	}
-	/* We need another static capability to say the backend has already sent the requests. */
 
 	if (status == GNOME_Evolution_Calendar_Success) {
 		ECalComponent *comp;

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 Jul 28 09:43:05 2008
@@ -586,6 +586,7 @@
 	PR_MID, 
 
 	PR_MESSAGE_CLASS, 
+	PR_MESSAGE_CLASS_UNICODE, 
 	PR_MESSAGE_SIZE, 
 	PR_MESSAGE_FLAGS, 
 	PR_MESSAGE_DELIVERY_TIME, 
@@ -612,6 +613,7 @@
 	PR_END_DATE, 
 	PR_RESPONSE_REQUESTED, 
 	PR_OWNER_APPT_ID, 
+	PR_PROCESSED, 
 
 	PR_SENT_REPRESENTING_NAME, 
 	PR_SENT_REPRESENTING_NAME_UNICODE, 
@@ -736,7 +738,7 @@
 	item->header.from = g_strdup (exchange_mapi_util_find_array_propval (array, PR_SENT_REPRESENTING_NAME));
 	item->header.size = *(glong *)(find_mapi_SPropValue_data (array, PR_MESSAGE_SIZE));
 
-	msg_class = (const char *)find_mapi_SPropValue_data (array, PR_MESSAGE_CLASS);
+	msg_class = (const char *) exchange_mapi_util_find_array_propval (array, PR_MESSAGE_CLASS);
 	if (g_str_has_prefix (msg_class, "IPM.Schedule.")) {
 		item->msg.body_plain_text = exchange_mapi_cal_util_camel_helper (array, streams, recipients, attachments);
 		item->is_cal = TRUE;

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 Jul 28 09:43:05 2008
@@ -600,6 +600,16 @@
 			g_free (value);
 		}
 
+		/* AppointmentSequence */
+		ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8201));
+		if (ui32) {
+			gchar *value = g_strdup_printf ("%d", *ui32);
+			prop = icalproperty_new_x (value);
+			icalproperty_set_x_name (prop, "X-EVOLUTION-MAPI-APPTSEQ");
+			icalcomponent_add_property (ical_comp, prop);
+			g_free (value);
+		}
+
 		location = (const char *)exchange_mapi_util_find_array_propval(properties, PROP_TAG(PT_STRING8, 0x8208));
 		if (location && *location)
 			icalcomponent_set_location (ical_comp, location);
@@ -786,55 +796,176 @@
 	return comp;
 }
 
+static gboolean 
+capture_req_props (struct mapi_SPropValue_array *properties, const mapi_id_t fid, const mapi_id_t mid, 
+		   GSList *streams, GSList *recipients, GSList *attachments, gpointer data)
+{
+	struct cbdata *cbdata = (struct cbdata *) data;
+	const uint32_t *ui32;
+
+	ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8201));
+	if (ui32)
+		cbdata->appt_seq = *ui32;
+	else 
+		cbdata->appt_seq = 0;
+
+	return TRUE;
+}
+
+static void 
+update_server_object (struct mapi_SPropValue_array *properties, GSList *attachments, ECalComponent *comp, mapi_id_t *mid)
+{
+	const uint32_t *ui32 = NULL;
+	uint32_t cur_seq;
+	mapi_id_t fid;
+	gboolean create_new = TRUE;
+
+	fid = exchange_mapi_get_default_folder_id (olFolderCalendar);
+
+	ui32 = (const uint32_t *) find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8201));
+	if (ui32)
+		cur_seq = *ui32;
+
+	if (*mid) {
+		struct cbdata server_cbdata;
+		server_cbdata.appt_seq = 0;
+
+		exchange_mapi_connection_fetch_item (fid, *mid, 
+			NULL, 0, 
+			NULL, NULL, 
+			capture_req_props, &server_cbdata, 
+			0);
+
+		if (cur_seq > server_cbdata.appt_seq) {
+			struct id_list idlist; 
+			GSList *ids = NULL;
+
+			idlist.id = *mid;
+			ids = g_slist_append (ids, &idlist);
+
+			exchange_mapi_remove_items (olFolderCalendar, fid, ids);
+		} else 
+			create_new = FALSE;
+	}
+
+	if (create_new) {
+		struct cbdata cbdata;
+		GSList *myrecipients = NULL;
+		GSList *myattachments = NULL;
+		icalcomponent_kind kind = icalcomponent_isa (e_cal_component_get_icalcomponent(comp));
+
+		cbdata.comp = comp;
+		cbdata.username = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_NAME);
+		cbdata.useridtype = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_ADDRTYPE);
+		cbdata.userid = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_EMAIL_ADDRESS);
+		cbdata.ownername = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_NAME);
+		cbdata.owneridtype = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_ADDRTYPE);
+		cbdata.ownerid = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_EMAIL_ADDRESS);
+		cbdata.is_modify = FALSE;
+		cbdata.msgflags = MSGFLAG_READ;
+		cbdata.meeting_type = MEETING_REQUEST_RCVD;
+		cbdata.appt_seq = (*(const uint32_t *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8201)));
+		cbdata.appt_id = (*(const uint32_t *)find_mapi_SPropValue_data(properties, PR_OWNER_APPT_ID));
+		cbdata.globalid = (const struct SBinary *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BINARY, 0x0003));
+		cbdata.cleanglobalid = (const struct SBinary *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BINARY, 0x0023));
+
+		exchange_mapi_cal_util_fetch_recipients (comp, &myrecipients);
+		myattachments = attachments;
+		*mid = exchange_mapi_create_item (olFolderCalendar, 0, 
+					exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
+					exchange_mapi_cal_util_build_props, &cbdata, 
+					myrecipients, myattachments, NULL, MAPI_OPTIONS_DONT_SUBMIT);
+		g_free (cbdata.props);
+		exchange_mapi_util_free_recipient_list (&myrecipients);
+	}
+}
+
+static void
+check_server_for_object (struct mapi_SPropValue_array *properties, mapi_id_t *mid)
+{
+	struct mapi_SRestriction res;
+	struct SPropValue sprop;
+	const struct SBinary *sb;
+	uint32_t proptag = 0x0;
+	struct SPropTagArray *array;
+	GSList *ids = NULL, *l;
+	mapi_id_t fid;
+
+	*mid = 0;
+
+	fid = exchange_mapi_get_default_folder_id (olFolderCalendar);
+
+	array = exchange_mapi_util_resolve_named_prop (olFolderCalendar, fid, 0x0023, PSETID_Meeting);
+	proptag = array->aulPropTag[0];
+
+	res.rt = RES_PROPERTY;
+	res.res.resProperty.relop = RELOP_EQ;
+	res.res.resProperty.ulPropTag = proptag;
+
+	sb = (const struct SBinary *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BINARY, 0x0023));
+
+	set_SPropValue_proptag (&sprop, proptag, (const void *) sb);
+	cast_mapi_SPropValue (&(res.res.resProperty.lpProp), &sprop);
+
+	ids = exchange_mapi_util_check_restriction (fid, &res);
+
+	if (ids && g_slist_length(ids) == 1) {
+		struct id_list *idlist = (struct id_list *)(ids->data);
+		*mid = idlist->id;
+	} else 
+	/* FIXME: what to do here? */
+	;
+
+	for (l = ids; l; l = l->next)
+		g_free(l->data);
+	g_slist_free(l);
+}
+
 char *
 exchange_mapi_cal_util_camel_helper (struct mapi_SPropValue_array *properties, 
 				   GSList *streams, GSList *recipients, GSList *attachments)
 {
 	ECalComponent *comp;
-	struct cbdata cbdata;
-	GSList *myrecipients = NULL;
-	GSList *myattachments = 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 *tmp;
-	icalcomponent *icalcomp = NULL;
 
-	comp = exchange_mapi_cal_util_mapi_props_to_comp (ICAL_VEVENT_COMPONENT, e_cal_component_gen_uid(), 
-						properties, streams, recipients, NULL, NULL, 
-						NULL);
-
-	cbdata.comp = comp;
-	cbdata.username = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_NAME);
-	cbdata.useridtype = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_ADDRTYPE);
-	cbdata.userid = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_EMAIL_ADDRESS);
-	cbdata.ownername = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_NAME);
-	cbdata.owneridtype = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_ADDRTYPE);
-	cbdata.ownerid = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_EMAIL_ADDRESS);
-	cbdata.is_modify = FALSE;
-	cbdata.msgflags = MSGFLAG_READ;
-	cbdata.meeting_type = MEETING_OBJECT_RCVD;
-	cbdata.appt_seq = (*(const uint32_t *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8201)));
-	cbdata.appt_id = (*(const uint32_t *)find_mapi_SPropValue_data(properties, PR_OWNER_APPT_ID));
-	cbdata.globalid = (const struct SBinary *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BINARY, 0x0003));
-	cbdata.cleanglobalid = (const struct SBinary *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BINARY, 0x0023));
-
-	exchange_mapi_cal_util_fetch_recipients (comp, &myrecipients);
-	myattachments = attachments;
-	mid = exchange_mapi_create_item (olFolderCalendar, 0, 
-					exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(ICAL_VEVENT_COMPONENT),
-					exchange_mapi_cal_util_build_props, &cbdata, 
-					myrecipients, myattachments, NULL, MAPI_OPTIONS_DONT_SUBMIT);
-	g_free (cbdata.props);
-	exchange_mapi_util_free_recipient_list (&myrecipients);
+	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")) {
+		method = ICAL_METHOD_REQUEST;
+		kind = ICAL_VEVENT_COMPONENT;
+	} else if (!g_ascii_strcasecmp (msg_class, "IPM.Schedule.Meeting.Canceled")) {
+		method = ICAL_METHOD_CANCEL;
+		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 (!(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);
 
 	icalcomp = e_cal_util_new_top_level ();
-	icalcomponent_set_method (icalcomp, ICAL_METHOD_REQUEST);
-	icalcomponent_add_component (icalcomp, e_cal_component_get_icalcomponent(comp));
+	icalcomponent_set_method (icalcomp, method);
+	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);
 
 	return str;
@@ -929,8 +1060,7 @@
 	I_APPT_CLIPSTART , 
 	I_APPT_CLIPEND , 
 	I_APPT_AUTOLOCATION , 
-	I_APPT_ISONLINEMEET , 
-	I_APPT_COUNTERPROPOSAL , 
+	I_APPT_NOTALLOWPROPOSE , 
 	I_APPT_STARTTZBLOB , 
 	I_APPT_ENDTZBLOB ,
 
@@ -973,15 +1103,14 @@
 	mapi_nameid_lid_add(nameid, 0x8235, PSETID_Appointment); 	// PT_SYSTIME - (dtstart)(for recurring events UTC 12 AM of day of start)
 	mapi_nameid_lid_add(nameid, 0x8236, PSETID_Appointment); 	// PT_SYSTIME - (dtend)(for recurring events UTC 12 AM of day of end)
 	mapi_nameid_lid_add(nameid, 0x823A, PSETID_Appointment); 	// PT_BOOLEAN - AutoFillLocation
-	mapi_nameid_lid_add(nameid, 0x8240, PSETID_Appointment); 	// PT_BOOLEAN - IsOnlineMeeting
-	mapi_nameid_lid_add(nameid, 0x8257, PSETID_Appointment); 	// PT_BOOLEAN - ApptCounterProposal
+	mapi_nameid_lid_add(nameid, 0x825A, PSETID_Appointment); 	// PT_BOOLEAN - ApptNotAllowPropose
 	mapi_nameid_lid_add(nameid, 0x825E, PSETID_Appointment); 	// PT_BINARY - (timezone for dtstart)
 	mapi_nameid_lid_add(nameid, 0x825F, PSETID_Appointment); 	// PT_BINARY - (timezone for dtend)
 
 	mapi_nameid_lid_add(nameid, 0x0002, PSETID_Meeting); 		// PT_STRING8 - Where
 	mapi_nameid_lid_add(nameid, 0x0003, PSETID_Meeting); 		// PT_BINARY - GlobalObjectId
 	mapi_nameid_lid_add(nameid, 0x0005, PSETID_Meeting); 		// PT_BOOLEAN - IsRecurring
-	mapi_nameid_lid_add(nameid, 0x000a, PSETID_Meeting); 		// PT_BOOLEAN - IsException 
+	mapi_nameid_lid_add(nameid, 0x000A, PSETID_Meeting); 		// PT_BOOLEAN - IsException 
 	mapi_nameid_lid_add(nameid, 0x0023, PSETID_Meeting); 		// PT_BINARY - CleanGlobalObjectId
 	mapi_nameid_lid_add(nameid, 0x0024, PSETID_Meeting); 		// PT_STRING8 - AppointmentMessageClass 
 	mapi_nameid_lid_add(nameid, 0x0026, PSETID_Meeting); 		// PT_LONG - MeetingType
@@ -1075,7 +1204,6 @@
 	ECalComponent *comp = cbdata->comp;
 	icalcomponent *ical_comp = e_cal_component_get_icalcomponent (comp);
 	icalcomponent_kind  kind = icalcomponent_isa (ical_comp);
-	gboolean has_attendees = e_cal_component_has_attendees (comp);
 	struct SPropValue *props = NULL;
 	int i=0;
 	uint32_t flag32;
@@ -1090,31 +1218,21 @@
 	switch (kind) {
 		case ICAL_VEVENT_COMPONENT:
 			props = g_new0 (struct SPropValue, REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + APPT_NAMED_PROPS_N);
-			g_print ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + APPT_NAMED_PROPS_N);
-			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_APPTMSGCLASS], (const void *) "IPM.Appointment");
-			if (has_attendees) {
-				if (cbdata->meeting_type & MEETING_OBJECT)
-					set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
-				else if (cbdata->meeting_type & MEETING_REQUEST)
-					set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Schedule.Meeting.Request");
-				else 
-					set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
-			} else
-				set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+			g_debug ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + APPT_NAMED_PROPS_N);
 			break;
 		case ICAL_VTODO_COMPONENT:
 			props = g_new0 (struct SPropValue, REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + TASK_NAMED_PROPS_N);
-			g_print ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + TASK_NAMED_PROPS_N);
-			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Task");
+			g_debug ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + TASK_NAMED_PROPS_N);
 			break;
 		case ICAL_VJOURNAL_COMPONENT:
 			props = g_new0 (struct SPropValue, REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + NOTE_NAMED_PROPS_N);
-			g_print ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + NOTE_NAMED_PROPS_N);
-			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.StickyNote");
+			g_debug ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + NOTE_NAMED_PROPS_N);
 			break;
 		default:
 			return 0;
-	} 											/* prop count: 1 */
+	} 
+
+	/* PR_MESSAGE_CLASS needs to be set appropriately */					/* prop count: 1 */
 
 	utc_zone = icaltimezone_get_utc_timezone ();
 
@@ -1261,15 +1379,22 @@
 		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");
+
 		/* Busy Status */
 		flag32 = olBusy; 	/* default */
 		prop = icalcomponent_get_first_property (ical_comp, ICAL_TRANSP_PROPERTY);
 		if (prop)
 			flag32 = get_prop_from_transp (icalproperty_get_transp (prop));
+		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_OBJECT_RCVD) {
+		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);
+		} else if (cbdata->meeting_type == MEETING_CANCEL) {
+			flag32 = olFree;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_BUSYSTATUS], (const void *) &flag32);
 		} else 
 			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_BUSYSTATUS], (const void *) &flag32);
 
@@ -1336,6 +1461,8 @@
 
 		switch (cbdata->meeting_type) {
 		case MEETING_OBJECT :
+			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);
 
@@ -1355,7 +1482,31 @@
 			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INVITED], (const void *) &b);
 
 			break;
-		case MEETING_OBJECT_RCVD :
+		case 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);
+
+			flag32 = 0x1C61;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+
+			flag32 = olMeetingReceived;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_MEETINGSTATUS], (const void *) &flag32);
+
+			flag32 = (cbdata->appt_seq == 0) ? mtgRequest : mtgFull; 
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_TYPE], (const void *) &flag32);
+
+			flag32 = olResponseNotResponded;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RESPONSESTATUS], (const void *) &flag32);
+
+			b = 1;
+			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INVITED], (const void *) &b);
+
+			break;
+		case MEETING_REQUEST_RCVD :
+			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);
 
@@ -1375,17 +1526,19 @@
 			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INVITED], (const void *) &b);
 
 			break;
-		case MEETING_REQUEST :
-			flag32 = 0xFFFFFFFF;  /* no idea why this has to be -1, but that's what the docs say */
+		case MEETING_CANCEL :
+			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Schedule.Meeting.Canceled");
+
+			flag32 = e_cal_component_has_recurrences (comp) ? RecurMeet : SingleMeet; 
 			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
 
-			flag32 = 0x1C61;
+			flag32 = 0x0171;
 			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
 
-			flag32 = olMeetingReceived;
+			flag32 = olMeetingCanceled;
 			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_MEETINGSTATUS], (const void *) &flag32);
 
-			flag32 = (cbdata->appt_seq == 0) ? mtgRequest : mtgFull; 
+			flag32 = mtgFull; 
 			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_TYPE], (const void *) &flag32);
 
 			flag32 = olResponseNotResponded;
@@ -1395,7 +1548,9 @@
 			set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INVITED], (const void *) &b);
 
 			break;
-		case MEETING_RESPONSE : 
+		case MEETING_RESPONSE_ACCEPT : 
+			set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+
 			flag32 = RespAccept; 
 			set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
 
@@ -1414,6 +1569,8 @@
 			break;
 		case NOT_A_MEETING :
 		default :
+			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);
 
@@ -1439,17 +1596,15 @@
 		b = e_cal_component_has_exceptions (comp) && FALSE; b = 0;
 		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_ISEXCEPTION], (const void *) &b);
 
-		/* Online Meeting : we probably would never support this */
-		b = 0;
-		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_ISONLINEMEET], (const void *) &b);
-
 		/* Counter Proposal for appointments : not supported */
-		b = 0;
-		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_COUNTERPROPOSAL], (const void *) &b);
+		b = 1;
+		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_NOTALLOWPROPOSE], (const void *) &b);
 
 	} else if (kind == ICAL_VTODO_COMPONENT) {
 		double d;
 
+		set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Task");
+
 		/* Context menu flags */ /* FIXME: for assigned tasks */
 		flag32 = 0x0110; 
 		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
@@ -1498,6 +1653,8 @@
 		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");
+
 		/* Context menu flags */
 		flag32 = 0x0110; 
 		set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
@@ -1510,8 +1667,39 @@
 	/* Free this memory at the backends. */
 	cbdata->props = props;
 
-	g_print ("\nEnded up setting %d props\n", i);
+	g_debug ("\nEnded up setting %d props\n", i);
 
 	return i;
 }
 
+uint32_t
+exchange_mapi_cal_util_get_new_appt_id (mapi_id_t fid)
+{
+	struct mapi_SRestriction res;
+	struct SPropValue sprop;
+	uint32_t id;
+	gboolean found = FALSE;
+
+	res.rt = RES_PROPERTY;
+	res.res.resProperty.relop = RELOP_EQ;
+	res.res.resProperty.ulPropTag = PR_OWNER_APPT_ID;
+
+	while (!found) {
+		id = g_random_int ();
+		if (id) {
+			GSList *ids = NULL;
+			set_SPropValue_proptag (&sprop, PR_OWNER_APPT_ID, (const void *) &id);
+			cast_mapi_SPropValue (&(res.res.resProperty.lpProp), &sprop);
+			ids = exchange_mapi_util_check_restriction (fid, &res);
+			if (ids) {
+				GSList *l;
+				for (l = ids; l; l = l->next)
+					g_free (l->data);
+			} else 
+				found = TRUE;
+		}
+	};
+
+	return id;
+}
+

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h	Mon Jul 28 09:43:05 2008
@@ -38,11 +38,16 @@
 
 typedef enum {
 	NOT_A_MEETING = 0, 
-	MEETING_OBJECT = (1 << 0),
-	MEETING_OBJECT_SENT = (1 << 1),
-	MEETING_OBJECT_RCVD = (1 << 2), 
-	MEETING_REQUEST = (1 << 3), 
-	MEETING_RESPONSE = (1 << 4)
+	MEETING_OBJECT 		= (1 << 0),
+	MEETING_OBJECT_SENT 	= (1 << 1),
+	MEETING_REQUEST 	= (1 << 2), 
+	MEETING_REQUEST_RCVD 	= (1 << 3), 
+	MEETING_RESPONSE_ACCEPT = (1 << 4), 
+	MEETING_RESPONSE_DECLINE = (1 << 5), 
+	MEETING_RESPONSE_TENTATIVE = (1 << 6), 
+	MEETING_RESPONSE_RCVD 	= (1 << 7), 
+	MEETING_CANCEL 		= (1 << 8), 
+	MEETING_CANCEL_RCVD 	= (1 << 9)
 } MAPIMeetingOptions;
 
 struct cbdata { 
@@ -89,6 +94,9 @@
 exchange_mapi_cal_util_camel_helper (struct mapi_SPropValue_array *properties, 
 				   GSList *streams, GSList *recipients, GSList *attachments);
 
+uint32_t
+exchange_mapi_cal_util_get_new_appt_id (mapi_id_t fid);
+
 /* we don't have to specify the PR_BODY_* tags since it is fetched by default */
 static const uint32_t cal_GetPropsList[] = {
 	PR_FID, 
@@ -109,6 +117,7 @@
 	PR_END_DATE, 
 	PR_RESPONSE_REQUESTED, 
 	PR_OWNER_APPT_ID, 
+	PR_PROCESSED, 
 
 	PR_SENT_REPRESENTING_NAME, 
 	PR_SENT_REPRESENTING_NAME_UNICODE, 

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 Jul 28 09:43:05 2008
@@ -933,7 +933,7 @@
 	d(g_print("\n%s(%d): Leaving %s ", __FILE__, __LINE__, __PRETTY_FUNCTION__));
 }
 
-guint32
+GSList *
 exchange_mapi_util_check_restriction (mapi_id_t fid, struct mapi_SRestriction *res)
 {
 	enum MAPISTATUS retval;
@@ -942,7 +942,9 @@
 	mapi_object_t obj_folder;
 	mapi_object_t obj_table;
 	struct SPropTagArray *SPropTagArray, *GetPropsTagArray;
-	uint32_t count = 0;
+	struct SRowSet SRowSet;
+	uint32_t count, i;
+	GSList *mids = NULL;
 
 	d(g_print("\n%s(%d): Entering %s: folder-id %016llX ", __FILE__, __LINE__, __PRETTY_FUNCTION__, fid));
 
@@ -1013,6 +1015,20 @@
 		goto cleanup;
 	}
 
+	/* Fill the table columns with data from the rows */
+	retval = QueryRows(&obj_table, count, TBL_ADVANCE, &SRowSet);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("QueryRows", GetLastError());
+		goto cleanup;
+	}
+
+	for (i = 0; i < SRowSet.cRows; i++) {
+		mapi_id_t *pmid = (mapi_id_t *) get_SPropValue_SRow_data(&SRowSet.aRow[i], PR_MID);
+		struct id_list *id_list = g_new0 (struct id_list, 1);
+		id_list->id = *pmid;
+		mids = g_slist_prepend (mids, id_list);
+	}
+
 cleanup:
 	mapi_object_release(&obj_folder);
 	mapi_object_release(&obj_table);
@@ -1022,7 +1038,7 @@
 
 	d(g_print("\n%s(%d): Leaving %s ", __FILE__, __LINE__, __PRETTY_FUNCTION__));
 
-	return count;
+	return mids;
 }
 
 // FIXME: May be we need to support Restrictions/Filters here. May be after libmapi-0.7.
@@ -2113,6 +2129,15 @@
 		goto cleanup;
 	}
 
+	/* If fid not present then we'll use olFolder. Document this in API doc. */
+	if (fid == 0) {
+		retval = GetDefaultFolder(&obj_store, &fid, olFolder);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultFolder", GetLastError());
+			goto cleanup;
+		}
+	}
+
 	/* Attempt to open the folder */
 	retval = OpenFolder(&obj_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
@@ -2217,7 +2242,7 @@
 
 	LOCK();
 
-	mem_ctx = talloc_init("ExchangeMAPI_ModifyItem");
+	mem_ctx = talloc_init("ExchangeMAPI_SetFlags");
 	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
 
@@ -2332,7 +2357,6 @@
 	return mapi_move_items (src_fid, dest_fid, mids, FALSE);
 }
 
-/* FIXME: param olFolder is never used in the routine. Remove it and cleanup at the backends */
 gboolean
 exchange_mapi_remove_items (uint32_t olFolder, mapi_id_t fid, GSList *mids)
 {
@@ -2366,6 +2390,15 @@
 		goto cleanup;
 	}
 
+	/* If fid not present then we'll use olFolder. Document this in API doc. */
+	if (fid == 0) {
+		retval = GetDefaultFolder(&obj_store, &fid, olFolder);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultFolder", GetLastError());
+			goto cleanup;
+		}
+	}
+
 	/* Attempt to open the folder */
 	retval = OpenFolder(&obj_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h	Mon Jul 28 09:43:05 2008
@@ -130,7 +130,7 @@
 gboolean 
 exchange_mapi_rename_folder (mapi_id_t fid, const char *new_name);
 
-guint32
+GSList *
 exchange_mapi_util_check_restriction (mapi_id_t fid, struct mapi_SRestriction *res);
 
 mapi_id_t

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-utils.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-utils.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-utils.c	Mon Jul 28 09:43:05 2008
@@ -329,24 +329,24 @@
 			const char *tmp =  get_proptag_name (lpProp->ulPropTag);
 			char t_str[26];
 			if (tmp && *tmp)
-				printf("\n%s \t",tmp);
+				g_print("\n%s \t",tmp);
 			else
-				printf("\n%x \t", lpProp->ulPropTag);
+				g_print("\n%x \t", lpProp->ulPropTag);
 			switch(lpProp->ulPropTag & 0xFFFF) {
 			case PT_BOOLEAN:
-				printf(" (bool) - %d", lpProp->value.b);
+				g_print(" (bool) - %d", lpProp->value.b);
 				break;
 			case PT_I2:
-				printf(" (uint16_t) - %d", lpProp->value.i);
+				g_print(" (uint16_t) - %d", lpProp->value.i);
 				break;
 			case PT_LONG:
-				printf(" (long) - %u", lpProp->value.l);
+				g_print(" (long) - %u", lpProp->value.l);
 				break;
 			case PT_DOUBLE:
-				printf (" (double) -  %lf", lpProp->value.dbl);
+				g_print (" (double) -  %lf", lpProp->value.dbl);
 				break;
 			case PT_I8:
-				printf (" (int) - %lld", lpProp->value.d);
+				g_print (" (int) - %lld", lpProp->value.d);
 				break;
 			case PT_SYSTIME: {
 					struct timeval t;
@@ -355,25 +355,25 @@
 					gmtime_r (&(t.tv_sec), &tm);
 					strftime (t_str, 26, "%Y-%m-%dT%H:%M:%SZ", &tm);
 				}
-				printf (" (struct FILETIME *) - %p\t (struct timeval) %s\t", &lpProp->value.ft, t_str);
+				g_print (" (struct FILETIME *) - %p\t (struct timeval) %s\t", &lpProp->value.ft, t_str);
 				break;
 			case PT_ERROR:
-				printf (" (error) - %p", lpProp->value.err);
+				g_print (" (error) - %p", lpProp->value.err);
 				break;
 			case PT_STRING8:
-				printf(" (string) - %s", lpProp->value.lpszA ? lpProp->value.lpszA : "null" );
+				g_print(" (string) - %s", lpProp->value.lpszA ? lpProp->value.lpszA : "null" );
 				break;
 			case PT_UNICODE:
-				printf(" (unicodestring) - %s", lpProp->value.lpszW ? lpProp->value.lpszW : "null");
+				g_print(" (unicodestring) - %s", lpProp->value.lpszW ? lpProp->value.lpszW : "null");
 				break;
 			case PT_BINARY:
-//				printf(" (struct SBinary_short *) - %p", &lpProp->value.bin);
+//				g_print(" (struct SBinary_short *) - %p", &lpProp->value.bin);
 				break;
 			case PT_MV_STRING8:
- 				printf(" (struct mapi_SLPSTRArray *) - %p", &lpProp->value.MVszA);
+ 				g_print(" (struct mapi_SLPSTRArray *) - %p", &lpProp->value.MVszA);
 				break;
 			default:
-				printf(" - NONE NULL");
+				g_print(" - NONE NULL");
 			}
 		}
 	}



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