From 07fbf1a035bfa00d99c6d00dfd04cba7c1c093c3 Mon Sep 17 00:00:00 2001 From: Jon Trowbridge Date: Thu, 9 Aug 2001 18:07:35 +0000 Subject: Hook up some magic to (basically) cardify an entry on focus-out. (What we 2001-08-09 Jon Trowbridge * 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 --- .../component/select-names/e-select-names-bonobo.c | 11 +- .../select-names/e-select-names-manager.c | 45 ++++++++ .../component/select-names/e-select-names-model.c | 113 ++++++++++++++++++++- .../component/select-names/e-select-names-model.h | 6 ++ .../select-names/e-select-names-text-model.c | 2 +- 5 files changed, 171 insertions(+), 6 deletions(-) (limited to 'addressbook/gui') diff --git a/addressbook/gui/component/select-names/e-select-names-bonobo.c b/addressbook/gui/component/select-names/e-select-names-bonobo.c index 25adf13a65..90b3e477fb 100644 --- a/addressbook/gui/component/select-names/e-select-names-bonobo.c +++ b/addressbook/gui/component/select-names/e-select-names-bonobo.c @@ -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: { diff --git a/addressbook/gui/component/select-names/e-select-names-manager.c b/addressbook/gui/component/select-names/e-select-names-manager.c index 4481438327..0bec7da416 100644 --- a/addressbook/gui/component/select-names/e-select-names-manager.c +++ b/addressbook/gui/component/select-names/e-select-names-manager.c @@ -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; diff --git a/addressbook/gui/component/select-names/e-select-names-model.c b/addressbook/gui/component/select-names/e-select-names-model.c index dc383994d3..9dda927640 100644 --- a/addressbook/gui/component/select-names/e-select-names-model.c +++ b/addressbook/gui/component/select-names/e-select-names-model.c @@ -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); + } +} + diff --git a/addressbook/gui/component/select-names/e-select-names-model.h b/addressbook/gui/component/select-names/e-select-names-model.h index b11e9503ec..9f89e91093 100644 --- a/addressbook/gui/component/select-names/e-select-names-model.h +++ b/addressbook/gui/component/select-names/e-select-names-model.h @@ -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__ */ diff --git a/addressbook/gui/component/select-names/e-select-names-text-model.c b/addressbook/gui/component/select-names/e-select-names-text-model.c index 11b3b67323..2f10516dd1 100644 --- a/addressbook/gui/component/select-names/e-select-names-text-model.c +++ b/addressbook/gui/component/select-names/e-select-names-text-model.c @@ -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) { -- cgit v1.2.3