From 653cfffc0e00dfb59b36813c1b45c53d3f773c65 Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Tue, 21 Oct 2003 18:49:34 +0000 Subject: Merge new-ui-branch to the trunk. svn path=/trunk/; revision=22965 --- addressbook/gui/widgets/eab-vcard-control.c | 310 ++++++++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 addressbook/gui/widgets/eab-vcard-control.c (limited to 'addressbook/gui/widgets/eab-vcard-control.c') diff --git a/addressbook/gui/widgets/eab-vcard-control.c b/addressbook/gui/widgets/eab-vcard-control.c new file mode 100644 index 0000000000..82c5fd6032 --- /dev/null +++ b/addressbook/gui/widgets/eab-vcard-control.c @@ -0,0 +1,310 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * eab-vcard-control.c + * + * Copyright (C) 1999, 2000, 2001, 2002, 2003, Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: + * Chris Lahey + * Chris Toshok + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "eab-vcard-control.h" +#include "eab-contact-merging.h" + +typedef struct { + EABContactDisplay *display; + GList *card_list; + GtkWidget *label; + EABContactDisplayRenderMode render_mode; +} EABVCardControl; + +#define VCARD_CONTROL_ID "OAFIID:GNOME_Evolution_Addressbook_VCard_Control" + +/* + * 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; + } + + e_free_object_list (vcard_control->card_list); + list = eab_contact_list_from_string (vcard); + g_free(vcard); + vcard_control->card_list = list; + if (list) { + eab_contact_display_render (vcard_control->display, E_CONTACT (list->data), + vcard_control->render_mode); + } + if (list && list->next) { + char *message; + int length = g_list_length (list) - 1; + if (length > 1) { + message = g_strdup_printf (_("and %d other contacts."), length); + } else { + message = g_strdup_printf (_("and one other contact.")); + } + 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); + e_free_object_list (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; + char *label; + + if (!vcard_control->card_list) + return; + + if (vcard_control->render_mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) { + vcard_control->render_mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT; + label = _("Show Full VCard"); + } + else { + vcard_control->render_mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL; + label = _("Show Compact VCard"); + } + + gtk_button_set_label (GTK_BUTTON (button), label); + eab_contact_display_render (vcard_control->display, E_CONTACT (vcard_control->card_list->data), + vcard_control->render_mode); +} + +static void +free_struct (gpointer data, GObject *where_object_was) +{ + EABVCardControl *vcard_control = data; + e_free_object_list (vcard_control->card_list); + g_free (vcard_control); +} + +BonoboControl * +eab_vcard_control_new (void) +{ + BonoboControl *control; + BonoboPersistStream *stream; + GtkWidget *display; + GtkWidget *button1, *button2; + GtkWidget *label; + GtkWidget *table; + + EABVCardControl *vcard_control = g_new (EABVCardControl, 1); + + printf ("inside eab_vcard_control_new\n"); + + vcard_control->card_list = NULL; + vcard_control->display = NULL; + vcard_control->label = NULL; + + vcard_control->render_mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT; + + /* Create the control. */ + + display = eab_contact_display_new (); + gtk_widget_show (display); + vcard_control->display = EAB_CONTACT_DISPLAY (display); + + /* This is intentionally not shown. */ + label = gtk_label_new (""); + vcard_control->label = label; + + button1 = gtk_button_new_with_label(_("Show Full VCard")); + g_signal_connect (button1, "clicked", + G_CALLBACK (toggle_full_vcard), vcard_control); + gtk_widget_show (button1); + + button2 = gtk_button_new_with_label(_("Save in addressbook")); + g_signal_connect (button2, "clicked", + G_CALLBACK (save_in_addressbook), vcard_control); + gtk_widget_show (button2); + + table = gtk_table_new (6, 6, FALSE); + gtk_table_attach (GTK_TABLE (table), display, 0, 6, 3, 6, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach (GTK_TABLE (table), label, 0, 3, 2, 3, GTK_FILL, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), button1, 0, 1, 1, 2, 0, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), button2, 1, 2, 1, 2, 0, 0, 0, 0); + gtk_widget_show (table); + + control = bonobo_control_new (table); + + 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; +} -- cgit v1.2.3