diff options
8 files changed, 153 insertions, 81 deletions
diff --git a/addressbook/gui/component/select-names/e-select-names-completion.c b/addressbook/gui/component/select-names/e-select-names-completion.c index b853dbe835..c5d1727300 100644 --- a/addressbook/gui/component/select-names/e-select-names-completion.c +++ b/addressbook/gui/component/select-names/e-select-names-completion.c @@ -821,6 +821,8 @@ clean_query_text (const gchar *s) } *t = '\0'; + g_strstrip (q); + return q; } 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 3212242fbd..3b49497f42 100644 --- a/addressbook/gui/component/select-names/e-select-names-manager.c +++ b/addressbook/gui/component/select-names/e-select-names-manager.c @@ -40,6 +40,7 @@ typedef struct { char *id; char *title; ESelectNamesModel *model; + ESelectNamesModel *original_model; ESelectNamesManager *manager; guint changed_handler; } ESelectNamesManagerSection; @@ -188,6 +189,7 @@ section_copy(const void *sec, void *data) newsec->id = g_strdup(section->id); newsec->title = g_strdup(section->title); newsec->model = section->model; + newsec->original_model = section->original_model; newsec->manager = section->manager; newsec->changed_handler = gtk_signal_connect (GTK_OBJECT (newsec->model), "changed", @@ -196,6 +198,9 @@ section_copy(const void *sec, void *data) if (newsec->model) gtk_object_ref(GTK_OBJECT(newsec->model)); + if (newsec->original_model) + gtk_object_ref(GTK_OBJECT(newsec->original_model)); + return newsec; } @@ -209,7 +214,10 @@ section_free(void *sec, void *data) g_free(section->id); g_free(section->title); if (section->model) - gtk_object_unref(GTK_OBJECT(section->model)); + gtk_object_unref (GTK_OBJECT(section->model)); + if (section->original_model) + gtk_object_unref (GTK_OBJECT (section->original_model)); + g_free(section); } @@ -290,6 +298,8 @@ e_select_names_manager_add_section_with_limit (ESelectNamesManager *manager, section->model = e_select_names_model_new(); e_select_names_model_set_limit (section->model, limit); + section->original_model = NULL; + section->manager = manager; section->changed_handler = gtk_signal_connect (GTK_OBJECT (section->model), @@ -420,7 +430,7 @@ e_select_names_manager_create_entry (ESelectNamesManager *manager, const char *i "popup", GTK_SIGNAL_FUNC (popup_cb), section->model); - + gtk_signal_connect (GTK_OBJECT (eentry->canvas), "focus_in_event", GTK_SIGNAL_FUNC (focus_in_cb), @@ -465,42 +475,26 @@ e_select_names_manager_create_entry (ESelectNamesManager *manager, const char *i static void e_select_names_clicked(ESelectNames *dialog, gint button, ESelectNamesManager *manager) { + gnome_dialog_close(GNOME_DIALOG(dialog)); + switch(button) { - case 0: { + case 0: + /* We don't need to do anything if they click on OK */ + break; + + case 1: { EList *list = manager->sections; EIterator *iterator = e_list_get_iterator(list); - for (e_iterator_reset(iterator); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - ESelectNamesManagerSection *section = (void *) e_iterator_get(iterator); - ESelectNamesModel *source = e_select_names_get_source(dialog, section->id); - e_select_names_model_merge (section->model, source); - gtk_object_unref (GTK_OBJECT (source)); - - } - gtk_object_unref(GTK_OBJECT(iterator)); -#if 0 - list = manager->entries; - iterator = e_list_get_iterator(list); for (e_iterator_reset(iterator); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - ESelectNamesManagerEntry *entry = (void *) e_iterator_get(iterator); - ESelectNamesModel *source = e_select_names_get_source(dialog, entry->id); - if (source) { - ETextModel *model = e_select_names_text_model_new(source); - if (model) { - gtk_object_set(GTK_OBJECT(entry->entry), - "model", model, - NULL); - gtk_object_unref(GTK_OBJECT(source)); - } - gtk_object_unref(GTK_OBJECT(model)); - } + ESelectNamesManagerSection *section = (void *) e_iterator_get(iterator); + e_select_names_model_overwrite_copy (section->model, section->original_model); } + gtk_object_unref(GTK_OBJECT(iterator)); -#endif break; } } - gnome_dialog_close(GNOME_DIALOG(dialog)); } void @@ -519,14 +513,15 @@ e_select_names_manager_activate_dialog (ESelectNamesManager *manager, iterator = e_list_get_iterator(manager->sections); for (e_iterator_reset(iterator); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - const ESelectNamesManagerSection *section = e_iterator_get(iterator); - ESelectNamesModel *newmodel = e_select_names_model_duplicate(section->model); - e_select_names_add_section(manager->names, section->id, section->title, newmodel); - gtk_signal_connect (GTK_OBJECT (newmodel), + ESelectNamesManagerSection *section = (ESelectNamesManagerSection *) e_iterator_get(iterator); + if (section->original_model != NULL) + gtk_object_unref (GTK_OBJECT (section->original_model)); + section->original_model = e_select_names_model_duplicate (section->model); + e_select_names_add_section (manager->names, section->id, section->title, section->model); + gtk_signal_connect (GTK_OBJECT (section->model), "changed", GTK_SIGNAL_FUNC (section_model_working_copy_changed_cb), (gpointer)section); /* casting out const to avoid compiler warning */ - gtk_object_unref(GTK_OBJECT(newmodel)); } e_select_names_set_default(manager->names, id); gtk_signal_connect(GTK_OBJECT(manager->names), "clicked", @@ -538,20 +533,3 @@ e_select_names_manager_activate_dialog (ESelectNamesManager *manager, } } -#if 0 -/* Of type ECard */ -EList * -e_select_names_manager_get_cards (ESelectNamesManager *manager, - const char *id) -{ - EIterator *iterator; - iterator = e_list_get_iterator(manager->sections); - for (e_iterator_reset(iterator); e_iterator_is_valid(iterator); e_iterator_next(iterator)) { - const ESelectNamesManagerSection *section = e_iterator_get(iterator); - if (!strcmp(section->id, id)) { - return e_select_names_model_get_cards(section->model); - } - } - return NULL; -} -#endif diff --git a/addressbook/gui/component/select-names/e-select-names-manager.h b/addressbook/gui/component/select-names/e-select-names-manager.h index 61779fb56a..dccc3fd7c2 100644 --- a/addressbook/gui/component/select-names/e-select-names-manager.h +++ b/addressbook/gui/component/select-names/e-select-names-manager.h @@ -54,12 +54,6 @@ GtkWidget *e_select_names_manager_create_entry (ESelectNames void e_select_names_manager_activate_dialog (ESelectNamesManager *manager, const char *id); -#if 0 -/* Of type ECard */ -EList *e_select_names_manager_get_cards (ESelectNamesManager *manager, - const char *id); -#endif - /* Standard Gtk function */ GtkType e_select_names_manager_get_type (void); 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 0f43464507..89838f9b82 100644 --- a/addressbook/gui/component/select-names/e-select-names-model.c +++ b/addressbook/gui/component/select-names/e-select-names-model.c @@ -58,6 +58,9 @@ struct _ESelectNamesModelPrivate { gchar *addr_text; gint limit; + + gint freeze_count; + gboolean pending_changed; }; @@ -216,7 +219,12 @@ e_select_names_model_changed (ESelectNamesModel *model) g_free (model->priv->addr_text); model->priv->addr_text = NULL; - gtk_signal_emit (GTK_OBJECT(model), e_select_names_model_signals[E_SELECT_NAMES_MODEL_CHANGED]); + if (model->priv->freeze_count > 0) { + model->priv->pending_changed = TRUE; + } else { + gtk_signal_emit (GTK_OBJECT(model), e_select_names_model_signals[E_SELECT_NAMES_MODEL_CHANGED]); + model->priv->pending_changed = FALSE; + } } static void @@ -580,14 +588,17 @@ void e_select_names_model_delete (ESelectNamesModel *model, gint index) { GList *node; + EDestination *dest; g_return_if_fail (model != NULL); g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model)); 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)); + dest = E_DESTINATION (node->data); + + disconnect_destination (model, dest); + gtk_object_unref (GTK_OBJECT (dest)); model->priv->data = g_list_remove_link (model->priv->data, node); g_list_free_1 (node); @@ -788,6 +799,31 @@ e_select_names_model_cardify (ESelectNamesModel *model, EBook *book, gint index, } } +gboolean +e_select_names_model_uncardify (ESelectNamesModel *model, gint index) +{ + EDestination *dest; + gboolean rv = FALSE; + + g_return_val_if_fail (E_IS_SELECT_NAMES_MODEL (model), FALSE); + g_return_val_if_fail (0 <= index && index < g_list_length (model->priv->data), FALSE); + + dest = E_DESTINATION (g_list_nth_data (model->priv->data, index)); + + if (!e_destination_is_empty (dest)) { + EDestination *cpy_dest = e_destination_copy (dest); + + rv = e_destination_uncardify (cpy_dest); + + if (rv) { + e_select_names_model_replace (model, index, cpy_dest); + } + + } + + return rv; +} + void e_select_names_model_cancel_cardify (ESelectNamesModel *model, gint index) { @@ -834,3 +870,21 @@ e_select_names_model_cancel_cardify_all (ESelectNamesModel *model) } } +void +e_select_names_model_freeze (ESelectNamesModel *model) +{ + g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model)); + + ++model->priv->freeze_count; +} + +void +e_select_names_model_thaw (ESelectNamesModel *model) +{ + g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model)); + g_return_if_fail (model->priv->freeze_count > 0); + + --model->priv->freeze_count; + if (model->priv->pending_changed) + e_select_names_model_changed (model); +} 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 c10b6ccf2a..b7fa04d6cd 100644 --- a/addressbook/gui/component/select-names/e-select-names-model.h +++ b/addressbook/gui/component/select-names/e-select-names-model.h @@ -77,9 +77,15 @@ void e_select_names_model_name_pos (ESelectNamesModel *model, gint inde 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); +gboolean e_select_names_model_uncardify (ESelectNamesModel *model, gint index); 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); +/* This is a mildly annoying freeze/thaw pair, in that it only applies to the 'changed' + signal and not to 'resized'. This could cause unexpected results in some cases. */ +void e_select_names_model_freeze (ESelectNamesModel *model); +void e_select_names_model_thaw (ESelectNamesModel *model); + #endif /* ! __E_SELECT_NAMES_MODEL_H__ */ diff --git a/addressbook/gui/component/select-names/e-select-names-table-model.c b/addressbook/gui/component/select-names/e-select-names-table-model.c index fee84ce071..84c7754020 100644 --- a/addressbook/gui/component/select-names/e-select-names-table-model.c +++ b/addressbook/gui/component/select-names/e-select-names-table-model.c @@ -129,8 +129,11 @@ fill_in_info (ESelectNamesTableModel *model) model->data[i].email = g_strdup(""); gtk_object_unref(GTK_OBJECT(simple)); } else { - model->data[i].name = g_strdup (e_destination_get_name (dest)); - model->data[i].email = g_strdup (e_destination_get_email (dest)); + const gchar *name = e_destination_get_name (dest); + const gchar *email = e_destination_get_email (dest); + + model->data[i].name = g_strdup (name && *name ? name : email); + model->data[i].email = g_strdup (email); } } } else { 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 c6f2b7856b..782b7ebb90 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 @@ -426,10 +426,12 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha if (new_str) { - EDestination *dest = e_destination_new (); + EDestination *dest; + dest = index >= 0 ? e_destination_copy (e_select_names_model_get_destination (source, index)) : e_destination_new (); e_destination_set_raw (dest, new_str); - e_select_names_model_replace (source, index, dest); + + /* e_select_names_model_replace (source, index, dest); */ if (this_length > 0) { repos.model = model; @@ -616,7 +618,7 @@ e_select_names_text_model_delete (ETextModel *model, gint pos, gint length) EReposDeleteShift repos; EDestination *dest; - dest = e_destination_new (); + dest = index >= 0 ? e_destination_copy (e_select_names_model_get_destination (source, index)) : e_destination_new (); e_destination_set_raw (dest, new_str); e_select_names_model_replace (source, index, dest); diff --git a/addressbook/gui/component/select-names/e-select-names.c b/addressbook/gui/component/select-names/e-select-names.c index 7316458630..eda6dbd301 100644 --- a/addressbook/gui/component/select-names/e-select-names.c +++ b/addressbook/gui/component/select-names/e-select-names.c @@ -146,13 +146,48 @@ addressbook_model_set_uri(EAddressbookModel *model, char *uri) static void * card_key (ECard *card) { - EBook *book = e_card_get_book (card); - const gchar *book_uri = book ? e_book_get_uri (book) : "NoBook"; + EBook *book; + const gchar *book_uri; + if (card == NULL) + return NULL; + + g_assert (E_IS_CARD (card)); + + book = e_card_get_book (card); + book_uri = book ? e_book_get_uri (book) : "NoBook"; return g_strdup_printf ("%s|%s", book_uri ? book_uri : "NoURI", e_card_get_id (card)); } static void +sync_one_model (gpointer k, gpointer val, gpointer closure) +{ + ETableWithout *etw = E_TABLE_WITHOUT (closure); + ESelectNamesChild *child = val; + ESelectNamesModel *model = child->source; + gint i, count; + ECard *card; + void *key; + + count = e_select_names_model_count (model); + for (i = 0; i < count; ++i) { + card = e_select_names_model_get_card (model, i); + if (card) { + key = card_key (card); + e_table_without_hide (etw, key); + g_free (key); + } + } +} + +static void +sync_table_and_models (ESelectNamesModel *triggering_model, ESelectNames *esl) +{ + e_table_without_show_all (E_TABLE_WITHOUT (esl->without)); + g_hash_table_foreach (esl->children, sync_one_model, esl->without); +} + +static void real_add_address_cb (int model_row, gpointer closure) { ESelectNamesChild *child = closure; @@ -160,14 +195,11 @@ real_add_address_cb (int model_row, gpointer closure) ECard *card; EDestination *dest = e_destination_new (); gint mapped_row; - void *key; mapped_row = e_table_subset_view_to_model_row (E_TABLE_SUBSET (names->without), model_row); card = e_addressbook_model_get_card(E_ADDRESSBOOK_MODEL(names->model), mapped_row); - key = card_key (card); - e_table_without_hide (E_TABLE_WITHOUT (names->without), key); - g_free (key); + e_destination_set_card (dest, card, 0); @@ -180,8 +212,10 @@ real_add_address_cb (int model_row, gpointer closure) static void real_add_address(ESelectNames *names, ESelectNamesChild *child) { + e_select_names_model_freeze (child->source); e_table_selected_row_foreach(e_table_scrolled_get_table(names->table), real_add_address_cb, child); + e_select_names_model_thaw (child->source); } static void @@ -597,6 +631,7 @@ e_select_names_init (ESelectNames *e_select_names) static void e_select_names_child_free(char *key, ESelectNamesChild *child, ESelectNames *e_select_names) { + gtk_signal_disconnect_by_func (GTK_OBJECT (child->source), GTK_SIGNAL_FUNC (sync_table_and_models), e_select_names); g_free(child->title); gtk_object_unref(GTK_OBJECT(child->model)); gtk_object_unref(GTK_OBJECT(child->source)); @@ -607,7 +642,7 @@ static void e_select_names_destroy (GtkObject *object) { ESelectNames *e_select_names = E_SELECT_NAMES(object); - + gtk_signal_disconnect_by_data(GTK_OBJECT(e_select_names->local_listener), e_select_names); gtk_object_unref(GTK_OBJECT(e_select_names->local_listener)); gtk_signal_disconnect_by_data(GTK_OBJECT(e_select_names->other_contacts_listener), e_select_names); @@ -663,16 +698,7 @@ button_clicked(GtkWidget *button, ESelectNamesChild *child) static void remove_address(ETable *table, int row, int col, GdkEvent *event, ESelectNamesChild *child) { - const EDestination *dest; - ECard *card; - void *key; - dest = e_select_names_model_get_destination (child->source, row); - card = e_destination_get_card (dest); - key = card_key (card); - e_select_names_model_delete (child->source, row); - e_table_without_show (E_TABLE_WITHOUT (child->names->without), key); - g_free (key); } struct _RightClickData { @@ -698,7 +724,7 @@ selected_rows_foreach_cb (void *row, void *data) { ESelectNamesChild *child = data; - e_select_names_model_delete (child->source, GPOINTER_TO_INT (row)); + remove_address (NULL, GPOINTER_TO_INT (row), 0, NULL, child); } static void @@ -798,6 +824,11 @@ e_select_names_add_section(ESelectNames *e_select_names, char *name, char *id, E child->source = source; gtk_object_ref(GTK_OBJECT(child->model)); gtk_object_ref(GTK_OBJECT(child->source)); + + gtk_signal_connect (GTK_OBJECT (child->source), + "changed", + GTK_SIGNAL_FUNC (sync_table_and_models), + e_select_names); gtk_widget_show(etable); @@ -809,6 +840,8 @@ e_select_names_add_section(ESelectNames *e_select_names, char *name, char *id, E 0, 0); g_hash_table_insert(e_select_names->children, g_strdup(id), child); + + sync_table_and_models (child->source, e_select_names); } static void * |