aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@src.gnome.org>2009-02-21 11:36:34 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2009-02-21 11:36:34 +0800
commited77e8e15bbbb886cf92dfb0fb1700a1c1d92548 (patch)
tree4fe3562533ac4b58715786682f5758e1e25e0954
parent567453082a1ee766d207847ccea0e9ff948133d7 (diff)
downloadgsoc2013-evolution-ed77e8e15bbbb886cf92dfb0fb1700a1c1d92548.tar
gsoc2013-evolution-ed77e8e15bbbb886cf92dfb0fb1700a1c1d92548.tar.gz
gsoc2013-evolution-ed77e8e15bbbb886cf92dfb0fb1700a1c1d92548.tar.bz2
gsoc2013-evolution-ed77e8e15bbbb886cf92dfb0fb1700a1c1d92548.tar.lz
gsoc2013-evolution-ed77e8e15bbbb886cf92dfb0fb1700a1c1d92548.tar.xz
gsoc2013-evolution-ed77e8e15bbbb886cf92dfb0fb1700a1c1d92548.tar.zst
gsoc2013-evolution-ed77e8e15bbbb886cf92dfb0fb1700a1c1d92548.zip
Convert eab-vcard-control.c to a new "vcard-inline" plugin, similar to the
"audio-inline" plugin. svn path=/branches/kill-bonobo/; revision=37301
-rw-r--r--addressbook/gui/widgets/eab-vcard-control.c324
-rw-r--r--addressbook/gui/widgets/eab-vcard-control.h28
-rw-r--r--configure.in69
-rw-r--r--mail/e-mail-shell-module.c3
-rw-r--r--mail/em-folder-view.c11
-rw-r--r--mail/em-format-html-display.c208
-rw-r--r--plugins/audio-inline/org-gnome-audio-inline.eplug.xml105
-rw-r--r--plugins/vcard-inline/Makefile.am20
-rw-r--r--plugins/vcard-inline/org-gnome-vcard-inline.eplug.xml28
-rw-r--r--plugins/vcard-inline/vcard-inline.c285
10 files changed, 459 insertions, 622 deletions
diff --git a/addressbook/gui/widgets/eab-vcard-control.c b/addressbook/gui/widgets/eab-vcard-control.c
deleted file mode 100644
index 786e54632d..0000000000
--- a/addressbook/gui/widgets/eab-vcard-control.c
+++ /dev/null
@@ -1,324 +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:
- * Chris Lahey <clahey@ximian.com>
- * Chris Toshok <toshok@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include <config.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-persist.h>
-#include <bonobo/bonobo-persist-stream.h>
-#include <bonobo/bonobo-stream-client.h>
-#include <e-util/e-util.h>
-
-#include <libebook/e-book.h>
-#include <libebook/e-contact.h>
-#include <addressbook/gui/component/addressbook.h>
-#include <addressbook/gui/widgets/eab-contact-display.h>
-#include <addressbook/util/eab-book-util.h>
-
-#include "eab-vcard-control.h"
-#include "eab-contact-merging.h"
-
-typedef struct {
- EABContactDisplay *display;
- GList *card_list;
- GtkWidget *label;
- EABContactDisplayMode mode;
-} EABVCardControl;
-
-#define VCARD_CONTROL_ID "OAFIID:GNOME_Evolution_Addressbook_VCard_Control:" BASE_VERSION
-
-/*
- * Bonobo::PersistStream
- *
- * These two functions implement the Bonobo::PersistStream load and
- * save methods which allow data to be loaded into and out of the
- * BonoboObject.
- */
-static char *
-stream_read (Bonobo_Stream stream)
-{
- Bonobo_Stream_iobuf *buffer;
- CORBA_Environment ev;
- char *data = NULL;
- gint length = 0;
-
- CORBA_exception_init (&ev);
- do {
-#define READ_CHUNK_SIZE 65536
- Bonobo_Stream_read (stream, READ_CHUNK_SIZE,
- &buffer, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- if (buffer->_length <= 0)
- break;
-
- data = g_realloc (data, length + buffer->_length + 1);
-
- memcpy (data + length, buffer->_buffer, buffer->_length);
-
- length += buffer->_length;
-
- CORBA_free (buffer);
- } while (1);
-
- CORBA_free (buffer);
- CORBA_exception_free (&ev);
-
- if (data)
- data[length] = '\0';
- else
- data = g_strdup("");
-
- return data;
-} /* stream_read */
-
-/*
- * This function implements the Bonobo::PersistStream:load method.
- */
-static void
-pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream,
- Bonobo_Persist_ContentType type, void *data,
- CORBA_Environment *ev)
-{
- GList *list;
- char *vcard;
- EABVCardControl *vcard_control = data;
-
- if (type && g_ascii_strcasecmp (type, "text/vCard") != 0 &&
- g_ascii_strcasecmp (type, "text/x-vCard") != 0) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_WrongDataType, NULL);
- return;
- }
-
- if ((vcard = stream_read (stream)) == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_FileNotFound, NULL);
- return;
- }
-
- g_list_foreach (
- vcard_control->card_list,
- (GFunc) g_object_unref, NULL);
- g_list_free (vcard_control->card_list);
-
- list = eab_contact_list_from_string (vcard);
- g_free(vcard);
- vcard_control->card_list = list;
- if (list) {
- eab_contact_display_set_mode (
- vcard_control->display, vcard_control->mode);
- eab_contact_display_set_contact (
- vcard_control->display, E_CONTACT (list->data));
- }
- if (list && list->next) {
- char *message;
- int length = g_list_length (list) - 1;
- message = g_strdup_printf (ngettext("There is one other contact.",
- "There are %d other contacts.", length),
- length);
- gtk_label_set_text (GTK_LABEL (vcard_control->label), message);
- g_free (message);
- gtk_widget_show (vcard_control->label);
- } else {
- gtk_widget_hide (vcard_control->label);
- }
-} /* pstream_load */
-
-/*
- * This function implements the Bonobo::PersistStream:save method.
- */
-static void
-pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream,
- Bonobo_Persist_ContentType type, void *data,
- CORBA_Environment *ev)
-{
- EABVCardControl *vcard_control = data;
- char *vcard;
- int length;
-
- if (type && g_ascii_strcasecmp (type, "text/vCard") != 0 &&
- g_ascii_strcasecmp (type, "text/x-vCard") != 0) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_WrongDataType, NULL);
- return;
- }
-
- vcard = eab_contact_list_to_string (vcard_control->card_list);
- length = strlen (vcard);
- bonobo_stream_client_write (stream, vcard, length, ev);
- g_free (vcard);
-} /* pstream_save */
-
-static Bonobo_Persist_ContentTypeList *
-pstream_get_content_types (BonoboPersistStream *ps, void *closure,
- CORBA_Environment *ev)
-{
- return bonobo_persist_generate_content_types (2, "text/vCard", "text/x-vCard");
-}
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- GList *list = closure;
- if (status == E_BOOK_ERROR_OK) {
- GList *p;
- for (p = list; p; p = p->next) {
- /* XXX argh, more passing of NULL's for callbacks */
- eab_merging_book_add_contact (book, E_CONTACT (p->data), NULL, NULL);
- }
- }
- if (book)
- g_object_unref (book);
- g_list_foreach (list, (GFunc) g_object_unref, NULL);
- g_list_free (list);
-}
-
-static void
-save_in_addressbook(GtkWidget *button, gpointer data)
-{
- EABVCardControl *vcard_control = data;
- GList *list, *p;
-
- list = g_list_copy (vcard_control->card_list);
-
- for (p = list; p; p = p->next)
- g_object_ref (p->data);
-
- addressbook_load_default_book (book_open_cb, list);
-}
-
-static void
-toggle_full_vcard(GtkWidget *button, gpointer data)
-{
- EABVCardControl *vcard_control = data;
- EContact *contact;
- char *label;
-
- if (!vcard_control->card_list)
- return;
-
- contact = E_CONTACT (vcard_control->card_list->data);
-
- if (vcard_control->mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) {
- vcard_control->mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
- label = _("Show Full vCard");
- }
- else {
- vcard_control->mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
- label = _("Show Compact vCard");
- }
-
- gtk_button_set_label (GTK_BUTTON (button), label);
-
- eab_contact_display_set_mode (
- vcard_control->display, vcard_control->mode);
- eab_contact_display_set_contact (
- vcard_control->display, contact);
-}
-
-static void
-free_struct (gpointer data, GObject *where_object_was)
-{
- EABVCardControl *vcard_control = data;
-
- g_list_foreach (
- vcard_control->card_list,
- (GFunc) g_object_unref, NULL);
- g_list_free (vcard_control->card_list);
- g_free (vcard_control);
-}
-
-BonoboControl *
-eab_vcard_control_new (void)
-{
- BonoboControl *control;
- BonoboPersistStream *stream;
- GtkWidget *display;
- GtkWidget *button1, *button2;
- GtkWidget *bbox;
- GtkWidget *vbox;
-
- EABVCardControl *vcard_control = g_new (EABVCardControl, 1);
-
- vcard_control->card_list = NULL;
- vcard_control->display = NULL;
- vcard_control->label = NULL;
-
- vcard_control->mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
-
- /* Create the control. */
-
- display = eab_contact_display_new ();
- vcard_control->display = EAB_CONTACT_DISPLAY (display);
-
- bbox = gtk_hbutton_box_new ();
- gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
- gtk_box_set_spacing (GTK_BOX (bbox), 12);
-
- button1 = gtk_button_new_with_label(_("Show Full vCard"));
- g_signal_connect (button1, "clicked",
- G_CALLBACK (toggle_full_vcard), vcard_control);
- gtk_box_pack_start (GTK_BOX (bbox), button1, FALSE, FALSE, 0);
-
- button2 = gtk_button_new_with_label(_("Save in address book"));
- g_signal_connect (button2, "clicked",
- G_CALLBACK (save_in_addressbook), vcard_control);
- gtk_box_pack_start (GTK_BOX (bbox), button2, FALSE, FALSE, 0);
-
- /* This is intentionally not shown. */
- vcard_control->label = gtk_label_new ("");
-
- vbox = gtk_vbox_new (FALSE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), display, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), vcard_control->label, TRUE, TRUE, 0);
- gtk_widget_show_all (bbox);
- gtk_widget_show (display);
- gtk_widget_show (vbox);
-
- control = bonobo_control_new (vbox);
-
- g_object_weak_ref (G_OBJECT (control), free_struct, vcard_control);
-
- stream = bonobo_persist_stream_new (pstream_load, pstream_save,
- pstream_get_content_types,
- VCARD_CONTROL_ID,
- vcard_control);
-
- if (stream == NULL) {
- bonobo_object_unref (BONOBO_OBJECT (control));
- return NULL;
- }
-
- bonobo_object_add_interface (BONOBO_OBJECT (control),
- BONOBO_OBJECT (stream));
-
- return control;
-}
diff --git a/addressbook/gui/widgets/eab-vcard-control.h b/addressbook/gui/widgets/eab-vcard-control.h
deleted file mode 100644
index 06ca62727a..0000000000
--- a/addressbook/gui/widgets/eab-vcard-control.h
+++ /dev/null
@@ -1,28 +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)
- *
- */
-
-#ifndef __EAB_VCARD_CONTROL_H__
-#define __EAB_VCARD_CONTROL_H__
-
-#include <bonobo/bonobo-control.h>
-
-BonoboControl *eab_vcard_control_new (void);
-
-#endif /* __EAB_VCARD_CONTROL_H__ */
diff --git a/configure.in b/configure.in
index de0b0fe4dd..3d29ea6f64 100644
--- a/configure.in
+++ b/configure.in
@@ -1780,7 +1780,7 @@ plugins_base_always="calendar-file calendar-http $CALENDAR_WEATHER itip-formatte
plugins_base="$plugins_base_always $SA_JUNK_PLUGIN $BF_JUNK_PLUGIN $EXCHANGE_PLUGIN $MONO_PLUGIN "
all_plugins_base="$plugins_base_always sa-junk-plugin bogo-junk-plugin exchange-operations mono"
-plugins_standard_always="bbdb subject-thread save-calendar copy-tool mail-to-task audio-inline mailing-list-actions default-mailer import-ics-attachments prefer-plain mail-notification attachment-reminder face backup-restore email-custom-header templates pst-import"
+plugins_standard_always="bbdb subject-thread save-calendar copy-tool mail-to-task audio-inline mailing-list-actions default-mailer import-ics-attachments prefer-plain mail-notification attachment-reminder face backup-restore email-custom-header templates pst-import vcard-inline"
plugins_standard="$plugins_standard_always"
all_plugins_standard="$plugins_standard"
@@ -1790,7 +1790,7 @@ plugins_experimental="$plugins_experimental_always $IPOD_SYNC $TNEF_ATTACHMENTS
all_plugins_experimental="$plugins_experimental_always ipod-sync tnef-attachments"
dnl Temporary KILL-BONOBO hack
-enable_plugins="addressbook-file audio-inline bbdb bogo-junk-plugin caldav calendar-file calendar-http copy-tool default-source external-editor google-account-setup hula-account-setup imap-features mail-notification mail-to-meeting mark-all-read plugin-manager profiler sa-junk-plugin save-attachments save-calendar subject-thread tnef-attachments webdav-account-setup"
+enable_plugins="addressbook-file audio-inline bbdb bogo-junk-plugin caldav calendar-file calendar-http copy-tool default-source external-editor google-account-setup hula-account-setup imap-features mail-notification mail-to-meeting mark-all-read plugin-manager profiler sa-junk-plugin save-attachments save-calendar subject-thread tnef-attachments vcard-inline webdav-account-setup"
dnl PLUGINS NOT BUILDING YET
dnl ------------------------
@@ -2100,51 +2100,52 @@ mail/default/sv/Makefile
mail/default/hu/Makefile
mail/importers/Makefile
plugins/Makefile
-plugins/mark-all-read/Makefile
+plugins/addressbook-file/Makefile
+plugins/attachment-reminder/Makefile
+plugins/audio-inline/Makefile
+plugins/backup-restore/Makefile
+plugins/bbdb/Makefile
+plugins/bogo-junk-plugin/Makefile
plugins/caldav/Makefile
-plugins/google-account-setup/Makefile
plugins/calendar-file/Makefile
plugins/calendar-http/Makefile
plugins/calendar-weather/Makefile
-plugins/plugin-manager/Makefile
-plugins/bbdb/Makefile
-plugins/audio-inline/Makefile
-plugins/attachment-reminder/Makefile
+plugins/copy-tool/Makefile
+plugins/default-mailer/Makefile
+plugins/default-source/Makefile
+plugins/email-custom-header/Makefile
+plugins/exchange-operations/Makefile
+plugins/external-editor/Makefile
+plugins/face/Makefile
+plugins/folder-unsubscribe/Makefile
+plugins/google-account-setup/Makefile
+plugins/groupwise-account-setup/Makefile
+plugins/groupwise-features/Makefile
+plugins/hula-account-setup/Makefile
+plugins/imap-features/Makefile
+plugins/import-ics-attachments/Makefile
+plugins/ipod-sync/Makefile
+plugins/itip-formatter/Makefile
plugins/mail-notification/Makefile
plugins/mail-to-meeting/Makefile
plugins/mail-to-task/Makefile
+plugins/mailing-list-actions/Makefile
+plugins/mark-all-read/Makefile
plugins/mono/Makefile
-plugins/subject-thread/Makefile
-plugins/save-attachments/Makefile
-plugins/save-calendar/Makefile
+plugins/plugin-manager/Makefile
plugins/prefer-plain/Makefile
plugins/profiler/Makefile
+plugins/pst-import/Makefile
+plugins/publish-calendar/Makefile
plugins/python/Makefile
-plugins/copy-tool/Makefile
-plugins/folder-unsubscribe/Makefile
-plugins/mailing-list-actions/Makefile
-plugins/itip-formatter/Makefile
-plugins/backup-restore/Makefile
-plugins/email-custom-header/Makefile
-plugins/exchange-operations/Makefile
-plugins/default-source/Makefile
-plugins/default-mailer/Makefile
-plugins/addressbook-file/Makefile
-plugins/startup-wizard/Makefile
-plugins/groupwise-account-setup/Makefile
-plugins/hula-account-setup/Makefile
-plugins/groupwise-features/Makefile
plugins/sa-junk-plugin/Makefile
-plugins/bogo-junk-plugin/Makefile
-plugins/ipod-sync/Makefile
-plugins/publish-calendar/Makefile
-plugins/import-ics-attachments/Makefile
-plugins/imap-features/Makefile
-plugins/tnef-attachments/Makefile
+plugins/save-attachments/Makefile
+plugins/save-calendar/Makefile
+plugins/startup-wizard/Makefile
+plugins/subject-thread/Makefile
plugins/templates/Makefile
-plugins/pst-import/Makefile
-plugins/face/Makefile
-plugins/external-editor/Makefile
+plugins/tnef-attachments/Makefile
+plugins/vcard-inline/Makefile
plugins/webdav-account-setup/Makefile
smime/Makefile
smime/lib/Makefile
diff --git a/mail/e-mail-shell-module.c b/mail/e-mail-shell-module.c
index cdbfeac0f0..f699edf7c3 100644
--- a/mail/e-mail-shell-module.c
+++ b/mail/e-mail-shell-module.c
@@ -264,12 +264,13 @@ mail_shell_module_init_hooks (void)
{
e_plugin_hook_register_type (em_config_hook_get_type ());
e_plugin_hook_register_type (em_event_hook_get_type ());
- e_plugin_hook_register_type (em_format_hook_get_type ());
e_plugin_hook_register_type (em_junk_hook_get_type ());
+ /* EMFormat classes must be registered before EMFormatHook. */
em_format_hook_register_type (em_format_get_type ());
em_format_hook_register_type (em_format_html_get_type ());
em_format_hook_register_type (em_format_html_display_get_type ());
+ e_plugin_hook_register_type (em_format_hook_get_type ());
em_junk_hook_register_type (emj_get_type ());
}
diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c
index a857405bf9..9783a7157c 100644
--- a/mail/em-folder-view.c
+++ b/mail/em-folder-view.c
@@ -200,17 +200,6 @@ enum {
static guint signals[LAST_SIGNAL];
-static void emfv_selection_get(GtkWidget *widget, GtkSelectionData *data, guint info, guint time_stamp, EMFolderView *emfv);
-static void emfv_selection_clear_event(GtkWidget *widget, GdkEventSelection *event, EMFolderView *emfv);
-
-//#ifdef ENABLE_PROFILING
-//static void
-//emfv_format_complete(EMFormat *emf, EMFolderView *emfv)
-//{
-// e_profile_event_emit("goto.done", emf->uid?emf->uid:"", 0);
-//}
-//#endif
-
static void
emfv_init(GObject *o)
{
diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c
index 03ded0ef5c..70b92c39ff 100644
--- a/mail/em-format-html-display.c
+++ b/mail/em-format-html-display.c
@@ -46,11 +46,6 @@
#include <glib/gi18n.h>
-#include <bonobo/bonobo-control-frame.h>
-#include <bonobo/bonobo-stream-memory.h>
-#include <bonobo/bonobo-widget.h>
-#include <bonobo-activation/bonobo-activation-mime.h>
-
#include <camel/camel-stream.h>
#include <camel/camel-stream-filter.h>
#include <camel/camel-stream-mem.h>
@@ -198,8 +193,6 @@ static void efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart
static void efhd_complete(EMFormat *);
gboolean efhd_mnemonic_show_bar (GtkWidget *widget, gboolean focus, GtkWidget *efhd);
-static gboolean efhd_bonobo_object(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject);
-static gboolean efhd_use_component(const char *mime_type);
static void efhd_builtin_init(EMFormatHTMLDisplayClass *efhc);
enum {
@@ -211,8 +204,6 @@ enum {
static guint efhd_signals[EFHD_LAST_SIGNAL] = { 0 };
-/* EMFormatHandler's for bonobo objects */
-static GHashTable *efhd_bonobo_handlers;
static EMFormatHTMLClass *efhd_parent;
static EMFormatClass *efhd_format_class;
@@ -436,7 +427,7 @@ efhd_class_init (GObjectClass *class)
}
GType
-em_format_html_display_get_type(void)
+em_format_html_display_get_type (void)
{
static GType type = 0;
@@ -452,8 +443,6 @@ em_format_html_display_get_type(void)
efhd_parent = g_type_class_ref(em_format_html_get_type());
efhd_format_class = g_type_class_ref(em_format_get_type());
type = g_type_register_static(em_format_html_get_type(), "EMFormatHTMLDisplay", &info, 0);
-
- efhd_bonobo_handlers = g_hash_table_new(g_str_hash, g_str_equal);
}
return type;
@@ -1428,38 +1417,10 @@ efhd_builtin_init(EMFormatHTMLDisplayClass *efhc)
em_format_class_add_handler((EMFormatClass *)efhc, &type_builtin_table[i]);
}
-/* ********************************************************************** */
-static void
-efhd_bonobo_unknown(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- char *classid;
-
- classid = g_strdup_printf("bonobo-unknown:///em-format-html-display/%s", emf->part_id->str);
- em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_bonobo_object);
- camel_stream_printf(stream, "<object classid=\"%s\" type=\"%s\"></object><br>\n", classid, info->mime_type);
- g_free(classid);
-}
-
- /* ********************************************************************** */
-static const EMFormatHandler *efhd_find_handler(EMFormat *emf, const char *mime_type)
+static const EMFormatHandler *
+efhd_find_handler(EMFormat *emf, const char *mime_type)
{
- const EMFormatHandler *handle;
-
- if ( (handle = ((EMFormatClass *)efhd_parent)->find_handler(emf, mime_type)) == NULL
- && efhd_use_component(mime_type)
- && (handle = g_hash_table_lookup(efhd_bonobo_handlers, mime_type)) == NULL) {
-
- EMFormatHandler *h = g_malloc0(sizeof(*h));
-
- h->mime_type = g_strdup(mime_type);
- h->handler = efhd_bonobo_unknown;
- h->flags = EM_FORMAT_HANDLER_INLINE_DISPOSITION;
- g_hash_table_insert(efhd_bonobo_handlers, h->mime_type, h);
-
- handle = h;
- }
-
- return handle;
+ return ((EMFormatClass *) efhd_parent)->find_handler (emf, mime_type);
}
static void efhd_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *src)
@@ -2109,155 +2070,6 @@ efhd_attachment_frame(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri)
}
}
-static gboolean
-efhd_bonobo_object(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject)
-{
- CamelDataWrapper *wrapper;
- Bonobo_ServerInfo *component;
- GtkWidget *embedded;
- Bonobo_PersistStream persist;
- CORBA_Environment ev;
- CamelStreamMem *cstream;
- BonoboStream *bstream;
- BonoboControlFrame *control_frame;
- Bonobo_PropertyBag prop_bag;
-
- component = bonobo_activation_get_default_component_for_mime_type (eb->type);
- if (component == NULL)
- return FALSE;
-
- embedded = bonobo_widget_new_control(component->iid, NULL);
- CORBA_free(component);
- if (embedded == NULL)
- return FALSE;
-
- CORBA_exception_init(&ev);
-
- control_frame = bonobo_widget_get_control_frame((BonoboWidget *)embedded);
- prop_bag = bonobo_control_frame_get_control_property_bag(control_frame, NULL);
- if (prop_bag != CORBA_OBJECT_NIL) {
- /*
- * Now we can take care of business. Currently, the only control
- * that needs something passed to it through a property bag is
- * the iTip control, and it needs only the From email address,
- * but perhaps in the future we can generalize this section of code
- * to pass a bunch of useful things to all embedded controls.
- */
- const CamelInternetAddress *from;
- char *from_address;
-
- from = camel_mime_message_get_from((CamelMimeMessage *)((EMFormat *)efh)->message);
- from_address = camel_address_encode((CamelAddress *)from);
- bonobo_property_bag_client_set_value_string(prop_bag, "from_address", from_address, &ev);
- g_free(from_address);
-
- Bonobo_Unknown_unref(prop_bag, &ev);
- }
-
- persist = (Bonobo_PersistStream)Bonobo_Unknown_queryInterface(bonobo_widget_get_objref((BonoboWidget *)embedded),
- "IDL:Bonobo/PersistStream:1.0", &ev);
- if (persist == CORBA_OBJECT_NIL) {
- g_object_ref_sink(embedded);
- CORBA_exception_free(&ev);
- return FALSE;
- }
-
- /* Write the data to a CamelStreamMem... */
- cstream = (CamelStreamMem *)camel_stream_mem_new();
- wrapper = camel_medium_get_content_object((CamelMedium *)pobject->part);
- if (FALSE && !g_ascii_strncasecmp (eb->type, "text/", 5)) {
- /* do charset conversion, etc */
- d(printf("performing charset conversion for %s component\n", eb->type));
- em_format_format_text((EMFormat *)efh, (CamelStream *)cstream, wrapper);
- } else {
- camel_data_wrapper_decode_to_stream (wrapper, (CamelStream *) cstream);
- }
-
- /* ...convert the CamelStreamMem to a BonoboStreamMem... */
- bstream = bonobo_stream_mem_create((char *)cstream->buffer->data, cstream->buffer->len, TRUE, FALSE);
- camel_object_unref(cstream);
-
- /* ...and hydrate the PersistStream from the BonoboStream. */
- Bonobo_PersistStream_load(persist,
- bonobo_object_corba_objref(BONOBO_OBJECT (bstream)),
- eb->type, &ev);
- bonobo_object_unref(BONOBO_OBJECT (bstream));
- Bonobo_Unknown_unref(persist, &ev);
- CORBA_Object_release(persist, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_object_ref_sink(embedded);
- CORBA_exception_free(&ev);
- return FALSE;
- }
- CORBA_exception_free(&ev);
-
- gtk_widget_show(embedded);
- gtk_container_add(GTK_CONTAINER (eb), embedded);
-
- return TRUE;
-}
-
-static gboolean
-efhd_check_server_prop(Bonobo_ServerInfo *component, const char *propname, const char *value)
-{
- CORBA_sequence_CORBA_string stringv;
- Bonobo_ActivationProperty *prop;
- int i;
-
- prop = bonobo_server_info_prop_find(component, propname);
- if (!prop || prop->v._d != Bonobo_ACTIVATION_P_STRINGV)
- return FALSE;
-
- stringv = prop->v._u.value_stringv;
- for (i = 0; i < stringv._length; i++) {
- if (!g_ascii_strcasecmp(value, stringv._buffer[i]))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-efhd_use_component(const char *mime_type)
-{
- GList *components, *iter;
- Bonobo_ServerInfo *component = NULL;
-
- /* should this cache it? */
-
- if (g_ascii_strcasecmp(mime_type, "text/x-vcard") != 0
- && g_ascii_strcasecmp(mime_type, "text/calendar") != 0) {
- const char **mime_types;
- int i;
-
- mime_types = mail_config_get_allowable_mime_types();
- for (i = 0; mime_types[i]; i++) {
- if (!g_ascii_strcasecmp(mime_types[i], mime_type))
- goto type_ok;
- }
- return FALSE;
- }
-type_ok:
- components = bonobo_activation_get_all_components_for_mime_type (mime_type);
- for (iter = components; iter; iter = iter->next) {
- Bonobo_ServerInfo *comp = iter->data;
-
- comp = iter->data;
- if (efhd_check_server_prop(comp, "repo_ids", "IDL:Bonobo/PersistStream:1.0")
- && efhd_check_server_prop(comp, "bonobo:supported_mime_types", mime_type)) {
- component = comp;
- break;
- }
- }
-
- /* FIXME: How should I free the Bonobo_ServerInfo's ? */
- g_list_foreach (components, (GFunc)CORBA_free, NULL);
- g_list_free (components);
-
- return component != NULL;
-}
-
static void
attachment_bar_arrow_clicked(GtkWidget *w, EMFormatHTMLDisplay *efhd)
{
@@ -2639,16 +2451,8 @@ efhd_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part,
"</font></td></tr><tr></table>\n"
EM_FORMAT_HTML_VPAD);
- if (handle) {
- if (info->shown)
- handle->handler(emf, stream, part, handle);
- } else if (efhd_use_component(mime_type)) {
- g_free(classid); /* messy */
-
- classid = g_strdup_printf("bonobo-unknown:///em-format-html-display/%s", emf->part_id->str);
- em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_bonobo_object);
- camel_stream_printf(stream, "<object classid=\"%s\" type=\"%s\"></object><br>>\n", classid, mime_type);
- }
+ if (handle && info->shown)
+ handle->handler(emf, stream, part, handle);
g_free(classid);
}
diff --git a/plugins/audio-inline/org-gnome-audio-inline.eplug.xml b/plugins/audio-inline/org-gnome-audio-inline.eplug.xml
index 16c282a014..1e853df10b 100644
--- a/plugins/audio-inline/org-gnome-audio-inline.eplug.xml
+++ b/plugins/audio-inline/org-gnome-audio-inline.eplug.xml
@@ -4,33 +4,94 @@
type="shlib"
id="org.gnome.evolution.plugin.audioInline"
location="@PLUGINDIR@/liborg-gnome-audio-inline@SOEXT@"
- _name="Audio inline plugin">
+ _name="Inline Audio">
- <_description>A formatter plugin which displays audio attachments inline and allows you to play them directly from Evolution.</_description>
<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"/>
+ <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>
diff --git a/plugins/vcard-inline/Makefile.am b/plugins/vcard-inline/Makefile.am
new file mode 100644
index 0000000000..781eb53bd4
--- /dev/null
+++ b/plugins/vcard-inline/Makefile.am
@@ -0,0 +1,20 @@
+INCLUDES = \
+ -I$(top_srcdir) \
+ $(EVOLUTION_ADDRESSBOOK_CFLAGS) \
+ $(EVOLUTION_MAIL_CFLAGS)
+
+@EVO_PLUGIN_RULE@
+
+plugin_DATA = org-gnome-vcard-inline.eplug
+plugin_LTLIBRARIES = liborg-gnome-vcard-inline.la
+
+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 = \
+ $(EVOLUTION_ADDRESSBOOK_LIBS)
+ $(EVOLUTION_MAIL_LIBS)
+
+EXTRA_DIST = org-gnome-vcard-inline.eplug.xml
+
+BUILT_SOURCES = $(plugin_DATA)
+CLEANFILES = $(BUILT_SOURCES)
diff --git a/plugins/vcard-inline/org-gnome-vcard-inline.eplug.xml b/plugins/vcard-inline/org-gnome-vcard-inline.eplug.xml
new file mode 100644
index 0000000000..c54587d369
--- /dev/null
+++ b/plugins/vcard-inline/org-gnome-vcard-inline.eplug.xml
@@ -0,0 +1,28 @@
+<?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">
+
+ <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"/>
+ </group>
+ </hook>
+
+ </e-plugin>
+</e-plugin-list>
diff --git a/plugins/vcard-inline/vcard-inline.c b/plugins/vcard-inline/vcard-inline.c
new file mode 100644
index 0000000000..211eb69c2d
--- /dev/null
+++ b/plugins/vcard-inline/vcard-inline.c
@@ -0,0 +1,285 @@
+/*
+ * 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/e-book.h>
+#include <libebook/e-contact.h>
+#include <camel/camel-medium.h>
+#include <camel/camel-mime-part.h>
+#include <camel/camel-stream-mem.h>
+#include <gtkhtml/gtkhtml-embedded.h>
+
+#include "addressbook/gui/merging/eab-contact-merging.h"
+#include "addressbook/gui/widgets/eab-contact-display.h"
+#include "addressbook/util/addressbook.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 _VCardInlinePObject VCardInlinePObject;
+
+struct _VCardInlinePObject {
+ EMFormatHTMLPObject object;
+
+ GList *contact_list;
+ GtkWidget *contact_display;
+ GtkWidget *message_label;
+};
+
+static gint org_gnome_vcard_inline_classid;
+
+/* Forward Declarations */
+void org_gnome_vcard_inline_format (void *ep, EMFormatHookTarget *target);
+
+static void
+org_gnome_vcard_inline_pobject_free (EMFormatHTMLPObject *object)
+{
+ VCardInlinePObject *vcard_object;
+
+ vcard_object = (VCardInlinePObject *) object;
+
+ g_list_foreach (
+ vcard_object->contact_list,
+ (GFunc) g_object_unref, NULL);
+ g_list_free (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;
+ }
+}
+
+static void
+org_gnome_vcard_inline_decode (VCardInlinePObject *vcard_object,
+ CamelMimePart *mime_part)
+{
+ CamelDataWrapper *data_wrapper;
+ CamelMedium *medium;
+ CamelStream *stream;
+ GList *contact_list;
+ GByteArray *array;
+ const gchar *string;
+
+ 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_object (medium);
+ camel_data_wrapper_decode_to_stream (data_wrapper, stream);
+
+ string = (gchar *) array->data;
+ contact_list = eab_contact_list_from_string (string);
+ vcard_object->contact_list = contact_list;
+
+ camel_object_unref (data_wrapper);
+ camel_object_unref (stream);
+}
+
+static void
+org_gnome_vcard_inline_book_open_cb (EBook *book,
+ EBookStatus status,
+ gpointer user_data)
+{
+ GList *contact_list = user_data;
+ GList *iter;
+
+ if (status != E_BOOK_ERROR_OK)
+ goto exit;
+
+ for (iter = contact_list; iter != NULL; iter = iter->next)
+ eab_merging_book_add_contact (
+ book, E_CONTACT (iter->data), NULL, NULL);
+
+exit:
+ if (book != NULL)
+ g_object_unref (book);
+
+ g_list_foreach (contact_list, (GFunc) g_object_unref, NULL);
+ g_list_free (contact_list);
+}
+
+static void
+org_gnome_vcard_inline_save_cb (VCardInlinePObject *vcard_object)
+{
+ GList *contact_list;
+
+ contact_list = g_list_copy (vcard_object->contact_list);
+ g_list_foreach (contact_list, (GFunc) g_object_ref, NULL);
+
+ addressbook_load_default_book (
+ org_gnome_vcard_inline_book_open_cb, contact_list);
+}
+
+static void
+org_gnome_vcard_inline_toggle_cb (VCardInlinePObject *vcard_object,
+ GtkButton *button)
+{
+ EABContactDisplay *contact_display;
+ EABContactDisplayMode mode;
+ const gchar *label;
+
+ contact_display = EAB_CONTACT_DISPLAY (vcard_object->contact_display);
+ mode = eab_contact_display_get_mode (contact_display);
+
+ /* Toggle between "full" and "compact" modes. */
+ if (mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) {
+ mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT;
+ label = _("Show Full vCard");
+ } else {
+ mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
+ label = _("Show Compact vCard");
+ }
+
+ eab_contact_display_set_mode (contact_display, mode);
+ gtk_button_set_label (button, label);
+}
+
+static gboolean
+org_gnome_vcard_inline_embed (EMFormatHTML *format,
+ GtkHTMLEmbedded *embedded,
+ EMFormatHTMLPObject *object)
+{
+ VCardInlinePObject *vcard_object;
+ GtkWidget *button_box;
+ GtkWidget *container;
+ GtkWidget *widget;
+ EContact *contact;
+ guint length;
+
+ vcard_object = (VCardInlinePObject *) object;
+ length = g_list_length (vcard_object->contact_list);
+
+ if (vcard_object->contact_list != NULL)
+ contact = E_CONTACT (vcard_object->contact_list->data);
+ else
+ contact = NULL;
+
+ container = GTK_WIDGET (embedded);
+
+ widget = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_hbutton_box_new ();
+ gtk_button_box_set_layout (
+ GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START);
+ gtk_box_set_spacing (GTK_BOX (widget), 12);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ button_box = widget;
+
+ widget = eab_contact_display_new ();
+ eab_contact_display_set_contact (
+ EAB_CONTACT_DISPLAY (widget), contact);
+ eab_contact_display_set_mode (
+ EAB_CONTACT_DISPLAY (widget),
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ vcard_object->contact_display = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ vcard_object->message_label = g_object_ref (widget);
+
+ if (length == 2) {
+ const gchar *text;
+
+ text = _("There is one other contact.");
+ gtk_label_set_text (GTK_LABEL (widget), text);
+ gtk_widget_show (widget);
+
+ } else if (length > 2) {
+ gchar *text;
+
+ text = g_strdup_printf (
+ _("There are %d other contacts."), length - 1);
+ gtk_label_set_text (GTK_LABEL (widget), text);
+ gtk_widget_show (widget);
+ g_free (text);
+
+ } else
+ gtk_widget_hide (widget);
+
+ container = button_box;
+
+ widget = gtk_button_new_with_label (_("Show Full vCard"));
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (org_gnome_vcard_inline_toggle_cb),
+ vcard_object);
+
+ widget = gtk_button_new_with_label (_("Save in Address Book"));
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (org_gnome_vcard_inline_save_cb),
+ vcard_object);
+
+ return TRUE;
+}
+
+void
+org_gnome_vcard_inline_format (void *ep, EMFormatHookTarget *target)
+{
+ VCardInlinePObject *vcard_object;
+ gchar *classid;
+
+ classid = g_strdup_printf (
+ "org-gnome-vcard-inline-display-%d",
+ org_gnome_vcard_inline_classid++);
+
+ vcard_object = (VCardInlinePObject *)
+ em_format_html_add_pobject (
+ EM_FORMAT_HTML (target->format),
+ sizeof (VCardInlinePObject),
+ classid, target->part,
+ org_gnome_vcard_inline_embed);
+
+ camel_object_ref (target->part);
+
+ vcard_object->object.free = org_gnome_vcard_inline_pobject_free;
+ org_gnome_vcard_inline_decode (vcard_object, target->part);
+
+ camel_stream_printf (
+ target->stream, "<object classid=%s></object>", classid);
+
+ g_free (classid);
+}