aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/itip-formatter/itip-formatter.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/itip-formatter/itip-formatter.c')
-rw-r--r--plugins/itip-formatter/itip-formatter.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/plugins/itip-formatter/itip-formatter.c b/plugins/itip-formatter/itip-formatter.c
new file mode 100644
index 0000000000..c16cc24826
--- /dev/null
+++ b/plugins/itip-formatter/itip-formatter.c
@@ -0,0 +1,275 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: JP Rosevear <jpr@novell.com>
+ *
+ * Copyright 2004 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <libgnome/gnome-i18n.h>
+#include <gconf/gconf-client.h>
+#include <camel/camel-stream.h>
+#include <camel/camel-stream-mem.h>
+#include <camel/camel-medium.h>
+#include <camel/camel-mime-message.h>
+#include <libecal/e-cal.h>
+#include <libecal/e-cal-time-util.h>
+#include <gtkhtml/gtkhtml-embedded.h>
+#include <mail/em-format-hook.h>
+#include <mail/em-format-html.h>
+#include <e-util/e-account-list.h>
+#include <e-util/e-icon-factory.h>
+#include <calendar/gui/itip-utils.h>
+#include "itip-view.h"
+
+#define CLASSID "itip://"
+
+void format_itip (EPlugin *ep, EMFormatHookTarget *target);
+
+typedef struct {
+ EMFormatHTMLPObject pobject;
+
+ GtkWidget *view;
+
+ ESourceList *source_lists[E_CAL_SOURCE_TYPE_LAST];
+ GHashTable *ecals[E_CAL_SOURCE_TYPE_LAST];
+
+ ECal *current_ecal;
+ ECalSourceType type;
+
+ char action;
+ gboolean rsvp;
+
+ GtkWidget *ok;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+
+ char *vcalendar;
+ ECalComponent *comp;
+ icalcomponent *main_comp;
+ icalcomponent *ical_comp;
+ icalcomponent *top_level;
+ icalcompiter iter;
+ icalproperty_method method;
+
+ int current;
+ int total;
+
+ gchar *calendar_uid;
+
+ EAccountList *accounts;
+
+ gchar *from_address;
+ gchar *delegator_address;
+ gchar *delegator_name;
+ gchar *my_address;
+ gint view_only;
+} FormatItipPObject;
+
+static icalcomponent *
+get_next (icalcompiter *iter)
+{
+ icalcomponent *ret = NULL;
+ icalcomponent_kind kind;
+
+ do {
+ icalcompiter_next (iter);
+ ret = icalcompiter_deref (iter);
+ if (ret == NULL)
+ break;
+ kind = icalcomponent_isa (ret);
+ } while (ret != NULL
+ && kind != ICAL_VEVENT_COMPONENT
+ && kind != ICAL_VTODO_COMPONENT
+ && kind != ICAL_VFREEBUSY_COMPONENT);
+
+ return ret;
+}
+
+static void
+extract_itip_data (FormatItipPObject *pitip)
+{
+ CamelDataWrapper *content;
+ CamelStream *mem;
+ icalproperty *prop;
+ icalcomponent_kind kind = ICAL_NO_COMPONENT;
+ icalcomponent *tz_comp;
+ icalcompiter tz_iter;
+
+/* FIXME try and match sender with organizer/attendee/sentby?
+ pd->from_address = camel_address_encode ((CamelAddress *)from);
+ g_message ("Detected from address %s", pd->from_address);
+*/
+
+ content = camel_medium_get_content_object ((CamelMedium *) pitip->pobject.part);
+ mem = camel_stream_mem_new ();
+ camel_data_wrapper_write_to_stream (content, mem);
+
+ pitip->vcalendar = g_strndup (((CamelStreamMem *) mem)->buffer->data, ((CamelStreamMem *) mem)->buffer->len);
+
+ /* FIXME unref the content object as well? */
+ camel_object_unref (mem);
+
+ pitip->top_level = e_cal_util_new_top_level ();
+
+ pitip->main_comp = icalparser_parse_string (pitip->vcalendar);
+ if (pitip->main_comp == NULL) {
+// write_error_html (itip, _("The attachment does not contain a valid calendar message"));
+ return;
+ }
+
+ prop = icalcomponent_get_first_property (pitip->main_comp, ICAL_METHOD_PROPERTY);
+ if (prop == NULL) {
+ pitip->method = ICAL_METHOD_PUBLISH;
+ } else {
+ pitip->method = icalproperty_get_method (prop);
+ }
+
+ tz_iter = icalcomponent_begin_component (pitip->main_comp, ICAL_VTIMEZONE_COMPONENT);
+ while ((tz_comp = icalcompiter_deref (&tz_iter)) != NULL) {
+ icalcomponent *clone;
+
+ clone = icalcomponent_new_clone (tz_comp);
+ icalcomponent_add_component (pitip->top_level, clone);
+
+ icalcompiter_next (&tz_iter);
+ }
+
+ pitip->iter = icalcomponent_begin_component (pitip->main_comp, ICAL_ANY_COMPONENT);
+ pitip->ical_comp = icalcompiter_deref (&pitip->iter);
+ if (pitip->ical_comp != NULL) {
+ kind = icalcomponent_isa (pitip->ical_comp);
+ if (kind != ICAL_VEVENT_COMPONENT
+ && kind != ICAL_VTODO_COMPONENT
+ && kind != ICAL_VFREEBUSY_COMPONENT)
+ pitip->ical_comp = get_next (&pitip->iter);
+ }
+
+ if (pitip->ical_comp == NULL) {
+// write_error_html (itip, _("The attachment has no viewable calendar items"));
+ return;
+ }
+
+ pitip->total = icalcomponent_count_components (pitip->main_comp, ICAL_VEVENT_COMPONENT);
+ pitip->total += icalcomponent_count_components (pitip->main_comp, ICAL_VTODO_COMPONENT);
+ pitip->total += icalcomponent_count_components (pitip->main_comp, ICAL_VFREEBUSY_COMPONENT);
+
+ if (pitip->total > 0)
+ pitip->current = 1;
+ else
+ pitip->current = 0;
+
+ pitip->comp = e_cal_component_new ();
+ if (!e_cal_component_set_icalcomponent (pitip->comp, pitip->ical_comp)) {
+// write_error_html (itip, _("The message does not appear to be properly formed"));
+ g_object_unref (pitip->comp);
+ pitip->comp = NULL;
+ return;
+ };
+
+// show_current (itip);
+}
+
+static gboolean
+format_itip_object (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject)
+{
+ FormatItipPObject *pitip = (FormatItipPObject *) pobject;
+ ECalComponentText text;
+ ECalComponentOrganizer organizer;
+ ECalComponentDateTime datetime;
+ icaltimezone *from_zone, *to_zone;
+ const char *string;
+
+ /* FIXME Error handling? */
+ extract_itip_data (pitip);
+
+ pitip->view = itip_view_new ();
+ gtk_widget_show (pitip->view);
+
+ itip_view_set_mode (ITIP_VIEW (pitip->view), ITIP_VIEW_MODE_REQUEST);
+
+ e_cal_component_get_organizer (pitip->comp, &organizer);
+ itip_view_set_organizer (ITIP_VIEW (pitip->view), organizer.cn ? organizer.cn : itip_strip_mailto (organizer.value));
+ /* FIXME, do i need to strip the sentby somehow? Maybe with camel? */
+ itip_view_set_sentby (ITIP_VIEW (pitip->view), organizer.sentby);
+
+ e_cal_component_get_summary (pitip->comp, &text);
+ itip_view_set_summary (ITIP_VIEW (pitip->view), text.value ? text.value : _("None"));
+
+ e_cal_component_get_location (pitip->comp, &string);
+ itip_view_set_location (ITIP_VIEW (pitip->view), string);
+
+ to_zone = calendar_config_get_icaltimezone ();
+
+ e_cal_component_get_dtstart (pitip->comp, &datetime);
+ if (datetime.value) {
+ struct tm start_tm;
+
+ /* FIXME Handle tzid that is not in the component - treat as "local" time */
+ if (!datetime.value->is_utc && datetime.tzid)
+ from_zone = icalcomponent_get_timezone (pitip->top_level, datetime.tzid);
+ else
+ from_zone = NULL;
+
+ start_tm = icaltimetype_to_tm_with_zone (datetime.value, from_zone, to_zone);
+
+ itip_view_set_start (ITIP_VIEW (pitip->view), &start_tm);
+ }
+ e_cal_component_free_datetime (&datetime);
+
+ e_cal_component_get_dtend (pitip->comp, &datetime);
+ if (datetime.value) {
+ struct tm end_tm;
+
+ /* FIXME Handle tzid that is not in the component - treat as "local" time */
+ if (!datetime.value->is_utc && datetime.tzid)
+ from_zone = icalcomponent_get_timezone (pitip->top_level, datetime.tzid);
+ else
+ from_zone = NULL;
+
+ end_tm = icaltimetype_to_tm_with_zone (datetime.value, from_zone, to_zone);
+
+ itip_view_set_end (ITIP_VIEW (pitip->view), &end_tm);
+ }
+ e_cal_component_free_datetime (&datetime);
+
+ gtk_container_add (GTK_CONTAINER (eb), pitip->view);
+
+ return TRUE;
+}
+
+void
+format_itip (EPlugin *ep, EMFormatHookTarget *target)
+{
+ FormatItipPObject *pitip;
+
+ calendar_config_init ();
+
+ pitip = (FormatItipPObject *) em_format_html_add_pobject ((EMFormatHTML *) target->format, sizeof (FormatItipPObject), CLASSID, target->part, format_itip_object);
+ // FIXME set the free function
+// pitip->object.free = pitip_free;
+ camel_stream_printf (target->stream, "<table border=0 width=\"100%%\" cellpadding=3><tr>");
+ camel_stream_printf (target->stream, "<td valign=top><object classid=\"%s\"></object></td><td width=100%% valign=top>", CLASSID);
+ camel_stream_printf (target->stream, "</td></tr></table>");
+}