aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/backend
diff options
context:
space:
mode:
authorJon Trowbridge <trow@ximian.com>2001-03-02 05:03:02 +0800
committerJon Trowbridge <trow@src.gnome.org>2001-03-02 05:03:02 +0800
commitce67772c53108003cd8ba2bf2130722ab17d5df8 (patch)
tree1b732c251e8cbf340ea060f8737fe504dadc7d77 /addressbook/backend
parentfae87e8d3d4e69f40b6c3e51ea2c8c8477995857 (diff)
downloadgsoc2013-evolution-ce67772c53108003cd8ba2bf2130722ab17d5df8.tar.gz
gsoc2013-evolution-ce67772c53108003cd8ba2bf2130722ab17d5df8.tar.zst
gsoc2013-evolution-ce67772c53108003cd8ba2bf2130722ab17d5df8.zip
Change for new EDestination/ESelectNamesModel API.
2001-03-01 Jon Trowbridge <trow@ximian.com> * gui/component/select-names/e-select-names-table-model.c (fill_in_info): Change for new EDestination/ESelectNamesModel API. * gui/component/select-names/e-select-names-manager.c (e_select_names_manager_get_source): Added. A function for looking up the ESelectNamesModel by id. (I didn't end up using this function, but it might come in handy later.) (e_select_names_manager_get_cards): #if 0/#endif out this function. (e_select_names_manager_create_entry): Modified to attach an ESelectNamesCompletion to the entry we create. (completion_handler): A post-completion handler for our EEntry, to take the completion's extra data (an EDestination) and properly stick it into our ESelectNamesModel. * gui/component/select-names/e-select-names.c (real_add_address_cb): Changed to operate on EDestinations rather than ECards and to use the new ESelectNamesModel API. This leads to a rather nice code simplication. (remove_address): Changed for new ESelectNamesModel API. * gui/component/select-names/e-select-names-bonobo.c (entry_get_property_fn): Rather than just passing the entry's text through the property bag, get the "address text" from the model. This returns a nice, verbose string of addresses with names expanded when the address is tied to an ECard (i.e. "Jon Trowbridge <trow@ximian.com>"). (impl_SelectNames_get_entry_for_section): Make the text property read-only. (entry_set_property_fn): ...and since it is read-only now, chop out the setter code. * gui/component/select-names/e-select-names-text-model.h: * gui/component/select-names/e-select-names-text-model.c: Again, this code has been (pretty much) totally rewritten to convert all text operations into changes on the ESelectNamesModel. This lets us give the associated EEntry some (IMHO) nice semantics regarding whitespace, etc. Includes object activation, so destinations tied to ECards are underlined and can be double-clicked to bring up a contact editor. * gui/component/select-names/e-select-names-model.h: * gui/component/select-names/e-select-names-model.c: I've heavily modified this object to both hide all implementation details (which the old version exposed a bit too much for my peculiar tastes) and to act as an EDestination container. The old code put the text model operations here. I've moved them all to ESelectNamesTextModel --- so the text model actions (insert, delete, etc.) are all done through the API rather than operating on ESelectNamesModel internals. * gui/component/select-names/e-select-names-completion.c: Added. A fairly complicated object derived from ECompletion that searches our local addressbook in various and sundry ways. * gui/component/select-names/e-select-names-completion.h: * backend/ebook/e-destination.h: * backend/ebook/e-destination.c: Added. This object encapsulates a place to sent an email to, which can either be just a address as a string ("trow@ximian.com"), a fancier string ("Jon Trowbridge <trow@ximian.com>"), or an ECard and a specific address within that ECard. svn path=/trunk/; revision=8459
Diffstat (limited to 'addressbook/backend')
-rw-r--r--addressbook/backend/ebook/Makefile.am8
-rw-r--r--addressbook/backend/ebook/e-address-completion.c315
-rw-r--r--addressbook/backend/ebook/e-address-completion.h65
-rw-r--r--addressbook/backend/ebook/e-destination.c284
-rw-r--r--addressbook/backend/ebook/e-destination.h73
5 files changed, 361 insertions, 384 deletions
diff --git a/addressbook/backend/ebook/Makefile.am b/addressbook/backend/ebook/Makefile.am
index 207a87256e..fbba0c98d0 100644
--- a/addressbook/backend/ebook/Makefile.am
+++ b/addressbook/backend/ebook/Makefile.am
@@ -39,19 +39,18 @@ lib_LTLIBRARIES = libebook.la
libebook_la_SOURCES = \
$(CORBA_SOURCE) \
- e-address-completion.c \
e-book-listener.c \
e-book-view-listener.c \
e-book-view.c \
e-book.c \
e-card-cursor.c \
e-card-simple.c \
- e-card.c
+ e-card.c \
+ e-destination.c
libebookincludedir = $(includedir)/evolution/ebook
libebookinclude_HEADERS = \
- e-address-completion.h \
e-book-listener.h \
e-book-types.h \
e-book-view-listener.h \
@@ -61,7 +60,8 @@ libebookinclude_HEADERS = \
e-card-pairs.h \
e-card-simple.h \
e-card-types.h \
- e-card.h
+ e-card.h \
+ e-destination.h
#
diff --git a/addressbook/backend/ebook/e-address-completion.c b/addressbook/backend/ebook/e-address-completion.c
deleted file mode 100644
index 398782e13e..0000000000
--- a/addressbook/backend/ebook/e-address-completion.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * An auto-completer for addresses from the address book.
- *
- * Author:
- * Jon Trowbridge <trow@ximian.com>
- *
- * Copyright (C) 2001 Ximian, Inc.
- */
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#include <config.h>
-#include "e-address-completion.h"
-
-static void e_address_completion_class_init (EAddressCompletionClass *klass);
-static void e_address_completion_init (EAddressCompletion *addr_comp);
-static void e_address_completion_destroy (GtkObject *object);
-
-static GtkObjectClass *parent_class;
-
-typedef struct _BookQuery BookQuery;
-struct _BookQuery {
- EAddressCompletion *completion;
- guint seq_no;
-
- gchar *text;
-
- EBookView *book_view;
- guint card_added_id;
- guint sequence_complete_id;
-};
-
-static BookQuery *book_query_new (EAddressCompletion *, const gchar *query_text);
-static void book_query_attach_book_view (BookQuery *, EBookView *);
-static void book_query_free (BookQuery *);
-static gboolean book_query_has_expired (BookQuery *);
-static double book_query_score_e_card (BookQuery *, ECard *);
-static void book_query_book_view_cb (EBook *, EBookStatus, EBookView *, gpointer book_query);
-static void book_query_card_added_cb (EBookView *, const GList *cards, gpointer book_query);
-static void book_query_sequence_complete_cb (EBookView *, gpointer book_query);
-
-
-
-GtkType
-e_address_completion_get_type (void)
-{
- static GtkType address_completion_type = 0;
-
- if (!address_completion_type) {
- GtkTypeInfo address_completion_info = {
- "EAddressCompletion",
- sizeof (EAddressCompletion),
- sizeof (EAddressCompletionClass),
- (GtkClassInitFunc) e_address_completion_class_init,
- (GtkObjectInitFunc) e_address_completion_init,
- NULL, NULL,
- (GtkClassInitFunc) NULL
- };
- address_completion_type = gtk_type_unique (e_completion_get_type (),
- &address_completion_info);
- }
-
- return address_completion_type;
-}
-
-static void
-e_address_completion_class_init (EAddressCompletionClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- parent_class = GTK_OBJECT_CLASS (gtk_type_class (e_completion_get_type ()));
-
- object_class->destroy = e_address_completion_destroy;
-}
-
-static void
-e_address_completion_init (EAddressCompletion *addr_comp)
-{
-
-}
-
-static void
-e_address_completion_destroy (GtkObject *object)
-{
- EAddressCompletion *addr_comp = E_ADDRESS_COMPLETION (object);
-
- gtk_object_unref (GTK_OBJECT (addr_comp->book));
-}
-
-static BookQuery *
-book_query_new (EAddressCompletion *comp, const gchar *text)
-{
- BookQuery *q = g_new0 (BookQuery, 1);
-
- q->completion = comp;
- gtk_object_ref (GTK_OBJECT (comp));
-
- q->seq_no = comp->seq_no;
-
- q->text = g_strdup (text);
-
- return q;
-}
-
-static void
-book_query_attach_book_view (BookQuery *q, EBookView *book_view)
-{
- g_return_if_fail (q);
-
- g_assert (q->book_view == NULL);
- q->book_view = book_view;
- gtk_object_ref (GTK_OBJECT (book_view));
-
- q->card_added_id = gtk_signal_connect (GTK_OBJECT (book_view),
- "card_added",
- GTK_SIGNAL_FUNC (book_query_card_added_cb),
- q);
- q->sequence_complete_id = gtk_signal_connect (GTK_OBJECT (book_view),
- "sequence_complete",
- GTK_SIGNAL_FUNC (book_query_sequence_complete_cb),
- q);
-}
-
-static void
-book_query_free (BookQuery *q)
-{
- if (q) {
- if (q->book_view) {
- gtk_signal_disconnect (GTK_OBJECT (q->book_view), q->card_added_id);
- gtk_signal_disconnect (GTK_OBJECT (q->book_view), q->sequence_complete_id);
- gtk_object_unref (GTK_OBJECT (q->book_view));
- }
-
- gtk_object_unref (GTK_OBJECT (q->completion));
-
- g_free (q->text);
-
- g_free (q);
- }
-}
-
-static gboolean
-book_query_has_expired (BookQuery *q)
-{
- g_return_val_if_fail (q != NULL, FALSE);
- return q->seq_no != q->completion->seq_no;
-}
-
-static double
-book_query_score_e_card (BookQuery *q, ECard *card)
-{
- gint len;
-
- g_return_val_if_fail (q != NULL, -1);
- g_return_val_if_fail (card != NULL && E_IS_CARD (card), -1);
-
- len = strlen (q->text);
-
- if (card->name->given && !g_strncasecmp (card->name->given, q->text, len))
- return len;
-
- if (card->name->additional && !g_strncasecmp (card->name->additional, q->text, len))
- return len;
-
- if (card->name->family && !g_strncasecmp (card->name->family, q->text, len))
- return len;
-
- return 0.5; /* Not good, but we'll leave them in anyway for now... */
-}
-
-static gchar*
-book_query_card_text (ECard *card)
-{
- if (card->name) {
- /* Sort of a lame hack. */
- return g_strdup_printf ("%s %s%s%s",
- card->name->given ? card->name->given : "",
- card->name->additional ? card->name->additional : "",
- card->name->additional ? " " : "",
- card->name->family ? card->name->family : "");
- } else if (card->fname) {
- return g_strdup (card->fname);
- } else if (card->file_as) {
- return g_strdup (card->file_as);
- }
-
- return NULL;
-}
-
-static void
-book_query_book_view_cb (EBook *book, EBookStatus status, EBookView *book_view, gpointer user_data)
-{
- BookQuery *q = (BookQuery *) user_data;
-
- if (book_query_has_expired (q)) {
- book_query_free (q);
- return;
- }
-
- book_query_attach_book_view (q, book_view);
-}
-
-static void
-book_query_card_added_cb (EBookView *book_view, const GList *cards, gpointer user_data)
-{
- BookQuery *q = (BookQuery *) user_data;
-
- if (book_query_has_expired (q)) {
- book_query_free (q);
- return;
- }
-
- while (cards) {
- ECard *card = (ECard *) cards->data;
- double score;
-
- if (card && (score = book_query_score_e_card (q, card)) >= 0) {
- gchar *str = book_query_card_text (card);
-
- if (str) {
- gtk_object_ref (GTK_OBJECT (card));
- e_completion_found_match_full (E_COMPLETION (q->completion), str, score,
- card, (GtkDestroyNotify)gtk_object_unref);
- }
- }
-
- cards = g_list_next (cards);
- }
-}
-
-static void
-book_query_sequence_complete_cb (EBookView *book_view, gpointer user_data)
-{
- BookQuery *q = (BookQuery *) user_data;
-
- if (! book_query_has_expired (q)) {
- e_completion_end_search (E_COMPLETION (q->completion));
- }
-
- book_query_free (q);
-}
-
-static void
-e_address_completion_begin (ECompletion *comp, const gchar *text, gint pos, gint limit, gpointer user_data)
-{
- EAddressCompletion *addr_comp = E_ADDRESS_COMPLETION (comp);
- BookQuery *q;
- gchar *query;
-
- ++addr_comp->seq_no; /* Paranoia, in case completion_begin were to be called twice in a row
- without an intervening completion_end. (Of course, this shouldn't
- happen...) */
- q = book_query_new (addr_comp, text);
-
- query = g_strdup_printf ("(contains \"x-evolution-any-field\" \"%s\")", text);
- e_book_get_book_view (addr_comp->book, query, book_query_book_view_cb, q);
- g_free (query);
-}
-
-static void
-e_address_completion_end (ECompletion *comp, gboolean finished, gpointer user_data)
-{
- EAddressCompletion *addr_comp = E_ADDRESS_COMPLETION (comp);
-
- ++addr_comp->seq_no;
-}
-
-void
-e_address_completion_construct (EAddressCompletion *addr_comp, EBook *book)
-{
- g_return_if_fail (addr_comp != NULL);
- g_return_if_fail (E_IS_ADDRESS_COMPLETION (addr_comp));
- g_return_if_fail (book != NULL);
- g_return_if_fail (E_IS_BOOK (book));
-
- /* No switching books mid-stream. */
- g_return_if_fail (addr_comp->book == NULL);
-
- e_completion_construct (E_COMPLETION (addr_comp),
- e_address_completion_begin,
- e_address_completion_end,
- NULL);
-
- addr_comp->book = book;
- gtk_object_ref (GTK_OBJECT (book));
-}
-
-ECompletion *
-e_address_completion_new (EBook *book)
-{
- gpointer ptr;
-
- g_return_val_if_fail (book != NULL, NULL);
- g_return_val_if_fail (E_IS_BOOK (book), NULL);
-
- ptr = gtk_type_new (e_address_completion_get_type ());
- e_address_completion_construct (E_ADDRESS_COMPLETION (ptr), book);
- return E_COMPLETION (ptr);
-}
diff --git a/addressbook/backend/ebook/e-address-completion.h b/addressbook/backend/ebook/e-address-completion.h
deleted file mode 100644
index d0fca50cda..0000000000
--- a/addressbook/backend/ebook/e-address-completion.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * An auto-completer for addresses from the address book.
- *
- * Author:
- * Jon Trowbridge <trow@ximian.com>
- *
- * Copyright (C) 2001 Ximian, Inc.
- */
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#ifndef E_ADDRESS_COMPLETION_H
-#define E_ADDRESS_COMPLETION_H
-
-#include "e-book.h"
-#include <gal/e-text/e-completion.h>
-
-BEGIN_GNOME_DECLS
-
-#define E_ADDRESS_COMPLETION_TYPE (e_address_completion_get_type ())
-#define E_ADDRESS_COMPLETION(o) (GTK_CHECK_CAST ((o), E_ADDRESS_COMPLETION_TYPE, EAddressCompletion))
-#define E_ADDRESS_COMPLETION_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), E_ADDRESS_COMPLETION_TYPE, EAddressCompletionClass))
-#define E_IS_ADDRESS_COMPLETION(o) (GTK_CHECK_TYPE ((o), E_ADDRESS_COMPLETION_TYPE))
-#define E_IS_ADDRESS_COMPLETION_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_ADDRESS_COMPLETION_TYPE))
-
-typedef struct _EAddressCompletion EAddressCompletion;
-typedef struct _EAddressCompletionClass EAddressCompletionClass;
-
-struct _EAddressCompletion {
- ECompletion parent;
-
- EBook *book;
- guint seq_no;
-};
-
-struct _EAddressCompletionClass {
- ECompletionClass parent_class;
-};
-
-GtkType e_address_completion_get_type (void);
-
-void e_address_completion_construct (EAddressCompletion *addr_comp, EBook *book);
-ECompletion *e_address_completion_new (EBook *book);
-
-
-
-
-#endif /* E_ADDRESS_COMPLETION_H */
-
diff --git a/addressbook/backend/ebook/e-destination.c b/addressbook/backend/ebook/e-destination.c
new file mode 100644
index 0000000000..92aed64715
--- /dev/null
+++ b/addressbook/backend/ebook/e-destination.c
@@ -0,0 +1,284 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * e-destination.c
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Developed by Jon Trowbridge <trow@ximian.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <libgnome/gnome-defs.h>
+#include <libgnome/gnome-i18n.h>
+#include "e-destination.h"
+
+struct _EDestinationPrivate {
+ ECard *card;
+ gint card_email_num;
+
+ gchar *string;
+ gchar *string_email;
+ gchar *string_email_verbose;
+};
+
+static void e_destination_clear_card (EDestination *);
+static void e_destination_clear_strings (EDestination *);
+
+static GtkObjectClass *parent_class;
+
+static void
+e_destination_destroy (GtkObject *obj)
+{
+ EDestination *dest = E_DESTINATION (obj);
+
+ e_destination_clear_card (dest);
+ e_destination_clear_strings (dest);
+
+ g_free (dest->priv);
+
+ if (parent_class->destroy)
+ parent_class->destroy (obj);
+}
+
+static void
+e_destination_class_init (EDestinationClass *klass)
+{
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
+
+ parent_class = GTK_OBJECT_CLASS (gtk_type_class (GTK_TYPE_OBJECT));
+
+ object_class->destroy = e_destination_destroy;
+}
+
+static void
+e_destination_init (EDestination *dest)
+{
+ dest->priv = g_new0 (struct _EDestinationPrivate, 1);
+}
+
+GtkType
+e_destination_get_type (void)
+{
+ static GtkType dest_type = 0;
+
+ if (!dest_type) {
+ GtkTypeInfo dest_info = {
+ "EDestination",
+ sizeof (EDestination),
+ sizeof (EDestinationClass),
+ (GtkClassInitFunc) e_destination_class_init,
+ (GtkObjectInitFunc) e_destination_init,
+ NULL, NULL, /* reserved */
+ (GtkClassInitFunc) NULL
+ };
+
+ dest_type = gtk_type_unique (gtk_object_get_type (), &dest_info);
+ }
+
+ return dest_type;
+}
+
+EDestination *
+e_destination_new (void)
+{
+ return E_DESTINATION (gtk_type_new (E_TYPE_DESTINATION));
+}
+
+EDestination *
+e_destination_copy (EDestination *dest)
+{
+ EDestination *new_dest;
+
+ g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
+
+ new_dest = e_destination_new ();
+
+ new_dest->priv->card = dest->priv->card;
+ if (new_dest->priv->card)
+ gtk_object_ref (GTK_OBJECT (new_dest->priv->card));
+
+ new_dest->priv->card_email_num = dest->priv->card_email_num;
+
+ new_dest->priv->string = g_strdup (dest->priv->string);
+ new_dest->priv->string_email = g_strdup (dest->priv->string_email);
+ new_dest->priv->string_email_verbose = g_strdup (dest->priv->string_email_verbose);
+
+ return new_dest;
+}
+
+static void
+e_destination_clear_card (EDestination *dest)
+{
+ if (dest->priv->card)
+ gtk_object_unref (GTK_OBJECT (dest->priv->card));
+ dest->priv->card = NULL;
+
+ dest->priv->card_email_num = -1;
+}
+
+static void
+e_destination_clear_strings (EDestination *dest)
+{
+ g_free (dest->priv->string);
+ g_free (dest->priv->string_email);
+ g_free (dest->priv->string_email_verbose);
+
+ dest->priv->string = NULL;
+ dest->priv->string_email = NULL;
+ dest->priv->string_email_verbose = NULL;
+}
+
+void
+e_destination_set_card (EDestination *dest, ECard *card, gint email_num)
+{
+ g_return_if_fail (dest && E_IS_DESTINATION (dest));
+ g_return_if_fail (card && E_IS_CARD (card));
+
+ if (dest->priv->card != card) {
+ if (dest->priv->card)
+ gtk_object_unref (GTK_OBJECT (dest->priv->card));
+ dest->priv->card = card;
+ gtk_object_ref (GTK_OBJECT (card));
+ }
+
+ dest->priv->card_email_num = email_num;
+
+ e_destination_clear_strings (dest);
+}
+
+void
+e_destination_set_string (EDestination *dest, const gchar *string)
+{
+ g_return_if_fail (dest && E_IS_DESTINATION (dest));
+ g_return_if_fail (string != NULL);
+
+ g_free (dest->priv->string);
+ dest->priv->string = g_strdup (string);
+}
+
+ECard *
+e_destination_get_card (const EDestination *dest)
+{
+ g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
+
+ return dest->priv->card;
+}
+
+const gchar *
+e_destination_get_string (const EDestination *dest)
+{
+ struct _EDestinationPrivate *priv;
+
+ g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
+
+ priv = (struct _EDestinationPrivate *)dest->priv; /* cast out const */
+
+ if (priv->string == NULL) {
+
+ if (priv->card) {
+
+ priv->string = e_card_name_to_string (priv->card->name);
+
+ }
+ }
+
+ return priv->string;
+}
+
+gint
+e_destination_get_strlen (const EDestination *dest)
+{
+ const gchar *str;
+
+ g_return_val_if_fail (dest && E_IS_DESTINATION (dest), 0);
+
+ str = e_destination_get_string (dest);
+ return str ? strlen (str) : 0;
+}
+
+const gchar *
+e_destination_get_email (const EDestination *dest)
+{
+ struct _EDestinationPrivate *priv;
+
+ g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
+
+ priv = (struct _EDestinationPrivate *)dest->priv; /* cast out const */
+
+ if (priv->string_email == NULL) {
+
+ if (priv->card) { /* Pull the address out of the card. */
+
+ EIterator *iter = e_list_get_iterator (priv->card->email);
+ gint n = priv->card_email_num;
+
+ if (n >= 0) {
+ while (n > 0) {
+ e_iterator_next (iter);
+ --n;
+ }
+
+ if (e_iterator_is_valid (iter)) {
+ gconstpointer ptr = e_iterator_get (iter);
+ priv->string_email = g_strdup ((gchar *) ptr);
+ }
+ }
+
+ } else if (priv->string) { /* Use the string as an e-mail address */
+ return priv->string;
+ }
+
+ /* else we just return NULL */
+ }
+
+ return priv->string_email;
+}
+
+const gchar *
+e_destination_get_email_verbose (const EDestination *dest)
+{
+ struct _EDestinationPrivate *priv;
+
+ g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
+
+ priv = (struct _EDestinationPrivate *)dest->priv; /* cast out const */
+
+ if (priv->string_email_verbose == NULL) {
+
+ const gchar *email = e_destination_get_email (dest);
+
+ if (priv->card) {
+
+ priv->string_email_verbose = g_strdup_printf ("%s <%s>",
+ e_card_name_to_string (priv->card->name),
+ email);
+ } else {
+
+ return email;
+ }
+
+ }
+
+ return priv->string_email_verbose;
+}
+
+
diff --git a/addressbook/backend/ebook/e-destination.h b/addressbook/backend/ebook/e-destination.h
new file mode 100644
index 0000000000..509a351f1d
--- /dev/null
+++ b/addressbook/backend/ebook/e-destination.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * e-destination.h
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Developed by Jon Trowbridge <trow@ximian.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+#ifndef __E_DESTINATION_H__
+#define __E_DESTINATION_H__
+
+#include <gtk/gtk.h>
+#include <addressbook/backend/ebook/e-card.h>
+
+#define E_TYPE_DESTINATION (e_destination_get_type ())
+#define E_DESTINATION(o) (GTK_CHECK_CAST ((o), E_TYPE_DESTINATION, EDestination))
+#define E_DESTINATION_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), E_TYPE_DESTINATION, EDestinationClass))
+#define E_IS_DESTINATION(o) (GTK_CHECK_TYPE ((o), E_TYPE_DESTINATION))
+#define E_IS_DESTINATION_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TYPE_DESTINATION))
+
+typedef struct _EDestination EDestination;
+typedef struct _EDestinationClass EDestinationClass;
+
+struct _EDestinationPrivate;
+
+struct _EDestination {
+ GtkObject object;
+
+ struct _EDestinationPrivate *priv;
+};
+
+struct _EDestinationClass {
+ GtkObjectClass parent_class;
+};
+
+GtkType e_destination_get_type (void);
+
+EDestination *e_destination_new (void);
+EDestination *e_destination_copy (EDestination *);
+
+void e_destination_set_card (EDestination *, ECard *card, gint email_num);
+void e_destination_set_string (EDestination *, const gchar *string);
+
+ECard *e_destination_get_card (const EDestination *);
+const gchar *e_destination_get_string (const EDestination *);
+gint e_destination_get_strlen (const EDestination *); /* a convenience function... */
+
+const gchar *e_destination_get_email (const EDestination *);
+const gchar *e_destination_get_email_verbose (const EDestination *);
+
+
+
+#endif /* __E_DESTINATION_H__ */
+