aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac34
-rw-r--r--modules/Makefile.am16
-rw-r--r--modules/audio-inline/Makefile.am31
-rw-r--r--modules/audio-inline/e-mail-formatter-audio-inline.c383
-rw-r--r--modules/audio-inline/e-mail-formatter-audio-inline.h30
-rw-r--r--modules/audio-inline/e-mail-parser-audio-inline.c199
-rw-r--r--modules/audio-inline/e-mail-parser-audio-inline.h30
-rw-r--r--modules/audio-inline/e-mail-part-audio-inline.h46
-rw-r--r--modules/audio-inline/evolution-module-audio-inline.c54
-rw-r--r--modules/bogofilter/evolution-bogofilter.c4
-rw-r--r--modules/itip-formatter/Makefile.am51
-rw-r--r--modules/itip-formatter/e-conflict-search-selector.c (renamed from plugins/itip-formatter/e-conflict-search-selector.c)0
-rw-r--r--modules/itip-formatter/e-conflict-search-selector.h (renamed from plugins/itip-formatter/e-conflict-search-selector.h)0
-rw-r--r--modules/itip-formatter/e-mail-formatter-itip.c219
-rw-r--r--modules/itip-formatter/e-mail-formatter-itip.h30
-rw-r--r--modules/itip-formatter/e-mail-parser-itip.c314
-rw-r--r--modules/itip-formatter/e-mail-parser-itip.h30
-rw-r--r--modules/itip-formatter/e-mail-part-itip.h123
-rw-r--r--modules/itip-formatter/e-source-conflict-search.c (renamed from plugins/itip-formatter/e-source-conflict-search.c)0
-rw-r--r--modules/itip-formatter/e-source-conflict-search.h (renamed from plugins/itip-formatter/e-source-conflict-search.h)0
-rw-r--r--modules/itip-formatter/evolution-module-itip-formatter.c75
-rw-r--r--modules/itip-formatter/itip-view.c (renamed from plugins/itip-formatter/itip-formatter.c)3580
-rw-r--r--modules/itip-formatter/itip-view.h270
-rw-r--r--modules/itip-formatter/org-gnome-itip-formatter.error.xml (renamed from plugins/itip-formatter/org-gnome-itip-formatter.error.xml)0
-rw-r--r--modules/itip-formatter/plugin/Makefile.am36
-rw-r--r--modules/itip-formatter/plugin/config-ui.c159
-rw-r--r--modules/itip-formatter/plugin/org-gnome-itip-formatter.eplug.xml (renamed from plugins/itip-formatter/org-gnome-itip-formatter.eplug.xml)13
-rw-r--r--modules/prefer-plain/Makefile.am28
-rw-r--r--modules/prefer-plain/e-mail-parser-prefer-plain.c553
-rw-r--r--modules/prefer-plain/e-mail-parser-prefer-plain.h30
-rw-r--r--modules/prefer-plain/evolution-module-prefer-plain.c73
-rw-r--r--modules/prefer-plain/plugin/Makefile.am (renamed from plugins/prefer-plain/Makefile.am)20
-rw-r--r--modules/prefer-plain/plugin/config-ui.c192
-rw-r--r--modules/prefer-plain/plugin/org-gnome-prefer-plain.eplug.xml (renamed from plugins/prefer-plain/org-gnome-prefer-plain.eplug.xml)16
-rw-r--r--modules/text-highlight/Makefile.am27
-rw-r--r--modules/text-highlight/evolution-module-text-highlight.c51
-rw-r--r--modules/text-highlight/text-highlight.c314
-rw-r--r--modules/text-highlight/text-highlight.h30
-rw-r--r--modules/tnef-attachment/Makefile.am34
-rw-r--r--modules/tnef-attachment/e-mail-parser-tnef-attachment.c (renamed from plugins/tnef-attachments/tnef-plugin.c)183
-rw-r--r--modules/tnef-attachment/e-mail-parser-tnef-attachment.h30
-rw-r--r--modules/tnef-attachment/evolution-module-tnef-attachment.c51
-rw-r--r--modules/vcard-inline/Makefile.am32
-rw-r--r--modules/vcard-inline/e-mail-formatter-vcard-inline.c249
-rw-r--r--modules/vcard-inline/e-mail-formatter-vcard-inline.h30
-rw-r--r--modules/vcard-inline/e-mail-parser-vcard-inline.c410
-rw-r--r--modules/vcard-inline/e-mail-parser-vcard-inline.h30
-rw-r--r--modules/vcard-inline/e-mail-part-vcard-inline.h50
-rw-r--r--modules/vcard-inline/evolution-module-vcard-inline.c53
-rw-r--r--plugins/audio-inline/Makefile.am39
-rw-r--r--plugins/audio-inline/audio-inline.c347
-rw-r--r--plugins/audio-inline/org-gnome-audio-inline.eplug.xml100
-rw-r--r--plugins/itip-formatter/Makefile.am56
-rw-r--r--plugins/itip-formatter/itip-view.c3062
-rw-r--r--plugins/itip-formatter/itip-view.h246
-rw-r--r--plugins/mail-to-task/mail-to-task.c1
-rw-r--r--plugins/mailing-list-actions/mailing-list-actions.c1
-rw-r--r--plugins/prefer-plain/prefer-plain.c392
-rw-r--r--plugins/tnef-attachments/Makefile.am37
-rw-r--r--plugins/tnef-attachments/org-gnome-tnef-attachments.eplug.xml26
-rw-r--r--plugins/vcard-inline/Makefile.am40
-rw-r--r--plugins/vcard-inline/org-gnome-vcard-inline.eplug.xml33
-rw-r--r--plugins/vcard-inline/vcard-inline.c452
-rw-r--r--po/POTFILES.in53
64 files changed, 7680 insertions, 5418 deletions
diff --git a/configure.ac b/configure.ac
index f234723df8..1a18edb4a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1106,8 +1106,9 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
)], [tnef_ok=yes], [tnef_ok=no])
if test "$tnef_ok" = "yes"; then
AC_MSG_RESULT([yes])
- TNEF_ATTACHMENTS="tnef-attachments"
TNEF_CFLAGS="-DHAVE_YTNEF_H"
+ AC_DEFINE(ENABLE_TNEF,1,[Define if TNEF attachments parser should be built])
+
else
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
@@ -1118,14 +1119,14 @@ else
)], [tnef_ok=yes], [tnef_ok=no])
if test "$tnef_ok" = "yes"; then
AC_MSG_RESULT([yes])
- TNEF_ATTACHMENTS="tnef-attachments"
TNEF_CFLAGS="-DHAVE_LIBYTNEF_YTNEF_H"
+ AC_DEFINE(ENABLE_TNEF,1,[Define if TNEF attachments parser should be built])
else
AC_MSG_RESULT([no])
- TNEF_ATTACHMENTS=""
TNEF_CFLAGS=""
fi
fi
+AM_CONDITIONAL([ENABLE_TNEF], [test "$tnef_ok" = "yes"])
AC_SUBST(TNEF_CFLAGS)
dnl *******************************
@@ -1298,20 +1299,20 @@ AC_ARG_ENABLE([plugins],
[enable_plugins="$enableval"],[enable_plugins=all])
dnl Add any new plugins here
-plugins_base_always="itip-formatter mark-all-read publish-calendar"
+plugins_base_always="mark-all-read publish-calendar"
plugins_base="$plugins_base_always"
dist_plugins_base="$plugins_base_always"
-plugins_standard_always="bbdb save-calendar mail-to-task mailing-list-actions prefer-plain mail-notification attachment-reminder email-custom-header face templates vcard-inline dbx-import external-editor"
+plugins_standard_always="bbdb save-calendar mail-to-task mailing-list-actions mail-notification attachment-reminder email-custom-header face templates dbx-import external-editor"
plugins_standard="$plugins_standard_always"
-dist_plugins_standard="$plugins_standard audio-inline image-inline pst-import"
+dist_plugins_standard="$plugins_standard image-inline pst-import"
plugins_experimental_always=""
-plugins_experimental="$plugins_experimental_always $TNEF_ATTACHMENTS"
-dist_plugins_experimental="$plugins_experimental_always tnef-attachments"
+plugins_experimental="$plugins_experimental_always"
+dist_plugins_experimental="$plugins_experimental_always"
dnl ******************************************************************
dnl The following plugins have additional library dependencies.
@@ -1332,12 +1333,14 @@ if test "x$enable_audio_inline" = "xyes"; then
AC_SUBST(GSTREAMER_LIBS)
if test "x$have_gst" = "xyes"; then
- plugins_standard="$plugins_standard audio-inline"
+ AC_DEFINE(ENABLE_AUDIO_INLINE, 1, [Define to add support for inlining audio attachments])
else
AC_MSG_ERROR([gstreamer-0.10 is required for the audio-inline plugin. Use --disable-audio-inline to exclude the plugin.])
fi
fi
+AM_CONDITIONAL([ENABLE_AUDIO_INLINE], [test "x$enable_audio_inline" = "xyes"])
+
dnl **************************************
dnl Weather calendars require gweather-3.0
dnl **************************************
@@ -1627,8 +1630,11 @@ mail/importers/Makefile
maint/Makefile
modules/Makefile
modules/addressbook/Makefile
+modules/audio-inline/Makefile
modules/bogofilter/Makefile
modules/calendar/Makefile
+modules/itip-formatter/Makefile
+modules/itip-formatter/plugin/Makefile
modules/mail/Makefile
modules/backup-restore/Makefile
modules/book-config-google/Makefile
@@ -1652,30 +1658,30 @@ modules/plugin-lib/Makefile
modules/plugin-manager/Makefile
modules/plugin-mono/Makefile
modules/plugin-python/Makefile
+modules/prefer-plain/Makefile
+modules/prefer-plain/plugin/Makefile
modules/spamassassin/Makefile
modules/startup-wizard/Makefile
+modules/text-highlight/Makefile
+modules/tnef-attachment/Makefile
+modules/vcard-inline/Makefile
modules/web-inspector/Makefile
plugins/Makefile
plugins/attachment-reminder/Makefile
-plugins/audio-inline/Makefile
plugins/bbdb/Makefile
plugins/dbx-import/Makefile
plugins/email-custom-header/Makefile
plugins/external-editor/Makefile
plugins/face/Makefile
plugins/image-inline/Makefile
-plugins/itip-formatter/Makefile
plugins/mail-notification/Makefile
plugins/mail-to-task/Makefile
plugins/mailing-list-actions/Makefile
plugins/mark-all-read/Makefile
-plugins/prefer-plain/Makefile
plugins/pst-import/Makefile
plugins/publish-calendar/Makefile
plugins/save-calendar/Makefile
plugins/templates/Makefile
-plugins/tnef-attachments/Makefile
-plugins/vcard-inline/Makefile
smclient/Makefile
smime/Makefile
smime/lib/Makefile
diff --git a/modules/Makefile.am b/modules/Makefile.am
index b26d161e36..16810fd55c 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -18,6 +18,14 @@ if ENABLE_ONLINE_ACCOUNTS
ONLINE_ACCOUNTS_DIR = online-accounts
endif
+if ENABLE_TNEF
+TNEF_ATTACHMENT_DIR = tnef-attachment
+endif
+
+if ENABLE_AUDIO_INLINE
+AUDIO_INLINE_DIR = audio-inline
+endif
+
SUBDIRS = \
addressbook \
bogofilter \
@@ -36,17 +44,23 @@ SUBDIRS = \
cal-config-webcal \
composer-autosave \
imap-features \
+ itip-formatter \
mail-config \
mailto-handler \
mdn \
offline-alert \
plugin-lib \
plugin-manager \
+ prefer-plain \
spamassassin \
startup-wizard \
+ text-highlight \
+ vcard-inline \
web-inspector \
$(MONO_DIR) \
$(PYTHON_DIR) \
- $(ONLINE_ACCOUNTS_DIR)
+ $(ONLINE_ACCOUNTS_DIR) \
+ $(TNEF_ATTACHMENT_DIR) \
+ $(AUDIO_INLINE_DIR)
-include $(top_srcdir)/git.mk
diff --git a/modules/audio-inline/Makefile.am b/modules/audio-inline/Makefile.am
new file mode 100644
index 0000000000..152086ba08
--- /dev/null
+++ b/modules/audio-inline/Makefile.am
@@ -0,0 +1,31 @@
+module_LTLIBRARIES = module-audio-inline.la
+
+module_audio_inline_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
+ -DG_LOG_DOMAIN=\"evolution-module-audio-inline\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GSTREAMER_CFLAGS)
+
+module_audio_inline_la_SOURCES = \
+ e-mail-formatter-audio-inline.c \
+ e-mail-formatter-audio-inline.h \
+ e-mail-parser-audio-inline.c \
+ e-mail-parser-audio-inline.h \
+ evolution-module-audio-inline.c
+
+module_audio_inline_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(top_builddir)/em-format/libemformat.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GSTREAMER_LIBS)
+
+module_audio_inline_la_LDFLAGS = \
+ -avoid-version -module $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/audio-inline/e-mail-formatter-audio-inline.c b/modules/audio-inline/e-mail-formatter-audio-inline.c
new file mode 100644
index 0000000000..4116748923
--- /dev/null
+++ b/modules/audio-inline/e-mail-formatter-audio-inline.c
@@ -0,0 +1,383 @@
+/*
+ * e-mail-formatter-audio-inline.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-mail-formatter-audio-inline.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+
+#include <libebackend/libebackend.h>
+
+#include <em-format/e-mail-formatter-extension.h>
+#include <em-format/e-mail-formatter.h>
+
+#include "e-util/e-mktemp.h"
+
+#include <camel/camel.h>
+#include <gst/gst.h>
+
+#include "e-mail-part-audio-inline.h"
+
+#define d(x)
+
+typedef struct _EMailFormatterAudioInline {
+ EExtension parent;
+} EMailFormatterAudioInline;
+
+typedef struct _EMailFormatterAudioInlineClass {
+ EExtensionClass parent_class;
+} EMailFormatterAudioInlineClass;
+
+GType e_mail_formatter_audio_inline_get_type (void);
+static void e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface);
+static void e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailFormatterAudioInline,
+ e_mail_formatter_audio_inline,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_EXTENSION,
+ e_mail_formatter_mail_extension_interface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_FORMATTER_EXTENSION,
+ e_mail_formatter_formatter_extension_interface_init));
+
+static const gchar* formatter_mime_types[] = { "application/vnd.evolution.widget.audio-inline",
+ "audio/ac3", "audio/x-ac3",
+ "audio/basic", "audio/mpeg",
+ "audio/x-mpeg", "audio/mpeg3",
+ "audio/x-mpeg3", "audio/mp3",
+ "audio/x-mp3", "audio/mp4",
+ "audio/flac", "audio/x-flac",
+ "audio/mod", "audio/x-mod",
+ "audio/x-wav", "audio/microsoft-wav",
+ "audio/x-wma", "audio/x-ms-wma",
+ "application/ogg", "application/x-ogg",
+ NULL };
+
+static void
+pause_clicked (GtkWidget *button,
+ EMailPartAudioInline *part)
+{
+ if (part->playbin) {
+ /* pause playing */
+ gst_element_set_state (part->playbin, GST_STATE_PAUSED);
+ }
+}
+
+static void
+stop_clicked (GtkWidget *button,
+ EMailPartAudioInline *part)
+{
+ if (part->playbin) {
+ /* ready to play */
+ gst_element_set_state (part->playbin, GST_STATE_READY);
+ part->target_state = GST_STATE_READY;
+ }
+}
+
+static void
+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
+gst_callback (GstBus *bus,
+ GstMessage *message,
+ gpointer data)
+{
+ EMailPartAudioInline *part = data;
+ GstMessageType msg_type;
+
+ g_return_val_if_fail (part != NULL, TRUE);
+ g_return_val_if_fail (part->playbin != NULL, TRUE);
+
+ msg_type = GST_MESSAGE_TYPE (message);
+
+ switch (msg_type) {
+ case GST_MESSAGE_ERROR:
+ gst_element_set_state (part->playbin, GST_STATE_NULL);
+ break;
+ case GST_MESSAGE_EOS:
+ gst_element_set_state (part->playbin, GST_STATE_READY);
+ break;
+ case GST_MESSAGE_STATE_CHANGED:
+ {
+ GstState old_state, new_state;
+
+ if (GST_MESSAGE_SRC (message) != GST_OBJECT (part->playbin))
+ break;
+
+ gst_message_parse_state_changed (message, &old_state, &new_state, NULL);
+
+ if (old_state == new_state)
+ break;
+
+ if (part->play_button)
+ gtk_widget_set_sensitive (
+ part->play_button,
+ new_state <= GST_STATE_PAUSED);
+ if (part->pause_button)
+ gtk_widget_set_sensitive (
+ part->pause_button,
+ new_state > GST_STATE_PAUSED);
+ if (part->stop_button)
+ gtk_widget_set_sensitive (
+ part->stop_button,
+ new_state >= GST_STATE_PAUSED);
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+static void
+play_clicked (GtkWidget *button,
+ EMailPartAudioInline *part)
+{
+ GstState cur_state;
+
+ d(printf ("audio inline formatter: play\n"));
+
+ if (!part->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 */
+ part->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 (
+ part->filename, O_RDWR | O_CREAT | O_TRUNC, 0600, NULL);
+ data = camel_medium_get_content (CAMEL_MEDIUM (part->parent.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 */
+ part->playbin = gst_element_factory_make ("playbin", "playbin");
+ if (part->playbin == NULL) {
+ g_printerr ("Failed to create gst_element_factory playbin; check your installation\n");
+ return;
+
+ }
+
+ uri = g_filename_to_uri (part->filename, NULL, NULL);
+ g_object_set (part->playbin, "uri", uri, NULL);
+ g_free (uri);
+ set_audiosink (part->playbin);
+
+ bus = gst_element_get_bus (part->playbin);
+ part->bus_id = gst_bus_add_watch (bus, gst_callback, part);
+ gst_object_unref (bus);
+
+ } else {
+ g_printerr ("GStreamer failed to initialize: %s",error ? error->message : "");
+ g_error_free (error);
+ }
+ }
+
+ gst_element_get_state (part->playbin, &cur_state, NULL, 0);
+
+ if (cur_state >= GST_STATE_PAUSED) {
+ gst_element_set_state (part->playbin, GST_STATE_READY);
+ }
+
+ if (part->playbin) {
+ /* start playing */
+ gst_element_set_state (part->playbin, GST_STATE_PLAYING);
+ }
+}
+
+static GtkWidget *
+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 gboolean
+emfe_audio_inline_format (EMailFormatterExtension *extension,
+ EMailFormatter *formatter,
+ EMailFormatterContext *context,
+ EMailPart *part,
+ CamelStream *stream,
+ GCancellable *cancellable)
+{
+ gchar *str;
+
+ str = g_strdup_printf (
+ "<object type=\"application/vnd.evolution.widget.audio-inline\" "
+ "width=\"100%%\" height=\"auto\" data=\"%s\" id=\"%s\"></object>",
+ part->id, part->id);
+
+ camel_stream_write_string (stream, str, cancellable, NULL);
+
+ g_free (str);
+
+ return TRUE;
+}
+
+static GtkWidget *
+emfe_audio_inline_get_widget (EMailFormatterExtension *extension,
+ EMailPartList *context,
+ EMailPart *part,
+ GHashTable *params)
+{
+ GtkWidget *box;
+ EMailPartAudioInline *ai_part;
+
+ g_return_val_if_fail (E_MAIL_PART_IS (part, EMailPartAudioInline), NULL);
+ ai_part = (EMailPartAudioInline *) part;
+
+ /* it is OK to call UI functions here, since we are called from UI thread */
+ box = gtk_hbutton_box_new ();
+ ai_part->play_button = g_object_ref (
+ add_button (box, GTK_STOCK_MEDIA_PLAY,
+ G_CALLBACK (play_clicked), part, TRUE));
+ ai_part->pause_button = g_object_ref (
+ add_button (box, GTK_STOCK_MEDIA_PAUSE,
+ G_CALLBACK (pause_clicked), part, FALSE));
+ ai_part->stop_button = g_object_ref (
+ add_button (box, GTK_STOCK_MEDIA_STOP,
+ G_CALLBACK (stop_clicked), part, FALSE));
+
+ gtk_widget_show (box);
+
+ return box;
+}
+
+static const gchar *
+emfe_audio_inline_get_display_name (EMailFormatterExtension *extension)
+{
+ return _("Audio Player");
+}
+
+static const gchar *
+emfe_audio_inline_get_description (EMailFormatterExtension *extension)
+{
+ return _("Play the attachment in embedded audio player");
+}
+
+static const gchar **
+emfe_audio_inline_mime_types (EMailExtension *extension)
+{
+ return formatter_mime_types;
+}
+
+static void
+e_mail_formatter_audio_inline_constructed (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_formatter_audio_inline_class_init (EMailFormatterAudioInlineClass *klass)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ e_mail_formatter_audio_inline_parent_class = g_type_class_peek_parent (klass);
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = e_mail_formatter_audio_inline_constructed;
+
+ extension_class = E_EXTENSION_CLASS (klass);
+ extension_class->extensible_type = E_TYPE_MAIL_FORMATTER_EXTENSION_REGISTRY;
+}
+
+static void
+e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface)
+{
+ iface->format = emfe_audio_inline_format;
+ iface->get_widget = emfe_audio_inline_get_widget;
+ iface->get_display_name = emfe_audio_inline_get_display_name;
+ iface->get_description = emfe_audio_inline_get_description;
+}
+
+static void
+e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface)
+{
+ iface->mime_types = emfe_audio_inline_mime_types;
+}
+
+static void
+e_mail_formatter_audio_inline_init (EMailFormatterAudioInline *formatter)
+{
+
+}
+
+void
+e_mail_formatter_audio_inline_type_register (GTypeModule *type_module)
+{
+ e_mail_formatter_audio_inline_register_type (type_module);
+}
+
+static void
+e_mail_formatter_audio_inline_class_finalize (EMailFormatterAudioInlineClass *klass)
+{
+
+}
diff --git a/modules/audio-inline/e-mail-formatter-audio-inline.h b/modules/audio-inline/e-mail-formatter-audio-inline.h
new file mode 100644
index 0000000000..1960f382da
--- /dev/null
+++ b/modules/audio-inline/e-mail-formatter-audio-inline.h
@@ -0,0 +1,30 @@
+/*
+ * e-mail-formatter-audio-inline.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_MAIL_FORMATTER_AUDIO_INLINE_H
+#define E_MAIL_FORMATTER_AUDIO_INLINE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_formatter_audio_inline_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_FORMATTER_AUDIO_INLINE_H */
diff --git a/modules/audio-inline/e-mail-parser-audio-inline.c b/modules/audio-inline/e-mail-parser-audio-inline.c
new file mode 100644
index 0000000000..0e872971f4
--- /dev/null
+++ b/modules/audio-inline/e-mail-parser-audio-inline.c
@@ -0,0 +1,199 @@
+/*
+ * e-mail-parser-audio-inline.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/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include "e-mail-parser-audio-inline.h"
+#include "e-mail-part-audio-inline.h"
+
+#include <camel/camel.h>
+
+#include <em-format/e-mail-extension-registry.h>
+#include <em-format/e-mail-parser-extension.h>
+#include <em-format/e-mail-part.h>
+
+#include <libebackend/libebackend.h>
+
+#define d(x)
+
+typedef struct _EMailParserInlineAudio {
+ EExtension parent;
+} EMailParserAudioInline;
+
+typedef struct _EMailParserAudioInlineClass {
+ EExtensionClass parent_class;
+} EMailParserAudioInlineClass;
+
+GType e_mail_parser_audio_inline_get_type (void);
+static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
+static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailParserAudioInline,
+ e_mail_parser_audio_inline,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_EXTENSION,
+ e_mail_parser_mail_extension_interface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_PARSER_EXTENSION,
+ e_mail_parser_parser_extension_interface_init));
+
+static const gchar* parser_mime_types[] = { "audio/ac3", "audio/x-ac3",
+ "audio/basic", "audio/mpeg",
+ "audio/x-mpeg", "audio/mpeg3",
+ "audio/x-mpeg3", "audio/mp3",
+ "audio/x-mp3", "audio/mp4",
+ "audio/flac", "audio/x-flac",
+ "audio/mod", "audio/x-mod",
+ "audio/x-wav", "audio/microsoft-wav",
+ "audio/x-wma", "audio/x-ms-wma",
+ "application/ogg", "application/x-ogg",
+ NULL };
+
+static void
+mail_part_audio_inline_free (EMailPart *mail_part)
+{
+ EMailPartAudioInline *ai_part = (EMailPartAudioInline *) mail_part;
+
+ g_clear_object (&ai_part->play_button);
+ g_clear_object (&ai_part->pause_button);
+ g_clear_object (&ai_part->stop_button);
+
+ if (ai_part->filename) {
+ g_unlink (ai_part->filename);
+ g_free (ai_part->filename);
+ ai_part->filename = NULL;
+ }
+
+ if (ai_part->bus_id) {
+ g_source_remove (ai_part->bus_id);
+ ai_part->bus_id = 0;
+ }
+
+ if (ai_part->playbin) {
+ gst_element_set_state (ai_part->playbin, GST_STATE_NULL);
+ gst_object_unref (ai_part->playbin);
+ ai_part->playbin = NULL;
+ }
+}
+
+static GSList *
+empe_audio_inline_parse (EMailParserExtension *extension,
+ EMailParser *parser,
+ CamelMimePart *part,
+ GString *part_id,
+ GCancellable *cancellable)
+{
+ EMailPartAudioInline *mail_part;
+ gint len;
+
+ len = part_id->len;
+ g_string_append (part_id, ".org-gnome-audio-inline-button-panel");
+
+ d(printf ("audio inline formatter: format classid %s\n", part_id->str));
+
+ mail_part = (EMailPartAudioInline *) e_mail_part_subclass_new (
+ part, part_id->str, sizeof (EMailPartAudioInline),
+ (GFreeFunc) mail_part_audio_inline_free);
+ mail_part->parent.mime_type = camel_content_type_simple (
+ camel_mime_part_get_content_type (part));
+ mail_part->parent.is_attachment = TRUE;
+ g_string_truncate (part_id, len);
+
+ return e_mail_parser_wrap_as_attachment (
+ parser, part, g_slist_append (NULL, mail_part),
+ part_id, cancellable);
+}
+
+static guint32
+empe_audio_inline_get_flags (EMailParserExtension *extension)
+{
+ return E_MAIL_PARSER_EXTENSION_INLINE_DISPOSITION;
+}
+
+static const gchar **
+empe_mime_types (EMailExtension *extension)
+{
+ return parser_mime_types;
+}
+
+void
+e_mail_parser_audio_inline_type_register (GTypeModule *type_module)
+{
+ e_mail_parser_audio_inline_register_type (type_module);
+}
+
+static void
+e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
+{
+ iface->mime_types = empe_mime_types;
+}
+
+static void
+e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
+{
+ iface->parse = empe_audio_inline_parse;
+ iface->get_flags = empe_audio_inline_get_flags;
+}
+
+static void
+e_mail_parser_audio_inline_constructed (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_parser_audio_inline_class_init (EMailParserAudioInlineClass *klass)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ e_mail_parser_audio_inline_parent_class = g_type_class_peek_parent (klass);
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = e_mail_parser_audio_inline_constructed;
+
+ extension_class = E_EXTENSION_CLASS (klass);
+ extension_class->extensible_type = E_TYPE_MAIL_PARSER_EXTENSION_REGISTRY;
+}
+
+static void
+e_mail_parser_audio_inline_class_finalize (EMailParserAudioInlineClass *klass)
+{
+
+}
+
+static void
+e_mail_parser_audio_inline_init (EMailParserAudioInline *self)
+{
+}
diff --git a/modules/audio-inline/e-mail-parser-audio-inline.h b/modules/audio-inline/e-mail-parser-audio-inline.h
new file mode 100644
index 0000000000..8c80becb20
--- /dev/null
+++ b/modules/audio-inline/e-mail-parser-audio-inline.h
@@ -0,0 +1,30 @@
+/*
+ * e-mail-parser-audio-inline.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_MAIL_PARSER_AUDIO_INLINE_H
+#define E_MAIL_PARSER_AUDIO_INLINE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_parser_audio_inline_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_PARSER_AUDIO_INLINE_H */
diff --git a/modules/audio-inline/e-mail-part-audio-inline.h b/modules/audio-inline/e-mail-part-audio-inline.h
new file mode 100644
index 0000000000..e087ecdff6
--- /dev/null
+++ b/modules/audio-inline/e-mail-part-audio-inline.h
@@ -0,0 +1,46 @@
+/*
+ * e-mail-part-audio-inline.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_MAIL_PART_AUDIO_INLINE_H
+#define E_MAIL_PART_AUDIO_INLINE_H
+
+#include <glib-object.h>
+
+#include <em-format/e-mail-part.h>
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EMailPartAudioInline EMailPartAudioInline;
+
+struct _EMailPartAudioInline {
+ EMailPart parent;
+
+ gchar *filename;
+ GstElement *playbin;
+ gulong bus_id;
+ GstState target_state;
+ GtkWidget *play_button;
+ GtkWidget *pause_button;
+ GtkWidget *stop_button;
+};
+
+G_END_DECLS
+
+#endif /* E_MAIL_PART_AUDIO_INLINE_H */
+
diff --git a/modules/audio-inline/evolution-module-audio-inline.c b/modules/audio-inline/evolution-module-audio-inline.c
new file mode 100644
index 0000000000..b5dffb183e
--- /dev/null
+++ b/modules/audio-inline/evolution-module-audio-inline.c
@@ -0,0 +1,54 @@
+/*
+ * evolution-module-audio-inline.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-mail-formatter-audio-inline.h"
+#include "e-mail-parser-audio-inline.h"
+
+#include <gmodule.h>
+
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+const gchar * g_module_check_init (GModule *module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ /* Register dynamically loaded types. */
+
+ e_mail_parser_audio_inline_type_register (type_module);
+ e_mail_formatter_audio_inline_type_register (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
+
+G_MODULE_EXPORT const gchar *
+g_module_check_init (GModule *module)
+{
+ /* FIXME Until mail is split into a module library and a
+ * reusable shared library, prevent the module from
+ * being unloaded. Unloading the module resets all
+ * static variables, which screws up foo_get_type()
+ * functions among other things. */
+ g_module_make_resident (module);
+
+ return NULL;
+}
+
diff --git a/modules/bogofilter/evolution-bogofilter.c b/modules/bogofilter/evolution-bogofilter.c
index 0467c0f654..7d00888565 100644
--- a/modules/bogofilter/evolution-bogofilter.c
+++ b/modules/bogofilter/evolution-bogofilter.c
@@ -16,6 +16,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <config.h>
#include <sys/types.h>
#include <sys/wait.h>
diff --git a/modules/itip-formatter/Makefile.am b/modules/itip-formatter/Makefile.am
new file mode 100644
index 0000000000..84fd8830a3
--- /dev/null
+++ b/modules/itip-formatter/Makefile.am
@@ -0,0 +1,51 @@
+module_LTLIBRARIES = module-itip-formatter.la
+
+module_itip_formatter_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
+ -DG_LOG_DOMAIN=\"evolution-module-itip-formatter\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS)
+
+module_itip_formatter_la_SOURCES = \
+ e-conflict-search-selector.c \
+ e-conflict-search-selector.h \
+ e-mail-formatter-itip.c \
+ e-mail-formatter-itip.h \
+ e-mail-parser-itip.c \
+ e-mail-parser-itip.h \
+ e-source-conflict-search.c \
+ e-sourec-conflict-search.h \
+ itip-view.c \
+ itip-view.h \
+ evolution-module-itip-formatter.c
+
+module_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)
+
+module_itip_formatter_la_LDFLAGS = \
+ -avoid-version -module $(NO_UNDEFINED)
+
+error_DATA = org-gnome-itip-formatter.error.xml
+errordir = $(privdatadir)/errors
+
+BUILT_SOURCES = $(error_DATA)
+
+CLEANFILES = $(BUILT_SOURCES)
+
+EXTRA_DIST = \
+ org-gnome-itip-formatter.error.xml
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/itip-formatter/e-conflict-search-selector.c b/modules/itip-formatter/e-conflict-search-selector.c
index 8f497f5d4f..8f497f5d4f 100644
--- a/plugins/itip-formatter/e-conflict-search-selector.c
+++ b/modules/itip-formatter/e-conflict-search-selector.c
diff --git a/plugins/itip-formatter/e-conflict-search-selector.h b/modules/itip-formatter/e-conflict-search-selector.h
index 091e1c9328..091e1c9328 100644
--- a/plugins/itip-formatter/e-conflict-search-selector.h
+++ b/modules/itip-formatter/e-conflict-search-selector.h
diff --git a/modules/itip-formatter/e-mail-formatter-itip.c b/modules/itip-formatter/e-mail-formatter-itip.c
new file mode 100644
index 0000000000..ebec6bc56c
--- /dev/null
+++ b/modules/itip-formatter/e-mail-formatter-itip.c
@@ -0,0 +1,219 @@
+/*
+ * e-mail-formatter-itip.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-mail-formatter-itip.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+
+#include <em-format/e-mail-formatter-extension.h>
+#include <em-format/e-mail-formatter.h>
+#include <em-format/e-mail-part-utils.h>
+#include <libebackend/libebackend.h>
+
+#include "itip-view.h"
+#include "e-mail-part-itip.h"
+
+#define d(x)
+
+typedef struct _EMailFormatterItip {
+ EExtension parent;
+} EMailFormatterItip;
+
+typedef struct _EMailFormatterItipClass {
+ EExtensionClass parent_class;
+} EMailFormatterItipClass;
+
+GType e_mail_formatter_itip_get_type (void);
+static void e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface);
+static void e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailFormatterItip,
+ e_mail_formatter_itip,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_EXTENSION,
+ e_mail_formatter_mail_extension_interface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_FORMATTER_EXTENSION,
+ e_mail_formatter_formatter_extension_interface_init));
+
+static const gchar* formatter_mime_types[] = { "text/calendar" , NULL };
+
+static gboolean
+emfe_itip_format (EMailFormatterExtension *extension,
+ EMailFormatter *formatter,
+ EMailFormatterContext *context,
+ EMailPart *part,
+ CamelStream *stream,
+ GCancellable *cancellable)
+{
+ GString *buffer;
+ EMailPartItip *itip_part;
+
+ g_return_val_if_fail (E_MAIL_PART_IS (part, EMailPartItip), FALSE);
+ itip_part = (EMailPartItip *) part;
+
+ if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) {
+ buffer = g_string_sized_new (1024);
+
+ itip_part->view = itip_view_new (itip_part, itip_part->registry);
+
+ itip_view_init_view (itip_part->view);
+ itip_view_write_for_printing (itip_part->view, buffer);
+
+ } else if (context->mode == E_MAIL_FORMATTER_MODE_RAW) {
+ buffer = g_string_sized_new (2048);
+
+ itip_view_write (buffer);
+
+ } else {
+ gchar *uri;
+
+ /* mark message as containing calendar, thus it will show the
+ * icon in message list now on */
+ if (context->message_uid && context->folder &&
+ !camel_folder_get_message_user_flag (
+ context->folder, context->message_uid, "$has_cal")) {
+
+ camel_folder_set_message_user_flag (
+ context->folder, context->message_uid,
+ "$has_cal", TRUE);
+ }
+
+ itip_part->folder = g_object_ref (context->folder);
+ itip_part->uid = g_strdup (context->message_uid);
+ itip_part->msg = g_object_ref (context->message);
+
+ uri = e_mail_part_build_uri (context->folder, context->message_uid,
+ "part_id", G_TYPE_STRING, part->id,
+ "mode", G_TYPE_INT, E_MAIL_FORMATTER_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, part->id, part->id);
+
+ g_free (uri);
+ }
+
+ camel_stream_write_string (stream, buffer->str, cancellable, NULL);
+
+ g_string_free (buffer, TRUE);
+
+ return TRUE;
+}
+
+static const gchar *
+emfe_itip_get_display_name (EMailFormatterExtension *extension)
+{
+ return _("ITIP");
+}
+
+static const gchar *
+emfe_itip_get_description (EMailFormatterExtension *extension)
+{
+ return _("Display part as an invitation");
+}
+
+static const gchar **
+emfe_itip_mime_types (EMailExtension *extension)
+{
+ return formatter_mime_types;
+}
+
+static void
+e_mail_formatter_itip_constructed (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_formatter_itip_finalize (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_remove_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_formatter_itip_class_init (EMailFormatterItipClass *klass)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ e_mail_formatter_itip_parent_class = g_type_class_peek_parent (klass);
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = e_mail_formatter_itip_constructed;
+ object_class->finalize = e_mail_formatter_itip_finalize;
+
+ extension_class = E_EXTENSION_CLASS (klass);
+ extension_class->extensible_type = E_TYPE_MAIL_FORMATTER_EXTENSION_REGISTRY;
+}
+
+static void
+e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface)
+{
+ iface->format = emfe_itip_format;
+ iface->get_display_name = emfe_itip_get_display_name;
+ iface->get_description = emfe_itip_get_description;
+}
+
+static void
+e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface)
+{
+ iface->mime_types = emfe_itip_mime_types;
+}
+
+static void
+e_mail_formatter_itip_init (EMailFormatterItip *formatter)
+{
+}
+
+void
+e_mail_formatter_itip_type_register (GTypeModule *type_module)
+{
+ e_mail_formatter_itip_register_type (type_module);
+}
+
+static void
+e_mail_formatter_itip_class_finalize (EMailFormatterItipClass *klass)
+{
+
+}
diff --git a/modules/itip-formatter/e-mail-formatter-itip.h b/modules/itip-formatter/e-mail-formatter-itip.h
new file mode 100644
index 0000000000..737926d578
--- /dev/null
+++ b/modules/itip-formatter/e-mail-formatter-itip.h
@@ -0,0 +1,30 @@
+/*
+ * e-mail-formatter-itip.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_MAIL_FORMATTER_ITIP_H
+#define E_MAIL_FORMATTER_ITIP_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_formatter_itip_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_FORMATTER_ITIP_H */
diff --git a/modules/itip-formatter/e-mail-parser-itip.c b/modules/itip-formatter/e-mail-parser-itip.c
new file mode 100644
index 0000000000..f8000aa46f
--- /dev/null
+++ b/modules/itip-formatter/e-mail-parser-itip.c
@@ -0,0 +1,314 @@
+/*
+ * 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 "e-mail-parser-itip.h"
+
+#include <em-format/e-mail-extension-registry.h>
+#include <em-format/e-mail-parser-extension.h>
+#include <em-format/e-mail-part.h>
+
+#include <misc/e-attachment.h>
+
+#include "e-mail-part-itip.h"
+#include "itip-view.h"
+#include <shell/e-shell.h>
+
+#define CONF_KEY_DELETE "delete-processed"
+
+#define d(x)
+
+typedef struct _EMailParserItip {
+ EExtension parent;
+} EMailParserItip;
+
+typedef struct _EMailParserItipClass {
+ EExtensionClass parent_class;
+} EMailParserItipClass;
+
+GType e_mail_parser_itip_get_type (void);
+static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
+static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailParserItip,
+ e_mail_parser_itip,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_EXTENSION,
+ e_mail_parser_mail_extension_interface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_PARSER_EXTENSION,
+ e_mail_parser_parser_extension_interface_init));
+
+static const gchar* parser_mime_types[] = { "text/calendar", NULL };
+
+static void
+mail_part_itip_free (EMailPart *mail_part)
+{
+ EMailPartItip *pitip = (EMailPartItip *) mail_part;
+ gint i;
+
+ g_cancellable_cancel (pitip->cancellable);
+ g_clear_object (&pitip->cancellable);
+ g_clear_object (&pitip->registry);
+
+ 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);
+
+ g_clear_object (&pitip->view);
+}
+
+/******************************************************************************/
+
+static void
+bind_itip_view (EMailPart *part,
+ WebKitDOMElement *element)
+{
+ GString *buffer;
+ WebKitDOMDocument *document;
+ ItipView *view;
+ EMailPartItip *pitip;
+
+ if (!WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element)) {
+
+ WebKitDOMNodeList *nodes;
+ guint length, i;
+
+ nodes = webkit_dom_element_get_elements_by_tag_name (
+ element, "iframe");
+ length = webkit_dom_node_list_get_length (nodes);
+ for (i = 0; i < length; i++) {
+
+ element = WEBKIT_DOM_ELEMENT (
+ webkit_dom_node_list_item (nodes, i));
+ break;
+ }
+
+ }
+
+ g_return_if_fail (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element));
+
+ buffer = g_string_new ("");
+ document = webkit_dom_html_iframe_element_get_content_document (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (element));
+ pitip = E_MAIL_PART_ITIP (part);
+
+ 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));
+
+ itip_view_init_view (view);
+ g_string_free (buffer, TRUE);
+}
+
+/*******************************************************************************/
+
+static GSList *
+empe_itip_parse (EMailParserExtension *extension,
+ EMailParser *parser,
+ CamelMimePart *part,
+ GString *part_id,
+ GCancellable *cancellable)
+{
+ EShell *shell;
+ GSettings *settings;
+ EMailPartItip *itip_part;
+ CamelDataWrapper *content;
+ CamelStream *stream;
+ GByteArray *byte_array;
+ gint len;
+
+ len = part_id->len;
+ g_string_append_printf (part_id, ".itip");
+
+ settings = g_settings_new ("org.gnome.evolution.plugin.itip");
+ shell = e_shell_get_default ();
+
+ itip_part = (EMailPartItip *) e_mail_part_subclass_new (
+ part, part_id->str, sizeof (EMailPartItip),
+ (GFreeFunc) mail_part_itip_free);
+ itip_part->parent.mime_type = g_strdup ("text/calendar");
+ itip_part->parent.bind_func = bind_itip_view;
+ itip_part->delete_message = g_settings_get_boolean (settings, CONF_KEY_DELETE);
+ itip_part->has_organizer = FALSE;
+ itip_part->no_reply_wanted = FALSE;
+ itip_part->part = part;
+ itip_part->cancellable = g_cancellable_new ();
+ itip_part->real_comps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ itip_part->registry = g_object_ref (e_shell_get_registry (shell));
+
+ g_object_unref (settings);
+
+ /* This is non-gui thread. Download the part for using in the main thread */
+ content = camel_medium_get_content ((CamelMedium *) 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)
+ itip_part->vcalendar = NULL;
+ else
+ itip_part->vcalendar = g_strndup (
+ (gchar *) byte_array->data, byte_array->len);
+
+ g_object_unref (stream);
+ g_string_truncate (part_id, len);
+
+ return g_slist_append (NULL, itip_part);
+}
+
+static guint32
+empe_itip_get_flags (EMailParserExtension *extension)
+{
+ return E_MAIL_PARSER_EXTENSION_INLINE_DISPOSITION;
+}
+
+static const gchar **
+empe_mime_types (EMailExtension *extension)
+{
+ return parser_mime_types;
+}
+
+void
+e_mail_parser_itip_type_register (GTypeModule *type_module)
+{
+ e_mail_parser_itip_register_type (type_module);
+}
+
+static void
+e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
+{
+ iface->mime_types = empe_mime_types;
+}
+
+static void
+e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
+{
+ iface->parse = empe_itip_parse;
+ iface->get_flags = empe_itip_get_flags;
+}
+
+static void
+e_mail_parser_itip_constructed (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_parser_itip_finalize (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_remove_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_parser_itip_class_init (EMailParserItipClass *klass)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ e_mail_parser_itip_parent_class = g_type_class_peek_parent (klass);
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = e_mail_parser_itip_constructed;
+ object_class->finalize = e_mail_parser_itip_finalize;
+
+ extension_class = E_EXTENSION_CLASS (klass);
+ extension_class->extensible_type = E_TYPE_MAIL_PARSER_EXTENSION_REGISTRY;
+}
+
+static void
+e_mail_parser_itip_class_finalize (EMailParserItipClass *klass)
+{
+
+}
+
+static void
+e_mail_parser_itip_init (EMailParserItip *self)
+{
+}
diff --git a/modules/itip-formatter/e-mail-parser-itip.h b/modules/itip-formatter/e-mail-parser-itip.h
new file mode 100644
index 0000000000..956af460d0
--- /dev/null
+++ b/modules/itip-formatter/e-mail-parser-itip.h
@@ -0,0 +1,30 @@
+/*
+ * e-mail-parser-itip.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_MAIL_PARSER_ITIP_H
+#define E_MAIL_PARSER_ITIP_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_parser_itip_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_PARSER_ITIP_H */
diff --git a/modules/itip-formatter/e-mail-part-itip.h b/modules/itip-formatter/e-mail-part-itip.h
new file mode 100644
index 0000000000..d1d577a675
--- /dev/null
+++ b/modules/itip-formatter/e-mail-part-itip.h
@@ -0,0 +1,123 @@
+/*
+ * 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_MAIL_PART_ITIP_H
+#define E_MAIL_PART_ITIP_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libecal/libecal.h>
+#include <libedataserverui/libedataserverui.h>
+#include <libebackend/libebackend.h>
+
+#include <em-format/e-mail-part.h>
+
+#include "itip-view.h"
+
+#define E_MAIL_PART_ITIP(p) ((EMailPartItip *) p)
+
+G_BEGIN_DECLS
+
+typedef struct _EMailPartItip EMailPartItip;
+
+struct _EMailPartItip {
+ EMailPart parent;
+
+ 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 */
+
+ ItipView *view;
+};
+
+typedef struct _EMailPartItip EMailPartItip;
+
+G_END_DECLS
+
+#endif /* E_MAIL_PART_ITIP_H */
diff --git a/plugins/itip-formatter/e-source-conflict-search.c b/modules/itip-formatter/e-source-conflict-search.c
index c2f5eb6e99..c2f5eb6e99 100644
--- a/plugins/itip-formatter/e-source-conflict-search.c
+++ b/modules/itip-formatter/e-source-conflict-search.c
diff --git a/plugins/itip-formatter/e-source-conflict-search.h b/modules/itip-formatter/e-source-conflict-search.h
index f91fcc4d43..f91fcc4d43 100644
--- a/plugins/itip-formatter/e-source-conflict-search.h
+++ b/modules/itip-formatter/e-source-conflict-search.h
diff --git a/modules/itip-formatter/evolution-module-itip-formatter.c b/modules/itip-formatter/evolution-module-itip-formatter.c
new file mode 100644
index 0000000000..13a73a30d7
--- /dev/null
+++ b/modules/itip-formatter/evolution-module-itip-formatter.c
@@ -0,0 +1,75 @@
+/*
+ * evolution-module-itip-formatter.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-mail-formatter-itip.h"
+#include "e-mail-parser-itip.h"
+
+#include <gmodule.h>
+#include <gio/gio.h>
+
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+const gchar * g_module_check_init (GModule *module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ GSettings *settings;
+ gchar **disabled_plugins;
+ gint i = 0;
+
+ settings = g_settings_new ("org.gnome.evolution");
+ disabled_plugins = g_settings_get_strv (settings, "disabled-eplugins");
+
+ for (i = 0; disabled_plugins && disabled_plugins[i] != NULL; i++) {
+
+ if (g_strcmp0 (
+ disabled_plugins[i],
+ "org.gnome.evolution.itip_formatter") == 0) {
+
+ g_strfreev (disabled_plugins);
+ g_object_unref (settings);
+ return;
+ }
+
+ }
+
+ e_mail_parser_itip_type_register (type_module);
+ e_mail_formatter_itip_type_register (type_module);
+
+ g_strfreev (disabled_plugins);
+ g_object_unref (settings);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
+
+G_MODULE_EXPORT const gchar *
+g_module_check_init (GModule *module)
+{
+ /* FIXME Until mail is split into a module library and a
+ * reusable shared library, prevent the module from
+ * being unloaded. Unloading the module resets all
+ * static variables, which screws up foo_get_type()
+ * functions among other things. */
+ g_module_make_resident (module);
+
+ return NULL;
+}
diff --git a/plugins/itip-formatter/itip-formatter.c b/modules/itip-formatter/itip-view.c
index 6780d09505..5e655eb74d 100644
--- a/plugins/itip-formatter/itip-formatter.c
+++ b/modules/itip-formatter/itip-view.c
@@ -25,11 +25,14 @@
#endif
#include <string.h>
-#include <gtk/gtk.h>
#include <glib/gi18n.h>
-
-#include <libecal/libecal.h>
#include <libedataserverui/libedataserverui.h>
+#include <libedataserver/libedataserver.h>
+
+#include <e-util/e-util.h>
+#include <e-util/e-unicode.h>
+#include <calendar/gui/itip-utils.h>
+#include <webkit/webkitdom.h>
#include <libevolution-utils/e-alert-dialog.h>
#include <e-util/e-mktemp.h>
@@ -42,109 +45,3060 @@
#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"
+#include "e-mail-part-itip.h"
#define d(x)
-struct _ItipPURI {
- EMFormatPURI puri;
+#define MEETING_ICON "stock_new-meeting"
- const EMFormatHandler *handle;
- CamelFolder *folder;
- CamelMimeMessage *msg;
- CamelMimePart *part;
+#define ITIP_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), ITIP_TYPE_VIEW, ItipViewPrivate))
- gchar *uid;
+G_DEFINE_TYPE (ItipView, itip_view, G_TYPE_OBJECT)
+
+typedef struct {
+ ItipViewInfoItemType type;
+ gchar *message;
+
+ guint id;
+} ItipViewInfoItem;
+struct _ItipViewPrivate {
ESourceRegistry *registry;
- GHashTable *clients[E_CAL_CLIENT_SOURCE_TYPE_LAST];
+ gulong source_added_id;
+ gulong source_removed_id;
+ gchar *extension_name;
- ECalClient *current_client;
+ ItipViewMode mode;
ECalClientSourceType type;
- /* cancelled when freeing the puri */
- GCancellable *cancellable;
+ gchar *sender;
+ gchar *organizer;
+ gchar *organizer_sentby;
+ gchar *delegator;
+ gchar *attendee;
+ gchar *attendee_sentby;
+ gchar *proxy;
- 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;
+ 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;
- 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 */
+ gboolean is_recur_set;
+
+ gint needs_decline : 1;
+
+ WebKitDOMDocument *dom_document;
+ EMailPartItip *itip_part;
+
+ 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
};
-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);
+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) {
+ gchar *tmp;
+ tmp = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL);
+ g_free (sender);
+ sender = tmp;
+ }
+
+ 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) {
+ gchar *tmp;
+ tmp = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL);
+ g_free (sender);
+ sender = tmp;
+ }
+
+ 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;
+
+ if (priv->sender)
+ g_free (priv->sender);
+
+ 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);
+}
+
+EMailPartItip *
+itip_view_get_mail_part (ItipView *view)
+{
+ g_return_val_if_fail (ITIP_IS_VIEW (view), NULL);
+
+ return view->priv->itip_part;
+}
+
+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);
+}
+
+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);
+ }
+}
+
+static void
+itip_view_init (ItipView *view)
+{
+ view->priv = ITIP_VIEW_GET_PRIVATE (view);
+
+}
+
+ItipView *
+itip_view_new (EMailPartItip *puri,
+ ESourceRegistry *registry)
+{
+ ItipView *view;
+
+ view = ITIP_VIEW (g_object_new (
+ ITIP_TYPE_VIEW,
+ "registry", registry,
+ NULL));
+ view->priv->itip_part = puri;
+
+ return 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);
+ }
+}
+
+/******************************************************************************/
typedef struct {
- ItipPURI *puri;
+ EMailPartItip *puri;
ItipView *view;
GCancellable *cancellable;
gboolean keep_alarm_check;
@@ -160,13 +3114,6 @@ typedef struct {
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)
@@ -239,7 +3186,7 @@ find_attendee_if_sentby (icalcomponent *ical_comp,
}
static void
-find_to_address (ItipPURI *pitip,
+find_to_address (EMailPartItip *itip_part,
icalcomponent *ical_comp,
icalparameter_partstat *status)
{
@@ -248,32 +3195,31 @@ find_to_address (ItipPURI *pitip,
GList *list, *link;
const gchar *extension_name;
- registry = pitip->registry;
+ registry = itip_part->registry;
extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
- if (pitip->to_address != NULL)
+ if (itip_part->to_address != NULL)
return;
- if (pitip->msg != NULL && pitip->folder != NULL) {
+ if (itip_part->msg != NULL && itip_part->folder != NULL) {
ESource *source;
source = em_utils_guess_mail_identity (
- registry, pitip->msg, pitip->folder);
+ registry, itip_part->msg, itip_part->folder);
if (source != NULL) {
extension = e_source_get_extension (source, extension_name);
- pitip->to_address = e_source_mail_identity_dup_address (extension);
+ itip_part->to_address = e_source_mail_identity_dup_address (extension);
g_object_unref (source);
}
}
- if (pitip->to_address != NULL)
+ if (itip_part->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)) {
@@ -295,20 +3241,20 @@ find_to_address (ItipPURI *pitip,
param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER);
if (param != NULL)
- pitip->to_name = g_strdup (icalparameter_get_cn (param));
+ itip_part->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));
+ itip_part->to_address = g_strdup (itip_strip_mailto (text));
g_free (text);
- g_strstrip (pitip->to_address);
+ g_strstrip (itip_part->to_address);
- pitip->my_address = g_strdup (address);
+ itip_part->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;
+ itip_part->no_reply_wanted = TRUE;
if (status) {
param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER);
@@ -320,19 +3266,20 @@ find_to_address (ItipPURI *pitip,
g_list_free_full (list, (GDestroyNotify) g_object_unref);
- if (pitip->to_address != NULL)
+ if (itip_part->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);
@@ -343,7 +3290,6 @@ find_to_address (ItipPURI *pitip,
const gchar *address;
gchar *text;
-
if (!e_source_get_enabled (source))
continue;
@@ -356,20 +3302,20 @@ find_to_address (ItipPURI *pitip,
param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER);
if (param != NULL)
- pitip->to_name = g_strdup (icalparameter_get_cn (param));
+ itip_part->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));
+ itip_part->to_address = g_strdup (itip_strip_mailto (text));
g_free (text);
- g_strstrip (pitip->to_address);
+ g_strstrip (itip_part->to_address);
- pitip->my_address = g_strdup (address);
+ itip_part->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;
+ itip_part->no_reply_wanted = TRUE;
if (status) {
param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER);
@@ -383,7 +3329,7 @@ find_to_address (ItipPURI *pitip,
}
static void
-find_from_address (ItipPURI *pitip,
+find_from_address (EMailPartItip *pitip,
icalcomponent *ical_comp)
{
GList *list, *link;
@@ -457,7 +3403,7 @@ find_from_address (ItipPURI *pitip,
}
static ECalComponent *
-get_real_item (ItipPURI *pitip)
+get_real_item (EMailPartItip *pitip)
{
ECalComponent *comp = NULL;
ESource *source;
@@ -474,7 +3420,7 @@ get_real_item (ItipPURI *pitip)
}
static void
-adjust_item (ItipPURI *pitip,
+adjust_item (EMailPartItip *pitip,
ECalComponent *comp)
{
ECalComponent *real_comp;
@@ -502,7 +3448,7 @@ adjust_item (ItipPURI *pitip,
}
static void
-set_buttons_sensitive (ItipPURI *pitip,
+set_buttons_sensitive (EMailPartItip *pitip,
ItipView *view)
{
gboolean read_only = TRUE;
@@ -540,7 +3486,7 @@ cal_opened_cb (GObject *source_object,
{
ESource *source = E_SOURCE (source_object);
ItipView *view = user_data;
- ItipPURI *pitip = itip_view_get_puri (view);
+ EMailPartItip *pitip = itip_view_get_mail_part (view);
ECalClientSourceType source_type;
EClient *client = NULL;
ECalClient *cal_client;
@@ -599,7 +3545,7 @@ cal_opened_cb (GObject *source_object,
}
static void
-start_calendar_server (ItipPURI *pitip,
+start_calendar_server (EMailPartItip *pitip,
ItipView *view,
ESource *source,
ECalClientSourceType type,
@@ -631,7 +3577,7 @@ start_calendar_server (ItipPURI *pitip,
}
static void
-start_calendar_server_by_uid (ItipPURI *pitip,
+start_calendar_server_by_uid (EMailPartItip *pitip,
ItipView *view,
const gchar *uid,
ECalClientSourceType type)
@@ -653,7 +3599,7 @@ source_selected_cb (ItipView *view,
ESource *source,
gpointer data)
{
- ItipPURI *pitip = data;
+ EMailPartItip *pitip = data;
itip_view_set_buttons_sensitive (view, FALSE);
@@ -666,7 +3612,7 @@ static void
find_cal_update_ui (FormatItipFindData *fd,
ECalClient *cal_client)
{
- ItipPURI *pitip;
+ EMailPartItip *pitip;
ItipView *view;
ESource *source;
@@ -745,7 +3691,7 @@ decrease_find_data (FormatItipFindData *fd)
if (fd->count == 0 && !g_cancellable_is_cancelled (fd->cancellable)) {
gboolean rsvp_enabled = FALSE;
- ItipPURI *pitip = fd->puri;
+ EMailPartItip *pitip = fd->puri;
ItipView *view = fd->view;
itip_view_remove_lower_info_item (view, pitip->progress_info_id);
@@ -793,14 +3739,14 @@ decrease_find_data (FormatItipFindData *fd)
itip_view_set_extension_name (view, extension_name);
g_signal_connect (
- view, "source_selected",
+ 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? */
+ /* 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);
@@ -990,7 +3936,7 @@ find_cal_opened_cb (GObject *source_object,
{
ESource *source = E_SOURCE (source_object);
FormatItipFindData *fd = user_data;
- ItipPURI *pitip = fd->puri;
+ EMailPartItip *pitip = fd->puri;
ItipView *view = fd->view;
ECalClientSourceType source_type;
EClient *client = NULL;
@@ -1054,9 +4000,9 @@ find_cal_opened_cb (GObject *source_object,
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? */
+ /* 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,
@@ -1077,7 +4023,7 @@ find_cal_opened_cb (GObject *source_object,
}
static void
-find_server (ItipPURI *pitip,
+find_server (EMailPartItip *pitip,
ItipView *view,
ECalComponent *comp)
{
@@ -1118,6 +4064,7 @@ find_server (ItipPURI *pitip,
* 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);
@@ -1159,12 +4106,12 @@ find_server (ItipPURI *pitip,
pitip->progress_info_id = itip_view_add_lower_info_item (
view, ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS,
- _("Opening the calendar. Please wait..."));
+ _("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"));
+ _("Searching for an existing version of this appointment"));
}
for (; link != NULL; link = g_list_next (link)) {
@@ -1402,7 +4349,7 @@ get_uri_for_part (CamelMimePart *mime_part)
}
static void
-update_item_progress_info (ItipPURI *pitip,
+update_item_progress_info (EMailPartItip *pitip,
ItipView *view,
const gchar *message)
{
@@ -1430,7 +4377,7 @@ update_item_progress_info (ItipPURI *pitip,
}
static void
-finish_message_delete_with_rsvp (ItipPURI *pitip,
+finish_message_delete_with_rsvp (EMailPartItip *pitip,
ItipView *view,
ECalClient *client)
{
@@ -1514,7 +4461,7 @@ finish_message_delete_with_rsvp (ItipPURI *pitip,
E_CAL_COMPONENT_METHOD_REPLY,
comp, pitip->current_client,
pitip->top_level, NULL, NULL, TRUE, FALSE) &&
- pitip->folder != NULL) {
+ pitip->folder) {
camel_folder_set_message_flags (
pitip->folder, pitip->uid,
CAMEL_MESSAGE_ANSWERED,
@@ -1535,7 +4482,7 @@ receive_objects_ready_cb (GObject *ecalclient,
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);
+ EMailPartItip *pitip = itip_view_get_mail_part (view);
gboolean save_schedules;
GError *error = NULL;
@@ -1638,7 +4585,7 @@ receive_objects_ready_cb (GObject *ecalclient,
}
static void
-update_item (ItipPURI *pitip,
+update_item (EMailPartItip *pitip,
ItipView *view,
ItipViewResponse response)
{
@@ -1869,7 +4816,7 @@ send_comp_to_attendee (ESourceRegistry *registry,
}
static void
-remove_delegate (ItipPURI *pitip,
+remove_delegate (EMailPartItip *pitip,
ItipView *view,
const gchar *delegate,
const gchar *delegator,
@@ -1929,7 +4876,7 @@ modify_object_cb (GObject *ecalclient,
{
ECalClient *client = E_CAL_CLIENT (ecalclient);
ItipView *view = user_data;
- ItipPURI *pitip = itip_view_get_puri (view);
+ EMailPartItip *pitip = itip_view_get_mail_part (view);
GError *error = NULL;
if (!e_cal_client_modify_object_finish (client, result, &error)) {
@@ -1956,7 +4903,7 @@ modify_object_cb (GObject *ecalclient,
}
static void
-update_attendee_status_icalcomp (ItipPURI *pitip,
+update_attendee_status_icalcomp (EMailPartItip *pitip,
ItipView *view,
icalcomponent *icalcomp)
{
@@ -2059,11 +5006,12 @@ update_attendee_status_icalcomp (ItipPURI *pitip,
new_prop = find_attendee (org_icalcomp, itip_strip_mailto (a->value));
icalcomponent_add_property (icalcomp, icalproperty_new_clone (new_prop));
- } else
+ } else {
change_status (
pitip->registry, icalcomp,
itip_strip_mailto (a->value),
a->status);
+ }
e_cal_component_rescan (comp);
}
@@ -2101,7 +5049,7 @@ update_attendee_status_get_object_without_rid_cb (GObject *ecalclient,
{
ECalClient *client = E_CAL_CLIENT (ecalclient);
ItipView *view = user_data;
- ItipPURI *pitip = itip_view_get_puri (view);
+ EMailPartItip *pitip = itip_view_get_mail_part (view);
icalcomponent *icalcomp = NULL;
GError *error = NULL;
@@ -2132,7 +5080,7 @@ update_attendee_status_get_object_with_rid_cb (GObject *ecalclient,
{
ECalClient *client = E_CAL_CLIENT (ecalclient);
ItipView *view = user_data;
- ItipPURI *pitip = itip_view_get_puri (view);
+ EMailPartItip *pitip = itip_view_get_mail_part (view);
icalcomponent *icalcomp = NULL;
GError *error = NULL;
@@ -2178,7 +5126,7 @@ update_attendee_status_get_object_with_rid_cb (GObject *ecalclient,
}
static void
-update_attendee_status (ItipPURI *pitip,
+update_attendee_status (EMailPartItip *pitip,
ItipView *view)
{
const gchar *uid = NULL;
@@ -2202,7 +5150,7 @@ update_attendee_status (ItipPURI *pitip,
}
static void
-send_item (ItipPURI *pitip,
+send_item (EMailPartItip *pitip,
ItipView *view)
{
ECalComponent *comp;
@@ -2303,7 +5251,7 @@ attachment_load_finish (EAttachment *attachment,
}
static void
-save_vcalendar_cb (ItipPURI *pitip)
+save_vcalendar_cb (EMailPartItip *pitip)
{
EAttachment *attachment;
EShell *shell;
@@ -2354,7 +5302,7 @@ set_itip_error (ItipView *view,
}
static gboolean
-extract_itip_data (ItipPURI *pitip,
+extract_itip_data (EMailPartItip *pitip,
ItipView *view,
gboolean *have_alarms)
{
@@ -2654,7 +5602,7 @@ static MailMsgInfo open_calendar_info = {
static gboolean
idle_open_cb (gpointer data)
{
- ItipPURI *pitip = data;
+ EMailPartItip *pitip = data;
struct _opencal_msg *m;
gchar *start, *end;
@@ -2675,7 +5623,7 @@ view_response_cb (ItipView *view,
ItipViewResponse response,
gpointer data)
{
- ItipPURI *pitip = data;
+ EMailPartItip *pitip = data;
gboolean status = FALSE;
icalproperty *prop;
ECalComponentTransparency trans;
@@ -2727,10 +5675,10 @@ view_response_cb (ItipView *view,
break;
case ITIP_VIEW_RESPONSE_TENTATIVE:
status = change_status (
- pitip->registry,
- pitip->ical_comp,
- pitip->to_address,
- ICAL_PARTSTAT_TENTATIVE);
+ 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;
@@ -2839,9 +5787,8 @@ in_proper_folder (ESourceRegistry *registry,
return res;
}
-static void
-init_itip_view (ItipPURI *info,
- ItipView *view)
+void
+itip_view_init_view (ItipView *view)
{
EShell *shell;
EShellSettings *shell_settings;
@@ -2857,7 +5804,10 @@ init_itip_view (ItipPURI *info,
gint i;
gboolean response_enabled;
gboolean have_alarms = FALSE;
- EMFormat *emf = info->puri.emf;
+ EMailPartItip *info;
+
+ info = view->priv->itip_part;
+ g_return_if_fail (info != NULL);
shell = e_shell_get_default ();
registry = e_shell_get_registry (shell);
@@ -2880,7 +5830,7 @@ init_itip_view (ItipPURI *info,
if (!extract_itip_data (info, view, &have_alarms))
return;
- response_enabled = in_proper_folder (registry, emf->folder);
+ response_enabled = in_proper_folder (registry, info->folder);
if (!response_enabled) {
itip_view_set_mode (view, ITIP_VIEW_MODE_HIDE_ALL);
@@ -3185,321 +6135,3 @@ init_itip_view (ItipPURI *info,
}
}
}
-
-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/modules/itip-formatter/itip-view.h b/modules/itip-formatter/itip-view.h
new file mode 100644
index 0000000000..60b8b1d4ba
--- /dev/null
+++ b/modules/itip-formatter/itip-view.h
@@ -0,0 +1,270 @@
+/*
+ *
+ * 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>
+#include <libedataserver/libedataserver.h>
+
+G_BEGIN_DECLS
+
+#define ITIP_TYPE_VIEW (itip_view_get_type ())
+#define ITIP_VIEW(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), ITIP_TYPE_VIEW, ItipView))
+#define ITIP_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ITIP_TYPE_VIEW, ItipViewClass))
+#define ITIP_IS_VIEW(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), ITIP_TYPE_VIEW))
+#define ITIP_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ITIP_TYPE_VIEW))
+#define ITIP_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ITIP_TYPE_VIEW, ItipViewClass))
+
+typedef struct _ItipView ItipView;
+typedef struct _ItipViewPrivate ItipViewPrivate;
+typedef struct _ItipViewClass ItipViewClass;
+typedef struct _EMailPartItip EMailPartItip;
+
+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_instance;
+
+ 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 (EMailPartItip *puri,
+ ESourceRegistry *registry);
+void itip_view_init_view (ItipView *view);
+
+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);
+
+EMailPartItip * itip_view_get_mail_part (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);
+
+void itip_view_set_mode (ItipView *view,
+ ItipViewMode mode);
+ItipViewMode itip_view_get_mode (ItipView *view);
+
+void itip_view_set_item_type (ItipView *view,
+ ECalClientSourceType type);
+ECalClientSourceType
+ itip_view_get_item_type (ItipView *view);
+
+void itip_view_set_organizer (ItipView *view,
+ const gchar *organizer);
+const gchar * itip_view_get_organizer (ItipView *view);
+
+void itip_view_set_organizer_sentby (ItipView *view,
+ const gchar *sentby);
+const gchar * itip_view_get_organizer_sentby (ItipView *view);
+
+void itip_view_set_attendee (ItipView *view,
+ const gchar *attendee);
+const gchar * itip_view_get_attendee (ItipView *view);
+
+void itip_view_set_attendee_sentby (ItipView *view,
+ const gchar *sentby);
+const gchar * itip_view_get_attendee_sentby (ItipView *view);
+
+void itip_view_set_delegator (ItipView *view,
+ const gchar *delegator);
+const gchar * itip_view_get_delegator (ItipView *view);
+
+void itip_view_set_proxy (ItipView *view,
+ const gchar *proxy);
+const gchar * itip_view_get_proxy (ItipView *view);
+
+void itip_view_set_summary (ItipView *view,
+ const gchar *summary);
+const gchar * itip_view_get_summary (ItipView *view);
+
+void itip_view_set_location (ItipView *view,
+ const gchar *location);
+const gchar * itip_view_get_location (ItipView *view);
+
+void itip_view_set_status (ItipView *view,
+ const gchar *status);
+const gchar * itip_view_get_status (ItipView *view);
+
+void itip_view_set_comment (ItipView *view,
+ const gchar *comment);
+const gchar * itip_view_get_comment (ItipView *view);
+
+void itip_view_set_description (ItipView *view,
+ const gchar *description);
+const gchar * itip_view_get_description (ItipView *view);
+
+void itip_view_set_start (ItipView *view,
+ struct tm *start,
+ gboolean is_date);
+const struct tm *
+ itip_view_get_start (ItipView *view,
+ gboolean *is_date);
+
+void itip_view_set_end (ItipView *view,
+ struct tm *end,
+ gboolean is_date);
+const struct tm *
+ itip_view_get_end (ItipView *view,
+ 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);
+
+void itip_view_set_source (ItipView *view,
+ ESource *source);
+ESource * itip_view_ref_source (ItipView *view);
+
+void itip_view_set_rsvp (ItipView *view,
+ gboolean rsvp);
+gboolean itip_view_get_rsvp (ItipView *view);
+
+void itip_view_set_show_rsvp_check (ItipView *view,
+ gboolean show);
+gboolean itip_view_get_show_rsvp_check (ItipView *view);
+
+void itip_view_set_update (ItipView *view,
+ gboolean update);
+gboolean itip_view_get_update (ItipView *view);
+
+void itip_view_set_show_update_check (ItipView *view,
+ gboolean show);
+gboolean itip_view_get_show_update_check (ItipView *view);
+
+void itip_view_set_rsvp_comment (ItipView *view,
+ const gchar *comment);
+gchar * itip_view_get_rsvp_comment (ItipView *view);
+
+void itip_view_set_buttons_sensitive (ItipView *view,
+ gboolean sensitive);
+gboolean itip_view_get_buttons_sensitive (ItipView *view);
+
+void itip_view_set_show_recur_check (ItipView *view,
+ gboolean show);
+gboolean itip_view_get_recur_check_state (ItipView *view);
+
+void itip_view_set_needs_decline (ItipView *view,
+ gboolean needs_decline);
+
+void itip_view_set_show_free_time_check
+ (ItipView *view,
+ gboolean show);
+gboolean itip_view_get_free_time_check_state
+ (ItipView *view);
+
+void itip_view_set_show_keep_alarm_check
+ (ItipView *view,
+ gboolean show);
+gboolean itip_view_get_keep_alarm_check_state
+ (ItipView *view);
+
+void itip_view_set_show_inherit_alarm_check
+ (ItipView *view,
+ gboolean show);
+gboolean itip_view_get_inherit_alarm_check_state
+ (ItipView *view);
+
+void itip_view_set_error (ItipView *view,
+ const gchar *error_html,
+ gboolean show_save_btn);
+
+G_END_DECLS
+
+#endif
diff --git a/plugins/itip-formatter/org-gnome-itip-formatter.error.xml b/modules/itip-formatter/org-gnome-itip-formatter.error.xml
index e5d84c67af..e5d84c67af 100644
--- a/plugins/itip-formatter/org-gnome-itip-formatter.error.xml
+++ b/modules/itip-formatter/org-gnome-itip-formatter.error.xml
diff --git a/modules/itip-formatter/plugin/Makefile.am b/modules/itip-formatter/plugin/Makefile.am
new file mode 100644
index 0000000000..b84059c2b4
--- /dev/null
+++ b/modules/itip-formatter/plugin/Makefile.am
@@ -0,0 +1,36 @@
+@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 \
+ -I$(top_srcdir)/modules/itip-formatter \
+ -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS)
+
+liborg_gnome_itip_formatter_la_SOURCES = \
+ config-ui.c
+
+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)/modules/itip-formatter/module-itip-formatter.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS)
+
+BUILT_SOURCES = $(plugin_DATA)
+
+CLEANFILES = $(BUILT_SOURCES)
+
+EXTRA_DIST = \
+ org-gnome-itip-formatter.eplug.xml
diff --git a/modules/itip-formatter/plugin/config-ui.c b/modules/itip-formatter/plugin/config-ui.c
new file mode 100644
index 0000000000..9ba6f05b0e
--- /dev/null
+++ b/modules/itip-formatter/plugin/config-ui.c
@@ -0,0 +1,159 @@
+/*
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <mail/em-config.h>
+
+#include <shell/e-shell.h>
+#include <libedataserver/libedataserver.h>
+#include <libecal/libecal.h>
+#include <modules/itip-formatter/e-conflict-search-selector.h>
+#include <modules/itip-formatter/e-source-conflict-search.h>
+
+#define CONF_KEY_DELETE "delete-processed"
+
+GtkWidget *itip_formatter_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
+
+gint
+e_plugin_lib_enable (EPlugin *ep,
+ gint enable)
+{
+ return 0;
+}
+
+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/org-gnome-itip-formatter.eplug.xml b/modules/itip-formatter/plugin/org-gnome-itip-formatter.eplug.xml
index 1cc441a37d..b60b0e129f 100644
--- a/plugins/itip-formatter/org-gnome-itip-formatter.eplug.xml
+++ b/modules/itip-formatter/plugin/org-gnome-itip-formatter.eplug.xml
@@ -1,19 +1,10 @@
<?xml version="1.0"?>
<e-plugin-list>
- <e-plugin id="org.gnome.evolution.itip_formatter"
+ <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">
@@ -21,4 +12,4 @@
</group>
</hook>
</e-plugin>
-</e-plugin-list>
+</e-plugin-list> \ No newline at end of file
diff --git a/modules/prefer-plain/Makefile.am b/modules/prefer-plain/Makefile.am
new file mode 100644
index 0000000000..e4e6b56d02
--- /dev/null
+++ b/modules/prefer-plain/Makefile.am
@@ -0,0 +1,28 @@
+SUBDIRS=plugin
+
+module_LTLIBRARIES = module-prefer-plain.la
+
+module_prefer_plain_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
+ -DG_LOG_DOMAIN=\"evolution-module-prefer-plain\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS)
+
+module_prefer_plain_la_SOURCES = \
+ e-mail-parser-prefer-plain.c \
+ e-mail-parser-prefer-plain.h \
+ evolution-module-prefer-plain.c
+
+module_prefer_plain_la_LIBADD = \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(top_builddir)/em-format/libemformat.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS)
+
+module_prefer_plain_la_LDFLAGS = \
+ -avoid-version -module $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/prefer-plain/e-mail-parser-prefer-plain.c b/modules/prefer-plain/e-mail-parser-prefer-plain.c
new file mode 100644
index 0000000000..37da8d3a43
--- /dev/null
+++ b/modules/prefer-plain/e-mail-parser-prefer-plain.c
@@ -0,0 +1,553 @@
+/*
+ * 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/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "e-mail-parser-prefer-plain.h"
+
+#include <em-format/e-mail-extension-registry.h>
+#include <em-format/e-mail-parser-extension.h>
+#include <em-format/e-mail-part.h>
+#include <em-format/e-mail-part-utils.h>
+
+#include <libebackend/libebackend.h>
+
+#define d(x)
+
+typedef struct _EMailParserPreferPlain {
+ EExtension parent;
+
+ GSettings *settings;
+ gint mode;
+ gboolean show_suppressed;
+} EMailParserPreferPlain;
+
+typedef struct _EMailParserPreferPlainClass {
+ EExtensionClass parent_class;
+} EMailParserPreferPlainClass;
+
+GType e_mail_parser_prefer_plain_get_type (void);
+static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
+static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
+
+enum {
+ EPP_NORMAL,
+ EPP_PREFER,
+ EPP_TEXT
+};
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailParserPreferPlain,
+ e_mail_parser_prefer_plain,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_EXTENSION,
+ e_mail_parser_mail_extension_interface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_PARSER_EXTENSION,
+ e_mail_parser_parser_extension_interface_init));
+
+static const gchar* parser_mime_types[] = { "multipart/alternative",
+ "text/html",
+ NULL };
+
+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.") },
+};
+
+enum {
+ PROP_0,
+ PROP_MODE,
+ PROP_SHOW_SUPPRESSED
+};
+
+static GSList *
+make_part_attachment (EMailParser *parser,
+ CamelMimePart *part,
+ GString *part_id,
+ gboolean force_html,
+ GCancellable *cancellable)
+{
+ GSList *parts;
+
+ if (camel_content_type_is (camel_mime_part_get_content_type (part), "text", "html")) {
+ EMailPart *mail_part;
+ gint len;
+ /* 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);
+ }
+
+ len = part_id->len;
+ g_string_append (part_id, ".text_html");
+ mail_part = e_mail_part_new (part, part_id->str);
+ mail_part->mime_type = g_strdup ("text/html");
+ g_string_truncate (part_id, len);
+
+ parts = e_mail_parser_wrap_as_attachment (
+ parser, part, g_slist_append (NULL, mail_part),
+ part_id, 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_val_if_fail (content != NULL, NULL);
+
+ new_part = camel_mime_part_new ();
+ camel_medium_set_content (CAMEL_MEDIUM (new_part), content);
+
+ parts = e_mail_parser_parse_part (
+ parser, new_part, part_id, cancellable);
+
+ g_object_unref (new_part);
+ } else {
+ parts = e_mail_parser_parse_part (
+ parser, part, part_id, cancellable);
+ }
+
+ return parts;
+}
+
+static GSList *
+export_as_attachments (CamelMultipart *mp,
+ EMailParser *parser,
+ CamelMimePart *except,
+ GString *part_id,
+ GCancellable *cancellable)
+{
+ gint i, nparts;
+ CamelMimePart *part;
+ gint len;
+ GSList *parts;
+
+ if (!mp || !CAMEL_IS_MULTIPART (mp))
+ return NULL;
+
+ len = part_id->len;
+ nparts = camel_multipart_get_number (mp);
+ parts = NULL;
+ 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)) {
+ parts = g_slist_concat (parts,
+ export_as_attachments (
+ multipart, parser,
+ except, part_id,
+ cancellable));
+ } else {
+ parts = g_slist_concat (parts,
+ make_part_attachment (
+ parser, part, part_id,
+ FALSE, cancellable));
+ }
+ g_string_truncate (part_id, len);
+ }
+ }
+
+ return parts;
+}
+
+static GSList *
+empe_prefer_plain_parse (EMailParserExtension *extension,
+ EMailParser *parser,
+ CamelMimePart *part,
+ GString *part_id,
+ GCancellable *cancellable)
+{
+ EMailParserPreferPlain *emp_pp;
+ CamelMultipart *mp;
+ CamelMimePart *display_part = NULL, *calendar_part = NULL;
+ gint i, nparts, partidlen, displayid = 0, calendarid = 0;
+ GSList *parts;
+
+ emp_pp = (EMailParserPreferPlain *) extension;
+
+ /* We 'can' parse HTML as well!
+ * The reason simply is to convert the HTML part to attachment in some
+ * cases, otherwise we will return NULL and fallback to "normal" parser. */
+ if (camel_content_type_is (camel_mime_part_get_content_type (part), "text", "html")) {
+ GQueue *extensions;
+ EMailExtensionRegistry *reg;
+
+ reg = e_mail_parser_get_extension_registry (parser);
+ extensions = e_mail_extension_registry_get_for_mime_type (
+ reg, "text/html");
+
+ if (emp_pp->mode != EPP_TEXT
+ || strstr (part_id->str, ".alternative-prefer-plain.") != NULL
+ || e_mail_part_is_inline (part, extensions)) {
+
+ return NULL;
+
+ } else if (emp_pp->show_suppressed) {
+ return make_part_attachment (
+ parser, part, part_id,
+ TRUE, cancellable);
+ }
+
+ /* Return an empty item. We MUST return something, otherwise
+ * the parser would think we have failed to parse the part
+ * and would let a fallback extension to parse it and we don't
+ * want that... */
+ /* FIXME: In theory we could parse it anyway and just set
+ * is_hidden to TRUE....? */
+ return g_slist_alloc ();
+ }
+
+ mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);
+ partidlen = part_id->len;
+
+ parts = NULL;
+ if (emp_pp->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 (part_id, ".alternative-prefer-plain.%d", displayid);
+ /* FIXME Not passing a GCancellable here. */
+ parts = e_mail_parser_parse_part_as (
+ parser, display_part, part_id,
+ "text/html", cancellable);
+
+ g_string_truncate (part_id, partidlen);
+ } else {
+ /* Parser will automatically fallback to next extension */
+ return NULL;
+
+ }
+
+ return parts;
+
+ } else if (!CAMEL_IS_MULTIPART (mp)) {
+ return e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution.source", cancellable);
+ }
+
+ 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(part_id, ".alternative-prefer-plain.%d", displayid);
+ parts = g_slist_concat (parts,
+ e_mail_parser_parse_part_as (
+ parser, display_part, part_id,
+ "text/plain", cancellable));
+
+ g_string_truncate (part_id, partidlen);
+ }
+
+ /* all other parts are attachments */
+ if (emp_pp->show_suppressed) {
+ parts = g_slist_concat (parts,
+ export_as_attachments (
+ mp, parser, display_part, part_id,
+ cancellable));
+ } else if (calendar_part) {
+ g_string_append_printf(part_id, ".alternative-prefer-plain.%d", calendarid);
+ parts = g_slist_concat (parts,
+ make_part_attachment (
+ parser, calendar_part, part_id,
+ FALSE, NULL));
+ }
+
+ g_string_truncate (part_id, partidlen);
+
+ return parts;
+}
+
+static const gchar **
+empe_mime_types (EMailExtension *extension)
+{
+ return parser_mime_types;
+}
+
+void
+e_mail_parser_prefer_plain_type_register (GTypeModule *type_module)
+{
+ e_mail_parser_prefer_plain_register_type (type_module);
+}
+
+static void
+e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
+{
+ iface->mime_types = empe_mime_types;
+}
+
+static void
+e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
+{
+ iface->parse = empe_prefer_plain_parse;
+}
+
+static void
+e_mail_parser_prefer_plain_constructed (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_parser_prefer_plain_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EMailParserPreferPlain *parser;
+
+ parser = (EMailParserPreferPlain *) object;
+
+ switch (property_id) {
+ case PROP_MODE:
+ g_value_set_int (value, parser->mode);
+ return;
+ case PROP_SHOW_SUPPRESSED:
+ g_value_set_boolean (value, parser->show_suppressed);
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+e_mail_parser_prefer_plain_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EMailParserPreferPlain *parser;
+
+ parser = (EMailParserPreferPlain *) object;
+
+ switch (property_id) {
+ case PROP_MODE:
+ parser->mode = g_value_get_int (value);
+ return;
+ case PROP_SHOW_SUPPRESSED:
+ parser->show_suppressed = g_value_get_boolean (value);
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+e_mail_parser_prefer_plain_finalize (GObject *object)
+{
+ EMailParserPreferPlain *parser;
+
+ parser = (EMailParserPreferPlain *) object;
+
+ g_clear_object (&parser->settings);
+
+ G_OBJECT_CLASS (e_mail_parser_prefer_plain_parent_class)->finalize (object);
+}
+
+static void
+e_mail_parser_prefer_plain_class_init (EMailParserPreferPlainClass *klass)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ e_mail_parser_prefer_plain_parent_class = g_type_class_peek_parent (klass);
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = e_mail_parser_prefer_plain_constructed;
+ object_class->get_property = e_mail_parser_prefer_plain_get_property;
+ object_class->set_property = e_mail_parser_prefer_plain_set_property;
+ object_class->finalize = e_mail_parser_prefer_plain_finalize;
+
+ extension_class = E_EXTENSION_CLASS (klass);
+ extension_class->extensible_type = E_TYPE_MAIL_PARSER_EXTENSION_REGISTRY;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODE,
+ g_param_spec_int (
+ "mode",
+ "Mode",
+ NULL,
+ EPP_NORMAL,
+ EPP_TEXT,
+ EPP_NORMAL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_SUPPRESSED,
+ g_param_spec_boolean (
+ "show-suppressed",
+ "Show Suppressed",
+ NULL,
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+}
+
+void
+e_mail_parser_prefer_plain_class_finalize (EMailParserPreferPlainClass *klass)
+{
+}
+
+static gboolean
+parser_mode_get_mapping (GValue *value,
+ GVariant *variant,
+ gpointer user_data)
+{
+ gint i;
+
+ const gchar *key = g_variant_get_string (variant, NULL);
+ if (key) {
+ for (i = 0; i < G_N_ELEMENTS (epp_options); i++) {
+ if (!strcmp (epp_options[i].key, key)) {
+ g_value_set_int (value, i);
+ return TRUE;
+ }
+ }
+ } else {
+ g_value_set_int (value, 0);
+ }
+
+ return TRUE;
+}
+
+static GVariant *
+parser_mode_set_mapping (const GValue *value,
+ const GVariantType *expected_type,
+ gpointer user_data)
+{
+ return g_variant_new_string (epp_options[g_value_get_int (value)].key);
+}
+
+static void
+e_mail_parser_prefer_plain_init (EMailParserPreferPlain *parser)
+{
+ gchar *key;
+ gint i;
+
+ parser->settings = g_settings_new ("org.gnome.evolution.plugin.prefer-plain");
+ g_settings_bind_with_mapping (
+ parser->settings, "mode",
+ parser, "mode", G_SETTINGS_BIND_DEFAULT,
+ parser_mode_get_mapping,
+ parser_mode_set_mapping,
+ NULL, NULL);
+ g_settings_bind (
+ parser->settings, "show-suppressed",
+ parser, "show-suppressed", G_SETTINGS_BIND_DEFAULT);
+
+ /* Initialize the settings */
+ key = g_settings_get_string (parser->settings, "mode");
+ if (key) {
+ for (i = 0; i < G_N_ELEMENTS (epp_options); i++) {
+ if (!strcmp (epp_options[i].key, key)) {
+ parser->mode = i;
+ break;
+ }
+ }
+ g_free (key);
+ } else {
+ parser->mode = 0;
+ }
+
+ parser->show_suppressed = g_settings_get_boolean (parser->settings, "show-suppressed");
+}
diff --git a/modules/prefer-plain/e-mail-parser-prefer-plain.h b/modules/prefer-plain/e-mail-parser-prefer-plain.h
new file mode 100644
index 0000000000..4cfb8226f9
--- /dev/null
+++ b/modules/prefer-plain/e-mail-parser-prefer-plain.h
@@ -0,0 +1,30 @@
+/*
+ * e-mail-parser-prefer-plain.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_MAIL_PARSER_PREFER_PLAIN_H
+#define E_MAIL_PARSER_PREFER_PLAIN_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_parser_prefer_plain_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_PARSER_PREFER_PLAIN_H */
diff --git a/modules/prefer-plain/evolution-module-prefer-plain.c b/modules/prefer-plain/evolution-module-prefer-plain.c
new file mode 100644
index 0000000000..cb81932594
--- /dev/null
+++ b/modules/prefer-plain/evolution-module-prefer-plain.c
@@ -0,0 +1,73 @@
+/*
+ * evolution-module-prefer-plain.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-mail-parser-prefer-plain.h"
+
+#include <gmodule.h>
+#include <gio/gio.h>
+
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+const gchar * g_module_check_init (GModule *module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ GSettings *settings;
+ gchar **disabled_plugins;
+ gint i = 0;
+
+ settings = g_settings_new ("org.gnome.evolution");
+ disabled_plugins = g_settings_get_strv (settings, "disabled-eplugins");
+
+ for (i = 0; disabled_plugins && disabled_plugins[i] != NULL; i++) {
+
+ if (g_strcmp0 (
+ disabled_plugins[i],
+ "org.gnome.evolution.plugin.preferPlain") == 0) {
+
+ g_strfreev (disabled_plugins);
+ g_object_unref (settings);
+ return;
+ }
+
+ }
+
+ e_mail_parser_prefer_plain_type_register (type_module);
+
+ g_strfreev (disabled_plugins);
+ g_object_unref (settings);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
+
+G_MODULE_EXPORT const gchar *
+g_module_check_init (GModule *module)
+{
+ /* FIXME Until mail is split into a module library and a
+ * reusable shared library, prevent the module from
+ * being unloaded. Unloading the module resets all
+ * static variables, which screws up foo_get_type()
+ * functions among other things. */
+ g_module_make_resident (module);
+
+ return NULL;
+}
diff --git a/plugins/prefer-plain/Makefile.am b/modules/prefer-plain/plugin/Makefile.am
index 5375da81fd..3a0e16d29a 100644
--- a/plugins/prefer-plain/Makefile.am
+++ b/modules/prefer-plain/plugin/Makefile.am
@@ -1,28 +1,28 @@
@EVO_PLUGIN_RULE@
plugin_DATA = org-gnome-prefer-plain.eplug
-
plugin_LTLIBRARIES = liborg-gnome-prefer-plain.la
-liborg_gnome_prefer_plain_la_CPPFLAGS = \
+liborg_gnome_prefer_plain_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
-I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
$(EVOLUTION_DATA_SERVER_CFLAGS) \
$(GNOME_PLATFORM_CFLAGS)
-liborg_gnome_prefer_plain_la_SOURCES = prefer-plain.c
+liborg_gnome_prefer_plain_la_SOURCES = \
+ config-ui.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) \
+liborg_gnome_prefer_plain_la_LIBADD = \
+ $(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
+EXTRA_DIST = \
+ org-gnome-prefer-plain.eplug.xml
diff --git a/modules/prefer-plain/plugin/config-ui.c b/modules/prefer-plain/plugin/config-ui.c
new file mode 100644
index 0000000000..29b81a60fe
--- /dev/null
+++ b/modules/prefer-plain/plugin/config-ui.c
@@ -0,0 +1,192 @@
+/*
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <mail/em-config.h>
+
+#include <libedataserverui/libedataserverui.h>
+
+GtkWidget *prefer_plain_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_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 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 *
+prefer_plain_page_factory (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/prefer-plain/org-gnome-prefer-plain.eplug.xml b/modules/prefer-plain/plugin/org-gnome-prefer-plain.eplug.xml
index 6d0c3ae6ac..43948e3a69 100644
--- a/plugins/prefer-plain/org-gnome-prefer-plain.eplug.xml
+++ b/modules/prefer-plain/plugin/org-gnome-prefer-plain.eplug.xml
@@ -17,21 +17,9 @@
<!-- 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"/>
+ <item type="item_table" path="10.html/80.mode/00.mode" factory="prefer_plain_page_factory"/>
</group>
</hook>
</e-plugin>
-</e-plugin-list>
+</e-plugin-list> \ No newline at end of file
diff --git a/modules/text-highlight/Makefile.am b/modules/text-highlight/Makefile.am
new file mode 100644
index 0000000000..9b27298474
--- /dev/null
+++ b/modules/text-highlight/Makefile.am
@@ -0,0 +1,27 @@
+module_LTLIBRARIES = module-text-highlight.la
+
+module_text_highlight_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
+ -DG_LOG_DOMAIN=\"evolution-module-text-highlight\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS)
+
+module_text_highlight_la_SOURCES = \
+ text-highlight.c \
+ text-highlight.h \
+ evolution-module-text-highlight.c
+
+module_text_highlight_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(top_builddir)/em-format/libemformat.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS)
+
+module_text_highlight_la_LDFLAGS = \
+ -avoid-version -module $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/text-highlight/evolution-module-text-highlight.c b/modules/text-highlight/evolution-module-text-highlight.c
new file mode 100644
index 0000000000..de6e469bde
--- /dev/null
+++ b/modules/text-highlight/evolution-module-text-highlight.c
@@ -0,0 +1,51 @@
+/*
+ * evolution-module-text-highlight.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 "text-highlight.h"
+
+#include <gmodule.h>
+
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+const gchar * g_module_check_init (GModule *module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ /* Register dynamically loaded types. */
+
+ e_mail_formatter_text_highlight_type_register (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
+
+G_MODULE_EXPORT const gchar *
+g_module_check_init (GModule *module)
+{
+ /* FIXME Until mail is split into a module library and a
+ * reusable shared library, prevent the module from
+ * being unloaded. Unloading the module resets all
+ * static variables, which screws up foo_get_type()
+ * functions among other things. */
+ g_module_make_resident (module);
+
+ return NULL;
+}
diff --git a/modules/text-highlight/text-highlight.c b/modules/text-highlight/text-highlight.c
new file mode 100644
index 0000000000..462e5f0dc3
--- /dev/null
+++ b/modules/text-highlight/text-highlight.c
@@ -0,0 +1,314 @@
+/*
+ * text-highlight.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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "text-highlight.h"
+
+#include <em-format/e-mail-formatter-extension.h>
+#include <em-format/e-mail-formatter.h>
+#include <em-format/e-mail-part-utils.h>
+#include <e-util/e-util.h>
+
+#include <libebackend/libebackend.h>
+#include <libedataserver/libedataserver.h>
+
+#include <glib/gi18n-lib.h>
+#include <X11/Xlib.h>
+#include <camel/camel.h>
+
+typedef struct _EMailFormatterTextHighlight EMailFormatterTextHighlight;
+typedef struct _EMailFormatterTextHighlightClass EMailFormatterTextHighlightClass;
+
+struct _EMailFormatterTextHighlight {
+ EExtension parent;
+};
+
+struct _EMailFormatterTextHighlightClass {
+ EExtensionClass parent_class;
+};
+
+GType e_mail_formatter_text_highlight_get_type (void);
+static void e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface);
+static void e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailFormatterTextHighlight,
+ e_mail_formatter_text_highlight,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_EXTENSION,
+ e_mail_formatter_mail_extension_interface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_FORMATTER_EXTENSION,
+ e_mail_formatter_formatter_extension_interface_init));
+
+static gpointer emfe_parent_class = 0;
+
+static const gchar *formatter_mime_types[] = { "text/x-diff",
+ "text/x-patch",
+ NULL };
+
+static gchar * get_default_font (void)
+{
+ gchar *font;
+ GSettings *settings;
+
+ settings = g_settings_new ("org.gnome.desktop.interface");
+
+ font = g_settings_get_string (settings, "monospace-font-name");
+
+ return font ? font : g_strdup ("monospace 10");
+}
+
+static gboolean
+emfe_text_highlight_format (EMailFormatterExtension *extension,
+ EMailFormatter *formatter,
+ EMailFormatterContext *context,
+ EMailPart *part,
+ CamelStream *stream,
+ GCancellable *cancellable)
+{
+ if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) {
+
+ CamelDataWrapper *dw;
+ CamelStream *filter_stream;
+ CamelMimeFilter *mime_filter;
+
+ dw = camel_medium_get_content (CAMEL_MEDIUM (part->part));
+ if (!dw) {
+ return FALSE;
+ }
+
+ camel_stream_write_string (
+ stream, "<pre><div class=\"pre\">", cancellable, NULL);
+
+ filter_stream = camel_stream_filter_new (stream);
+ mime_filter = camel_mime_filter_tohtml_new (
+ CAMEL_MIME_FILTER_TOHTML_PRE |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES,
+ 0x7a7a7a);
+ camel_stream_filter_add (
+ CAMEL_STREAM_FILTER (filter_stream), mime_filter);
+ g_object_unref (mime_filter);
+
+ e_mail_formatter_format_text (
+ formatter, part, filter_stream, cancellable);
+
+ camel_stream_flush (filter_stream, cancellable, NULL);
+ g_object_unref (filter_stream);
+
+ camel_stream_write_string (
+ stream, "</div></pre>", cancellable, NULL);
+
+ return TRUE;
+
+ } else if (context->mode == E_MAIL_FORMATTER_MODE_RAW) {
+ gint stdin, stdout;
+ GPid pid;
+ CamelStream *read, *write;
+ CamelDataWrapper *dw;
+ gchar *font_family, *font_size;
+ gboolean use_custom_font;
+ GSettings *settings;
+ PangoFontDescription *fd;
+ const gchar *argv[] = { "highlight",
+ NULL, /* don't move these! */
+ NULL,
+ "--out-format=html",
+ "--include-style",
+ "--inline-css",
+ "--style=bclear",
+ "--syntax=diff",
+ "--failsafe",
+ NULL };
+
+ dw = camel_medium_get_content (CAMEL_MEDIUM (part->part));
+ if (!dw) {
+ return FALSE;
+ }
+
+ fd = NULL;
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ use_custom_font = g_settings_get_boolean (settings, "use-custom-font");
+ if (!use_custom_font) {
+ gchar *font;
+
+ font = get_default_font ();
+ fd = pango_font_description_from_string (font);
+ g_free (font);
+
+ g_object_unref (settings);
+
+ } else {
+ gchar *font;
+
+ font = g_settings_get_string (settings, "monospace-font");
+ if (!font)
+ font = get_default_font ();
+
+ fd = pango_font_description_from_string (font);
+
+ g_free (font);
+ }
+
+ font_family = g_strdup_printf ("--font='%s'",
+ pango_font_description_get_family (fd));
+ font_size = g_strdup_printf ("--font-size=%d",
+ pango_font_description_get_size (fd) / PANGO_SCALE);
+
+ argv[1] = font_family;
+ argv[2] = font_size;
+
+ if (!g_spawn_async_with_pipes (
+ NULL, (gchar **) argv, NULL,
+ G_SPAWN_SEARCH_PATH |
+ G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL, NULL, &pid, &stdin, &stdout, NULL, NULL)) {
+ return FALSE;
+ }
+
+ write = camel_stream_fs_new_with_fd (stdin);
+ read = camel_stream_fs_new_with_fd (stdout);
+
+ camel_data_wrapper_decode_to_stream_sync (
+ dw, write, cancellable, NULL);
+ g_object_unref (write);
+
+ g_spawn_close_pid (pid);
+
+ g_seekable_seek (G_SEEKABLE (read), 0, G_SEEK_SET, cancellable, NULL);
+ camel_stream_write_to_stream (read, stream, cancellable, NULL);
+ camel_stream_flush (read, cancellable, NULL);
+ g_object_unref (read);
+
+ g_free (font_family);
+ g_free (font_size);
+ pango_font_description_free (fd);
+
+ } else {
+ gchar *uri, *str;
+
+ uri = e_mail_part_build_uri (
+ context->folder, context->message_uid,
+ "part_id", G_TYPE_STRING, part->id,
+ "mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW,
+ NULL);
+
+ str = g_strdup_printf (
+ "<div class=\"part-container\" style=\"border-color: #%06x; "
+ "background-color: #%06x;\">"
+ "<div class=\"part-container-inner-margin\">\n"
+ "<iframe width=\"100%%\" height=\"10\""
+ " name=\"%s\" frameborder=\"0\" src=\"%s\"></iframe>"
+ "</div></div>",
+ e_color_to_value ((GdkColor *)
+ e_mail_formatter_get_color (
+ formatter, E_MAIL_FORMATTER_COLOR_FRAME)),
+ e_color_to_value ((GdkColor *)
+ e_mail_formatter_get_color (
+ formatter, E_MAIL_FORMATTER_COLOR_CONTENT)),
+ part->id, uri);
+
+ camel_stream_write_string (stream, str, cancellable, NULL);
+
+ g_free (str);
+ g_free (uri);
+
+ }
+
+ return TRUE;
+}
+
+static const gchar *
+emfe_text_highlight_get_display_name (EMailFormatterExtension *extension)
+{
+ return _("Patch");
+}
+
+static const gchar *
+emfe_text_highlight_get_description (EMailFormatterExtension *extension)
+{
+ return _("Format part as a patch");
+}
+
+static const gchar **
+emfe_text_highlight_mime_types (EMailExtension *extension)
+{
+ return formatter_mime_types;
+}
+
+static void
+emfe_text_highlight_constructed (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_formatter_text_highlight_init (EMailFormatterTextHighlight *object)
+{
+}
+
+static void
+e_mail_formatter_text_highlight_class_init (EMailFormatterTextHighlightClass *klass)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ emfe_parent_class = g_type_class_peek_parent (klass);
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = emfe_text_highlight_constructed;
+
+ extension_class = E_EXTENSION_CLASS (klass);
+ extension_class->extensible_type = E_TYPE_MAIL_FORMATTER_EXTENSION_REGISTRY;
+}
+
+static void
+e_mail_formatter_text_highlight_class_finalize (EMailFormatterTextHighlightClass *klass)
+{
+}
+
+void
+e_mail_formatter_text_highlight_type_register (GTypeModule *type_module)
+{
+ e_mail_formatter_text_highlight_register_type (type_module);
+}
+
+static void
+e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface)
+{
+ iface->format = emfe_text_highlight_format;
+ iface->get_display_name = emfe_text_highlight_get_display_name;
+ iface->get_description = emfe_text_highlight_get_description;
+}
+
+static void
+e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface)
+{
+ iface->mime_types = emfe_text_highlight_mime_types;
+}
diff --git a/modules/text-highlight/text-highlight.h b/modules/text-highlight/text-highlight.h
new file mode 100644
index 0000000000..af10da4c84
--- /dev/null
+++ b/modules/text-highlight/text-highlight.h
@@ -0,0 +1,30 @@
+/*
+ * text-highlight.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 TEXT_HIGHLIGHT_H
+#define TEXT_HIGHLIGHT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_formatter_text_highlight_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* TEXT_HIGHLIGHT_H */
diff --git a/modules/tnef-attachment/Makefile.am b/modules/tnef-attachment/Makefile.am
new file mode 100644
index 0000000000..ff5b412275
--- /dev/null
+++ b/modules/tnef-attachment/Makefile.am
@@ -0,0 +1,34 @@
+if OS_WIN32
+NO_UNDEFINED_REQUIRED_LIBS = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/mail/libevolution-mail.la
+endif
+
+module_LTLIBRARIES = module-tnef-attachment.la
+
+module_tnef_attachment_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
+ -DG_LOG_DOMAIN=\"evolution-module-tnef-attachment\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(TNEF_CFLAGS)
+
+module_tnef_attachment_la_SOURCES = \
+ e-mail-parser-tnef-attachment.c \
+ e-mail-parser-tnef-attachment.h \
+ evolution-module-tnef-attachment.c
+
+module_tnef_attachment_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/em-format/libemformat.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ -lytnef
+
+module_tnef_attachment_la_LDFLAGS = \
+ -avoid-version -module $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/tnef-attachments/tnef-plugin.c b/modules/tnef-attachment/e-mail-parser-tnef-attachment.c
index 52cd68664f..854a17765a 100644
--- a/plugins/tnef-attachments/tnef-plugin.c
+++ b/modules/tnef-attachment/e-mail-parser-tnef-attachment.c
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -12,23 +11,25 @@
*
* 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 <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
#include <stdio.h>
+#include "e-mail-parser-tnef-attachment.h"
+
+#include <em-format/e-mail-extension-registry.h>
+#include <em-format/e-mail-parser-extension.h>
+#include <em-format/e-mail-part.h>
+#include <em-format/e-mail-part-utils.h>
+
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
@@ -41,11 +42,45 @@
#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>
+#include <libebackend/libebackend.h>
+
+#define d(x)
+
+typedef struct _EMailParserTnefAttachment {
+ EExtension parent;
+
+ GSettings *settings;
+ gint mode;
+ gboolean show_suppressed;
+} EMailParserTnefAttachment;
+
+typedef struct _EMailParserTnefAttachmentClass {
+ EExtensionClass parent_class;
+} EMailParserTnefAttachmentClass;
+
+GType e_mail_parser_tnef_attachment_get_type (void);
+static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
+static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailParserTnefAttachment,
+ e_mail_parser_tnef_attachment,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_EXTENSION,
+ e_mail_parser_mail_extension_interface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_PARSER_EXTENSION,
+ e_mail_parser_parser_extension_interface_init));
+
+static const gchar* parser_mime_types[] = { "application/vnd.ms-tnef",
+ "application/ms-tnefl",
+ NULL };
+
gint verbose = 0;
gint saveRTF = 0;
gint saveintermediate = 0;
@@ -55,8 +90,6 @@ 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[]);
@@ -81,9 +114,12 @@ sanitize_filename (const gchar *filename)
}
}
-void
-org_gnome_format_tnef (gpointer ep,
- EMFormatHookTarget *t)
+static GSList *
+empe_tnef_attachment_parse (EMailParserExtension *extension,
+ EMailParser *parser,
+ CamelMimePart *part,
+ GString *part_id,
+ GCancellable *cancellable)
{
gchar *tmpdir, *name;
CamelStream *out;
@@ -92,32 +128,32 @@ org_gnome_format_tnef (gpointer ep,
CamelMultipart *mp;
CamelMimePart *mainpart;
CamelDataWrapper *content;
- const EMFormatHandler *handler;
gint len;
TNEFStruct tnef;
+ GSList *parts;
tmpdir = e_mkdtemp("tnef-attachment-XXXXXX");
if (tmpdir == NULL)
- return;
+ return NULL;
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;
+ return NULL;
}
- content = camel_medium_get_content ((CamelMedium *) t->part);
+ content = camel_medium_get_content ((CamelMedium *) part);
if (content == NULL) {
g_free (name);
g_object_unref (out);
- return;
+ return NULL;
}
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;
+ return NULL;
}
g_object_unref (out);
@@ -136,7 +172,7 @@ org_gnome_format_tnef (gpointer ep,
if (dir == NULL) {
g_object_unref (out);
g_free (name);
- return;
+ return NULL;
}
mainpart = camel_mime_part_new ();
@@ -173,7 +209,7 @@ org_gnome_format_tnef (gpointer ep,
camel_medium_set_content ((CamelMedium *) part, content);
g_object_unref (content);
- type = em_format_snoop_type (part);
+ type = e_mail_part_snoop_type (part);
if (type)
camel_data_wrapper_set_mime_type ((CamelDataWrapper *) part, type);
@@ -187,42 +223,98 @@ org_gnome_format_tnef (gpointer ep,
closedir (dir);
- len = t->part_id->len;
- g_string_append_printf(t->part_id, ".tnef");
+ len = part_id->len;
+ g_string_append_printf(part_id, ".tnef");
+ parts = NULL;
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);
- }
+
+ CamelMimePart *part = camel_mime_part_new ();
+
+ camel_medium_set_content ((CamelMedium *) part,
+ CAMEL_DATA_WRAPPER (mp));
+
+ parts = e_mail_parser_parse_part_as (parser, part,
+ part_id, "multipart/mixed", cancellable);
+
+ g_object_unref (part);
}
- g_string_truncate (t->part_id, len);
+ g_string_truncate (part_id, len);
+
+ if (parts) {
+ parts = e_mail_parser_wrap_as_attachment (parser,
+ part, parts, part_id, cancellable);
+ }
g_object_unref (mp);
g_object_unref (mainpart);
g_free (name);
g_free (tmpdir);
+
+ return parts;
+}
+
+static const gchar **
+empe_mime_types (EMailExtension *extension)
+{
+ return parser_mime_types;
+}
+
+void
+e_mail_parser_tnef_attachment_type_register (GTypeModule *type_module)
+{
+ e_mail_parser_tnef_attachment_register_type (type_module);
+}
+
+static void
+e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
+{
+ iface->mime_types = empe_mime_types;
+}
+
+static void
+e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
+{
+ iface->parse = empe_tnef_attachment_parse;
}
-gint e_plugin_lib_enable (EPlugin *ep, gint enable);
+static void
+e_mail_parser_tnef_attachment_constructed (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
-gint
-e_plugin_lib_enable (EPlugin *ep,
- gint enable)
+ e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_parser_tnef_attachment_class_init (EMailParserTnefAttachmentClass *klass)
{
- if (loaded)
- return 0;
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
- loaded = TRUE;
+ e_mail_parser_tnef_attachment_parent_class = g_type_class_peek_parent (klass);
- return 0;
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = e_mail_parser_tnef_attachment_constructed;
+
+ extension_class = E_EXTENSION_CLASS (klass);
+ extension_class->extensible_type = E_TYPE_MAIL_PARSER_EXTENSION_REGISTRY;
+}
+
+void
+e_mail_parser_tnef_attachment_class_finalize (EMailParserTnefAttachmentClass *klass)
+{
+}
+
+static void
+e_mail_parser_tnef_attachment_init (EMailParserTnefAttachment *parser)
+{
}
void
@@ -421,7 +513,7 @@ saveVCard (TNEFStruct *tnef,
return;
absfilename = g_strconcat (file, ".vcard", NULL);
} else
- absfilename = g_strdup ("unknown.vcard");
+ absfilename = g_strdup ("unknown.vcard");
} else {
file = sanitize_filename (vl->data);
if (!file)
@@ -1352,4 +1444,3 @@ void printRtf (FILE *fptr, variableLength *vl) {
}
fprintf(fptr, "\n");
}
-
diff --git a/modules/tnef-attachment/e-mail-parser-tnef-attachment.h b/modules/tnef-attachment/e-mail-parser-tnef-attachment.h
new file mode 100644
index 0000000000..360c66ad9a
--- /dev/null
+++ b/modules/tnef-attachment/e-mail-parser-tnef-attachment.h
@@ -0,0 +1,30 @@
+/*
+ * e-mail-parser-tnef-attachment.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_MAIL_PARSER_TNEF_ATTACHMENT_H
+#define E_MAIL_PARSER_TNEF_ATTACHMENT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_parser_tnef_attachment_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_PARSER_TNEF_ATTACHMENT_H */
diff --git a/modules/tnef-attachment/evolution-module-tnef-attachment.c b/modules/tnef-attachment/evolution-module-tnef-attachment.c
new file mode 100644
index 0000000000..df31b97a13
--- /dev/null
+++ b/modules/tnef-attachment/evolution-module-tnef-attachment.c
@@ -0,0 +1,51 @@
+/*
+ * evolution-module-tnef-attachment.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-mail-parser-tnef-attachment.h"
+
+#include <gmodule.h>
+
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+const gchar * g_module_check_init (GModule *module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ /* Register dynamically loaded types. */
+
+ e_mail_parser_tnef_attachment_type_register (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
+
+G_MODULE_EXPORT const gchar *
+g_module_check_init (GModule *module)
+{
+ /* FIXME Until mail is split into a module library and a
+ * reusable shared library, prevent the module from
+ * being unloaded. Unloading the module resets all
+ * static variables, which screws up foo_get_type()
+ * functions among other things. */
+ g_module_make_resident (module);
+
+ return NULL;
+}
diff --git a/modules/vcard-inline/Makefile.am b/modules/vcard-inline/Makefile.am
new file mode 100644
index 0000000000..fc0b610000
--- /dev/null
+++ b/modules/vcard-inline/Makefile.am
@@ -0,0 +1,32 @@
+module_LTLIBRARIES = module-vcard-inline.la
+
+module_vcard_inline_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
+ -DG_LOG_DOMAIN=\"evolution-module-vcard-inline\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS)
+
+module_vcard_inline_la_SOURCES = \
+ e-mail-formatter-vcard-inline.c \
+ e-mail-formatter-vcard-inline.h \
+ e-mail-parser-vcard-inline.c \
+ e-mail-parser-vcard-inline.h \
+ evolution-module-vcard-inline.c
+
+module_vcard_inline_la_LIBADD = \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(top_builddir)/em-format/libemformat.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 \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS)
+
+module_vcard_inline_la_LDFLAGS = \
+ -avoid-version -module $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/vcard-inline/e-mail-formatter-vcard-inline.c b/modules/vcard-inline/e-mail-formatter-vcard-inline.c
new file mode 100644
index 0000000000..25cdacb116
--- /dev/null
+++ b/modules/vcard-inline/e-mail-formatter-vcard-inline.c
@@ -0,0 +1,249 @@
+/*
+ * e-mail-formatter-vcard-inline.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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-mail-formatter-vcard-inline.h"
+#include "e-mail-part-vcard-inline.h"
+
+#include <glib/gi18n-lib.h>
+
+#include <libebackend/libebackend.h>
+
+#include <em-format/e-mail-formatter-extension.h>
+#include <em-format/e-mail-formatter.h>
+#include <em-format/e-mail-part-utils.h>
+
+#include <camel/camel.h>
+
+#define d(x)
+
+typedef struct _EMailFormatterVCardInline {
+ EExtension parent;
+} EMailFormatterVCardInline;
+
+typedef struct _EMailFormatterVCardInlineClass {
+ EExtensionClass parent_class;
+} EMailFormatterVCardInlineClass;
+
+GType e_mail_formatter_vcard_inline_get_type (void);
+static void e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface);
+static void e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailFormatterVCardInline,
+ e_mail_formatter_vcard_inline,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_EXTENSION,
+ e_mail_formatter_mail_extension_interface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_FORMATTER_EXTENSION,
+ e_mail_formatter_formatter_extension_interface_init));
+
+static const gchar* formatter_mime_types[] = { "text/vcard", "text/x-vcard",
+ "text/directory", NULL };
+
+static gboolean
+emfe_vcard_inline_format (EMailFormatterExtension *extension,
+ EMailFormatter *formatter,
+ EMailFormatterContext *context,
+ EMailPart *part,
+ CamelStream *stream,
+ GCancellable *cancellable)
+{
+ EMailPartVCardInline *vcard_part;
+
+ g_return_val_if_fail (E_MAIL_PART_IS (part, EMailPartVCardInline), FALSE);
+ vcard_part = (EMailPartVCardInline *) part;
+
+ if (context->mode == E_MAIL_FORMATTER_MODE_RAW) {
+
+ EContact *contact;
+
+ if (vcard_part->contact_list != NULL)
+ contact = E_CONTACT (vcard_part->contact_list->data);
+ else
+ contact = NULL;
+
+ eab_contact_formatter_format_contact_sync (
+ vcard_part->formatter, contact, stream, cancellable);
+
+ } else {
+ gchar *str, *uri;
+ gint length;
+ const gchar *label = NULL;
+ EABContactDisplayMode mode;
+ const gchar *info = NULL;
+
+ length = g_slist_length (vcard_part->contact_list);
+ if (length < 1)
+ return FALSE;
+
+ if (!vcard_part->message_uid && context->message_uid)
+ vcard_part->message_uid = g_strdup (context->message_uid);
+
+ if (!vcard_part->folder && context->folder)
+ vcard_part->folder = g_object_ref (context->folder);
+
+ uri = e_mail_part_build_uri (
+ context->folder, context->message_uid,
+ "part_id", G_TYPE_STRING, part->id,
+ "mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW,
+ NULL);
+
+ mode = eab_contact_formatter_get_display_mode (vcard_part->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>",
+ part->id,
+ mode, label,
+ part->id, _("Save To Addressbook"),
+ uri, part->id);
+
+ 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);
+ }
+
+ return TRUE;
+}
+
+static const gchar *
+emfe_vcard_inline_get_display_name (EMailFormatterExtension *extension)
+{
+ return _("Addressbok Contact");
+}
+
+static const gchar *
+emfe_vcard_inline_get_description (EMailFormatterExtension *extension)
+{
+ return _("Display the part as an addressbook contact");
+}
+
+static const gchar **
+emfe_vcard_inline_mime_types (EMailExtension *extension)
+{
+ return formatter_mime_types;
+}
+
+static void
+e_mail_formatter_vcard_inline_constructed (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_formatter_vcard_inline_class_init (EMailFormatterVCardInlineClass *klass)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ e_mail_formatter_vcard_inline_parent_class = g_type_class_peek_parent (klass);
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = e_mail_formatter_vcard_inline_constructed;
+
+ extension_class = E_EXTENSION_CLASS (klass);
+ extension_class->extensible_type = E_TYPE_MAIL_FORMATTER_EXTENSION_REGISTRY;
+}
+
+static void
+e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface)
+{
+ iface->format = emfe_vcard_inline_format;
+ iface->get_display_name = emfe_vcard_inline_get_display_name;
+ iface->get_description = emfe_vcard_inline_get_description;
+}
+
+static void
+e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface)
+{
+ iface->mime_types = emfe_vcard_inline_mime_types;
+}
+
+static void
+e_mail_formatter_vcard_inline_init (EMailFormatterVCardInline *formatter)
+{
+
+}
+
+void
+e_mail_formatter_vcard_inline_type_register (GTypeModule *type_module)
+{
+ e_mail_formatter_vcard_inline_register_type (type_module);
+}
+
+static void
+e_mail_formatter_vcard_inline_class_finalize (EMailFormatterVCardInlineClass *klass)
+{
+
+}
diff --git a/modules/vcard-inline/e-mail-formatter-vcard-inline.h b/modules/vcard-inline/e-mail-formatter-vcard-inline.h
new file mode 100644
index 0000000000..1dcec839f3
--- /dev/null
+++ b/modules/vcard-inline/e-mail-formatter-vcard-inline.h
@@ -0,0 +1,30 @@
+/*
+ * e-mail-formatter-vcard-inline.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_MAIL_FORMATTER_VCARD_INLINE_H
+#define E_MAIL_FORMATTER_VCARD_INLINE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_formatter_vcard_inline_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_FORMATTER_VCARD_INLINE_H */
diff --git a/modules/vcard-inline/e-mail-parser-vcard-inline.c b/modules/vcard-inline/e-mail-parser-vcard-inline.c
new file mode 100644
index 0000000000..562ca75c72
--- /dev/null
+++ b/modules/vcard-inline/e-mail-parser-vcard-inline.c
@@ -0,0 +1,410 @@
+/*
+ * e-mail-parser-vcard-inline.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/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include "e-mail-parser-vcard-inline.h"
+#include "e-mail-part-vcard-inline.h"
+
+#include <camel/camel.h>
+
+#include <em-format/e-mail-extension-registry.h>
+#include <em-format/e-mail-parser-extension.h>
+#include <em-format/e-mail-part.h>
+#include <em-format/e-mail-part-utils.h>
+#include <em-format/e-mail-formatter.h>
+
+#include <libebook/libebook.h>
+#include <libedataserver/libedataserver.h>
+#include <libedataserverui/libedataserverui.h>
+
+#include <shell/e-shell.h>
+#include <addressbook/gui/merging/eab-contact-merging.h>
+#include <addressbook/util/eab-book-util.h>
+
+#include <libebackend/libebackend.h>
+
+#define d(x)
+
+typedef struct _EMailParserVCardInline {
+ EExtension parent;
+} EMailParserVCardInline;
+
+typedef struct _EMailParserVCardInlineClass {
+ EExtensionClass parent_class;
+} EMailParserVCardInlineClass;
+
+GType e_mail_parser_vcard_inline_get_type (void);
+static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
+static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailParserVCardInline,
+ e_mail_parser_vcard_inline,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_EXTENSION,
+ e_mail_parser_mail_extension_interface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_PARSER_EXTENSION,
+ e_mail_parser_parser_extension_interface_init));
+
+static const gchar* parser_mime_types[] = { "text/vcard", "text/x-vcard",
+ "text/directory", NULL };
+
+static void
+mail_part_vcard_inline_free (EMailPart *mail_part)
+{
+ EMailPartVCardInline *vi_part = (EMailPartVCardInline *) mail_part;
+
+ g_clear_object (&vi_part->contact_display);
+ g_clear_object (&vi_part->message_label);
+ g_clear_object (&vi_part->formatter);
+ g_clear_object (&vi_part->iframe);
+ g_clear_object (&vi_part->save_button);
+ g_clear_object (&vi_part->toggle_button);
+ g_clear_object (&vi_part->folder);
+
+ if (vi_part->message_uid) {
+ g_free (vi_part->message_uid);
+ vi_part->message_uid = NULL;
+ }
+}
+
+static void
+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
+save_vcard_cb (WebKitDOMEventTarget *button,
+ WebKitDOMEvent *event,
+ EMailPartVCardInline *vcard_part)
+{
+ 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_part->contact_list);
+
+ e_client_utils_open_new (
+ source, E_CLIENT_SOURCE_TYPE_CONTACTS,
+ FALSE, NULL, (GAsyncReadyCallback) client_loaded_cb,
+ contact_list);
+}
+
+static void
+display_mode_toggle_cb (WebKitDOMEventTarget *button,
+ WebKitDOMEvent *event,
+ EMailPartVCardInline *vcard_part)
+{
+ EABContactDisplayMode mode;
+ gchar *uri;
+
+ mode = eab_contact_formatter_get_display_mode (vcard_part->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_part->formatter, mode);
+
+ uri = e_mail_part_build_uri (
+ vcard_part->folder, vcard_part->message_uid,
+ "part_id", G_TYPE_STRING, vcard_part->parent.id,
+ "mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW, NULL);
+
+ webkit_dom_html_iframe_element_set_src (
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (vcard_part->iframe), uri);
+
+ g_free (uri);
+}
+
+static void
+bind_dom (EMailPartVCardInline *vcard_part,
+ WebKitDOMElement *attachment)
+{
+ WebKitDOMNodeList *list;
+ WebKitDOMElement *iframe, *toggle_button, *save_button;
+
+ /* 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_part->iframe)
+ g_object_unref (vcard_part->iframe);
+ vcard_part->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_part->toggle_button)
+ g_object_unref (vcard_part->toggle_button);
+ vcard_part->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_part->save_button)
+ g_object_unref (vcard_part->save_button);
+ vcard_part->save_button = g_object_ref (save_button);
+
+ webkit_dom_event_target_add_event_listener (
+ WEBKIT_DOM_EVENT_TARGET (toggle_button),
+ "click", G_CALLBACK (display_mode_toggle_cb),
+ FALSE, vcard_part);
+
+ webkit_dom_event_target_add_event_listener (
+ WEBKIT_DOM_EVENT_TARGET (save_button),
+ "click", G_CALLBACK (save_vcard_cb),
+ FALSE, vcard_part);
+
+ /* 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
+decode_vcard (EMailPartVCardInline *vcard_part,
+ 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_part->contact_list = contact_list;
+
+ g_object_unref (mime_part);
+ g_object_unref (stream);
+}
+
+static GSList *
+empe_vcard_inline_parse (EMailParserExtension *extension,
+ EMailParser *parser,
+ CamelMimePart *part,
+ GString *part_id,
+ GCancellable *cancellable)
+{
+ EMailPartVCardInline *vcard_part;
+ gint len;
+
+ len = part_id->len;
+ g_string_append (part_id, ".org-gnome-vcard-inline-display");
+
+ vcard_part = (EMailPartVCardInline *) e_mail_part_subclass_new (
+ part, part_id->str, sizeof (EMailPartVCardInline),
+ (GFreeFunc) mail_part_vcard_inline_free);
+ vcard_part->parent.mime_type = camel_content_type_simple (
+ camel_mime_part_get_content_type (part));
+ vcard_part->parent.bind_func = (EMailPartDOMBindFunc) bind_dom;
+ vcard_part->parent.is_attachment = TRUE;
+ vcard_part->formatter = g_object_new (
+ EAB_TYPE_CONTACT_FORMATTER,
+ "display-mode", EAB_CONTACT_DISPLAY_RENDER_COMPACT,
+ "render-maps", FALSE, NULL);
+ g_object_ref (part);
+
+ decode_vcard (vcard_part, part);
+
+ g_string_truncate (part_id, len);
+
+ return e_mail_parser_wrap_as_attachment (
+ parser, part, g_slist_append (NULL, vcard_part),
+ part_id, cancellable);
+}
+
+static guint32
+empe_vcard_inline_get_flags (EMailParserExtension *extension)
+{
+ return E_MAIL_PARSER_EXTENSION_INLINE_DISPOSITION;
+}
+
+static const gchar **
+empe_mime_types (EMailExtension *extension)
+{
+ return parser_mime_types;
+}
+
+void
+e_mail_parser_vcard_inline_type_register (GTypeModule *type_module)
+{
+ e_mail_parser_vcard_inline_register_type (type_module);
+}
+
+static void
+e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
+{
+ iface->mime_types = empe_mime_types;
+}
+
+static void
+e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
+{
+ iface->parse = empe_vcard_inline_parse;
+ iface->get_flags = empe_vcard_inline_get_flags;
+}
+
+static void
+e_mail_parser_vcard_inline_constructed (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_parser_vcard_inline_class_init (EMailParserVCardInlineClass *klass)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ e_mail_parser_vcard_inline_parent_class = g_type_class_peek_parent (klass);
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = e_mail_parser_vcard_inline_constructed;
+
+ extension_class = E_EXTENSION_CLASS (klass);
+ extension_class->extensible_type = E_TYPE_MAIL_PARSER_EXTENSION_REGISTRY;
+}
+
+static void
+e_mail_parser_vcard_inline_class_finalize (EMailParserVCardInlineClass *klass)
+{
+
+}
+
+static void
+e_mail_parser_vcard_inline_init (EMailParserVCardInline *self)
+{
+}
diff --git a/modules/vcard-inline/e-mail-parser-vcard-inline.h b/modules/vcard-inline/e-mail-parser-vcard-inline.h
new file mode 100644
index 0000000000..76ec5fe206
--- /dev/null
+++ b/modules/vcard-inline/e-mail-parser-vcard-inline.h
@@ -0,0 +1,30 @@
+/*
+ * e-mail-parser-vcard-inline.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_MAIL_PARSER_VCARD_INLINE_H
+#define E_MAIL_PARSER_VCARD_INLINE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_parser_vcard_inline_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_PARSER_VCARD_INLINE_H */
diff --git a/modules/vcard-inline/e-mail-part-vcard-inline.h b/modules/vcard-inline/e-mail-part-vcard-inline.h
new file mode 100644
index 0000000000..8272d2f672
--- /dev/null
+++ b/modules/vcard-inline/e-mail-part-vcard-inline.h
@@ -0,0 +1,50 @@
+/*
+ * e-mail-part-vcard-inline.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_MAIL_PART_VCARD_INLINE_H
+#define E_MAIL_PART_VCARD_INLINE_H
+
+#include <em-format/e-mail-part.h>
+
+#include <addressbook/gui/widgets/eab-contact-formatter.h>
+#include <webkit/webkitdom.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EMailPartVCardInline EMailPartVCardInline;
+
+struct _EMailPartVCardInline {
+ EMailPart parent;
+
+ GSList *contact_list;
+ GtkWidget *contact_display;
+ GtkWidget *message_label;
+
+ EABContactFormatter *formatter;
+ WebKitDOMElement *iframe;
+ WebKitDOMElement *toggle_button;
+ WebKitDOMElement *save_button;
+
+ CamelFolder *folder;
+ gchar *message_uid;
+};
+
+G_END_DECLS
+
+#endif /* E_MAIL_PART_VCARD_INLINE_H */
+
diff --git a/modules/vcard-inline/evolution-module-vcard-inline.c b/modules/vcard-inline/evolution-module-vcard-inline.c
new file mode 100644
index 0000000000..4e95aba312
--- /dev/null
+++ b/modules/vcard-inline/evolution-module-vcard-inline.c
@@ -0,0 +1,53 @@
+/*
+ * evolution-module-vcard-inline.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-mail-formatter-vcard-inline.h"
+#include "e-mail-parser-vcard-inline.h"
+
+#include <gmodule.h>
+
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+const gchar * g_module_check_init (GModule *module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ /* Register dynamically loaded types. */
+
+ e_mail_formatter_vcard_inline_type_register (type_module);
+ e_mail_parser_vcard_inline_type_register (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
+
+G_MODULE_EXPORT const gchar *
+g_module_check_init (GModule *module)
+{
+ /* FIXME Until mail is split into a module library and a
+ * reusable shared library, prevent the module from
+ * being unloaded. Unloading the module resets all
+ * static variables, which screws up foo_get_type()
+ * functions among other things. */
+ g_module_make_resident (module);
+
+ return NULL;
+}
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/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/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/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/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);
-}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8fcfd5de50..cc08947540 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -155,8 +155,30 @@ data/org.gnome.evolution.plugin.prefer-plain.gschema.xml.in
data/org.gnome.evolution.plugin.templates.gschema.xml.in
data/org.gnome.evolution.shell.gschema.xml.in
data/org.gnome.evolution.spamassassin.gschema.xml.in
-em-format/em-format.c
-em-format/em-format-quote.c
+em-format/e-mail-formatter-attachment.c
+em-format/e-mail-formatter-headers.c
+em-format/e-mail-formatter-image.c
+em-format/e-mail-formatter-message-rfc822.c
+em-format/e-mail-formatter-print-headers.c
+em-format/e-mail-formatter-print.c
+em-format/e-mail-formatter-quote-text-enriched.c
+em-format/e-mail-formatter-quote-text-html.c
+em-format/e-mail-formatter-quote-text-plain.c
+em-format/e-mail-formatter-secure-button.c
+em-format/e-mail-formatter-source.c
+em-format/e-mail-formatter-text-enriched.c
+em-format/e-mail-formatter-text-html.c
+em-format/e-mail-formatter-text-plain.c
+em-format/e-mail-formatter-utils.c
+em-format/e-mail-formatter.c
+em-format/e-mail-parser-application-mbox.c
+em-format/e-mail-parser-application-smime.c
+em-format/e-mail-parser-inlinepgp-encrypted.c
+em-format/e-mail-parser-inlinepgp-signed.c
+em-format/e-mail-parser-message-external.c
+em-format/e-mail-parser-multipart-encrypted.c
+em-format/e-mail-parser-multipart-signed.c
+em-format/e-mail-part-utils.c
e-util/e-activity.c
e-util/e-categories-config.c
e-util/e-charset.c
@@ -192,7 +214,6 @@ libemail-utils/mail-mt.c
libevolution-utils/e-alert-dialog.c
mail/e-mail-account-manager.c
mail/e-mail-account-tree-view.c
-mail/e-mail-attachment-bar.c
mail/e-mail-autoconfig.c
mail/e-mail-backend.c
mail/e-mail-browser.c
@@ -236,9 +257,6 @@ mail/em-folder-selector.c
mail/em-folder-tree.c
mail/em-folder-tree-model.c
mail/em-folder-utils.c
-mail/em-format-html.c
-mail/em-format-html-display.c
-mail/em-format-html-print.c
mail/em-subscription-editor.c
mail/em-utils.c
mail/em-vfolder-editor.c
@@ -267,6 +285,7 @@ modules/addressbook/e-book-shell-sidebar.c
modules/addressbook/e-book-shell-view-actions.c
modules/addressbook/e-book-shell-view.c
[type: gettext/glade]modules/addressbook/ldap-config.ui
+modules/audio-inline/e-mail-formatter-audio-inline.c
modules/backup-restore/e-mail-config-restore-page.c
modules/backup-restore/e-mail-config-restore-ready-page.c
modules/backup-restore/evolution-backup-restore.c
@@ -316,6 +335,11 @@ modules/calendar/e-task-shell-view-actions.c
modules/calendar/e-task-shell-view.c
modules/calendar/e-task-shell-view-private.c
modules/imap-features/e-mail-config-imap-headers-page.c
+modules/itip-formatter/e-mail-formatter-itip.c
+modules/itip-formatter/itip-view.c
+modules/itip-formatter/org-gnome-itip-formatter.error.xml
+modules/itip-formatter/plugin/config-ui.c
+modules/itip-formatter/plugin/org-gnome-itip-formatter.eplug.xml
modules/mail/em-account-prefs.c
modules/mail/e-mail-attachment-handler.c
modules/mail/e-mail-shell-backend.c
@@ -339,18 +363,23 @@ modules/online-accounts/camel-sasl-xoauth.c
modules/plugin-manager/evolution-plugin-manager.c
modules/plugin-python/example/org-gnome-hello-python.eplug.xml
modules/plugin-python/example/org-gnome-hello-python-ui.xml
+modules/prefer-plain/e-mail-parser-prefer-plain.c
+modules/prefer-plain/plugin/config-ui.c
+modules/prefer-plain/plugin/org-gnome-prefer-plain.eplug.xml
modules/spamassassin/evolution-spamassassin.c
modules/spamassassin/evolution-spamassassin.schemas.in
modules/startup-wizard/e-mail-config-import-page.c
modules/startup-wizard/e-mail-config-import-progress-page.c
modules/startup-wizard/e-startup-assistant.c
modules/startup-wizard/evolution-startup-wizard.c
+modules/text-highlight/text-highlight.c
+modules/vcard-inline/e-mail-formatter-vcard-inline.c
+modules/vcard-inline/e-mail-parser-vcard-inline.c
modules/web-inspector/evolution-web-inspector.c
plugins/attachment-reminder/apps-evolution-attachment-reminder.schemas.in
plugins/attachment-reminder/attachment-reminder.c
plugins/attachment-reminder/org-gnome-attachment-reminder.error.xml
plugins/attachment-reminder/org-gnome-evolution-attachment-reminder.eplug.xml
-plugins/audio-inline/org-gnome-audio-inline.eplug.xml
plugins/bbdb/bbdb.c
plugins/bbdb/org-gnome-evolution-bbdb.eplug.xml
plugins/dbx-import/dbx-importer.c
@@ -368,10 +397,6 @@ plugins/face/face.c
plugins/face/org-gnome-face.eplug.xml
plugins/face/org-gnome-face.error.xml
plugins/image-inline/org-gnome-image-inline.eplug.xml
-plugins/itip-formatter/itip-formatter.c
-plugins/itip-formatter/itip-view.c
-plugins/itip-formatter/org-gnome-itip-formatter.eplug.xml
-plugins/itip-formatter/org-gnome-itip-formatter.error.xml
plugins/mailing-list-actions/mailing-list-actions.c
plugins/mailing-list-actions/org-gnome-mailing-list-actions.eplug.xml
plugins/mailing-list-actions/org-gnome-mailing-list-actions.error.xml
@@ -382,8 +407,6 @@ plugins/mail-to-task/mail-to-task.c
plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml
plugins/mark-all-read/mark-all-read.c
plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml
-plugins/prefer-plain/org-gnome-prefer-plain.eplug.xml
-plugins/prefer-plain/prefer-plain.c
plugins/pst-import/org-gnome-pst-import.eplug.xml
plugins/pst-import/pst-importer.c
plugins/publish-calendar/org-gnome-publish-calendar.eplug.xml
@@ -400,9 +423,6 @@ plugins/save-calendar/save-calendar.c
plugins/templates/apps-evolution-template-placeholders.schemas.in
plugins/templates/org-gnome-templates.eplug.xml
plugins/templates/templates.c
-plugins/tnef-attachments/org-gnome-tnef-attachments.eplug.xml
-plugins/vcard-inline/org-gnome-vcard-inline.eplug.xml
-plugins/vcard-inline/vcard-inline.c
shell/apps_evolution_shell.schemas.in
shell/e-shell-backend.c
shell/e-shell.c
@@ -451,6 +471,7 @@ widgets/misc/e-action-combo-box.c
widgets/misc/e-activity-proxy.c
widgets/misc/e-alert-bar.c
widgets/misc/e-attachment.c
+widgets/misc/e-attachment-bar.c
widgets/misc/e-attachment-dialog.c
widgets/misc/e-attachment-handler-image.c
widgets/misc/e-attachment-handler-sendto.c