diff options
Diffstat (limited to 'plugins')
24 files changed, 0 insertions, 10202 deletions
diff --git a/plugins/audio-inline/Makefile.am b/plugins/audio-inline/Makefile.am deleted file mode 100644 index 7afdceec97..0000000000 --- a/plugins/audio-inline/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -if OS_WIN32 -NO_UNDEFINED_REQUIRED_LIBS = \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/e-util/libeutil.la \ - $(GNOME_PLATFORM_LIBS) -endif - -@EVO_PLUGIN_RULE@ - -plugin_DATA = org-gnome-audio-inline.eplug - -plugin_LTLIBRARIES = liborg-gnome-audio-inline.la - -liborg_gnome_audio_inline_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(GSTREAMER_CFLAGS) - -liborg_gnome_audio_inline_la_SOURCES = audio-inline.c - -liborg_gnome_audio_inline_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_audio_inline_la_LIBADD = \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/em-format/libemformat.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(GSTREAMER_LIBS) - -EXTRA_DIST = org-gnome-audio-inline.eplug.xml - -BUILT_SOURCES = $(plugin_DATA) -CLEANFILES = $(BUILT_SOURCES) - --include $(top_srcdir)/git.mk diff --git a/plugins/audio-inline/audio-inline.c b/plugins/audio-inline/audio-inline.c deleted file mode 100644 index 45238db2eb..0000000000 --- a/plugins/audio-inline/audio-inline.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * 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: - * Radek Doulik <rodo@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <glib/gstdio.h> -#include "e-util/e-mktemp.h" -#include "mail/em-format-hook.h" -#include "mail/em-format-html.h" -#include "gst/gst.h" - -#define d(x) - -gint e_plugin_lib_enable (EPlugin *ep, gint enable); - -gint -e_plugin_lib_enable (EPlugin *ep, - gint enable) -{ - return 0; -} - -void org_gnome_audio_inline_format (gpointer ep, EMFormatHookTarget *t); - -typedef struct _EMFormatInlineAudioPURI EMFormatInlineAudioPURI; - -struct _EMFormatInlineAudioPURI { - EMFormatPURI puri; - - gchar *filename; - GstElement *playbin; - gulong bus_id; - GstState target_state; - GtkWidget *play_button; - GtkWidget *pause_button; - GtkWidget *stop_button; -}; - -static void -org_gnome_audio_inline_pobject_free (EMFormatPURI *o) -{ - EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) o; - - d(printf ("audio inline formatter: pobject free\n")); - - if (po->play_button) { - g_object_unref (po->play_button); - po->play_button = NULL; - } - - if (po->pause_button) { - g_object_unref (po->pause_button); - po->pause_button = NULL; - } - - if (po->stop_button) { - g_object_unref (po->stop_button); - po->stop_button = NULL; - } - - if (po->filename) { - g_unlink (po->filename); - g_free (po->filename); - po->filename = NULL; - } - - if (po->bus_id) { - g_source_remove (po->bus_id); - po->bus_id = 0; - } - - if (po->playbin) { - gst_element_set_state (po->playbin, GST_STATE_NULL); - gst_object_unref (po->playbin); - po->playbin = NULL; - } -} - -static void -org_gnome_audio_inline_pause_clicked (GtkWidget *button, - EMFormatPURI *puri) -{ - EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri; - - if (po->playbin) { - /* pause playing */ - gst_element_set_state (po->playbin, GST_STATE_PAUSED); - } -} - -static void -org_gnome_audio_inline_stop_clicked (GtkWidget *button, - EMFormatPURI *puri) -{ - EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri; - - if (po->playbin) { - /* ready to play */ - gst_element_set_state (po->playbin, GST_STATE_READY); - po->target_state = GST_STATE_READY; - } -} - -static void -org_gnome_audio_inline_set_audiosink (GstElement *playbin) -{ - GstElement *audiosink; - - /* now it's time to get the audio sink */ - audiosink = gst_element_factory_make ("gconfaudiosink", "play_audio"); - if (audiosink == NULL) { - audiosink = gst_element_factory_make ("autoaudiosink", "play_audio"); - } - - if (audiosink) { - g_object_set (playbin, "audio-sink", audiosink, NULL); - } -} - -static gboolean -org_gnome_audio_inline_gst_callback (GstBus *bus, - GstMessage *message, - gpointer data) -{ - EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) data; - GstMessageType msg_type; - - g_return_val_if_fail (po != NULL, TRUE); - g_return_val_if_fail (po->playbin != NULL, TRUE); - - msg_type = GST_MESSAGE_TYPE (message); - - switch (msg_type) { - case GST_MESSAGE_ERROR: - gst_element_set_state (po->playbin, GST_STATE_NULL); - break; - case GST_MESSAGE_EOS: - gst_element_set_state (po->playbin, GST_STATE_READY); - break; - case GST_MESSAGE_STATE_CHANGED: - { - GstState old_state, new_state; - - if (GST_MESSAGE_SRC (message) != GST_OBJECT (po->playbin)) - break; - - gst_message_parse_state_changed (message, &old_state, &new_state, NULL); - - if (old_state == new_state) - break; - - if (po->play_button) - gtk_widget_set_sensitive (po->play_button, new_state <= GST_STATE_PAUSED); - if (po->pause_button) - gtk_widget_set_sensitive (po->pause_button, new_state > GST_STATE_PAUSED); - if (po->stop_button) - gtk_widget_set_sensitive (po->stop_button, new_state >= GST_STATE_PAUSED); - } - - break; - default: - break; - } - - return TRUE; -} - -static void -org_gnome_audio_inline_play_clicked (GtkWidget *button, - EMFormatPURI *puri) -{ - EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri; - GstState cur_state; - - d(printf ("audio inline formatter: play\n")); - - if (!po->filename) { - CamelStream *stream; - CamelDataWrapper *data; - GError *error = NULL; - gint argc = 1; - const gchar *argv [] = { "org_gnome_audio_inline", NULL }; - - /* FIXME this is ugly, we should stream this directly to gstreamer */ - po->filename = e_mktemp ("org-gnome-audio-inline-file-XXXXXX"); - - d(printf ("audio inline formatter: write to temp file %s\n", po->filename)); - - stream = camel_stream_fs_new_with_name (po->filename, O_RDWR | O_CREAT | O_TRUNC, 0600, NULL); - data = camel_medium_get_content (CAMEL_MEDIUM (po->puri.part)); - camel_data_wrapper_decode_to_stream_sync ( - data, stream, NULL, NULL); - camel_stream_flush (stream, NULL, NULL); - g_object_unref (stream); - - d(printf ("audio inline formatter: init gst playbin\n")); - - if (gst_init_check (&argc, (gchar ***) &argv, &error)) { - gchar *uri; - GstBus *bus; - - /* create a disk reader */ - po->playbin = gst_element_factory_make ("playbin", "playbin"); - if (po->playbin == NULL) { - g_printerr ("Failed to create gst_element_factory playbin; check your installation\n"); - return; - - } - - uri = g_filename_to_uri (po->filename, NULL, NULL); - g_object_set (po->playbin, "uri", uri, NULL); - g_free (uri); - org_gnome_audio_inline_set_audiosink (po->playbin); - - bus = gst_element_get_bus (po->playbin); - po->bus_id = gst_bus_add_watch (bus, org_gnome_audio_inline_gst_callback, po); - gst_object_unref (bus); - - } else { - g_printerr ("GStreamer failed to initialize: %s",error ? error->message : ""); - g_error_free (error); - } - } - - gst_element_get_state (po->playbin, &cur_state, NULL, 0); - - if (cur_state >= GST_STATE_PAUSED) { - gst_element_set_state (po->playbin, GST_STATE_READY); - } - - if (po->playbin) { - /* start playing */ - gst_element_set_state (po->playbin, GST_STATE_PLAYING); - } -} - -static GtkWidget * -org_gnome_audio_inline_add_button (GtkWidget *box, - const gchar *stock_icon, - GCallback cb, - gpointer data, - gboolean sensitive) -{ - GtkWidget *button; - - button = gtk_button_new_from_stock (stock_icon); - gtk_widget_set_sensitive (button, sensitive); - g_signal_connect (button, "clicked", cb, data); - - gtk_widget_show (button); - gtk_box_pack_end (GTK_BOX (box), button, TRUE, TRUE, 0); - - return button; -} - -static void -write_button_panel (EMFormat *emf, - EMFormatPURI *puri, - CamelStream *stream, - EMFormatWriterInfo *info, - GCancellable *cancellable) -{ - gchar *str; - - str = g_strdup_printf ( - "<object type=\"application/x-org-gnome-audio-inline-button-panel\" " - "width=\"100%%\" height=\"auto\" data=\"%s\" id=\"%s\"></object>", - puri->uri, puri->uri); - camel_stream_write_string (stream, str, cancellable, NULL); - - g_free (str); -} - -static GtkWidget * -org_gnome_audio_inline_button_panel (EMFormat *emf, - EMFormatPURI *puri, - GCancellable *cancellable) -{ - GtkWidget *box; - EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri; - - /* it is OK to call UI functions here, since we are called from UI thread */ - - box = gtk_hbutton_box_new (); - po->play_button = g_object_ref (org_gnome_audio_inline_add_button (box, GTK_STOCK_MEDIA_PLAY, G_CALLBACK (org_gnome_audio_inline_play_clicked), po, TRUE)); - po->pause_button = g_object_ref (org_gnome_audio_inline_add_button (box, GTK_STOCK_MEDIA_PAUSE, G_CALLBACK (org_gnome_audio_inline_pause_clicked), po, FALSE)); - po->stop_button = g_object_ref (org_gnome_audio_inline_add_button (box, GTK_STOCK_MEDIA_STOP, G_CALLBACK (org_gnome_audio_inline_stop_clicked), po, FALSE)); - - gtk_widget_show (box); - - return box; -} - -void -org_gnome_audio_inline_format (gpointer ep, - EMFormatHookTarget *t) -{ - EMFormatInlineAudioPURI *pobj; - gint len; - - len = t->part_id->len; - g_string_append (t->part_id, ".org-gnome-audio-inline-button-panel"); - - d(printf ("audio inline formatter: format classid %s\n", t->part_id->str)); - - pobj = (EMFormatInlineAudioPURI *) em_format_puri_new ( - t->format, sizeof (EMFormatInlineAudioPURI), - t->part, t->part_id->str); - pobj->puri.widget_func = org_gnome_audio_inline_button_panel; - pobj->puri.write_func = write_button_panel; - pobj->puri.part = g_object_ref (t->part); - pobj->puri.is_attachment = TRUE; - pobj->filename = NULL; - pobj->playbin = NULL; - pobj->play_button = NULL; - pobj->stop_button = NULL; - pobj->pause_button = NULL; - pobj->bus_id = 0; - pobj->puri.free = org_gnome_audio_inline_pobject_free; - pobj->target_state = GST_STATE_NULL; - - em_format_add_puri (t->format, (EMFormatPURI *) pobj); - - g_string_truncate (t->part_id, len); -} diff --git a/plugins/audio-inline/org-gnome-audio-inline.eplug.xml b/plugins/audio-inline/org-gnome-audio-inline.eplug.xml deleted file mode 100644 index 06903e796f..0000000000 --- a/plugins/audio-inline/org-gnome-audio-inline.eplug.xml +++ /dev/null @@ -1,100 +0,0 @@ -<?xml version="1.0"?> -<e-plugin-list> - <e-plugin - type="shlib" - id="org.gnome.evolution.plugin.audioInline" - location="@PLUGINDIR@/liborg-gnome-audio-inline@SOEXT@" - _name="Inline Audio" - system_plugin="true"> - - <author name="Radek DoulĂk" email="rodo@novell.com"/> - <_description> - Play audio attachments directly in mail messages. - </_description> - - <hook class="org.gnome.evolution.mail.format:1.0"> - <group id="EMFormatHTMLDisplay"> - <item - mime_type="audio/ac3" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/x-ac3" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/basic" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/mpeg" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/x-mpeg" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/mpeg3" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/x-mpeg3" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/mp3" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/x-mp3" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/mp4" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/flac" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/x-flac" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/mod" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/x-mod" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/x-wav" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/microsoft-wav" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/x-wma" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="audio/x-ms-wma" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item - mime_type="application/ogg" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - <item mime_type="application/x-ogg" - format="org_gnome_audio_inline_format" - flags="inline_disposition"/> - </group> - </hook> - - </e-plugin> -</e-plugin-list> diff --git a/plugins/itip-formatter/Makefile.am b/plugins/itip-formatter/Makefile.am deleted file mode 100644 index af8f6c8668..0000000000 --- a/plugins/itip-formatter/Makefile.am +++ /dev/null @@ -1,56 +0,0 @@ -NULL = - -@EVO_PLUGIN_RULE@ - -plugin_DATA = org-gnome-itip-formatter.eplug -plugin_LTLIBRARIES = liborg-gnome-itip-formatter.la - -liborg_gnome_itip_formatter_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(NULL) - -liborg_gnome_itip_formatter_la_SOURCES = \ - e-conflict-search-selector.c \ - e-conflict-search-selector.h \ - e-source-conflict-search.c \ - e-source-conflict-search.h \ - itip-formatter.c \ - itip-view.c \ - itip-view.h \ - $(NULL) - -liborg_gnome_itip_formatter_la_LDFLAGS = \ - -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_itip_formatter_la_LIBADD = \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/calendar/gui/libevolution-calendar.la \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/shell/libeshell.la \ - $(top_builddir)/em-format/libemformat.la \ - $(top_builddir)/widgets/misc/libemiscwidgets.la \ - $(top_builddir)/libemail-utils/libemail-utils.la \ - $(top_builddir)/libemail-engine/libemail-engine.la \ - $(top_builddir)/libevolution-utils/libevolution-utils.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(NULL) - -error_DATA = org-gnome-itip-formatter.error -errordir = $(privdatadir)/errors - -BUILT_SOURCES = $(plugin_DATA) $(error_DATA) - -CLEANFILES = $(BUILT_SOURCES) - -EXTRA_DIST = \ - org-gnome-itip-formatter.eplug.xml \ - org-gnome-itip-formatter.error.xml \ - $(NULL) - --include $(top_srcdir)/git.mk diff --git a/plugins/itip-formatter/e-conflict-search-selector.c b/plugins/itip-formatter/e-conflict-search-selector.c deleted file mode 100644 index 8f497f5d4f..0000000000 --- a/plugins/itip-formatter/e-conflict-search-selector.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * e-conflict-search-selector.c - * - * 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/> - * - */ - -#include "e-conflict-search-selector.h" - -#include "e-source-conflict-search.h" - -/* This forces the GType to be registered in a way that - * avoids a "statement with no effect" compiler warning. */ -#define REGISTER_TYPE(type) \ - (g_type_class_unref (g_type_class_ref (type))) - -G_DEFINE_TYPE ( - EConflictSearchSelector, - e_conflict_search_selector, - E_TYPE_SOURCE_SELECTOR) - -static gboolean -conflict_search_selector_get_source_selected (ESourceSelector *selector, - ESource *source) -{ - ESourceConflictSearch *extension; - const gchar *extension_name; - - /* Make sure this source is a calendar. */ - extension_name = e_source_selector_get_extension_name (selector); - if (!e_source_has_extension (source, extension_name)) - return FALSE; - - extension_name = E_SOURCE_EXTENSION_CONFLICT_SEARCH; - extension = e_source_get_extension (source, extension_name); - g_return_val_if_fail (E_IS_SOURCE_CONFLICT_SEARCH (extension), FALSE); - - return e_source_conflict_search_get_include_me (extension); -} - -static void -conflict_search_selector_set_source_selected (ESourceSelector *selector, - ESource *source, - gboolean selected) -{ - ESourceConflictSearch *extension; - const gchar *extension_name; - - /* Make sure this source is a calendar. */ - extension_name = e_source_selector_get_extension_name (selector); - if (!e_source_has_extension (source, extension_name)) - return; - - extension_name = E_SOURCE_EXTENSION_CONFLICT_SEARCH; - extension = e_source_get_extension (source, extension_name); - g_return_if_fail (E_IS_SOURCE_CONFLICT_SEARCH (extension)); - - if (selected != e_source_conflict_search_get_include_me (extension)) { - e_source_conflict_search_set_include_me (extension, selected); - e_source_selector_queue_write (selector, source); - } -} - -static void -e_conflict_search_selector_class_init (EConflictSearchSelectorClass *class) -{ - ESourceSelectorClass *source_selector_class; - - source_selector_class = E_SOURCE_SELECTOR_CLASS (class); - source_selector_class->get_source_selected = - conflict_search_selector_get_source_selected; - source_selector_class->set_source_selected = - conflict_search_selector_set_source_selected; - - REGISTER_TYPE (E_TYPE_SOURCE_CONFLICT_SEARCH); -} - -static void -e_conflict_search_selector_init (EConflictSearchSelector *selector) -{ -} - -GtkWidget * -e_conflict_search_selector_new (ESourceRegistry *registry) -{ - g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - - return g_object_new ( - E_TYPE_CONFLICT_SEARCH_SELECTOR, - "extension-name", E_SOURCE_EXTENSION_CALENDAR, - "registry", registry, NULL); -} diff --git a/plugins/itip-formatter/e-conflict-search-selector.h b/plugins/itip-formatter/e-conflict-search-selector.h deleted file mode 100644 index 091e1c9328..0000000000 --- a/plugins/itip-formatter/e-conflict-search-selector.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * e-conflict-search-selector.h - * - * 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/> - * - */ - -#ifndef E_CONFLICT_SEARCH_SELECTOR_H -#define E_CONFLICT_SEARCH_SELECTOR_H - -#include <libedataserverui/libedataserverui.h> - -/* Standard GObject macros */ -#define E_TYPE_CONFLICT_SEARCH_SELECTOR \ - (e_conflict_search_selector_get_type ()) -#define E_CONFLICT_SEARCH_SELECTOR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CONFLICT_SEARCH_SELECTOR, EConflictSearchSelector)) -#define E_CONFLICT_SEARCH_SELECTOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CONFLICT_SEARCH_SELECTOR, EConflictSearchSelectorClass)) -#define E_IS_CONFLICT_SEARCH_SELECTOR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CONFLICT_SEARCH_SELECTOR)) -#define E_IS_CONFLICT_SEARCH_SELECTOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CONFLICT_SEARCH_SELECTOR)) -#define E_CONFLICT_SEARCH_SELECTOR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CONFLICT_SEARCH_SELECTOR, EConflictSearchSelectorClass)) - -G_BEGIN_DECLS - -typedef struct _EConflictSearchSelector EConflictSearchSelector; -typedef struct _EConflictSearchSelectorClass EConflictSearchSelectorClass; -typedef struct _EConflictSearchSelectorPrivate EConflictSearchSelectorPrivate; - -struct _EConflictSearchSelector { - ESourceSelector parent; - EConflictSearchSelectorPrivate *priv; -}; - -struct _EConflictSearchSelectorClass { - ESourceSelectorClass parent_class; -}; - -GType e_conflict_search_selector_get_type - (void) G_GNUC_CONST; -GtkWidget * e_conflict_search_selector_new (ESourceRegistry *registry); - -G_END_DECLS - -#endif /* E_CONFLICT_SEARCH_SELECTOR_H */ diff --git a/plugins/itip-formatter/e-source-conflict-search.c b/plugins/itip-formatter/e-source-conflict-search.c deleted file mode 100644 index c2f5eb6e99..0000000000 --- a/plugins/itip-formatter/e-source-conflict-search.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * e-source-conflict-search.c - * - * 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/> - * - */ - -#include "e-source-conflict-search.h" - -#define E_SOURCE_CONFLICT_SEARCH_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_SOURCE_CONFLICT_SEARCH, ESourceConflictSearchPrivate)) - -struct _ESourceConflictSearchPrivate { - gboolean include_me; -}; - -enum { - PROP_0, - PROP_INCLUDE_ME -}; - -G_DEFINE_TYPE ( - ESourceConflictSearch, - e_source_conflict_search, - E_TYPE_SOURCE_EXTENSION) - -static void -source_conflict_search_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_INCLUDE_ME: - e_source_conflict_search_set_include_me ( - E_SOURCE_CONFLICT_SEARCH (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -source_conflict_search_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_INCLUDE_ME: - g_value_set_boolean ( - value, - e_source_conflict_search_get_include_me ( - E_SOURCE_CONFLICT_SEARCH (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -e_source_conflict_search_class_init (ESourceConflictSearchClass *class) -{ - GObjectClass *object_class; - ESourceExtensionClass *extension_class; - - g_type_class_add_private (class, sizeof (ESourceConflictSearchPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = source_conflict_search_set_property; - object_class->get_property = source_conflict_search_get_property; - - extension_class = E_SOURCE_EXTENSION_CLASS (class); - extension_class->name = E_SOURCE_EXTENSION_CONFLICT_SEARCH; - - g_object_class_install_property ( - object_class, - PROP_INCLUDE_ME, - g_param_spec_boolean ( - "include-me", - "IncludeMe", - "Include this calendar in when " - "searching for scheduling conflicts", - TRUE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS | - E_SOURCE_PARAM_SETTING)); -} - -static void -e_source_conflict_search_init (ESourceConflictSearch *extension) -{ - extension->priv = E_SOURCE_CONFLICT_SEARCH_GET_PRIVATE (extension); -} - -/** - * e_source_conflict_search_get_include_me: - * @extension: an #ESourceConflictSearch - * - * Returns whether the calendar described by the #ESource to which - * @extension belongs should be queried for scheduling conflicts when - * negotiating a meeting invitation. - * - * Returns: whether to search for scheduling conflicts - * - * Since: 3.6 - **/ -gboolean -e_source_conflict_search_get_include_me (ESourceConflictSearch *extension) -{ - g_return_val_if_fail (E_IS_SOURCE_CONFLICT_SEARCH (extension), FALSE); - - return extension->priv->include_me; -} - -/** - * e_source_conflict_search_set_include_me: - * @extension: an #ESourceConflictSearch - * @include_me: whether to search for scheduling conflicts - * - * Sets whether the calendar described by the #ESource to which @extension - * belongs should be queried for scheduling conflicts when negotiating a - * meeting invitation. - * - * Since: 3.6 - **/ -void -e_source_conflict_search_set_include_me (ESourceConflictSearch *extension, - gboolean include_me) -{ - g_return_if_fail (E_IS_SOURCE_CONFLICT_SEARCH (extension)); - - extension->priv->include_me = include_me; - - g_object_notify (G_OBJECT (extension), "include-me"); -} - diff --git a/plugins/itip-formatter/e-source-conflict-search.h b/plugins/itip-formatter/e-source-conflict-search.h deleted file mode 100644 index f91fcc4d43..0000000000 --- a/plugins/itip-formatter/e-source-conflict-search.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * e-source-conflict-search.h - * - * 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/> - * - */ - -#ifndef E_SOURCE_CONFLICT_SEARCH_H -#define E_SOURCE_CONFLICT_SEARCH_H - -#include <libedataserver/libedataserver.h> - -/* Standard GObject macros */ -#define E_TYPE_SOURCE_CONFLICT_SEARCH \ - (e_source_conflict_search_get_type ()) -#define E_SOURCE_CONFLICT_SEARCH(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_SOURCE_CONFLICT_SEARCH, ESourceConflictSearch)) -#define E_SOURCE_CONFLICT_SEARCH_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_SOURCE_CONFLICT_SEARCH, ESourceConflictSearchClass)) -#define E_IS_SOURCE_CONFLICT_SEARCH(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_SOURCE_CONFLICT_SEARCH)) -#define E_IS_SOURCE_CONFLICT_SEARCH_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_SOURCE_CONFLICT_SEARCH)) -#define E_SOURCE_CONFLICT_SEARCH_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_SOURCE_CONFLICT_SEARCH, ESourceConflictSearchClass)) - -/** - * E_SOURCE_EXTENSION_CONFLICT_SEARCH: - * - * Pass this extension name to e_source_get_extension() to access - * #ESourceConflictSearch. This is also used as a group name in key files. - * - * Since: 3.6 - **/ -#define E_SOURCE_EXTENSION_CONFLICT_SEARCH "Conflict Search" - -G_BEGIN_DECLS - -typedef struct _ESourceConflictSearch ESourceConflictSearch; -typedef struct _ESourceConflictSearchClass ESourceConflictSearchClass; -typedef struct _ESourceConflictSearchPrivate ESourceConflictSearchPrivate; - -/** - * ESourceConflictSearch: - * - * Contains only private data that should be read and manipulated using the - * functions below. - * - * Since: 3.6 - **/ -struct _ESourceConflictSearch { - ESourceExtension parent; - ESourceConflictSearchPrivate *priv; -}; - -struct _ESourceConflictSearchClass { - ESourceExtensionClass parent_class; -}; - -GType e_source_conflict_search_get_type - (void) G_GNUC_CONST; -gboolean e_source_conflict_search_get_include_me - (ESourceConflictSearch *extension); -void e_source_conflict_search_set_include_me - (ESourceConflictSearch *extension, - gboolean include_me); - -G_END_DECLS - -#endif /* E_SOURCE_CONFLICT_SEARCH_H */ diff --git a/plugins/itip-formatter/itip-formatter.c b/plugins/itip-formatter/itip-formatter.c deleted file mode 100644 index 6780d09505..0000000000 --- a/plugins/itip-formatter/itip-formatter.c +++ /dev/null @@ -1,3505 +0,0 @@ -/* - * 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: - * JP Rosevear <jpr@novell.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <gtk/gtk.h> -#include <glib/gi18n.h> - -#include <libecal/libecal.h> -#include <libedataserverui/libedataserverui.h> - -#include <libevolution-utils/e-alert-dialog.h> -#include <e-util/e-mktemp.h> - -#include <shell/e-shell.h> -#include <shell/e-shell-utils.h> - -#include <libemail-utils/mail-mt.h> - -#include <libemail-engine/mail-folder-cache.h> -#include <libemail-engine/mail-tools.h> - -#include <mail/em-format-hook.h> -#include <mail/em-config.h> -#include <mail/em-format-html.h> -#include <mail/em-utils.h> - -#include <misc/e-attachment.h> - -#include <calendar/gui/itip-utils.h> - -#include "e-conflict-search-selector.h" -#include "e-source-conflict-search.h" -#include "itip-view.h" - -#define CONF_KEY_DELETE "delete-processed" - -#define d(x) - -struct _ItipPURI { - EMFormatPURI puri; - - const EMFormatHandler *handle; - CamelFolder *folder; - CamelMimeMessage *msg; - CamelMimePart *part; - - gchar *uid; - - ESourceRegistry *registry; - GHashTable *clients[E_CAL_CLIENT_SOURCE_TYPE_LAST]; - - ECalClient *current_client; - ECalClientSourceType type; - - /* cancelled when freeing the puri */ - GCancellable *cancellable; - - gchar *vcalendar; - ECalComponent *comp; - icalcomponent *main_comp; - icalcomponent *ical_comp; - icalcomponent *top_level; - icalcompiter iter; - icalproperty_method method; - time_t start_time; - time_t end_time; - - gint current; - gint total; - - gchar *calendar_uid; - - gchar *from_address; - gchar *from_name; - gchar *to_address; - gchar *to_name; - gchar *delegator_address; - gchar *delegator_name; - gchar *my_address; - gint view_only; - - guint progress_info_id; - - gboolean delete_message; - /* a reply can only be sent if and only if there is an organizer */ - gboolean has_organizer; - /* - * Usually replies are sent unless the user unchecks that option. - * There are some cases when the default is not to sent a reply - * (but the user can still chose to do so by checking the option): - * - the organizer explicitly set RSVP=FALSE for the current user - * - the event has no ATTENDEEs: that's the case for most non-meeting - * events - * - * The last case is meant for forwarded non-meeting - * events. Traditionally Evolution hasn't offered to send a - * reply, therefore the updated implementation mimics that - * behavior. - * - * Unfortunately some software apparently strips all ATTENDEEs - * when forwarding a meeting; in that case sending a reply is - * also unchecked by default. So the check for ATTENDEEs is a - * tradeoff between sending unwanted replies in cases where - * that wasn't done in the past and not sending a possibly - * wanted reply where that wasn't possible in the past - * (because replies to forwarded events were not - * supported). Overall that should be an improvement, and the - * user can always override the default. - */ - gboolean no_reply_wanted; - - guint update_item_progress_info_id; - guint update_item_error_info_id; - ItipViewResponse update_item_response; - gboolean can_delete_invitation_from_cache; - GHashTable *real_comps; /* ESource's UID -> ECalComponent stored on the server */ -}; - -void format_itip (EPlugin *ep, EMFormatHookTarget *target); -GtkWidget *itip_formatter_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data); -gint e_plugin_lib_enable (EPlugin *ep, gint enable); - -typedef struct { - ItipPURI *puri; - ItipView *view; - GCancellable *cancellable; - gboolean keep_alarm_check; - GHashTable *conflicts; - - gchar *uid; - gchar *rid; - - gchar *sexp; - - gint count; -} FormatItipFindData; - -static gboolean check_is_instance (icalcomponent *icalcomp); - -gint -e_plugin_lib_enable (EPlugin *ep, - gint enable) -{ - return 0; -} - -static icalproperty * -find_attendee (icalcomponent *ical_comp, - const gchar *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)) { - gchar *attendee; - gchar *text; - - attendee = icalproperty_get_value_as_string_r (prop); - - if (!attendee) - continue; - - text = g_strdup (itip_strip_mailto (attendee)); - text = g_strstrip (text); - if (text && !g_ascii_strcasecmp (address, text)) { - g_free (text); - g_free (attendee); - break; - } - g_free (text); - g_free (attendee); - } - - return prop; -} - -static icalproperty * -find_attendee_if_sentby (icalcomponent *ical_comp, - const gchar *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)) { - icalparameter *param; - const gchar *attendee_sentby; - gchar *text; - - param = icalproperty_get_first_parameter (prop, ICAL_SENTBY_PARAMETER); - if (!param) - continue; - - attendee_sentby = icalparameter_get_sentby (param); - - if (!attendee_sentby) - continue; - - text = g_strdup (itip_strip_mailto (attendee_sentby)); - text = g_strstrip (text); - if (text && !g_ascii_strcasecmp (address, text)) { - g_free (text); - break; - } - g_free (text); - } - - return prop; -} - -static void -find_to_address (ItipPURI *pitip, - icalcomponent *ical_comp, - icalparameter_partstat *status) -{ - ESourceRegistry *registry; - ESourceMailIdentity *extension; - GList *list, *link; - const gchar *extension_name; - - registry = pitip->registry; - extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY; - - if (pitip->to_address != NULL) - return; - - if (pitip->msg != NULL && pitip->folder != NULL) { - ESource *source; - - source = em_utils_guess_mail_identity ( - registry, pitip->msg, pitip->folder); - - if (source != NULL) { - extension = e_source_get_extension (source, extension_name); - - pitip->to_address = e_source_mail_identity_dup_address (extension); - - g_object_unref (source); - } - } - - if (pitip->to_address != NULL) - return; - - /* Look through the list of attendees to find the user's address */ - - list = e_source_registry_list_sources (registry, extension_name); - - for (link = list; link != NULL; link = g_list_next (link)) { - ESource *source = E_SOURCE (link->data); - icalproperty *prop = NULL; - icalparameter *param; - const gchar *address; - gchar *text; - - if (!e_source_get_enabled (source)) - continue; - - extension = e_source_get_extension (source, extension_name); - address = e_source_mail_identity_get_address (extension); - - prop = find_attendee (ical_comp, address); - if (prop == NULL) - continue; - - param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER); - if (param != NULL) - pitip->to_name = g_strdup (icalparameter_get_cn (param)); - - text = icalproperty_get_value_as_string_r (prop); - - pitip->to_address = g_strdup (itip_strip_mailto (text)); - g_free (text); - g_strstrip (pitip->to_address); - - pitip->my_address = g_strdup (address); - - param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER); - if (param != NULL && - icalparameter_get_rsvp (param) == ICAL_RSVP_FALSE) - pitip->no_reply_wanted = TRUE; - - if (status) { - param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER); - *status = param ? icalparameter_get_partstat (param) : ICAL_PARTSTAT_NEEDSACTION; - } - - break; - } - - g_list_free_full (list, (GDestroyNotify) g_object_unref); - - if (pitip->to_address != NULL) - return; - - /* If the user's address was not found in the attendee's list, - * then the user might be responding on behalf of his/her delegator. - * In this case, we would want to go through the SENT-BY fields of - * the attendees to find the user's address. - * - * Note: This functionality could have been (easily) implemented - * in the previous loop, but it would hurt the performance for all - * providers in general. Hence, we choose to iterate through the - * accounts list again. - */ - - list = e_source_registry_list_sources (registry, extension_name); - - for (link = list; link != NULL; link = g_list_next (link)) { - ESource *source = E_SOURCE (link->data); - icalproperty *prop = NULL; - icalparameter *param; - const gchar *address; - gchar *text; - - - if (!e_source_get_enabled (source)) - continue; - - extension = e_source_get_extension (source, extension_name); - address = e_source_mail_identity_get_address (extension); - - prop = find_attendee_if_sentby (ical_comp, address); - if (prop == NULL) - continue; - - param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER); - if (param != NULL) - pitip->to_name = g_strdup (icalparameter_get_cn (param)); - - text = icalproperty_get_value_as_string_r (prop); - - pitip->to_address = g_strdup (itip_strip_mailto (text)); - g_free (text); - g_strstrip (pitip->to_address); - - pitip->my_address = g_strdup (address); - - param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER); - if (param != NULL && - ICAL_RSVP_FALSE == icalparameter_get_rsvp (param)) - pitip->no_reply_wanted = TRUE; - - if (status) { - param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER); - *status = param ? icalparameter_get_partstat (param) : ICAL_PARTSTAT_NEEDSACTION; - } - - break; - } - - g_list_free_full (list, (GDestroyNotify) g_object_unref); -} - -static void -find_from_address (ItipPURI *pitip, - icalcomponent *ical_comp) -{ - GList *list, *link; - icalproperty *prop; - gchar *organizer; - icalparameter *param; - const gchar *extension_name; - const gchar *organizer_sentby; - gchar *organizer_clean = NULL; - gchar *organizer_sentby_clean = NULL; - - prop = icalcomponent_get_first_property (ical_comp, ICAL_ORGANIZER_PROPERTY); - - if (!prop) - return; - - organizer = icalproperty_get_value_as_string_r (prop); - if (organizer) { - organizer_clean = g_strdup (itip_strip_mailto (organizer)); - organizer_clean = g_strstrip (organizer_clean); - g_free (organizer); - } - - param = icalproperty_get_first_parameter (prop, ICAL_SENTBY_PARAMETER); - if (param) { - organizer_sentby = icalparameter_get_sentby (param); - if (organizer_sentby) { - organizer_sentby_clean = g_strdup (itip_strip_mailto (organizer_sentby)); - organizer_sentby_clean = g_strstrip (organizer_sentby_clean); - } - } - - if (!(organizer_sentby_clean || organizer_clean)) - return; - - pitip->from_address = g_strdup (organizer_clean); - - param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER); - if (param) - pitip->from_name = g_strdup (icalparameter_get_cn (param)); - - extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY; - list = e_source_registry_list_sources (pitip->registry, extension_name); - - for (link = list; link != NULL; link = g_list_next (link)) { - ESource *source = E_SOURCE (link->data); - ESourceMailIdentity *extension; - const gchar *address; - - if (!e_source_get_enabled (source)) - continue; - - extension = e_source_get_extension (source, extension_name); - address = e_source_mail_identity_get_address (extension); - - if (address == NULL) - continue; - - if ((organizer_clean && !g_ascii_strcasecmp (organizer_clean, address)) - || (organizer_sentby_clean && !g_ascii_strcasecmp (organizer_sentby_clean, address))) { - pitip->my_address = g_strdup (address); - - break; - } - } - - g_list_free_full (list, (GDestroyNotify) g_object_unref); - - g_free (organizer_sentby_clean); - g_free (organizer_clean); -} - -static ECalComponent * -get_real_item (ItipPURI *pitip) -{ - ECalComponent *comp = NULL; - ESource *source; - - source = e_client_get_source (E_CLIENT (pitip->current_client)); - if (source) - comp = g_hash_table_lookup (pitip->real_comps, e_source_get_uid (source)); - - if (!comp) { - return NULL; - } - - return e_cal_component_clone (comp); -} - -static void -adjust_item (ItipPURI *pitip, - ECalComponent *comp) -{ - ECalComponent *real_comp; - - real_comp = get_real_item (pitip); - if (real_comp != NULL) { - ECalComponentText text; - const gchar *string; - GSList *l; - - e_cal_component_get_summary (real_comp, &text); - e_cal_component_set_summary (comp, &text); - e_cal_component_get_location (real_comp, &string); - e_cal_component_set_location (comp, string); - e_cal_component_get_description_list (real_comp, &l); - e_cal_component_set_description_list (comp, l); - e_cal_component_free_text_list (l); - - g_object_unref (real_comp); - } else { - ECalComponentText text = {_("Unknown"), NULL}; - - e_cal_component_set_summary (comp, &text); - } -} - -static void -set_buttons_sensitive (ItipPURI *pitip, - ItipView *view) -{ - gboolean read_only = TRUE; - - if (pitip->current_client) - read_only = e_client_is_readonly (E_CLIENT (pitip->current_client)); - - itip_view_set_buttons_sensitive (view, pitip->current_client != NULL && !read_only); -} - -static void -add_failed_to_load_msg (ItipView *view, - ESource *source, - const GError *error) -{ - gchar *msg; - - g_return_if_fail (view != NULL); - g_return_if_fail (source != NULL); - g_return_if_fail (error != NULL); - - /* Translators: The first '%s' is replaced with a calendar name, - * the second '%s' with an error message */ - msg = g_strdup_printf (_("Failed to load the calendar '%s' (%s)"), e_source_get_display_name (source), error->message); - - itip_view_add_lower_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING, msg); - - g_free (msg); -} - -static void -cal_opened_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - ESource *source = E_SOURCE (source_object); - ItipView *view = user_data; - ItipPURI *pitip = itip_view_get_puri (view); - ECalClientSourceType source_type; - EClient *client = NULL; - ECalClient *cal_client; - const gchar *uid; - GError *error = NULL; - - e_client_utils_open_new_finish (source, result, &client, &error); - - /* Ignore cancellations. */ - if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || - g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_warn_if_fail (client == NULL); - g_error_free (error); - return; - - } else if (error != NULL) { - g_warn_if_fail (client == NULL); - add_failed_to_load_msg (view, source, error); - g_error_free (error); - return; - } - - g_return_if_fail (E_IS_CAL_CLIENT (client)); - - cal_client = E_CAL_CLIENT (client); - g_return_if_fail (cal_client != NULL); - - uid = e_source_get_uid (source); - source_type = e_cal_client_get_source_type (cal_client); - g_hash_table_insert ( - pitip->clients[source_type], g_strdup (uid), cal_client); - - if (e_cal_client_check_recurrences_no_master (cal_client)) { - icalcomponent *icalcomp; - gboolean show_recur_check; - - icalcomp = e_cal_component_get_icalcomponent (pitip->comp); - - show_recur_check = check_is_instance (icalcomp); - itip_view_set_show_recur_check (view, show_recur_check); - } - - if (pitip->type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS) { - gboolean needs_decline; - - needs_decline = e_client_check_capability ( - E_CLIENT (client), - CAL_STATIC_CAPABILITY_HAS_UNACCEPTED_MEETING); - itip_view_set_needs_decline (view, needs_decline); - itip_view_set_mode (view, ITIP_VIEW_MODE_PUBLISH); - } - - pitip->current_client = cal_client; - - set_buttons_sensitive (pitip, view); -} - -static void -start_calendar_server (ItipPURI *pitip, - ItipView *view, - ESource *source, - ECalClientSourceType type, - GAsyncReadyCallback func, - gpointer data) -{ - ECalClient *client; - - g_return_if_fail (source != NULL); - - client = g_hash_table_lookup (pitip->clients[type], e_source_get_uid (source)); - if (client) { - pitip->current_client = client; - - itip_view_remove_lower_info_item (view, pitip->progress_info_id); - pitip->progress_info_id = 0; - - set_buttons_sensitive (pitip, view); - - return; - } - - e_client_utils_open_new (source, - type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS ? E_CLIENT_SOURCE_TYPE_EVENTS : - type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS ? E_CLIENT_SOURCE_TYPE_MEMOS : - type == E_CAL_CLIENT_SOURCE_TYPE_TASKS ? E_CLIENT_SOURCE_TYPE_TASKS : E_CLIENT_SOURCE_TYPE_LAST, - TRUE, pitip->cancellable, - func, data); -} - -static void -start_calendar_server_by_uid (ItipPURI *pitip, - ItipView *view, - const gchar *uid, - ECalClientSourceType type) -{ - ESource *source; - - itip_view_set_buttons_sensitive (view, FALSE); - - source = e_source_registry_ref_source (pitip->registry, uid); - if (source != NULL) { - start_calendar_server ( - pitip, view, source, type, cal_opened_cb, view); - g_object_unref (source); - } -} - -static void -source_selected_cb (ItipView *view, - ESource *source, - gpointer data) -{ - ItipPURI *pitip = data; - - itip_view_set_buttons_sensitive (view, FALSE); - - g_return_if_fail (source != NULL); - - start_calendar_server (pitip, view, source, pitip->type, cal_opened_cb, view); -} - -static void -find_cal_update_ui (FormatItipFindData *fd, - ECalClient *cal_client) -{ - ItipPURI *pitip; - ItipView *view; - ESource *source; - - g_return_if_fail (fd != NULL); - - pitip = fd->puri; - view = fd->view; - - /* UI part gone */ - if (g_cancellable_is_cancelled (fd->cancellable)) - return; - - source = cal_client ? e_client_get_source (E_CLIENT (cal_client)) : NULL; - - if (cal_client && g_hash_table_lookup (fd->conflicts, cal_client)) { - itip_view_add_upper_info_item_printf (view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING, - _("An appointment in the calendar '%s' conflicts with this meeting"), e_source_get_display_name (source)); - } - - /* search for a master object if the detached object doesn't exist in the calendar */ - if (pitip->current_client && pitip->current_client == cal_client) { - itip_view_set_show_keep_alarm_check (view, fd->keep_alarm_check); - - pitip->current_client = cal_client; - - /* Provide extra info, since its not in the component */ - /* FIXME Check sequence number of meeting? */ - /* FIXME Do we need to adjust elsewhere for the delegated calendar item? */ - /* FIXME Need to update the fields in the view now */ - if (pitip->method == ICAL_METHOD_REPLY || pitip->method == ICAL_METHOD_REFRESH) - adjust_item (pitip, pitip->comp); - - /* We clear everything because we don't really care - * about any other info/warnings now we found an - * existing versions */ - itip_view_clear_lower_info_items (view); - pitip->progress_info_id = 0; - - /* FIXME Check read only state of calendar? */ - itip_view_add_lower_info_item_printf (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Found the appointment in the calendar '%s'"), e_source_get_display_name (source)); - - set_buttons_sensitive (pitip, view); - } else if (!pitip->current_client) - itip_view_set_show_keep_alarm_check (view, FALSE); - - if (pitip->current_client && pitip->current_client == cal_client) { - if (e_cal_client_check_recurrences_no_master (pitip->current_client)) { - icalcomponent *icalcomp = e_cal_component_get_icalcomponent (pitip->comp); - - if (check_is_instance (icalcomp)) - itip_view_set_show_recur_check (view, TRUE); - else - itip_view_set_show_recur_check (view, FALSE); - } - - if (pitip->type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS) { - /* TODO The static capability should be made generic to convey that the calendar contains unaccepted items */ - if (e_client_check_capability (E_CLIENT (pitip->current_client), CAL_STATIC_CAPABILITY_HAS_UNACCEPTED_MEETING)) - itip_view_set_needs_decline (view, TRUE); - else - itip_view_set_needs_decline (view, FALSE); - - itip_view_set_mode (view, ITIP_VIEW_MODE_PUBLISH); - } - } -} - -static void -decrease_find_data (FormatItipFindData *fd) -{ - g_return_if_fail (fd != NULL); - - fd->count--; - d(printf ("Decreasing itip formatter search count to %d\n", fd->count)); - - if (fd->count == 0 && !g_cancellable_is_cancelled (fd->cancellable)) { - gboolean rsvp_enabled = FALSE; - ItipPURI *pitip = fd->puri; - ItipView *view = fd->view; - - itip_view_remove_lower_info_item (view, pitip->progress_info_id); - pitip->progress_info_id = 0; - - /* - * Only allow replies if backend doesn't do that automatically. - * * Only enable it for forwarded invitiations (PUBLISH) or direct - * * invitiations (REQUEST), but not replies (REPLY). - * Replies only make sense for events with an organizer. - */ - if ((!pitip->current_client || !e_cal_client_check_save_schedules (pitip->current_client)) && - (pitip->method == ICAL_METHOD_PUBLISH || pitip->method == ICAL_METHOD_REQUEST) && - pitip->has_organizer) { - rsvp_enabled = TRUE; - } - itip_view_set_show_rsvp_check (view, rsvp_enabled); - - /* default is chosen in extract_itip_data() based on content of the VEVENT */ - itip_view_set_rsvp (view, !pitip->no_reply_wanted); - - if ((pitip->method == ICAL_METHOD_PUBLISH || pitip->method == ICAL_METHOD_REQUEST) - && !pitip->current_client) { - /* Reuse already declared one or rename? */ - ESource *source = NULL; - const gchar *extension_name; - - switch (pitip->type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - extension_name = E_SOURCE_EXTENSION_CALENDAR; - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - extension_name = E_SOURCE_EXTENSION_TASK_LIST; - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - extension_name = E_SOURCE_EXTENSION_MEMO_LIST; - break; - default: - g_return_if_reached (); - } - - source = e_source_registry_ref_default_for_extension_name ( - pitip->registry, extension_name); - - itip_view_set_extension_name (view, extension_name); - - g_signal_connect ( - view, "source_selected", - G_CALLBACK (source_selected_cb), pitip); - - if (source != NULL) { - itip_view_set_source (view, source); - g_object_unref (source); - - /* FIXME Shouldn't the buttons be sensitized here? */ - } else { - itip_view_add_lower_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to find any calendars")); - itip_view_set_buttons_sensitive (view, FALSE); - } - } else if (!pitip->current_client) { - switch (pitip->type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - itip_view_add_lower_info_item_printf ( - view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING, - _("Unable to find this meeting in any calendar")); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - itip_view_add_lower_info_item_printf ( - view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING, - _("Unable to find this task in any task list")); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - itip_view_add_lower_info_item_printf ( - view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING, - _("Unable to find this memo in any memo list")); - break; - default: - g_assert_not_reached (); - break; - } - } - } - - if (fd->count == 0) { - g_hash_table_destroy (fd->conflicts); - g_object_unref (fd->cancellable); - g_free (fd->uid); - g_free (fd->rid); - if (fd->sexp) - g_free (fd->sexp); - g_free (fd); - } -} - -static void -get_object_without_rid_ready_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - ECalClient *cal_client = E_CAL_CLIENT (source_object); - FormatItipFindData *fd = user_data; - icalcomponent *icalcomp = NULL; - GError *error = NULL; - - if (!e_cal_client_get_object_finish (cal_client, result, &icalcomp, &error)) - icalcomp = NULL; - - if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || - g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || - g_cancellable_is_cancelled (fd->cancellable)) { - g_clear_error (&error); - find_cal_update_ui (fd, cal_client); - decrease_find_data (fd); - return; - } - - g_clear_error (&error); - - if (icalcomp) { - ECalComponent *comp; - - fd->puri->current_client = cal_client; - fd->keep_alarm_check = (fd->puri->method == ICAL_METHOD_PUBLISH || fd->puri->method == ICAL_METHOD_REQUEST) && - (icalcomponent_get_first_component (icalcomp, ICAL_VALARM_COMPONENT) || - icalcomponent_get_first_component (icalcomp, ICAL_XAUDIOALARM_COMPONENT) || - icalcomponent_get_first_component (icalcomp, ICAL_XDISPLAYALARM_COMPONENT) || - icalcomponent_get_first_component (icalcomp, ICAL_XPROCEDUREALARM_COMPONENT) || - icalcomponent_get_first_component (icalcomp, ICAL_XEMAILALARM_COMPONENT)); - - comp = e_cal_component_new_from_icalcomponent (icalcomp); - if (comp) { - ESource *source = e_client_get_source (E_CLIENT (cal_client)); - - g_hash_table_insert (fd->puri->real_comps, g_strdup (e_source_get_uid (source)), comp); - } - - find_cal_update_ui (fd, cal_client); - decrease_find_data (fd); - return; - } - - find_cal_update_ui (fd, cal_client); - decrease_find_data (fd); -} - -static void -get_object_with_rid_ready_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - ECalClient *cal_client = E_CAL_CLIENT (source_object); - FormatItipFindData *fd = user_data; - icalcomponent *icalcomp = NULL; - GError *error = NULL; - - if (!e_cal_client_get_object_finish (cal_client, result, &icalcomp, &error)) - icalcomp = NULL; - - if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || - g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || - g_cancellable_is_cancelled (fd->cancellable)) { - g_clear_error (&error); - find_cal_update_ui (fd, cal_client); - decrease_find_data (fd); - return; - } - - g_clear_error (&error); - - if (icalcomp) { - ECalComponent *comp; - - fd->puri->current_client = cal_client; - fd->keep_alarm_check = (fd->puri->method == ICAL_METHOD_PUBLISH || fd->puri->method == ICAL_METHOD_REQUEST) && - (icalcomponent_get_first_component (icalcomp, ICAL_VALARM_COMPONENT) || - icalcomponent_get_first_component (icalcomp, ICAL_XAUDIOALARM_COMPONENT) || - icalcomponent_get_first_component (icalcomp, ICAL_XDISPLAYALARM_COMPONENT) || - icalcomponent_get_first_component (icalcomp, ICAL_XPROCEDUREALARM_COMPONENT) || - icalcomponent_get_first_component (icalcomp, ICAL_XEMAILALARM_COMPONENT)); - - comp = e_cal_component_new_from_icalcomponent (icalcomp); - if (comp) { - ESource *source = e_client_get_source (E_CLIENT (cal_client)); - - g_hash_table_insert (fd->puri->real_comps, g_strdup (e_source_get_uid (source)), comp); - } - - find_cal_update_ui (fd, cal_client); - decrease_find_data (fd); - return; - } - - if (fd->rid && *fd->rid) { - e_cal_client_get_object (cal_client, fd->uid, NULL, fd->cancellable, get_object_without_rid_ready_cb, fd); - return; - } - - find_cal_update_ui (fd, cal_client); - decrease_find_data (fd); -} - -static void -get_object_list_ready_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - ECalClient *cal_client = E_CAL_CLIENT (source_object); - FormatItipFindData *fd = user_data; - GSList *objects = NULL; - GError *error = NULL; - - if (!e_cal_client_get_object_list_finish (cal_client, result, &objects, &error)) - objects = NULL; - - if (g_cancellable_is_cancelled (fd->cancellable)) { - g_clear_error (&error); - decrease_find_data (fd); - return; - } - - if (error) { - if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || - g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_error_free (error); - decrease_find_data (fd); - return; - } - - g_error_free (error); - } else { - g_hash_table_insert (fd->conflicts, cal_client, GINT_TO_POINTER (g_slist_length (objects))); - e_cal_client_free_icalcomp_slist (objects); - } - - e_cal_client_get_object (cal_client, fd->uid, fd->rid, fd->cancellable, get_object_with_rid_ready_cb, fd); -} - -static void -find_cal_opened_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - ESource *source = E_SOURCE (source_object); - FormatItipFindData *fd = user_data; - ItipPURI *pitip = fd->puri; - ItipView *view = fd->view; - ECalClientSourceType source_type; - EClient *client = NULL; - ECalClient *cal_client; - gboolean search_for_conflicts = FALSE; - const gchar *extension_name; - const gchar *uid; - GError *error = NULL; - - e_client_utils_open_new_finish (source, result, &client, &error); - - /* Ignore cancellations. */ - if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || - g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_warn_if_fail (client == NULL); - decrease_find_data (fd); - g_error_free (error); - return; - } - - if (g_cancellable_is_cancelled (fd->cancellable)) { - g_clear_error (&error); - decrease_find_data (fd); - return; - } - - if (error) { - /* FIXME Do we really want to warn here? If we fail - * to find the item, this won't be cleared but the - * selector might be shown */ - g_warn_if_fail (client == NULL); - add_failed_to_load_msg (view, source, error); - decrease_find_data (fd); - g_error_free (error); - return; - } - - g_return_if_fail (E_IS_CAL_CLIENT (client)); - - /* Do not process read-only calendars */ - if (e_client_is_readonly (client)) { - g_object_unref (client); - decrease_find_data (fd); - return; - } - - cal_client = E_CAL_CLIENT (client); - source_type = e_cal_client_get_source_type (cal_client); - - uid = e_source_get_uid (source); - g_hash_table_insert ( - pitip->clients[source_type], g_strdup (uid), cal_client); - - extension_name = E_SOURCE_EXTENSION_CONFLICT_SEARCH; - if (e_source_has_extension (source, extension_name)) { - ESourceConflictSearch *extension; - - extension = e_source_get_extension (source, extension_name); - search_for_conflicts = - (pitip->type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS) && - e_source_conflict_search_get_include_me (extension); - } - - /* Check for conflicts */ - /* If the query fails, we'll just ignore it */ - /* FIXME What happens for recurring conflicts? */ - if (search_for_conflicts) { - e_cal_client_get_object_list ( - cal_client, fd->sexp, - fd->cancellable, - get_object_list_ready_cb, fd); - return; - } - - if (!pitip->current_client) { - e_cal_client_get_object ( - cal_client, fd->uid, fd->rid, - fd->cancellable, - get_object_with_rid_ready_cb, fd); - return; - } - - decrease_find_data (fd); -} - -static void -find_server (ItipPURI *pitip, - ItipView *view, - ECalComponent *comp) -{ - FormatItipFindData *fd = NULL; - const gchar *uid; - gchar *rid = NULL; - CamelStore *parent_store; - ESourceRegistry *registry; - ESource *current_source = NULL; - GList *list, *link; - GList *conflict_list = NULL; - const gchar *extension_name; - const gchar *store_uid; - - g_return_if_fail (pitip->folder != NULL); - - switch (pitip->type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - extension_name = E_SOURCE_EXTENSION_CALENDAR; - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - extension_name = E_SOURCE_EXTENSION_TASK_LIST; - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - extension_name = E_SOURCE_EXTENSION_MEMO_LIST; - break; - default: - g_return_if_reached (); - } - - registry = pitip->registry; - list = e_source_registry_list_sources (registry, extension_name); - - e_cal_component_get_uid (comp, &uid); - rid = e_cal_component_get_recurid_as_string (comp); - - /* XXX Not sure what this was trying to do, - * but it propbably doesn't work anymore. - * Some comments would have been helpful. */ - parent_store = camel_folder_get_parent_store (pitip->folder); - store_uid = camel_service_get_uid (CAMEL_SERVICE (parent_store)); - - itip_view_set_buttons_sensitive (view, FALSE); - - for (link = list; link != NULL; link = g_list_next (link)) { - ESource *source = E_SOURCE (link->data); - gboolean search_for_conflicts = FALSE; - const gchar *source_uid; - - extension_name = E_SOURCE_EXTENSION_CONFLICT_SEARCH; - if (e_source_has_extension (source, extension_name)) { - ESourceConflictSearch *extension; - - extension = - e_source_get_extension (source, extension_name); - search_for_conflicts = - e_source_conflict_search_get_include_me (extension); - } - - if (search_for_conflicts) - conflict_list = g_list_prepend ( - conflict_list, g_object_ref (source)); - - if (current_source != NULL) - continue; - - source_uid = e_source_get_uid (source); - if (g_strcmp0 (source_uid, store_uid) == 0) { - current_source = source; - conflict_list = g_list_prepend ( - conflict_list, g_object_ref (source)); - - continue; - } - } - - if (current_source) { - link = conflict_list; - - pitip->progress_info_id = itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS, - _("Opening the calendar. Please wait...")); - } else { - link = list; - pitip->progress_info_id = itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS, - _("Searching for an existing version of this appointment")); - } - - for (; link != NULL; link = g_list_next (link)) { - ESource *source = E_SOURCE (link->data); - - if (!fd) { - gchar *start = NULL, *end = NULL; - - fd = g_new0 (FormatItipFindData, 1); - fd->puri = pitip; - fd->view = view; - fd->cancellable = g_object_ref (pitip->cancellable); - fd->conflicts = g_hash_table_new (g_direct_hash, g_direct_equal); - fd->uid = g_strdup (uid); - fd->rid = rid; - /* avoid free this at the end */ - rid = NULL; - - if (pitip->start_time && pitip->end_time) { - start = isodate_from_time_t (pitip->start_time); - end = isodate_from_time_t (pitip->end_time); - - fd->sexp = g_strdup_printf ("(and (occur-in-time-range? (make-time \"%s\") (make-time \"%s\")) (not (uid? \"%s\")))", - start, end, icalcomponent_get_uid (pitip->ical_comp)); - } - - g_free (start); - g_free (end); - } - fd->count++; - d(printf ("Increasing itip formatter search count to %d\n", fd->count)); - - if (current_source == source) - start_calendar_server ( - pitip, view, source, pitip->type, - find_cal_opened_cb, fd); - else - start_calendar_server ( - pitip, view, source, pitip->type, - find_cal_opened_cb, fd); - } - - g_list_free_full (conflict_list, (GDestroyNotify) g_object_unref); - g_list_free_full (list, (GDestroyNotify) g_object_unref); - - g_free (rid); -} - -static gboolean -change_status (ESourceRegistry *registry, - icalcomponent *ical_comp, - const gchar *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; - - if (address != NULL) { - 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); - } else { - gchar *default_name = NULL; - gchar *default_address = NULL; - - itip_get_default_name_and_address ( - registry, &default_name, &default_address); - - prop = icalproperty_new_attendee (default_address); - icalcomponent_add_property (ical_comp, prop); - - param = icalparameter_new_cn (default_name); - icalproperty_add_parameter (prop, param); - - param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT); - icalproperty_add_parameter (prop, param); - - param = icalparameter_new_partstat (status); - icalproperty_add_parameter (prop, param); - - g_free (default_name); - g_free (default_address); - } - } - - return TRUE; -} - -static void -message_foreach_part (CamelMimePart *part, - GSList **part_list) -{ - CamelDataWrapper *containee; - gint parts, i; - gint go = TRUE; - - if (!part) - return; - - *part_list = g_slist_append (*part_list, part); - - containee = camel_medium_get_content (CAMEL_MEDIUM (part)); - - if (containee == NULL) - return; - - /* using the object types is more accurate than using the mime/types */ - if (CAMEL_IS_MULTIPART (containee)) { - parts = camel_multipart_get_number (CAMEL_MULTIPART (containee)); - for (i = 0; go && i < parts; i++) { - /* Reuse already declared *parts? */ - CamelMimePart *part = camel_multipart_get_part (CAMEL_MULTIPART (containee), i); - - message_foreach_part (part, part_list); - } - } else if (CAMEL_IS_MIME_MESSAGE (containee)) { - message_foreach_part ((CamelMimePart *) containee, part_list); - } -} - -static void -attachment_load_finished (EAttachment *attachment, - GAsyncResult *result, - gpointer user_data) -{ - struct { - GFile *file; - gboolean done; - } *status = user_data; - - /* Should be no need to check for error here. */ - e_attachment_load_finish (attachment, result, NULL); - - status->done = TRUE; -} - -static void -attachment_save_finished (EAttachment *attachment, - GAsyncResult *result, - gpointer user_data) -{ - GError *error = NULL; - - struct { - GFile *file; - gboolean done; - } *status = user_data; - - status->file = e_attachment_save_finish (attachment, result, &error); - status->done = TRUE; - - /* XXX Error handling needs improvement. */ - if (error != NULL) { - g_warning ("%s", error->message); - g_error_free (error); - } -} - -static gchar * -get_uri_for_part (CamelMimePart *mime_part) -{ - EAttachment *attachment; - GFile *temp_directory; - gchar *template; - gchar *path; - - struct { - GFile *file; - gboolean done; - } status; - - /* XXX Error handling leaves much to be desired. */ - - template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ()); - path = e_mkdtemp (template); - g_free (template); - - if (path == NULL) - return NULL; - - temp_directory = g_file_new_for_path (path); - g_free (path); - - attachment = e_attachment_new (); - e_attachment_set_mime_part (attachment, mime_part); - - status.done = FALSE; - - e_attachment_load_async ( - attachment, (GAsyncReadyCallback) - attachment_load_finished, &status); - - /* Loading should be instantaneous since we already have - * the full content, but we still have to crank the main - * loop until the callback gets triggered. */ - while (!status.done) - gtk_main_iteration (); - - status.file = NULL; - status.done = FALSE; - - e_attachment_save_async ( - attachment, temp_directory, (GAsyncReadyCallback) - attachment_save_finished, &status); - - /* We can't return until we have results, so crank - * the main loop until the callback gets triggered. */ - while (!status.done) - gtk_main_iteration (); - - if (status.file != NULL) { - path = g_file_get_path (status.file); - g_object_unref (status.file); - } else - path = NULL; - - g_object_unref (attachment); - g_object_unref (temp_directory); - - return path; -} - -static void -update_item_progress_info (ItipPURI *pitip, - ItipView *view, - const gchar *message) -{ - if (pitip->update_item_progress_info_id) { - itip_view_remove_lower_info_item (view, pitip->update_item_progress_info_id); - pitip->update_item_progress_info_id = 0; - - if (!message) - itip_view_set_buttons_sensitive (view, TRUE); - } - - if (pitip->update_item_error_info_id) { - itip_view_remove_lower_info_item (view, pitip->update_item_error_info_id); - pitip->update_item_error_info_id = 0; - } - - if (message) { - itip_view_set_buttons_sensitive (view, FALSE); - pitip->update_item_progress_info_id = - itip_view_add_lower_info_item ( - view, - ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS, - message); - } -} - -static void -finish_message_delete_with_rsvp (ItipPURI *pitip, - ItipView *view, - ECalClient *client) -{ - gboolean save_schedules = e_cal_client_check_save_schedules (client); - - if (!save_schedules && pitip->delete_message && pitip->folder) - camel_folder_delete_message (pitip->folder, pitip->uid); - - if (itip_view_get_rsvp (view)) { - ECalComponent *comp = NULL; - icalcomponent *ical_comp; - icalproperty *prop; - icalvalue *value; - const gchar *attendee; - gchar *comment; - GSList *l, *list = NULL; - gboolean found; - - comp = e_cal_component_clone (pitip->comp); - if (comp == NULL) - return; - - if (pitip->to_address == NULL) - find_to_address (pitip, pitip->ical_comp, NULL); - g_assert (pitip->to_address != NULL); - - ical_comp = e_cal_component_get_icalcomponent (comp); - - /* Remove all attendees except the one we are responding as */ - found = FALSE; - for (prop = icalcomponent_get_first_property (ical_comp, ICAL_ATTENDEE_PROPERTY); - prop != NULL; - prop = icalcomponent_get_next_property (ical_comp, ICAL_ATTENDEE_PROPERTY)) { - gchar *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); - - /* We do this to ensure there is at most one - * attendee in the response */ - if (found || g_ascii_strcasecmp (pitip->to_address, text)) - list = g_slist_prepend (list, prop); - else if (!g_ascii_strcasecmp (pitip->to_address, text)) - found = TRUE; - g_free (text); - } - - for (l = list; l; l = l->next) { - prop = l->data; - icalcomponent_remove_property (ical_comp, prop); - icalproperty_free (prop); - } - g_slist_free (list); - - /* Add a comment if there user set one */ - comment = itip_view_get_rsvp_comment (view); - if (comment) { - GSList comments; - ECalComponentText text; - - text.value = comment; - text.altrep = NULL; - - comments.data = &text; - comments.next = NULL; - - e_cal_component_set_comment_list (comp, &comments); - - g_free (comment); - } - - e_cal_component_rescan (comp); - if (itip_send_comp ( - pitip->registry, - E_CAL_COMPONENT_METHOD_REPLY, - comp, pitip->current_client, - pitip->top_level, NULL, NULL, TRUE, FALSE) && - pitip->folder != NULL) { - camel_folder_set_message_flags ( - pitip->folder, pitip->uid, - CAMEL_MESSAGE_ANSWERED, - CAMEL_MESSAGE_ANSWERED); - } - - g_object_unref (comp); - } - - update_item_progress_info (pitip, view, NULL); -} - -static void -receive_objects_ready_cb (GObject *ecalclient, - GAsyncResult *result, - gpointer user_data) -{ - ECalClient *client = E_CAL_CLIENT (ecalclient); - ESource *source = e_client_get_source (E_CLIENT (client)); - ItipView *view = user_data; - ItipPURI *pitip = itip_view_get_puri (view); - gboolean save_schedules; - GError *error = NULL; - - if (!e_cal_client_receive_objects_finish (client, result, &error)) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && - !g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED)) { - update_item_progress_info (pitip, view, NULL); - pitip->update_item_error_info_id = - itip_view_add_lower_info_item_printf ( - view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Unable to send item to calendar '%s'. %s"), - e_source_get_display_name (source), error ? error->message : _("Unknown error")); - } - g_clear_error (&error); - return; - } - - itip_view_set_extension_name (view, NULL); - - itip_view_clear_lower_info_items (view); - - switch (pitip->update_item_response) { - case ITIP_VIEW_RESPONSE_ACCEPT: - itip_view_add_lower_info_item_printf ( - view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Sent to calendar '%s' as accepted"), e_source_get_display_name (source)); - break; - case ITIP_VIEW_RESPONSE_TENTATIVE: - itip_view_add_lower_info_item_printf ( - view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Sent to calendar '%s' as tentative"), e_source_get_display_name (source)); - break; - case ITIP_VIEW_RESPONSE_DECLINE: - /* FIXME some calendars just might not save it at all, is this accurate? */ - itip_view_add_lower_info_item_printf ( - view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Sent to calendar '%s' as declined"), e_source_get_display_name (source)); - break; - case ITIP_VIEW_RESPONSE_CANCEL: - /* FIXME some calendars just might not save it at all, is this accurate? */ - itip_view_add_lower_info_item_printf ( - view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Sent to calendar '%s' as canceled"), e_source_get_display_name (source)); - break; - default: - g_assert_not_reached (); - break; - } - - /*FIXME Save schedules is misused here, remove it */ - save_schedules = e_cal_client_check_save_schedules (client); - - /* FIXME Remove this and handle this at the groupwise mail provider */ - if (save_schedules && pitip->can_delete_invitation_from_cache && pitip->folder) { - CamelFolderChangeInfo *changes = NULL; - const gchar *tag = NULL; - CamelMessageInfo *mi; - mi = camel_folder_summary_get (pitip->folder->summary, pitip->uid); - if (mi) { - changes = camel_folder_change_info_new (); - - if (itip_view_get_recur_check_state (view)) { - /* Recurring appointment and "apply-to-all" is selected */ - tag = camel_message_info_user_tag (mi, "recurrence-key"); - if (tag) { - gint i; - GPtrArray *known_uids; - - known_uids = camel_folder_summary_get_array (pitip->folder->summary); - for (i = 0; known_uids && i < known_uids->len; i++) { - const gchar *uid = g_ptr_array_index (known_uids, i); - CamelMessageInfo *mi2; - - mi2 = camel_folder_summary_get (pitip->folder->summary, uid); - if (!mi2) - continue; - - if (camel_message_info_user_tag (mi2, "recurrence-key") && - g_str_equal (camel_message_info_user_tag (mi2, "recurrence-key"), tag)) { - camel_folder_summary_remove_uid (pitip->folder->summary, mi2->uid); - camel_folder_change_info_remove_uid (changes, mi2->uid); - } - - camel_message_info_free (mi2); - } - } - } else { - /* Either not a recurring appointment or "apply-to-all" is not selected. So just delete this instance alone */ - camel_folder_summary_remove_uid (pitip->folder->summary, pitip->uid); - camel_folder_change_info_remove_uid (changes, pitip->uid); - } - - camel_folder_changed (pitip->folder, changes); - camel_folder_change_info_free (changes); - camel_message_info_free (mi); - } - } - - finish_message_delete_with_rsvp (pitip, view, client); -} - -static void -update_item (ItipPURI *pitip, - ItipView *view, - ItipViewResponse response) -{ - struct icaltimetype stamp; - icalproperty *prop; - icalcomponent *clone; - ECalComponent *clone_comp; - gchar *str; - - update_item_progress_info (pitip, view, _("Saving changes to the calendar. Please wait...")); - - /* Set X-MICROSOFT-CDO-REPLYTIME to record the time at which - * the user accepted/declined the request. (Outlook ignores - * SEQUENCE in REPLY reponses and instead requires that each - * updated response have a later REPLYTIME than the previous - * one.) This also ends up getting saved in our own copy of - * the meeting, though there's currently no way to see that - * information (unless it's being saved to an Exchange folder - * and you then look at it in Outlook). - */ - stamp = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ()); - str = icaltime_as_ical_string_r (stamp); - prop = icalproperty_new_x (str); - g_free (str); - icalproperty_set_x_name (prop, "X-MICROSOFT-CDO-REPLYTIME"); - icalcomponent_add_property (pitip->ical_comp, prop); - - clone = icalcomponent_new_clone (pitip->ical_comp); - icalcomponent_add_component (pitip->top_level, clone); - icalcomponent_set_method (pitip->top_level, pitip->method); - - if (!itip_view_get_inherit_alarm_check_state (view)) { - icalcomponent *alarm_comp; - icalcompiter alarm_iter; - - alarm_iter = icalcomponent_begin_component (clone, ICAL_VALARM_COMPONENT); - while ((alarm_comp = icalcompiter_deref (&alarm_iter)) != NULL) { - icalcompiter_next (&alarm_iter); - - icalcomponent_remove_component (clone, alarm_comp); - icalcomponent_free (alarm_comp); - } - } - - clone_comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (clone_comp, clone)) { - update_item_progress_info (pitip, view, NULL); - pitip->update_item_error_info_id = itip_view_add_lower_info_item (view, - ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to parse item")); - goto cleanup; - } - - if (itip_view_get_keep_alarm_check_state (view)) { - ECalComponent *real_comp; - GList *alarms, *l; - ECalComponentAlarm *alarm; - - real_comp = get_real_item (pitip); - if (real_comp != NULL) { - alarms = e_cal_component_get_alarm_uids (real_comp); - - for (l = alarms; l; l = l->next) { - alarm = e_cal_component_get_alarm (real_comp, (const gchar *) l->data); - - if (alarm) { - ECalComponentAlarm *aclone = e_cal_component_alarm_clone (alarm); - - if (aclone) { - e_cal_component_add_alarm (clone_comp, aclone); - e_cal_component_alarm_free (aclone); - } - - e_cal_component_alarm_free (alarm); - } - } - - cal_obj_uid_list_free (alarms); - g_object_unref (real_comp); - } - } - - if ((response != ITIP_VIEW_RESPONSE_CANCEL) - && (response != ITIP_VIEW_RESPONSE_DECLINE)) { - GSList *attachments = NULL, *new_attachments = NULL, *l; - CamelMimeMessage *msg = pitip->msg; - - e_cal_component_get_attachment_list (clone_comp, &attachments); - - for (l = attachments; l; l = l->next) { - GSList *parts = NULL, *m; - gchar *uri, *new_uri; - CamelMimePart *part; - - uri = l->data; - - if (!g_ascii_strncasecmp (uri, "cid:...", 7)) { - message_foreach_part ((CamelMimePart *) msg, &parts); - - for (m = parts; m; m = m->next) { - part = m->data; - - /* Skip the actual message and the text/calendar part */ - /* FIXME Do we need to skip anything else? */ - if (part == (CamelMimePart *) msg || part == pitip->part) - continue; - - new_uri = get_uri_for_part (part); - if (new_uri != NULL) - new_attachments = g_slist_append (new_attachments, new_uri); - } - - g_slist_free (parts); - - } else if (!g_ascii_strncasecmp (uri, "cid:", 4)) { - part = camel_mime_message_get_part_by_content_id (msg, uri + 4); - if (part) { - new_uri = get_uri_for_part (part); - if (new_uri != NULL) - new_attachments = g_slist_append (new_attachments, new_uri); - } - - } else { - /* Preserve existing non-cid ones */ - new_attachments = g_slist_append (new_attachments, g_strdup (uri)); - } - } - - g_slist_foreach (attachments, (GFunc) g_free, NULL); - g_slist_free (attachments); - - e_cal_component_set_attachment_list (clone_comp, new_attachments); - } - - pitip->update_item_response = response; - - e_cal_client_receive_objects ( - pitip->current_client, - pitip->top_level, - pitip->cancellable, - receive_objects_ready_cb, - view); - - cleanup: - icalcomponent_remove_component (pitip->top_level, clone); - g_object_unref (clone_comp); -} - -/* TODO These operations should be available in e-cal-component.c */ -static void -set_attendee (ECalComponent *comp, - const gchar *address) -{ - icalproperty *prop; - icalcomponent *icalcomp; - gboolean found = FALSE; - - icalcomp = e_cal_component_get_icalcomponent (comp); - - for (prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY); - prop; - prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) { - const gchar *attendee = icalproperty_get_attendee (prop); - - if (!(g_str_equal (itip_strip_mailto (attendee), address))) - icalcomponent_remove_property (icalcomp, prop); - else - found = TRUE; - } - - if (!found) { - icalparameter *param; - gchar *temp = g_strdup_printf ("MAILTO:%s", address); - - prop = icalproperty_new_attendee ((const gchar *) temp); - icalcomponent_add_property (icalcomp, prop); - - param = icalparameter_new_partstat (ICAL_PARTSTAT_NEEDSACTION); - icalproperty_add_parameter (prop, param); - - param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT); - icalproperty_add_parameter (prop, param); - - param = icalparameter_new_cutype (ICAL_CUTYPE_INDIVIDUAL); - icalproperty_add_parameter (prop, param); - - param = icalparameter_new_rsvp (ICAL_RSVP_TRUE); - icalproperty_add_parameter (prop, param); - - g_free (temp); - } - -} - -static gboolean -send_comp_to_attendee (ESourceRegistry *registry, - ECalComponentItipMethod method, - ECalComponent *comp, - const gchar *user, - ECalClient *client, - const gchar *comment) -{ - gboolean status; - ECalComponent *send_comp = e_cal_component_clone (comp); - - set_attendee (send_comp, user); - - if (comment) { - GSList comments; - ECalComponentText text; - - text.value = comment; - text.altrep = NULL; - - comments.data = &text; - comments.next = NULL; - - e_cal_component_set_comment_list (send_comp, &comments); - } - - /* FIXME send the attachments in the request */ - status = itip_send_comp ( - registry, method, send_comp, - client, NULL, NULL, NULL, TRUE, FALSE); - - g_object_unref (send_comp); - - return status; -} - -static void -remove_delegate (ItipPURI *pitip, - ItipView *view, - const gchar *delegate, - const gchar *delegator, - ECalComponent *comp) -{ - gboolean status; - gchar *comment = g_strdup_printf (_("Organizer has removed the delegate %s "), itip_strip_mailto (delegate)); - - /* send cancellation notice to delegate */ - status = send_comp_to_attendee ( - pitip->registry, - E_CAL_COMPONENT_METHOD_CANCEL, pitip->comp, - delegate, pitip->current_client, comment); - if (status) - send_comp_to_attendee ( - pitip->registry, - E_CAL_COMPONENT_METHOD_REQUEST, pitip->comp, - delegator, pitip->current_client, comment); - if (status) { - itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Sent a cancelation notice to the delegate")); - } else - itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Could not send the cancelation notice to the delegate")); - - g_free (comment); - -} - -static void -update_x (ECalComponent *pitip_comp, - ECalComponent *comp) -{ - icalcomponent *itip_icalcomp = e_cal_component_get_icalcomponent (pitip_comp); - icalcomponent *icalcomp = e_cal_component_get_icalcomponent (comp); - - icalproperty *prop = icalcomponent_get_first_property (itip_icalcomp, ICAL_X_PROPERTY); - while (prop) { - const gchar *name = icalproperty_get_x_name (prop); - if (!g_ascii_strcasecmp (name, "X-EVOLUTION-IS-REPLY")) { - icalproperty *new_prop = icalproperty_new_x (icalproperty_get_x (prop)); - icalproperty_set_x_name (new_prop, "X-EVOLUTION-IS-REPLY"); - icalcomponent_add_property (icalcomp, new_prop); - } - prop = icalcomponent_get_next_property (itip_icalcomp, ICAL_X_PROPERTY); - } - - e_cal_component_set_icalcomponent (comp, icalcomp); -} - -static void -modify_object_cb (GObject *ecalclient, - GAsyncResult *result, - gpointer user_data) -{ - ECalClient *client = E_CAL_CLIENT (ecalclient); - ItipView *view = user_data; - ItipPURI *pitip = itip_view_get_puri (view); - GError *error = NULL; - - if (!e_cal_client_modify_object_finish (client, result, &error)) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || - g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED)) { - g_clear_error (&error); - return; - } - - update_item_progress_info (pitip, view, NULL); - pitip->update_item_error_info_id = - itip_view_add_lower_info_item_printf ( - view, - ITIP_VIEW_INFO_ITEM_TYPE_ERROR, - _("Unable to update attendee. %s"), - error ? error->message : _("Unknown error")); - - g_clear_error (&error); - } else { - update_item_progress_info (pitip, view, NULL); - itip_view_add_lower_info_item (view, - ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Attendee status updated")); - } -} - -static void -update_attendee_status_icalcomp (ItipPURI *pitip, - ItipView *view, - icalcomponent *icalcomp) -{ - ECalComponent *comp; - const gchar *uid = NULL; - gchar *rid; - GSList *attendees; - - e_cal_component_get_uid (pitip->comp, &uid); - rid = e_cal_component_get_recurid_as_string (pitip->comp); - - comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (comp, icalcomp)) { - icalcomponent_free (icalcomp); - - itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, - _("The meeting is invalid and cannot be updated")); - } else { - icalcomponent *org_icalcomp; - const gchar *delegate; - - org_icalcomp = e_cal_component_get_icalcomponent (pitip->comp); - - e_cal_component_get_attendee_list (pitip->comp, &attendees); - if (attendees != NULL) { - ECalComponentAttendee *a = attendees->data; - icalproperty *prop, *del_prop; - EShell *shell = e_shell_get_default (); - - prop = find_attendee (icalcomp, itip_strip_mailto (a->value)); - if ((a->status == ICAL_PARTSTAT_DELEGATED) && (del_prop = find_attendee (org_icalcomp, itip_strip_mailto (a->delto))) && !(find_attendee (icalcomp, itip_strip_mailto (a->delto)))) { - gint response; - delegate = icalproperty_get_attendee (del_prop); - response = e_alert_run_dialog_for_args (e_shell_get_active_window (shell), - "org.gnome.itip-formatter:add-delegate", - itip_strip_mailto (a->value), - itip_strip_mailto (delegate), NULL); - if (response == GTK_RESPONSE_YES) { - icalcomponent_add_property (icalcomp, icalproperty_new_clone (del_prop)); - e_cal_component_rescan (comp); - } else if (response == GTK_RESPONSE_NO) { - remove_delegate (pitip, view, delegate, itip_strip_mailto (a->value), comp); - goto cleanup; - } else { - goto cleanup; - } - } - - if (prop == NULL) { - gint response; - - if (a->delfrom && *a->delfrom) { - response = e_alert_run_dialog_for_args (e_shell_get_active_window (shell), - "org.gnome.itip-formatter:add-delegate", - itip_strip_mailto (a->delfrom), - itip_strip_mailto (a->value), NULL); - if (response == GTK_RESPONSE_YES) { - /* Already declared in this function */ - icalproperty *prop = find_attendee (icalcomp, itip_strip_mailto (a->value)); - icalcomponent_add_property (icalcomp,icalproperty_new_clone (prop)); - e_cal_component_rescan (comp); - } else if (response == GTK_RESPONSE_NO) { - remove_delegate (pitip, - view, - itip_strip_mailto (a->value), - itip_strip_mailto (a->delfrom), - comp); - goto cleanup; - } else { - goto cleanup; - } - } - - response = e_alert_run_dialog_for_args ( - e_shell_get_active_window (shell), - "org.gnome.itip-formatter:add-unknown-attendee", NULL); - - if (response == GTK_RESPONSE_YES) { - change_status ( - pitip->registry, icalcomp, - itip_strip_mailto (a->value), - a->status); - e_cal_component_rescan (comp); - } else { - goto cleanup; - } - } else if (a->status == ICAL_PARTSTAT_NONE || a->status == ICAL_PARTSTAT_X) { - itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, - _("Attendee status could not be updated because the status is invalid")); - goto cleanup; - } else { - if (a->status == ICAL_PARTSTAT_DELEGATED) { - /* *prop already declared in this function */ - icalproperty *prop, *new_prop; - - prop = find_attendee (icalcomp, itip_strip_mailto (a->value)); - icalcomponent_remove_property (icalcomp, prop); - - new_prop = find_attendee (org_icalcomp, itip_strip_mailto (a->value)); - icalcomponent_add_property (icalcomp, icalproperty_new_clone (new_prop)); - } else - change_status ( - pitip->registry, icalcomp, - itip_strip_mailto (a->value), - a->status); - - e_cal_component_rescan (comp); - } - } - } - - update_x (pitip->comp, comp); - - if (itip_view_get_update (view)) { - e_cal_component_commit_sequence (comp); - itip_send_comp ( - pitip->registry, - E_CAL_COMPONENT_METHOD_REQUEST, - comp, pitip->current_client, - NULL, NULL, NULL, TRUE, FALSE); - } - - update_item_progress_info (pitip, view, _("Saving changes to the calendar. Please wait...")); - - e_cal_client_modify_object ( - pitip->current_client, - icalcomp, rid ? CALOBJ_MOD_THIS : CALOBJ_MOD_ALL, - pitip->cancellable, - modify_object_cb, - view); - - cleanup: - g_object_unref (comp); -} - -static void -update_attendee_status_get_object_without_rid_cb (GObject *ecalclient, - GAsyncResult *result, - gpointer user_data) -{ - ECalClient *client = E_CAL_CLIENT (ecalclient); - ItipView *view = user_data; - ItipPURI *pitip = itip_view_get_puri (view); - icalcomponent *icalcomp = NULL; - GError *error = NULL; - - if (!e_cal_client_get_object_finish (client, result, &icalcomp, &error)) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || - g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED)) { - g_clear_error (&error); - return; - } - - g_clear_error (&error); - - update_item_progress_info (pitip, view, NULL); - pitip->update_item_error_info_id = itip_view_add_lower_info_item ( - view, - ITIP_VIEW_INFO_ITEM_TYPE_WARNING, - _("Attendee status can not be updated because the item no longer exists")); - return; - } - - update_attendee_status_icalcomp (pitip, view, icalcomp); -} - -static void -update_attendee_status_get_object_with_rid_cb (GObject *ecalclient, - GAsyncResult *result, - gpointer user_data) -{ - ECalClient *client = E_CAL_CLIENT (ecalclient); - ItipView *view = user_data; - ItipPURI *pitip = itip_view_get_puri (view); - icalcomponent *icalcomp = NULL; - GError *error = NULL; - - if (!e_cal_client_get_object_finish (client, result, &icalcomp, &error)) { - const gchar *uid; - gchar *rid; - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || - g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED)) { - g_clear_error (&error); - return; - } - - g_clear_error (&error); - - e_cal_component_get_uid (pitip->comp, &uid); - rid = e_cal_component_get_recurid_as_string (pitip->comp); - - if (!rid || !*rid) { - g_free (rid); - - update_item_progress_info (pitip, view, NULL); - pitip->update_item_error_info_id = itip_view_add_lower_info_item ( - view, - ITIP_VIEW_INFO_ITEM_TYPE_WARNING, - _("Attendee status can not be updated because the item no longer exists")); - return; - } - - e_cal_client_get_object ( - pitip->current_client, - uid, - NULL, - pitip->cancellable, - update_attendee_status_get_object_without_rid_cb, - view); - - g_free (rid); - return; - } - - update_attendee_status_icalcomp (pitip, view, icalcomp); -} - -static void -update_attendee_status (ItipPURI *pitip, - ItipView *view) -{ - const gchar *uid = NULL; - gchar *rid; - - /* Obtain our version */ - e_cal_component_get_uid (pitip->comp, &uid); - rid = e_cal_component_get_recurid_as_string (pitip->comp); - - update_item_progress_info (pitip, view, _("Saving changes to the calendar. Please wait...")); - - /* search for a master object if the detached object doesn't exist in the calendar */ - e_cal_client_get_object ( - pitip->current_client, - uid, rid, - pitip->cancellable, - update_attendee_status_get_object_with_rid_cb, - view); - - g_free (rid); -} - -static void -send_item (ItipPURI *pitip, - ItipView *view) -{ - ECalComponent *comp; - - comp = get_real_item (pitip); - - if (comp != NULL) { - itip_send_comp ( - pitip->registry, - E_CAL_COMPONENT_METHOD_REQUEST, - comp, pitip->current_client, - NULL, NULL, NULL, TRUE, FALSE); - g_object_unref (comp); - - switch (pitip->type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Meeting information sent")); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Task information sent")); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Memo information sent")); - break; - default: - g_assert_not_reached (); - break; - } - } else { - switch (pitip->type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, - _("Unable to send meeting information, the meeting does not exist")); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, - _("Unable to send task information, the task does not exist")); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - itip_view_add_lower_info_item ( - view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, - _("Unable to send memo information, the memo does not exist")); - break; - default: - g_assert_not_reached (); - break; - } - } -} - -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 -attachment_load_finish (EAttachment *attachment, - GAsyncResult *result, - GFile *file) -{ - EShell *shell; - GtkWindow *parent; - - /* XXX Theoretically, this should never fail. */ - e_attachment_load_finish (attachment, result, NULL); - - shell = e_shell_get_default (); - parent = e_shell_get_active_window (shell); - - e_attachment_save_async ( - attachment, file, (GAsyncReadyCallback) - e_attachment_save_handle_error, parent); - - g_object_unref (file); -} - -static void -save_vcalendar_cb (ItipPURI *pitip) -{ - EAttachment *attachment; - EShell *shell; - GFile *file; - const gchar *suggestion; - - g_return_if_fail (pitip != NULL); - g_return_if_fail (pitip->vcalendar != NULL); - g_return_if_fail (pitip->part != NULL); - - suggestion = camel_mime_part_get_filename (pitip->part); - if (suggestion == NULL) { - /* Translators: This is a default filename for a calendar. */ - suggestion = _("calendar.ics"); - } - - shell = e_shell_get_default (); - file = e_shell_run_save_dialog ( - shell, _("Save Calendar"), suggestion, "*.ics:text/calendar", NULL, NULL); - if (file == NULL) - return; - - attachment = e_attachment_new (); - e_attachment_set_mime_part (attachment, pitip->part); - - e_attachment_load_async ( - attachment, (GAsyncReadyCallback) - attachment_load_finish, file); -} - -static void -set_itip_error (ItipView *view, - const gchar *primary, - const gchar *secondary, - gboolean save_btn) -{ - gchar *error; - - error = g_strdup_printf ( - "<div class=\"error\">" - "<p><b>%s</b></p>" - "<p>%s</p>", - primary, secondary); - - itip_view_set_error (view, error, save_btn); - - g_free (error); -} - -static gboolean -extract_itip_data (ItipPURI *pitip, - ItipView *view, - gboolean *have_alarms) -{ - EShell *shell; - EShellSettings *shell_settings; - icalproperty *prop; - icalcomponent_kind kind = ICAL_NO_COMPONENT; - icalcomponent *tz_comp; - icalcompiter tz_iter; - icalcomponent *alarm_comp; - icalcompiter alarm_iter; - ECalComponent *comp; - gboolean use_default_reminder; - - shell = e_shell_get_default (); - shell_settings = e_shell_get_shell_settings (shell); - - if (!pitip->vcalendar) { - set_itip_error (view, - _("The calendar attached is not valid"), - _("The message claims to contain a calendar, but the calendar is not a valid iCalendar."), - FALSE); - - return FALSE; - } - - pitip->top_level = e_cal_util_new_top_level (); - - pitip->main_comp = icalparser_parse_string (pitip->vcalendar); - if (pitip->main_comp == NULL || !is_icalcomp_valid (pitip->main_comp)) { - set_itip_error (view, - _("The calendar attached is not valid"), - _("The message claims to contain a calendar, but the calendar is not a valid iCalendar."), - FALSE); - - if (pitip->main_comp) { - icalcomponent_free (pitip->main_comp); - pitip->main_comp = NULL; - } - - return FALSE; - } - - 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 - && kind != ICAL_VJOURNAL_COMPONENT) - pitip->ical_comp = get_next (&pitip->iter); - } - - if (pitip->ical_comp == NULL) { - set_itip_error (view, - _("The item in the calendar is not valid"), - _("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"), - FALSE); - - return FALSE; - } - - switch (icalcomponent_isa (pitip->ical_comp)) { - case ICAL_VEVENT_COMPONENT: - pitip->type = E_CAL_CLIENT_SOURCE_TYPE_EVENTS; - pitip->has_organizer = icalcomponent_get_first_property (pitip->ical_comp, ICAL_ORGANIZER_PROPERTY) != NULL; - if (icalcomponent_get_first_property (pitip->ical_comp, ICAL_ATTENDEE_PROPERTY) == NULL) { - /* no attendees: assume that that this is not a meeting and organizer doesn't want a reply */ - pitip->no_reply_wanted = TRUE; - } else { - /* - * if we have attendees, then find_to_address() will check for our RSVP - * and set no_reply_wanted=TRUE if RSVP=FALSE for the current user - */ - } - break; - case ICAL_VTODO_COMPONENT: - pitip->type = E_CAL_CLIENT_SOURCE_TYPE_TASKS; - break; - case ICAL_VJOURNAL_COMPONENT: - pitip->type = E_CAL_CLIENT_SOURCE_TYPE_MEMOS; - break; - default: - set_itip_error (view, - _("The item in the calendar is not valid"), - _("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"), - FALSE); - - return FALSE; - } - - 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); - pitip->total += icalcomponent_count_components (pitip->main_comp, ICAL_VJOURNAL_COMPONENT); - - if (pitip->total > 1) { - - set_itip_error (view, - _("The calendar attached contains multiple items"), - _("To process all of these items, the file should be saved and the calendar imported"), - TRUE); - - } if (pitip->total > 0) { - pitip->current = 1; - } else { - pitip->current = 0; - } - - if (icalcomponent_isa (pitip->ical_comp) != ICAL_VJOURNAL_COMPONENT) { - gchar *my_address; - - prop = NULL; - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (pitip->ical_comp)); - my_address = itip_get_comp_attendee (pitip->registry, comp, NULL); - g_object_unref (comp); - comp = NULL; - - if (!prop) - prop = find_attendee (pitip->ical_comp, my_address); - if (!prop) - prop = find_attendee_if_sentby (pitip->ical_comp, my_address); - if (prop) { - icalparameter *param; - const gchar * delfrom; - - if ((param = icalproperty_get_first_parameter (prop, ICAL_DELEGATEDFROM_PARAMETER))) { - delfrom = icalparameter_get_delegatedfrom (param); - - pitip->delegator_address = g_strdup (itip_strip_mailto (delfrom)); - } - } - g_free (my_address); - prop = NULL; - - /* Determine any delegate sections */ - prop = icalcomponent_get_first_property (pitip->ical_comp, ICAL_X_PROPERTY); - while (prop) { - const gchar *x_name, *x_val; - - x_name = icalproperty_get_x_name (prop); - x_val = icalproperty_get_x (prop); - - if (!strcmp (x_name, "X-EVOLUTION-DELEGATOR-CALENDAR-UID")) - pitip->calendar_uid = g_strdup (x_val); - else if (!strcmp (x_name, "X-EVOLUTION-DELEGATOR-CALENDAR-URI")) - g_warning (G_STRLOC ": X-EVOLUTION-DELEGATOR-CALENDAR-URI used"); - else if (!strcmp (x_name, "X-EVOLUTION-DELEGATOR-ADDRESS")) - pitip->delegator_address = g_strdup (x_val); - else if (!strcmp (x_name, "X-EVOLUTION-DELEGATOR-NAME")) - pitip->delegator_name = g_strdup (x_val); - - prop = icalcomponent_get_next_property (pitip->ical_comp, ICAL_X_PROPERTY); - } - - /* Strip out procedural alarms for security purposes */ - alarm_iter = icalcomponent_begin_component (pitip->ical_comp, ICAL_VALARM_COMPONENT); - while ((alarm_comp = icalcompiter_deref (&alarm_iter)) != NULL) { - icalproperty *p; - - icalcompiter_next (&alarm_iter); - - p = icalcomponent_get_first_property (alarm_comp, ICAL_ACTION_PROPERTY); - if (!p || icalproperty_get_action (p) == ICAL_ACTION_PROCEDURE) - icalcomponent_remove_component (pitip->ical_comp, alarm_comp); - - icalcomponent_free (alarm_comp); - } - - if (have_alarms) { - alarm_iter = icalcomponent_begin_component (pitip->ical_comp, ICAL_VALARM_COMPONENT); - *have_alarms = icalcompiter_deref (&alarm_iter) != NULL; - } - } - - pitip->comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (pitip->comp, pitip->ical_comp)) { - g_object_unref (pitip->comp); - pitip->comp = NULL; - - set_itip_error (view, - _("The item in the calendar is not valid"), - _("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"), - FALSE); - - return FALSE; - }; - - /* Add default reminder if the config says so */ - - use_default_reminder = e_shell_settings_get_boolean ( - shell_settings, "cal-use-default-reminder"); - - if (use_default_reminder) { - ECalComponentAlarm *acomp; - gint interval; - EDurationType units; - ECalComponentAlarmTrigger trigger; - - interval = e_shell_settings_get_int ( - shell_settings, "cal-default-reminder-interval"); - units = e_shell_settings_get_int ( - shell_settings, "cal-default-reminder-units"); - - acomp = e_cal_component_alarm_new (); - - e_cal_component_alarm_set_action (acomp, E_CAL_COMPONENT_ALARM_DISPLAY); - - trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START; - memset (&trigger.u.rel_duration, 0, sizeof (trigger.u.rel_duration)); - - trigger.u.rel_duration.is_neg = TRUE; - - switch (units) { - case E_DURATION_MINUTES: - trigger.u.rel_duration.minutes = interval; - break; - case E_DURATION_HOURS: - trigger.u.rel_duration.hours = interval; - break; - case E_DURATION_DAYS: - trigger.u.rel_duration.days = interval; - break; - default: - g_assert_not_reached (); - } - - e_cal_component_alarm_set_trigger (acomp, trigger); - e_cal_component_add_alarm (pitip->comp, acomp); - - e_cal_component_alarm_free (acomp); - } - - find_from_address (pitip, pitip->ical_comp); - find_to_address (pitip, pitip->ical_comp, NULL); - - return TRUE; -} - -struct _opencal_msg { - MailMsg base; - - gchar *command; /* command line to run */ -}; - -static gchar * -open_calendar__desc (struct _opencal_msg *m, - gint complete) -{ - return g_strdup (_("Opening calendar")); -} - -static void -open_calendar__exec (struct _opencal_msg *m, - GCancellable *cancellable, - GError **error) -{ - if (!g_spawn_command_line_async (m->command, NULL)) { - g_warning ("Could not launch %s", m->command); - } -} - -static void -open_calendar__free (struct _opencal_msg *m) -{ - g_free (m->command); - m->command = NULL; -} - -static MailMsgInfo open_calendar_info = { - sizeof (struct _opencal_msg), - (MailMsgDescFunc) open_calendar__desc, - (MailMsgExecFunc) open_calendar__exec, - (MailMsgDoneFunc) NULL, - (MailMsgFreeFunc) open_calendar__free, -}; - -static gboolean -idle_open_cb (gpointer data) -{ - ItipPURI *pitip = data; - struct _opencal_msg *m; - gchar *start, *end; - - start = isodate_from_time_t (pitip->start_time); - end = isodate_from_time_t (pitip->end_time); - m = mail_msg_new (&open_calendar_info); - m->command = g_strdup_printf ("evolution \"calendar:///?startdate=%s&enddate=%s\"", start, end); - mail_msg_slow_ordered_push (m); - - g_free (start); - g_free (end); - - return FALSE; -} - -static void -view_response_cb (ItipView *view, - ItipViewResponse response, - gpointer data) -{ - ItipPURI *pitip = data; - gboolean status = FALSE; - icalproperty *prop; - ECalComponentTransparency trans; - - if (response == ITIP_VIEW_RESPONSE_SAVE) { - save_vcalendar_cb (pitip); - return; - } - - pitip->can_delete_invitation_from_cache = FALSE; - if (pitip->method == ICAL_METHOD_PUBLISH || pitip->method == ICAL_METHOD_REQUEST) { - if (itip_view_get_free_time_check_state (view)) - e_cal_component_set_transparency (pitip->comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT); - else - e_cal_component_set_transparency (pitip->comp, E_CAL_COMPONENT_TRANSP_OPAQUE); - } else { - e_cal_component_get_transparency (pitip->comp, &trans); - - if (trans == E_CAL_COMPONENT_TRANSP_NONE) - e_cal_component_set_transparency (pitip->comp, E_CAL_COMPONENT_TRANSP_OPAQUE); - } - - if (!pitip->to_address && pitip->current_client != NULL) - e_client_get_backend_property_sync (E_CLIENT (pitip->current_client), CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS, &pitip->to_address, NULL, NULL); - - /* check if it is a recur instance (no master object) and - * add a property */ - if (itip_view_get_recur_check_state (view)) { - prop = icalproperty_new_x ("All"); - icalproperty_set_x_name (prop, "X-GW-RECUR-INSTANCES-MOD-TYPE"); - icalcomponent_add_property (pitip->ical_comp, prop); - } - - switch (response) { - case ITIP_VIEW_RESPONSE_ACCEPT: - if (pitip->type != E_CAL_CLIENT_SOURCE_TYPE_MEMOS) - status = change_status ( - pitip->registry, - pitip->ical_comp, - pitip->to_address, - ICAL_PARTSTAT_ACCEPTED); - else - status = TRUE; - if (status) { - e_cal_component_rescan (pitip->comp); - pitip->can_delete_invitation_from_cache = TRUE; - update_item (pitip, view, response); - } - break; - case ITIP_VIEW_RESPONSE_TENTATIVE: - status = change_status ( - pitip->registry, - pitip->ical_comp, - pitip->to_address, - ICAL_PARTSTAT_TENTATIVE); - if (status) { - e_cal_component_rescan (pitip->comp); - pitip->can_delete_invitation_from_cache = TRUE; - update_item (pitip, view, response); - } - break; - case ITIP_VIEW_RESPONSE_DECLINE: - if (pitip->type != E_CAL_CLIENT_SOURCE_TYPE_MEMOS) - status = change_status ( - pitip->registry, - pitip->ical_comp, - pitip->to_address, - ICAL_PARTSTAT_DECLINED); - else { - prop = icalproperty_new_x ("1"); - icalproperty_set_x_name (prop, "X-GW-DECLINED"); - icalcomponent_add_property (pitip->ical_comp, prop); - status = TRUE; - } - - if (status) { - e_cal_component_rescan (pitip->comp); - pitip->can_delete_invitation_from_cache = TRUE; - update_item (pitip, view, response); - } - break; - case ITIP_VIEW_RESPONSE_UPDATE: - update_attendee_status (pitip, view); - break; - case ITIP_VIEW_RESPONSE_CANCEL: - update_item (pitip, view, response); - break; - case ITIP_VIEW_RESPONSE_REFRESH: - send_item (pitip, view); - break; - case ITIP_VIEW_RESPONSE_OPEN: - g_idle_add (idle_open_cb, pitip); - return; - default: - break; - } -} - -static gboolean -check_is_instance (icalcomponent *icalcomp) -{ - icalproperty *icalprop; - - icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY); - while (icalprop) { - const gchar *x_name; - - x_name = icalproperty_get_x_name (icalprop); - if (!strcmp (x_name, "X-GW-RECURRENCE-KEY")) { - return TRUE; - } - icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY); - } - - return FALSE; -} - -static gboolean -in_proper_folder (ESourceRegistry *registry, - CamelFolder *folder) -{ - EShell *shell; - EShellBackend *shell_backend; - EMailBackend *backend; - EMailSession *session; - MailFolderCache *folder_cache; - gboolean res = TRUE; - CamelFolderInfoFlags flags = 0; - - if (!folder) - return FALSE; - - shell = e_shell_get_default (); - shell_backend = e_shell_get_backend_by_name (shell, "mail"); - backend = E_MAIL_BACKEND (shell_backend); - session = e_mail_backend_get_session (backend); - folder_cache = e_mail_session_get_folder_cache (session); - - if (mail_folder_cache_get_folder_info_flags (folder_cache, folder, &flags)) { - /* it should be neither trash nor junk folder, */ - res = ((flags & CAMEL_FOLDER_TYPE_MASK) != CAMEL_FOLDER_TYPE_TRASH && - (flags & CAMEL_FOLDER_TYPE_MASK) != CAMEL_FOLDER_TYPE_JUNK && - /* it can be Inbox */ - ( (flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX || - /* or any other virtual folder */ - CAMEL_IS_VEE_FOLDER (folder) || - /* or anything else except of sent, outbox or drafts folder */ - (!em_utils_folder_is_sent (registry, folder) && - !em_utils_folder_is_outbox (registry, folder) && - !em_utils_folder_is_drafts (registry, folder)) - )); - } else { - /* cannot check for Inbox folder here */ - res = (folder->folder_flags & (CAMEL_FOLDER_IS_TRASH | CAMEL_FOLDER_IS_JUNK)) == 0 && ( - (CAMEL_IS_VEE_FOLDER (folder)) || ( - !em_utils_folder_is_sent (registry, folder) && - !em_utils_folder_is_outbox (registry, folder) && - !em_utils_folder_is_drafts (registry, folder))); - } - - return res; -} - -static void -init_itip_view (ItipPURI *info, - ItipView *view) -{ - EShell *shell; - EShellSettings *shell_settings; - ESourceRegistry *registry; - ECalComponentText text; - ECalComponentOrganizer organizer; - ECalComponentDateTime datetime; - icaltimezone *from_zone, *to_zone; - GString *gstring = NULL; - GSList *list, *l; - icalcomponent *icalcomp; - const gchar *string, *org; - gint i; - gboolean response_enabled; - gboolean have_alarms = FALSE; - EMFormat *emf = info->puri.emf; - - shell = e_shell_get_default (); - registry = e_shell_get_registry (shell); - shell_settings = e_shell_get_shell_settings (shell); - - info->registry = g_object_ref (registry); - - /* Reset current client before initializing view */ - info->current_client = NULL; - - /* Initialize the ecal hashes */ - for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) - info->clients[i] = g_hash_table_new_full ( - (GHashFunc) g_str_hash, - (GEqualFunc) g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_object_unref); - - /* FIXME Handle multiple VEVENTS with the same UID, ie detached instances */ - if (!extract_itip_data (info, view, &have_alarms)) - return; - - response_enabled = in_proper_folder (registry, emf->folder); - - if (!response_enabled) { - itip_view_set_mode (view, ITIP_VIEW_MODE_HIDE_ALL); - } else { - itip_view_set_show_inherit_alarm_check ( - view, - have_alarms && (info->method == ICAL_METHOD_PUBLISH || info->method == ICAL_METHOD_REQUEST)); - - switch (info->method) { - case ICAL_METHOD_PUBLISH: - case ICAL_METHOD_REQUEST: - /* - * Treat meeting request (sent by organizer directly) and - * published evend (forwarded by organizer or attendee) alike: - * if the event has an organizer, then it can be replied to and - * we show the "accept/tentative/decline" choice. - * Otherwise only show "accept". - */ - itip_view_set_mode (view, - info->has_organizer ? - ITIP_VIEW_MODE_REQUEST : - ITIP_VIEW_MODE_PUBLISH); - break; - case ICAL_METHOD_REPLY: - itip_view_set_mode (view, ITIP_VIEW_MODE_REPLY); - break; - case ICAL_METHOD_ADD: - itip_view_set_mode (view, ITIP_VIEW_MODE_ADD); - break; - case ICAL_METHOD_CANCEL: - itip_view_set_mode (view, ITIP_VIEW_MODE_CANCEL); - break; - case ICAL_METHOD_REFRESH: - itip_view_set_mode (view, ITIP_VIEW_MODE_REFRESH); - break; - case ICAL_METHOD_COUNTER: - itip_view_set_mode (view, ITIP_VIEW_MODE_COUNTER); - break; - case ICAL_METHOD_DECLINECOUNTER: - itip_view_set_mode (view, ITIP_VIEW_MODE_DECLINECOUNTER); - break; - case ICAL_METHOD_X : - /* Handle appointment requests from Microsoft Live. This is - * a best-at-hand-now handling. Must be revisited when we have - * better access to the source of such meetings */ - info->method = ICAL_METHOD_REQUEST; - itip_view_set_mode (view, ITIP_VIEW_MODE_REQUEST); - break; - default: - return; - } - } - - itip_view_set_item_type (view, info->type); - - if (response_enabled) { - switch (info->method) { - case ICAL_METHOD_REQUEST: - /* FIXME What about the name? */ - itip_view_set_delegator (view, info->delegator_name ? info->delegator_name : info->delegator_address); - case ICAL_METHOD_PUBLISH: - case ICAL_METHOD_ADD: - case ICAL_METHOD_CANCEL: - case ICAL_METHOD_DECLINECOUNTER: - itip_view_set_show_update_check (view, FALSE); - - /* An organizer sent this */ - e_cal_component_get_organizer (info->comp, &organizer); - org = organizer.cn ? organizer.cn : itip_strip_mailto (organizer.value); - - itip_view_set_organizer (view, org); - if (organizer.sentby) - itip_view_set_organizer_sentby ( - view, itip_strip_mailto (organizer.sentby)); - - if (info->my_address) { - if (!(organizer.value && !g_ascii_strcasecmp (itip_strip_mailto (organizer.value), info->my_address)) - && !(organizer.sentby && !g_ascii_strcasecmp (itip_strip_mailto (organizer.sentby), info->my_address)) - && (info->to_address && g_ascii_strcasecmp (info->to_address, info->my_address))) - itip_view_set_proxy (view, info->to_name ? info->to_name : info->to_address); - } - break; - case ICAL_METHOD_REPLY: - case ICAL_METHOD_REFRESH: - case ICAL_METHOD_COUNTER: - itip_view_set_show_update_check (view, TRUE); - - /* An attendee sent this */ - e_cal_component_get_attendee_list (info->comp, &list); - if (list != NULL) { - ECalComponentAttendee *attendee; - - attendee = list->data; - - itip_view_set_attendee (view, attendee->cn ? attendee->cn : itip_strip_mailto (attendee->value)); - - if (attendee->sentby) - itip_view_set_attendee_sentby (view, itip_strip_mailto (attendee->sentby)); - - if (info->my_address) { - if (!(attendee->value && !g_ascii_strcasecmp (itip_strip_mailto (attendee->value), info->my_address)) - && !(attendee->sentby && !g_ascii_strcasecmp (itip_strip_mailto (attendee->sentby), info->my_address)) - && (info->from_address && g_ascii_strcasecmp (info->from_address, info->my_address))) - itip_view_set_proxy (view, info->from_name ? info->from_name : info->from_address); - } - - e_cal_component_free_attendee_list (list); - } - break; - default: - g_assert_not_reached (); - break; - } - } - - e_cal_component_get_summary (info->comp, &text); - itip_view_set_summary (view, text.value ? text.value : C_("cal-itip", "None")); - - e_cal_component_get_location (info->comp, &string); - itip_view_set_location (view, string); - - /* Status really only applies for REPLY */ - if (response_enabled && info->method == ICAL_METHOD_REPLY) { - e_cal_component_get_attendee_list (info->comp, &list); - if (list != NULL) { - ECalComponentAttendee *a = list->data; - - switch (a->status) { - case ICAL_PARTSTAT_ACCEPTED: - itip_view_set_status (view, _("Accepted")); - break; - case ICAL_PARTSTAT_TENTATIVE: - itip_view_set_status (view, _("Tentatively Accepted")); - break; - case ICAL_PARTSTAT_DECLINED: - itip_view_set_status (view, _("Declined")); - break; - case ICAL_PARTSTAT_DELEGATED: - itip_view_set_status (view, _("Delegated")); - break; - default: - itip_view_set_status (view, _("Unknown")); - } - } - e_cal_component_free_attendee_list (list); - } - - if (info->method == ICAL_METHOD_REPLY - || info->method == ICAL_METHOD_COUNTER - || info->method == ICAL_METHOD_DECLINECOUNTER) { - /* FIXME Check spec to see if multiple comments are actually valid */ - /* Comments for iTIP are limited to one per object */ - e_cal_component_get_comment_list (info->comp, &list); - if (list) { - ECalComponentText *text = list->data; - - if (text->value) { - gchar *html; - - html = camel_text_to_html ( - text->value, - CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | - CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | - CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES, - 0); - - itip_view_set_comment (view, html); - - g_free (html); - } - } - e_cal_component_free_text_list (list); - } - - e_cal_component_get_description_list (info->comp, &list); - for (l = list; l; l = l->next) { - ECalComponentText *text = l->data; - - if (!gstring && text->value) - gstring = g_string_new (text->value); - else if (text->value) - g_string_append_printf (gstring, "\n\n%s", text->value); - } - - e_cal_component_free_text_list (list); - - if (gstring) { - gchar *html; - - html = camel_text_to_html ( - gstring->str, - CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | - CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES | - CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | - CAMEL_MIME_FILTER_TOHTML_MARK_CITATION | - CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES, - 0); - - itip_view_set_description (view, html); - g_string_free (gstring, TRUE); - g_free (html); - } - - to_zone = e_shell_settings_get_pointer (shell_settings, "cal-timezone"); - - e_cal_component_get_dtstart (info->comp, &datetime); - info->start_time = 0; - if (datetime.value) { - struct tm start_tm; - - /* If the timezone is not in the component, guess the local time */ - /* Should we guess if the timezone is an olsen name somehow? */ - if (datetime.value->is_utc) - from_zone = icaltimezone_get_utc_timezone (); - else if (!datetime.value->is_utc && datetime.tzid) - from_zone = icalcomponent_get_timezone (info->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 (view, &start_tm, datetime.value->is_date); - info->start_time = icaltime_as_timet_with_zone (*datetime.value, from_zone); - } - - icalcomp = e_cal_component_get_icalcomponent (info->comp); - - /* Set the recurrence id */ - if (check_is_instance (icalcomp) && datetime.value) { - ECalComponentRange *recur_id; - struct icaltimetype icaltime = icaltime_convert_to_zone (*datetime.value, to_zone); - - recur_id = g_new0 (ECalComponentRange, 1); - recur_id->type = E_CAL_COMPONENT_RANGE_SINGLE; - recur_id->datetime.value = &icaltime; - recur_id->datetime.tzid = icaltimezone_get_tzid (to_zone); - e_cal_component_set_recurid (info->comp, recur_id); - g_free (recur_id); /* it's ok to call g_free here */ - } - e_cal_component_free_datetime (&datetime); - - e_cal_component_get_dtend (info->comp, &datetime); - info->end_time = 0; - if (datetime.value) { - struct tm end_tm; - - /* If the timezone is not in the component, guess the local time */ - /* Should we guess if the timezone is an olsen name somehow? */ - if (datetime.value->is_utc) - from_zone = icaltimezone_get_utc_timezone (); - else if (!datetime.value->is_utc && datetime.tzid) - from_zone = icalcomponent_get_timezone (info->top_level, datetime.tzid); - else - from_zone = NULL; - - if (datetime.value->is_date) { - /* RFC says the DTEND is not inclusive, thus subtract one day - * if we have a date */ - - icaltime_adjust (datetime.value, -1, 0, 0, 0); - } - - end_tm = icaltimetype_to_tm_with_zone (datetime.value, from_zone, to_zone); - - itip_view_set_end (view, &end_tm, datetime.value->is_date); - info->end_time = icaltime_as_timet_with_zone (*datetime.value, from_zone); - } - e_cal_component_free_datetime (&datetime); - - /* Recurrence info */ - /* FIXME Better recurring description */ - if (e_cal_component_has_recurrences (info->comp)) { - /* FIXME Tell the user we don't support recurring tasks */ - switch (info->type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - itip_view_add_upper_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This meeting recurs")); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - itip_view_add_upper_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This task recurs")); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - itip_view_add_upper_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This memo recurs")); - break; - default: - g_assert_not_reached (); - break; - } - } - - if (response_enabled) { - g_signal_connect ( - view, "response", - G_CALLBACK (view_response_cb), info); - - itip_view_set_show_free_time_check (view, info->type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS && (info->method == ICAL_METHOD_PUBLISH || info->method == ICAL_METHOD_REQUEST)); - - if (info->calendar_uid) { - start_calendar_server_by_uid (info, view, info->calendar_uid, info->type); - } else { - find_server (info, view, info->comp); - set_buttons_sensitive (info, view); - } - } -} - -static void -puri_free (EMFormatPURI *puri) -{ - ItipPURI *pitip = (ItipPURI *) puri; - gint i; - - g_cancellable_cancel (pitip->cancellable); - g_object_unref (pitip->cancellable); - - if (pitip->registry != NULL) { - g_object_unref (pitip->registry); - pitip->registry = NULL; - } - - for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) { - g_hash_table_destroy (pitip->clients[i]); - pitip->clients[i] = NULL; - } - - g_free (pitip->vcalendar); - pitip->vcalendar = NULL; - - if (pitip->comp) { - g_object_unref (pitip->comp); - pitip->comp = NULL; - } - - if (pitip->top_level) { - icalcomponent_free (pitip->top_level); - pitip->top_level = NULL; - } - - if (pitip->main_comp) { - icalcomponent_free (pitip->main_comp); - pitip->main_comp = NULL; - } - pitip->ical_comp = NULL; - - g_free (pitip->calendar_uid); - pitip->calendar_uid = NULL; - - g_free (pitip->from_address); - pitip->from_address = NULL; - g_free (pitip->from_name); - pitip->from_name = NULL; - g_free (pitip->to_address); - pitip->to_address = NULL; - g_free (pitip->to_name); - pitip->to_name = NULL; - g_free (pitip->delegator_address); - pitip->delegator_address = NULL; - g_free (pitip->delegator_name); - pitip->delegator_name = NULL; - g_free (pitip->my_address); - pitip->my_address = NULL; - g_free (pitip->uid); - g_hash_table_destroy (pitip->real_comps); -} - -static void -write_itip_view (EMFormat *emf, - EMFormatPURI *puri, - CamelStream *stream, - EMFormatWriterInfo *info, - GCancellable *cancellable) -{ - GString *buffer; - - if (info->mode == EM_FORMAT_WRITE_MODE_PRINTING) { - ItipView *view; - ItipPURI *pitip; - - buffer = g_string_sized_new (1024); - - pitip = (ItipPURI *) puri; - view = itip_view_new (pitip, pitip->registry); - - init_itip_view (pitip, view); - itip_view_write_for_printing (view, buffer); - - /* Destroy the view when the formatter is destroyed */ - g_object_weak_ref ( - G_OBJECT (emf), (GWeakNotify) g_object_unref, view); - - } else if (info->mode == EM_FORMAT_WRITE_MODE_RAW) { - buffer = g_string_sized_new (2048); - - itip_view_write (buffer); - - } else { - gchar *uri; - - uri = em_format_build_mail_uri ( - emf->folder, emf->message_uid, - "part_id", G_TYPE_STRING, puri->uri, - "mode", G_TYPE_INT, EM_FORMAT_WRITE_MODE_RAW, - NULL); - - buffer = g_string_sized_new (256); - g_string_append_printf (buffer, - "<div class=\"part-container\" " - "style=\"border: none; background: none;\">" - "<iframe width=\"100%%\" height=\"auto\"" - " frameborder=\"0\" src=\"%s\" name=\"%s\" id=\"%s\"></iframe>" - "</div>", - uri, puri->uri, puri->uri); - - g_free (uri); - } - - camel_stream_write_string (stream, buffer->str, cancellable, NULL); - - g_string_free (buffer, TRUE); -} - -static void -bind_itip_view (WebKitDOMElement *element, - EMFormatPURI *puri) -{ - if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element)) { - ItipPURI *pitip = (ItipPURI *) puri; - GString *buffer = g_string_new (""); - WebKitDOMDocument *document; - ItipView *view; - - document = webkit_dom_html_iframe_element_get_content_document ( - WEBKIT_DOM_HTML_IFRAME_ELEMENT (element)); - - view = itip_view_new (pitip, pitip->registry); - - g_object_set_data_full ( - G_OBJECT (element), "view", view, - (GDestroyNotify) g_object_unref); - - itip_view_create_dom_bindings (view, - webkit_dom_document_get_document_element (document)); - - init_itip_view (pitip, view); - g_string_free (buffer, TRUE); - } -} - -void -format_itip (EPlugin *ep, - EMFormatHookTarget *target) -{ - GSettings *settings; - ItipPURI *puri; - CamelDataWrapper *content; - CamelStream *stream; - GByteArray *byte_array; - gint len; - - len = target->part_id->len; - g_string_append_printf (target->part_id, ".itip"); - - /* mark message as containing calendar, thus it will show the icon in message list now on */ - if (target->format->message_uid && target->format->folder && - !camel_folder_get_message_user_flag (target->format->folder, target->format->message_uid, "$has_cal")) - camel_folder_set_message_user_flag (target->format->folder, target->format->message_uid, "$has_cal", TRUE); - - settings = g_settings_new ("org.gnome.evolution.plugin.itip"); - - puri = (ItipPURI *) em_format_puri_new ( - target->format, sizeof (ItipPURI), - target->part, target->part_id->str); - puri->puri.write_func = write_itip_view; - puri->puri.bind_func = bind_itip_view; - puri->puri.free = puri_free; - puri->puri.is_attachment = target->info->is_attachment; - puri->puri.mime_type = g_strdup ("text/html"); - puri->delete_message = g_settings_get_boolean (settings, CONF_KEY_DELETE); - puri->has_organizer = FALSE; - puri->no_reply_wanted = FALSE; - puri->folder = ((EMFormat *) target->format)->folder; - puri->uid = g_strdup (((EMFormat *) target->format)->message_uid); - puri->msg = ((EMFormat *) target->format)->message; - puri->part = target->part; - puri->cancellable = g_cancellable_new (); - puri->real_comps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - - em_format_add_puri (target->format, (EMFormatPURI *) puri); - - g_object_unref (settings); - - /* This is non-gui thread. Download the part for using in the main thread */ - content = camel_medium_get_content ((CamelMedium *) target->part); - - byte_array = g_byte_array_new (); - stream = camel_stream_mem_new_with_byte_array (byte_array); - camel_data_wrapper_decode_to_stream_sync (content, stream, NULL, NULL); - - if (byte_array->len == 0) - puri->vcalendar = NULL; - else - puri->vcalendar = g_strndup ( - (gchar *) byte_array->data, byte_array->len); - - g_object_unref (stream); - g_string_truncate (target->part_id, len); -} - -static void -delete_toggled_cb (GtkWidget *widget) -{ - GSettings *settings; - gboolean active; - - settings = g_settings_new ("org.gnome.evolution.plugin.itip"); - active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - g_settings_set_boolean (settings, CONF_KEY_DELETE, active); - g_object_unref (settings); -} - -GtkWidget * -itip_formatter_page_factory (EPlugin *ep, - EConfigHookItemFactoryData *hook_data) -{ - EShell *shell; - ESourceRegistry *registry; - GtkWidget *page; - GtkWidget *tab_label; - GtkWidget *frame; - GtkWidget *frame_label; - GtkWidget *padding_label; - GtkWidget *hbox; - GtkWidget *inner_vbox; - GtkWidget *check; - GtkWidget *label; - GtkWidget *ess; - GtkWidget *scrolledwin; - gchar *str; - GSettings *settings; - - shell = e_shell_get_default (); - registry = e_shell_get_registry (shell); - - /* Create a new notebook page */ - page = gtk_vbox_new (FALSE, 0); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - tab_label = gtk_label_new (_("Meeting Invitations")); - gtk_notebook_append_page (GTK_NOTEBOOK (hook_data->parent), page, tab_label); - - /* Frame */ - frame = gtk_vbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0); - - /* "General" */ - frame_label = gtk_label_new (""); - str = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("General")); - gtk_label_set_markup (GTK_LABEL (frame_label), str); - g_free (str); - gtk_misc_set_alignment (GTK_MISC (frame_label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (frame), frame_label, FALSE, FALSE, 0); - - /* Indent/padding */ - hbox = gtk_hbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (frame), hbox, FALSE, TRUE, 0); - padding_label = gtk_label_new (""); - gtk_box_pack_start (GTK_BOX (hbox), padding_label, FALSE, FALSE, 0); - inner_vbox = gtk_vbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (hbox), inner_vbox, FALSE, FALSE, 0); - - /* Delete message after acting */ - settings = g_settings_new ("org.gnome.evolution.plugin.itip"); - - check = gtk_check_button_new_with_mnemonic (_("_Delete message after acting")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), g_settings_get_boolean (settings, CONF_KEY_DELETE)); - g_signal_connect ( - check, "toggled", - G_CALLBACK (delete_toggled_cb), NULL); - gtk_box_pack_start (GTK_BOX (inner_vbox), check, FALSE, FALSE, 0); - - g_object_unref (settings); - - /* "Conflict searching" */ - frame = gtk_vbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (page), frame, TRUE, TRUE, 24); - - frame_label = gtk_label_new (""); - str = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("Conflict Search")); - gtk_label_set_markup (GTK_LABEL (frame_label), str); - g_free (str); - gtk_misc_set_alignment (GTK_MISC (frame_label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (frame), frame_label, FALSE, FALSE, 0); - - /* Indent/padding */ - hbox = gtk_hbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (frame), hbox, TRUE, TRUE, 0); - padding_label = gtk_label_new (""); - gtk_box_pack_start (GTK_BOX (hbox), padding_label, FALSE, FALSE, 0); - inner_vbox = gtk_vbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (hbox), inner_vbox, TRUE, TRUE, 0); - - /* Source selector */ - label = gtk_label_new (_("Select the calendars to search for meeting conflicts")); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - gtk_box_pack_start (GTK_BOX (inner_vbox), label, FALSE, FALSE, 0); - - scrolledwin = gtk_scrolled_window_new (NULL, NULL); - - gtk_scrolled_window_set_policy ( - GTK_SCROLLED_WINDOW (scrolledwin), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type ( - GTK_SCROLLED_WINDOW (scrolledwin), GTK_SHADOW_IN); - gtk_box_pack_start (GTK_BOX (inner_vbox), scrolledwin, TRUE, TRUE, 0); - - ess = e_conflict_search_selector_new (registry); - atk_object_set_name (gtk_widget_get_accessible (ess), _("Conflict Search")); - gtk_container_add (GTK_CONTAINER (scrolledwin), ess); - - gtk_widget_show_all (page); - - return page; -} - diff --git a/plugins/itip-formatter/itip-view.c b/plugins/itip-formatter/itip-view.c deleted file mode 100644 index 16388f7232..0000000000 --- a/plugins/itip-formatter/itip-view.c +++ /dev/null @@ -1,3062 +0,0 @@ -/* - * 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: - * JP Rosevear <jpr@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 <libedataserverui/libedataserverui.h> - -#include <mail/em-format-hook.h> -#include <mail/em-format-html.h> -#include <e-util/e-util.h> -#include <e-util/e-unicode.h> -#include <calendar/gui/itip-utils.h> -#include <webkit/webkitdom.h> - -#include "itip-view.h" - -#define d(x) - -#define MEETING_ICON "stock_new-meeting" - -#define ITIP_VIEW_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), ITIP_TYPE_VIEW, ItipViewPrivate)) - -G_DEFINE_TYPE (ItipView, itip_view, G_TYPE_OBJECT) - -typedef struct { - ItipViewInfoItemType type; - gchar *message; - - guint id; -} ItipViewInfoItem; - -struct _ItipViewPrivate { - ESourceRegistry *registry; - gulong source_added_id; - gulong source_removed_id; - gchar *extension_name; - - ItipViewMode mode; - ECalClientSourceType type; - - gchar *sender; - gchar *organizer; - gchar *organizer_sentby; - gchar *delegator; - gchar *attendee; - gchar *attendee_sentby; - gchar *proxy; - - gchar *summary; - - gchar *location; - gchar *status; - gchar *comment; - - struct tm *start_tm; - gint start_tm_is_date : 1; - gchar *start_label; - const gchar *start_header; - - struct tm *end_tm; - gint end_tm_is_date : 1; - gchar *end_label; - const gchar *end_header; - - GSList *upper_info_items; - GSList *lower_info_items; - - guint next_info_item_id; - - gchar *description; - - gint buttons_sensitive : 1; - - gboolean is_recur_set; - - gint needs_decline : 1; - - WebKitDOMDocument *dom_document; - ItipPURI *puri; - - gchar *error; -}; - -#define TEXT_ROW_SENDER "text_row_sender" -#define TABLE_ROW_SUMMARY "table_row_summary" -#define TABLE_ROW_LOCATION "table_row_location" -#define TABLE_ROW_START_DATE "table_row_start_time" -#define TABLE_ROW_END_DATE "table_row_end_time" -#define TABLE_ROW_STATUS "table_row_status" -#define TABLE_ROW_COMMENT "table_row_comment" -#define TABLE_ROW_DESCRIPTION "table_row_description" -#define TABLE_ROW_RSVP_COMMENT "table_row_rsvp_comment" -#define TABLE_ROW_ESCB "table_row_escb" -#define TABLE_ROW_BUTTONS "table_row_buttons" -#define TABLE_ROW_ESCB_LABEL "table_row_escb_label" - -#define TABLE_BUTTONS "table_buttons" - -#define SELECT_ESOURCE "select_esource" -#define TEXTAREA_RSVP_COMMENT "textarea_rsvp_comment" - -#define CHECKBOX_RSVP "checkbox_rsvp" -#define CHECKBOX_RECUR "checkbox_recur" -#define CHECKBOX_UPDATE "checkbox_update" -#define CHECKBOX_FREE_TIME "checkbox_free_time" -#define CHECKBOX_KEEP_ALARM "checkbox_keep_alarm" -#define CHECKBOX_INHERIT_ALARM "checkbox_inherit_alarm" - -#define BUTTON_OPEN_CALENDAR "button_open_calendar" -#define BUTTON_DECLINE "button_decline" -#define BUTTON_DECLINE_ALL "button_decline_all" -#define BUTTON_ACCEPT "button_accept" -#define BUTTON_ACCEPT_ALL "button_accept_all" -#define BUTTON_TENTATIVE "button_tentative" -#define BUTTON_TENTATIVE_ALL "button_tentative_all" -#define BUTTON_SEND_INFORMATION "button_send_information" -#define BUTTON_UPDATE "button_update" -#define BUTTON_UPDATE_ATTENDEE_STATUS "button_update_attendee_status" -#define BUTTON_SAVE "button_save" - -#define TABLE_UPPER_ITIP_INFO "table_upper_itip_info" -#define TABLE_LOWER_ITIP_INFO "table_lower_itip_info" - -#define DIV_ITIP_CONTENT "div_itip_content" -#define DIV_ITIP_ERROR "div_itip_error" - -enum { - PROP_0, - PROP_EXTENSION_NAME, - PROP_REGISTRY -}; - -enum { - SOURCE_SELECTED, - RESPONSE, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -static void -format_date_and_time_x (struct tm *date_tm, - struct tm *current_tm, - gboolean use_24_hour_format, - gboolean show_midnight, - gboolean show_zero_seconds, - gboolean is_date, - gchar *buffer, - gint buffer_size) -{ - gchar *format; - struct tm tomorrow_tm, week_tm; - - /* Calculate a normalized "tomorrow" */ - tomorrow_tm = *current_tm; - /* Don't need this if date is in the past. Also, year assumption won't fail. */ - if (date_tm->tm_year >= current_tm->tm_year && tomorrow_tm.tm_mday == time_days_in_month (current_tm->tm_year + 1900, current_tm->tm_mon)) { - tomorrow_tm.tm_mday = 1; - if (tomorrow_tm.tm_mon == 11) { - tomorrow_tm.tm_mon = 1; - tomorrow_tm.tm_year++; - } else { - tomorrow_tm.tm_mon++; - } - } else { - tomorrow_tm.tm_mday++; - } - - /* Calculate a normalized "next seven days" */ - week_tm = *current_tm; - /* Don't need this if date is in the past. Also, year assumption won't fail. */ - if (date_tm->tm_year >= current_tm->tm_year && week_tm.tm_mday + 6 > time_days_in_month (date_tm->tm_year + 1900, date_tm->tm_mon)) { - week_tm.tm_mday = (week_tm.tm_mday + 6) % time_days_in_month (date_tm->tm_year + 1900, date_tm->tm_mon); - if (week_tm.tm_mon == 11) { - week_tm.tm_mon = 1; - week_tm.tm_year++; - } else { - week_tm.tm_mon++; - } - } else { - week_tm.tm_mday += 6; - } - - /* Today */ - if (date_tm->tm_mday == current_tm->tm_mday && - date_tm->tm_mon == current_tm->tm_mon && - date_tm->tm_year == current_tm->tm_year) { - if (is_date || (!show_midnight && date_tm->tm_hour == 0 - && date_tm->tm_min == 0 && date_tm->tm_sec == 0)) { - /* strftime format of a weekday and a date. */ - format = _("Today"); - } else if (use_24_hour_format) { - if (!show_zero_seconds && date_tm->tm_sec == 0) - /* strftime format of a time, - * in 24-hour format, without seconds. */ - format = _("Today %H:%M"); - else - /* strftime format of a time, - * in 24-hour format. */ - format = _("Today %H:%M:%S"); - } else { - if (!show_zero_seconds && date_tm->tm_sec == 0) - /* strftime format of a time, - * in 12-hour format, without seconds. */ - format = _("Today %l:%M %p"); - else - /* strftime format of a time, - * in 12-hour format. */ - format = _("Today %l:%M:%S %p"); - } - - /* Tomorrow */ - } else if (date_tm->tm_mday == tomorrow_tm.tm_mday && - date_tm->tm_mon == tomorrow_tm.tm_mon && - date_tm->tm_year == tomorrow_tm.tm_year) { - if (is_date || (!show_midnight && date_tm->tm_hour == 0 - && date_tm->tm_min == 0 && date_tm->tm_sec == 0)) { - /* strftime format of a weekday and a date. */ - format = _("Tomorrow"); - } else if (use_24_hour_format) { - if (!show_zero_seconds && date_tm->tm_sec == 0) - /* strftime format of a time, - * in 24-hour format, without seconds. */ - format = _("Tomorrow %H:%M"); - else - /* strftime format of a time, - * in 24-hour format. */ - format = _("Tomorrow %H:%M:%S"); - } else { - if (!show_zero_seconds && date_tm->tm_sec == 0) - /* strftime format of a time, - * in 12-hour format, without seconds. */ - format = _("Tomorrow %l:%M %p"); - else - /* strftime format of a time, - * in 12-hour format. */ - format = _("Tomorrow %l:%M:%S %p"); - } - - /* Within 6 days */ - } else if ((date_tm->tm_year >= current_tm->tm_year && - date_tm->tm_mon >= current_tm->tm_mon && - date_tm->tm_mday >= current_tm->tm_mday) && - - (date_tm->tm_year < week_tm.tm_year || - - (date_tm->tm_year == week_tm.tm_year && - date_tm->tm_mon < week_tm.tm_mon) || - - (date_tm->tm_year == week_tm.tm_year && - date_tm->tm_mon == week_tm.tm_mon && - date_tm->tm_mday < week_tm.tm_mday))) { - if (is_date || (!show_midnight && date_tm->tm_hour == 0 - && date_tm->tm_min == 0 && date_tm->tm_sec == 0)) { - /* strftime format of a weekday. */ - format = _("%A"); - } else if (use_24_hour_format) { - if (!show_zero_seconds && date_tm->tm_sec == 0) - /* strftime format of a weekday and a - * time, in 24-hour format, without seconds. */ - format = _("%A %H:%M"); - else - /* strftime format of a weekday and a - * time, in 24-hour format. */ - format = _("%A %H:%M:%S"); - } else { - if (!show_zero_seconds && date_tm->tm_sec == 0) - /* strftime format of a weekday and a - * time, in 12-hour format, without seconds. */ - format = _("%A %l:%M %p"); - else - /* strftime format of a weekday and a - * time, in 12-hour format. */ - format = _("%A %l:%M:%S %p"); - } - - /* This Year */ - } else if (date_tm->tm_year == current_tm->tm_year) { - if (is_date || (!show_midnight && date_tm->tm_hour == 0 - && date_tm->tm_min == 0 && date_tm->tm_sec == 0)) { - /* strftime format of a weekday and a date - * without a year. */ - format = _("%A, %B %e"); - } else if (use_24_hour_format) { - if (!show_zero_seconds && date_tm->tm_sec == 0) - /* strftime format of a weekday, a date - * without a year and a time, - * in 24-hour format, without seconds. */ - format = _("%A, %B %e %H:%M"); - else - /* strftime format of a weekday, a date without a year - * and a time, in 24-hour format. */ - format = _("%A, %B %e %H:%M:%S"); - } else { - if (!show_zero_seconds && date_tm->tm_sec == 0) - /* strftime format of a weekday, a date without a year - * and a time, in 12-hour format, without seconds. */ - format = _("%A, %B %e %l:%M %p"); - else - /* strftime format of a weekday, a date without a year - * and a time, in 12-hour format. */ - format = _("%A, %B %e %l:%M:%S %p"); - } - } else { - if (is_date || (!show_midnight && date_tm->tm_hour == 0 - && date_tm->tm_min == 0 && date_tm->tm_sec == 0)) { - /* strftime format of a weekday and a date. */ - format = _("%A, %B %e, %Y"); - } else if (use_24_hour_format) { - if (!show_zero_seconds && date_tm->tm_sec == 0) - /* strftime format of a weekday, a date and a - * time, in 24-hour format, without seconds. */ - format = _("%A, %B %e, %Y %H:%M"); - else - /* strftime format of a weekday, a date and a - * time, in 24-hour format. */ - format = _("%A, %B %e, %Y %H:%M:%S"); - } else { - if (!show_zero_seconds && date_tm->tm_sec == 0) - /* strftime format of a weekday, a date and a - * time, in 12-hour format, without seconds. */ - format = _("%A, %B %e, %Y %l:%M %p"); - else - /* strftime format of a weekday, a date and a - * time, in 12-hour format. */ - format = _("%A, %B %e, %Y %l:%M:%S %p"); - } - } - - /* strftime returns 0 if the string doesn't fit, and leaves the buffer - * undefined, so we set it to the empty string in that case. */ - if (e_utf8_strftime_fix_am_pm (buffer, buffer_size, format, date_tm) == 0) - buffer[0] = '\0'; -} - -static gchar * -dupe_first_bold (const gchar *format, - const gchar *first, - const gchar *second) -{ - gchar *f, *s, *res; - - f = g_markup_printf_escaped ("<b>%s</b>", first ? first : ""); - s = g_markup_escape_text (second ? second : "", -1); - - res = g_strdup_printf (format, f, s); - - g_free (f); - g_free (s); - - return res; -} - -static gchar * -set_calendar_sender_text (ItipView *view) -{ - ItipViewPrivate *priv; - const gchar *organizer, *attendee; - gchar *sender = NULL; - gchar *on_behalf_of = NULL; - - priv = view->priv; - - organizer = priv->organizer ? priv->organizer : _("An unknown person"); - attendee = priv->attendee ? priv->attendee : _("An unknown person"); - - /* The current account ID (i.e. the delegatee) is receiving a copy of the request/response. Here we ask the delegatee to respond/accept on behalf of the delegator. */ - if (priv->organizer && priv->proxy) - on_behalf_of = dupe_first_bold (_("Please respond on behalf of %s"), priv->proxy, NULL); - else if (priv->attendee && priv->proxy) - on_behalf_of = dupe_first_bold (_("Received on behalf of %s"), priv->proxy, NULL); - - switch (priv->mode) { - case ITIP_VIEW_MODE_PUBLISH: - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s has published the following meeting information:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s has published the following meeting information:"), organizer, NULL); - break; - case ITIP_VIEW_MODE_REQUEST: - /* FIXME is the delegator stuff handled correctly here? */ - if (priv->delegator) { - sender = dupe_first_bold (_("%s has delegated the following meeting to you:"), priv->delegator, NULL); - } else { - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s requests your presence at the following meeting:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s requests your presence at the following meeting:"), organizer, NULL); - } - break; - case ITIP_VIEW_MODE_ADD: - /* FIXME What text for this? */ - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s wishes to add to an existing meeting:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s wishes to add to an existing meeting:"), organizer, NULL); - break; - case ITIP_VIEW_MODE_REFRESH: - if (priv->attendee_sentby) - sender = dupe_first_bold (_("%s through %s wishes to receive the latest information for the following meeting:"), attendee, priv->attendee_sentby); - else - sender = dupe_first_bold (_("%s wishes to receive the latest information for the following meeting:"), attendee, NULL); - break; - case ITIP_VIEW_MODE_REPLY: - if (priv->attendee_sentby) - sender = dupe_first_bold (_("%s through %s has sent back the following meeting response:"), attendee, priv->attendee_sentby); - else - sender = dupe_first_bold (_("%s has sent back the following meeting response:"), attendee, NULL); - break; - case ITIP_VIEW_MODE_CANCEL: - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s has canceled the following meeting:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s has canceled the following meeting:"), organizer, NULL); - break; - case ITIP_VIEW_MODE_COUNTER: - if (priv->attendee_sentby) - sender = dupe_first_bold (_("%s through %s has proposed the following meeting changes."), attendee, priv->attendee_sentby); - else - sender = dupe_first_bold (_("%s has proposed the following meeting changes:"), attendee, NULL); - break; - case ITIP_VIEW_MODE_DECLINECOUNTER: - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s has declined the following meeting changes:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s has declined the following meeting changes:"), organizer, NULL); - break; - default: - break; - } - - if (sender && on_behalf_of) - sender = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL); - - g_free (on_behalf_of); - - return sender; -} - -static gchar * -set_tasklist_sender_text (ItipView *view) -{ - ItipViewPrivate *priv; - const gchar *organizer, *attendee; - gchar *sender = NULL; - gchar *on_behalf_of = NULL; - - priv = view->priv; - - organizer = priv->organizer ? priv->organizer : _("An unknown person"); - attendee = priv->attendee ? priv->attendee : _("An unknown person"); - - /* The current account ID (i.e. the delegatee) is receiving a copy of the request/response. Here we ask the delegatee to respond/accept on behalf of the delegator. */ - if (priv->organizer && priv->proxy) - on_behalf_of = dupe_first_bold (_("Please respond on behalf of %s"), priv->proxy, NULL); - else if (priv->attendee && priv->proxy) - on_behalf_of = dupe_first_bold (_("Received on behalf of %s"), priv->proxy, NULL); - - switch (priv->mode) { - case ITIP_VIEW_MODE_PUBLISH: - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s has published the following task:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s has published the following task:"), organizer, NULL); - break; - case ITIP_VIEW_MODE_REQUEST: - /* FIXME is the delegator stuff handled correctly here? */ - if (priv->delegator) { - sender = dupe_first_bold (_("%s requests the assignment of %s to the following task:"), organizer, priv->delegator); - } else { - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s has assigned you a task:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s has assigned you a task:"), organizer, NULL); - } - break; - case ITIP_VIEW_MODE_ADD: - /* FIXME What text for this? */ - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s wishes to add to an existing task:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s wishes to add to an existing task:"), organizer, NULL); - break; - case ITIP_VIEW_MODE_REFRESH: - if (priv->attendee_sentby) - sender = dupe_first_bold (_("%s through %s wishes to receive the latest information for the following assigned task:"), attendee, priv->attendee_sentby); - else - sender = dupe_first_bold (_("%s wishes to receive the latest information for the following assigned task:"), attendee, NULL); - break; - case ITIP_VIEW_MODE_REPLY: - if (priv->attendee_sentby) - sender = dupe_first_bold (_("%s through %s has sent back the following assigned task response:"), attendee, priv->attendee_sentby); - else - sender = dupe_first_bold (_("%s has sent back the following assigned task response:"), attendee, NULL); - break; - case ITIP_VIEW_MODE_CANCEL: - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s has canceled the following assigned task:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s has canceled the following assigned task:"), organizer, NULL); - break; - case ITIP_VIEW_MODE_COUNTER: - if (priv->attendee_sentby) - sender = dupe_first_bold (_("%s through %s has proposed the following task assignment changes:"), attendee, priv->attendee_sentby); - else - sender = dupe_first_bold (_("%s has proposed the following task assignment changes:"), attendee, NULL); - break; - case ITIP_VIEW_MODE_DECLINECOUNTER: - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s has declined the following assigned task:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s has declined the following assigned task:"), organizer, NULL); - break; - default: - break; - } - - if (sender && on_behalf_of) - sender = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL); - - g_free (on_behalf_of); - - return sender; -} - -static gchar * -set_journal_sender_text (ItipView *view) -{ - ItipViewPrivate *priv; - const gchar *organizer; - gchar *sender = NULL; - gchar *on_behalf_of = NULL; - - priv = view->priv; - - organizer = priv->organizer ? priv->organizer : _("An unknown person"); - - /* The current account ID (i.e. the delegatee) is receiving a copy of the request/response. Here we ask the delegatee to respond/accept on behalf of the delegator. */ - if (priv->organizer && priv->proxy) - on_behalf_of = dupe_first_bold (_("Please respond on behalf of %s"), priv->proxy, NULL); - else if (priv->attendee && priv->proxy) - on_behalf_of = dupe_first_bold (_("Received on behalf of %s"), priv->proxy, NULL); - - switch (priv->mode) { - case ITIP_VIEW_MODE_PUBLISH: - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s has published the following memo:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s has published the following memo:"), organizer, NULL); - break; - case ITIP_VIEW_MODE_ADD: - /* FIXME What text for this? */ - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s wishes to add to an existing memo:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s wishes to add to an existing memo:"), organizer, NULL); - break; - case ITIP_VIEW_MODE_CANCEL: - if (priv->organizer_sentby) - sender = dupe_first_bold (_("%s through %s has canceled the following shared memo:"), organizer, priv->organizer_sentby); - else - sender = dupe_first_bold (_("%s has canceled the following shared memo:"), organizer, NULL); - break; - default: - break; - } - - if (sender && on_behalf_of) - sender = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL); - - g_free (on_behalf_of); - - return sender; -} - -static void -set_sender_text (ItipView *view) -{ - ItipViewPrivate *priv; - priv = view->priv; - - switch (priv->type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - priv->sender = set_calendar_sender_text (view); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - priv->sender = set_tasklist_sender_text (view); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - priv->sender = set_journal_sender_text (view); - break; - default: - priv->sender = NULL; - break; - } - - if (priv->sender && priv->dom_document) { - WebKitDOMElement *div; - - div = webkit_dom_document_get_element_by_id ( - priv->dom_document, TEXT_ROW_SENDER); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (div), priv->sender, NULL); - } -} - -static void -update_start_end_times (ItipView *view) -{ - ItipViewPrivate *priv; - WebKitDOMElement *row, *col; - gchar buffer[256]; - time_t now; - struct tm *now_tm; - - priv = view->priv; - - now = time (NULL); - now_tm = localtime (&now); - - if (priv->start_label) - g_free (priv->start_label); - if (priv->end_label) - g_free (priv->end_label); - - #define is_same(_member) (priv->start_tm->_member == priv->end_tm->_member) - if (priv->start_tm && priv->end_tm && priv->start_tm_is_date && priv->end_tm_is_date - && is_same (tm_mday) && is_same (tm_mon) && is_same (tm_year)) { - /* it's an all day event in one particular day */ - format_date_and_time_x (priv->start_tm, now_tm, FALSE, TRUE, FALSE, priv->start_tm_is_date, buffer, 256); - priv->start_label = g_strdup (buffer); - priv->start_header = _("All day:"); - priv->end_header = NULL; - priv->end_label = NULL; - } else { - if (priv->start_tm) { - format_date_and_time_x (priv->start_tm, now_tm, FALSE, TRUE, FALSE, priv->start_tm_is_date, buffer, 256); - priv->start_header = priv->start_tm_is_date ? _("Start day:") : _("Start time:"); - priv->start_label = g_strdup (buffer); - } else { - priv->start_header = NULL; - priv->start_label = NULL; - } - - if (priv->end_tm) { - format_date_and_time_x (priv->end_tm, now_tm, FALSE, TRUE, FALSE, priv->end_tm_is_date, buffer, 256); - priv->end_header = priv->end_tm_is_date ? _("End day:") : _("End time:"); - priv->end_label = g_strdup (buffer); - } else { - priv->end_header = NULL; - priv->end_label = NULL; - } - } - #undef is_same - - if (priv->dom_document) { - row = webkit_dom_document_get_element_by_id ( - priv->dom_document, TABLE_ROW_START_DATE); - if (priv->start_header && priv->start_label) { - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (row), FALSE); - - col = webkit_dom_element_get_first_element_child (row); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (col), priv->start_header, NULL); - - col = webkit_dom_element_get_last_element_child (row); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (col), priv->start_label, NULL); - } else { - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (row), TRUE); - } - - row = webkit_dom_document_get_element_by_id ( - priv->dom_document, TABLE_ROW_END_DATE); - if (priv->end_header && priv->end_label) { - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (row), FALSE); - - col = webkit_dom_element_get_first_element_child (row); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (col), priv->end_header, NULL); - - col = webkit_dom_element_get_last_element_child (row); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (col), priv->end_label, NULL); - } else { - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (row), TRUE); - } - } -} - -static void -button_clicked_cb (WebKitDOMElement *element, - WebKitDOMEvent *event, - gpointer data) -{ - ItipViewResponse response; - gchar *responseStr; - - responseStr = webkit_dom_html_button_element_get_value ( - WEBKIT_DOM_HTML_BUTTON_ELEMENT (element)); - - response = atoi (responseStr); - - //d(printf("Clicked btton %d\n", response)); - g_signal_emit (G_OBJECT (data), signals[RESPONSE], 0, response); -} - -static void -rsvp_toggled_cb (WebKitDOMHTMLInputElement *input, - WebKitDOMEvent *event, - gpointer data) -{ - WebKitDOMElement *el; - - ItipView *view = data; - gboolean rsvp; - - rsvp = webkit_dom_html_input_element_get_checked (input); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TEXTAREA_RSVP_COMMENT); - webkit_dom_html_text_area_element_set_disabled ( - WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !rsvp); -} - -static void -recur_toggled_cb (WebKitDOMHTMLInputElement *input, - WebKitDOMEvent *event, - gpointer data) -{ - ItipView *view = data; - - itip_view_set_mode (view, view->priv->mode); -} - -/* - alarm_check_toggled_cb - check1 was changed, so make the second available based on state of the first check. -*/ -static void -alarm_check_toggled_cb (WebKitDOMHTMLInputElement *check1, - WebKitDOMEvent *event, - ItipView *view) -{ - WebKitDOMElement *check2; - gchar *id = webkit_dom_html_element_get_id (WEBKIT_DOM_HTML_ELEMENT (check1)); - - if (g_strcmp0 (id, CHECKBOX_INHERIT_ALARM)) { - check2 = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_KEEP_ALARM); - } else { - check2 = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_INHERIT_ALARM); - } - - g_free (id); - - webkit_dom_html_input_element_set_disabled ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (check2), - (webkit_dom_html_element_get_hidden ( - WEBKIT_DOM_HTML_ELEMENT (check1)) && - webkit_dom_html_input_element_get_checked (check1))); -} - -static void -source_changed_cb (WebKitDOMElement *select, - WebKitDOMEvent *event, - ItipView *view) -{ - ESource *source; - - source = itip_view_ref_source (view); - - d(printf("Source changed to '%s'\n", e_source_get_display_name (source))); - g_signal_emit (view, signals[SOURCE_SELECTED], 0, source); - - g_object_unref (source); -} - -static gchar * -parse_html_mnemonics (const gchar *label, - gchar **access_key) -{ - const gchar *pos = NULL; - gchar ak = 0; - GString *html_label = NULL; - - pos = strstr (label, "_"); - if (pos != NULL) { - ak = pos[1]; - - /* Convert to uppercase */ - if (ak >= 'a') - ak = ak - 32; - - html_label = g_string_new (""); - g_string_append_len (html_label, label, pos - label); - g_string_append_printf (html_label, "<u>%c</u>", pos[1]); - g_string_append (html_label, &pos[2]); - - if (access_key) { - if (ak) { - *access_key = g_strdup_printf ("%c", ak); - } else { - *access_key = NULL; - } - } - - } else { - html_label = g_string_new (label); - - if (access_key) { - *access_key = NULL; - } - } - - return g_string_free (html_label, FALSE); -} - -static void -append_checkbox_table_row (GString *buffer, - const gchar *name, - const gchar *label) -{ - gchar *access_key, *html_label; - - html_label = parse_html_mnemonics (label, &access_key); - - g_string_append_printf ( - buffer, - "<tr id=\"table_row_%s\" hidden=\"\"><td colspan=\"2\">" - "<input type=\"checkbox\" name=\"%s\" id=\"%s\" value=\"%s\" >" - "<label for=\"%s\" accesskey=\"%s\">%s</label>" - "</td></tr>\n", - name, name, name, name, name, - access_key ? access_key : "", html_label); - - g_free (html_label); - - if (access_key) - g_free (access_key); -} - -static void -append_text_table_row (GString *buffer, - const gchar *id, - const gchar *label, - const gchar *value) -{ - if (label && *label) { - - g_string_append_printf (buffer, - "<tr id=\"%s\" %s><th>%s</th><td>%s</td></tr>\n", - id, (value && *value) ? "" : "hidden=\"\"", label, value); - - } else { - - g_string_append_printf ( - buffer, - "<tr id=\"%s\" hidden=\"\"><td colspan=\"2\"></td></tr>\n", - id); - - } -} - -static void -append_info_item_row (ItipView *view, - const gchar *table_id, - ItipViewInfoItem *item) -{ - WebKitDOMElement *table; - WebKitDOMHTMLElement *row, *cell; - const gchar *icon_name; - gchar *id; - - table = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, table_id); - row = webkit_dom_html_table_element_insert_row ( - WEBKIT_DOM_HTML_TABLE_ELEMENT (table), -1, NULL); - - id = g_strdup_printf ("%s_row_%d", table_id, item->id); - webkit_dom_html_element_set_id (row, id); - g_free (id); - - switch (item->type) { - case ITIP_VIEW_INFO_ITEM_TYPE_INFO: - icon_name = GTK_STOCK_DIALOG_INFO; - break; - case ITIP_VIEW_INFO_ITEM_TYPE_WARNING: - icon_name = GTK_STOCK_DIALOG_WARNING; - break; - case ITIP_VIEW_INFO_ITEM_TYPE_ERROR: - icon_name = GTK_STOCK_DIALOG_ERROR; - break; - case ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS: - icon_name = GTK_STOCK_FIND; - break; - case ITIP_VIEW_INFO_ITEM_TYPE_NONE: - default: - icon_name = NULL; - } - - cell = webkit_dom_html_table_row_element_insert_cell ( - (WebKitDOMHTMLTableRowElement *) row, -1, NULL); - - if (icon_name) { - WebKitDOMElement *image; - gchar *icon_uri; - - image = webkit_dom_document_create_element ( - view->priv->dom_document, "IMG", NULL); - - icon_uri = g_strdup_printf ("gtk-stock://%s", icon_name); - webkit_dom_html_image_element_set_src ( - WEBKIT_DOM_HTML_IMAGE_ELEMENT (image), icon_uri); - g_free (icon_uri); - - webkit_dom_node_append_child ( - WEBKIT_DOM_NODE (cell), - WEBKIT_DOM_NODE (image), - NULL); - } - - cell = webkit_dom_html_table_row_element_insert_cell ( - (WebKitDOMHTMLTableRowElement *) row, -1, NULL); - - webkit_dom_html_element_set_inner_html (cell, item->message, NULL); - - d(printf("Added row %s_row_%d ('%s')\n", table_id, item->id, item->message)); -} - -static void -remove_info_item_row (ItipView *view, - const gchar *table_id, - guint id) -{ - WebKitDOMElement *row; - gchar *row_id; - - row_id = g_strdup_printf ("%s_row_%d", table_id, id); - row = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, row_id); - g_free (row_id); - - webkit_dom_node_remove_child ( - webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (row)), - WEBKIT_DOM_NODE (row), - NULL); - - d(printf("Removed row %s_row_%d\n", table_id, id)); -} - -static void -buttons_table_write_button (GString *buffer, - const gchar *name, - const gchar *label, - const gchar *icon, - ItipViewResponse response) -{ - gchar *access_key, *html_label; - - html_label = parse_html_mnemonics (label, &access_key); - - g_string_append_printf ( - buffer, - "<td><button type=\"button\" name=\"%s\" value=\"%d\" id=\"%s\" accesskey=\"%s\" hidden>" - "<div><img src=\"gtk-stock://%s?size=%d\"> <span>%s</span></div>" - "</button></td>\n", - name, response, name, access_key ? access_key : "" , icon, - GTK_ICON_SIZE_BUTTON, html_label); - - g_free (html_label); - - if (access_key) - g_free (access_key); -} - -static void -append_buttons_table (GString *buffer) -{ - g_string_append (buffer, - "<table class=\"itip buttons\" border=\"0\" " - "id=\"" TABLE_BUTTONS "\" cellspacing=\"6\" " - "cellpadding=\"0\" >" - "<tr id=\"" TABLE_ROW_BUTTONS "\">"); - - /* Everything gets the open button */ - buttons_table_write_button ( - buffer, BUTTON_OPEN_CALENDAR, _("_Open Calendar"), - GTK_STOCK_JUMP_TO, ITIP_VIEW_RESPONSE_OPEN); - buttons_table_write_button ( - buffer, BUTTON_DECLINE_ALL, _("_Decline all"), - GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE); - buttons_table_write_button ( - buffer, BUTTON_DECLINE, _("_Decline"), - GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE); - buttons_table_write_button ( - buffer, BUTTON_TENTATIVE_ALL, _("_Tentative all"), - GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE); - buttons_table_write_button ( - buffer, BUTTON_TENTATIVE, _("_Tentative"), - GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE); - buttons_table_write_button ( - buffer, BUTTON_ACCEPT_ALL, _("A_ccept all"), - GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT); - buttons_table_write_button ( - buffer, BUTTON_ACCEPT, _("A_ccept"), - GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT); - buttons_table_write_button ( - buffer, BUTTON_SEND_INFORMATION, _("_Send Information"), - GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_REFRESH); - buttons_table_write_button ( - buffer, BUTTON_UPDATE_ATTENDEE_STATUS, _("_Update Attendee Status"), - GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_UPDATE); - buttons_table_write_button ( - buffer, BUTTON_UPDATE, _("_Update"), - GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_CANCEL); - - g_string_append (buffer, "</tr></table>"); -} - -static void -itip_view_rebuild_source_list (ItipView *view) -{ - ESourceRegistry *registry; - WebKitDOMElement *select; - GList *list, *link; - const gchar *extension_name; - - d(printf("Assigning a new source list!\n")); - - if (!view->priv->dom_document) - return; - - registry = itip_view_get_registry (view); - extension_name = itip_view_get_extension_name (view); - - select = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, SELECT_ESOURCE); - - while (webkit_dom_node_has_child_nodes (WEBKIT_DOM_NODE (select))) { - webkit_dom_node_remove_child ( - WEBKIT_DOM_NODE (select), - webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (select)), - NULL); - } - - if (extension_name == NULL) - return; - - list = e_source_registry_list_sources (registry, extension_name); - - for (link = list; link != NULL; link = g_list_next (link)) { - ESource *source = E_SOURCE (link->data); - WebKitDOMElement *option; - - option = webkit_dom_document_create_element ( - view->priv->dom_document, "OPTION", NULL); - webkit_dom_html_option_element_set_value ( - WEBKIT_DOM_HTML_OPTION_ELEMENT (option), - e_source_get_uid (source)); - webkit_dom_html_option_element_set_label ( - WEBKIT_DOM_HTML_OPTION_ELEMENT (option), - e_source_get_display_name (source)); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (option), - e_source_get_display_name (source), NULL); - webkit_dom_html_element_set_class_name ( - WEBKIT_DOM_HTML_ELEMENT (option), "calendar"); - - webkit_dom_node_append_child ( - WEBKIT_DOM_NODE (select), - WEBKIT_DOM_NODE (option), - NULL); - } - - g_list_free_full (list, (GDestroyNotify) g_object_unref); - - source_changed_cb (select, NULL, view); -} - -static void -itip_view_source_added_cb (ESourceRegistry *registry, - ESource *source, - ItipView *view) -{ - const gchar *extension_name; - - extension_name = itip_view_get_extension_name (view); - - /* If we don't have an extension name set - * yet then disregard the signal emission. */ - if (extension_name == NULL) - return; - - if (e_source_has_extension (source, extension_name)) - itip_view_rebuild_source_list (view); -} - -static void -itip_view_source_removed_cb (ESourceRegistry *registry, - ESource *source, - ItipView *view) -{ - const gchar *extension_name; - - extension_name = itip_view_get_extension_name (view); - - /* If we don't have an extension name set - * yet then disregard the signal emission. */ - if (extension_name == NULL) - return; - - if (e_source_has_extension (source, extension_name)) - itip_view_rebuild_source_list (view); -} - -static void -itip_view_set_registry (ItipView *view, - ESourceRegistry *registry) -{ - g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); - g_return_if_fail (view->priv->registry == NULL); - - view->priv->registry = g_object_ref (registry); -} - -static void -itip_view_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_EXTENSION_NAME: - itip_view_set_extension_name ( - ITIP_VIEW (object), - g_value_get_string (value)); - return; - - case PROP_REGISTRY: - itip_view_set_registry ( - ITIP_VIEW (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -itip_view_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_EXTENSION_NAME: - g_value_set_string ( - value, itip_view_get_extension_name ( - ITIP_VIEW (object))); - return; - - case PROP_REGISTRY: - g_value_set_object ( - value, itip_view_get_registry ( - ITIP_VIEW (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -itip_view_dispose (GObject *object) -{ - ItipViewPrivate *priv; - - priv = ITIP_VIEW_GET_PRIVATE (object); - - if (priv->registry != NULL) { - g_signal_handler_disconnect ( - priv->registry, priv->source_added_id); - g_signal_handler_disconnect ( - priv->registry, priv->source_removed_id); - g_object_unref (priv->registry); - priv->registry = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (itip_view_parent_class)->dispose (object); -} - -static void -itip_view_finalize (GObject *object) -{ - ItipViewPrivate *priv; - GSList *iter; - - priv = ITIP_VIEW_GET_PRIVATE (object); - - d(printf("Itip view finalized!\n")); - - g_free (priv->extension_name); - g_free (priv->sender); - g_free (priv->organizer); - g_free (priv->organizer_sentby); - g_free (priv->delegator); - g_free (priv->attendee); - g_free (priv->attendee_sentby); - g_free (priv->proxy); - g_free (priv->summary); - g_free (priv->location); - g_free (priv->status); - g_free (priv->comment); - g_free (priv->start_tm); - g_free (priv->start_label); - g_free (priv->end_tm); - g_free (priv->end_label); - g_free (priv->description); - g_free (priv->error); - - for (iter = priv->lower_info_items; iter; iter = iter->next) { - ItipViewInfoItem *item = iter->data; - g_free (item->message); - g_free (item); - } - - g_slist_free (priv->lower_info_items); - - for (iter = priv->upper_info_items; iter; iter = iter->next) { - ItipViewInfoItem *item = iter->data; - g_free (item->message); - g_free (item); - } - - g_slist_free (priv->upper_info_items); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (itip_view_parent_class)->finalize (object); -} - -static void -itip_view_constructed (GObject *object) -{ - ItipView *view; - ESourceRegistry *registry; - - view = ITIP_VIEW (object); - registry = itip_view_get_registry (view); - - view->priv->source_added_id = g_signal_connect ( - registry, "source-added", - G_CALLBACK (itip_view_source_added_cb), view); - - view->priv->source_removed_id = g_signal_connect ( - registry, "source-removed", - G_CALLBACK (itip_view_source_removed_cb), view); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (itip_view_parent_class)->constructed (object); -} - -static void -itip_view_class_init (ItipViewClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ItipViewPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = itip_view_set_property; - object_class->get_property = itip_view_get_property; - object_class->dispose = itip_view_dispose; - object_class->finalize = itip_view_finalize; - object_class->constructed = itip_view_constructed; - - g_object_class_install_property ( - object_class, - PROP_REGISTRY, - g_param_spec_string ( - "extension-name", - "Extension Name", - "Show only data sources with this extension", - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_REGISTRY, - g_param_spec_object ( - "registry", - "Registry", - "Data source registry", - E_TYPE_SOURCE_REGISTRY, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - signals[SOURCE_SELECTED] = g_signal_new ( - "source_selected", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ItipViewClass, source_selected), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - E_TYPE_SOURCE); - - signals[RESPONSE] = g_signal_new ( - "response", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ItipViewClass, response), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); -} - -static void -itip_view_init (ItipView *view) -{ - view->priv = ITIP_VIEW_GET_PRIVATE (view); -} - -ItipView * -itip_view_new (ItipPURI *puri, - ESourceRegistry *registry) -{ - ItipView *view; - - view = g_object_new (ITIP_TYPE_VIEW, "registry", registry, NULL); - view->priv->puri = puri; - - return view; -} - -void -itip_view_write (GString *buffer) -{ - g_string_append (buffer, - "<html>\n" - "<head>\n" - "<title>ITIP</title>\n" - "<link type=\"text/css\" rel=\"stylesheet\" href=\"evo-file://" EVOLUTION_PRIVDATADIR "/theme/webview.css\" />\n" - "</head>\n" - "<body>\n"); - - g_string_append_printf (buffer, - "<img src=\"gtk-stock://%s?size=%d\" class=\"itip icon\" />\n", - MEETING_ICON, GTK_ICON_SIZE_BUTTON); - - g_string_append (buffer, - "<div class=\"itip content\" id=\"" DIV_ITIP_CONTENT "\">\n"); - - /* The first section listing the sender */ - /* FIXME What to do if the send and organizer do not match */ - g_string_append (buffer, - "<div id=\"" TEXT_ROW_SENDER "\" class=\"itip sender\"></div>\n"); - - g_string_append (buffer, "<hr>\n"); - - /* Elementary event information */ - g_string_append (buffer, - "<table class=\"itip table\" border=\"0\" " - "cellspacing=\"5\" cellpadding=\"0\">\n"); - - append_text_table_row (buffer, TABLE_ROW_SUMMARY, NULL, NULL); - append_text_table_row (buffer, TABLE_ROW_LOCATION, _("Location:"), NULL); - append_text_table_row (buffer, TABLE_ROW_START_DATE, _("Start time:"), NULL); - append_text_table_row (buffer, TABLE_ROW_END_DATE, _("End time:"), NULL); - append_text_table_row (buffer, TABLE_ROW_STATUS, _("Status:"), NULL); - append_text_table_row (buffer, TABLE_ROW_COMMENT, _("Comment:"), NULL); - - g_string_append (buffer, "</table>\n"); - - /* Upper Info items */ - g_string_append (buffer, - "<table class=\"itip info\" id=\"" TABLE_UPPER_ITIP_INFO "\" border=\"0\" " - "cellspacing=\"5\" cellpadding=\"0\">"); - - /* Description */ - g_string_append (buffer, - "<div id=\"" TABLE_ROW_DESCRIPTION "\" class=\"itip description\" hidden=\"\"></div>\n"); - - g_string_append (buffer, "<hr>\n"); - - /* Lower Info items */ - g_string_append (buffer, - "<table class=\"itip info\" id=\"" TABLE_LOWER_ITIP_INFO "\" border=\"0\" " - "cellspacing=\"5\" cellpadding=\"0\">"); - - g_string_append (buffer, - "<table class=\"itip table\" border=\"0\" " - "cellspacing=\"5\" cellpadding=\"0\">\n"); - - g_string_append (buffer, - "<tr id=\"" TABLE_ROW_ESCB "\" hidden=\"\""">" - "<th><label id=\"" TABLE_ROW_ESCB_LABEL "\" for=\"" SELECT_ESOURCE "\"></label></th>" - "<td><select name=\"" SELECT_ESOURCE "\" id=\"" SELECT_ESOURCE "\"></select></td>" - "</tr>\n"); - - /* RSVP area */ - append_checkbox_table_row (buffer, CHECKBOX_RSVP, _("Send reply to sender")); - - /* Comments */ - g_string_append_printf (buffer, - "<tr id=\"" TABLE_ROW_RSVP_COMMENT "\" hidden=\"\">" - "<th>%s</th>" - "<td><textarea name=\"" TEXTAREA_RSVP_COMMENT "\" " - "id=\"" TEXTAREA_RSVP_COMMENT "\" " - "rows=\"3\" cols=\"40\" disabled=\"\">" - "</textarea></td>\n" - "</tr>\n", - _("Comment:")); - - /* Updates */ - append_checkbox_table_row (buffer, CHECKBOX_UPDATE, _("Send _updates to attendees")); - - /* The recurrence check button */ - append_checkbox_table_row (buffer, CHECKBOX_RECUR, _("_Apply to all instances")); - append_checkbox_table_row (buffer, CHECKBOX_FREE_TIME, _("Show time as _free")); - append_checkbox_table_row (buffer, CHECKBOX_KEEP_ALARM, _("_Preserve my reminder")); - append_checkbox_table_row (buffer, CHECKBOX_INHERIT_ALARM, _("_Inherit reminder")); - - g_string_append (buffer, "</table>\n"); - - /* Buttons table */ - append_buttons_table (buffer); - - /* <div class="itip content" > */ - g_string_append (buffer, "</div>\n"); - - g_string_append (buffer, "<div class=\"itip error\" id=\"" DIV_ITIP_ERROR "\"></div>"); - - g_string_append (buffer, "</body></html>"); -} - -void -itip_view_write_for_printing (ItipView *view, - GString *buffer) -{ - if (view->priv->error && *view->priv->error) { - g_string_append (buffer, view->priv->error); - return; - } - - g_string_append (buffer, - "<div class=\"itip print_content\" id=\"" DIV_ITIP_CONTENT "\">\n"); - - /* The first section listing the sender */ - /* FIXME What to do if the send and organizer do not match */ - g_string_append_printf (buffer, - "<div id=\"" TEXT_ROW_SENDER "\" class=\"itip sender\">%s</div>\n", - view->priv->sender ? view->priv->sender : ""); - - g_string_append (buffer, "<hr>\n"); - - /* Elementary event information */ - g_string_append (buffer, - "<table class=\"itip table\" border=\"0\" " - "cellspacing=\"5\" cellpadding=\"0\">\n"); - - append_text_table_row ( - buffer, TABLE_ROW_SUMMARY, - NULL, view->priv->summary); - append_text_table_row ( - buffer, TABLE_ROW_LOCATION, - _("Location:"), view->priv->location); - append_text_table_row ( - buffer, TABLE_ROW_START_DATE, - view->priv->start_header, view->priv->start_label); - append_text_table_row ( - buffer, TABLE_ROW_END_DATE, - view->priv->end_header, view->priv->end_label); - append_text_table_row ( - buffer, TABLE_ROW_STATUS, - _("Status:"), view->priv->status); - append_text_table_row ( - buffer, TABLE_ROW_COMMENT, - _("Comment:"), view->priv->comment); - - g_string_append (buffer, "</table>\n"); - - /* Description */ - g_string_append_printf ( - buffer, - "<div id=\"" TABLE_ROW_DESCRIPTION "\" " - "class=\"itip description\" %s>%s</div>\n", - view->priv->description ? "" : "hidden=\"\"", view->priv->description); - - g_string_append (buffer, "</div>"); -} - -void -itip_view_create_dom_bindings (ItipView *view, - WebKitDOMElement *element) -{ - WebKitDOMElement *el; - WebKitDOMDocument *doc; - - doc = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element)); - view->priv->dom_document = doc; - - el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_RECUR); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (recur_toggled_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_RSVP); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (rsvp_toggled_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_INHERIT_ALARM); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (alarm_check_toggled_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_KEEP_ALARM); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (alarm_check_toggled_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, BUTTON_OPEN_CALENDAR); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (button_clicked_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, BUTTON_ACCEPT); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (button_clicked_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, BUTTON_ACCEPT_ALL); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (button_clicked_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, BUTTON_TENTATIVE); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (button_clicked_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, BUTTON_TENTATIVE_ALL); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (button_clicked_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, BUTTON_DECLINE); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (button_clicked_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, BUTTON_DECLINE_ALL); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (button_clicked_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, BUTTON_UPDATE); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (button_clicked_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, BUTTON_UPDATE_ATTENDEE_STATUS); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (button_clicked_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, BUTTON_SEND_INFORMATION); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (button_clicked_cb), FALSE, view); - } - - el = webkit_dom_document_get_element_by_id (doc, SELECT_ESOURCE); - if (el) { - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "change", - G_CALLBACK (source_changed_cb), FALSE, view); - } -} - -ItipPURI * -itip_view_get_puri (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->puri; -} - -ESourceRegistry * -itip_view_get_registry (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->registry; -} - -const gchar * -itip_view_get_extension_name (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->extension_name; -} - -void -itip_view_set_extension_name (ItipView *view, - const gchar *extension_name) -{ - g_return_if_fail (ITIP_IS_VIEW (view)); - - /* Avoid unnecessary rebuilds. */ - if (g_strcmp0 (extension_name, view->priv->extension_name) == 0) - return; - - g_free (view->priv->extension_name); - view->priv->extension_name = g_strdup (extension_name); - - g_object_notify (G_OBJECT (view), "extension-name"); - - itip_view_rebuild_source_list (view); -} - -static void -show_button (ItipView *view, - const gchar *id) -{ - WebKitDOMElement *button; - - button = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, id); - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (button), FALSE); -} - -void -itip_view_set_mode (ItipView *view, - ItipViewMode mode) -{ - WebKitDOMElement *row, *cell; - WebKitDOMElement *button; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - view->priv->mode = mode; - - set_sender_text (view); - - if (!view->priv->dom_document) - return; - - row = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TABLE_ROW_BUTTONS); - cell = webkit_dom_element_get_first_element_child (row); - do { - button = webkit_dom_element_get_first_element_child (cell); - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (button), TRUE); - } while ((cell = webkit_dom_element_get_next_element_sibling (cell)) != NULL); - - view->priv->is_recur_set = itip_view_get_recur_check_state (view); - - /* Always visible */ - show_button (view, BUTTON_OPEN_CALENDAR); - - switch (mode) { - case ITIP_VIEW_MODE_PUBLISH: - if (view->priv->needs_decline) { - show_button (view, BUTTON_DECLINE); - } - show_button (view, BUTTON_ACCEPT); - break; - case ITIP_VIEW_MODE_REQUEST: - show_button (view, view->priv->is_recur_set ? BUTTON_DECLINE_ALL : BUTTON_DECLINE); - show_button (view, view->priv->is_recur_set ? BUTTON_TENTATIVE_ALL : BUTTON_TENTATIVE); - show_button (view, view->priv->is_recur_set ? BUTTON_ACCEPT_ALL : BUTTON_ACCEPT); - break; - case ITIP_VIEW_MODE_ADD: - if (view->priv->type != E_CAL_CLIENT_SOURCE_TYPE_MEMOS) { - show_button (view, BUTTON_DECLINE); - show_button (view, BUTTON_TENTATIVE); - } - show_button (view, BUTTON_ACCEPT); - break; - case ITIP_VIEW_MODE_REFRESH: - show_button (view, BUTTON_SEND_INFORMATION); - break; - case ITIP_VIEW_MODE_REPLY: - show_button (view, BUTTON_UPDATE_ATTENDEE_STATUS); - break; - case ITIP_VIEW_MODE_CANCEL: - show_button (view, BUTTON_UPDATE); - break; - case ITIP_VIEW_MODE_COUNTER: - case ITIP_VIEW_MODE_DECLINECOUNTER: - show_button (view, BUTTON_DECLINE); - show_button (view, BUTTON_TENTATIVE); - show_button (view, BUTTON_ACCEPT); - break; - default: - break; - } -} - -ItipViewMode -itip_view_get_mode (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), ITIP_VIEW_MODE_NONE); - - return view->priv->mode; -} - -void -itip_view_set_item_type (ItipView *view, - ECalClientSourceType type) -{ - WebKitDOMElement *label; - const gchar *header; - gchar *access_key, *html_label; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - view->priv->type = type; - - if (!view->priv->dom_document) - return; - - label = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TABLE_ROW_ESCB_LABEL); - - switch (view->priv->type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - header = _("_Calendar:"); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - header = _("_Tasks:"); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - header = _("_Memos:"); - break; - default: - header = NULL; - break; - } - - if (!header) { - set_sender_text (view); - return; - } - - html_label = parse_html_mnemonics (header, &access_key); - - webkit_dom_html_element_set_access_key ( - WEBKIT_DOM_HTML_ELEMENT (label), access_key); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (label), html_label, NULL); - - g_free (html_label); - - if (access_key) - g_free (access_key); - - set_sender_text (view); -} - -ECalClientSourceType -itip_view_get_item_type (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), ITIP_VIEW_MODE_NONE); - - return view->priv->type; -} - -void -itip_view_set_organizer (ItipView *view, - const gchar *organizer) -{ - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (view->priv->organizer) - g_free (view->priv->organizer); - - view->priv->organizer = e_utf8_ensure_valid (organizer); - - set_sender_text (view); -} - -const gchar * -itip_view_get_organizer (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->organizer; -} - -void -itip_view_set_organizer_sentby (ItipView *view, - const gchar *sentby) -{ - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (view->priv->organizer_sentby) - g_free (view->priv->organizer_sentby); - - view->priv->organizer_sentby = e_utf8_ensure_valid (sentby); - - set_sender_text (view); -} - -const gchar * -itip_view_get_organizer_sentby (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->organizer_sentby; -} - -void -itip_view_set_attendee (ItipView *view, - const gchar *attendee) -{ - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (view->priv->attendee) - g_free (view->priv->attendee); - - view->priv->attendee = e_utf8_ensure_valid (attendee); - - set_sender_text (view); -} - -const gchar * -itip_view_get_attendee (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->attendee; -} - -void -itip_view_set_attendee_sentby (ItipView *view, - const gchar *sentby) -{ - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (view->priv->attendee_sentby) - g_free (view->priv->attendee_sentby); - - view->priv->attendee_sentby = e_utf8_ensure_valid (sentby); - - set_sender_text (view); -} - -const gchar * -itip_view_get_attendee_sentby (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->attendee_sentby; -} - -void -itip_view_set_proxy (ItipView *view, - const gchar *proxy) -{ - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (view->priv->proxy) - g_free (view->priv->proxy); - - view->priv->proxy = e_utf8_ensure_valid (proxy); - - set_sender_text (view); -} - -const gchar * -itip_view_get_proxy (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->proxy; -} - -void -itip_view_set_delegator (ItipView *view, - const gchar *delegator) -{ - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (view->priv->delegator) - g_free (view->priv->delegator); - - view->priv->delegator = e_utf8_ensure_valid (delegator); - - set_sender_text (view); -} - -const gchar * -itip_view_get_delegator (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->delegator; -} - -void -itip_view_set_summary (ItipView *view, - const gchar *summary) -{ - WebKitDOMElement *row, *col; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (view->priv->summary) - g_free (view->priv->summary); - - view->priv->summary = summary ? g_strstrip (e_utf8_ensure_valid (summary)) : NULL; - - if (!view->priv->dom_document) - return; - - row = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TABLE_ROW_SUMMARY); - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->summary == NULL)); - - col = webkit_dom_element_get_last_element_child (row); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (col), - view->priv->summary ? view->priv->summary : "", - NULL); -} - -const gchar * -itip_view_get_summary (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->summary; -} - -void -itip_view_set_location (ItipView *view, - const gchar *location) -{ - WebKitDOMElement *row, *col; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (view->priv->location) - g_free (view->priv->location); - - view->priv->location = location ? g_strstrip (e_utf8_ensure_valid (location)) : NULL; - - if (!view->priv->dom_document) - return; - - row = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TABLE_ROW_LOCATION); - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->location == NULL)); - - col = webkit_dom_element_get_last_element_child (row); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (col), - view->priv->location ? view->priv->location : "", - NULL); -} - -const gchar * -itip_view_get_location (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->location; -} - -void -itip_view_set_status (ItipView *view, - const gchar *status) -{ - WebKitDOMElement *row, *col; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (view->priv->status) - g_free (view->priv->status); - - view->priv->status = status ? g_strstrip (e_utf8_ensure_valid (status)) : NULL; - - if (!view->priv->dom_document) - return; - - row = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TABLE_ROW_STATUS); - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->status == NULL)); - - col = webkit_dom_element_get_last_element_child (row); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (col), - view->priv->status ? view->priv->status : "", - NULL); -} - -const gchar * -itip_view_get_status (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->status; -} - -void -itip_view_set_comment (ItipView *view, - const gchar *comment) -{ - WebKitDOMElement *row, *col; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (view->priv->comment) - g_free (view->priv->comment); - - view->priv->comment = comment ? g_strstrip (e_utf8_ensure_valid (comment)) : NULL; - - if (!view->priv->dom_document) - return; - - row = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TABLE_ROW_COMMENT); - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->comment == NULL)); - - col = webkit_dom_element_get_last_element_child (row); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (col), - view->priv->comment ? view->priv->comment : "", - NULL); -} - -const gchar * -itip_view_get_comment (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->comment; -} - -void -itip_view_set_description (ItipView *view, - const gchar *description) -{ - WebKitDOMElement *div; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (view->priv->description) - g_free (view->priv->description); - - view->priv->description = description ? g_strstrip (e_utf8_ensure_valid (description)) : NULL; - - if (!view->priv->dom_document) - return; - - div = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TABLE_ROW_DESCRIPTION); - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (div), (view->priv->description == NULL)); - - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (div), - view->priv->description ? view->priv->description : "", - NULL); -} - -const gchar * -itip_view_get_description (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->description; -} - -void -itip_view_set_start (ItipView *view, - struct tm *start, - gboolean is_date) -{ - ItipViewPrivate *priv; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - priv = view->priv; - - if (priv->start_tm && !start) { - g_free (priv->start_tm); - priv->start_tm = NULL; - } else if (start) { - if (!priv->start_tm) - priv->start_tm = g_new0 (struct tm, 1); - - *priv->start_tm = *start; - } - - priv->start_tm_is_date = is_date && start; - - update_start_end_times (view); -} - -const struct tm * -itip_view_get_start (ItipView *view, - gboolean *is_date) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - if (is_date) - *is_date = view->priv->start_tm_is_date; - - return view->priv->start_tm; -} - -void -itip_view_set_end (ItipView *view, - struct tm *end, - gboolean is_date) -{ - ItipViewPrivate *priv; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - priv = view->priv; - - if (priv->end_tm && !end) { - g_free (priv->end_tm); - priv->end_tm = NULL; - } else if (end) { - if (!priv->end_tm) - priv->end_tm = g_new0 (struct tm, 1); - - *priv->end_tm = *end; - } - - priv->end_tm_is_date = is_date && end; - - update_start_end_times (view); -} - -const struct tm * -itip_view_get_end (ItipView *view, - gboolean *is_date) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - if (is_date) - *is_date = view->priv->end_tm_is_date; - - return view->priv->end_tm; -} - -guint -itip_view_add_upper_info_item (ItipView *view, - ItipViewInfoItemType type, - const gchar *message) -{ - ItipViewPrivate *priv; - ItipViewInfoItem *item; - - g_return_val_if_fail (ITIP_IS_VIEW (view), 0); - - priv = view->priv; - - item = g_new0 (ItipViewInfoItem, 1); - - item->type = type; - item->message = e_utf8_ensure_valid (message); - item->id = priv->next_info_item_id++; - - priv->upper_info_items = g_slist_append (priv->upper_info_items, item); - - if (!view->priv->dom_document) - return item->id; - - append_info_item_row (view, TABLE_UPPER_ITIP_INFO, item); - - return item->id; -} - -guint -itip_view_add_upper_info_item_printf (ItipView *view, - ItipViewInfoItemType type, - const gchar *format, - ...) -{ - va_list args; - gchar *message; - guint id; - - g_return_val_if_fail (ITIP_IS_VIEW (view), 0); - - va_start (args, format); - message = g_strdup_vprintf (format, args); - va_end (args); - - id = itip_view_add_upper_info_item (view, type, message); - g_free (message); - - return id; -} - -void -itip_view_remove_upper_info_item (ItipView *view, - guint id) -{ - ItipViewPrivate *priv; - GSList *l; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - priv = view->priv; - - for (l = priv->upper_info_items; l; l = l->next) { - ItipViewInfoItem *item = l->data; - - if (item->id == id) { - priv->upper_info_items = g_slist_remove (priv->upper_info_items, item); - - g_free (item->message); - g_free (item); - - if (!view->priv->dom_document) - remove_info_item_row (view, TABLE_UPPER_ITIP_INFO, id); - - return; - } - } -} - -void -itip_view_clear_upper_info_items (ItipView *view) -{ - ItipViewPrivate *priv; - GSList *l; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - priv = view->priv; - - for (l = priv->upper_info_items; l; l = l->next) { - ItipViewInfoItem *item = l->data; - - if (view->priv->dom_document) - remove_info_item_row (view, TABLE_UPPER_ITIP_INFO, item->id); - - g_free (item->message); - g_free (item); - } - - g_slist_free (priv->upper_info_items); - priv->upper_info_items = NULL; -} - -guint -itip_view_add_lower_info_item (ItipView *view, - ItipViewInfoItemType type, - const gchar *message) -{ - ItipViewPrivate *priv; - ItipViewInfoItem *item; - - g_return_val_if_fail (ITIP_IS_VIEW (view), 0); - - priv = view->priv; - - item = g_new0 (ItipViewInfoItem, 1); - - item->type = type; - item->message = e_utf8_ensure_valid (message); - item->id = priv->next_info_item_id++; - - priv->lower_info_items = g_slist_append (priv->lower_info_items, item); - - if (!view->priv->dom_document) - return item->id; - - append_info_item_row (view, TABLE_LOWER_ITIP_INFO, item); - - return item->id; -} - -guint -itip_view_add_lower_info_item_printf (ItipView *view, - ItipViewInfoItemType type, - const gchar *format, - ...) -{ - va_list args; - gchar *message; - guint id; - - g_return_val_if_fail (ITIP_IS_VIEW (view), 0); - - va_start (args, format); - message = g_strdup_vprintf (format, args); - va_end (args); - - id = itip_view_add_lower_info_item (view, type, message); - g_free (message); - - return id; -} - -void -itip_view_remove_lower_info_item (ItipView *view, - guint id) -{ - ItipViewPrivate *priv; - GSList *l; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - priv = view->priv; - - for (l = priv->lower_info_items; l; l = l->next) { - ItipViewInfoItem *item = l->data; - - if (item->id == id) { - priv->lower_info_items = g_slist_remove (priv->lower_info_items, item); - - g_free (item->message); - g_free (item); - - if (view->priv->dom_document) - remove_info_item_row (view, TABLE_LOWER_ITIP_INFO, id); - - return; - } - } -} - -void -itip_view_clear_lower_info_items (ItipView *view) -{ - ItipViewPrivate *priv; - GSList *l; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - priv = view->priv; - - for (l = priv->lower_info_items; l; l = l->next) { - ItipViewInfoItem *item = l->data; - - if (view->priv->dom_document) - remove_info_item_row (view, TABLE_LOWER_ITIP_INFO, item->id); - - g_free (item->message); - g_free (item); - } - - g_slist_free (priv->lower_info_items); - priv->lower_info_items = NULL; -} - -void -itip_view_set_source (ItipView *view, - ESource *source) -{ - WebKitDOMElement *select; - WebKitDOMElement *row; - ESource *selected_source; - gulong i, len; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - d(printf("Settings default source '%s'\n", e_source_get_display_name (source))); - - if (!view->priv->dom_document) - return; - - row = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TABLE_ROW_ESCB); - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (row), (source == NULL)); - if (source == NULL) - return; - - select = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, SELECT_ESOURCE); - - /* <select> does not emit 'change' event when already selected - * <option> is re-selected, but we need to notify itip formatter, - * so that it would make all the buttons sensitive. */ - selected_source = itip_view_ref_source (view); - if (source == selected_source) - source_changed_cb (select, NULL, view); - if (selected_source != NULL) - g_object_unref (selected_source); - - if (webkit_dom_html_select_element_get_disabled ( - WEBKIT_DOM_HTML_SELECT_ELEMENT (select))) { - webkit_dom_html_select_element_set_disabled ( - WEBKIT_DOM_HTML_SELECT_ELEMENT (select), FALSE); - } - - len = webkit_dom_html_select_element_get_length ( - WEBKIT_DOM_HTML_SELECT_ELEMENT (select)); - for (i = 0; i < len; i++) { - - WebKitDOMNode *node; - WebKitDOMHTMLOptionElement *option; - gchar *value; - - node = webkit_dom_html_select_element_item ( - WEBKIT_DOM_HTML_SELECT_ELEMENT (select), i); - option = WEBKIT_DOM_HTML_OPTION_ELEMENT (node); - - value = webkit_dom_html_option_element_get_value (option); - if (g_strcmp0 (value, e_source_get_uid (source)) == 0) { - webkit_dom_html_option_element_set_selected ( - option, TRUE); - - g_free (value); - break; - } - - g_free (value); - } -} - -ESource * -itip_view_ref_source (ItipView *view) -{ - ESourceRegistry *registry; - WebKitDOMElement *select; - gchar *uid; - ESource *source; - gboolean disable = FALSE; - - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - if (!view->priv->dom_document) - return NULL; - - select = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, SELECT_ESOURCE); - if (webkit_dom_html_select_element_get_disabled ( - WEBKIT_DOM_HTML_SELECT_ELEMENT (select))) { - webkit_dom_html_select_element_set_disabled ( - WEBKIT_DOM_HTML_SELECT_ELEMENT (select), FALSE); - disable = TRUE; - } - - uid = webkit_dom_html_select_element_get_value ( - WEBKIT_DOM_HTML_SELECT_ELEMENT (select)); - - registry = itip_view_get_registry (view); - source = e_source_registry_ref_source (registry, uid); - - g_free (uid); - - if (disable) { - webkit_dom_html_select_element_set_disabled ( - WEBKIT_DOM_HTML_SELECT_ELEMENT (select), TRUE); - } - - return source; -} - -void -itip_view_set_rsvp (ItipView *view, - gboolean rsvp) -{ - WebKitDOMElement *el; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (!view->priv->dom_document) - return; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_RSVP); - webkit_dom_html_input_element_set_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), rsvp); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TEXTAREA_RSVP_COMMENT); - webkit_dom_html_text_area_element_set_disabled ( - WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !rsvp); -} - -gboolean -itip_view_get_rsvp (ItipView *view) -{ - WebKitDOMElement *el; - - g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - - if (!view->priv->dom_document) - return FALSE; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_UPDATE); - return webkit_dom_html_input_element_get_checked (WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); -} - -void -itip_view_set_show_rsvp_check (ItipView *view, - gboolean show) -{ - WebKitDOMElement *label; - WebKitDOMElement *el; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (!view->priv->dom_document) - return; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, "table_row_" CHECKBOX_RSVP); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_RSVP); - label = webkit_dom_element_get_next_element_sibling (el); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); - - if (!show) { - webkit_dom_html_input_element_set_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); - } - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TABLE_ROW_RSVP_COMMENT); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); -} - -gboolean -itip_view_get_show_rsvp_check (ItipView *view) -{ - WebKitDOMElement *el; - - g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - - if (!view->priv->dom_document) - return FALSE; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_RSVP); - return !webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el)); -} - -void -itip_view_set_update (ItipView *view, - gboolean update) -{ - WebKitDOMElement *el; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (!view->priv->dom_document) - return; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_UPDATE); - - webkit_dom_html_input_element_set_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), update); -} - -gboolean -itip_view_get_update (ItipView *view) -{ - WebKitDOMElement *el; - - g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - - if (!view->priv->dom_document) - return FALSE; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_UPDATE); - return webkit_dom_html_input_element_get_checked (WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); -} - -void -itip_view_set_show_update_check (ItipView *view, - gboolean show) -{ - WebKitDOMElement *label; - WebKitDOMElement *el; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (!view->priv->dom_document) - return; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, "table_row_" CHECKBOX_UPDATE); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_UPDATE); - label = webkit_dom_element_get_next_element_sibling (el); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); - - if (!show) { - webkit_dom_html_input_element_set_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); - } -} - -gboolean -itip_view_get_show_update_check (ItipView *view) -{ - WebKitDOMElement *el; - - g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - - if (!view->priv->dom_document) - return FALSE; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_UPDATE); - return !webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el)); -} - -void -itip_view_set_rsvp_comment (ItipView *view, - const gchar *comment) -{ - WebKitDOMElement *el; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (!view->priv->dom_document) - return; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TEXTAREA_RSVP_COMMENT); - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (el), (comment == NULL)); - - if (comment) { - webkit_dom_html_text_area_element_set_value ( - WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), comment); - } -} - -gchar * -itip_view_get_rsvp_comment (ItipView *view) -{ - WebKitDOMElement *el; - - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - if (!view->priv->dom_document) - return NULL; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TEXTAREA_RSVP_COMMENT); - - if (webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el))) { - return NULL; - } - - return webkit_dom_html_text_area_element_get_value ( - WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el)); -} - -void -itip_view_set_needs_decline (ItipView *view, - gboolean needs_decline) -{ - g_return_if_fail (ITIP_IS_VIEW (view)); - - view->priv->needs_decline = needs_decline; -} - -void -itip_view_set_buttons_sensitive (ItipView *view, - gboolean sensitive) -{ - WebKitDOMElement *el, *cell; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - d(printf("Settings buttons %s\n", sensitive ? "sensitive" : "insensitive")); - - view->priv->buttons_sensitive = sensitive; - - if (!view->priv->dom_document) - return; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_UPDATE); - webkit_dom_html_input_element_set_disabled ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_RECUR); - webkit_dom_html_input_element_set_disabled ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_FREE_TIME); - webkit_dom_html_input_element_set_disabled ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_KEEP_ALARM); - webkit_dom_html_input_element_set_disabled ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_INHERIT_ALARM); - webkit_dom_html_input_element_set_disabled ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_RSVP); - webkit_dom_html_input_element_set_disabled ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TEXTAREA_RSVP_COMMENT); - webkit_dom_html_text_area_element_set_disabled ( - WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !sensitive); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, SELECT_ESOURCE); - webkit_dom_html_select_element_set_disabled ( - WEBKIT_DOM_HTML_SELECT_ELEMENT (el), !sensitive); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, TABLE_ROW_BUTTONS); - cell = webkit_dom_element_get_first_element_child (el); - do { - WebKitDOMElement *btn; - btn = webkit_dom_element_get_first_element_child (cell); - if (!webkit_dom_html_element_get_hidden ( - WEBKIT_DOM_HTML_ELEMENT (btn))) { - webkit_dom_html_button_element_set_disabled ( - WEBKIT_DOM_HTML_BUTTON_ELEMENT (btn), !sensitive); - } - } while ((cell = webkit_dom_element_get_next_element_sibling (cell)) != NULL); -} - -gboolean -itip_view_get_buttons_sensitive (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - - return view->priv->buttons_sensitive; -} - -gboolean -itip_view_get_recur_check_state (ItipView *view) -{ - WebKitDOMElement *el; - - g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - - if (!view->priv->dom_document) - return FALSE; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_RECUR); - return webkit_dom_html_input_element_get_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); -} - -void -itip_view_set_show_recur_check (ItipView *view, - gboolean show) -{ - WebKitDOMElement *label; - WebKitDOMElement *el; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (!view->priv->dom_document) - return; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, "table_row_" CHECKBOX_RECUR); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_RECUR); - label = webkit_dom_element_get_next_element_sibling (el); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); - - if (!show) { - webkit_dom_html_input_element_set_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); - } - - /* and update state of the second check */ - alarm_check_toggled_cb ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), - NULL, view); -} - -void -itip_view_set_show_free_time_check (ItipView *view, - gboolean show) -{ - WebKitDOMElement *label; - WebKitDOMElement *el; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (!view->priv->dom_document) - return; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, "table_row_" CHECKBOX_FREE_TIME); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_FREE_TIME); - label = webkit_dom_element_get_next_element_sibling (el); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); - - if (!show) { - webkit_dom_html_input_element_set_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); - } - - /* and update state of the second check */ - alarm_check_toggled_cb ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), - NULL, view); -} - -gboolean -itip_view_get_free_time_check_state (ItipView *view) -{ - WebKitDOMElement *el; - - g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - - if (!view->priv->dom_document) - return FALSE; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_FREE_TIME); - return webkit_dom_html_input_element_get_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); -} - -void -itip_view_set_show_keep_alarm_check (ItipView *view, - gboolean show) -{ - WebKitDOMElement *label; - WebKitDOMElement *el; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (!view->priv->dom_document) - return; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, "table_row_" CHECKBOX_KEEP_ALARM); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_KEEP_ALARM); - label = webkit_dom_element_get_next_element_sibling (el); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); - - if (!show) { - webkit_dom_html_input_element_set_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); - } - - /* and update state of the second check */ - alarm_check_toggled_cb ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), - NULL, view); -} - -gboolean -itip_view_get_keep_alarm_check_state (ItipView *view) -{ - WebKitDOMElement *el; - - g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - - if (!view->priv->dom_document) - return FALSE; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_KEEP_ALARM); - return webkit_dom_html_input_element_get_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); -} - -void -itip_view_set_show_inherit_alarm_check (ItipView *view, - gboolean show) -{ - WebKitDOMElement *label; - WebKitDOMElement *el; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - if (!view->priv->dom_document) - return; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, "table_row_" CHECKBOX_INHERIT_ALARM); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_INHERIT_ALARM); - label = webkit_dom_element_get_next_element_sibling (el); - webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); - - if (!show) { - webkit_dom_html_input_element_set_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); - } - - /* and update state of the second check */ - alarm_check_toggled_cb ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el), - NULL, view); -} - -gboolean -itip_view_get_inherit_alarm_check_state (ItipView *view) -{ - WebKitDOMElement *el; - - g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - - if (!view->priv->dom_document) - return FALSE; - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, CHECKBOX_INHERIT_ALARM); - return webkit_dom_html_input_element_get_checked ( - WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); -} - -void -itip_view_set_error (ItipView *view, - const gchar *error_html, - gboolean show_save_btn) -{ - WebKitDOMElement *content, *error; - GString *str; - - g_return_if_fail (ITIP_IS_VIEW (view)); - g_return_if_fail (error_html); - - str = g_string_new (error_html); - - if (show_save_btn) { - g_string_append (str, - "<table border=\"0\" width=\"100%\">" - "<tr width=\"100%\" id=\"" TABLE_ROW_BUTTONS "\">"); - - buttons_table_write_button ( - str, BUTTON_SAVE, _("_Save"), - GTK_STOCK_SAVE, ITIP_VIEW_RESPONSE_SAVE); - - g_string_append (str, "</tr></table>"); - } - - view->priv->error = str->str; - g_string_free (str, FALSE); - - if (!view->priv->dom_document) - return; - - content = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, DIV_ITIP_CONTENT); - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (content), TRUE); - - error = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, DIV_ITIP_ERROR); - webkit_dom_html_element_set_hidden ( - WEBKIT_DOM_HTML_ELEMENT (error), FALSE); - - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (error), view->priv->error, NULL); - - if (show_save_btn) { - WebKitDOMElement *el; - - show_button (view, BUTTON_SAVE); - - el = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, BUTTON_SAVE); - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (el), "click", - G_CALLBACK (button_clicked_cb), FALSE, view); - } -} diff --git a/plugins/itip-formatter/itip-view.h b/plugins/itip-formatter/itip-view.h deleted file mode 100644 index 2e35aec39d..0000000000 --- a/plugins/itip-formatter/itip-view.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * - * 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: - * JP Rosevear <jpr@novell.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef ITIP_VIEW_H -#define ITIP_VIEW_H - -#include <stdarg.h> -#include <unistd.h> -#include <gtk/gtk.h> -#include <webkit/webkitdom.h> -#include <libecal/libecal.h> - -/* Standard GObject macros */ -#define ITIP_TYPE_VIEW \ - (itip_view_get_type ()) -#define ITIP_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), ITIP_TYPE_VIEW, ItipView)) -#define ITIP_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), ITIP_TYPE_VIEW, ItipViewClass)) -#define ITIP_IS_VIEW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), ITIP_TYPE_VIEW)) -#define ITIP_IS_VIEW_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), ITIP_TYPE_VIEW)) -#define ITIP_VIEW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), ITIP_TYPE_VIEW, ItipViewClass)) - -G_BEGIN_DECLS - -typedef struct _ItipView ItipView; -typedef struct _ItipViewClass ItipViewClass; -typedef struct _ItipViewPrivate ItipViewPrivate; -typedef struct _ItipPURI ItipPURI; - -typedef enum { - ITIP_VIEW_MODE_NONE, - ITIP_VIEW_MODE_PUBLISH, - ITIP_VIEW_MODE_REQUEST, - ITIP_VIEW_MODE_COUNTER, - ITIP_VIEW_MODE_DECLINECOUNTER, - ITIP_VIEW_MODE_ADD, - ITIP_VIEW_MODE_REPLY, - ITIP_VIEW_MODE_REFRESH, - ITIP_VIEW_MODE_CANCEL, - ITIP_VIEW_MODE_HIDE_ALL -} ItipViewMode; - -typedef enum { - ITIP_VIEW_RESPONSE_NONE, - ITIP_VIEW_RESPONSE_ACCEPT, - ITIP_VIEW_RESPONSE_TENTATIVE, - ITIP_VIEW_RESPONSE_DECLINE, - ITIP_VIEW_RESPONSE_UPDATE, - ITIP_VIEW_RESPONSE_CANCEL, - ITIP_VIEW_RESPONSE_REFRESH, - ITIP_VIEW_RESPONSE_OPEN, - ITIP_VIEW_RESPONSE_SAVE -} ItipViewResponse; - -typedef enum { - ITIP_VIEW_INFO_ITEM_TYPE_NONE, - ITIP_VIEW_INFO_ITEM_TYPE_INFO, - ITIP_VIEW_INFO_ITEM_TYPE_WARNING, - ITIP_VIEW_INFO_ITEM_TYPE_ERROR, - ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS -} ItipViewInfoItemType; - -struct _ItipView { - GObject parent; - ItipViewPrivate *priv; -}; - -struct _ItipViewClass { - GObjectClass parent_class; - - void (*source_selected) (ItipView *view, - ESource *selected_source); - void (*response) (ItipView *view, - gint response); -}; - -GType itip_view_get_type (void); -ItipView * itip_view_new (ItipPURI *puri, - ESourceRegistry *registry); -void itip_view_write (GString *buffer); -void itip_view_write_for_printing (ItipView *view, - GString *buffer); -void itip_view_create_dom_bindings (ItipView *view, - WebKitDOMElement *element); -ItipPURI * itip_view_get_puri (ItipView *view); -ESourceRegistry * - itip_view_get_registry (ItipView *view); -const gchar * itip_view_get_extension_name (ItipView *view); -void itip_view_set_extension_name (ItipView *view, - const gchar *extension_name); -ItipViewMode itip_view_get_mode (ItipView *view); -void itip_view_set_mode (ItipView *view, - ItipViewMode mode); -ECalClientSourceType - itip_view_get_item_type (ItipView *view); -void itip_view_set_item_type (ItipView *view, - ECalClientSourceType type); -const gchar * itip_view_get_organizer (ItipView *view); -void itip_view_set_organizer (ItipView *view, - const gchar *organizer); -const gchar * itip_view_get_organizer_sentby (ItipView *view); -void itip_view_set_organizer_sentby (ItipView *view, - const gchar *sentby); -const gchar * itip_view_get_attendee (ItipView *view); -void itip_view_set_attendee (ItipView *view, - const gchar *attendee); -const gchar * itip_view_get_attendee_sentby (ItipView *view); -void itip_view_set_attendee_sentby (ItipView *view, - const gchar *sentby); -const gchar * itip_view_get_delegator (ItipView *view); -void itip_view_set_delegator (ItipView *view, - const gchar *delegator); -const gchar * itip_view_get_proxy (ItipView *view); -void itip_view_set_proxy (ItipView *view, - const gchar *proxy); -const gchar * itip_view_get_summary (ItipView *view); -void itip_view_set_summary (ItipView *view, - const gchar *summary); -const gchar * itip_view_get_location (ItipView *view); -void itip_view_set_location (ItipView *view, - const gchar *location); -const gchar * itip_view_get_status (ItipView *view); -void itip_view_set_status (ItipView *view, - const gchar *status); -const gchar * itip_view_get_comment (ItipView *view); -void itip_view_set_comment (ItipView *view, - const gchar *comment); -const gchar * itip_view_get_description (ItipView *view); -void itip_view_set_description (ItipView *view, - const gchar *description); -const struct tm * - itip_view_get_start (ItipView *view, - gboolean *is_date); -void itip_view_set_start (ItipView *view, - struct tm *start, - gboolean is_date); -const struct tm * - itip_view_get_end (ItipView *view, - gboolean *is_date); -void itip_view_set_end (ItipView *view, - struct tm *end, - gboolean is_date); -guint itip_view_add_upper_info_item (ItipView *view, - ItipViewInfoItemType type, - const gchar *message); -guint itip_view_add_upper_info_item_printf - (ItipView *view, - ItipViewInfoItemType, - const gchar *format, - ...) G_GNUC_PRINTF (3, 4); -void itip_view_remove_upper_info_item - (ItipView *view, - guint id); -void itip_view_clear_upper_info_items - (ItipView *view); -guint itip_view_add_lower_info_item (ItipView *view, - ItipViewInfoItemType type, - const gchar *message); -guint itip_view_add_lower_info_item_printf - (ItipView *view, - ItipViewInfoItemType type, - const gchar *format, - ...) G_GNUC_PRINTF (3, 4); -void itip_view_remove_lower_info_item - (ItipView *view, - guint id); -void itip_view_clear_lower_info_items - (ItipView *view); -ESource * itip_view_ref_source (ItipView *view); -void itip_view_set_source (ItipView *view, - ESource *source); -gboolean itip_view_get_rsvp (ItipView *view); -void itip_view_set_rsvp (ItipView *view, - gboolean rsvp); -gboolean itip_view_get_show_rsvp_check (ItipView *view); -void itip_view_set_show_rsvp_check (ItipView *view, - gboolean show); -gboolean itip_view_get_update (ItipView *view); -void itip_view_set_update (ItipView *view, - gboolean update); -gboolean itip_view_get_show_update_check (ItipView *view); -void itip_view_set_show_update_check (ItipView *view, - gboolean show); -gchar * itip_view_get_rsvp_comment (ItipView *view); -void itip_view_set_rsvp_comment (ItipView *view, - const gchar *comment); -gboolean itip_view_get_buttons_sensitive (ItipView *view); -void itip_view_set_buttons_sensitive (ItipView *view, - gboolean sensitive); -gboolean itip_view_get_recur_check_state (ItipView *view); -void itip_view_set_show_recur_check (ItipView *view, - gboolean show); -void itip_view_set_needs_decline (ItipView *view, - gboolean needs_decline); -gboolean itip_view_get_free_time_check_state - (ItipView *view); -void itip_view_set_show_free_time_check - (ItipView *view, - gboolean show); -gboolean itip_view_get_keep_alarm_check_state - (ItipView *view); -void itip_view_set_show_keep_alarm_check - (ItipView *view, - gboolean show); -gboolean itip_view_get_inherit_alarm_check_state - (ItipView *view); -void itip_view_set_show_inherit_alarm_check - (ItipView *view, - gboolean show); -void itip_view_set_error (ItipView *view, - const gchar *error_html, - gboolean show_save_btn); - -G_END_DECLS - -#endif /* ITIP_VIEW_H */ - diff --git a/plugins/itip-formatter/org-gnome-itip-formatter.eplug.xml b/plugins/itip-formatter/org-gnome-itip-formatter.eplug.xml deleted file mode 100644 index 1cc441a37d..0000000000 --- a/plugins/itip-formatter/org-gnome-itip-formatter.eplug.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0"?> -<e-plugin-list> - <e-plugin id="org.gnome.evolution.itip_formatter" - type="shlib" _name="Itip Formatter" - location="@PLUGINDIR@/liborg-gnome-itip-formatter@SOEXT@"> - <_description>Display "text/calendar" MIME parts in mail messages.</_description> - <author name="JP Rosevear" email="jpr@novell.com"/> - - <hook class="org.gnome.evolution.mail.format:1.0"> - <group id="EMFormatHTMLDisplay"> - <item mime_type="text/calendar" flags="inline_disposition" format="format_itip"/> - </group> - <group id="EMFormat"> - <item mime_type="text/calendar" flags="inline_disposition" format="format_itip"/> - </group> - </hook> - - <hook class="org.gnome.evolution.calendar.config:1.0"> - <group id="org.gnome.evolution.calendar.prefs" target="prefs"> - <item type="page" path="90.itip" label="itip" factory="itip_formatter_page_factory"/> - </group> - </hook> - </e-plugin> -</e-plugin-list> diff --git a/plugins/itip-formatter/org-gnome-itip-formatter.error.xml b/plugins/itip-formatter/org-gnome-itip-formatter.error.xml deleted file mode 100644 index e5d84c67af..0000000000 --- a/plugins/itip-formatter/org-gnome-itip-formatter.error.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<error-list domain="org.gnome.itip-formatter"> - - <error id="add-unknown-attendee" type="question"> - <_primary>This response is not from a current attendee. Add the sender as an attendee?</_primary> - <button stock="gtk-yes" response="GTK_RESPONSE_YES"/> - <button stock="gtk-no" response="GTK_RESPONSE_NO"/> - </error> - - <error id="add-delegate" type="question"> - <_primary>This meeting has been delegated</_primary> - <_secondary>'{0}' has delegated the meeting. Do you want to add the delegate '{1}'?</_secondary> - <button stock="gtk-yes" response="GTK_RESPONSE_YES"/> - <button stock="gtk-no" response="GTK_RESPONSE_NO"/> - </error> - -</error-list> diff --git a/plugins/mail-to-task/mail-to-task.c b/plugins/mail-to-task/mail-to-task.c index e74cece640..89ba097611 100644 --- a/plugins/mail-to-task/mail-to-task.c +++ b/plugins/mail-to-task/mail-to-task.c @@ -47,7 +47,6 @@ #include <mail/e-mail-browser.h> #include <mail/em-utils.h> -#include <mail/em-format-html.h> #include <mail/message-list.h> #include <calendar/gui/dialogs/comp-editor.h> diff --git a/plugins/mailing-list-actions/mailing-list-actions.c b/plugins/mailing-list-actions/mailing-list-actions.c index 3b541d0352..b31414276b 100644 --- a/plugins/mailing-list-actions/mailing-list-actions.c +++ b/plugins/mailing-list-actions/mailing-list-actions.c @@ -45,7 +45,6 @@ #include <mail/e-mail-reader.h> #include <mail/em-composer-utils.h> #include <mail/em-config.h> -#include <mail/em-format-hook.h> #include <mail/em-utils.h> #include <mail/message-list.h> diff --git a/plugins/prefer-plain/Makefile.am b/plugins/prefer-plain/Makefile.am deleted file mode 100644 index 5375da81fd..0000000000 --- a/plugins/prefer-plain/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -@EVO_PLUGIN_RULE@ - -plugin_DATA = org-gnome-prefer-plain.eplug - -plugin_LTLIBRARIES = liborg-gnome-prefer-plain.la - -liborg_gnome_prefer_plain_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) - -liborg_gnome_prefer_plain_la_SOURCES = prefer-plain.c - -liborg_gnome_prefer_plain_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_prefer_plain_la_LIBADD = \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/em-format/libemformat.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -EXTRA_DIST = org-gnome-prefer-plain.eplug.xml - -BUILT_SOURCES = $(plugin_DATA) -CLEANFILES = $(BUILT_SOURCES) - --include $(top_srcdir)/git.mk diff --git a/plugins/prefer-plain/org-gnome-prefer-plain.eplug.xml b/plugins/prefer-plain/org-gnome-prefer-plain.eplug.xml deleted file mode 100644 index 6d0c3ae6ac..0000000000 --- a/plugins/prefer-plain/org-gnome-prefer-plain.eplug.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0"?> -<e-plugin-list> - <e-plugin - type="shlib" - id="org.gnome.evolution.plugin.preferPlain" - location="@PLUGINDIR@/liborg-gnome-prefer-plain@SOEXT@" - _name="Prefer Plain Text"> - - - <_description>View mail messages as plain text, even if they contain HTML content.</_description> - <author name="Michael Zucchi" email="NotZed@Ximian.com"/> - - - <!-- hook into the 'html mail' preferences page --> - <hook class="org.gnome.evolution.mail.config:1.0"> - <group target="prefs" id="org.gnome.evolution.mail.prefs"> - <!-- we could also just insert our own items from a section factory, --> - <!-- but then we also need to create our own section frame --> - <item type="section_table" path="10.html/80.mode" _label="Plain Text Mode"/> - <item type="item_table" path="10.html/80.mode/00.mode" factory="org_gnome_prefer_plain_config_mode"/> - </group> - </hook> - - <hook class="org.gnome.evolution.mail.format:1.0"> - <!-- need to override all formatters that override this type --> - <group id="EMFormatHTMLDisplay"> - <item mime_type="multipart/alternative" format="org_gnome_prefer_plain_multipart_alternative"/> - <item mime_type="text/html" format="org_gnome_prefer_plain_text_html"/> - </group> - <group id="EMFormat"> - <item mime_type="multipart/alternative" format="org_gnome_prefer_plain_multipart_alternative"/> - <item mime_type="text/html" format="org_gnome_prefer_plain_text_html"/> - </group> - </hook> - - </e-plugin> -</e-plugin-list> diff --git a/plugins/prefer-plain/prefer-plain.c b/plugins/prefer-plain/prefer-plain.c deleted file mode 100644 index 5793370374..0000000000 --- a/plugins/prefer-plain/prefer-plain.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * 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: - * Michael Zucchi <notzed@novell.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <glib/gi18n-lib.h> -#include <string.h> -#include <stdio.h> - -#include <em-format/em-format.h> -#include <mail/em-config.h> -#include <mail/em-format-hook.h> - -void org_gnome_prefer_plain_multipart_alternative (gpointer ep, EMFormatHookTarget *t); -void org_gnome_prefer_plain_text_html (gpointer ep, EMFormatHookTarget *t); -GtkWidget *org_gnome_prefer_plain_config_mode (EPlugin *epl, struct _EConfigHookItemFactoryData *data); - -enum { - EPP_NORMAL, - EPP_PREFER, - EPP_TEXT -}; - -static GSettings *epp_settings = NULL; -static gint epp_mode = -1; -static gboolean epp_show_suppressed = TRUE; - -static void -make_part_attachment (EMFormat *format, - CamelMimePart *part, - GString *part_id, - gboolean force_html, - GCancellable *cancellable) -{ - EMFormatParserInfo info = {0}; - - if (camel_content_type_is (camel_mime_part_get_content_type (part), "text", "html")) { - /* always show HTML as attachments and not inline */ - camel_mime_part_set_disposition (part, "attachment"); - - if (!camel_mime_part_get_filename (part)) { - gchar *str = g_strdup_printf ("%s.html", _("attachment")); - camel_mime_part_set_filename (part, str); - g_free (str); - } - - em_format_parse_part_as ( - format, part, part_id, &info, "application/octet-stream", cancellable); - } else if (force_html && CAMEL_IS_MIME_MESSAGE (part)) { - /* message was asked to be formatted as text/html; - * might be for cases where message itself is a text/html part */ - CamelMimePart *new_part; - CamelDataWrapper *content; - - content = camel_medium_get_content (CAMEL_MEDIUM (part)); - g_return_if_fail (content != NULL); - - new_part = camel_mime_part_new (); - camel_medium_set_content (CAMEL_MEDIUM (new_part), content); - - em_format_parse_part (format, new_part, part_id, &info, cancellable); - - g_object_unref (new_part); - } else { - em_format_parse_part (format, part, part_id, &info, cancellable); - } -} - -void -org_gnome_prefer_plain_text_html (gpointer ep, - EMFormatHookTarget *t) -{ - /* In text-only mode, all html output is suppressed for the first processing */ - if (epp_mode != EPP_TEXT - || strstr (t->part_id->str, ".alternative-prefer-plain.") != NULL - || em_format_is_inline (t->format, t->part_id->str, t->part, t->info->handler)) { - /* FIXME Not passing a GCancellable here. */ - t->info->handler->old->parse_func ( - t->format, t->part, t->part_id, - t->info, NULL); - } else if (epp_show_suppressed) - make_part_attachment (t->format, t->part, t->part_id, TRUE, NULL); -} - -static void -export_as_attachments (CamelMultipart *mp, - EMFormat *format, - CamelMimePart *except, - GString *part_id) -{ - gint i, nparts; - CamelMimePart *part; - gint len; - - if (!mp || !CAMEL_IS_MULTIPART (mp)) - return; - - len = part_id->len; - nparts = camel_multipart_get_number (mp); - for (i = 0; i < nparts; i++) { - part = camel_multipart_get_part (mp, i); - - if (part != except) { - CamelMultipart *multipart = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part); - - g_string_append_printf (part_id, ".aleternative-prefer-plain.%d", i); - if (CAMEL_IS_MULTIPART (multipart)) { - export_as_attachments (multipart, format, except, part_id); - } else { - make_part_attachment (format, part, part_id, FALSE, NULL); - } - g_string_truncate (part_id, len); - } - } -} - -void -org_gnome_prefer_plain_multipart_alternative (gpointer ep, - EMFormatHookTarget *t) -{ - CamelMultipart *mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) t->part); - CamelMimePart *part, *display_part = NULL, *calendar_part = NULL; - gint i, nparts, partidlen, displayid = 0, calendarid = 0; - - partidlen = t->part_id->len; - - if (epp_mode == EPP_NORMAL) { - gboolean have_plain = FALSE; - - /* Try to find text/html part even when not as last and force - * to show it. Old handler will show the last part of - * multipart/alternate, but if we can offer HTML, then - * offer it, regardless of position in multipart. But do - * this when have only text/plain and text/html parts, - * not more. */ - nparts = camel_multipart_get_number (mp); - for (i = 0; i < nparts; i++) { - CamelContentType *content_type; - - part = camel_multipart_get_part (mp, i); - - if (!part) - continue; - - content_type = camel_mime_part_get_content_type (part); - - if (camel_content_type_is (content_type, "text", "html")) { - displayid = i; - display_part = part; - - if (have_plain) - break; - } else if (camel_content_type_is (content_type, "text", "plain")) { - have_plain = TRUE; - - if (display_part) - break; - } - } - - if (display_part && have_plain && nparts == 2) { - g_string_append_printf (t->part_id, ".alternative-prefer-plain.%d", displayid); - /* FIXME Not passing a GCancellable here. */ - em_format_parse_part_as ( - t->format, display_part, t->part_id, t->info, "text/html", NULL); - g_string_truncate (t->part_id, partidlen); - } else { - /* FIXME Not passing a GCancellable here. */ - t->info->handler->old->parse_func ( - t->format, t->part, t->part_id, t->info, NULL); - } - return; - } else if (!CAMEL_IS_MULTIPART (mp)) { - /* FIXME Not passing GCancellable here. */ - em_format_parse_part_as (t->format, t->part, t->part_id, t->info, "x-evolution/message/source", NULL); - return; - } - - nparts = camel_multipart_get_number (mp); - for (i = 0; i < nparts; i++) { - CamelContentType *ct; - - part = camel_multipart_get_part (mp, i); - - if (!part) - continue; - - ct = camel_mime_part_get_content_type (part); - if (!display_part && camel_content_type_is (ct, "text", "plain")) { - displayid = i; - display_part = part; - } else if (!calendar_part && (camel_content_type_is (ct, "text", "calendar") || camel_content_type_is (ct, "text", "x-calendar"))) { - calendarid = i; - calendar_part = part; - } - } - - /* if we found a text part, show it */ - if (display_part) { - g_string_append_printf(t->part_id, ".alternative-prefer-plain.%d", displayid); - /* FIXME Not passing a GCancellable here. */ - em_format_parse_part_as ( - t->format, display_part, t->part_id, t->info, "text/plain", NULL); - g_string_truncate (t->part_id, partidlen); - } - - /* all other parts are attachments */ - if (epp_show_suppressed) - export_as_attachments (mp, t->format, display_part, t->part_id); - else if (calendar_part) { - g_string_append_printf(t->part_id, ".alternative-prefer-plain.%d", calendarid); - make_part_attachment (t->format, calendar_part, t->part_id, FALSE, NULL); - } - - g_string_truncate (t->part_id, partidlen); -} - -static struct { - const gchar *key; - const gchar *label; - const gchar *description; -} epp_options[] = { - { "normal", - N_("Show HTML if present"), - N_("Let Evolution choose the best part to show.") }, - - { "prefer_plain", - N_("Show plain text if present"), - N_("Show plain text part, if present, otherwise " - "let Evolution choose the best part to show.") }, - - { "only_plain", - N_("Only ever show plain text"), - N_("Always show plain text part and make attachments " - "from other parts, if requested.") }, -}; - -static void -update_info_label (GtkWidget *info_label, - guint mode) -{ - gchar *str = g_strconcat ("<i>", _(epp_options[mode > 2 ? 0 : mode].description), "</i>", NULL); - - gtk_label_set_markup (GTK_LABEL (info_label), str); - - g_free (str); -} - -static void -epp_mode_changed (GtkComboBox *dropdown, - GtkWidget *info_label) -{ - epp_mode = gtk_combo_box_get_active (dropdown); - if (epp_mode > 2) - epp_mode = 0; - - g_settings_set_string (epp_settings, "mode", epp_options[epp_mode].key); - update_info_label (info_label, epp_mode); -} - -static void -epp_show_suppressed_toggled (GtkToggleButton *check, - gpointer data) -{ - g_return_if_fail (check != NULL); - - epp_show_suppressed = gtk_toggle_button_get_active (check); - g_settings_set_boolean (epp_settings, "show-suppressed", epp_show_suppressed); -} - -GtkWidget * -org_gnome_prefer_plain_config_mode (EPlugin *epl, - struct _EConfigHookItemFactoryData *data) -{ - GtkComboBox *dropdown; - GtkCellRenderer *cell; - GtkListStore *store; - GtkWidget *dropdown_label, *info, *check; - guint i; - GtkTreeIter iter; - - if (data->old) - return data->old; - - check = gtk_check_button_new_with_mnemonic (_("Show s_uppressed HTML parts as attachments")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), epp_show_suppressed); - gtk_widget_show (check); - g_signal_connect ( - check, "toggled", - G_CALLBACK (epp_show_suppressed_toggled), NULL); - - dropdown = (GtkComboBox *) gtk_combo_box_new (); - cell = gtk_cell_renderer_text_new (); - store = gtk_list_store_new (1, G_TYPE_STRING); - for (i = 0; i < G_N_ELEMENTS (epp_options); i++) { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, _(epp_options[i].label), -1); - } - - gtk_cell_layout_pack_start ((GtkCellLayout *) dropdown, cell, TRUE); - gtk_cell_layout_set_attributes((GtkCellLayout *)dropdown, cell, "text", 0, NULL); - gtk_combo_box_set_model (dropdown, (GtkTreeModel *) store); - /*gtk_combo_box_set_active(dropdown, -1);*/ - gtk_combo_box_set_active (dropdown, epp_mode); - gtk_widget_show ((GtkWidget *) dropdown); - - dropdown_label = gtk_label_new_with_mnemonic (_("HTML _Mode")); - gtk_widget_show (dropdown_label); - gtk_label_set_mnemonic_widget (GTK_LABEL (dropdown_label), (GtkWidget *) dropdown); - - info = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (info), 0.0, 0.5); - gtk_label_set_line_wrap (GTK_LABEL (info), TRUE); - - gtk_widget_show (info); - update_info_label (info, epp_mode); - - g_signal_connect ( - dropdown, "changed", - G_CALLBACK (epp_mode_changed), info); - - g_object_get (data->parent, "n-rows", &i, NULL); - gtk_table_attach ((GtkTable *) data->parent, check, 0, 2, i, i + 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); - gtk_table_attach ((GtkTable *) data->parent, dropdown_label, 0, 1, i + 1, i + 2, 0, 0, 0, 0); - gtk_table_attach ((GtkTable *) data->parent, (GtkWidget *) dropdown, 1, 2, i + 1, i + 2, GTK_FILL | GTK_EXPAND, 0, 0, 0); - gtk_table_attach ((GtkTable *) data->parent, info, 1, 2, i + 2, i + 3, GTK_FILL | GTK_EXPAND, 0, 0, 0); - - /* since this isnt dynamic, we don't need to track each item */ - - return (GtkWidget *) dropdown; -} - -gint e_plugin_lib_enable (EPlugin *ep, gint enable); - -gint -e_plugin_lib_enable (EPlugin *ep, - gint enable) -{ - gchar *key; - gint i; - - if (epp_settings || epp_mode != -1) - return 0; - - if (enable) { - - epp_settings = g_settings_new ("org.gnome.evolution.plugin.prefer-plain"); - key = g_settings_get_string (epp_settings, "mode"); - if (key) { - for (i = 0; i < G_N_ELEMENTS (epp_options); i++) { - if (!strcmp (epp_options[i].key, key)) { - epp_mode = i; - break; - } - } - g_free (key); - } else { - epp_mode = 0; - } - - epp_show_suppressed = g_settings_get_boolean (epp_settings, "show-suppressed"); - } else { - if (epp_settings) { - g_object_unref (epp_settings); - epp_settings = NULL; - } - } - - return 0; -} diff --git a/plugins/tnef-attachments/Makefile.am b/plugins/tnef-attachments/Makefile.am deleted file mode 100644 index 6a393044d1..0000000000 --- a/plugins/tnef-attachments/Makefile.am +++ /dev/null @@ -1,37 +0,0 @@ -if OS_WIN32 -NO_UNDEFINED_REQUIRED_LIBS = \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/mail/libevolution-mail.la -endif - -@EVO_PLUGIN_RULE@ - -plugin_DATA = org-gnome-tnef-attachments.eplug - -plugin_LTLIBRARIES = liborg-gnome-tnef-attachments.la - -liborg_gnome_tnef_attachments_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(TNEF_CFLAGS) - -liborg_gnome_tnef_attachments_la_SOURCES = tnef-plugin.c - -liborg_gnome_tnef_attachments_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_tnef_attachments_la_LIBADD = \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/em-format/libemformat.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - -lytnef - -EXTRA_DIST = org-gnome-tnef-attachments.eplug.xml - -BUILT_SOURCES = $(plugin_DATA) -CLEANFILES = $(BUILT_SOURCES) - --include $(top_srcdir)/git.mk diff --git a/plugins/tnef-attachments/org-gnome-tnef-attachments.eplug.xml b/plugins/tnef-attachments/org-gnome-tnef-attachments.eplug.xml deleted file mode 100644 index 5bfb0e65c0..0000000000 --- a/plugins/tnef-attachments/org-gnome-tnef-attachments.eplug.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0"?> -<e-plugin-list> - <e-plugin - type="shlib" - id="org.gnome.evolution.mail.tnefattachments" - location="@PLUGINDIR@/liborg-gnome-tnef-attachments@SOEXT@" - _name="TNEF Decoder"> - <_description>Decode TNEF (winmail.dat) attachments from Microsoft Outlook.</_description> - <author name="Lucky Wankhede" email="wlakke@novell.com"/> - - <hook class="org.gnome.evolution.mail.format:1.0"> - <group id="EMFormatHTML"> - <item flags="inline_disposition" mime_type="application/vnd.ms-tnef" - format="org_gnome_format_tnef"/> - <item flags="inline_disposition" mime_type="application/ms-tnef" - format="org_gnome_format_tnef"/> - </group> - <group id="EMFormatHTMLDisplay"> - <item flags="inline_disposition" mime_type="application/vnd.ms-tnef" - format="org_gnome_format_tnef"/> - <item flags="inline_disposition" mime_type="application/ms-tnef" - format="org_gnome_format_tnef"/> - </group> - </hook> - </e-plugin> -</e-plugin-list> diff --git a/plugins/tnef-attachments/tnef-plugin.c b/plugins/tnef-attachments/tnef-plugin.c deleted file mode 100644 index 52cd68664f..0000000000 --- a/plugins/tnef-attachments/tnef-plugin.c +++ /dev/null @@ -1,1355 +0,0 @@ -/* - * - * 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/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright (C) Randall Hand <randall.hand@gmail.com> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -/* We include gi18n-lib.h so that we have strings translated directly for this package */ -#include <glib/gi18n-lib.h> -#include <glib/gprintf.h> -#include <string.h> -#include <stdio.h> - -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <ctype.h> -#include <stdlib.h> -#ifdef HAVE_YTNEF_H -#include <ytnef.h> -#elif defined HAVE_LIBYTNEF_YTNEF_H -#include <libytnef/ytnef.h> -#endif - -#include <em-format/em-format.h> -#include <mail/em-format-hook.h> -#include <mail/em-utils.h> -#include <e-util/e-mktemp.h> - -gint verbose = 0; -gint saveRTF = 0; -gint saveintermediate = 0; -gboolean loaded = FALSE; -void processTnef (TNEFStruct *tnef, const gchar *tmpdir); -void saveVCalendar (TNEFStruct *tnef, const gchar *tmpdir); -void saveVCard (TNEFStruct *tnef, const gchar *tmpdir); -void saveVTask (TNEFStruct *tnef, const gchar *tmpdir); - -void org_gnome_format_tnef (gpointer ep, EMFormatHookTarget *t); - -/* Other Prototypes */ -void fprintProperty (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]); -void fprintUserProp (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]); -void quotedfprint (FILE *fptr, variableLength *vl); -void cstylefprint (FILE *fptr, variableLength *vl); -void printRtf (FILE *fptr, variableLength *vl); -void printRrule (FILE *fptr, gchar *recur_data, gint size, TNEFStruct *tnef); -guchar getRruleCount (guchar a, guchar b); -guchar getRruleMonthNum (guchar a, guchar b); -gchar * getRruleDayname (guchar a); - -static gchar * -sanitize_filename (const gchar *filename) -{ - gchar * sanitized_name; - sanitized_name = g_path_get_basename (filename); - if (sanitized_name == NULL || !g_strcmp0 (sanitized_name, ".")) { - g_free (sanitized_name); - return NULL; - } else { - return g_strdelimit (sanitized_name, " ", '_'); - } -} - -void -org_gnome_format_tnef (gpointer ep, - EMFormatHookTarget *t) -{ - gchar *tmpdir, *name; - CamelStream *out; - struct dirent *d; - DIR *dir; - CamelMultipart *mp; - CamelMimePart *mainpart; - CamelDataWrapper *content; - const EMFormatHandler *handler; - gint len; - TNEFStruct tnef; - - tmpdir = e_mkdtemp("tnef-attachment-XXXXXX"); - if (tmpdir == NULL) - return; - - name = g_build_filename(tmpdir, ".evo-attachment.tnef", NULL); - - out = camel_stream_fs_new_with_name (name, O_RDWR | O_CREAT, 0666, NULL); - if (out == NULL) { - g_free (name); - return; - } - content = camel_medium_get_content ((CamelMedium *) t->part); - if (content == NULL) { - g_free (name); - g_object_unref (out); - return; - } - if (camel_data_wrapper_decode_to_stream_sync (content, out, NULL, NULL) == -1 - || camel_stream_close (out, NULL, NULL) == -1) { - g_object_unref (out); - g_free (name); - return; - } - g_object_unref (out); - - /* Extracting the winmail.dat */ - TNEFInitialize (&tnef); - tnef.Debug = verbose; - if (TNEFParseFile (name, &tnef) == -1) { - printf("ERROR processing file\n"); - } - processTnef (&tnef, tmpdir); - - TNEFFree (&tnef); - /* Extraction done */ - - dir = opendir (tmpdir); - if (dir == NULL) { - g_object_unref (out); - g_free (name); - return; - } - - mainpart = camel_mime_part_new (); - - mp = camel_multipart_new (); - camel_data_wrapper_set_mime_type((CamelDataWrapper *)mp, "multipart/mixed"); - camel_multipart_set_boundary (mp, NULL); - - camel_medium_set_content ((CamelMedium *) mainpart, (CamelDataWrapper *) mp); - - while ((d = readdir (dir))) { - CamelMimePart *part; - CamelDataWrapper *content; - CamelStream *stream; - gchar *path; - const gchar *type; - - if (!strcmp(d->d_name, ".") - || !strcmp(d->d_name, "..") - || !strcmp(d->d_name, ".evo-attachment.tnef")) - continue; - - path = g_build_filename (tmpdir, d->d_name, NULL); - - stream = camel_stream_fs_new_with_name (path, O_RDONLY, 0, NULL); - content = camel_data_wrapper_new (); - camel_data_wrapper_construct_from_stream_sync ( - content, stream, NULL, NULL); - g_object_unref (stream); - - part = camel_mime_part_new (); - camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_BINARY); - - camel_medium_set_content ((CamelMedium *) part, content); - g_object_unref (content); - - type = em_format_snoop_type (part); - if (type) - camel_data_wrapper_set_mime_type ((CamelDataWrapper *) part, type); - - camel_mime_part_set_filename (part, d->d_name); - - g_free (path); - - camel_multipart_add_part (mp, part); - g_object_unref (part); - } - - closedir (dir); - - len = t->part_id->len; - g_string_append_printf(t->part_id, ".tnef"); - - if (camel_multipart_get_number (mp) > 0) { - handler = em_format_find_handler (t->format, "multiplart/mixed"); - /* FIXME Not passing a GCancellable here. */ - if (handler && handler->parse_func) { - CamelMimePart *part = camel_mime_part_new (); - camel_medium_set_content ((CamelMedium *) part, - CAMEL_DATA_WRAPPER (mp)); - handler->parse_func (t->format, part, t->part_id, t->info, NULL); - g_object_unref (part); - } - } - - g_string_truncate (t->part_id, len); - - g_object_unref (mp); - g_object_unref (mainpart); - - g_free (name); - g_free (tmpdir); -} - -gint e_plugin_lib_enable (EPlugin *ep, gint enable); - -gint -e_plugin_lib_enable (EPlugin *ep, - gint enable) -{ - if (loaded) - return 0; - - loaded = TRUE; - - return 0; -} - -void -processTnef (TNEFStruct *tnef, - const gchar *tmpdir) -{ - variableLength *filename; - variableLength *filedata; - Attachment *p; - gint RealAttachment; - gint object; - gchar *ifilename = NULL; - gchar *absfilename, *file; - gint count; - gint foundCal = 0; - - FILE *fptr; - - /* First see if this requires special processing. */ - /* ie: it's a Contact Card, Task, or Meeting request (vCal/vCard) */ - if (tnef->messageClass[0] != 0) { - if (strcmp(tnef->messageClass, "IPM.Contact") == 0) { - saveVCard (tnef, tmpdir); - } - if (strcmp(tnef->messageClass, "IPM.Task") == 0) { - saveVTask (tnef, tmpdir); - } - if (strcmp(tnef->messageClass, "IPM.Appointment") == 0) { - saveVCalendar (tnef, tmpdir); - foundCal = 1; - } - } - - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_STRING8,0x24))) != MAPI_UNDEFINED) { - if (strcmp(filename->data, "IPM.Appointment") == 0) { - /* If it's "indicated" twice, we don't want to save 2 calendar entries. */ - if (foundCal == 0) { - saveVCalendar (tnef, tmpdir); - } - } - } - - if (strcmp(tnef->messageClass, "IPM.Microsoft Mail.Note") == 0) { - if ((saveRTF == 1) && (tnef->subject.size > 0)) { - /* Description */ - if ((filename = MAPIFindProperty (&(tnef->MapiProperties), - PROP_TAG (PT_BINARY, PR_RTF_COMPRESSED))) - != MAPI_UNDEFINED) { - variableLength buf; - if ((buf.data = (gchar *) DecompressRTF (filename, &buf.size)) != NULL) { - file = sanitize_filename (tnef->subject.data); - if (!file) - return; - absfilename = g_strconcat (file, ".rtf", NULL); - ifilename = g_build_filename (tmpdir, file, NULL); - g_free (absfilename); - g_free (file); - - if ((fptr = fopen(ifilename, "wb"))==NULL) { - printf("ERROR: Error writing file to disk!"); - } else { - fwrite (buf.data, - sizeof (BYTE), - buf.size, - fptr); - fclose (fptr); - } - free (buf.data); - } - } - } - } - - /* Now process each attachment */ - p = tnef->starting_attach.next; - count = 0; - while (p != NULL) { - count++; - /* Make sure it has a size. */ - if (p->FileData.size > 0) { - object = 1; - - /* See if the contents are stored as "attached data" */ - /* Inside the MAPI blocks. */ - if ((filedata = MAPIFindProperty (&(p->MAPI), - PROP_TAG (PT_OBJECT, PR_ATTACH_DATA_OBJ))) - == MAPI_UNDEFINED) { - if ((filedata = MAPIFindProperty (&(p->MAPI), - PROP_TAG (PT_BINARY, PR_ATTACH_DATA_OBJ))) - == MAPI_UNDEFINED) { - /* Nope, standard TNEF stuff. */ - filedata = &(p->FileData); - object = 0; - } - } - /* See if this is an embedded TNEF stream. */ - RealAttachment = 1; - if (object == 1) { - /* This is an "embedded object", so skip the */ - /* 16-byte identifier first. */ - TNEFStruct emb_tnef; - DWORD signature; - memcpy (&signature, filedata->data + 16, sizeof (DWORD)); - if (TNEFCheckForSignature (signature) == 0) { - /* Has a TNEF signature, so process it. */ - TNEFInitialize (&emb_tnef); - emb_tnef.Debug = tnef->Debug; - if (TNEFParseMemory ((guchar *) filedata->data + 16, - filedata->size - 16, &emb_tnef) != -1) { - processTnef (&emb_tnef, tmpdir); - RealAttachment = 0; - } - TNEFFree (&emb_tnef); - } - } else { - TNEFStruct emb_tnef; - DWORD signature; - memcpy (&signature, filedata->data, sizeof (DWORD)); - if (TNEFCheckForSignature (signature) == 0) { - /* Has a TNEF signature, so process it. */ - TNEFInitialize (&emb_tnef); - emb_tnef.Debug = tnef->Debug; - if (TNEFParseMemory ((guchar *) filedata->data, - filedata->size, &emb_tnef) != -1) { - processTnef (&emb_tnef, tmpdir); - RealAttachment = 0; - } - TNEFFree (&emb_tnef); - } - } - if ((RealAttachment == 1) || (saveintermediate == 1)) { - gchar tmpname[20]; - /* Ok, it's not an embedded stream, so now we */ - /* process it. */ - if ((filename = MAPIFindProperty (&(p->MAPI), - PROP_TAG (PT_STRING8, PR_ATTACH_LONG_FILENAME))) - == MAPI_UNDEFINED) { - if ((filename = MAPIFindProperty (&(p->MAPI), - PROP_TAG (PT_STRING8, PR_DISPLAY_NAME))) - == MAPI_UNDEFINED) { - filename = &(p->Title); - } - } - if (filename->size == 1) { - filename->size = 20; - g_sprintf(tmpname, "file_%03i.dat", count); - filename->data = tmpname; - } - absfilename = sanitize_filename (filename->data); - if (!absfilename) - return; - ifilename = g_build_filename (tmpdir, absfilename, NULL); - g_free (absfilename); - - if ((fptr = fopen(ifilename, "wb"))==NULL) { - printf("ERROR: Error writing file to disk!"); - } else { - if (object == 1) { - fwrite (filedata->data + 16, - sizeof (BYTE), - filedata->size - 16, - fptr); - } else { - fwrite (filedata->data, - sizeof (BYTE), - filedata->size, - fptr); - } - fclose (fptr); - } - } - } /* if size>0 */ - p = p->next; - } /* while p!= null */ - g_free (ifilename); -} - -void -saveVCard (TNEFStruct *tnef, - const gchar *tmpdir) -{ - gchar *ifilename; - gchar *absfilename, *file = NULL; - FILE *fptr; - variableLength *vl; - variableLength *pobox, *street, *city, *state, *zip, *country; - dtr thedate; - gint boolean; - - if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_DISPLAY_NAME))) == MAPI_UNDEFINED) { - if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_COMPANY_NAME))) == MAPI_UNDEFINED) { - if (tnef->subject.size > 0) { - file = sanitize_filename (tnef->subject.data); - if (!file) - return; - absfilename = g_strconcat (file, ".vcard", NULL); - } else - absfilename = g_strdup ("unknown.vcard"); - } else { - file = sanitize_filename (vl->data); - if (!file) - return; - absfilename = g_strconcat (file, ".vcard", NULL); - } - } else { - file = sanitize_filename (vl->data); - if (!file) - return; - absfilename = g_strconcat (file, ".vcard", NULL); - } - - ifilename = g_build_filename (tmpdir, absfilename, NULL); - g_free (file); - g_free (absfilename); - - if ((fptr = fopen(ifilename, "wb"))==NULL) { - printf("Error writing file to disk!"); - } else { - fprintf(fptr, "BEGIN:VCARD\n"); - fprintf(fptr, "VERSION:2.1\n"); - if (vl != MAPI_UNDEFINED) { - fprintf(fptr, "FN:%s\n", vl->data); - } - fprintProperty(tnef, fptr, PT_STRING8, PR_NICKNAME, "NICKNAME:%s\n"); - fprintUserProp(tnef, fptr, PT_STRING8, 0x8554, "MAILER:Microsoft Outlook %s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_SPOUSE_NAME, "X-EVOLUTION-SPOUSE:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_MANAGER_NAME, "X-EVOLUTION-MANAGER:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_ASSISTANT, "X-EVOLUTION-ASSISTANT:%s\n"); - - /* Organizational */ - if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_COMPANY_NAME))) != MAPI_UNDEFINED) { - if (vl->size > 0) { - if ((vl->size == 1) && (vl->data[0] == 0)) { - } else { - fprintf(fptr,"ORG:%s", vl->data); - if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_DEPARTMENT_NAME))) != MAPI_UNDEFINED) { - fprintf(fptr,";%s", vl->data); - } - fprintf(fptr, "\n"); - } - } - } - - fprintProperty(tnef, fptr, PT_STRING8, PR_OFFICE_LOCATION, "X-EVOLUTION-OFFICE:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_TITLE, "TITLE:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_PROFESSION, "ROLE:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_BODY, "NOTE:%s\n"); - if (tnef->body.size > 0) { - fprintf(fptr, "NOTE;QUOTED-PRINTABLE:"); - quotedfprint (fptr, &(tnef->body)); - fprintf(fptr,"\n"); - } - - /* Business Address */ - boolean = 0; - if ((pobox = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_POST_OFFICE_BOX))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((street = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_STREET_ADDRESS))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((city = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_LOCALITY))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((state = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((zip = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_POSTAL_CODE))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((country = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_COUNTRY))) != MAPI_UNDEFINED) { - boolean = 1; - } - if (boolean == 1) { - fprintf(fptr, "ADR;QUOTED-PRINTABLE;WORK:"); - if (pobox != MAPI_UNDEFINED) { - quotedfprint (fptr, pobox); - } - fprintf(fptr, ";;"); - if (street != MAPI_UNDEFINED) { - quotedfprint (fptr, street); - } - fprintf(fptr, ";"); - if (city != MAPI_UNDEFINED) { - quotedfprint (fptr, city); - } - fprintf(fptr, ";"); - if (state != MAPI_UNDEFINED) { - quotedfprint (fptr, state); - } - fprintf(fptr, ";"); - if (zip != MAPI_UNDEFINED) { - quotedfprint (fptr, zip); - } - fprintf(fptr, ";"); - if (country != MAPI_UNDEFINED) { - quotedfprint (fptr, country); - } - fprintf(fptr,"\n"); - if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x801b))) != MAPI_UNDEFINED) { - fprintf(fptr, "LABEL;QUOTED-PRINTABLE;WORK:"); - quotedfprint (fptr, vl); - fprintf(fptr,"\n"); - } - } - - /* Home Address */ - boolean = 0; - if ((pobox = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_POST_OFFICE_BOX))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((street = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_STREET))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((city = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_CITY))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((state = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((zip = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_POSTAL_CODE))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((country = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_COUNTRY))) != MAPI_UNDEFINED) { - boolean = 1; - } - if (boolean == 1) { - fprintf(fptr, "ADR;QUOTED-PRINTABLE;HOME:"); - if (pobox != MAPI_UNDEFINED) { - quotedfprint (fptr, pobox); - } - fprintf(fptr, ";;"); - if (street != MAPI_UNDEFINED) { - quotedfprint (fptr, street); - } - fprintf(fptr, ";"); - if (city != MAPI_UNDEFINED) { - quotedfprint (fptr, city); - } - fprintf(fptr, ";"); - if (state != MAPI_UNDEFINED) { - quotedfprint (fptr, state); - } - fprintf(fptr, ";"); - if (zip != MAPI_UNDEFINED) { - quotedfprint (fptr, zip); - } - fprintf(fptr, ";"); - if (country != MAPI_UNDEFINED) { - quotedfprint (fptr, country); - } - fprintf(fptr,"\n"); - if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x801a))) != MAPI_UNDEFINED) { - fprintf(fptr, "LABEL;QUOTED-PRINTABLE;WORK:"); - quotedfprint (fptr, vl); - fprintf(fptr,"\n"); - } - } - - /* Other Address */ - boolean = 0; - if ((pobox = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_POST_OFFICE_BOX))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((street = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_STREET))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((city = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_CITY))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((state = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((zip = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_POSTAL_CODE))) != MAPI_UNDEFINED) { - boolean = 1; - } - if ((country = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_COUNTRY))) != MAPI_UNDEFINED) { - boolean = 1; - } - if (boolean == 1) { - fprintf(fptr, "ADR;QUOTED-PRINTABLE;OTHER:"); - if (pobox != MAPI_UNDEFINED) { - quotedfprint (fptr, pobox); - } - fprintf(fptr, ";;"); - if (street != MAPI_UNDEFINED) { - quotedfprint (fptr, street); - } - fprintf(fptr, ";"); - if (city != MAPI_UNDEFINED) { - quotedfprint (fptr, city); - } - fprintf(fptr, ";"); - if (state != MAPI_UNDEFINED) { - quotedfprint (fptr, state); - } - fprintf(fptr, ";"); - if (zip != MAPI_UNDEFINED) { - quotedfprint (fptr, zip); - } - fprintf(fptr, ";"); - if (country != MAPI_UNDEFINED) { - quotedfprint (fptr, country); - } - fprintf(fptr,"\n"); - } - - fprintProperty(tnef, fptr, PT_STRING8, PR_CALLBACK_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-CALLBACK:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_PRIMARY_TELEPHONE_NUMBER, "TEL;PREF:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_MOBILE_TELEPHONE_NUMBER, "TEL;CELL:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_RADIO_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-RADIO:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_CAR_TELEPHONE_NUMBER, "TEL;CAR:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_OTHER_TELEPHONE_NUMBER, "TEL;VOICE:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_PAGER_TELEPHONE_NUMBER, "TEL;PAGER:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_TELEX_NUMBER, "TEL;X-EVOLUTION-TELEX:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_ISDN_NUMBER, "TEL;ISDN:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_HOME2_TELEPHONE_NUMBER, "TEL;HOME:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_TTYTDD_PHONE_NUMBER, "TEL;X-EVOLUTION-TTYTDD:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_HOME_TELEPHONE_NUMBER, "TEL;HOME;VOICE:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_ASSISTANT_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-ASSISTANT:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_COMPANY_MAIN_PHONE_NUMBER, "TEL;WORK:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_BUSINESS_TELEPHONE_NUMBER, "TEL;WORK:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_BUSINESS2_TELEPHONE_NUMBER, "TEL;WORK;VOICE:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_PRIMARY_FAX_NUMBER, "TEL;PREF;FAX:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_BUSINESS_FAX_NUMBER, "TEL;WORK;FAX:%s\n"); - fprintProperty(tnef, fptr, PT_STRING8, PR_HOME_FAX_NUMBER, "TEL;HOME;FAX:%s\n"); - - /* Email addresses */ - if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8083))) == MAPI_UNDEFINED) { - vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8084)); - } - if (vl != MAPI_UNDEFINED) { - if (vl->size > 0) - fprintf(fptr, "EMAIL:%s\n", vl->data); - } - if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8093))) == MAPI_UNDEFINED) { - vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8094)); - } - if (vl != MAPI_UNDEFINED) { - if (vl->size > 0) - fprintf(fptr, "EMAIL:%s\n", vl->data); - } - if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x80a3))) == MAPI_UNDEFINED) { - vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x80a4)); - } - if (vl != MAPI_UNDEFINED) { - if (vl->size > 0) - fprintf(fptr, "EMAIL:%s\n", vl->data); - } - - fprintProperty(tnef, fptr, PT_STRING8, PR_BUSINESS_HOME_PAGE, "URL:%s\n"); - fprintUserProp(tnef, fptr, PT_STRING8, 0x80d8, "FBURL:%s\n"); - - /* Birthday */ - if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_SYSTIME, PR_BIRTHDAY))) != MAPI_UNDEFINED) { - fprintf(fptr, "BDAY:"); - MAPISysTimetoDTR ((guchar *) vl->data, &thedate); - fprintf(fptr, "%i-%02i-%02i\n", thedate.wYear, thedate.wMonth, thedate.wDay); - } - - /* Anniversary */ - if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_SYSTIME, PR_WEDDING_ANNIVERSARY))) != MAPI_UNDEFINED) { - fprintf(fptr, "X-EVOLUTION-ANNIVERSARY:"); - MAPISysTimetoDTR ((guchar *) vl->data, &thedate); - fprintf(fptr, "%i-%02i-%02i\n", thedate.wYear, thedate.wMonth, thedate.wDay); - } - fprintf(fptr, "END:VCARD\n"); - fclose (fptr); - } - g_free (ifilename); -} - -guchar getRruleCount (guchar a, guchar b) { - return ((a << 8) | b); -} - -guchar getRruleMonthNum (guchar a, guchar b) { - switch (a) { - case 0x00: - switch (b) { - case 0x00: - /* Jan */ - return (1); - case 0xA3: - /* May */ - return (5); - case 0xAE: - /* Nov */ - return (11); - } - break; - case 0x60: - switch (b) { - case 0xAE: - /* Feb */ - return (2); - case 0x51: - /* Jun */ - return (6); - } - break; - case 0xE0: - switch (b) { - case 0x4B: - /* Mar */ - return (3); - case 0x56: - /* Sep */ - return (9); - } - break; - case 0x40: - switch (b) { - case 0xFA: - /* Apr */ - return (4); - } - break; - case 0x20: - if (b == 0xFA) { - /* Jul */ - return (7); - } - break; - case 0x80: - if (b == 0xA8) { - /* Aug */ - return (8); - } - break; - case 0xA0: - if (b == 0xFF) { - /* Oct */ - return (10); - } - break; - case 0xC0: - if (b == 0x56) { - return (12); - } - } - - /* Error */ - return (0); -} - -gchar * getRruleDayname (guchar a) { - static gchar daystring[25]; - - *daystring = 0; - - if (a & 0x01) { - strcat(daystring, "SU,"); - } - if (a & 0x02) { - strcat(daystring, "MO,"); - } - if (a & 0x04) { - strcat(daystring, "TU,"); - } - if (a & 0x08) { - strcat(daystring, "WE,"); - } - if (a & 0x10) { - strcat(daystring, "TH,"); - } - if (a & 0x20) { - strcat(daystring, "FR,"); - } - if (a & 0x40) { - strcat(daystring, "SA,"); - } - - if (strlen (daystring)) { - daystring[strlen (daystring) - 1] = 0; - } - - return (daystring); -} - -void printRrule (FILE *fptr, gchar *recur_data, gint size, TNEFStruct *tnef) -{ - variableLength *filename; - - if (size < 0x1F) { - return; - } - - fprintf(fptr, "RRULE:FREQ="); - - if (recur_data[0x04] == 0x0A) { - fprintf(fptr, "DAILY"); - - if (recur_data[0x16] == 0x23 || recur_data[0x16] == 0x22 || - recur_data[0x16] == 0x21) { - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_I2, 0x0011))) != MAPI_UNDEFINED) { - fprintf(fptr, ";INTERVAL=%d", *(filename->data)); - } - if (recur_data[0x16] == 0x22 || recur_data[0x16] == 0x21) { - fprintf(fptr, ";COUNT=%d", - getRruleCount (recur_data[0x1B], recur_data[0x1A])); - } - } else if (recur_data[0x16] == 0x3E) { - fprintf(fptr, ";BYDAY=MO,TU,WE,TH,FR"); - if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) { - fprintf(fptr, ";COUNT=%d", - getRruleCount (recur_data[0x1F], recur_data[0x1E])); - } - } - } else if (recur_data[0x04] == 0x0B) { - fprintf(fptr, "WEEKLY;INTERVAL=%d;BYDAY=%s", - recur_data[0x0E], getRruleDayname (recur_data[0x16])); - if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) { - fprintf(fptr, ";COUNT=%d", - getRruleCount (recur_data[0x1F], recur_data[0x1E])); - } - } else if (recur_data[0x04] == 0x0C) { - fprintf(fptr, "MONTHLY"); - if (recur_data[0x06] == 0x02) { - fprintf(fptr, ";INTERVAL=%d;BYMONTHDAY=%d", recur_data[0x0E], - recur_data[0x16]); - if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) { - fprintf(fptr, ";COUNT=%d", getRruleCount(recur_data[0x1F], - recur_data[0x1E])); - } - } else if (recur_data[0x06] == 0x03) { - fprintf(fptr, ";BYDAY=%s;BYSETPOS=%d;INTERVAL=%d", - getRruleDayname (recur_data[0x16]), - recur_data[0x1A] == 0x05 ? -1 : recur_data[0x1A], - recur_data[0x0E]); - if (recur_data[0x1E] == 0x22 || recur_data[0x1E] == 0x21) { - fprintf(fptr, ";COUNT=%d", getRruleCount(recur_data[0x23], - recur_data[0x22])); - } - } - } else if (recur_data[0x04] == 0x0D) { - fprintf(fptr, "YEARLY;BYMONTH=%d", - getRruleMonthNum (recur_data[0x0A], recur_data[0x0B])); - if (recur_data[0x06] == 0x02) { - fprintf(fptr, ";BYMONTHDAY=%d", recur_data[0x16]); - } else if (recur_data[0x06] == 0x03) { - fprintf(fptr, ";BYDAY=%s;BYSETPOS=%d", - getRruleDayname (recur_data[0x16]), - recur_data[0x1A] == 0x05 ? -1 : recur_data[0x1A]); - } - if (recur_data[0x1E] == 0x22 || recur_data[0x1E] == 0x21) { - fprintf(fptr, ";COUNT=%d", getRruleCount(recur_data[0x23], - recur_data[0x22])); - } - } - fprintf(fptr, "\n"); -} - -void saveVCalendar (TNEFStruct *tnef, const gchar *tmpdir) { - gchar *ifilename; - variableLength *filename; - gchar *charptr, *charptr2; - FILE *fptr; - gint index; - DWORD *dword_ptr; - dtr thedate; - - ifilename = g_build_filename (tmpdir, "calendar.vcf", NULL); - printf("%s\n", ifilename); - - if ((fptr = fopen(ifilename, "wb"))==NULL) { - printf("Error writing file to disk!"); - } else { - fprintf(fptr, "BEGIN:VCALENDAR\n"); - if (tnef->messageClass[0] != 0) { - charptr2 = tnef->messageClass; - charptr = charptr2; - while (*charptr != 0) { - if (*charptr == '.') { - charptr2 = charptr; - } - charptr++; - } - if (strcmp(charptr2, ".MtgCncl") == 0) { - fprintf(fptr, "METHOD:CANCEL\n"); - } else { - fprintf(fptr, "METHOD:REQUEST\n"); - } - } else { - fprintf(fptr, "METHOD:REQUEST\n"); - } - fprintf(fptr, "VERSION:2.0\n"); - fprintf(fptr, "BEGIN:VEVENT\n"); - - /* UID - * After alot of comparisons, I'm reasonably sure this is totally - * wrong. But it's not really necessary. */ - - /* I think it only exists to connect future modification entries to - * this entry. so as long as it's incorrectly interpreted the same way - * every time, it should be ok :) */ - filename = NULL; - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_BINARY, 0x3))) == MAPI_UNDEFINED) { - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_BINARY, 0x23))) == MAPI_UNDEFINED) { - filename = NULL; - } - } - if (filename != NULL) { - fprintf(fptr, "UID:"); - for (index = 0; index < filename->size; index++) { - fprintf(fptr,"%02X", (guchar)filename->data[index]); - } - fprintf(fptr,"\n"); - } - - /* Sequence */ - filename = NULL; - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_LONG, 0x8201))) != MAPI_UNDEFINED) { - dword_ptr = (DWORD *) filename->data; - fprintf(fptr, "SEQUENCE:%i\n", (gint) *dword_ptr); - } - if ((filename = MAPIFindProperty (&(tnef->MapiProperties), - PROP_TAG (PT_BINARY, PR_SENDER_SEARCH_KEY))) - != MAPI_UNDEFINED) { - charptr = filename->data; - charptr2 = strstr(charptr, ":"); - if (charptr2 == NULL) - charptr2 = charptr; - else - charptr2++; - fprintf(fptr, "ORGANIZER;CN=\"%s\":MAILTO:%s\n", - charptr2, charptr2); - } - - /* Required Attendees */ - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_STRING8, 0x823b))) != MAPI_UNDEFINED) { - /* We have a list of required participants, so - write them out. */ - if (filename->size > 1) { - charptr = filename->data - 1; - while (charptr != NULL) { - charptr++; - charptr2 = strstr(charptr, ";"); - if (charptr2 != NULL) { - *charptr2 = 0; - } - while (*charptr == ' ') - charptr++; - fprintf(fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;"); - fprintf(fptr, "ROLE=REQ-PARTICIPANT;RSVP=TRUE;"); - fprintf(fptr, "CN=\"%s\":MAILTO:%s\n", - charptr, charptr); - charptr = charptr2; - } - } - /* Optional attendees */ - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_STRING8, 0x823c))) != MAPI_UNDEFINED) { - /* The list of optional participants */ - if (filename->size > 1) { - charptr = filename->data - 1; - while (charptr != NULL) { - charptr++; - charptr2 = strstr(charptr, ";"); - if (charptr2 != NULL) { - *charptr2 = 0; - } - while (*charptr == ' ') - charptr++; - fprintf(fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;"); - fprintf(fptr, "ROLE=OPT-PARTICIPANT;RSVP=TRUE;"); - fprintf(fptr, "CN=\"%s\":MAILTO:%s\n", - charptr, charptr); - charptr = charptr2; - } - } - } - } else if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_STRING8, 0x8238))) != MAPI_UNDEFINED) { - if (filename->size > 1) { - charptr = filename->data - 1; - while (charptr != NULL) { - charptr++; - charptr2 = strstr(charptr, ";"); - if (charptr2 != NULL) { - *charptr2 = 0; - } - while (*charptr == ' ') - charptr++; - fprintf(fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;"); - fprintf(fptr, "ROLE=REQ-PARTICIPANT;RSVP=TRUE;"); - fprintf(fptr, "CN=\"%s\":MAILTO:%s\n", - charptr, charptr); - charptr = charptr2; - } - } - - } - /* Summary */ - filename = NULL; - if ((filename = MAPIFindProperty (&(tnef->MapiProperties), - PROP_TAG (PT_STRING8, PR_CONVERSATION_TOPIC))) - != MAPI_UNDEFINED) { - fprintf(fptr, "SUMMARY:"); - cstylefprint (fptr, filename); - fprintf(fptr, "\n"); - } - - /* Description */ - if ((filename = MAPIFindProperty (&(tnef->MapiProperties), - PROP_TAG (PT_BINARY, PR_RTF_COMPRESSED))) - != MAPI_UNDEFINED) { - variableLength buf; - if ((buf.data = (gchar *) DecompressRTF (filename, &buf.size)) != NULL) { - fprintf(fptr, "DESCRIPTION:"); - printRtf (fptr, &buf); - free (buf.data); - } - - } - - /* Location */ - filename = NULL; - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_STRING8, 0x0002))) == MAPI_UNDEFINED) { - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_STRING8, 0x8208))) == MAPI_UNDEFINED) { - filename = NULL; - } - } - if (filename != NULL) { - fprintf(fptr,"LOCATION: %s\n", filename->data); - } - /* Date Start */ - filename = NULL; - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_SYSTIME, 0x820d))) == MAPI_UNDEFINED) { - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_SYSTIME, 0x8516))) == MAPI_UNDEFINED) { - filename = NULL; - } - } - if (filename != NULL) { - fprintf(fptr, "DTSTART:"); - MAPISysTimetoDTR ((guchar *) filename->data, &thedate); - fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n", - thedate.wYear, thedate.wMonth, thedate.wDay, - thedate.wHour, thedate.wMinute, thedate.wSecond); - } - /* Date End */ - filename = NULL; - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_SYSTIME, 0x820e))) == MAPI_UNDEFINED) { - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_SYSTIME, 0x8517))) == MAPI_UNDEFINED) { - filename = NULL; - } - } - if (filename != NULL) { - fprintf(fptr, "DTEND:"); - MAPISysTimetoDTR ((guchar *) filename->data, &thedate); - fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n", - thedate.wYear, thedate.wMonth, thedate.wDay, - thedate.wHour, thedate.wMinute, thedate.wSecond); - } - /* Date Stamp */ - filename = NULL; - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_SYSTIME, 0x8202))) != MAPI_UNDEFINED) { - fprintf(fptr, "CREATED:"); - MAPISysTimetoDTR ((guchar *) filename->data, &thedate); - fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n", - thedate.wYear, thedate.wMonth, thedate.wDay, - thedate.wHour, thedate.wMinute, thedate.wSecond); - } - /* Class */ - filename = NULL; - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_BOOLEAN, 0x8506))) != MAPI_UNDEFINED) { - dword_ptr = (DWORD *) filename->data; - fprintf(fptr, "CLASS:" ); - if (*dword_ptr == 1) { - fprintf(fptr,"PRIVATE\n"); - } else { - fprintf(fptr,"PUBLIC\n"); - } - } - /* Recurrence */ - filename = NULL; - if ((filename = MAPIFindUserProp (&(tnef->MapiProperties), - PROP_TAG (PT_BINARY, 0x8216))) != MAPI_UNDEFINED) { - printRrule (fptr, filename->data, filename->size, tnef); - } - - /* Wrap it up */ - fprintf(fptr, "END:VEVENT\n"); - fprintf(fptr, "END:VCALENDAR\n"); - fclose (fptr); - } - g_free (ifilename); -} - -void saveVTask (TNEFStruct *tnef, const gchar *tmpdir) { - variableLength *vl; - variableLength *filename; - gint index; - gchar *ifilename; - gchar *absfilename, *file; - gchar *charptr, *charptr2; - dtr thedate; - FILE *fptr; - DWORD *dword_ptr; - - vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_CONVERSATION_TOPIC)); - - if (vl == MAPI_UNDEFINED) { - return; - } - - index = strlen (vl->data); - while (vl->data[index] == ' ') - vl->data[index--] = 0; - - file = sanitize_filename (vl->data); - if (!file) - return; - absfilename = g_strconcat (file, ".vcf", NULL); - ifilename = g_build_filename (tmpdir, absfilename, NULL); - g_free (file); - g_free (absfilename); - - printf("%s\n", ifilename); - - if ((fptr = fopen(ifilename, "wb"))==NULL) { - printf("Error writing file to disk!"); - } else { - fprintf(fptr, "BEGIN:VCALENDAR\n"); - fprintf(fptr, "VERSION:2.0\n"); - fprintf(fptr, "METHOD:PUBLISH\n"); - filename = NULL; - - fprintf(fptr, "BEGIN:VTODO\n"); - if (tnef->messageID[0] != 0) { - fprintf(fptr,"UID:%s\n", tnef->messageID); - } - filename = MAPIFindUserProp (&(tnef->MapiProperties), \ - PROP_TAG (PT_STRING8, 0x8122)); - if (filename != MAPI_UNDEFINED) { - fprintf(fptr, "ORGANIZER:%s\n", filename->data); - } - - if ((filename = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_DISPLAY_TO))) != MAPI_UNDEFINED) { - filename = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x811f)); - } - if ((filename != MAPI_UNDEFINED) && (filename->size > 1)) { - charptr = filename->data - 1; - while (charptr != NULL) { - charptr++; - charptr2 = strstr(charptr, ";"); - if (charptr2 != NULL) { - *charptr2 = 0; - } - while (*charptr == ' ') - charptr++; - fprintf(fptr, "ATTENDEE;CN=%s;ROLE=REQ-PARTICIPANT:%s\n", charptr, charptr); - charptr = charptr2; - } - } - - if (tnef->subject.size > 0) { - fprintf(fptr,"SUMMARY:"); - cstylefprint (fptr,&(tnef->subject)); - fprintf(fptr,"\n"); - } - - if (tnef->body.size > 0) { - fprintf(fptr,"DESCRIPTION:"); - cstylefprint (fptr,&(tnef->body)); - fprintf(fptr,"\n"); - } - - filename = MAPIFindProperty (&(tnef->MapiProperties), \ - PROP_TAG (PT_SYSTIME, PR_CREATION_TIME)); - if (filename != MAPI_UNDEFINED) { - fprintf(fptr, "DTSTAMP:"); - MAPISysTimetoDTR ((guchar *) filename->data, &thedate); - fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n", - thedate.wYear, thedate.wMonth, thedate.wDay, - thedate.wHour, thedate.wMinute, thedate.wSecond); - } - - filename = MAPIFindUserProp (&(tnef->MapiProperties), \ - PROP_TAG (PT_SYSTIME, 0x8517)); - if (filename != MAPI_UNDEFINED) { - fprintf(fptr, "DUE:"); - MAPISysTimetoDTR ((guchar *) filename->data, &thedate); - fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n", - thedate.wYear, thedate.wMonth, thedate.wDay, - thedate.wHour, thedate.wMinute, thedate.wSecond); - } - filename = MAPIFindProperty (&(tnef->MapiProperties), \ - PROP_TAG (PT_SYSTIME, PR_LAST_MODIFICATION_TIME)); - if (filename != MAPI_UNDEFINED) { - fprintf(fptr, "LAST-MODIFIED:"); - MAPISysTimetoDTR ((guchar *) filename->data, &thedate); - fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n", - thedate.wYear, thedate.wMonth, thedate.wDay, - thedate.wHour, thedate.wMinute, thedate.wSecond); - } - /* Class */ - filename = MAPIFindUserProp (&(tnef->MapiProperties), \ - PROP_TAG (PT_BOOLEAN, 0x8506)); - if (filename != MAPI_UNDEFINED) { - dword_ptr = (DWORD *) filename->data; - fprintf(fptr, "CLASS:" ); - if (*dword_ptr == 1) { - fprintf(fptr,"PRIVATE\n"); - } else { - fprintf(fptr,"PUBLIC\n"); - } - } - fprintf(fptr, "END:VTODO\n"); - fprintf(fptr, "END:VCALENDAR\n"); - fclose (fptr); - } - g_free (ifilename); -} - -void fprintProperty (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]) { - variableLength *vl; - if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (proptype, propid))) != MAPI_UNDEFINED) { - if (vl->size > 0) { - if ((vl->size == 1) && (vl->data[0] == 0)) { - } else { - fprintf (fptr, text, vl->data); - } - } - } -} - -void fprintUserProp (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]) { - variableLength *vl; - if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (proptype, propid))) != MAPI_UNDEFINED) { - if (vl->size > 0) { - if ((vl->size == 1) && (vl->data[0] == 0)) { - } else { - fprintf (fptr, text, vl->data); - } - } - } -} - -void quotedfprint (FILE *fptr, variableLength *vl) { - gint index; - - for (index = 0; index < vl->size - 1; index++) { - if (vl->data[index] == '\n') { - fprintf(fptr, "=0A"); - } else if (vl->data[index] == '\r') { - } else { - fprintf(fptr, "%c", vl->data[index]); - } - } -} - -void cstylefprint (FILE *fptr, variableLength *vl) { - gint index; - - for (index = 0; index < vl->size - 1; index++) { - if (vl->data[index] == '\n') { - fprintf(fptr, "\\n"); - } else if (vl->data[index] == '\r') { - /* Print nothing. */ - } else if (vl->data[index] == ';') { - fprintf(fptr, "\\;"); - } else if (vl->data[index] == ',') { - fprintf(fptr, "\\,"); - } else if (vl->data[index] == '\\') { - fprintf(fptr, "\\"); - } else { - fprintf(fptr, "%c", vl->data[index]); - } - } -} - -void printRtf (FILE *fptr, variableLength *vl) { - gint index; - gchar *byte; - gint brace_ct; - gint key; - - key = 0; - brace_ct = 0; - - for (index = 0, byte = vl->data; index < vl->size; index++, byte++) { - if (*byte == '}') { - brace_ct--; - key = 0; - continue; - } - if (*byte == '{') { - brace_ct++; - continue; - } - if (*byte == '\\') { - key = 1; - } - if (isspace (*byte)) { - key = 0; - } - if ((brace_ct == 1) && (key == 0)) { - if (*byte == '\n') { - fprintf(fptr, "\\n"); - } else if (*byte == '\r') { - /* Print nothing. */ - } else if (*byte == ';') { - fprintf(fptr, "\\;"); - } else if (*byte == ',') { - fprintf(fptr, "\\,"); - } else if (*byte == '\\') { - fprintf(fptr, "\\"); - } else { - fprintf(fptr, "%c", *byte); - } - } - } - fprintf(fptr, "\n"); -} - diff --git a/plugins/vcard-inline/Makefile.am b/plugins/vcard-inline/Makefile.am deleted file mode 100644 index afde012ddf..0000000000 --- a/plugins/vcard-inline/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -if OS_WIN32 -NO_UNDEFINED_REQUIRED_LIBS = \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/e-util/libeutil.la \ - $(GNOME_PLATFORM_LIBS) -endif - -@EVO_PLUGIN_RULE@ - -plugin_DATA = org-gnome-vcard-inline.eplug - -plugin_LTLIBRARIES = liborg-gnome-vcard-inline.la - -liborg_gnome_vcard_inline_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) - -liborg_gnome_vcard_inline_la_SOURCES = vcard-inline.c - -liborg_gnome_vcard_inline_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_vcard_inline_la_LIBADD = \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/addressbook/util/libeabutil.la \ - $(top_builddir)/addressbook/gui/widgets/libeabwidgets.la \ - $(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \ - $(top_builddir)/addressbook/printing/libecontactprint.la \ - $(top_builddir)/em-format/libemformat.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -EXTRA_DIST = org-gnome-vcard-inline.eplug.xml - -BUILT_SOURCES = $(plugin_DATA) -CLEANFILES = $(BUILT_SOURCES) - --include $(top_srcdir)/git.mk diff --git a/plugins/vcard-inline/org-gnome-vcard-inline.eplug.xml b/plugins/vcard-inline/org-gnome-vcard-inline.eplug.xml deleted file mode 100644 index 45b8a7b6ef..0000000000 --- a/plugins/vcard-inline/org-gnome-vcard-inline.eplug.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0"?> -<e-plugin-list> - <e-plugin - type="shlib" - id="org.gnome.evolution.plugin.vcardInline" - location="@PLUGINDIR@/liborg-gnome-vcard-inline@SOEXT@" - _name="Inline vCards" - system_plugin="true"> - - <author name="Matthew Barnes" email="mbarnes@redhat.com"/> - <_description> - Show vCards directly in mail messages. - </_description> - - <hook class="org.gnome.evolution.mail.format:1.0"> - <group id="EMFormatHTMLDisplay"> - <item - mime_type="text/vcard" - format="org_gnome_vcard_inline_format" - flags="inline_disposition"/> - <item - mime_type="text/x-vcard" - format="org_gnome_vcard_inline_format" - flags="inline_disposition"/> - <item - mime_type="text/directory" - format="org_gnome_vcard_inline_format" - flags="inline_disposition"/> - </group> - </hook> - - </e-plugin> -</e-plugin-list> diff --git a/plugins/vcard-inline/vcard-inline.c b/plugins/vcard-inline/vcard-inline.c deleted file mode 100644 index 3b5885adbc..0000000000 --- a/plugins/vcard-inline/vcard-inline.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * 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/> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <glib/gi18n-lib.h> -#include <libebook/libebook.h> -#include <libedataserverui/libedataserverui.h> - -#include <shell/e-shell.h> -#include <addressbook/gui/merging/eab-contact-merging.h> -#include <addressbook/gui/widgets/eab-contact-display.h> -#include <addressbook/gui/widgets/eab-contact-formatter.h> -#include <addressbook/util/eab-book-util.h> -#include <mail/em-format-hook.h> -#include <mail/em-format-html.h> - -#define d(x) - -typedef struct _VCardInlinePURI VCardInlinePURI; - -struct _VCardInlinePURI { - EMFormatPURI puri; - - GSList *contact_list; - GtkWidget *contact_display; - GtkWidget *message_label; - - EABContactFormatter *formatter; - WebKitDOMElement *iframe; - WebKitDOMElement *toggle_button; - WebKitDOMElement *save_button; -}; - -/* Forward Declarations */ -void org_gnome_vcard_inline_format (gpointer ep, EMFormatHookTarget *target); -gint e_plugin_lib_enable (EPlugin *ep, gint enable); - -gint -e_plugin_lib_enable (EPlugin *ep, - gint enable) -{ - return 0; -} - -static void -org_gnome_vcard_inline_pobject_free (EMFormatPURI *object) -{ - VCardInlinePURI *vcard_object; - - vcard_object = (VCardInlinePURI *) object; - - e_client_util_free_object_slist (vcard_object->contact_list); - vcard_object->contact_list = NULL; - - if (vcard_object->contact_display != NULL) { - g_object_unref (vcard_object->contact_display); - vcard_object->contact_display = NULL; - } - - if (vcard_object->message_label != NULL) { - g_object_unref (vcard_object->message_label); - vcard_object->message_label = NULL; - } - - if (vcard_object->formatter != NULL) { - g_object_unref (vcard_object->formatter); - vcard_object->formatter = NULL; - } - - if (vcard_object->iframe != NULL) { - g_object_unref (vcard_object->iframe); - vcard_object->iframe = NULL; - } - - if (vcard_object->toggle_button != NULL) { - g_object_unref (vcard_object->toggle_button); - vcard_object->toggle_button = NULL; - } - - if (vcard_object->save_button != NULL) { - g_object_unref (vcard_object->save_button); - vcard_object->save_button = NULL; - } -} - -static void -org_gnome_vcard_inline_decode (VCardInlinePURI *vcard_object, - CamelMimePart *mime_part) -{ - CamelDataWrapper *data_wrapper; - CamelMedium *medium; - CamelStream *stream; - GSList *contact_list; - GByteArray *array; - const gchar *string; - const guint8 padding[2] = {0}; - - array = g_byte_array_new (); - medium = CAMEL_MEDIUM (mime_part); - - /* Stream takes ownership of the byte array. */ - stream = camel_stream_mem_new_with_byte_array (array); - data_wrapper = camel_medium_get_content (medium); - camel_data_wrapper_decode_to_stream_sync ( - data_wrapper, stream, NULL, NULL); - - /* because the result is not NULL-terminated */ - g_byte_array_append (array, padding, 2); - - string = (gchar *) array->data; - contact_list = eab_contact_list_from_string (string); - vcard_object->contact_list = contact_list; - - g_object_unref (mime_part); - g_object_unref (stream); -} - -static void -org_gnome_vcard_inline_client_loaded_cb (ESource *source, - GAsyncResult *result, - GSList *contact_list) -{ - EShell *shell; - EClient *client = NULL; - EBookClient *book_client; - ESourceRegistry *registry; - GSList *iter; - GError *error = NULL; - - e_client_utils_open_new_finish (source, result, &client, &error); - - if (error != NULL) { - g_warn_if_fail (client == NULL); - g_warning ( - "%s: Failed to open book client: %s", - G_STRFUNC, error->message); - g_error_free (error); - goto exit; - } - - g_return_if_fail (E_IS_BOOK_CLIENT (client)); - - book_client = E_BOOK_CLIENT (client); - - shell = e_shell_get_default (); - registry = e_shell_get_registry (shell); - - for (iter = contact_list; iter != NULL; iter = iter->next) { - EContact *contact; - - contact = E_CONTACT (iter->data); - eab_merging_book_add_contact ( - registry, book_client, contact, NULL, NULL); - } - - g_object_unref (client); - - exit: - e_client_util_free_object_slist (contact_list); -} - -static void -org_gnome_vcard_inline_save_cb (WebKitDOMEventTarget *button, - WebKitDOMEvent *event, - VCardInlinePURI *vcard_object) -{ - EShell *shell; - ESource *source; - ESourceRegistry *registry; - ESourceSelector *selector; - GSList *contact_list; - const gchar *extension_name; - GtkWidget *dialog; - - shell = e_shell_get_default (); - registry = e_shell_get_registry (shell); - extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK; - - dialog = e_source_selector_dialog_new (NULL, registry, extension_name); - - selector = e_source_selector_dialog_get_selector ( - E_SOURCE_SELECTOR_DIALOG (dialog)); - - source = e_source_registry_ref_default_address_book (registry); - e_source_selector_set_primary_selection (selector, source); - g_object_unref (source); - - if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK) { - gtk_widget_destroy (dialog); - return; - } - - source = e_source_selector_dialog_peek_primary_selection ( - E_SOURCE_SELECTOR_DIALOG (dialog)); - - gtk_widget_destroy (dialog); - - g_return_if_fail (source != NULL); - - contact_list = e_client_util_copy_object_slist (NULL, vcard_object->contact_list); - - e_client_utils_open_new ( - source, E_CLIENT_SOURCE_TYPE_CONTACTS, - FALSE, NULL, (GAsyncReadyCallback) - org_gnome_vcard_inline_client_loaded_cb, - contact_list); -} - -static void -org_gnome_vcard_inline_toggle_cb (WebKitDOMEventTarget *button, - WebKitDOMEvent *event, - EMFormatPURI *puri) -{ - VCardInlinePURI *vcard_object; - EABContactDisplayMode mode; - gchar *uri; - - vcard_object = (VCardInlinePURI *) puri; - - mode = eab_contact_formatter_get_display_mode (vcard_object->formatter); - if (mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) { - mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT; - - webkit_dom_html_element_set_inner_text ( - WEBKIT_DOM_HTML_ELEMENT (button), - _("Show Full vCard"), NULL); - - } else { - mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL; - - webkit_dom_html_element_set_inner_text ( - WEBKIT_DOM_HTML_ELEMENT (button), - _("Show Compact vCard"), NULL); - } - - eab_contact_formatter_set_display_mode (vcard_object->formatter, mode); - - uri = em_format_build_mail_uri ( - puri->emf->folder, puri->emf->message_uid, - "part_id", G_TYPE_STRING, puri->uri, - "mode", G_TYPE_INT, EM_FORMAT_WRITE_MODE_RAW, NULL); - - webkit_dom_html_iframe_element_set_src ( - WEBKIT_DOM_HTML_IFRAME_ELEMENT (vcard_object->iframe), uri); - - g_free (uri); -} - -static void -org_gnome_vcard_inline_bind_dom (WebKitDOMElement *attachment, - EMFormatPURI *puri) -{ - WebKitDOMNodeList *list; - WebKitDOMElement *iframe, *toggle_button, *save_button; - VCardInlinePURI *vcard_object; - - vcard_object = (VCardInlinePURI *) puri; - - /* IFRAME */ - list = webkit_dom_element_get_elements_by_tag_name (attachment, "iframe"); - if (webkit_dom_node_list_get_length (list) != 1) - return; - iframe = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0)); - if (vcard_object->iframe) - g_object_unref (vcard_object->iframe); - vcard_object->iframe = g_object_ref (iframe); - - /* TOGGLE DISPLAY MODE BUTTON */ - list = webkit_dom_element_get_elements_by_class_name ( - attachment, "org-gnome-vcard-inline-display-mode-button"); - if (webkit_dom_node_list_get_length (list) != 1) - return; - toggle_button = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0)); - if (vcard_object->toggle_button) - g_object_unref (vcard_object->toggle_button); - vcard_object->toggle_button = g_object_ref (toggle_button); - - /* SAVE TO ADDRESSBOOK BUTTON */ - list = webkit_dom_element_get_elements_by_class_name ( - attachment, "org-gnome-vcard-inline-save-button"); - if (webkit_dom_node_list_get_length (list) != 1) - return; - save_button = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0)); - if (vcard_object->save_button) - g_object_unref (vcard_object->save_button); - vcard_object->save_button = g_object_ref (save_button); - - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (toggle_button), - "click", G_CALLBACK (org_gnome_vcard_inline_toggle_cb), - FALSE, puri); - - webkit_dom_event_target_add_event_listener ( - WEBKIT_DOM_EVENT_TARGET (save_button), - "click", G_CALLBACK (org_gnome_vcard_inline_save_cb), - FALSE, puri); - - /* Bind collapse buttons for contact lists. */ - eab_contact_formatter_bind_dom ( - webkit_dom_html_iframe_element_get_content_document ( - WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe))); -} - -static void -org_gnome_vcard_inline_write (EMFormat *emf, - EMFormatPURI *puri, - CamelStream *stream, - EMFormatWriterInfo *info, - GCancellable *cancellable) -{ - VCardInlinePURI *vpuri; - - vpuri = (VCardInlinePURI *) puri; - - if (info->mode == EM_FORMAT_WRITE_MODE_RAW) { - - EContact *contact; - - if (vpuri->contact_list != NULL) - contact = E_CONTACT (vpuri->contact_list->data); - else - contact = NULL; - - eab_contact_formatter_format_contact_sync ( - vpuri->formatter, contact, stream, cancellable); - - } else { - gchar *str, *uri; - gint length; - const gchar *label = NULL; - EABContactDisplayMode mode; - const gchar *info = NULL; - - length = g_slist_length (vpuri->contact_list); - if (length < 1) - return; - - uri = em_format_build_mail_uri ( - emf->folder, emf->message_uid, - "part_id", G_TYPE_STRING, puri->uri, - "mode", G_TYPE_INT, EM_FORMAT_WRITE_MODE_RAW, NULL); - - mode = eab_contact_formatter_get_display_mode (vpuri->formatter); - if (mode == EAB_CONTACT_DISPLAY_RENDER_COMPACT) { - mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL; - label =_("Show Full vCard"); - } else { - mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT; - label = _("Show Compact vCard"); - } - - str = g_strdup_printf ( - "<div id=\"%s\">" - "<button type=\"button\" " - "name=\"set-display-mode\" " - "class=\"org-gnome-vcard-inline-display-mode-button\" " - "value=\"%d\">%s</button>" - "<button type=\"button\" " - "name=\"save-to-addressbook\" " - "class=\"org-gnome-vcard-inline-save-button\" " - "value=\"%s\">%s</button><br/>" - "<iframe width=\"100%%\" height=\"auto\" frameborder=\"0\"" - "src=\"%s\" name=\"%s\"></iframe>" - "</div>", - puri->uri, - mode, label, - puri->uri, _("Save To Addressbook"), - uri, puri->uri); - - camel_stream_write_string (stream, str, cancellable, NULL); - - g_free (str); - - if (length == 2) { - - info = _("There is one other contact."); - - } else if (length > 2) { - - /* Translators: This will always be two or more. */ - info = g_strdup_printf (ngettext ( - "There is %d other contact.", - "There are %d other contacts.", - length - 1), length - 1); - } - - if (info) { - - str = g_strdup_printf ( - "<div class=\"attachment-info\">%s</div>", - info); - - camel_stream_write_string (stream, str, cancellable, NULL); - - g_free (str); - } - - g_free (uri); - } -} - -void -org_gnome_vcard_inline_format (gpointer ep, - EMFormatHookTarget *target) -{ - VCardInlinePURI *vcard_object; - gint len; - - len = target->part_id->len; - g_string_append (target->part_id, ".org-gnome-vcard-inline-display"); - - vcard_object = (VCardInlinePURI *) em_format_puri_new ( - target->format, sizeof (VCardInlinePURI), - target->part, target->part_id->str); - vcard_object->puri.mime_type = g_strdup("text/html"); - vcard_object->puri.write_func = org_gnome_vcard_inline_write; - vcard_object->puri.bind_func = org_gnome_vcard_inline_bind_dom; - vcard_object->puri.free = org_gnome_vcard_inline_pobject_free; - vcard_object->puri.is_attachment = true; - vcard_object->formatter - = g_object_new ( - EAB_TYPE_CONTACT_FORMATTER, - "display-mode", EAB_CONTACT_DISPLAY_RENDER_COMPACT, - "render-maps", FALSE, NULL); - - em_format_add_puri (target->format, (EMFormatPURI *) vcard_object); - - g_object_ref (target->part); - - org_gnome_vcard_inline_decode (vcard_object, target->part); - - g_string_truncate (target->part_id, len); -} |