aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/gui/contact-editor/e-contact-quick-add.c
diff options
context:
space:
mode:
Diffstat (limited to 'addressbook/gui/contact-editor/e-contact-quick-add.c')
-rw-r--r--addressbook/gui/contact-editor/e-contact-quick-add.c731
1 files changed, 519 insertions, 212 deletions
diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.c b/addressbook/gui/contact-editor/e-contact-quick-add.c
index e8d623afb0..5814205c4d 100644
--- a/addressbook/gui/contact-editor/e-contact-quick-add.c
+++ b/addressbook/gui/contact-editor/e-contact-quick-add.c
@@ -1,286 +1,395 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-contact-quick-add.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 version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
+ * 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 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.
+ * 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:
+ * Jon Trowbridge <trow@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
+
#include <ctype.h>
-#include <glib.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtktable.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <libgnomeui/gnome-stock.h>
-#include <gal/widgets/e-unicode.h>
-#include <addressbook/gui/component/addressbook.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-book-util.h>
-#include <addressbook/backend/ebook/e-card.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <addressbook/util/eab-book-util.h>
#include "e-contact-editor.h"
#include "e-contact-quick-add.h"
-#include "e-card-merging.h"
+#include "eab-contact-merging.h"
typedef struct _QuickAdd QuickAdd;
struct _QuickAdd {
gchar *name;
gchar *email;
- ECard *card;
+ gchar *vcard;
+ EContact *contact;
+ GCancellable *cancellable;
+ EClientCache *client_cache;
+ ESource *source;
EContactQuickAddCallback cb;
gpointer closure;
+ GtkWidget *dialog;
GtkWidget *name_entry;
GtkWidget *email_entry;
+ GtkWidget *combo_box;
gint refs;
};
static QuickAdd *
-quick_add_new (void)
+quick_add_new (EClientCache *client_cache)
{
QuickAdd *qa = g_new0 (QuickAdd, 1);
- qa->card = e_card_new ("");
+ qa->contact = e_contact_new ();
+ qa->client_cache = g_object_ref (client_cache);
qa->refs = 1;
return qa;
}
static void
-quick_add_ref (QuickAdd *qa)
-{
- if (qa) {
- ++qa->refs;
- }
-}
-
-static void
quick_add_unref (QuickAdd *qa)
{
if (qa) {
--qa->refs;
if (qa->refs == 0) {
+ if (qa->cancellable != NULL) {
+ g_cancellable_cancel (qa->cancellable);
+ g_object_unref (qa->cancellable);
+ }
g_free (qa->name);
g_free (qa->email);
- gtk_object_unref (GTK_OBJECT (qa->card));
+ g_free (qa->vcard);
+ g_object_unref (qa->contact);
+ g_object_unref (qa->client_cache);
g_free (qa);
}
}
}
static void
-quick_add_set_name (QuickAdd *qa, const gchar *name)
+quick_add_set_name (QuickAdd *qa,
+ const gchar *name)
{
- ECardName *card_name;
-
if (name == qa->name)
return;
g_free (qa->name);
-
- card_name = e_card_name_from_string (name);
- qa->name = e_card_name_to_string (card_name);
-
- gtk_object_set (GTK_OBJECT (qa->card),
- "full_name", qa->name,
- NULL);
-
- e_card_name_unref (card_name);
+ qa->name = g_strdup (name);
}
static void
-quick_add_set_email (QuickAdd *qa, const gchar *email)
+quick_add_set_email (QuickAdd *qa,
+ const gchar *email)
{
- ECardSimple *simple;
-
if (email == qa->email)
return;
g_free (qa->email);
qa->email = g_strdup (email);
+}
+
+static void
+quick_add_set_vcard (QuickAdd *qa,
+ const gchar *vcard)
+{
+ if (vcard == qa->vcard)
+ return;
- simple = e_card_simple_new (qa->card);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_EMAIL, email);
- e_card_simple_sync_card (simple);
- gtk_object_unref (GTK_OBJECT (simple));
+ g_free (qa->vcard);
+ qa->vcard = g_strdup (vcard);
}
static void
-merge_cb (EBook *book, EBookStatus status, gpointer closure)
+merge_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- QuickAdd *qa = (QuickAdd *) closure;
+ QuickAdd *qa = user_data;
+ EClient *client;
+ GError *error = NULL;
+
+ client = e_client_cache_get_client_finish (
+ E_CLIENT_CACHE (source_object), result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ /* Ignore cancellations. */
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_warn_if_fail (client == NULL);
+ g_error_free (error);
+ return;
+ }
- if (book != NULL) {
- e_card_merging_book_add_card (book, qa->card, NULL, NULL);
- if (qa->cb)
- qa->cb (qa->card, qa->closure);
- gtk_object_unref (GTK_OBJECT (book));
- } else {
- /* Something went wrong. */
+ if (error != NULL) {
if (qa->cb)
qa->cb (NULL, qa->closure);
+ g_error_free (error);
+ quick_add_unref (qa);
+ return;
+ }
+
+ if (!e_client_is_readonly (client)) {
+ ESourceRegistry *registry;
+
+ registry = e_client_cache_ref_registry (qa->client_cache);
+
+ eab_merging_book_add_contact (
+ registry, E_BOOK_CLIENT (client),
+ qa->contact, NULL, NULL);
+
+ g_object_unref (registry);
+ } else {
+ ESource *source = e_client_get_source (client);
+
+ e_alert_run_dialog_for_args (
+ e_shell_get_active_window (NULL),
+ "addressbook:error-read-only",
+ e_source_get_display_name (source),
+ NULL);
}
-
+
+ if (qa->cb)
+ qa->cb (qa->contact, qa->closure);
+
+ g_object_unref (client);
+
quick_add_unref (qa);
}
static void
-quick_add_merge_card (QuickAdd *qa)
+quick_add_merge_contact (QuickAdd *qa)
{
- EBook *book;
+ if (qa->cancellable != NULL) {
+ g_cancellable_cancel (qa->cancellable);
+ g_object_unref (qa->cancellable);
+ }
- quick_add_ref (qa);
+ qa->cancellable = g_cancellable_new ();
- book = e_book_new ();
- if (!addressbook_load_default_book (book, merge_cb, qa)) {
- gtk_object_unref (GTK_OBJECT (book));
- merge_cb (book, E_BOOK_STATUS_OTHER_ERROR, qa);
- }
+ e_client_cache_get_client (
+ qa->client_cache, qa->source,
+ E_SOURCE_EXTENSION_ADDRESS_BOOK,
+ qa->cancellable, merge_cb, qa);
}
-
-/*
- * Raise a contact editor with all fields editable, and hook up all signals accordingly.
- */
+/* Raise a contact editor with all fields editable,
+ * and hook up all signals accordingly. */
static void
-card_added_cb (EContactEditor *ce, EBookStatus status, ECard *card, gpointer closure)
+contact_added_cb (EContactEditor *ce,
+ const GError *error,
+ EContact *contact,
+ gpointer closure)
{
- QuickAdd *qa = (QuickAdd *) gtk_object_get_data (GTK_OBJECT (ce), "quick_add");
+ QuickAdd *qa;
- if (qa) {
+ qa = g_object_get_data (G_OBJECT (ce), "quick_add");
+ if (qa) {
if (qa->cb)
- qa->cb (qa->card, qa->closure);
-
+ qa->cb (qa->contact, qa->closure);
+
/* We don't need to unref qa because we set_data_full below */
- gtk_object_set_data (GTK_OBJECT (ce), "quick_add", NULL);
+ g_object_set_data (G_OBJECT (ce), "quick_add", NULL);
}
}
static void
-editor_closed_cb (GtkWidget *w, gpointer closure)
+editor_closed_cb (GtkWidget *w,
+ gpointer closure)
{
- QuickAdd *qa = (QuickAdd *) gtk_object_get_data (GTK_OBJECT (w), "quick_add");
+ QuickAdd *qa;
+
+ qa = g_object_get_data (G_OBJECT (w), "quick_add");
if (qa)
/* We don't need to unref qa because we set_data_full below */
- gtk_object_set_data (GTK_OBJECT (w), "quick_add", NULL);
-
- gtk_object_unref (GTK_OBJECT (w));
+ g_object_set_data (G_OBJECT (w), "quick_add", NULL);
}
static void
-ce_have_book (EBook *book, EBookStatus status, gpointer closure)
+ce_have_contact (EBookClient *book_client,
+ const GError *error,
+ EContact *contact,
+ gpointer closure)
{
QuickAdd *qa = (QuickAdd *) closure;
- if (book == NULL) {
- g_warning ("Couldn't open local address book.");
+ if (error) {
+ if (book_client)
+ g_object_unref (book_client);
+ g_warning (
+ "Failed to find contact, status %d (%s).",
+ error->code, error->message);
quick_add_unref (qa);
} else {
- EContactEditor *contact_editor = e_contact_editor_new (book, qa->card, TRUE, TRUE /* XXX */);
-
- /* mark it as changed so the Save buttons are enabled when we bring up the dialog. */
- gtk_object_set (GTK_OBJECT(contact_editor),
- "changed", TRUE,
- NULL);
-
- /* We pass this via object data, so that we don't get a dangling pointer referenced if both
- the "card_added" and "editor_closed" get emitted. (Which, based on a backtrace in bugzilla,
- I think can happen and cause a crash. */
- gtk_object_set_data_full (GTK_OBJECT (contact_editor), "quick_add", qa,
- (GtkDestroyNotify) quick_add_unref);
-
- gtk_signal_connect (GTK_OBJECT (contact_editor),
- "card_added",
- GTK_SIGNAL_FUNC (card_added_cb),
- NULL);
- gtk_signal_connect (GTK_OBJECT (contact_editor),
- "editor_closed",
- GTK_SIGNAL_FUNC (editor_closed_cb),
- NULL);
-
- gtk_object_unref (GTK_OBJECT (book));
+ EShell *shell;
+ EABEditor *contact_editor;
+
+ if (contact) {
+ /* use found contact */
+ if (qa->contact)
+ g_object_unref (qa->contact);
+ qa->contact = g_object_ref (contact);
+ }
+
+ shell = e_shell_get_default ();
+ contact_editor = e_contact_editor_new (
+ shell, book_client, qa->contact, TRUE, TRUE /* XXX */);
+
+ /* Mark it as changed so the Save buttons are
+ * enabled when we bring up the dialog. */
+ g_object_set (
+ contact_editor, "changed", contact != NULL, NULL);
+
+ /* We pass this via object data, so that we don't get a
+ * dangling pointer referenced if both the "contact_added"
+ * and "editor_closed" get emitted. (Which, based on a
+ * backtrace in bugzilla, I think can happen and cause a
+ * crash. */
+ g_object_set_data_full (
+ G_OBJECT (contact_editor), "quick_add", qa,
+ (GDestroyNotify) quick_add_unref);
+
+ g_signal_connect (
+ contact_editor, "contact_added",
+ G_CALLBACK (contact_added_cb), NULL);
+ g_signal_connect (
+ contact_editor, "editor_closed",
+ G_CALLBACK (editor_closed_cb), NULL);
+
+ g_object_unref (book_client);
+ }
+}
+
+static void
+ce_have_book (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ QuickAdd *qa = user_data;
+ EClient *client;
+ ESourceRegistry *registry;
+ GError *error = NULL;
+
+ client = e_client_cache_get_client_finish (
+ E_CLIENT_CACHE (source_object), result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ /* Ignore cancellations. */
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_warn_if_fail (client == NULL);
+ g_error_free (error);
+ return;
}
+
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ quick_add_unref (qa);
+ g_error_free (error);
+ return;
+ }
+
+ registry = e_client_cache_ref_registry (qa->client_cache);
+
+ eab_merging_book_find_contact (
+ registry, E_BOOK_CLIENT (client),
+ qa->contact, ce_have_contact, qa);
+
+ g_object_unref (registry);
}
static void
-edit_card (QuickAdd *qa)
+edit_contact (QuickAdd *qa)
{
- EBook *book;
- book = e_book_new ();
- if (!addressbook_load_default_book (book, ce_have_book, qa)) {
- gtk_object_unref (GTK_OBJECT (book));
- ce_have_book (book, E_BOOK_STATUS_OTHER_ERROR, qa);
+ if (qa->cancellable != NULL) {
+ g_cancellable_cancel (qa->cancellable);
+ g_object_unref (qa->cancellable);
}
+
+ qa->cancellable = g_cancellable_new ();
+
+ e_client_cache_get_client (
+ qa->client_cache, qa->source,
+ E_SOURCE_EXTENSION_ADDRESS_BOOK,
+ qa->cancellable, ce_have_book, qa);
}
+#define QUICK_ADD_RESPONSE_EDIT_FULL 2
+
static void
-clicked_cb (GtkWidget *w, gint button, gpointer closure)
+clicked_cb (GtkWidget *w,
+ gint button,
+ gpointer closure)
{
QuickAdd *qa = (QuickAdd *) closure;
/* Get data out of entries. */
- if (button == 0 || button == 1) {
+ if (!qa->vcard && (button == GTK_RESPONSE_OK ||
+ button == QUICK_ADD_RESPONSE_EDIT_FULL)) {
gchar *name = NULL;
gchar *email = NULL;
- if (qa->name_entry) {
- gchar *tmp;
- tmp = gtk_editable_get_chars (GTK_EDITABLE (qa->name_entry), 0, -1);
- name = e_utf8_from_gtk_string (qa->name_entry, tmp);
- g_free (tmp);
- }
+ if (qa->name_entry)
+ name = gtk_editable_get_chars (
+ GTK_EDITABLE (qa->name_entry), 0, -1);
- if (qa->email_entry) {
- gchar *tmp;
- tmp = gtk_editable_get_chars (GTK_EDITABLE (qa->email_entry), 0, -1);
- email = e_utf8_from_gtk_string (qa->email_entry, tmp);
- g_free (tmp);
- }
+ if (qa->email_entry)
+ email = gtk_editable_get_chars (
+ GTK_EDITABLE (qa->email_entry), 0, -1);
+
+ e_contact_set (
+ qa->contact, E_CONTACT_FULL_NAME,
+ (name != NULL) ? name : "");
+
+ e_contact_set (
+ qa->contact, E_CONTACT_EMAIL_1,
+ (email != NULL) ? email : "");
- quick_add_set_name (qa, name);
- quick_add_set_email (qa, email);
-
g_free (name);
g_free (email);
}
gtk_widget_destroy (w);
- if (button == 0) {
+ if (button == GTK_RESPONSE_OK) {
/* OK */
- quick_add_merge_card (qa);
+ quick_add_merge_contact (qa);
+
+ } else if (button == QUICK_ADD_RESPONSE_EDIT_FULL) {
- } else if (button == 1) {
-
/* EDIT FULL */
- edit_card (qa);
+ edit_contact (qa);
} else {
/* CANCEL */
@@ -289,74 +398,177 @@ clicked_cb (GtkWidget *w, gint button, gpointer closure)
}
+static void
+sanitize_widgets (QuickAdd *qa)
+{
+ GtkComboBox *combo_box;
+ const gchar *active_id;
+ gboolean enabled = TRUE;
+
+ g_return_if_fail (qa != NULL);
+ g_return_if_fail (qa->dialog != NULL);
+
+ combo_box = GTK_COMBO_BOX (qa->combo_box);
+ active_id = gtk_combo_box_get_active_id (combo_box);
+ enabled = (active_id != NULL);
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (qa->dialog),
+ QUICK_ADD_RESPONSE_EDIT_FULL, enabled);
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (qa->dialog), GTK_RESPONSE_OK, enabled);
+}
+
+static void
+source_changed (ESourceComboBox *source_combo_box,
+ QuickAdd *qa)
+{
+ ESource *source;
+
+ source = e_source_combo_box_ref_active (source_combo_box);
+
+ if (source != NULL) {
+ if (qa->source != NULL)
+ g_object_unref (qa->source);
+ qa->source = source; /* takes reference */
+ }
+
+ sanitize_widgets (qa);
+}
+
static GtkWidget *
build_quick_add_dialog (QuickAdd *qa)
{
+ GtkWidget *container;
GtkWidget *dialog;
+ GtkWidget *label;
GtkTable *table;
- const gint xpad=1, ypad=1;
+ ESource *source;
+ ESourceRegistry *registry;
+ const gchar *extension_name;
+ const gint xpad = 0, ypad = 0;
g_return_val_if_fail (qa != NULL, NULL);
- dialog = gnome_dialog_new (_("Contact Quick-Add"),
- GNOME_STOCK_BUTTON_OK,
- _("Edit Full"),
- GNOME_STOCK_BUTTON_CANCEL,
- NULL);
+ dialog = gtk_dialog_new_with_buttons (
+ _("Contact Quick-Add"),
+ e_shell_get_active_window (NULL),
+ 0,
+ _("_Edit Full"), QUICK_ADD_RESPONSE_EDIT_FULL,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
- gtk_signal_connect (GTK_OBJECT (dialog),
- "clicked",
- clicked_cb,
- qa);
+ gtk_widget_ensure_style (dialog);
- qa->name_entry = gtk_entry_new ();
- if (qa->name) {
- gchar *str = e_utf8_to_gtk_string (qa->name_entry, qa->name);
- gtk_entry_set_text (GTK_ENTRY (qa->name_entry), str);
- g_free (str);
- }
+ container = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 12);
+ container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 0);
+
+ g_signal_connect (
+ dialog, "response",
+ G_CALLBACK (clicked_cb), qa);
+ qa->dialog = dialog;
+
+ qa->name_entry = gtk_entry_new ();
+ if (qa->name)
+ gtk_entry_set_text (GTK_ENTRY (qa->name_entry), qa->name);
qa->email_entry = gtk_entry_new ();
- if (qa->email) {
- gchar *str = e_utf8_to_gtk_string (qa->email_entry, qa->email);
- gtk_entry_set_text (GTK_ENTRY (qa->email_entry), str);
- g_free (str);
+ if (qa->email)
+ gtk_entry_set_text (GTK_ENTRY (qa->email_entry), qa->email);
+
+ if (qa->vcard) {
+ /* when adding vCard, then do not allow change name or email */
+ gtk_widget_set_sensitive (qa->name_entry, FALSE);
+ gtk_widget_set_sensitive (qa->email_entry, FALSE);
}
- table = GTK_TABLE (gtk_table_new (2, 2, FALSE));
-
- gtk_table_attach (table, gtk_label_new (_("Full Name")),
- 0, 1, 0, 1,
- 0, 0, xpad, ypad);
- gtk_table_attach (table, qa->name_entry,
- 1, 2, 0, 1,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND, xpad, ypad);
- gtk_table_attach (table, gtk_label_new (_("E-mail")),
- 0, 1, 1, 2,
- 0, 0, xpad, ypad);
- gtk_table_attach (table, qa->email_entry,
- 1, 2, 1, 2,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND, xpad, ypad);
-
- gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox),
- GTK_WIDGET (table),
- TRUE, TRUE, 0);
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ registry = e_client_cache_ref_registry (qa->client_cache);
+ source = e_source_registry_ref_default_address_book (registry);
+ g_object_unref (registry);
+
+ qa->combo_box = e_client_combo_box_new (
+ qa->client_cache, extension_name);
+ e_source_combo_box_set_active (
+ E_SOURCE_COMBO_BOX (qa->combo_box), source);
+
+ g_object_unref (source);
+
+ source_changed (E_SOURCE_COMBO_BOX (qa->combo_box), qa);
+ g_signal_connect (
+ qa->combo_box, "changed",
+ G_CALLBACK (source_changed), qa);
+
+ table = GTK_TABLE (gtk_table_new (3, 2, FALSE));
+ gtk_table_set_row_spacings (table, 6);
+ gtk_table_set_col_spacings (table, 12);
+
+ label = gtk_label_new_with_mnemonic (_("_Full name"));
+ gtk_label_set_mnemonic_widget ((GtkLabel *) label, qa->name_entry);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ gtk_table_attach (
+ table, label,
+ 0, 1, 0, 1,
+ GTK_FILL, 0, xpad, ypad);
+ gtk_table_attach (
+ table, qa->name_entry,
+ 1, 2, 0, 1,
+ GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
+
+ label = gtk_label_new_with_mnemonic (_("E_mail"));
+ gtk_label_set_mnemonic_widget ((GtkLabel *) label, qa->email_entry);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ gtk_table_attach (
+ table, label,
+ 0, 1, 1, 2,
+ GTK_FILL, 0, xpad, ypad);
+ gtk_table_attach (
+ table, qa->email_entry,
+ 1, 2, 1, 2,
+ GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
+
+ label = gtk_label_new_with_mnemonic (_("_Select Address Book"));
+ gtk_label_set_mnemonic_widget ((GtkLabel *) label, qa->combo_box);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ gtk_table_attach (
+ table, label,
+ 0, 1, 2, 3,
+ GTK_FILL, 0, xpad, ypad);
+ gtk_table_attach (
+ table, qa->combo_box,
+ 1, 2, 2, 3,
+ GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
+
+ gtk_container_set_border_width (GTK_CONTAINER (table), 12);
+ container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_box_pack_start (
+ GTK_BOX (container), GTK_WIDGET (table), FALSE, FALSE, 0);
gtk_widget_show_all (GTK_WIDGET (table));
-
-
+
return dialog;
}
void
-e_contact_quick_add (const gchar *in_name, const gchar *email,
- EContactQuickAddCallback cb, gpointer closure)
+e_contact_quick_add (EClientCache *client_cache,
+ const gchar *in_name,
+ const gchar *email,
+ EContactQuickAddCallback cb,
+ gpointer closure)
{
QuickAdd *qa;
GtkWidget *dialog;
gchar *name = NULL;
gint len;
+ g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
+
/* We need to have *something* to work with. */
if (in_name == NULL && email == NULL) {
if (cb)
@@ -370,14 +582,15 @@ e_contact_quick_add (const gchar *in_name, const gchar *email,
/* Remove extra whitespace and the quotes some mailers put around names. */
g_strstrip (name);
len = strlen (name);
- if ((name[0] == '\'' && name[len-1] == '\'') || (name[0] == '"' && name[len-1] == '"')) {
+ if ((name[0] == '\'' && name[len - 1] == '\'') ||
+ (name[0] == '"' && name[len - 1] == '"')) {
name[0] = ' ';
- name[len-1] = ' ';
+ name[len - 1] = ' ';
}
g_strstrip (name);
}
- qa = quick_add_new ();
+ qa = quick_add_new (client_cache);
qa->cb = cb;
qa->closure = closure;
if (name)
@@ -392,14 +605,19 @@ e_contact_quick_add (const gchar *in_name, const gchar *email,
}
void
-e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, gpointer closure)
+e_contact_quick_add_free_form (EClientCache *client_cache,
+ const gchar *text,
+ EContactQuickAddCallback cb,
+ gpointer closure)
{
- gchar *name=NULL, *email=NULL;
+ gchar *name = NULL, *email = NULL;
const gchar *last_at, *s;
gboolean in_quote;
+ g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
+
if (text == NULL) {
- e_contact_quick_add (NULL, NULL, cb, closure);
+ e_contact_quick_add (client_cache, NULL, NULL, cb, closure);
return;
}
@@ -413,16 +631,17 @@ e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, g
in_quote = !in_quote;
}
-
if (last_at == NULL) {
/* No at sign, so we treat it all as the name */
name = g_strdup (text);
} else {
gboolean bad_char = FALSE;
-
+
/* walk backwards to whitespace or a < or a quote... */
while (last_at >= text && !bad_char
- && !(isspace ((gint) *last_at) || *last_at == '<' || *last_at == '"')) {
+ && !(isspace ((gint) *last_at) ||
+ *last_at == '<' ||
+ *last_at == '"')) {
/* Check for some stuff that can't appear in a legal e-mail address. */
if (*last_at == '['
|| *last_at == ']'
@@ -437,16 +656,14 @@ e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, g
/* ...and then split the text there */
if (!bad_char) {
if (text < last_at)
- name = g_strndup (text, last_at-text);
+ name = g_strndup (text, last_at - text);
email = g_strdup (last_at);
}
}
/* If all else has failed, make it the name. */
- if (name == NULL && email == NULL)
+ if (name == NULL && email == NULL)
name = g_strdup (text);
-
-
/* Clean up email, remove bracketing <>s */
if (email && *email) {
@@ -456,16 +673,106 @@ e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, g
*email = ' ';
changed = TRUE;
}
- if (email[strlen (email)-1] == '>') {
- email[strlen (email)-1] = ' ';
+ if (email[strlen (email) - 1] == '>') {
+ email[strlen (email) - 1] = ' ';
changed = TRUE;
}
if (changed)
g_strstrip (email);
}
-
- e_contact_quick_add (name, email, cb, closure);
+ e_contact_quick_add (client_cache, name, email, cb, closure);
+
g_free (name);
g_free (email);
}
+
+void
+e_contact_quick_add_email (EClientCache *client_cache,
+ const gchar *email,
+ EContactQuickAddCallback cb,
+ gpointer closure)
+{
+ gchar *name = NULL;
+ gchar *addr = NULL;
+ gchar *lt, *gt;
+
+ /* Handle something of the form "Foo <foo@bar.com>". This is more
+ * more forgiving than the free-form parser, allowing for unquoted
+ * whitespace since we know the whole string is an email address. */
+
+ lt = (email != NULL) ? strchr (email, '<') : NULL;
+ gt = (lt != NULL) ? strchr (email, '>') : NULL;
+
+ if (lt != NULL && gt != NULL && (gt - lt) > 0) {
+ name = g_strndup (email, lt - email);
+ addr = g_strndup (lt + 1, gt - lt - 1);
+ } else {
+ addr = g_strdup (email);
+ }
+
+ e_contact_quick_add (client_cache, name, addr, cb, closure);
+
+ g_free (name);
+ g_free (addr);
+}
+
+void
+e_contact_quick_add_vcard (EClientCache *client_cache,
+ const gchar *vcard,
+ EContactQuickAddCallback cb,
+ gpointer closure)
+{
+ QuickAdd *qa;
+ GtkWidget *dialog;
+ EContact *contact;
+
+ g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
+
+ /* We need to have *something* to work with. */
+ if (vcard == NULL) {
+ if (cb)
+ cb (NULL, closure);
+ return;
+ }
+
+ qa = quick_add_new (client_cache);
+ qa->cb = cb;
+ qa->closure = closure;
+ quick_add_set_vcard (qa, vcard);
+
+ contact = e_contact_new_from_vcard (qa->vcard);
+
+ if (contact) {
+ GList *emails;
+ gchar *name;
+ EContactName *contact_name;
+
+ g_object_unref (qa->contact);
+ qa->contact = contact;
+
+ contact_name = e_contact_get (qa->contact, E_CONTACT_NAME);
+ name = e_contact_name_to_string (contact_name);
+ quick_add_set_name (qa, name);
+ g_free (name);
+ e_contact_name_free (contact_name);
+
+ emails = e_contact_get (qa->contact, E_CONTACT_EMAIL);
+ if (emails) {
+ quick_add_set_email (qa, emails->data);
+
+ g_list_foreach (emails, (GFunc) g_free, NULL);
+ g_list_free (emails);
+ }
+ } else {
+ if (cb)
+ cb (NULL, closure);
+
+ quick_add_unref (qa);
+ g_warning ("Contact's vCard parsing failed!");
+ return;
+ }
+
+ dialog = build_quick_add_dialog (qa);
+ gtk_widget_show_all (dialog);
+}