Hook up some magic to (basically) cardify an entry on focus-out. (What we
2001-08-09 Jon Trowbridge <trow@ximian.com> * gui/component/select-names/e-select-names-manager.c (e_select_names_manager_create_entry): Hook up some magic to (basically) cardify an entry on focus-out. (What we do is actually more complicated than that.) * gui/component/select-names/e-select-names-bonobo.c (entry_set_property_fn): After we set an entry's text, try to cardify it. We need to do this so that (for example) reply e-mails get properly cardified. * gui/component/select-names/e-select-names-model.c (e_select_names_model_duplicate): Use e_select_names_model_append, rather than manipulating lists directly. (e_select_names_model_insert): Connect "changed" signal proxy for added EDestination. (e_select_names_model_append): Ditto. (e_select_names_model_replace): Ditto, and disconnect signals for replaced EDestination. (e_select_names_model_delete): Ditto on the disconnection. (e_select_names_model_delete_all): Ditto. (e_select_names_model_cardify): Added. Try to cardify a specified EDestination. (e_select_names_model_cancel_cardify): Added. Cancel the pending cardification of a single EDestination. (e_select_names_model_cardify_all): Added. Cardify all of the EDestinations in the model. (e_select_names_model_cancel_cardify_all): Added. Cancel's any and all pending cardifications. * backend/ebook/e-destination.c (e_destination_class_init): Added "changed" and "cardified" signals. (e_destination_freeze): Added (static). (e_destination_thaw): Added (static). (e_destination_clear_card): Reset allow_cardify and cannot_cardify, cancel any pending cardifications, and emit the "changed" signal. (e_destination_clear_strings): Emit the "changed" signal. (e_destination_clear): Do freeze/thaw to prevent multiple signal emissions. (e_destination_set_card): Check that the card we are setting is not equal to the current card, and emit the "changed" signal if we are actually changing. (e_destination_set_card_uri): Emit "changed" signal, if necessary. (e_destination_set_name): Emit "changed" signal, if necessary. (e_destination_set_email): Emit "changed" signal, if necessary. (e_destination_set_html_mail_pref): Emit "changed" signal, if necessary. (use_card_cb): If we've just loaded/set the ECard, emit the "changed" signal. (e_destination_set_raw): Emit "changed" signal, if necessary. (e_destination_allow_cardification): Added. (e_destination_set_allow_cardification): Added. (e_destination_cardify): Added. Tries to automatically convert a string-based EDestination to one based on an ECard. (e_destination_cardify_delayed): Added. Cardifies in a timeout. (e_destination_cancel_cardify): Added. Cancels any pending cardifications. (e_destination_xml_decode): Added freeze/thaw. * backend/ebook/e-book-util.c (e_book_nickname_query): Added. A canned simple query for nicknames. * backend/ebook/e-card.c (e_card_email_find_number): Added. Given a card and an string containing an email address, return the index number of the address inside of the card, or -1 if the address is not found. svn path=/trunk/; revision=11837
This commit is contained in:
committed by
Jon Trowbridge
parent
1844cac7c1
commit
07fbf1a035
@ -1,3 +1,72 @@
|
||||
2001-08-09 Jon Trowbridge <trow@ximian.com>
|
||||
|
||||
* gui/component/select-names/e-select-names-manager.c
|
||||
(e_select_names_manager_create_entry): Hook up some magic to
|
||||
(basically) cardify an entry on focus-out. (What we do is actually
|
||||
more complicated than that.)
|
||||
|
||||
* gui/component/select-names/e-select-names-bonobo.c
|
||||
(entry_set_property_fn): After we set an entry's text, try to
|
||||
cardify it. We need to do this so that (for example) reply
|
||||
e-mails get properly cardified.
|
||||
|
||||
* gui/component/select-names/e-select-names-model.c
|
||||
(e_select_names_model_duplicate): Use e_select_names_model_append,
|
||||
rather than manipulating lists directly.
|
||||
(e_select_names_model_insert): Connect "changed" signal proxy for
|
||||
added EDestination.
|
||||
(e_select_names_model_append): Ditto.
|
||||
(e_select_names_model_replace): Ditto, and disconnect signals for
|
||||
replaced EDestination.
|
||||
(e_select_names_model_delete): Ditto on the disconnection.
|
||||
(e_select_names_model_delete_all): Ditto.
|
||||
(e_select_names_model_cardify): Added. Try to cardify a specified
|
||||
EDestination.
|
||||
(e_select_names_model_cancel_cardify): Added. Cancel the pending
|
||||
cardification of a single EDestination.
|
||||
(e_select_names_model_cardify_all): Added. Cardify all of the
|
||||
EDestinations in the model.
|
||||
(e_select_names_model_cancel_cardify_all): Added. Cancel's any
|
||||
and all pending cardifications.
|
||||
|
||||
* backend/ebook/e-destination.c (e_destination_class_init): Added
|
||||
"changed" and "cardified" signals.
|
||||
(e_destination_freeze): Added (static).
|
||||
(e_destination_thaw): Added (static).
|
||||
(e_destination_clear_card): Reset allow_cardify and
|
||||
cannot_cardify, cancel any pending cardifications, and emit the
|
||||
"changed" signal.
|
||||
(e_destination_clear_strings): Emit the "changed" signal.
|
||||
(e_destination_clear): Do freeze/thaw to prevent multiple signal
|
||||
emissions.
|
||||
(e_destination_set_card): Check that the card we are setting is
|
||||
not equal to the current card, and emit the "changed" signal if we
|
||||
are actually changing.
|
||||
(e_destination_set_card_uri): Emit "changed" signal, if necessary.
|
||||
(e_destination_set_name): Emit "changed" signal, if necessary.
|
||||
(e_destination_set_email): Emit "changed" signal, if necessary.
|
||||
(e_destination_set_html_mail_pref): Emit "changed" signal, if
|
||||
necessary.
|
||||
(use_card_cb): If we've just loaded/set the ECard, emit the
|
||||
"changed" signal.
|
||||
(e_destination_set_raw): Emit "changed" signal, if necessary.
|
||||
(e_destination_allow_cardification): Added.
|
||||
(e_destination_set_allow_cardification): Added.
|
||||
(e_destination_cardify): Added. Tries to automatically convert
|
||||
a string-based EDestination to one based on an ECard.
|
||||
(e_destination_cardify_delayed): Added. Cardifies in a timeout.
|
||||
(e_destination_cancel_cardify): Added. Cancels any pending
|
||||
cardifications.
|
||||
(e_destination_xml_decode): Added freeze/thaw.
|
||||
|
||||
* backend/ebook/e-book-util.c (e_book_nickname_query): Added. A
|
||||
canned simple query for nicknames.
|
||||
|
||||
* backend/ebook/e-card.c (e_card_email_find_number): Added. Given
|
||||
a card and an string containing an email address, return the index
|
||||
number of the address inside of the card, or -1 if the address is
|
||||
not found.
|
||||
|
||||
2001-08-09 Chris Toshok <toshok@ximian.com>
|
||||
|
||||
[ Fixes ximian bugs #5080, #6021, #6704, #6705 ]
|
||||
|
||||
@ -507,6 +507,56 @@ e_book_name_and_email_query (EBook *book,
|
||||
return tag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple nickname query
|
||||
*/
|
||||
|
||||
typedef struct _NicknameQueryInfo NicknameQueryInfo;
|
||||
struct _NicknameQueryInfo {
|
||||
gchar *nickname;
|
||||
EBookSimpleQueryCallback cb;
|
||||
gpointer closure;
|
||||
};
|
||||
|
||||
static void
|
||||
nickname_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
|
||||
{
|
||||
NicknameQueryInfo *info = closure;
|
||||
|
||||
if (info->cb)
|
||||
info->cb (book, status, cards, info->closure);
|
||||
|
||||
g_free (info->nickname);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
guint
|
||||
e_book_nickname_query (EBook *book,
|
||||
const char *nickname,
|
||||
EBookSimpleQueryCallback cb,
|
||||
gpointer closure)
|
||||
{
|
||||
NicknameQueryInfo *info;
|
||||
gchar *query;
|
||||
guint retval;
|
||||
|
||||
g_return_val_if_fail (E_IS_BOOK (book), 0);
|
||||
g_return_val_if_fail (nickname && *nickname, 0);
|
||||
|
||||
info = g_new0 (NicknameQueryInfo, 1);
|
||||
info->nickname = g_strdup (nickname);
|
||||
info->cb = cb;
|
||||
info->closure = closure;
|
||||
|
||||
query = g_strdup_printf ("(is \"nickname\" \"%s\")", info->nickname);
|
||||
|
||||
retval = e_book_simple_query (book, query, nickname_cb, info);
|
||||
|
||||
g_free (query);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convenience routine to check for addresses in the local address book.
|
||||
*/
|
||||
|
||||
@ -61,6 +61,11 @@ guint e_book_name_and_email_query (EBook *book,
|
||||
EBookSimpleQueryCallback cb,
|
||||
gpointer closure);
|
||||
|
||||
guint e_book_nickname_query (EBook *book,
|
||||
const char *nickname,
|
||||
EBookSimpleQueryCallback cb,
|
||||
gpointer closure);
|
||||
|
||||
/* Returns the ECard associated to email in the callback,
|
||||
or NULL if no match is found in the local address book. */
|
||||
void e_book_query_address_locally (const gchar *email,
|
||||
|
||||
@ -1813,6 +1813,29 @@ e_card_email_match_string (const ECard *card, const gchar *str)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gint
|
||||
e_card_email_find_number (const ECard *card, const gchar *email)
|
||||
{
|
||||
EIterator *iter;
|
||||
gint count = 0;
|
||||
|
||||
g_return_val_if_fail (E_IS_CARD (card), -1);
|
||||
g_return_val_if_fail (email != NULL, -1);
|
||||
|
||||
iter = e_list_get_iterator (card->email);
|
||||
for (e_iterator_reset (iter); e_iterator_is_valid (iter); e_iterator_next (iter)) {
|
||||
if (!strcmp (e_iterator_get (iter), email))
|
||||
goto finished;
|
||||
++count;
|
||||
}
|
||||
count = -1;
|
||||
|
||||
finished:
|
||||
gtk_object_unref (GTK_OBJECT (iter));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* ECard lifecycle management and vCard loading/saving.
|
||||
*/
|
||||
|
||||
@ -174,6 +174,8 @@ void e_card_arbitrary_free (ECardArbitrary
|
||||
/* ECard email manipulation */
|
||||
gboolean e_card_email_match_string (const ECard *card,
|
||||
const gchar *str);
|
||||
gint e_card_email_find_number (const ECard *card,
|
||||
const gchar *email);
|
||||
|
||||
/* Specialized functionality */
|
||||
GList *e_card_load_cards_from_file (const char *filename);
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <gtk/gtkobject.h>
|
||||
#include <gtk/gtkmain.h>
|
||||
#include <libgnome/gnome-defs.h>
|
||||
#include <libgnome/gnome-i18n.h>
|
||||
#include "e-book.h"
|
||||
@ -41,6 +42,14 @@
|
||||
#include <gnome-xml/xmlmemory.h>
|
||||
#include <camel/camel-internet-address.h>
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
CARDIFIED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
guint e_destination_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
struct _EDestinationPrivate {
|
||||
|
||||
gchar *raw;
|
||||
@ -57,6 +66,15 @@ struct _EDestinationPrivate {
|
||||
gboolean wants_html_mail;
|
||||
|
||||
GList *list_dests;
|
||||
|
||||
gboolean has_been_cardified;
|
||||
gboolean allow_cardify;
|
||||
gboolean cannot_cardify;
|
||||
guint pending_cardification;
|
||||
EBook *cardify_book;
|
||||
|
||||
gint freeze_count;
|
||||
gboolean pending_change;
|
||||
};
|
||||
|
||||
static void e_destination_clear_card (EDestination *);
|
||||
@ -70,6 +88,10 @@ e_destination_destroy (GtkObject *obj)
|
||||
EDestination *dest = E_DESTINATION (obj);
|
||||
|
||||
e_destination_clear (dest);
|
||||
|
||||
if (dest->priv->cardify_book)
|
||||
gtk_object_unref (GTK_OBJECT (dest->priv->cardify_book));
|
||||
|
||||
g_free (dest->priv);
|
||||
|
||||
if (parent_class->destroy)
|
||||
@ -84,12 +106,34 @@ e_destination_class_init (EDestinationClass *klass)
|
||||
parent_class = GTK_OBJECT_CLASS (gtk_type_class (GTK_TYPE_OBJECT));
|
||||
|
||||
object_class->destroy = e_destination_destroy;
|
||||
|
||||
e_destination_signals[CHANGED] =
|
||||
gtk_signal_new ("changed",
|
||||
GTK_RUN_LAST,
|
||||
object_class->type,
|
||||
GTK_SIGNAL_OFFSET (EDestinationClass, changed),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
e_destination_signals[CARDIFIED] =
|
||||
gtk_signal_new ("cardified",
|
||||
GTK_RUN_LAST,
|
||||
object_class->type,
|
||||
GTK_SIGNAL_OFFSET (EDestinationClass, cardified),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
gtk_object_class_add_signals (object_class, e_destination_signals, LAST_SIGNAL);
|
||||
}
|
||||
|
||||
static void
|
||||
e_destination_init (EDestination *dest)
|
||||
{
|
||||
dest->priv = g_new0 (struct _EDestinationPrivate, 1);
|
||||
|
||||
dest->priv->allow_cardify = TRUE;
|
||||
dest->priv->cannot_cardify = FALSE;
|
||||
dest->priv->pending_cardification = 0;
|
||||
}
|
||||
|
||||
GtkType
|
||||
@ -120,6 +164,38 @@ e_destination_new (void)
|
||||
return E_DESTINATION (gtk_type_new (E_TYPE_DESTINATION));
|
||||
}
|
||||
|
||||
static void
|
||||
e_destination_freeze (EDestination *dest)
|
||||
{
|
||||
g_return_if_fail (E_IS_DESTINATION (dest));
|
||||
g_return_if_fail (dest->priv->freeze_count >= 0);
|
||||
++dest->priv->freeze_count;
|
||||
}
|
||||
|
||||
static void
|
||||
e_destination_thaw (EDestination *dest)
|
||||
{
|
||||
g_return_if_fail (E_IS_DESTINATION (dest));
|
||||
g_return_if_fail (dest->priv->freeze_count > 0);
|
||||
--dest->priv->freeze_count;
|
||||
if (dest->priv->freeze_count == 0 && dest->priv->pending_change)
|
||||
e_destination_changed (dest);
|
||||
}
|
||||
|
||||
void
|
||||
e_destination_changed (EDestination *dest)
|
||||
{
|
||||
if (dest->priv->freeze_count == 0) {
|
||||
gtk_signal_emit (GTK_OBJECT (dest), e_destination_signals[CHANGED]);
|
||||
dest->priv->pending_change = FALSE;
|
||||
|
||||
dest->priv->cannot_cardify = FALSE;
|
||||
|
||||
} else {
|
||||
dest->priv->pending_change = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
EDestination *
|
||||
e_destination_copy (const EDestination *dest)
|
||||
{
|
||||
@ -166,6 +242,13 @@ e_destination_clear_card (EDestination *dest)
|
||||
g_list_foreach (dest->priv->list_dests, (GFunc) gtk_object_unref, NULL);
|
||||
g_list_free (dest->priv->list_dests);
|
||||
dest->priv->list_dests = NULL;
|
||||
|
||||
dest->priv->allow_cardify = TRUE;
|
||||
dest->priv->cannot_cardify = FALSE;
|
||||
|
||||
e_destination_cancel_cardify (dest);
|
||||
|
||||
e_destination_changed (dest);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -182,6 +265,8 @@ e_destination_clear_strings (EDestination *dest)
|
||||
|
||||
g_free (dest->priv->addr);
|
||||
dest->priv->addr = NULL;
|
||||
|
||||
e_destination_changed (dest);
|
||||
}
|
||||
|
||||
void
|
||||
@ -189,8 +274,12 @@ e_destination_clear (EDestination *dest)
|
||||
{
|
||||
g_return_if_fail (dest && E_IS_DESTINATION (dest));
|
||||
|
||||
e_destination_freeze (dest);
|
||||
|
||||
e_destination_clear_card (dest);
|
||||
e_destination_clear_strings (dest);
|
||||
|
||||
e_destination_thaw (dest);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -215,12 +304,17 @@ 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));
|
||||
|
||||
e_destination_clear (dest);
|
||||
if (dest->priv->card != card || dest->priv->card_email_num != email_num) {
|
||||
|
||||
dest->priv->card = card;
|
||||
gtk_object_ref (GTK_OBJECT (dest->priv->card));
|
||||
e_destination_clear (dest);
|
||||
|
||||
dest->priv->card_email_num = email_num;
|
||||
dest->priv->card = card;
|
||||
gtk_object_ref (GTK_OBJECT (dest->priv->card));
|
||||
|
||||
dest->priv->card_email_num = email_num;
|
||||
|
||||
e_destination_changed (dest);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -228,16 +322,23 @@ e_destination_set_card_uri (EDestination *dest, const gchar *uri, gint email_num
|
||||
{
|
||||
g_return_if_fail (dest && E_IS_DESTINATION (dest));
|
||||
g_return_if_fail (uri != NULL);
|
||||
|
||||
g_free (dest->priv->card_uri);
|
||||
dest->priv->card_uri = g_strdup (uri);
|
||||
dest->priv->card_email_num = email_num;
|
||||
|
||||
/* If we already have a card, remove it unless it's uri matches the one
|
||||
we just set. */
|
||||
if (dest->priv->card && strcmp (uri, e_card_get_uri (dest->priv->card))) {
|
||||
gtk_object_unref (GTK_OBJECT (dest->priv->card));
|
||||
dest->priv->card = NULL;
|
||||
if (dest->priv->card_uri == NULL
|
||||
|| strcmp (dest->priv->card_uri, uri)
|
||||
|| dest->priv->card_email_num != email_num) {
|
||||
|
||||
g_free (dest->priv->card_uri);
|
||||
dest->priv->card_uri = g_strdup (uri);
|
||||
dest->priv->card_email_num = email_num;
|
||||
|
||||
/* If we already have a card, remove it unless it's uri matches the one
|
||||
we just set. */
|
||||
if (dest->priv->card && strcmp (uri, e_card_get_uri (dest->priv->card))) {
|
||||
gtk_object_unref (GTK_OBJECT (dest->priv->card));
|
||||
dest->priv->card = NULL;
|
||||
}
|
||||
|
||||
e_destination_changed (dest);
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,12 +348,17 @@ e_destination_set_name (EDestination *dest, const gchar *name)
|
||||
g_return_if_fail (dest && E_IS_DESTINATION (dest));
|
||||
g_return_if_fail (name != NULL);
|
||||
|
||||
g_free (dest->priv->name);
|
||||
dest->priv->name = g_strdup (name);
|
||||
if (dest->priv->name == NULL || strcmp (dest->priv->name, name)) {
|
||||
|
||||
if (dest->priv->addr != NULL) {
|
||||
g_free (dest->priv->addr);
|
||||
dest->priv->addr = NULL;
|
||||
g_free (dest->priv->name);
|
||||
dest->priv->name = g_strdup (name);
|
||||
|
||||
if (dest->priv->addr != NULL) {
|
||||
g_free (dest->priv->addr);
|
||||
dest->priv->addr = NULL;
|
||||
}
|
||||
|
||||
e_destination_changed (dest);
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,12 +368,17 @@ e_destination_set_email (EDestination *dest, const gchar *email)
|
||||
g_return_if_fail (dest && E_IS_DESTINATION (dest));
|
||||
g_return_if_fail (email != NULL);
|
||||
|
||||
g_free (dest->priv->email);
|
||||
dest->priv->email = g_strdup (email);
|
||||
if (dest->priv->email == NULL || strcmp (dest->priv->email, email)) {
|
||||
|
||||
if (dest->priv->addr != NULL) {
|
||||
g_free (dest->priv->addr);
|
||||
dest->priv->addr = NULL;
|
||||
g_free (dest->priv->email);
|
||||
dest->priv->email = g_strdup (email);
|
||||
|
||||
if (dest->priv->addr != NULL) {
|
||||
g_free (dest->priv->addr);
|
||||
dest->priv->addr = NULL;
|
||||
}
|
||||
|
||||
e_destination_changed (dest);
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,9 +386,12 @@ void
|
||||
e_destination_set_html_mail_pref (EDestination *dest, gboolean x)
|
||||
{
|
||||
g_return_if_fail (dest && E_IS_DESTINATION (dest));
|
||||
|
||||
|
||||
dest->priv->html_mail_override = TRUE;
|
||||
dest->priv->wants_html_mail = x;
|
||||
if (dest->priv->wants_html_mail != x) {
|
||||
dest->priv->wants_html_mail = x;
|
||||
e_destination_changed (dest);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -311,6 +425,7 @@ use_card_cb (ECard *card, gpointer closure)
|
||||
|
||||
uc->dest->priv->card = card;
|
||||
gtk_object_ref (GTK_OBJECT (uc->dest->priv->card));
|
||||
e_destination_changed (uc->dest);
|
||||
|
||||
}
|
||||
|
||||
@ -520,10 +635,16 @@ e_destination_set_raw (EDestination *dest, const gchar *raw)
|
||||
g_return_if_fail (E_IS_DESTINATION (dest));
|
||||
g_return_if_fail (raw != NULL);
|
||||
|
||||
e_destination_clear (dest);
|
||||
if (dest->priv->raw == NULL || strcmp (dest->priv->raw, raw)) {
|
||||
|
||||
dest->priv->raw = g_strdup (raw);
|
||||
e_destination_freeze (dest);
|
||||
|
||||
e_destination_clear (dest);
|
||||
dest->priv->raw = g_strdup (raw);
|
||||
e_destination_changed (dest);
|
||||
|
||||
e_destination_thaw (dest);
|
||||
}
|
||||
}
|
||||
|
||||
const gchar *
|
||||
@ -582,6 +703,202 @@ e_destination_get_html_mail_pref (const EDestination *dest)
|
||||
return dest->priv->card->wants_html;
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_destination_allow_cardification (const EDestination *dest)
|
||||
{
|
||||
g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE);
|
||||
|
||||
return dest->priv->allow_cardify;
|
||||
}
|
||||
|
||||
void
|
||||
e_destination_set_allow_cardification (EDestination *dest, gboolean x)
|
||||
{
|
||||
g_return_if_fail (E_IS_DESTINATION (dest));
|
||||
|
||||
dest->priv->allow_cardify = x;
|
||||
}
|
||||
|
||||
static void
|
||||
set_cardify_book (EDestination *dest, EBook *book)
|
||||
{
|
||||
if (dest->priv->cardify_book && dest->priv->cardify_book != book) {
|
||||
gtk_object_unref (GTK_OBJECT (dest->priv->cardify_book));
|
||||
}
|
||||
|
||||
dest->priv->cardify_book = book;
|
||||
|
||||
if (book)
|
||||
gtk_object_ref (GTK_OBJECT (book));
|
||||
}
|
||||
|
||||
static void
|
||||
name_and_email_simple_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
|
||||
{
|
||||
EDestination *dest = E_DESTINATION (closure);
|
||||
|
||||
if (status == E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS && g_list_length ((GList *) cards) == 1) {
|
||||
ECard *card = E_CARD (cards->data);
|
||||
gint email_num = e_card_email_find_number (card, e_destination_get_email (dest));
|
||||
|
||||
if (email_num >= 0) {
|
||||
dest->priv->has_been_cardified = TRUE;
|
||||
e_destination_set_card (dest, E_CARD (cards->data), email_num);
|
||||
gtk_signal_emit (GTK_OBJECT (dest), e_destination_signals[CARDIFIED]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dest->priv->has_been_cardified) {
|
||||
dest->priv->cannot_cardify = TRUE;
|
||||
}
|
||||
|
||||
gtk_object_unref (GTK_OBJECT (dest));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nickname_simple_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
|
||||
{
|
||||
EDestination *dest = E_DESTINATION (closure);
|
||||
|
||||
if (status == E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS && g_list_length ((GList *) cards) == 1) {
|
||||
|
||||
dest->priv->has_been_cardified = TRUE;
|
||||
e_destination_set_card (dest, E_CARD (cards->data), 0); /* Uses primary e-mail by default. */
|
||||
gtk_signal_emit (GTK_OBJECT (dest), e_destination_signals[CARDIFIED]);
|
||||
gtk_object_unref (GTK_OBJECT (dest));
|
||||
|
||||
} else {
|
||||
|
||||
e_book_name_and_email_query (book,
|
||||
e_destination_get_name (dest),
|
||||
e_destination_get_email (dest),
|
||||
name_and_email_simple_query_cb,
|
||||
dest);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
launch_cardify_query (EDestination *dest)
|
||||
{
|
||||
if (strchr (e_destination_get_textrep (dest), '@') == NULL) {
|
||||
|
||||
/* If it doesn't look like an e-mail address, see if it is a nickname. */
|
||||
e_book_nickname_query (dest->priv->cardify_book,
|
||||
e_destination_get_textrep (dest),
|
||||
nickname_simple_query_cb,
|
||||
dest);
|
||||
|
||||
} else {
|
||||
|
||||
e_book_name_and_email_query (dest->priv->cardify_book,
|
||||
e_destination_get_name (dest),
|
||||
e_destination_get_email (dest),
|
||||
name_and_email_simple_query_cb,
|
||||
dest);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
use_local_book_cb (EBook *book, gpointer closure)
|
||||
{
|
||||
EDestination *dest = E_DESTINATION (closure);
|
||||
if (dest->priv->cardify_book == NULL) {
|
||||
dest->priv->cardify_book = book;
|
||||
gtk_object_ref (GTK_OBJECT (book));
|
||||
}
|
||||
|
||||
launch_cardify_query (dest);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
e_destination_cardify (EDestination *dest, EBook *book)
|
||||
{
|
||||
g_return_if_fail (E_IS_DESTINATION (dest));
|
||||
g_return_if_fail (book == NULL || E_IS_BOOK (book));
|
||||
|
||||
if (e_destination_is_evolution_list (dest))
|
||||
return;
|
||||
|
||||
if (e_destination_contains_card (dest))
|
||||
return;
|
||||
|
||||
if (!dest->priv->allow_cardify)
|
||||
return;
|
||||
|
||||
if (dest->priv->cannot_cardify)
|
||||
return;
|
||||
|
||||
e_destination_cancel_cardify (dest);
|
||||
|
||||
set_cardify_book (dest, book);
|
||||
|
||||
/* Handle the case of an EDestination containing a card URL */
|
||||
if (e_destination_contains_card (dest)) {
|
||||
e_destination_use_card (dest, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we have a book ready, proceed. We hold a reference to ourselves
|
||||
until our query is complete. */
|
||||
gtk_object_ref (GTK_OBJECT (dest));
|
||||
if (dest->priv->cardify_book != NULL) {
|
||||
launch_cardify_query (dest);
|
||||
} else {
|
||||
e_book_use_local_address_book (use_local_book_cb, dest);
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
do_cardify_delayed (gpointer ptr)
|
||||
{
|
||||
EDestination *dest = E_DESTINATION (ptr);
|
||||
e_destination_cardify (dest, dest->priv->cardify_book);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
e_destination_cardify_delayed (EDestination *dest, EBook *book, gint delay)
|
||||
{
|
||||
g_return_if_fail (E_IS_DESTINATION (dest));
|
||||
g_return_if_fail (book == NULL || E_IS_BOOK (book));
|
||||
|
||||
if (delay < 0)
|
||||
delay = 500;
|
||||
|
||||
e_destination_cancel_cardify (dest);
|
||||
|
||||
set_cardify_book (dest, book);
|
||||
|
||||
dest->priv->pending_cardification = gtk_timeout_add (delay, do_cardify_delayed, dest);
|
||||
}
|
||||
|
||||
void
|
||||
e_destination_cancel_cardify (EDestination *dest)
|
||||
{
|
||||
g_return_if_fail (E_IS_DESTINATION (dest));
|
||||
|
||||
if (dest->priv->pending_cardification) {
|
||||
gtk_timeout_remove (dest->priv->pending_cardification);
|
||||
dest->priv->pending_cardification = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
e_destination_uncardify (EDestination *dest)
|
||||
{
|
||||
g_return_if_fail (E_IS_DESTINATION (dest));
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Destination import/export
|
||||
*/
|
||||
|
||||
gchar *
|
||||
e_destination_get_address_textv (EDestination **destv)
|
||||
{
|
||||
@ -754,6 +1071,8 @@ e_destination_xml_decode (EDestination *dest, xmlNodePtr node)
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
e_destination_freeze (dest);
|
||||
|
||||
e_destination_clear (dest);
|
||||
|
||||
@ -765,6 +1084,8 @@ e_destination_xml_decode (EDestination *dest, xmlNodePtr node)
|
||||
e_destination_set_card_uri (dest, card_uri, email_num);
|
||||
if (list_dests)
|
||||
dest->priv->list_dests = list_dests;
|
||||
|
||||
e_destination_thaw (dest);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -54,12 +54,16 @@ struct _EDestination {
|
||||
|
||||
struct _EDestinationClass {
|
||||
GtkObjectClass parent_class;
|
||||
|
||||
void (*changed) (EDestination *dest);
|
||||
void (*cardified) (EDestination *dest);
|
||||
};
|
||||
|
||||
GtkType e_destination_get_type (void);
|
||||
|
||||
|
||||
EDestination *e_destination_new (void);
|
||||
void e_destination_changed (EDestination *);
|
||||
EDestination *e_destination_copy (const EDestination *);
|
||||
void e_destination_clear (EDestination *);
|
||||
|
||||
@ -94,6 +98,16 @@ gboolean e_destination_is_evolution_list (const EDestination *);
|
||||
/* If true, they want HTML mail. */
|
||||
gboolean e_destination_get_html_mail_pref (const EDestination *);
|
||||
|
||||
gboolean e_destination_allow_cardification (const EDestination *);
|
||||
void e_destination_set_allow_cardification (EDestination *, gboolean);
|
||||
void e_destination_cardify (EDestination *, EBook *);
|
||||
void e_destination_cardify_delayed (EDestination *, EBook *, gint delay); /* delay < 0: "default" */
|
||||
void e_destination_cancel_cardify (EDestination *);
|
||||
|
||||
#if 0
|
||||
void e_destination_uncardify (EDestination *);
|
||||
#endif
|
||||
|
||||
gchar *e_destination_get_address_textv (EDestination **);
|
||||
|
||||
xmlNodePtr e_destination_xml_encode (const EDestination *dest);
|
||||
|
||||
@ -132,8 +132,15 @@ entry_set_property_fn (BonoboPropertyBag *bag,
|
||||
switch (arg_id) {
|
||||
|
||||
case ENTRY_PROPERTY_ID_TEXT:
|
||||
e_entry_set_text (E_ENTRY (w), BONOBO_ARG_GET_STRING (arg));
|
||||
break;
|
||||
{
|
||||
ESelectNamesModel *model;
|
||||
model = E_SELECT_NAMES_MODEL (gtk_object_get_data (GTK_OBJECT (w), "select_names_model"));
|
||||
g_assert (model != NULL);
|
||||
|
||||
e_entry_set_text (E_ENTRY (w), BONOBO_ARG_GET_STRING (arg));
|
||||
e_select_names_model_cardify_all (model, NULL, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case ENTRY_PROPERTY_ID_DESTINATIONS:
|
||||
{
|
||||
|
||||
@ -368,6 +368,38 @@ popup_cb (EEntry *entry, GdkEventButton *ev, gint pos, ESelectNamesModel *model)
|
||||
e_select_names_popup (model, ev, pos);
|
||||
}
|
||||
|
||||
static gint
|
||||
focus_in_cb (GtkWidget *w, GdkEventFocus *ev, gpointer user_data)
|
||||
{
|
||||
EEntry *entry = E_ENTRY (user_data);
|
||||
ESelectNamesModel *model = E_SELECT_NAMES_MODEL (gtk_object_get_data (GTK_OBJECT (entry), "select_names_model"));
|
||||
|
||||
e_select_names_model_cancel_cardify_all (model);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gint
|
||||
focus_out_cb (GtkWidget *w, GdkEventFocus *ev, gpointer user_data)
|
||||
{
|
||||
EEntry *entry = E_ENTRY (user_data);
|
||||
ESelectNamesModel *model = E_SELECT_NAMES_MODEL (gtk_object_get_data (GTK_OBJECT (entry), "select_names_model"));
|
||||
|
||||
if (!e_entry_completion_popup_is_visible (entry))
|
||||
e_select_names_model_cardify_all (model, NULL, 0);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
completion_popup_cb (EEntry *entry, gint visible, gpointer user_data)
|
||||
{
|
||||
ESelectNamesModel *model = E_SELECT_NAMES_MODEL (gtk_object_get_data (GTK_OBJECT (entry), "select_names_model"));
|
||||
|
||||
if (!visible && !GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (entry->canvas)))
|
||||
e_select_names_model_cardify_all (model, NULL, 0);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
e_select_names_manager_create_entry (ESelectNamesManager *manager, const char *id)
|
||||
{
|
||||
@ -389,6 +421,19 @@ e_select_names_manager_create_entry (ESelectNamesManager *manager, const char *i
|
||||
GTK_SIGNAL_FUNC (popup_cb),
|
||||
section->model);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (eentry->canvas),
|
||||
"focus_in_event",
|
||||
GTK_SIGNAL_FUNC (focus_in_cb),
|
||||
eentry);
|
||||
gtk_signal_connect (GTK_OBJECT (eentry->canvas),
|
||||
"focus_out_event",
|
||||
GTK_SIGNAL_FUNC (focus_out_cb),
|
||||
eentry);
|
||||
gtk_signal_connect (GTK_OBJECT (eentry),
|
||||
"completion_popup",
|
||||
GTK_SIGNAL_FUNC (completion_popup_cb),
|
||||
NULL);
|
||||
|
||||
entry = g_new (ESelectNamesManagerEntry, 1);
|
||||
entry->entry = eentry;
|
||||
entry->id = (char *)id;
|
||||
|
||||
@ -219,6 +219,12 @@ e_select_names_model_changed (ESelectNamesModel *model)
|
||||
gtk_signal_emit (GTK_OBJECT(model), e_select_names_model_signals[E_SELECT_NAMES_MODEL_CHANGED]);
|
||||
}
|
||||
|
||||
static void
|
||||
destination_changed_proxy (EDestination *dest, gpointer closure)
|
||||
{
|
||||
e_select_names_model_changed (E_SELECT_NAMES_MODEL (closure));
|
||||
}
|
||||
|
||||
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
|
||||
|
||||
ESelectNamesModel *
|
||||
@ -240,7 +246,7 @@ e_select_names_model_duplicate (ESelectNamesModel *old)
|
||||
|
||||
for (iter = old->priv->data; iter != NULL; iter = g_list_next (iter)) {
|
||||
EDestination *dup = e_destination_copy (E_DESTINATION (iter->data));
|
||||
model->priv->data = g_list_append (model->priv->data, dup);
|
||||
e_select_names_model_append (model, dup);
|
||||
}
|
||||
|
||||
model->priv->limit = old->priv->limit;
|
||||
@ -444,6 +450,21 @@ e_select_names_model_get_string (ESelectNamesModel *model, gint index)
|
||||
return dest ? e_destination_get_textrep (dest) : "";
|
||||
}
|
||||
|
||||
static void
|
||||
connect_destination (ESelectNamesModel *model, EDestination *dest)
|
||||
{
|
||||
gtk_signal_connect (GTK_OBJECT (dest),
|
||||
"changed",
|
||||
destination_changed_proxy,
|
||||
model);
|
||||
}
|
||||
|
||||
static void
|
||||
disconnect_destination (ESelectNamesModel *model, EDestination *dest)
|
||||
{
|
||||
gtk_signal_disconnect_by_func (GTK_OBJECT (dest), destination_changed_proxy, model);
|
||||
}
|
||||
|
||||
void
|
||||
e_select_names_model_insert (ESelectNamesModel *model, gint index, EDestination *dest)
|
||||
{
|
||||
@ -458,6 +479,8 @@ e_select_names_model_insert (ESelectNamesModel *model, gint index, EDestination
|
||||
return;
|
||||
}
|
||||
|
||||
connect_destination (model, dest);
|
||||
|
||||
model->priv->data = g_list_insert (model->priv->data, dest, index);
|
||||
|
||||
gtk_object_ref (GTK_OBJECT (dest));
|
||||
@ -478,6 +501,8 @@ e_select_names_model_append (ESelectNamesModel *model, EDestination *dest)
|
||||
return;
|
||||
}
|
||||
|
||||
connect_destination (model, dest);
|
||||
|
||||
model->priv->data = g_list_append (model->priv->data, dest);
|
||||
|
||||
gtk_object_ref (GTK_OBJECT (dest));
|
||||
@ -503,6 +528,8 @@ e_select_names_model_replace (ESelectNamesModel *model, gint index, EDestination
|
||||
|
||||
if (model->priv->data == NULL) {
|
||||
|
||||
connect_destination (model, dest);
|
||||
|
||||
model->priv->data = g_list_append (model->priv->data, dest);
|
||||
gtk_object_ref (GTK_OBJECT (dest));
|
||||
gtk_object_sink (GTK_OBJECT (dest));
|
||||
@ -513,6 +540,9 @@ e_select_names_model_replace (ESelectNamesModel *model, gint index, EDestination
|
||||
|
||||
if (node->data != dest) {
|
||||
|
||||
disconnect_destination (model, E_DESTINATION (node->data));
|
||||
connect_destination (model, dest);
|
||||
|
||||
old_str = e_destination_get_textrep (E_DESTINATION (node->data));
|
||||
old_strlen = old_str ? strlen (old_str) : 0;
|
||||
|
||||
@ -540,6 +570,7 @@ e_select_names_model_delete (ESelectNamesModel *model, gint index)
|
||||
g_return_if_fail (0 <= index && index < g_list_length (model->priv->data));
|
||||
|
||||
node = g_list_nth (model->priv->data, index);
|
||||
disconnect_destination (model, E_DESTINATION (node->data));
|
||||
gtk_object_unref (GTK_OBJECT (node->data));
|
||||
|
||||
model->priv->data = g_list_remove_link (model->priv->data, node);
|
||||
@ -565,8 +596,10 @@ e_select_names_model_clean (ESelectNamesModel *model)
|
||||
dest = iter->data ? E_DESTINATION (iter->data) : NULL;
|
||||
|
||||
if (dest == NULL || e_destination_is_empty (dest)) {
|
||||
if (dest)
|
||||
if (dest) {
|
||||
disconnect_destination (model, dest);
|
||||
gtk_object_unref (GTK_OBJECT (dest));
|
||||
}
|
||||
model->priv->data = g_list_remove_link (model->priv->data, iter);
|
||||
g_list_free_1 (iter);
|
||||
changed = TRUE;
|
||||
@ -579,12 +612,19 @@ e_select_names_model_clean (ESelectNamesModel *model)
|
||||
e_select_names_model_changed (model);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_all_iter (gpointer data, gpointer closure)
|
||||
{
|
||||
disconnect_destination (E_SELECT_NAMES_MODEL (closure), E_DESTINATION (data));
|
||||
gtk_object_unref (GTK_OBJECT (data));
|
||||
}
|
||||
|
||||
void
|
||||
e_select_names_model_delete_all (ESelectNamesModel *model)
|
||||
{
|
||||
g_return_if_fail (model != NULL && E_IS_SELECT_NAMES_MODEL (model));
|
||||
|
||||
g_list_foreach (model->priv->data, (GFunc) gtk_object_unref, NULL);
|
||||
g_list_foreach (model->priv->data, delete_all_iter, model);
|
||||
g_list_free (model->priv->data);
|
||||
model->priv->data = NULL;
|
||||
|
||||
@ -692,3 +732,70 @@ e_select_names_model_text_pos (ESelectNamesModel *model, gint pos, gint *index,
|
||||
if (length)
|
||||
*length = len;
|
||||
}
|
||||
|
||||
void
|
||||
e_select_names_model_cardify (ESelectNamesModel *model, EBook *book, gint index, gint delay)
|
||||
{
|
||||
EDestination *dest;
|
||||
|
||||
g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
|
||||
g_return_if_fail (book == NULL || E_IS_BOOK (book));
|
||||
g_return_if_fail (0 <= index && index < g_list_length (model->priv->data));
|
||||
|
||||
dest = E_DESTINATION (g_list_nth_data (model->priv->data, index));
|
||||
|
||||
if (!e_destination_is_empty (dest)) {
|
||||
|
||||
if (delay > 0)
|
||||
e_destination_cardify_delayed (dest, book, delay);
|
||||
else
|
||||
e_destination_cardify (dest, book);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
e_select_names_model_cancel_cardify (ESelectNamesModel *model, gint index)
|
||||
{
|
||||
EDestination *dest;
|
||||
|
||||
g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
|
||||
g_return_if_fail (0 <= index && index < g_list_length (model->priv->data));
|
||||
|
||||
dest = E_DESTINATION (g_list_nth_data (model->priv->data, index));
|
||||
|
||||
e_destination_cancel_cardify (dest);
|
||||
}
|
||||
|
||||
void
|
||||
e_select_names_model_cardify_all (ESelectNamesModel *model, EBook *book, gint delay)
|
||||
{
|
||||
GList *iter;
|
||||
|
||||
g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
|
||||
g_return_if_fail (book == NULL || E_IS_BOOK (book));
|
||||
|
||||
for (iter = model->priv->data; iter != NULL; iter = g_list_next (iter)) {
|
||||
EDestination *dest = E_DESTINATION (iter->data);
|
||||
if (!e_destination_is_empty (dest)) {
|
||||
|
||||
if (delay > 0)
|
||||
e_destination_cardify_delayed (dest, book, delay);
|
||||
else
|
||||
e_destination_cardify (dest, book);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
e_select_names_model_cancel_cardify_all (ESelectNamesModel *model)
|
||||
{
|
||||
GList *iter;
|
||||
|
||||
g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
|
||||
|
||||
for (iter = model->priv->data; iter != NULL; iter = g_list_next (iter)) {
|
||||
EDestination *dest = E_DESTINATION (iter->data);
|
||||
e_destination_cancel_cardify (dest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -73,4 +73,10 @@ void e_select_names_model_clean (ESelectNamesModel *model);
|
||||
void e_select_names_model_name_pos (ESelectNamesModel *model, gint index, gint *pos, gint *length);
|
||||
void e_select_names_model_text_pos (ESelectNamesModel *model, gint pos, gint *index, gint *start_pos, gint *length);
|
||||
|
||||
void e_select_names_model_cardify (ESelectNamesModel *model, EBook *book, gint index, gint delay);
|
||||
void e_select_names_model_cancel_cardify (ESelectNamesModel *model, gint index);
|
||||
void e_select_names_model_cardify_all (ESelectNamesModel *model, EBook *book, gint delay);
|
||||
void e_select_names_model_cancel_cardify_all (ESelectNamesModel *model);
|
||||
|
||||
|
||||
#endif /* ! __E_SELECT_NAMES_MODEL_H__ */
|
||||
|
||||
@ -423,7 +423,7 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha
|
||||
|
||||
EDestination *dest = e_destination_new ();
|
||||
e_destination_set_raw (dest, new_str);
|
||||
|
||||
|
||||
e_select_names_model_replace (source, index, dest);
|
||||
|
||||
if (this_length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user