evolution/sp-process-meetings.diff

441 lines
12 KiB
Diff

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);
+}