commit 18a2f5f1206e7a7583db2b8c47862f79abf13e50 Author: chenthill 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" /> + + + + + + + + + + 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 +#endif + +#include +#include +#include +#include +#include +#include +#include + +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 @@ + + + + + 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 + * + * + * Authors: + * Chenthill Palanisamy (pchenthill@novell.com) + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + + +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); +}