Added source selector to contact quick-add dialog.
svn path=/trunk/; revision=31278
This commit is contained in:
@ -1,3 +1,17 @@
|
||||
2006-01-23 Devashish Sharma <sdevashish@novell.com>
|
||||
|
||||
* gui/contact-editor/e-contact-quick-add.c : Added source selector to
|
||||
the quick add dialog so that the user can choose the addressbook also
|
||||
while storing the contact. Earlier it automatically went to the
|
||||
default addressbook.
|
||||
|
||||
* gui/widgets/eab-popup-control.c : It now directly tries to quick add
|
||||
the contact to the selected addressbook. All the duplicate detected and
|
||||
merging contacts logic is then handled by duplicate contact detected
|
||||
dialog. So removed the searching and merging code from the file.
|
||||
Earlier it added the contact to the default addressbook and checked
|
||||
for duplicated there only.
|
||||
|
||||
2006-01-23 Sushma Rai <rsushma@novell.com>
|
||||
|
||||
* addressbook/gui/component/addressbook.c (addressbook_authenticate):
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
#include <libgnomeui/gnome-app.h>
|
||||
#include <libebook/e-book.h>
|
||||
#include <libebook/e-contact.h>
|
||||
#include <libedataserverui/e-source-option-menu.h>
|
||||
#include <addressbook/gui/component/addressbook.h>
|
||||
#include <addressbook/util/eab-book-util.h>
|
||||
#include "e-contact-editor.h"
|
||||
@ -48,12 +49,14 @@ struct _QuickAdd {
|
||||
gchar *name;
|
||||
gchar *email;
|
||||
EContact *contact;
|
||||
EBook *book;
|
||||
|
||||
EContactQuickAddCallback cb;
|
||||
gpointer closure;
|
||||
|
||||
GtkWidget *name_entry;
|
||||
GtkWidget *email_entry;
|
||||
GtkWidget *option_menu;
|
||||
|
||||
gint refs;
|
||||
|
||||
@ -64,6 +67,7 @@ quick_add_new (void)
|
||||
{
|
||||
QuickAdd *qa = g_new0 (QuickAdd, 1);
|
||||
qa->contact = e_contact_new ();
|
||||
qa->book = NULL;
|
||||
qa->refs = 1;
|
||||
return qa;
|
||||
}
|
||||
@ -135,8 +139,7 @@ static void
|
||||
quick_add_merge_contact (QuickAdd *qa)
|
||||
{
|
||||
quick_add_ref (qa);
|
||||
|
||||
addressbook_load_default_book (merge_cb, qa);
|
||||
addressbook_load (qa->book, merge_cb, qa);
|
||||
}
|
||||
|
||||
|
||||
@ -211,7 +214,7 @@ ce_have_book (EBook *book, EBookStatus status, gpointer closure)
|
||||
static void
|
||||
edit_contact (QuickAdd *qa)
|
||||
{
|
||||
addressbook_load_default_book (ce_have_book, qa);
|
||||
addressbook_load (qa->book, ce_have_book, qa);
|
||||
}
|
||||
|
||||
#define QUICK_ADD_RESPONSE_EDIT_FULL 2
|
||||
@ -264,12 +267,23 @@ clicked_cb (GtkWidget *w, gint button, gpointer closure)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
source_selected (GtkWidget *source_option_menu, ESource *source, QuickAdd *qa)
|
||||
{
|
||||
if (qa->book) {
|
||||
g_object_unref (qa->book);
|
||||
qa->book = NULL;
|
||||
}
|
||||
qa->book = e_book_new (source, NULL);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
build_quick_add_dialog (QuickAdd *qa)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *label;
|
||||
GtkTable *table;
|
||||
EBook *book;
|
||||
const gint xpad=0, ypad=0;
|
||||
|
||||
g_return_val_if_fail (qa != NULL, NULL);
|
||||
@ -299,11 +313,28 @@ build_quick_add_dialog (QuickAdd *qa)
|
||||
if (qa->email)
|
||||
gtk_entry_set_text (GTK_ENTRY (qa->email_entry), qa->email);
|
||||
|
||||
table = GTK_TABLE (gtk_table_new (2, 2, FALSE));
|
||||
ESourceList *source_list;
|
||||
GConfClient *gconf_client;
|
||||
|
||||
gconf_client = gconf_client_get_default ();
|
||||
source_list = e_source_list_new_for_gconf (gconf_client, "/apps/evolution/addressbook/sources");
|
||||
qa->option_menu = e_source_option_menu_new (source_list);
|
||||
book = e_book_new_default_addressbook (NULL);
|
||||
e_source_option_menu_select (E_SOURCE_OPTION_MENU (qa->option_menu), e_book_get_source(book));
|
||||
if (qa->book) {
|
||||
g_object_unref (book);
|
||||
qa->book = NULL;
|
||||
}
|
||||
qa->book = book ;
|
||||
g_signal_connect (qa->option_menu, "source_selected", G_CALLBACK (source_selected), qa);
|
||||
|
||||
g_object_unref (source_list);
|
||||
|
||||
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:"));
|
||||
label = gtk_label_new_with_mnemonic (_("_Full name"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
|
||||
gtk_table_attach (table, label,
|
||||
@ -313,7 +344,7 @@ build_quick_add_dialog (QuickAdd *qa)
|
||||
1, 2, 0, 1,
|
||||
GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
|
||||
|
||||
label = gtk_label_new_with_mnemonic (_("E-_mail:"));
|
||||
label = gtk_label_new_with_mnemonic (_("E-_mail"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
|
||||
gtk_table_attach (table, label,
|
||||
@ -323,6 +354,16 @@ build_quick_add_dialog (QuickAdd *qa)
|
||||
1, 2, 1, 2,
|
||||
GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
|
||||
|
||||
label = gtk_label_new_with_mnemonic (_("_Select Address Book"));
|
||||
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->option_menu,
|
||||
1, 2, 2, 3,
|
||||
GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (table),
|
||||
12);
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
|
||||
|
||||
@ -58,588 +58,6 @@
|
||||
static void eab_popup_control_set_name (EABPopupControl *pop, const gchar *name);
|
||||
static void eab_popup_control_set_email (EABPopupControl *pop, const gchar *email);
|
||||
|
||||
/*
|
||||
* Some general scaffolding for our widgets. Think of this as a really, really
|
||||
* lame implementation of a wizard (...which is still somewhat more general that
|
||||
* we really need it to be).
|
||||
*/
|
||||
|
||||
typedef struct _MiniWizard MiniWizard;
|
||||
struct _MiniWizard {
|
||||
GtkWidget *body;
|
||||
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *ok_button;
|
||||
GtkWidget *cancel_button;
|
||||
|
||||
void (*ok_cb) (MiniWizard *, gpointer);
|
||||
void (*cleanup_cb) (gpointer);
|
||||
gpointer closure;
|
||||
|
||||
void (*destroy_cb) (MiniWizard *, gpointer);
|
||||
gpointer destroy_closure;
|
||||
};
|
||||
|
||||
static void
|
||||
mini_wizard_container_add (MiniWizard *wiz, GtkWidget *w)
|
||||
{
|
||||
GList *iter = gtk_container_get_children (GTK_CONTAINER (wiz->vbox));
|
||||
while (iter != NULL) {
|
||||
GtkWidget *oldw = (GtkWidget *) iter->data;
|
||||
iter = g_list_next (iter);
|
||||
gtk_container_remove (GTK_CONTAINER (wiz->vbox), oldw);
|
||||
}
|
||||
gtk_container_add (GTK_CONTAINER (wiz->vbox), w);
|
||||
}
|
||||
|
||||
static void
|
||||
mini_wizard_destroy (MiniWizard *wiz)
|
||||
{
|
||||
if (wiz->cleanup_cb)
|
||||
wiz->cleanup_cb (wiz->closure);
|
||||
wiz->cleanup_cb = NULL;
|
||||
|
||||
if (wiz->destroy_cb)
|
||||
wiz->destroy_cb (wiz, wiz->destroy_closure);
|
||||
}
|
||||
|
||||
static void
|
||||
mini_wizard_ok_cb (GtkWidget *b, gpointer closure)
|
||||
{
|
||||
MiniWizard *wiz = (MiniWizard *) closure;
|
||||
|
||||
gpointer old_closure = wiz->closure;
|
||||
void (*old_cleanup) (gpointer) = wiz->cleanup_cb;
|
||||
|
||||
wiz->cleanup_cb = NULL;
|
||||
|
||||
if (wiz->ok_cb)
|
||||
wiz->ok_cb (wiz, wiz->closure);
|
||||
|
||||
if (old_cleanup)
|
||||
old_cleanup (old_closure);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
mini_wizard_cancel_cb (GtkWidget *b, gpointer closure)
|
||||
{
|
||||
mini_wizard_destroy ((MiniWizard *) closure);
|
||||
}
|
||||
|
||||
static void
|
||||
mini_wizard_destroy_cb (gpointer closure, GObject *where_object_was)
|
||||
{
|
||||
MiniWizard *wiz = (MiniWizard *) closure;
|
||||
if (wiz->cleanup_cb)
|
||||
wiz->cleanup_cb (wiz->closure);
|
||||
g_free (wiz);
|
||||
}
|
||||
|
||||
static MiniWizard *
|
||||
mini_wizard_new (void)
|
||||
{
|
||||
MiniWizard *wiz = g_new (MiniWizard, 1);
|
||||
GtkWidget *bbox;
|
||||
|
||||
wiz->body = gtk_vbox_new (FALSE, 2);
|
||||
wiz->vbox = gtk_vbox_new (FALSE, 2);
|
||||
wiz->ok_button = gtk_button_new_from_stock (GTK_STOCK_OK);
|
||||
wiz->cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
|
||||
|
||||
wiz->ok_cb = NULL;
|
||||
wiz->cleanup_cb = NULL;
|
||||
wiz->closure = NULL;
|
||||
|
||||
wiz->destroy_cb = NULL;
|
||||
wiz->destroy_closure = NULL;
|
||||
|
||||
bbox = gtk_hbutton_box_new ();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox),
|
||||
GTK_BUTTONBOX_END);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (bbox), wiz->cancel_button, FALSE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), wiz->ok_button, FALSE, TRUE, 0);
|
||||
|
||||
gtk_box_set_spacing (GTK_BOX (bbox),
|
||||
10 /* ugh */);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (wiz->body), wiz->vbox, TRUE, TRUE, 2);
|
||||
gtk_box_pack_start (GTK_BOX (wiz->body), gtk_hseparator_new (), FALSE, TRUE, 2);
|
||||
gtk_box_pack_start (GTK_BOX (wiz->body), bbox, FALSE, TRUE, 2);
|
||||
|
||||
gtk_widget_show_all (wiz->body);
|
||||
|
||||
g_signal_connect (wiz->ok_button,
|
||||
"clicked",
|
||||
G_CALLBACK (mini_wizard_ok_cb),
|
||||
wiz);
|
||||
g_signal_connect (wiz->cancel_button,
|
||||
"clicked",
|
||||
G_CALLBACK (mini_wizard_cancel_cb),
|
||||
wiz);
|
||||
|
||||
g_object_weak_ref (G_OBJECT (wiz->body),
|
||||
mini_wizard_destroy_cb,
|
||||
wiz);
|
||||
|
||||
return wiz;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This is the code for the UI thingie that lets you manipulate the e-mail
|
||||
* addresses (and *only* the e-mail addresses) associated with an existing
|
||||
* contact.
|
||||
*/
|
||||
|
||||
#define EMPTY_ENTRY _("(none)")
|
||||
|
||||
typedef struct _EMailMenu EMailMenu;
|
||||
struct _EMailMenu {
|
||||
GtkWidget *option_menu;
|
||||
GList *options;
|
||||
gchar *current_selection;
|
||||
};
|
||||
|
||||
static void
|
||||
email_menu_free (EMailMenu *menu)
|
||||
{
|
||||
if (menu == NULL)
|
||||
return;
|
||||
|
||||
g_list_foreach (menu->options, (GFunc) g_free, NULL);
|
||||
g_list_free (menu->options);
|
||||
g_free (menu);
|
||||
}
|
||||
|
||||
static EMailMenu *
|
||||
email_menu_new (void)
|
||||
{
|
||||
EMailMenu *menu = g_new (EMailMenu, 1);
|
||||
|
||||
menu->option_menu = gtk_option_menu_new ();
|
||||
menu->options = NULL;
|
||||
menu->current_selection = NULL;
|
||||
|
||||
gtk_option_menu_set_menu (GTK_OPTION_MENU (menu->option_menu), gtk_menu_new ());
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
static void
|
||||
menu_activate_cb (GtkWidget *w, gpointer closure)
|
||||
{
|
||||
EMailMenu *menu = (EMailMenu *) closure;
|
||||
gchar *addr = (gchar *) g_object_get_data (G_OBJECT (w), "addr");
|
||||
|
||||
menu->current_selection = addr;
|
||||
}
|
||||
|
||||
static void
|
||||
email_menu_add_option (EMailMenu *menu, char *addr)
|
||||
{
|
||||
GtkWidget *menu_item;
|
||||
|
||||
g_return_if_fail (menu != NULL);
|
||||
if (!addr || !*addr)
|
||||
return;
|
||||
|
||||
menu->options = g_list_append (menu->options, addr);
|
||||
|
||||
menu_item = gtk_menu_item_new_with_label (addr);
|
||||
g_object_set_data (G_OBJECT (menu_item), "addr", addr);
|
||||
gtk_widget_show_all (menu_item);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (gtk_option_menu_get_menu (GTK_OPTION_MENU (menu->option_menu))), menu_item);
|
||||
|
||||
g_signal_connect (menu_item,
|
||||
"activate",
|
||||
G_CALLBACK (menu_activate_cb),
|
||||
menu);
|
||||
}
|
||||
|
||||
static void
|
||||
email_menu_add_options_from_contact (EMailMenu *menu, EContact *contact, const gchar *extra_addr)
|
||||
{
|
||||
g_return_if_fail (contact && E_IS_CONTACT (contact));
|
||||
|
||||
/* If any of these three e-mail fields are NULL, email_menu_add_option will just
|
||||
return without doing anything. */
|
||||
email_menu_add_option (menu, e_contact_get (contact, E_CONTACT_EMAIL_1));
|
||||
email_menu_add_option (menu, e_contact_get (contact, E_CONTACT_EMAIL_2));
|
||||
email_menu_add_option (menu, e_contact_get (contact, E_CONTACT_EMAIL_3));
|
||||
email_menu_add_option (menu, g_strdup (extra_addr));
|
||||
email_menu_add_option (menu, g_strdup (EMPTY_ENTRY));
|
||||
}
|
||||
|
||||
static void
|
||||
email_menu_set_option (EMailMenu *menu, const gchar *addr)
|
||||
{
|
||||
guint count = 0;
|
||||
GList *iter;
|
||||
|
||||
g_return_if_fail (menu != NULL);
|
||||
|
||||
if (addr == NULL) {
|
||||
email_menu_set_option (menu, EMPTY_ENTRY);
|
||||
return;
|
||||
}
|
||||
|
||||
iter = menu->options;
|
||||
while (iter && strcmp (addr, (gchar *) iter->data)) {
|
||||
++count;
|
||||
iter = g_list_next (iter);
|
||||
}
|
||||
|
||||
if (iter) {
|
||||
gtk_option_menu_set_history (GTK_OPTION_MENU (menu->option_menu), count);
|
||||
menu->current_selection = (gchar *) iter->data;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _EMailTable EMailTable;
|
||||
struct _EMailTable {
|
||||
GtkWidget *table;
|
||||
EContact *contact;
|
||||
EMailMenu *primary;
|
||||
EMailMenu *email2;
|
||||
EMailMenu *email3;
|
||||
};
|
||||
|
||||
static void
|
||||
email_table_cleanup_cb (gpointer closure)
|
||||
{
|
||||
EMailTable *et = (EMailTable *) closure;
|
||||
|
||||
if (et == NULL)
|
||||
return;
|
||||
|
||||
g_object_unref (et->contact);
|
||||
email_menu_free (et->primary);
|
||||
email_menu_free (et->email2);
|
||||
email_menu_free (et->email3);
|
||||
|
||||
g_free (et);
|
||||
}
|
||||
|
||||
static void
|
||||
email_table_from_contact (EMailTable *et)
|
||||
{
|
||||
g_return_if_fail (et != NULL);
|
||||
|
||||
email_menu_set_option (et->primary, e_contact_get_const (et->contact, E_CONTACT_EMAIL_1));
|
||||
email_menu_set_option (et->email2, e_contact_get_const (et->contact, E_CONTACT_EMAIL_2));
|
||||
email_menu_set_option (et->email3, e_contact_get_const (et->contact, E_CONTACT_EMAIL_3));
|
||||
}
|
||||
|
||||
static void
|
||||
email_table_to_contact (EMailTable *et)
|
||||
{
|
||||
gchar *curr;
|
||||
|
||||
g_return_if_fail (et != NULL);
|
||||
|
||||
curr = et->primary->current_selection;
|
||||
if (curr && !strcmp (curr, _(EMPTY_ENTRY)))
|
||||
curr = NULL;
|
||||
e_contact_set (et->contact, E_CONTACT_EMAIL_1, curr);
|
||||
|
||||
curr = et->email2->current_selection;
|
||||
if (curr && !strcmp (curr, _(EMPTY_ENTRY)))
|
||||
curr = NULL;
|
||||
e_contact_set (et->contact, E_CONTACT_EMAIL_2, curr);
|
||||
|
||||
curr = et->email3->current_selection;
|
||||
if (curr && !strcmp (curr, _(EMPTY_ENTRY)))
|
||||
curr = NULL;
|
||||
e_contact_set (et->contact, E_CONTACT_EMAIL_3, curr);
|
||||
}
|
||||
|
||||
static void
|
||||
email_table_save_contact_cb (EBook *book, EBookStatus status, gpointer closure)
|
||||
{
|
||||
EContact *contact = E_CONTACT (closure);
|
||||
|
||||
if (status == E_BOOK_ERROR_OK) {
|
||||
e_book_async_commit_contact (book, contact, NULL, NULL);
|
||||
}
|
||||
if (book)
|
||||
g_object_unref (book);
|
||||
g_object_unref (contact);
|
||||
}
|
||||
|
||||
static void
|
||||
email_table_ok_cb (MiniWizard *wiz, gpointer closure)
|
||||
{
|
||||
EMailTable *et = (EMailTable *) closure;
|
||||
|
||||
email_table_to_contact (et);
|
||||
|
||||
g_object_ref (et->contact);
|
||||
|
||||
addressbook_load_default_book (email_table_save_contact_cb, et->contact);
|
||||
|
||||
mini_wizard_destroy (wiz);
|
||||
}
|
||||
|
||||
static void
|
||||
email_table_init (MiniWizard *wiz, EContact *contact, const gchar *extra_address)
|
||||
{
|
||||
EMailTable *et;
|
||||
|
||||
gchar *name_str;
|
||||
gint xpad, ypad;
|
||||
GtkAttachOptions label_x_opts, label_y_opts;
|
||||
GtkAttachOptions menu_x_opts, menu_y_opts;
|
||||
|
||||
g_return_if_fail (contact && E_IS_CONTACT (contact));
|
||||
|
||||
et = g_new (EMailTable, 1);
|
||||
|
||||
et->contact = contact;
|
||||
g_object_ref (et->contact);
|
||||
|
||||
et->table = gtk_table_new (4, 2, FALSE);
|
||||
|
||||
et->primary = email_menu_new ();
|
||||
et->email2 = email_menu_new ();
|
||||
et->email3 = email_menu_new ();
|
||||
|
||||
email_menu_add_options_from_contact (et->primary, et->contact, extra_address);
|
||||
email_menu_add_options_from_contact (et->email2, et->contact, extra_address);
|
||||
email_menu_add_options_from_contact (et->email3, et->contact, extra_address);
|
||||
|
||||
email_table_from_contact (et);
|
||||
|
||||
label_x_opts = GTK_FILL;
|
||||
label_y_opts = GTK_FILL;
|
||||
menu_x_opts = GTK_EXPAND | GTK_FILL;
|
||||
menu_y_opts = GTK_EXPAND | GTK_FILL;
|
||||
xpad = 3;
|
||||
ypad = 3;
|
||||
|
||||
name_str = e_contact_get (et->contact, E_CONTACT_FULL_NAME);
|
||||
gtk_table_attach (GTK_TABLE (et->table),
|
||||
gtk_label_new (name_str),
|
||||
0, 2, 0, 1,
|
||||
label_x_opts, label_y_opts, xpad, ypad);
|
||||
g_free (name_str);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (et->table),
|
||||
gtk_label_new (_("Primary Email")),
|
||||
0, 1, 1, 2,
|
||||
label_x_opts, label_y_opts, xpad, ypad);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (et->table),
|
||||
et->primary->option_menu,
|
||||
1, 2, 1, 2,
|
||||
menu_x_opts, menu_y_opts, xpad, ypad);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (et->table),
|
||||
gtk_label_new (_("Email 2")),
|
||||
0, 1, 2, 3,
|
||||
label_x_opts, label_y_opts, xpad, ypad);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (et->table),
|
||||
et->email2->option_menu,
|
||||
1, 2, 2, 3,
|
||||
menu_x_opts, menu_y_opts, xpad, ypad);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (et->table),
|
||||
gtk_label_new (_("Email 3")),
|
||||
0, 1, 3, 4,
|
||||
label_x_opts, label_y_opts, xpad, ypad);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (et->table),
|
||||
et->email3->option_menu,
|
||||
1, 2, 3, 4,
|
||||
menu_x_opts, menu_y_opts, xpad, ypad);
|
||||
|
||||
gtk_widget_show_all (et->primary->option_menu);
|
||||
gtk_widget_show_all (et->email2->option_menu);
|
||||
gtk_widget_show_all (et->email3->option_menu);
|
||||
|
||||
gtk_widget_show_all (et->table);
|
||||
mini_wizard_container_add (wiz, et->table);
|
||||
wiz->ok_cb = email_table_ok_cb;
|
||||
wiz->cleanup_cb = email_table_cleanup_cb;
|
||||
wiz->closure = et;
|
||||
}
|
||||
|
||||
/*
|
||||
* This code is for the little UI thing that lets you pick from a set of contacts
|
||||
* and decide which one you want to add the e-mail address to.
|
||||
*/
|
||||
|
||||
typedef struct _ContactPicker ContactPicker;
|
||||
struct _ContactPicker {
|
||||
GtkWidget *body;
|
||||
GtkWidget *list;
|
||||
GtkListStore *model;
|
||||
GList *contacts;
|
||||
gchar *new_name;
|
||||
gchar *new_email;
|
||||
|
||||
EContact *current_contact;
|
||||
};
|
||||
|
||||
enum {
|
||||
COLUMN_ACTION,
|
||||
COLUMN_CONTACT
|
||||
};
|
||||
|
||||
static void
|
||||
contact_picker_selection_changed (GtkTreeSelection *selection, gpointer closure)
|
||||
{
|
||||
MiniWizard *wiz = (MiniWizard *) closure;
|
||||
ContactPicker *pick = (ContactPicker *) wiz->closure;
|
||||
gboolean selected;
|
||||
GtkTreeIter iter;
|
||||
|
||||
selected = gtk_tree_selection_get_selected (selection, NULL, &iter);
|
||||
|
||||
gtk_widget_set_sensitive (wiz->ok_button, selected);
|
||||
|
||||
if (selected) {
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (pick->model), &iter,
|
||||
COLUMN_CONTACT, &pick->current_contact,
|
||||
-1);
|
||||
}
|
||||
else {
|
||||
pick->current_contact = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
contact_picker_ok_cb (MiniWizard *wiz, gpointer closure)
|
||||
{
|
||||
ContactPicker *pick = (ContactPicker *) closure;
|
||||
|
||||
if (pick->current_contact == NULL) {
|
||||
e_contact_quick_add (pick->new_name, pick->new_email, NULL, NULL);
|
||||
mini_wizard_destroy (wiz);
|
||||
} else {
|
||||
email_table_init (wiz, pick->current_contact, pick->new_email);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
contact_picker_cleanup_cb (gpointer closure)
|
||||
{
|
||||
ContactPicker *pick = (ContactPicker *) closure;
|
||||
|
||||
g_list_foreach (pick->contacts, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (pick->contacts);
|
||||
|
||||
g_free (pick->new_name);
|
||||
g_free (pick->new_email);
|
||||
}
|
||||
|
||||
static void
|
||||
free_str (gpointer data,
|
||||
GObject *where_the_object_was)
|
||||
{
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
contact_picker_init (MiniWizard *wiz, const GList *contacts, const gchar *new_name, const gchar *new_email)
|
||||
{
|
||||
ContactPicker *pick;
|
||||
gchar *str;
|
||||
GtkWidget *w;
|
||||
GtkTreeIter iter;
|
||||
|
||||
pick = g_new (ContactPicker, 1);
|
||||
|
||||
pick->body = gtk_vbox_new (FALSE, 2);
|
||||
|
||||
pick->model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
|
||||
|
||||
pick->list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (pick->model));
|
||||
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (pick->list), TRUE);
|
||||
|
||||
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (pick->list),
|
||||
COLUMN_ACTION,
|
||||
_("Select an Action"),
|
||||
gtk_cell_renderer_text_new (),
|
||||
"text", COLUMN_ACTION,
|
||||
NULL);
|
||||
|
||||
gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (pick->list)),
|
||||
GTK_SELECTION_SINGLE);
|
||||
|
||||
str = g_strdup_printf (_("Create a new contact \"%s\""), new_name);
|
||||
gtk_list_store_append (pick->model, &iter);
|
||||
gtk_list_store_set (pick->model, &iter,
|
||||
COLUMN_ACTION, str,
|
||||
COLUMN_CONTACT, NULL,
|
||||
-1);
|
||||
g_object_weak_ref (G_OBJECT (pick->model), free_str, str);
|
||||
|
||||
pick->contacts = NULL;
|
||||
while (contacts) {
|
||||
EContact *contact = (EContact *) contacts->data;
|
||||
gchar *name_str = e_contact_get (contact, E_CONTACT_FULL_NAME);
|
||||
|
||||
pick->contacts = g_list_append (pick->contacts, contact);
|
||||
g_object_ref (contact);
|
||||
|
||||
str = g_strdup_printf (_("Add address to existing contact \"%s\""), name_str);
|
||||
gtk_list_store_append (pick->model, &iter);
|
||||
gtk_list_store_set (pick->model, &iter,
|
||||
COLUMN_ACTION, str,
|
||||
COLUMN_CONTACT, contact,
|
||||
-1);
|
||||
g_free (name_str);
|
||||
|
||||
g_object_weak_ref (G_OBJECT (pick->model), free_str, str);
|
||||
|
||||
contacts = g_list_next (contacts);
|
||||
}
|
||||
|
||||
pick->new_name = g_strdup (new_name);
|
||||
pick->new_email = g_strdup (new_email);
|
||||
|
||||
pick->current_contact = NULL;
|
||||
gtk_widget_set_sensitive (wiz->ok_button, FALSE);
|
||||
|
||||
/* Connect some signals & callbacks */
|
||||
|
||||
wiz->ok_cb = contact_picker_ok_cb;
|
||||
wiz->cleanup_cb = contact_picker_cleanup_cb;
|
||||
|
||||
g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (pick->list)),
|
||||
"changed", G_CALLBACK (contact_picker_selection_changed),
|
||||
wiz);
|
||||
|
||||
/* Build our widget */
|
||||
|
||||
w = gtk_label_new (new_email);
|
||||
gtk_box_pack_start (GTK_BOX (pick->body), w, FALSE, TRUE, 3);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (pick->body), pick->list, TRUE, TRUE, 2);
|
||||
gtk_widget_show_all (pick->body);
|
||||
|
||||
|
||||
/* Put it in our mini-wizard */
|
||||
|
||||
wiz->closure = pick;
|
||||
mini_wizard_container_add (wiz, pick->body);
|
||||
}
|
||||
|
||||
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
|
||||
|
||||
/*
|
||||
* The code for the actual EABPopupControl widget begins here.
|
||||
*/
|
||||
|
||||
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
|
||||
|
||||
|
||||
static GtkObjectClass *parent_class;
|
||||
|
||||
static void eab_popup_control_dispose (GObject *);
|
||||
@ -909,33 +327,6 @@ emit_event (EABPopupControl *pop, const char *event)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
contact_editor_cb (EBook *book, EBookStatus status, gpointer closure)
|
||||
{
|
||||
if (status == E_BOOK_ERROR_OK) {
|
||||
EABPopupControl *pop = EAB_POPUP_CONTROL (closure);
|
||||
eab_show_contact_editor (book, pop->contact, FALSE, TRUE);
|
||||
eab_popup_control_cleanup (pop);
|
||||
emit_event (pop, "Destroy");
|
||||
}
|
||||
|
||||
if (book)
|
||||
g_object_unref (book);
|
||||
}
|
||||
|
||||
static void
|
||||
eab_popup_control_display_contact (EABPopupControl *pop, EContact *contact)
|
||||
{
|
||||
g_return_if_fail (pop && EAB_IS_POPUP_CONTROL (pop));
|
||||
g_return_if_fail (contact && E_IS_CONTACT (contact));
|
||||
g_return_if_fail (pop->contact == NULL);
|
||||
|
||||
pop->contact = contact;
|
||||
g_object_ref (pop->contact);
|
||||
|
||||
addressbook_load_default_book (contact_editor_cb, pop);
|
||||
}
|
||||
|
||||
static void
|
||||
eab_popup_control_no_matches (EABPopupControl *pop)
|
||||
{
|
||||
@ -950,160 +341,6 @@ eab_popup_control_no_matches (EABPopupControl *pop)
|
||||
emit_event (pop, "Destroy");
|
||||
}
|
||||
|
||||
static void
|
||||
wizard_destroy_cb (MiniWizard *wiz, gpointer closure)
|
||||
{
|
||||
gtk_widget_destroy (GTK_WIDGET (closure));
|
||||
}
|
||||
|
||||
static void
|
||||
eab_popup_control_ambiguous_email_add (EABPopupControl *pop, const GList *contacts)
|
||||
{
|
||||
MiniWizard *wiz = mini_wizard_new ();
|
||||
GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
wiz->destroy_cb = wizard_destroy_cb;
|
||||
wiz->destroy_closure = win;
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (win), _("Merge E-Mail Address"));
|
||||
gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_MOUSE);
|
||||
|
||||
contact_picker_init (wiz, contacts, pop->name, pop->email);
|
||||
|
||||
eab_popup_control_cleanup (pop);
|
||||
emit_event (pop, "Destroy");
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (win), wiz->body);
|
||||
gtk_widget_show_all (win);
|
||||
}
|
||||
|
||||
static void
|
||||
eab_popup_control_multiple_matches (EABPopupControl *pop, const GList *contacts)
|
||||
{
|
||||
pop->multiple_matches = TRUE;
|
||||
|
||||
eab_popup_control_ambiguous_email_add (pop, contacts);
|
||||
}
|
||||
|
||||
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
|
||||
|
||||
/*
|
||||
* Addressbook Query Fun
|
||||
*/
|
||||
|
||||
static GList*
|
||||
remove_contact_lists (GList *contacts)
|
||||
{
|
||||
GList *contacts_copy = g_list_copy (contacts);
|
||||
GList *temp;
|
||||
GPtrArray *indices = g_ptr_array_new ();
|
||||
int i = 0;
|
||||
|
||||
|
||||
for (temp = contacts_copy; temp != NULL; temp = g_list_next (temp), i++) {
|
||||
if (e_contact_get (temp->data, E_CONTACT_IS_LIST))
|
||||
g_ptr_array_add (indices, temp);
|
||||
}
|
||||
|
||||
for (i =0; i < indices->len; i++) {
|
||||
GList *link = indices->pdata[i];
|
||||
contacts_copy = g_list_remove_link (contacts_copy, link);
|
||||
|
||||
}
|
||||
g_ptr_array_free (indices, FALSE);
|
||||
return contacts_copy;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
name_only_query_cb (EBook *book, EBookStatus status, GList *contacts, gpointer closure)
|
||||
{
|
||||
EABPopupControl *pop;
|
||||
|
||||
if (status != E_BOOK_ERROR_OK)
|
||||
return;
|
||||
|
||||
pop = EAB_POPUP_CONTROL (closure);
|
||||
|
||||
pop->query_tag = 0;
|
||||
if (contacts == NULL) {
|
||||
eab_popup_control_no_matches (pop);
|
||||
} else {
|
||||
eab_popup_control_ambiguous_email_add (pop, contacts);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
query_cb (EBook *book, EBookStatus status, GList *contacts, gpointer closure)
|
||||
{
|
||||
EABPopupControl *pop;
|
||||
GList *filtered_contacts;
|
||||
|
||||
if (status != E_BOOK_ERROR_OK)
|
||||
return;
|
||||
|
||||
pop = EAB_POPUP_CONTROL (closure);
|
||||
|
||||
pop->query_tag = 0;
|
||||
gtk_widget_hide (pop->query_msg);
|
||||
|
||||
/* remove contact lists from the search results to avoid
|
||||
cases like http://bugzilla.ximian.com/show_bug.cgi?id=68745*/
|
||||
|
||||
filtered_contacts = remove_contact_lists (contacts);
|
||||
|
||||
if (filtered_contacts == NULL) {
|
||||
|
||||
/* Do a name-only query if:
|
||||
(1) The name is non-empty.
|
||||
(2) The e-mail is also non-empty (so that the query we just did wasn't actually a name-only query.
|
||||
*/
|
||||
if (pop->name && *pop->name && pop->email && *pop->email) {
|
||||
pop->query_tag = eab_name_and_email_query (book, pop->name, NULL, name_only_query_cb, pop);
|
||||
} else {
|
||||
eab_popup_control_no_matches (pop);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (g_list_length (filtered_contacts) == 1)
|
||||
eab_popup_control_display_contact (pop, E_CONTACT (filtered_contacts->data));
|
||||
else
|
||||
eab_popup_control_multiple_matches (pop, filtered_contacts);
|
||||
g_list_free (filtered_contacts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
start_query (EBook *book, EBookStatus status, gpointer closure)
|
||||
{
|
||||
EABPopupControl *pop = EAB_POPUP_CONTROL (closure);
|
||||
|
||||
if (status != E_BOOK_ERROR_OK) {
|
||||
eab_popup_control_no_matches (pop);
|
||||
if (book)
|
||||
g_object_unref (book);
|
||||
return;
|
||||
}
|
||||
|
||||
#if notyet
|
||||
if (pop->query_tag)
|
||||
e_book_simple_query_cancel (book, pop->query_tag);
|
||||
#endif
|
||||
|
||||
if (pop->book != book) {
|
||||
g_object_ref (book);
|
||||
if (pop->book)
|
||||
g_object_unref (pop->book);
|
||||
pop->book = book;
|
||||
}
|
||||
|
||||
pop->query_tag = eab_name_and_email_query (book, pop->name, pop->email, query_cb, pop);
|
||||
|
||||
g_object_unref (pop);
|
||||
}
|
||||
|
||||
static void
|
||||
eab_popup_control_query (EABPopupControl *pop)
|
||||
{
|
||||
@ -1111,7 +348,10 @@ eab_popup_control_query (EABPopupControl *pop)
|
||||
|
||||
g_object_ref (pop);
|
||||
|
||||
addressbook_load_default_book (start_query, pop);
|
||||
eab_popup_control_no_matches (pop) ;
|
||||
|
||||
g_object_unref (pop);
|
||||
|
||||
}
|
||||
|
||||
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
|
||||
|
||||
Reference in New Issue
Block a user