File sp-process-meetings.diff of Package evolution

commit 18a2f5f1206e7a7583db2b8c47862f79abf13e50
Author: chenthill <chen@rocky.blr.novell.com>
Date:   Tue Dec 30 05:00:06 2008 +0530

    process meetings.

diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index 8d889bd..e1555d8 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -792,6 +792,13 @@ save_comp (CompEditor *editor)
 
 	e_cal_component_set_attachment_list (priv->comp,
 					     get_attachment_list (editor));
+
+	/* Give a chance for plugins to act on the component */
+	ECalEvent *ec_event = e_cal_event_peek ();
+	ECalEventTargetCompEditor *target;
+	target = e_cal_event_target_comp_editor (ec_event, editor);
+	e_event_emit ((EEvent *) ec_event, "editor.commit", (EEventTarget *) target);
+
 	icalcomp = e_cal_component_get_icalcomponent (priv->comp);
 	/* send the component to the server */
 	if (!cal_comp_is_on_server (priv->comp, priv->client)) {
diff --git a/plugins/sharepoint-features/Makefile.am b/plugins/sharepoint-features/Makefile.am
index f101059..9123b66 100644
--- a/plugins/sharepoint-features/Makefile.am
+++ b/plugins/sharepoint-features/Makefile.am
@@ -19,7 +19,9 @@ plugin_DATA = 						\
 plugin_LTLIBRARIES = liborg-gnome-sharepoint-features.la
 
 liborg_gnome_sharepoint_features_la_SOURCES =		\
-	meeting-workspace.c	
+	process-meeting.c				\
+	comp-commit.c					\
+	meeting-workspace.c
 
 liborg_gnome_sharepoint_features_la_LIBADD =				\
 	$(top_builddir)/e-util/libeutil.la				\
@@ -33,6 +35,7 @@ glade_DATA = meetingworkspaces.glade
 
 EXTRA_DIST = 					\
 	org-gnome-sharepoint-features.eplug.xml	\
+	org-gnome-share-point.error.xml		\
 	$(glade_DATA)
 
 BUILT_SOURCES = org-gnome-sharepoint-features.eplug
diff --git a/plugins/sharepoint-features/org-gnome-sharepoint-features.eplug.xml b/plugins/sharepoint-features/org-gnome-sharepoint-features.eplug.xml
index d59db73..3e318fc 100644
--- a/plugins/sharepoint-features/org-gnome-sharepoint-features.eplug.xml
+++ b/plugins/sharepoint-features/org-gnome-sharepoint-features.eplug.xml
@@ -16,5 +16,19 @@
 			   target="compeditor"
 			/>
 		</hook>
+
+		<hook class="org.gnome.evolution.calendar.events:1.0">
+			<event
+			   id="editor.commit"
+			   handle="org_gnome_comp_commit"
+			   target="compeditor"
+			/>
+		</hook>
+
+		<hook class="org.gnome.evolution.calendar.popup:1.0">
+			<menu id="org.gnome.evolution.calendar.view.popup" target="select" factory = "org_gnome_process_meeting">
+			</menu>
+		</hook>
+
 	</e-plugin>
 </e-plugin-list>
 diff --git a/plugins/sharepoint-features/comp-commit.c b/plugins/sharepoint-features/comp-commit.c
new file mode 100644
index 0000000..b87df4f
--- /dev/null
+++ b/plugins/sharepoint-features/comp-commit.c
@@ -0,0 +1,88 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <e-util/e-plugin.h>
+#include <glib/gi18n.h>
+#include <e-util/e-plugin-ui.h>
+#include <e-util/e-util-private.h>
+#include <e-cal-event.h>
+#include <calendar/gui/dialogs/event-editor.h>
+
+void org_gnome_comp_commit (EPlugin *ep, ECalEventTargetCompEditor *target);
+
+static icaltimezone*
+resolve_tzid_cb (const char *tzid, gpointer data)
+{
+	ECal *client;
+	icaltimezone *zone = NULL;
+
+	g_return_val_if_fail (data != NULL, NULL);
+	g_return_val_if_fail (E_IS_CAL (data), NULL);
+
+	client = E_CAL (data);
+
+	/* Try to find the builtin timezone first. */
+	zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
+
+	if (!zone) {
+		/* FIXME: Handle errors. */
+		e_cal_get_timezone (client, tzid, &zone, NULL);
+	}
+
+	return zone;
+}
+
+static gboolean
+recur_cb (ECalComponent *comp, time_t start, time_t end, gpointer data)
+{
+	time_t *end_date = data;
+
+	*end_date = end;
+
+	return TRUE;
+}
+
+void
+org_gnome_comp_commit (EPlugin *ep, ECalEventTargetCompEditor *target)
+{
+	CompEditor *editor = target->editor;
+	CompEditorFlags flags;
+	ECal *client;
+	ECalComponent *comp;
+	ECalComponentDateTime cdt;
+	icaltimezone *zone = NULL;
+	const char *uri;
+	time_t end_date = -1;
+
+	client = comp_editor_get_client (editor);
+	uri = e_cal_get_uri (client);
+	flags = comp_editor_get_flags (editor);
+
+	if (!g_str_has_prefix (uri, "sharepoint://"))
+		return;
+	
+	comp = comp_editor_get_comp (editor);
+	
+	if (!e_cal_component_has_recurrences (comp))
+		return;
+
+	e_cal_component_get_dtstart (comp, &cdt);
+	if (cdt.tzid != NULL) {
+		/* FIXME Will e_cal_get_timezone really not return builtin zones? */
+		if (!e_cal_get_timezone (client, cdt.tzid, &zone, NULL))
+			zone = icaltimezone_get_builtin_timezone_from_tzid (cdt.tzid);
+	}
+	e_cal_component_free_datetime (&cdt);
+
+	e_cal_recur_generate_instances (comp, -1, -1,
+						recur_cb, &end_date,
+						resolve_tzid_cb,
+						client, zone);
+
+	char *end = g_strdup_printf ("%ld",end_date);
+	e_cal_component_set_x_prop (comp, "X-SP-RECUR-ENDDATE", end);
+	g_free (end);
+	g_print ("DEBUG: the component to be saved is %s \n", e_cal_component_get_as_string (comp));
+}
diff --git a/plugins/sharepoint-features/org-gnome-share-point.error.xml b/plugins/sharepoint-features/org-gnome-share-point.error.xml
new file mode 100644
index 0000000..d656dea
--- /dev/null
+++ b/plugins/sharepoint-features/org-gnome-share-point.error.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<error-list domain="org.gnome.evolution.sharepoint">
+
+</error-list>
+
diff --git a/plugins/sharepoint-features/process-meeting.c b/plugins/sharepoint-features/process-meeting.c
new file mode 100644
index 0000000..917166b
--- /dev/null
+++ b/plugins/sharepoint-features/process-meeting.c
@@ -0,0 +1,258 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>  
+ *
+ *
+ * Authors:
+ *		Chenthill Palanisamy (pchenthill@novell.com)
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <calendar/gui/e-cal-popup.h>
+#include <calendar/gui/e-calendar-view.h>
+#include <calendar/gui/itip-utils.h>
+#include <e-util/e-error.h>
+#include <libecal/e-cal.h>
+
+
+typedef struct {
+	ECal *ecal;
+	icalcomponent *icalcomp;
+} ReceiveData;
+
+ECalendarView *c_view;
+
+void org_gnome_process_meeting (EPlugin *ep, ECalPopupTargetSelect *target);
+static void on_accept_meeting (EPopup *ep, EPopupItem *pitem, void *data);
+static void on_accept_meeting_tentative (EPopup *ep, EPopupItem *pitem, void *data);
+static void on_decline_meeting (EPopup *ep, EPopupItem *pitem, void *data);
+
+static EPopupItem popup_items[] = {
+{ E_POPUP_ITEM, "41.accept", N_("Accept"), on_accept_meeting, NULL, GTK_STOCK_APPLY, 0, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_MEETING},
+{ E_POPUP_ITEM, "42.accept", N_("Accept Tentatively"), on_accept_meeting_tentative, NULL, GTK_STOCK_DIALOG_QUESTION, 0, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_MEETING},
+{ E_POPUP_ITEM, "43.decline", N_("Decline"), on_decline_meeting, NULL, GTK_STOCK_CANCEL, 0, E_CAL_POPUP_SELECT_NOTEDITING}
+};
+
+static void
+popup_free (EPopup *ep, GSList *items, void *data)
+{
+	g_slist_free (items);
+	items = NULL;
+}
+
+void
+org_gnome_process_meeting (EPlugin *ep, ECalPopupTargetSelect *target)
+{
+	GSList *menus = NULL;
+	GList *selected;
+	int i = 0;
+	static int first = 0;
+	const char *uri = NULL;
+	ECalendarView *cal_view = E_CALENDAR_VIEW (target->target.widget);
+
+	c_view = cal_view;
+	selected = e_calendar_view_get_selected_events (cal_view);
+	if (selected) {
+		ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data;
+
+		uri = e_cal_get_uri (event->comp_data->client);
+	} else
+		return;
+
+	if (!uri)
+		return;
+
+	if (! g_strrstr (uri, "sharepoint://"))
+		return ;
+
+	/* for translation*/
+	if (!first) {
+		popup_items[0].label =  _(popup_items[0].label);
+	}
+
+	first++;
+
+	for (i = 0; i < sizeof (popup_items) / sizeof (popup_items[0]); i++)
+		menus = g_slist_prepend (menus, &popup_items[i]);
+
+	e_popup_add_items (target->target.popup, menus, NULL, popup_free, NULL);
+}
+
+static void
+finalize_receive_data (ReceiveData *r_data)
+{
+	if (r_data->ecal) {
+		g_object_unref (r_data->ecal);
+		r_data->ecal = NULL;
+	}
+
+	if (r_data->ecal) {
+		icalcomponent_free (r_data->icalcomp);
+		r_data->icalcomp = NULL;
+	}
+
+	g_free (r_data);
+}
+
+static gboolean
+receive_objects (gpointer data)
+{
+	GError *error = NULL;
+	ReceiveData *r_data = data;
+
+
+	icalcomponent_set_method (r_data->icalcomp, ICAL_METHOD_REQUEST);
+
+	if (!e_cal_receive_objects (r_data->ecal, r_data->icalcomp, &error)) {
+		/* FIXME show an error dialog */
+		g_error_free (error);
+	}
+
+	finalize_receive_data (r_data);
+	return TRUE;
+}
+
+static icalproperty *
+find_attendee (icalcomponent *ical_comp, const char *address)
+{
+	icalproperty *prop;
+
+	if (address == NULL)
+		return NULL;
+
+	for (prop = icalcomponent_get_first_property (ical_comp, ICAL_ATTENDEE_PROPERTY);
+	     prop != NULL;
+	     prop = icalcomponent_get_next_property (ical_comp, ICAL_ATTENDEE_PROPERTY)) {
+		icalvalue *value;
+		const char *attendee;
+		char *text;
+
+		value = icalproperty_get_value (prop);
+		if (!value)
+			continue;
+
+		attendee = icalvalue_get_string (value);
+
+		text = g_strdup (itip_strip_mailto (attendee));
+		text = g_strstrip (text);
+		if (!g_ascii_strcasecmp (address, text)) {
+			g_free (text);
+			break;
+		}
+		g_free (text);
+	}
+
+	return prop;
+}
+static void
+change_status (icalcomponent *ical_comp, const char *address, icalparameter_partstat status)
+{
+	icalproperty *prop;
+
+	prop = find_attendee (ical_comp, address);
+	if (prop) {
+		icalparameter *param;
+
+		icalproperty_remove_parameter (prop, ICAL_PARTSTAT_PARAMETER);
+		param = icalparameter_new_partstat (status);
+		icalproperty_add_parameter (prop, param);
+	} else {
+		icalparameter *param;
+
+		prop = icalproperty_new_attendee (address);
+		icalcomponent_add_property (ical_comp, prop);
+
+		param = icalparameter_new_role (ICAL_ROLE_OPTPARTICIPANT);
+		icalproperty_add_parameter (prop, param);
+
+		param = icalparameter_new_partstat (status);
+		icalproperty_add_parameter (prop, param);
+	}
+}
+
+static void
+process_meeting (ECalendarView *cal_view, icalparameter_partstat status)
+{
+	GList *selected;
+	icalcomponent *clone;
+
+	selected = e_calendar_view_get_selected_events (cal_view);
+	if (selected) {
+		ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data;
+		ECalComponent *comp = e_cal_component_new ();
+		ReceiveData *r_data = g_new0 (ReceiveData, 1);
+		gboolean recurring = FALSE;
+		GThread *thread = NULL;
+		GError *error = NULL;
+		char *address = NULL;
+
+		e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
+		address = itip_get_comp_attendee (comp, event->comp_data->client);
+
+		if (e_cal_component_has_recurrences (comp) || e_cal_component_is_instance (comp))
+			recurring = TRUE;
+
+		/* Free comp */
+		g_object_unref (comp);
+		comp = NULL;
+
+		clone = icalcomponent_new_clone (event->comp_data->icalcomp);
+		change_status (clone, address, status);
+
+		r_data->ecal = g_object_ref (event->comp_data->client);
+		r_data->icalcomp = clone;
+
+		g_print ("The updated meeting is %s \n", icalcomponent_as_ical_string (clone));
+
+		thread = g_thread_create ((GThreadFunc) receive_objects, r_data , FALSE, &error);
+		if (!thread) {
+			g_warning (G_STRLOC ": %s", error->message);
+			g_error_free (error);
+		}
+	}
+}
+
+/*FIXME the data does not give us the ECalendarView object.
+  we should remove the global c_view variable once we get it from the data*/
+static void
+on_accept_meeting (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	ECalendarView *cal_view = c_view;
+
+	process_meeting (cal_view, ICAL_PARTSTAT_ACCEPTED);
+}
+static void
+on_accept_meeting_tentative (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	ECalendarView *cal_view = c_view;
+
+	process_meeting (cal_view, ICAL_PARTSTAT_TENTATIVE);
+}
+
+static void
+on_decline_meeting (EPopup *ep, EPopupItem *pitem, void *data)
+{
+	ECalendarView *cal_view = c_view;
+
+	process_meeting (cal_view, ICAL_PARTSTAT_DECLINED);
+}
openSUSE Build Service is sponsored by