diff options
Diffstat (limited to 'addressbook/backend')
-rw-r--r-- | addressbook/backend/ebook/e-book-listener.c | 47 | ||||
-rw-r--r-- | addressbook/backend/ebook/e-book-view-listener.c | 52 | ||||
-rw-r--r-- | addressbook/backend/ebook/e-destination.c | 230 | ||||
-rw-r--r-- | addressbook/backend/ebook/e-destination.h | 10 |
4 files changed, 248 insertions, 91 deletions
diff --git a/addressbook/backend/ebook/e-book-listener.c b/addressbook/backend/ebook/e-book-listener.c index 15ceb04bd3..86b2e5cb9d 100644 --- a/addressbook/backend/ebook/e-book-listener.c +++ b/addressbook/backend/ebook/e-book-listener.c @@ -26,8 +26,9 @@ static BonoboObjectClass *e_book_listener_parent_class; POA_GNOME_Evolution_Addressbook_BookListener__vepv e_book_listener_vepv; struct _EBookListenerPrivate { - GList *response_queue; - gint idle_id; + GList *response_queue; + gint idle_id; + gboolean idle_lock; guint stopped : 1; }; @@ -35,32 +36,35 @@ struct _EBookListenerPrivate { static gboolean e_book_listener_check_queue (EBookListener *listener) { - gboolean retval; + if (listener->priv->idle_lock) + return TRUE; - /* Hold a reference locally, so that we can't get blown away - during the signal emission. */ - bonobo_object_ref (BONOBO_OBJECT (listener)); - retval = TRUE; + listener->priv->idle_lock = TRUE; + + if (listener->priv->stopped) { + listener->priv->idle_id = 0; + goto exit_gracefully; + } if (listener->priv->response_queue != NULL) { - gtk_signal_emit (GTK_OBJECT (listener), - e_book_listener_signals [RESPONSES_QUEUED]); + gtk_signal_emit (GTK_OBJECT (listener), e_book_listener_signals [RESPONSES_QUEUED]); } - /* Make sure that ->idle_id != 0, so that only the first reentrant call to - this function unrefs our "global" reference. */ - if (listener->priv->response_queue == NULL && listener->priv->idle_id != 0) { + if (listener->priv->response_queue == NULL) { listener->priv->idle_id = 0; - - /* We only release our reference to the listener when the idle - function is totally finished. */ - bonobo_object_unref (BONOBO_OBJECT (listener)); - retval = FALSE; } - bonobo_object_unref (BONOBO_OBJECT (listener)); + exit_gracefully: - return retval; + listener->priv->idle_lock = FALSE; + + /* Only drop the reference when we exit for the last time. */ + if (listener->priv->idle_id == 0) { + gtk_object_unref (GTK_OBJECT (listener)); + return FALSE; + } + + return TRUE; } static void @@ -74,10 +78,9 @@ e_book_listener_queue_response (EBookListener *listener, if (listener->priv->idle_id == 0) { /* Hold a reference to the listener until the idle function is finished. */ - bonobo_object_ref (BONOBO_OBJECT (listener)); + gtk_object_ref (GTK_OBJECT (listener)); - listener->priv->idle_id = g_idle_add ( - (GSourceFunc) e_book_listener_check_queue, listener); + listener->priv->idle_id = g_idle_add ((GSourceFunc) e_book_listener_check_queue, listener); } } diff --git a/addressbook/backend/ebook/e-book-view-listener.c b/addressbook/backend/ebook/e-book-view-listener.c index c2e5b66106..0b862fc61b 100644 --- a/addressbook/backend/ebook/e-book-view-listener.c +++ b/addressbook/backend/ebook/e-book-view-listener.c @@ -26,8 +26,9 @@ static BonoboObjectClass *e_book_view_listener_parent_class; POA_GNOME_Evolution_Addressbook_BookViewListener__vepv e_book_view_listener_vepv; struct _EBookViewListenerPrivate { - GList *response_queue; - gint idle_id; + GList *response_queue; + gint idle_id; + gboolean idle_lock; guint stopped : 1; }; @@ -36,56 +37,49 @@ struct _EBookViewListenerPrivate { static gboolean e_book_view_listener_check_queue (EBookViewListener *listener) { - gboolean retval; + if (listener->priv->idle_lock) + return TRUE; + + listener->priv->idle_lock = TRUE; if (listener->priv->stopped) { listener->priv->idle_id = 0; - bonobo_object_unref (BONOBO_OBJECT (listener)); - return FALSE; + goto exit_gracefully; } - /* An extra ref to keep listener from being destroyed during the - signal emission. */ - bonobo_object_ref (BONOBO_OBJECT (listener)); - retval = TRUE; - if (listener->priv->response_queue != NULL) { - - gtk_signal_emit (GTK_OBJECT (listener), - e_book_view_listener_signals [RESPONSES_QUEUED]); - + gtk_signal_emit (GTK_OBJECT (listener), e_book_view_listener_signals [RESPONSES_QUEUED]); } - /* this callback could be (and indeed is) called from signal emited above, - signal handler could call e_book_view_listener_stop, so we need to check - if idle is still set and if not we don't want to unref again */ - if (listener->priv->response_queue == NULL && listener->priv->idle_id != 0) { + if (listener->priv->response_queue == NULL) { listener->priv->idle_id = 0; - bonobo_object_unref (BONOBO_OBJECT (listener)); - retval = FALSE; } - /* Drop our extra reference from above. */ - bonobo_object_unref (BONOBO_OBJECT (listener)); + exit_gracefully: - return retval; + listener->priv->idle_lock = FALSE; + + /* Only drop the reference when we exit for the last time. */ + if (listener->priv->idle_id == 0) { + gtk_object_unref (GTK_OBJECT (listener)); + return FALSE; + } + + return TRUE; } static void e_book_view_listener_queue_response (EBookViewListener *listener, EBookViewListenerResponse *response) { - listener->priv->response_queue = - g_list_append (listener->priv->response_queue, - response); + listener->priv->response_queue = g_list_append (listener->priv->response_queue, response); if (listener->priv->idle_id == 0) { /* Hold a reference to the listener while the idle is active. */ - bonobo_object_ref (BONOBO_OBJECT (listener)); + gtk_object_ref (GTK_OBJECT (listener)); - listener->priv->idle_id = g_idle_add ( - (GSourceFunc) e_book_view_listener_check_queue, listener); + listener->priv->idle_id = g_idle_add ((GSourceFunc) e_book_view_listener_check_queue, listener); } } diff --git a/addressbook/backend/ebook/e-destination.c b/addressbook/backend/ebook/e-destination.c index 9e0e4b6067..842fa8652e 100644 --- a/addressbook/backend/ebook/e-destination.c +++ b/addressbook/backend/ebook/e-destination.c @@ -59,9 +59,13 @@ struct _EDestinationPrivate { ECard *card; gint card_email_num; + ECard *old_card; + gint old_card_email_num; + gchar *name; gchar *email; gchar *addr; + gchar *textrep; gboolean html_mail_override; gboolean wants_html_mail; @@ -90,6 +94,9 @@ e_destination_destroy (GtkObject *obj) EDestination *dest = E_DESTINATION (obj); e_destination_clear (dest); + + if (dest->priv->old_card) + gtk_object_unref (GTK_OBJECT (dest->priv->old_card)); if (dest->priv->cardify_book) gtk_object_unref (GTK_OBJECT (dest->priv->cardify_book)); @@ -207,17 +214,22 @@ e_destination_copy (const EDestination *dest) new_dest = e_destination_new (); - new_dest->priv->book_uri = g_strdup (dest->priv->book_uri); - new_dest->priv->card_uid = g_strdup (dest->priv->card_uid); - new_dest->priv->name = g_strdup (dest->priv->name); - new_dest->priv->email = g_strdup (dest->priv->email); - new_dest->priv->addr = g_strdup (dest->priv->addr); - new_dest->priv->card_email_num = dest->priv->card_email_num; + new_dest->priv->book_uri = g_strdup (dest->priv->book_uri); + new_dest->priv->card_uid = g_strdup (dest->priv->card_uid); + new_dest->priv->name = g_strdup (dest->priv->name); + new_dest->priv->email = g_strdup (dest->priv->email); + new_dest->priv->addr = g_strdup (dest->priv->addr); + new_dest->priv->card_email_num = dest->priv->card_email_num; + new_dest->priv->old_card_email_num = dest->priv->old_card_email_num; new_dest->priv->card = dest->priv->card; if (new_dest->priv->card) gtk_object_ref (GTK_OBJECT (new_dest->priv->card)); + new_dest->priv->old_card = dest->priv->old_card; + if (new_dest->priv->old_card) + gtk_object_ref (GTK_OBJECT (new_dest->priv->old_card)); + new_dest->priv->html_mail_override = dest->priv->html_mail_override; new_dest->priv->wants_html_mail = dest->priv->wants_html_mail; @@ -237,10 +249,16 @@ e_destination_clear_card (EDestination *dest) g_free (dest->priv->card_uid); dest->priv->card_uid = NULL; - if (dest->priv->card) - gtk_object_unref (GTK_OBJECT (dest->priv->card)); - dest->priv->card = NULL; + if (dest->priv->card) { + + if (dest->priv->old_card) + gtk_object_unref (GTK_OBJECT (dest->priv->old_card)); + dest->priv->old_card = dest->priv->card; + dest->priv->old_card_email_num = dest->priv->card_email_num; + } + + dest->priv->card = NULL; dest->priv->card_email_num = -1; g_list_foreach (dest->priv->list_dests, (GFunc) gtk_object_unref, NULL); @@ -270,6 +288,9 @@ e_destination_clear_strings (EDestination *dest) g_free (dest->priv->addr); dest->priv->addr = NULL; + g_free (dest->priv->textrep); + dest->priv->textrep = NULL; + e_destination_changed (dest); } @@ -290,7 +311,7 @@ gboolean e_destination_is_empty (const EDestination *dest) { struct _EDestinationPrivate *p; - g_return_val_if_fail (dest && E_IS_DESTINATION (dest), TRUE); + g_return_val_if_fail (E_IS_DESTINATION (dest), TRUE); p = dest->priv; return !(p->card != NULL @@ -304,6 +325,20 @@ e_destination_is_empty (const EDestination *dest) } gboolean +e_destination_is_valid (const EDestination *dest) +{ + const gchar *email; + + g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE); + + if (dest->priv->card != NULL) + return TRUE; + + email = e_destination_get_email (dest); + return email && *email && strchr (email, '@'); +} + +gboolean e_destination_equal (const EDestination *a, const EDestination *b) { const struct _EDestinationPrivate *pa, *pb; @@ -419,19 +454,25 @@ e_destination_set_card_uid (EDestination *dest, const gchar *uid, gint email_num void e_destination_set_name (EDestination *dest, const gchar *name) { - g_return_if_fail (dest && E_IS_DESTINATION (dest)); - g_return_if_fail (name != NULL); + gboolean changed = FALSE; - if (dest->priv->name == NULL || strcmp (dest->priv->name, name)) { + g_return_if_fail (E_IS_DESTINATION (dest)); + if (name == NULL) { + if (dest->priv->name != NULL) { + g_free (dest->priv->name); + dest->priv->name = NULL; + changed = TRUE; + } + } else if (dest->priv->name == NULL || strcmp (dest->priv->name, name)) { g_free (dest->priv->name); dest->priv->name = g_strdup (name); + changed = TRUE; + } - if (dest->priv->addr != NULL) { - g_free (dest->priv->addr); - dest->priv->addr = NULL; - } - + if (changed) { + g_free (dest->priv->addr); + dest->priv->addr = NULL; e_destination_changed (dest); } } @@ -439,19 +480,27 @@ e_destination_set_name (EDestination *dest, const gchar *name) void e_destination_set_email (EDestination *dest, const gchar *email) { - g_return_if_fail (dest && E_IS_DESTINATION (dest)); - g_return_if_fail (email != NULL); + gboolean changed = FALSE; - if (dest->priv->email == NULL || strcmp (dest->priv->email, email)) { - - g_free (dest->priv->email); - dest->priv->email = g_strdup (email); + g_return_if_fail (E_IS_DESTINATION (dest)); - if (dest->priv->addr != NULL) { + if (email == NULL) { + if (dest->priv->email != NULL) { g_free (dest->priv->addr); dest->priv->addr = NULL; + changed = TRUE; } + } else if (dest->priv->email == NULL || strcmp (dest->priv->email, email)) { + g_free (dest->priv->email); + dest->priv->email = g_strdup (email); + changed = TRUE; + } + + + if (changed) { + g_free (dest->priv->addr); + dest->priv->addr = NULL; e_destination_changed (dest); } } @@ -750,20 +799,32 @@ e_destination_set_raw (EDestination *dest, const gchar *raw) const gchar * e_destination_get_textrep (const EDestination *dest) { - const gchar *txt; + const gchar *name, *email; g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL); if (dest->priv->raw) return dest->priv->raw; - txt = e_destination_get_name (dest); - if (txt != NULL) - return txt; + name = e_destination_get_name (dest); + email = e_destination_get_email (dest); + + if (e_destination_from_card (dest) && name != NULL) + return name; - txt = e_destination_get_email (dest); - if (txt != NULL) - return txt; + if (name && email) { + gchar *rep = g_strdup_printf ("%s <%s>", name, email); + if (dest->priv->textrep && !strcmp (rep, dest->priv->textrep)) { + g_free (rep); + } else { + g_free (dest->priv->textrep); + dest->priv->textrep = rep; + } + return dest->priv->textrep; + } + + if (email) + return email; return ""; } @@ -943,6 +1004,11 @@ e_destination_cardify (EDestination *dest, EBook *book) e_destination_cancel_cardify (dest); + /* In some cases, we can revert to the previous card. */ + if (!e_destination_is_valid (dest) && e_destination_revert (dest)) { + return; + } + set_cardify_book (dest, book); /* Handle the case of an EDestination containing a card URL */ @@ -996,15 +1062,54 @@ e_destination_cancel_cardify (EDestination *dest) } } -#if 0 -void +gboolean e_destination_uncardify (EDestination *dest) { - g_return_if_fail (E_IS_DESTINATION (dest)); + gchar *email; - g_assert_not_reached (); + g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE); + + if (! e_destination_contains_card (dest)) + return FALSE; + + email = g_strdup (e_destination_get_email (dest)); + + if (email == NULL) + return FALSE; + + e_destination_freeze (dest); + e_destination_clear (dest); + e_destination_set_raw (dest, email); + g_free (email); + e_destination_thaw (dest); + + return TRUE; +} + +gboolean +e_destination_revert (EDestination *dest) +{ + g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE); + + if (dest->priv->old_card) { + ECard *card; + gint card_email_num; + + card = dest->priv->old_card; + card_email_num = dest->priv->old_card_email_num; + + dest->priv->old_card = NULL; + + e_destination_freeze (dest); + e_destination_clear (dest); + e_destination_set_card (dest, card, card_email_num); + e_destination_thaw (dest); + + return TRUE; + } + + return FALSE; } -#endif /* * Destination import/export @@ -1216,6 +1321,9 @@ e_destination_xml_decode (EDestination *dest, xmlNodePtr node) if (list_dests) dest->priv->list_dests = list_dests; + dest->priv->html_mail_override = TRUE; + dest->priv->wants_html_mail = html_mail; + dest->priv->show_addresses = show_addr; e_destination_thaw (dest); @@ -1390,6 +1498,42 @@ e_destination_importv (const gchar *str) return destv; } +EDestination ** +e_destination_list_to_vector (GList *list) +{ + gint N = g_list_length (list); + EDestination **destv; + gint i = 0; + + if (N == 0) + return NULL; + + destv = g_new (EDestination *, N+1); + while (list != NULL) { + destv[i] = E_DESTINATION (list->data); + list->data = NULL; + ++i; + list = g_list_next (list); + } + destv[N] = NULL; + + return destv; +} + +void +e_destination_freev (EDestination **destv) +{ + gint i; + + if (destv) { + for (i = 0; destv[i] != NULL; ++i) { + gtk_object_unref (GTK_OBJECT (destv[i])); + } + g_free (destv); + } + +} + static void touch_cb (EBook *book, const gchar *addr, ECard *card, gpointer closure) { @@ -1413,3 +1557,15 @@ e_destination_touch (EDestination *dest) e_book_query_address_locally (email, touch_cb, NULL); } } + +void +e_destination_touchv (EDestination **destv) +{ + gint i; + + g_return_if_fail (destv != NULL); + + for (i = 0; destv[i] != NULL; ++i) { + e_destination_touch (destv[i]); + } +} diff --git a/addressbook/backend/ebook/e-destination.h b/addressbook/backend/ebook/e-destination.h index b9b06c47ff..807ab51b8e 100644 --- a/addressbook/backend/ebook/e-destination.h +++ b/addressbook/backend/ebook/e-destination.h @@ -68,6 +68,7 @@ EDestination *e_destination_copy (const EDestination *); void e_destination_clear (EDestination *); gboolean e_destination_is_empty (const EDestination *); +gboolean e_destination_is_valid (const EDestination *); gboolean e_destination_equal (const EDestination *a, const EDestination *b); void e_destination_set_card (EDestination *, ECard *card, gint email_num); @@ -107,10 +108,9 @@ 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 *); +gboolean e_destination_uncardify (EDestination *); -#if 0 -void e_destination_uncardify (EDestination *); -#endif +gboolean e_destination_revert (EDestination *); gchar *e_destination_get_address_textv (EDestination **); @@ -123,7 +123,11 @@ EDestination *e_destination_import (const gchar *str); gchar *e_destination_exportv (EDestination **); EDestination **e_destination_importv (const gchar *str); +EDestination **e_destination_list_to_vector (GList *); +void e_destination_freev (EDestination **); + void e_destination_touch (EDestination *); +void e_destination_touchv (EDestination **); #endif /* __E_DESTINATION_H__ */ |