[evolution-patches] Patch for adding limited support for Recurrences plus a few bug fixes.



hi,

The following is a patch for adding a limited support for recurring
calendar items in the GW calendar and fixes for 59471, 56853 and 60926.
Sorry not to have split them into smaller chunks :( .  These changes
work only with GW server builds later than 9th of July 04. and i wanted
to keep the apply/retract options simple...

thanks,
harish



Index: servers/groupwise/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/groupwise/ChangeLog,v
retrieving revision 1.55
diff -u -p -r1.55 ChangeLog
--- servers/groupwise/ChangeLog	15 Jun 2004 15:59:07 -0000	1.55
+++ servers/groupwise/ChangeLog	12 Jul 2004 12:17:37 -0000
@@ -1,3 +1,30 @@
+2004-07-12  Harish Krishnaswamy  <kharish novell com>
+
+	* e-gw-connection.c: 
+	(e_gw_connection_new) : Fix for #59471 by getting around the server 
+	defect. Substitute the first . by @.
+	(e_gw_connection_get_deltas): Fix for #56853. The server may indicate
+	that there are changes but not provide deltas if they are outside our 
+	interest. This is now considered a valid response.
+	(e_gw_connection_send_item): Handle the change in the SOAP interface.
+	The sendItemResponse now returns a list of ids.
+	(e_gw_connection_accept_request), (e_gw_connection_decline_request),
+	(e_gw_connection_retract_request), (e_gw_connection_complete_request):
+	Implemented.
+	* e-gw-connection.h: Declaration for the added functions.
+	* e-gw-item.c: 
+	(e_gw_item_new_from_soap_parameter): Add organizer only if the item
+	source is not 'personal'. Use 'priority' instead of Taskpriority for
+	Todos as recommended by the server team.
+	(e_gw_item_set_calendar_item_elements): Organize common properties
+	to Appointments and todo-s into a separate function.
+	(e_gw_item_append_to_soap_message),
+	(append_event_changes_to_soap_message),
+	(e_gw_item_append_changes_to_soap_message): reorder soap elements
+	in the sequence specified by the schema. The server does not enforce
this 
+	but doing it right anyway..
+
+
 2004-06-15  Harish Krishnaswamy  <kharish novell com>
 
 	Fixes #59352
Index: servers/groupwise/e-gw-connection.c
===================================================================
RCS file:
/cvs/gnome/evolution-data-server/servers/groupwise/e-gw-connection.c,v
retrieving revision 1.76
diff -u -p -r1.76 e-gw-connection.c
--- servers/groupwise/e-gw-connection.c	1 Jun 2004 06:58:22 -0000	1.76
+++ servers/groupwise/e-gw-connection.c	12 Jul 2004 12:17:38 -0000
@@ -331,11 +331,20 @@ e_gw_connection_new (const char *uri, co
 	if (param) {
 		SoupSoapParameter *subparam;
 		const char *param_value;
+		int i;
 
 		subparam = soup_soap_parameter_get_first_child_by_name (param,
"email");
 		if (subparam) {
 			param_value = soup_soap_parameter_get_string_value (subparam);
 			cnc->priv->user_email  = g_strdup (param_value);
+			// change the first . to a @ to bypass a server bug
+			for (i=0; i < strlen (cnc->priv->user_email); i++) {
+				if (cnc->priv->user_email[i] == '.') {
+					cnc->priv->user_email[i] = '@';
+					break;
+				}
+			}
+				
 		}
 
 		subparam = soup_soap_parameter_get_first_child_by_name (param,
"name");
@@ -684,7 +693,10 @@ e_gw_connection_get_deltas ( EGwConnecti
                  g_object_unref (response); 
                  g_object_unref (msg); 
 		 // g_object_unref (cnc); 
-                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE; 
+//                 return E_GW_CONNECTION_STATUS_INVALID_RESPONSE; 
+		/* getting around the server behavior that deltas can be null
+		 * though changes is true */
+		 return E_GW_CONNECTION_STATUS_OK;
          } 
         
          /* process all deletes first*/ 
@@ -755,7 +767,7 @@ e_gw_connection_get_deltas ( EGwConnecti
 }
 
 EGwConnectionStatus
-e_gw_connection_send_item (EGwConnection *cnc, EGwItem *item, char
**id)
+e_gw_connection_send_item (EGwConnection *cnc, EGwItem *item, GSList
**id_list)
 {
 	SoupSoapMessage *msg;
 	SoupSoapResponse *response;
@@ -764,8 +776,8 @@ e_gw_connection_send_item (EGwConnection
 	g_return_val_if_fail (E_IS_GW_CONNECTION (cnc),
E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
 	g_return_val_if_fail (E_IS_GW_ITEM (item),
E_GW_CONNECTION_STATUS_INVALID_OBJECT);
 
-	if (id)
-		*id = NULL;
+	if (id_list)
+		*id_list = NULL;
 
 	/* compose SOAP message */
 	msg = e_gw_message_new_with_header (cnc->priv->uri,
cnc->priv->session_id, "sendItemRequest");
@@ -790,13 +802,16 @@ e_gw_connection_send_item (EGwConnection
 	}
 
 	status = e_gw_connection_parse_response_status (response);
-	if (status == E_GW_CONNECTION_STATUS_OK && id != NULL) {
+	if (status == E_GW_CONNECTION_STATUS_OK && id_list != NULL) {
 		SoupSoapParameter *param;
 
 		/* get the generated ID from the SOAP response */
-		param = soup_soap_response_get_first_parameter_by_name (response,
"id");
-		if (param)
-			*id = soup_soap_parameter_get_string_value (param);
+		for (param = soup_soap_response_get_first_parameter_by_name
(response, "id");
+			param; param = soup_soap_response_get_next_parameter_by_name
(response, param, "id")) {
+			
+			*id_list = g_slist_append (*id_list,
soup_soap_parameter_get_string_value (param));
+		}
 	}
 
 	g_object_unref (msg);
@@ -1018,6 +1033,109 @@ e_gw_connection_remove_items (EGwConnect
 
 	return status;
 }
+
+EGwConnectionStatus
+e_gw_connection_accept_request (EGwConnection *cnc, const char *id,
const char *accept_level)
+{
+	SoupSoapMessage *msg;
+	int status;
+	SoupSoapResponse *response;
+
+	msg = e_gw_message_new_with_header (cnc->priv->uri,
cnc->priv->session_id, "acceptRequest");
+	soup_soap_message_start_element (msg, "items", NULL, NULL);
+	e_gw_message_write_string_parameter (msg, "item", NULL, id);
+	e_gw_message_write_string_parameter (msg, "acceptLevel", NULL,
accept_level);
+	soup_soap_message_end_element (msg);
+	e_gw_message_write_footer (msg);
+
+	response = e_gw_connection_send_message (cnc, msg);
+        if (!response) {
+                g_object_unref (msg);
+                return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
+        }
+
+        status = e_gw_connection_parse_response_status (response);
+	g_object_unref (response);
+	g_object_unref (msg);
+	return status;
+}
+
+EGwConnectionStatus
+e_gw_connection_decline_request (EGwConnection *cnc, const char *id)
+{
+	SoupSoapMessage *msg;
+	int status;
+	SoupSoapResponse *response;
+
+	msg = e_gw_message_new_with_header (cnc->priv->uri,
cnc->priv->session_id, "declineRequest");
+	soup_soap_message_start_element (msg, "items", NULL, NULL);
+	e_gw_message_write_string_parameter (msg, "item", NULL, id);
+	soup_soap_message_end_element (msg);
+	e_gw_message_write_footer (msg);
+
+	response = e_gw_connection_send_message (cnc, msg);
+        if (!response) {
+                g_object_unref (msg);
+                return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
+        }
+
+        status = e_gw_connection_parse_response_status (response);
+	g_object_unref (response);
+	g_object_unref (msg);
+	return status;
+}
+
+EGwConnectionStatus
+e_gw_connection_retract_request (EGwConnection *cnc, const char *id,
const char *comment, gboolean retract_all, gboolean resend)
+{
+	SoupSoapMessage *msg;
+	int status;
+	SoupSoapResponse *response;
+
+	msg = e_gw_message_new_with_header (cnc->priv->uri,
cnc->priv->session_id, "retractRequest");
+	soup_soap_message_start_element (msg, "items", NULL, NULL);
+	e_gw_message_write_string_parameter (msg, "item", NULL, id);
+	soup_soap_message_end_element (msg);
+	/* comment, FALSE, FALSE to be filled in later. */
+	e_gw_message_write_footer (msg);
+
+	response = e_gw_connection_send_message (cnc, msg);
+        if (!response) {
+                g_object_unref (msg);
+                return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
+        }
+
+        status = e_gw_connection_parse_response_status (response);
+	g_object_unref (response);
+	g_object_unref (msg);
+	return status;
+}
+
+EGwConnectionStatus
+e_gw_connection_complete_request (EGwConnection *cnc, const char *id)
+{
+	SoupSoapMessage *msg;
+	int status;
+	SoupSoapResponse *response;
+
+	msg = e_gw_message_new_with_header (cnc->priv->uri,
cnc->priv->session_id, "completeRequest");
+	soup_soap_message_start_element (msg, "items", NULL, NULL);
+	e_gw_message_write_string_parameter (msg, "item", NULL, id);
+	soup_soap_message_end_element (msg);
+	e_gw_message_write_footer (msg);
+
+	response = e_gw_connection_send_message (cnc, msg);
+        if (!response) {
+                g_object_unref (msg);
+                return E_GW_CONNECTION_STATUS_INVALID_RESPONSE;
+        }
+
+        status = e_gw_connection_parse_response_status (response);
+	g_object_unref (response);
+	g_object_unref (msg);
+	return status;
+}
+
 const char *
 e_gw_connection_get_uri (EGwConnection *cnc)
 {
Index: servers/groupwise/e-gw-connection.h
===================================================================
RCS file:
/cvs/gnome/evolution-data-server/servers/groupwise/e-gw-connection.h,v
retrieving revision 1.32
diff -u -p -r1.32 e-gw-connection.h
--- servers/groupwise/e-gw-connection.h	1 Jun 2004 06:58:22 -0000	1.32
+++ servers/groupwise/e-gw-connection.h	12 Jul 2004 12:17:38 -0000
@@ -76,7 +76,7 @@ char               *e_gw_connection_get_
 EGwConnectionStatus e_gw_connection_get_items (EGwConnection *cnc,
const char *container,
 					       const char *view, EGwFilter *filter, GList **list);
 EGwConnectionStatus e_gw_connection_get_deltas ( EGwConnection *cnc,
GSList **adds, GSList **deletes, GSList **updates);
-EGwConnectionStatus e_gw_connection_send_item (EGwConnection *cnc,
EGwItem *item, char **id);
+EGwConnectionStatus e_gw_connection_send_item (EGwConnection *cnc,
EGwItem *item, GSList **id_list);
 EGwConnectionStatus e_gw_connection_remove_item (EGwConnection *cnc,
const char *container, const char *id);
 EGwConnectionStatus e_gw_connection_remove_items (EGwConnection *cnc,
const char *container, GList *item_ids);
 
@@ -94,6 +94,10 @@ char               *e_gw_connection_form
 EGwConnectionStatus e_gw_connection_create_item (EGwConnection *cnc,
EGwItem *item, char** id);
 EGwConnectionStatus e_gw_connection_get_item (EGwConnection *cnc, const
char *container, const char *id, EGwItem **item);
 EGwConnectionStatus e_gw_connection_modify_item (EGwConnection *cnc,
const char *id, EGwItem *item);
+EGwConnectionStatus e_gw_connection_accept_request (EGwConnection *cnc,
const char *id, const char *accept_level);
+EGwConnectionStatus e_gw_connection_decline_request (EGwConnection
*cnc, const char *id);
+EGwConnectionStatus e_gw_connection_retract_request (EGwConnection
*cnc, const char *id, const char *comment, gboolean retract_all,
gboolean resend);
+EGwConnectionStatus e_gw_connection_complete_request (EGwConnection
*cnc, const char *id);
 EGwConnectionStatus e_gw_connection_create_book (EGwConnection *cnc,
char *book_name, char**id);
 EGwConnectionStatus e_gw_connection_remove_book (EGwConnection *cnc,
char *book_uid);
 EGwConnectionStatus e_gw_connection_get_address_book_list
(EGwConnection *cnc, GList **container_list);
Index: servers/groupwise/e-gw-item.c
===================================================================
RCS file:
/cvs/gnome/evolution-data-server/servers/groupwise/e-gw-item.c,v
retrieving revision 1.39
diff -u -p -r1.39 e-gw-item.c
--- servers/groupwise/e-gw-item.c	15 Jun 2004 15:59:07 -0000	1.39
+++ servers/groupwise/e-gw-item.c	12 Jul 2004 12:17:38 -0000
@@ -1243,6 +1243,7 @@ e_gw_item_new_from_soap_parameter (const
 	EGwItem *item;
         char *item_type;
 	SoupSoapParameter *subparam, *child;
+	gboolean is_group_item = TRUE;
 	
 	g_return_val_if_fail (param != NULL, NULL);
 
@@ -1291,7 +1292,7 @@ e_gw_item_new_from_soap_parameter (const
 	g_free (item_type);
 
 	item->priv->container = g_strdup (container);
-	
+
 	/* If the parameter consists of changes - populate deltas */
 	subparam = soup_soap_parameter_get_first_child_by_name (param,
"changes");
 	if (subparam) {
@@ -1345,7 +1346,7 @@ e_gw_item_new_from_soap_parameter (const
 				set_recipient_list_from_soap_parameter
(&item->priv->recipient_list, tp);
 			}
 			tp = soup_soap_parameter_get_first_child_by_name (child, "from");
-			if (tp) {
+			if (tp && is_group_item) {
 				SoupSoapParameter *subparam;
 				EGwItemOrganizer *organizer = g_new0 (EGwItemOrganizer, 1);
 
@@ -1393,8 +1394,13 @@ e_gw_item_new_from_soap_parameter (const
 		else if (!g_ascii_strcasecmp (name, "place"))
 			item->priv->place = soup_soap_parameter_get_string_value (child);
 
-		else if (!g_ascii_strcasecmp (name, "priority"))
-			item->priv->priority = soup_soap_parameter_get_string_value (child);
+		else if (!g_ascii_strcasecmp (name, "options")) {
+			SoupSoapParameter *priority;
+
+			priority = soup_soap_parameter_get_first_child_by_name (child,
"priority");
+			if (priority)
+				e_gw_item_set_priority (item, soup_soap_parameter_get_string_value
(priority));
+		}
 
 		else if (!g_ascii_strcasecmp (name, "startDate")) {
 			char *formatted_date;
@@ -1402,9 +1408,18 @@ e_gw_item_new_from_soap_parameter (const
 			formatted_date = e_gw_connection_format_date_string (value);
 			e_gw_item_set_start_date (item, formatted_date);
 			g_free (value);
+			g_free (formatted_date);
 
 		} else if (!g_ascii_strcasecmp (name, "subject"))
 			item->priv->subject = soup_soap_parameter_get_string_value (child);
+		else if (!g_ascii_strcasecmp (name, "source")) {
+			char *value;
+			value = soup_soap_parameter_get_string_value (child);
+			if (!strcmp (value, "personal"))
+				is_group_item = FALSE;
+			g_free (value);
+		}
+			
 		else if (!g_ascii_strcasecmp (name, "alarm")) {
 			const char *enabled;
 			enabled = soup_soap_parameter_get_property (child, "enabled");
@@ -1803,11 +1818,65 @@ add_distribution_to_soap_message (EGwIte
 	soup_soap_message_end_element (msg);
 }
 
+void 
+e_gw_item_set_calendar_item_elements (EGwItem *item, SoupSoapMessage
*msg)
+{
+	EGwItemPrivate *priv = item->priv;
+	char *dtstring;
+
+	if (priv->id)
+		e_gw_message_write_string_parameter (msg, "id", NULL, priv->id);
+	if (priv->container)
+		e_gw_message_write_string_parameter (msg, "container", NULL,
priv->container);
+
+	if (priv->classification)
+		e_gw_message_write_string_parameter (msg, "class", NULL,
priv->classification);
+	else
+		e_gw_message_write_string_parameter (msg, "class", NULL, "");
+
+	e_gw_message_write_string_parameter (msg, "subject", NULL,
priv->subject ? priv->subject : "");
+	if (priv->recipient_list != NULL)
+		add_distribution_to_soap_message (priv->organizer,
priv->recipient_list, msg);
+
+	soup_soap_message_start_element (msg, "message", NULL, NULL);
+	if (priv->message) {
+		char *str;
+
+		str = soup_base64_encode (priv->message, strlen (priv->message));
+		dtstring = g_strdup_printf ("%d", strlen (str));
+		soup_soap_message_add_attribute (msg, "length", dtstring, NULL,
NULL);
+		g_free (dtstring);
+		soup_soap_message_write_string (msg, str);
+		g_free (str);
+	} else {
+		soup_soap_message_add_attribute (msg, "length", "0", NULL, NULL);
+		soup_soap_message_write_string (msg, "");
+	}
+
+	soup_soap_message_end_element (msg);
+
+	if (priv->start_date) {
+		e_gw_message_write_string_parameter (msg, "startDate", NULL, 
+				priv->start_date);
+	}
+
+	/* handle recurrences */
+	if (item->priv->recurrence_dates) {
+		GSList *date;
+		soup_soap_message_start_element (msg, "rdate", NULL, NULL);
+		for (date = item->priv->recurrence_dates; date != NULL; date =
g_slist_next (date)) {
+			e_gw_message_write_string_parameter (msg, "date", NULL, (char *)
date->data);
+		}
+		soup_soap_message_end_element (msg);
+	}
+
+	e_gw_message_write_string_parameter (msg, "iCalId", NULL, priv->icalid
? priv->icalid : "");
+}
+
 gboolean
 e_gw_item_append_to_soap_message (EGwItem *item, SoupSoapMessage *msg)
 {
 	EGwItemPrivate *priv;
-	char *dtstring;
 	char *alarm;
 
 	g_return_val_if_fail (E_IS_GW_ITEM (item), FALSE);
@@ -1821,38 +1890,45 @@ e_gw_item_append_to_soap_message (EGwIte
 	case E_GW_ITEM_TYPE_APPOINTMENT :
 		soup_soap_message_add_attribute (msg, "type", "Appointment", "xsi",
NULL);
 
+		/* Calendar Item properties. */
+		e_gw_item_set_calendar_item_elements (item, msg);
+
+		/* Appointment specific properties */
+		if (priv->end_date) {
+			e_gw_message_write_string_parameter (msg, "endDate", NULL,
priv->end_date);
+		} else
+			e_gw_message_write_string_parameter (msg, "endDate", NULL, "");
+
 		e_gw_message_write_string_parameter (msg, "acceptLevel", NULL,
priv->accept_level ? priv->accept_level : "");
-		e_gw_message_write_string_parameter (msg, "iCalId", NULL,
priv->icalid ? priv->icalid : "");
-		e_gw_message_write_string_parameter (msg, "place", NULL, priv->place
? priv->place : "");
 		if (priv->trigger != 0) {
 			alarm = g_strdup_printf ("%d", priv->trigger);
 			e_gw_message_write_string_parameter_with_attribute (msg, "alarm",
NULL, alarm, "enabled", "true");
 			g_free (alarm);
 		}
-		if (priv->recipient_list != NULL)
-			add_distribution_to_soap_message (priv->organizer,
priv->recipient_list, msg);
-		if (priv->end_date) {
-			e_gw_message_write_string_parameter (msg, "endDate", NULL,
priv->end_date);
-		} else
-			e_gw_message_write_string_parameter (msg, "endDate", NULL, "");
+		e_gw_message_write_string_parameter (msg, "place", NULL, priv->place
? priv->place : "");
 		
 		break;
 
 	case E_GW_ITEM_TYPE_TASK :
 		soup_soap_message_add_attribute (msg, "type", "Task", "xsi", NULL);
 
+		/* Calendar Item properties. */
+		e_gw_item_set_calendar_item_elements (item, msg);
+
+		/* Task specific properties */
 		if (priv->due_date) {
 			e_gw_message_write_string_parameter (msg, "dueDate", NULL,
priv->due_date);
 		} else
 			e_gw_message_write_string_parameter (msg, "dueDate", NULL, "");
 
+		soup_soap_message_start_element (msg, "options", NULL, NULL);
+		e_gw_message_write_string_parameter (msg, "priority", NULL,
priv->priority ? priv->priority : "");
+		soup_soap_message_end_element (msg);
 		if (priv->completed)
 			e_gw_message_write_string_parameter (msg, "completed", NULL, "1");
 		else
 			e_gw_message_write_string_parameter (msg, "completed", NULL, "0");
 
-		e_gw_message_write_string_parameter (msg, "iCalId", NULL,
priv->icalid ? priv->icalid : "");
-		e_gw_message_write_string_parameter (msg, "priority", NULL,
priv->priority ? priv->priority : "");
 		break;
 	case E_GW_ITEM_TYPE_CONTACT :
 		soup_soap_message_add_attribute (msg, "type", "Contact", "xsi",
NULL);
@@ -1879,54 +1955,6 @@ e_gw_item_append_to_soap_message (EGwIte
 		return FALSE;
 	}
 
-	/* add all properties */
-	if (priv->id)
-		e_gw_message_write_string_parameter (msg, "id", NULL, priv->id);
-	if (priv->container)
-		e_gw_message_write_string_parameter (msg, "container", NULL,
priv->container);
-	e_gw_message_write_string_parameter (msg, "subject", NULL,
priv->subject ? priv->subject : "");
-
-	soup_soap_message_start_element (msg, "message", NULL, NULL);
-	if (priv->message) {
-		char *str;
-
-		str = soup_base64_encode (priv->message, strlen (priv->message));
-		dtstring = g_strdup_printf ("%d", strlen (str));
-		soup_soap_message_add_attribute (msg, "length", dtstring, NULL,
NULL);
-		g_free (dtstring);
-		soup_soap_message_write_string (msg, str);
-		g_free (str);
-	} else {
-		soup_soap_message_add_attribute (msg, "length", "0", NULL, NULL);
-		soup_soap_message_write_string (msg, "");
-	}
-
-	soup_soap_message_end_element (msg);
-
-	if (priv->start_date) {
-		e_gw_message_write_string_parameter (msg, "startDate", NULL, 
-				priv->start_date);
-	}
-	
-	if (priv->creation_date) {
-		e_gw_message_write_string_parameter (msg, "created", NULL,
priv->creation_date);
-	}
-
-	if (priv->classification)
-		e_gw_message_write_string_parameter (msg, "class", NULL,
priv->classification);
-	else
-		e_gw_message_write_string_parameter (msg, "class", NULL, "");
-
-	/* handle recurrences */
-	if (item->priv->recurrence_dates) {
-		GSList *date;
-		soup_soap_message_start_element (msg, "rdate", NULL, NULL);
-		for (date = item->priv->recurrence_dates; date != NULL; date =
g_slist_next (date)) {
-			e_gw_message_write_string_parameter (msg, "date", NULL, (char *)
date->data);
-		}
-		soup_soap_message_end_element (msg);
-	}
-	/* finalize the SOAP element */
 	soup_soap_message_end_element (msg);
 
 	return TRUE;
@@ -2003,28 +2031,32 @@ append_event_changes_to_soap_message (EG
 	switch (change_type) {
 	case E_GW_ITEM_CHANGE_TYPE_ADD :
 		changes = priv->additions;
+		if (!changes)
+			return;
 		soup_soap_message_start_element (msg, "add", NULL, NULL);
 		break;
 	case E_GW_ITEM_CHANGE_TYPE_UPDATE :
 		changes = priv->updates;
+		if (!changes)
+			return;
 		soup_soap_message_start_element (msg, "update", NULL, NULL);
 		break;
 	case E_GW_ITEM_CHANGE_TYPE_DELETE :
 		changes = priv->deletions;
+		if (!changes)
+			return;
 		soup_soap_message_start_element (msg, "delete", NULL, NULL);
 		break;
 	}
-	if (!changes)
-		return;
 
 	if (g_hash_table_lookup (changes, "subject"))
 		e_gw_message_write_string_parameter (msg, "subject", NULL,
priv->subject ? priv->subject : "");
-	if (g_hash_table_lookup (changes, "startDate")) {
+	if (g_hash_table_lookup (changes, "start_date")) {
 		if (priv->start_date) {
 			e_gw_message_write_string_parameter (msg, "startDate", NULL,
priv->start_date); 
 		}
 	}
-	if (g_hash_table_lookup (changes, "endDate")) {
+	if (g_hash_table_lookup (changes, "end_date")) {
 		if (priv->end_date) {
 			e_gw_message_write_string_parameter (msg, "endDate", NULL,
priv->end_date);
 		}
@@ -2049,7 +2081,11 @@ append_event_changes_to_soap_message (EG
 	}
 	if (g_hash_table_lookup (changes, "classification"))
 		e_gw_message_write_string_parameter (msg, "class", NULL,
priv->classification);
-
+	if (g_hash_table_lookup (changes, "priority")) {
+		soup_soap_message_start_element (msg, "options", NULL, NULL);
+		e_gw_message_write_string_parameter (msg, "priority", NULL,
priv->priority);
+		soup_soap_message_end_element (msg);
+	}
 	if (g_hash_table_lookup (changes, "accept_level"))
 		e_gw_message_write_string_parameter (msg, "acceptLevel", NULL,
priv->accept_level ? priv->accept_level : "");
 	if (g_hash_table_lookup (changes, "place"))
@@ -2065,6 +2101,8 @@ append_event_changes_to_soap_message (EG
 	}
 	if (g_hash_table_lookup (changes, "completed"))
 		e_gw_message_write_string_parameter (msg, "completed", NULL,
priv->completed ? "1" : "0");
+	if (g_hash_table_lookup (changes, "due_date"))
+		e_gw_message_write_string_parameter (msg, "dueDate", NULL,
priv->due_date);
 	soup_soap_message_end_element (msg);
 
 }
@@ -2102,6 +2140,7 @@ e_gw_item_append_changes_to_soap_message
 		append_event_changes_to_soap_message (item, msg,
E_GW_ITEM_CHANGE_TYPE_ADD);
 		append_event_changes_to_soap_message (item, msg,
E_GW_ITEM_CHANGE_TYPE_UPDATE);
 		append_event_changes_to_soap_message (item, msg,
E_GW_ITEM_CHANGE_TYPE_DELETE);
+		soup_soap_message_end_element(msg); 
 		return TRUE;
 	default :
 		g_warning (G_STRLOC ": Unknown type for item");
Index: calendar/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/ChangeLog,v
retrieving revision 1.294
diff -u -p -r1.294 ChangeLog
--- calendar/ChangeLog	12 Jul 2004 09:08:36 -0000	1.294
+++ calendar/ChangeLog	12 Jul 2004 12:17:38 -0000
@@ -1,3 +1,33 @@
+2004-07-12  Harish Krishnaswamy  <kharish novell com>
+
+	* backends/groupwise/e-cal-backend-groupwise-utils.c:
+	(e_cal_component_get_gw_id): Access method for getting the 
+	XGWRECORDID property from the calendar component.
+	(set_properties_from_cal_component): Range of priority value
+	HIGH extended to include values 1 and 2.
+	The X-EVOLUTION-GROUPWISE-ID is now referred as XGWRECORDID
+	for consistency with the ITIP messages.
+	(e_gw_item_to_cal_component) : Absence of due_date does not 
+	invalidate the task component. Fixes #60926.
+	(e_gw_connection_send_appointment),(e_gw_connection_create_appointment):
+	Implemented.
+	(e_gw_connection_get_freebusy_info):
+	(e_gw_item_set_changes): Fixed compiler warnings.
+	
+	* backends/groupwise/e-cal-backend-groupwise-utils.h:
+	Declarations for added functions.
+	* backends/groupwise/e-cal-backend-groupwise.c: 
+	(populate_cache) : Removed unused variables.
+	(set_container_id): Extracted a function out of the code as it is
+	used twice.
+	(e_cal_backend_groupwise_create_object): Handle changes in the SOAP
interface.
+	The server now returns 	a list of uids. This is to allow creation of
recurring 
+	calendar events.
+	(e_cal_backend_groupwise_modify_object): Fix some leaks.
+	(e_cal_backend_groupwise_remove_object), (receive_object),
+	(send_object), (e_cal_backend_groupwise_send_objects): Use the newly
created
+	functions for handling group calendar items.
+
 2004-07-12  Sivaiah Nallagatla   <snallagatla novell com>
 
 	* backends/groupwise/e-cal-backend-groupwise.c
Index: calendar/backends/groupwise/e-cal-backend-groupwise-utils.c
===================================================================
RCS file:
/cvs/gnome/evolution-data-server/calendar/backends/groupwise/e-cal-backend-groupwise-utils.c,v
retrieving revision 1.23
diff -u -p -r1.23 e-cal-backend-groupwise-utils.c
--- calendar/backends/groupwise/e-cal-backend-groupwise-utils.c	5 Jul
2004 06:21:48 -0000	1.23
+++ calendar/backends/groupwise/e-cal-backend-groupwise-utils.c	12 Jul
2004 12:17:39 -0000
@@ -48,6 +48,28 @@ resolve_tzid_cb (const char *tzid, gpoin
 	return NULL;
 }
 
+const char *
+e_cal_component_get_gw_id (ECalComponent *comp)
+{
+	icalproperty *prop;	
+	
+	prop = icalcomponent_get_first_property
(e_cal_component_get_icalcomponent (comp),
+						 ICAL_X_PROPERTY);
+	while (prop) {
+		const char *x_name, *x_val;
+
+		x_name = icalproperty_get_x_name (prop);
+		x_val = icalproperty_get_x (prop);
+		if (!strcmp (x_name, "X-GWRECORDID")) {
+			return x_val;
+		}
+
+		prop = icalcomponent_get_next_property
(e_cal_component_get_icalcomponent (comp),
+							ICAL_X_PROPERTY);
+	}
+	return NULL;
+}
+
 static EGwItem *
 set_properties_from_cal_component (EGwItem *item, ECalComponent *comp,
const icaltimezone *default_zone)
 {
@@ -58,7 +80,6 @@ set_properties_from_cal_component (EGwIt
 	ECalComponentText text;
 	int *priority;
 	GSList *slist, *sl;
-	icalproperty *prop;
 	struct icaltimetype itt_utc;
 
 	/* first set specific properties */
@@ -123,7 +144,7 @@ set_properties_from_cal_component (EGwIt
 				e_gw_item_set_priority (item, E_GW_ITEM_PRIORITY_LOW);
 			else if (*priority >= 5)
 				e_gw_item_set_priority (item, E_GW_ITEM_PRIORITY_STANDARD);
-			else if (*priority >= 3)
+			else if (*priority >= 1)
 				e_gw_item_set_priority (item, E_GW_ITEM_PRIORITY_HIGH);
 			else
 				e_gw_item_set_priority (item, NULL);
@@ -147,21 +168,8 @@ set_properties_from_cal_component (EGwIt
 
 	/* set common properties */
 	/* GW server ID */
-	prop = icalcomponent_get_first_property
(e_cal_component_get_icalcomponent (comp),
-						 ICAL_X_PROPERTY);
-	while (prop) {
-		const char *x_name, *x_val;
-
-		x_name = icalproperty_get_x_name (prop);
-		x_val = icalproperty_get_x (prop);
-		if (!strcmp (x_name, "X-EVOLUTION-GROUPWISE-ID")) {
-			e_gw_item_set_id (item, x_val);
-			break;
-		}
-
-		prop = icalcomponent_get_next_property
(e_cal_component_get_icalcomponent (comp),
-							ICAL_X_PROPERTY);
-	}
+	e_gw_item_set_id (item, e_cal_component_get_gw_id (comp));
+	
 	
 	/* UID */
 	e_cal_component_get_uid (comp, &uid);
@@ -266,16 +274,14 @@ set_properties_from_cal_component (EGwIt
 	}
 
 	if (e_cal_component_has_organizer (comp)) {
-		ECalComponentOrganizer *cal_organizer;
+		ECalComponentOrganizer cal_organizer;
 		EGwItemOrganizer *organizer = NULL;
 
-		e_cal_component_get_organizer (comp, cal_organizer);
-		if (cal_organizer) {
-			organizer = g_new0 (EGwItemOrganizer, 1);
-			organizer->display_name = g_strdup (cal_organizer->cn);
-			organizer->email = g_strdup (cal_organizer->value + 7);
-			e_gw_item_set_organizer (item, organizer);
-		}
+		e_cal_component_get_organizer (comp, &cal_organizer);
+		organizer = g_new0 (EGwItemOrganizer, 1);
+		organizer->display_name = g_strdup (cal_organizer.cn);
+		organizer->email = g_strdup (cal_organizer.value + 7);
+		e_gw_item_set_organizer (item, organizer);
 	}
 
 	
@@ -287,7 +293,7 @@ set_properties_from_cal_component (EGwIt
 
 		e_cal_recur_generate_instances (comp, -1, -1,
 				get_recur_instance, &recur_dates, resolve_tzid_cb, NULL, 
-				default_zone);		
+				(icaltimezone *) default_zone);		
 		recur_dates = g_slist_delete_link (recur_dates, recur_dates);
 		
 		e_gw_item_set_recurrence_dates (item, recur_dates);
@@ -347,7 +353,7 @@ e_gw_item_to_cal_component (EGwItem *ite
 		icalproperty *icalprop;
 
 		icalprop = icalproperty_new_x (description);
-		icalproperty_set_x_name (icalprop, "X-EVOLUTION-GROUPWISE-ID");
+		icalproperty_set_x_name (icalprop, "X-GWRECORDID");
 		icalcomponent_add_property (e_cal_component_get_icalcomponent (comp),
icalprop);
 	}
 
@@ -527,23 +533,21 @@ e_gw_item_to_cal_component (EGwItem *ite
 	case E_GW_ITEM_TYPE_TASK :
 		/* due date */
 		t = e_gw_item_get_due_date (item);
-		if (!t)
-			break;
-		itt_utc = icaltime_from_string (t);
-		if (!icaltime_get_timezone (itt_utc))
-			icaltime_set_timezone (&itt_utc, icaltimezone_get_utc_timezone());
-		if (default_zone) {
-			itt = icaltime_convert_to_zone (itt_utc, default_zone); 
-			icaltime_set_timezone (&itt, default_zone);
-			dt.value = &itt;
-			dt.tzid = icaltimezone_get_tzid (default_zone);
-		} else {
-			dt.value = &itt_utc;
-			dt.tzid = g_strdup ("UTC");
+		if (t) {
+			itt_utc = icaltime_from_string (t);
+			if (!icaltime_get_timezone (itt_utc))
+				icaltime_set_timezone (&itt_utc, icaltimezone_get_utc_timezone());
+			if (default_zone) {
+				itt = icaltime_convert_to_zone (itt_utc, default_zone); 
+				icaltime_set_timezone (&itt, default_zone);
+				dt.value = &itt;
+				dt.tzid = icaltimezone_get_tzid (default_zone);
+			} else {
+				dt.value = &itt_utc;
+				dt.tzid = g_strdup ("UTC");
+			}
+			e_cal_component_set_due (comp, &dt);
 		}
-		e_cal_component_set_due (comp, &dt);
-		break;
-
 		/* priority */
 		description = e_gw_item_get_priority (item);
 		if (description) {
@@ -574,7 +578,86 @@ e_gw_item_to_cal_component (EGwItem *ite
 }
 
 EGwConnectionStatus
-e_gw_connection_send_appointment (EGwConnection *cnc, const char
*container, icaltimezone *default_zone, ECalComponent *comp, char **id)
+e_gw_connection_send_appointment (EGwConnection *cnc, const char
*container, icaltimezone *default_zone, ECalComponent *comp,
icalproperty_method method)
+{
+	EGwConnectionStatus status;
+	icalparameter_partstat partstat;
+	
+
+	g_return_val_if_fail (E_IS_GW_CONNECTION (cnc),
E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
+	g_return_val_if_fail (E_IS_CAL_COMPONENT (comp),
E_GW_CONNECTION_STATUS_INVALID_OBJECT);
+
+
+	switch (method) {
+	case ICAL_METHOD_REPLY:
+		/* get attendee here and add the list along. */
+		if (e_cal_component_has_attendees (comp))
+		{
+			GSList *attendee_list, *l;
+			ECalComponentAttendee  *attendee = NULL, *tmp;
+
+			
+			e_cal_component_get_attendee_list (comp, &attendee_list);
+			for (l = attendee_list; l ; l = g_slist_next (l)) {
+				tmp = (ECalComponentAttendee *) (l->data);
+				if (!strcmp (tmp->value, e_gw_connection_get_user_email (cnc))) {
+					attendee = tmp;
+				}
+			}
+			if (attendee_list)
+				e_cal_component_free_attendee_list (attendee_list);
+			if (attendee) {
+				partstat = attendee->status;
+			}
+			else {
+				status = E_GW_CONNECTION_STATUS_INVALID_OBJECT;
+				break;
+			}
+			
+		}
+		else {
+			status = E_GW_CONNECTION_STATUS_INVALID_OBJECT;
+			break;
+		}
+		
+		switch (partstat) {
+		ECalComponentTransparency transp;
+			
+		case ICAL_PARTSTAT_ACCEPTED: 
+			e_cal_component_get_transparency (comp, &transp);
+			if (transp == E_CAL_COMPONENT_TRANSP_OPAQUE) 
+				status = e_gw_connection_accept_request (cnc,
e_cal_component_get_gw_id (comp), "Busy");
+			else 
+				status = e_gw_connection_accept_request (cnc,
e_cal_component_get_gw_id (comp), "Free");
+			break;
+		case ICAL_PARTSTAT_DECLINED:
+			status = e_gw_connection_decline_request (cnc,
e_cal_component_get_gw_id (comp));
+			break;
+		case ICAL_PARTSTAT_TENTATIVE:
+			status = e_gw_connection_accept_request (cnc,
e_cal_component_get_gw_id (comp), "Tentative");
+			break;
+		case ICAL_PARTSTAT_COMPLETED:
+			status = e_gw_connection_complete_request (cnc,
e_cal_component_get_gw_id (comp));
+
+		default :
+			status = E_GW_CONNECTION_STATUS_INVALID_OBJECT;
+	
+		}
+
+		break;
+
+	case ICAL_METHOD_CANCEL:
+		status = e_gw_connection_retract_request (cnc,
e_cal_component_get_gw_id (comp), NULL, FALSE, FALSE);
+		break;
+	default:
+		status = E_GW_CONNECTION_STATUS_INVALID_OBJECT;
+	}	
+
+	return status;
+}
+
+EGwConnectionStatus
+e_gw_connection_create_appointment (EGwConnection *cnc, const char
*container, icaltimezone *default_zone, ECalComponent *comp, GSList
**id_list)
 {
 	EGwItem *item;
 	EGwConnectionStatus status;
@@ -584,7 +667,7 @@ e_gw_connection_send_appointment (EGwCon
 
 	item = e_gw_item_new_from_cal_component (container, default_zone,
comp);
 	e_gw_item_set_container_id (item, container);
-	status = e_gw_connection_send_item (cnc, item, id);
+	status = e_gw_connection_send_item (cnc, item, id_list);
 	g_object_unref (item);
 
 	return status;
@@ -695,7 +778,7 @@ close_freebusy_session (EGwConnection *c
 }
 
 EGwConnectionStatus
-e_gw_connection_get_freebusy_info (EGwConnection *cnc, GList *users,
time_t start, time_t end, GList **freebusy, icaltimezone *default_zone)
+e_gw_connection_get_freebusy_info (EGwConnection *cnc, GList *users,
time_t start, time_t end, GList **freebusy)
 {
         SoupSoapMessage *msg;
         SoupSoapResponse *response;
@@ -808,10 +891,7 @@ e_gw_connection_get_freebusy_info (EGwCo
 			if (tmp) {
 				start = soup_soap_parameter_get_string_value (tmp);
 				t = e_gw_connection_get_date_from_string (start);
-				if (default_zone)
-					itt = icaltime_from_timet_with_zone (t, 0, default_zone);
-				else
-					itt = icaltime_from_timet_with_zone (t, 0, 0);
+				itt = icaltime_from_timet (t, 0);
 				ipt.start = itt;
 			}        
 
@@ -819,10 +899,7 @@ e_gw_connection_get_freebusy_info (EGwCo
 			if (tmp) {
 				end = soup_soap_parameter_get_string_value (tmp);
 				t = e_gw_connection_get_date_from_string (end);
-				if (default_zone)
-					itt = icaltime_from_timet_with_zone (t, 0, default_zone);
-				else
-					itt = icaltime_from_timet_with_zone (t, 0, 0);
+				itt = icaltime_from_timet (t, 0);
 				ipt.end = itt;
 			}
 			icalprop = icalproperty_new_freebusy (ipt);
@@ -860,24 +937,27 @@ e_gw_connection_get_freebusy_info (EGwCo
 	cache_##fieldname = e_gw_item_get_##fieldname
(cache_item);                                           \
 	if ( cache_##fieldname )
{                                                                            \
 		if (!fieldname
)                                                                               \
-			e_gw_item_set_change (item, E_GW_ITEM_CHANGE_TYPE_DELETE,
#fieldname, cache_##fieldname );\
+			e_gw_item_set_change (item, E_GW_ITEM_CHANGE_TYPE_DELETE,
#fieldname, (gpointer) cache_##fieldname );\
 		else if (strcmp ( fieldname, cache_##fieldname
))                                               \
-			e_gw_item_set_change (item, E_GW_ITEM_CHANGE_TYPE_UPDATE,
#fieldname, fieldname );\
+			e_gw_item_set_change (item, E_GW_ITEM_CHANGE_TYPE_UPDATE,
#fieldname, (gpointer) fieldname );\

	}                                                                                                 \
 	else if ( fieldname
)                                                                               \
-		e_gw_item_set_change (item, E_GW_ITEM_CHANGE_TYPE_ADD, #fieldname,
fieldname );           \
+		e_gw_item_set_change (item, E_GW_ITEM_CHANGE_TYPE_ADD, #fieldname,
(gpointer) fieldname );           \
 	}G_STMT_END
 
 void
 e_gw_item_set_changes (EGwItem *item, EGwItem *cache_item)
 {
-	char *subject, *cache_subject;
-	char *message, *cache_message;
+	const char *subject, *cache_subject;
+	const char *message, *cache_message;
 	const char *classification, *cache_classification;
-	char *accept_level, *cache_accept_level;
-	char *place, *cache_place;
-	char *priority, *cache_priority;
+	const char *accept_level, *cache_accept_level;
+	const char *place, *cache_place;
+	const char *priority, *cache_priority;
 	int trigger, cache_trigger;
+	char *due_date, *cache_due_date;
+	char *start_date, *cache_start_date;
+	char *end_date, *cache_end_date;
 
 	/* TODO assert the types of the items are the same */
 
@@ -885,15 +965,13 @@ e_gw_item_set_changes (EGwItem *item, EG
 	SET_DELTA(message);
 	SET_DELTA(classification);
 
-	if (strcmp (e_gw_item_get_start_date (item), e_gw_item_get_start_date
(cache_item)))
-		e_gw_item_set_change (item, E_GW_ITEM_CHANGE_TYPE_UPDATE,
"startDate", e_gw_item_get_start_date (item));
 	
+	SET_DELTA(start_date);
 	/*FIXME  recipient_list modifications need go here after server starts
 	 * supporting retraction */
 	if (e_gw_item_get_item_type (item) == E_GW_ITEM_TYPE_APPOINTMENT) {
 
-		if (strcmp (e_gw_item_get_end_date (item), e_gw_item_get_end_date
(cache_item)))
-			e_gw_item_set_change (item, E_GW_ITEM_CHANGE_TYPE_UPDATE, "endDate",
e_gw_item_get_end_date (item));
+		SET_DELTA(end_date);
 		SET_DELTA(accept_level);
 		SET_DELTA(place);
 		trigger = e_gw_item_get_trigger (item);
@@ -910,8 +988,8 @@ e_gw_item_set_changes (EGwItem *item, EG
 	else if ( e_gw_item_get_item_type (item) == E_GW_ITEM_TYPE_TASK) {
 		gboolean completed, cache_completed;
 		
-		if (strcmp (e_gw_item_get_due_date (item), e_gw_item_get_due_date
(cache_item)))
-			e_gw_item_set_change (item, E_GW_ITEM_CHANGE_TYPE_UPDATE, "dueDate",
e_gw_item_get_due_date (item));
+		SET_DELTA(due_date);
+		
 		completed = e_gw_item_get_completed (item);
 		cache_completed = e_gw_item_get_completed (cache_item);
 		if ((completed && !cache_completed) || (!completed &&
cache_completed))
Index: calendar/backends/groupwise/e-cal-backend-groupwise-utils.h
===================================================================
RCS file:
/cvs/gnome/evolution-data-server/calendar/backends/groupwise/e-cal-backend-groupwise-utils.h,v
retrieving revision 1.6
diff -u -p -r1.6 e-cal-backend-groupwise-utils.h
--- calendar/backends/groupwise/e-cal-backend-groupwise-utils.h	5 Jul
2004 06:21:48 -0000	1.6
+++ calendar/backends/groupwise/e-cal-backend-groupwise-utils.h	12 Jul
2004 12:17:39 -0000
@@ -39,10 +39,16 @@ void          e_gw_item_set_changes (EGw
 /*
  * Connection-related utility functions
  */
-EGwConnectionStatus e_gw_connection_send_appointment (EGwConnection
*cnc, const char *container, icaltimezone *default_zone, ECalComponent
*comp, char **id);
+EGwConnectionStatus e_gw_connection_create_appointment (EGwConnection
*cnc, const char *container, icaltimezone *default_zone, ECalComponent
*comp, GSList **id_list);
+EGwConnectionStatus e_gw_connection_send_appointment (EGwConnection
*cnc, const char *container, icaltimezone *default_zone, ECalComponent
*comp, icalproperty_method method);
 EGwConnectionStatus e_gw_connection_get_freebusy_info (EGwConnection
*cnc, GList *users,
-			       time_t start, time_t end, GList **freebusy, icaltimezone
*default_zone);
+						       time_t start, time_t end, GList **freebusy);
 
+/*
+ * Component related utility functions
+ */
+  
+const char *e_cal_component_get_gw_id (ECalComponent *comp);
 G_END_DECLS
 
 #endif
Index: calendar/backends/groupwise/e-cal-backend-groupwise.c
===================================================================
RCS file:
/cvs/gnome/evolution-data-server/calendar/backends/groupwise/e-cal-backend-groupwise.c,v
retrieving revision 1.74
diff -u -p -r1.74 e-cal-backend-groupwise.c
--- calendar/backends/groupwise/e-cal-backend-groupwise.c	12 Jul 2004
09:08:36 -0000	1.74
+++ calendar/backends/groupwise/e-cal-backend-groupwise.c	12 Jul 2004
12:17:39 -0000
@@ -73,8 +73,6 @@ populate_cache (ECalBackendGroupwise *cb
 	ECalBackendGroupwisePrivate *priv;
 	EGwConnectionStatus status;
         ECalComponent *comp;
-	const char *uid;
-	char *rid;
         GList *list = NULL, *l;
 
 	priv = cbgw->priv;
@@ -95,10 +93,7 @@ populate_cache (ECalBackendGroupwise *cb
 		g_object_unref (item);
 		if (E_IS_CAL_COMPONENT (comp)) {
 			e_cal_component_commit_sequence (comp);
-			e_cal_component_get_uid (comp, &uid);
-			rid = g_strdup (e_cal_component_get_recurid_as_string (comp));
 			e_cal_backend_cache_put_component (priv->cache, comp);
-			g_free (rid);
 			g_object_unref (comp);
 		}
         }
@@ -796,14 +791,11 @@ e_cal_backend_groupwise_get_free_busy (E
        EGwConnectionStatus status;
        ECalBackendGroupwise *cbgw;
        EGwConnection *cnc;
-       icaltimezone *default_zone;
 
        cbgw = E_CAL_BACKEND_GROUPWISE (backend);
        cnc = cbgw->priv->cnc;
-       default_zone = cbgw->priv->default_zone;
-       
 
-       status = e_gw_connection_get_freebusy_info (cnc, users, start,
end, freebusy, default_zone);
+       status = e_gw_connection_get_freebusy_info (cnc, users, start,
end, freebusy);
        if (status != E_GW_CONNECTION_STATUS_OK)
                return GNOME_Evolution_Calendar_OtherError;
        return GNOME_Evolution_Calendar_Success; 
@@ -939,6 +931,36 @@ e_cal_backend_groupwise_internal_get_tim
 	return icaltimezone_get_utc_timezone ();
 }
 
+static void
+set_container_id (ECalBackendSync *backend, ECalComponent *comp, char
*server_uid)
+{
+	ECalBackendGroupwise *cbgw;
+	icalproperty *icalprop;
+	int i;
+	GString *str = g_string_new ("");;	
+	
+	cbgw = E_CAL_BACKEND_GROUPWISE (backend);
+	if (server_uid) {
+
+		/* the ID returned by sendItemResponse includes the container ID of
the
+		   inbox folder, so we need to replace that with our container ID */
+		for (i = 0; i < strlen (server_uid); i++) {
+			str = g_string_append_c (str, server_uid[i]);
+			if (server_uid[i] == ':') {
+				str = g_string_append (str, cbgw->priv->container_id);
+				break;
+			}
+		}
+		
+		/* add the extra property to the component */
+		icalprop = icalproperty_new_x (str->str);
+		icalproperty_set_x_name (icalprop, "X-GWRECORDID");
+		icalcomponent_add_property (e_cal_component_get_icalcomponent (comp),
icalprop);
+
+		g_string_free (str, TRUE);
+	}
+}
+
 static ECalBackendSyncStatus
 e_cal_backend_groupwise_create_object (ECalBackendSync *backend,
EDataCal *cal, char **calobj, char **uid)
 {
@@ -948,6 +970,8 @@ e_cal_backend_groupwise_create_object (E
 	ECalComponent *comp;
 	EGwConnectionStatus status;
 	char *server_uid = NULL;
+	GSList *uid_list = NULL, *l;
+	int i;
 
 	cbgw = E_CAL_BACKEND_GROUPWISE (backend);
 	priv = cbgw->priv;
@@ -973,40 +997,39 @@ e_cal_backend_groupwise_create_object (E
 	case CAL_MODE_ANY :
 	case CAL_MODE_REMOTE :
 		/* when online, send the item to the server */
-		status = e_gw_connection_send_appointment (priv->cnc,
priv->container_id, priv->default_zone, comp, &server_uid);
+		status = e_gw_connection_create_appointment (priv->cnc,
priv->container_id, priv->default_zone, comp, &uid_list);
 		if (status != E_GW_CONNECTION_STATUS_OK) {
 			g_object_unref (comp);
 			return GNOME_Evolution_Calendar_OtherError;
 		}
 
-		if (server_uid) {
-			icalproperty *icalprop;
-			int i;
-			GString *str = g_string_new ("");;
-
-			/* the ID returned by sendItemResponse includes the container ID of
the
-			   inbox folder, so we need to replace that with our container ID */
-			for (i = 0; i < strlen (server_uid); i++) {
-				str = g_string_append_c (str, server_uid[i]);
-				if (server_uid[i] == ':') {
-					str = g_string_append (str, priv->container_id);
-					break;
-				}
-			}
-			
-			/* add the extra property to the component */
-			icalprop = icalproperty_new_x (str->str);
-			icalproperty_set_x_name (icalprop, "X-EVOLUTION-GROUPWISE-ID");
-			icalcomponent_add_property (e_cal_component_get_icalcomponent
(comp), icalprop);
-
-			g_string_free (str, TRUE);
+		if (uid_list && (g_slist_length (uid_list) == 1)) {
+			server_uid = (char *) uid_list->data;
+			set_container_id (backend, comp, server_uid);	
 			g_free (server_uid);
+			/* if successful, update the cache */
+			e_cal_backend_cache_put_component (priv->cache, comp);
+		} else {
+			/* clone components and set individual ids to them */
+			for (i=0, l = uid_list; l ; l = g_slist_next (l), i++) {
+				ECalComponent *e_cal_comp;
+				char *new_uid, *uid;
+
+				server_uid = (char *) l->data;
+				e_cal_comp = e_cal_component_clone (comp);
+				/* set a new uid*/
+				e_cal_component_get_uid (comp, (const char **) &uid);
+				new_uid = g_strdup_printf ("%s%d", uid, i);
+//				e_cal_component_set_uid (comp, new_uid); 
+				g_free (new_uid);
+				set_container_id (backend, e_cal_comp, server_uid);
+				g_free (server_uid);
+				e_cal_backend_cache_put_component (priv->cache, e_cal_comp);
+				g_object_unref (e_cal_comp);
+			}
+			// FIXME  comp is not set to anything meaningful here.
 		}
 
-		/* if successful, update the cache */
-	case CAL_MODE_LOCAL :
-		/* in offline mode, we just update the cache */
-		e_cal_backend_cache_put_component (priv->cache, comp);
 		break;
 	default :
 		break;
@@ -1026,7 +1049,7 @@ e_cal_backend_groupwise_modify_object (E
 	ECalBackendGroupwise *cbgw;
         ECalBackendGroupwisePrivate *priv;
 	icalcomponent *icalcomp;
-	ECalComponent *comp, *cache_comp;
+	ECalComponent *comp, *cache_comp = NULL;
 	EGwConnectionStatus status;
 	EGwItem *item, *cache_item;
 
@@ -1059,12 +1082,12 @@ e_cal_backend_groupwise_modify_object (E
 
 		cache_item =  e_gw_item_new_from_cal_component (priv->container_id,
priv->default_zone, cache_comp);
 		e_gw_item_set_changes (item, cache_item); 
-		g_object_unref (cache_comp);
 
 		/* the second argument is redundant */
 		status = e_gw_connection_modify_item (priv->cnc, e_gw_item_get_id
(item), item);
 		if (status != E_GW_CONNECTION_STATUS_OK) {
 			g_object_unref (comp);
+			g_object_unref (cache_comp);
 			return GNOME_Evolution_Calendar_OtherError;
 		}
 		/* if successful, update the cache */
@@ -1077,9 +1100,10 @@ e_cal_backend_groupwise_modify_object (E
 		break;
 	}
 
-	g_object_unref (comp);
 
-	*old_object = g_strdup (calobj);
+	*old_object = e_cal_component_get_as_string (cache_comp);
+	g_object_unref (cache_comp);
+	g_object_unref (comp);
 	return GNOME_Evolution_Calendar_Success;
 }
 
@@ -1099,7 +1123,7 @@ e_cal_backend_groupwise_remove_object (E
 	/* if online, remove the item from the server */
 	if (priv->mode == CAL_MODE_REMOTE) {
 		ECalBackendSyncStatus status;
-		char *id_to_remove = NULL;
+		const char *id_to_remove = NULL;
 		icalproperty *icalprop;
 		icalcomponent *icalcomp;
 
@@ -1113,14 +1137,14 @@ e_cal_backend_groupwise_remove_object (E
 			return GNOME_Evolution_Calendar_InvalidObject;
 		}
 
-		/* search the component for the X-EVOLUTION-GROUPWISE-ID property */
+		/* search the component for the X-GWRECORDID property */
 		icalprop = icalcomponent_get_first_property (icalcomp,
ICAL_X_PROPERTY);
 		while (icalprop) {
 			const char *x_name, *x_val;
 
 			x_name = icalproperty_get_x_name (icalprop);
 			x_val = icalproperty_get_x (icalprop);
-			if (!strcmp (x_name, "X-EVOLUTION-GROUPWISE-ID")) {
+			if (!strcmp (x_name, "X-GWRECORDID")) {
 				id_to_remove = x_val;
 				break;
 			}
@@ -1165,33 +1189,18 @@ e_cal_backend_groupwise_remove_object (E
 static ECalBackendSyncStatus
 receive_object (ECalBackendGroupwise *cbgw, EDataCal *cal,
icalcomponent *icalcomp)
 {
-	ECalComponent *comp, *found_comp;
+	ECalComponent *comp;
 	ECalBackendGroupwisePrivate *priv;
-	const char *uid, *rid;
-	char *comp_str;
-	ECalBackendSyncStatus status = GNOME_Evolution_Calendar_Success;
+	icalproperty_method method;
 
 	priv = cbgw->priv;
 
 	/* search the object in the cache */
 	comp = e_cal_component_new ();
 	e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone
(icalcomp));
-	e_cal_component_get_uid (comp, &uid);
-	rid = e_cal_component_get_recurid_as_string (comp);
-
-	comp_str = e_cal_component_get_as_string (comp);
+	method = icalcomponent_get_method (icalcomp);
 
-	found_comp = e_cal_backend_cache_get_component (priv->cache, uid,
rid);
-	if (found_comp) {
-		status = e_cal_backend_groupwise_modify_object (E_CAL_BACKEND_SYNC
(cbgw), cal, comp_str,
-								CALOBJ_MOD_THIS, found_comp);
-	} else
-		status = e_cal_backend_groupwise_create_object (E_CAL_BACKEND_SYNC
(cbgw), cal, &comp_str, NULL);
-
-	g_free (comp_str);
-	g_object_unref (comp);
-
-	return status;
+	return e_gw_connection_send_appointment (priv->cnc,
priv->container_id, priv->default_zone, comp, method);
 }
 
 /* Update_objects handler for the file backend. */
@@ -1233,27 +1242,39 @@ e_cal_backend_groupwise_receive_objects 
 }
 
 static ECalBackendSyncStatus
-send_object (ECalBackendGroupwise *cbgw, EDataCal *cal, icalcomponent
*icalcomp)
+send_object (ECalBackendGroupwise *cbgw, EDataCal *cal, icalcomponent
*icalcomp, icalproperty_method method)
 {
-	ECalComponent *comp;
+	ECalComponent *comp, *found_comp;
 	ECalBackendGroupwisePrivate *priv;
 	ECalBackendSyncStatus status = GNOME_Evolution_Calendar_Success;
+	char *uid, *comp_str;
 
 	priv = cbgw->priv;
 
 	comp = e_cal_component_new ();
 	e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone
(icalcomp));
 
+	e_cal_component_get_uid (comp, (const char **) &uid);
+	found_comp = e_cal_backend_cache_get_component (priv->cache, uid,
NULL);
+
 	switch (priv->mode) {
 	case CAL_MODE_ANY :
 	case CAL_MODE_REMOTE :
-		/* when online, send the item to the server */
-		status = e_gw_connection_send_appointment (priv->cnc,
priv->container_id, priv->default_zone, comp, NULL);
+		if (found_comp) {
+			char *comp_str;
+			status = e_cal_backend_groupwise_modify_object (E_CAL_BACKEND_SYNC
(cbgw), cal, comp_str,
+									CALOBJ_MOD_THIS, &comp_str);
+			g_free (comp_str);
+		} else
+			status = e_cal_backend_groupwise_create_object (E_CAL_BACKEND_SYNC
(cbgw), cal, &comp_str, NULL);
+
 		break;
 	case CAL_MODE_LOCAL :
 		/* in offline mode, we just update the cache */
 		e_cal_backend_cache_put_component (priv->cache, comp);
 		break;
+	default:
+		break;	
 	}
 
 	g_object_unref (comp);
@@ -1268,6 +1289,7 @@ e_cal_backend_groupwise_send_objects (EC
 	ECalBackendSyncStatus status = GNOME_Evolution_Calendar_OtherError;
 	icalcomponent *icalcomp, *subcomp;
 	icalcomponent_kind kind;
+	icalproperty_method method;
 	ECalBackendGroupwise *cbgw;
 	ECalBackendGroupwisePrivate *priv;
 
@@ -1281,19 +1303,21 @@ e_cal_backend_groupwise_send_objects (EC
 	if (!icalcomp)
 		return GNOME_Evolution_Calendar_InvalidObject;
 
+	method = icalcomponent_get_method (icalcomp);
 	kind = icalcomponent_isa (icalcomp);
 	if (kind == ICAL_VCALENDAR_COMPONENT) {
 		subcomp = icalcomponent_get_first_component (icalcomp,
 							     e_cal_backend_get_kind (E_CAL_BACKEND (backend)));
 		while (subcomp) {
-			status = send_object (cbgw, cal, subcomp);
+
+			status = send_object (cbgw, cal, subcomp, method);
 			if (status != GNOME_Evolution_Calendar_Success)
 				break;
 			subcomp = icalcomponent_get_next_component (icalcomp,
 								    e_cal_backend_get_kind (E_CAL_BACKEND (backend)));
 		}
 	} else if (kind == e_cal_backend_get_kind (E_CAL_BACKEND (backend))) {
-		status = send_object (cbgw, cal, icalcomp);
+		status = send_object (cbgw, cal, icalcomp, method);
 	} else
 		status = GNOME_Evolution_Calendar_InvalidObject;
 	
@@ -1303,7 +1327,12 @@ e_cal_backend_groupwise_send_objects (EC
 		comp = e_cal_component_new ();
 		
 		if (e_cal_component_set_icalcomponent (comp, icalcomp)) {
-			e_cal_component_get_attendee_list (comp, users);
+			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))
+				*users = g_list_append (*users, tmp);
+			
 			g_object_unref (comp);	
 		}
 		*modified_calobj = g_strdup (calobj);




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