diff options
6 files changed, 365 insertions, 76 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index 2c42e102c8..de2baac2d1 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,48 @@ +2001-06-27 Chris Toshok <toshok@ximian.com> + + * gui/contact-list-editor/e-contact-list-model.c + (contact_list_row_count): track storage change - we're only using + 1 array now. + (contact_list_value_at): same. + (contact_list_model_destroy): same. + (e_contact_list_model_init): same. + (e_contact_list_model_add_email): same. + (e_contact_list_model_add_card): same. + (e_contact_list_model_remove_row): same. + (e_contact_list_model_remove_all): new function - just free/unref + all existing rows. + (e_contact_list_model_get_email): new function, returns the + alloc'ed string containing either an email address or an encoded + ECardId. + + * gui/contact-list-editor/e-contact-list-model.h: remove the 2 + separate arrays for email and cards, and store them in the same + array. + + * gui/contact-list-editor/e-contact-list-editor.h (struct + _EContactListEditor): add the visible_addr_checkbutton widget. + + * gui/contact-list-editor/e-contact-list-editor.c + (visible_addrs_toggled_cb): new function. + (e_contact_list_editor_init): connect to "toggled" on + visible_addrs_checkbutton. + (file_save_cb): new function. + (tb_save_and_close_cb): new function. + (verbs): add Save and Save & Close. + (list_added_cb): new function. + (list_modified_cb): new function. + (save_card): new function - we do *not* use e_card_merging_* calls + here. + (e_contact_list_editor_get_arg): un-#if 0 code in the "card" + getter. + (e_contact_list_editor_set_arg): same for the "card" setter. + (extract_info): new function. + (fill_in_info): new function. + + * gui/contact-list-editor/contact-list-editor.glade: add a + checkbutton at the bottom to determine whether to visibly include + mail addresses in mail sent to this list. + 2001-06-26 Christopher James Lahey <clahey@ximian.com> * gui/component/select-names/e-select-names.c diff --git a/addressbook/gui/contact-list-editor/contact-list-editor.glade b/addressbook/gui/contact-list-editor/contact-list-editor.glade index 51b7c1a877..c20527c7d4 100644 --- a/addressbook/gui/contact-list-editor/contact-list-editor.glade +++ b/addressbook/gui/contact-list-editor/contact-list-editor.glade @@ -40,7 +40,7 @@ <child_name>GnomeDock:contents</child_name> <name>table1</name> <border_width>13</border_width> - <rows>6</rows> + <rows>7</rows> <columns>3</columns> <homogeneous>False</homogeneous> <row_spacing>5</row_spacing> @@ -274,6 +274,29 @@ </child> </widget> </widget> + + <widget> + <class>GtkCheckButton</class> + <name>visible-addrs-checkbutton</name> + <can_focus>True</can_focus> + <label>Hide addresses when sending mail to this list</label> + <active>False</active> + <draw_indicator>True</draw_indicator> + <child> + <left_attach>0</left_attach> + <right_attach>3</right_attach> + <top_attach>6</top_attach> + <bottom_attach>7</bottom_attach> + <xpad>0</xpad> + <ypad>0</ypad> + <xexpand>False</xexpand> + <yexpand>False</yexpand> + <xshrink>False</xshrink> + <yshrink>False</yshrink> + <xfill>True</xfill> + <yfill>False</yfill> + </child> + </widget> </widget> </widget> </widget> diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.c b/addressbook/gui/contact-list-editor/e-contact-list-editor.c index 06a3473baa..cd2710f022 100644 --- a/addressbook/gui/contact-list-editor/e-contact-list-editor.c +++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.c @@ -19,13 +19,14 @@ * Boston, MA 02111-1307, USA. */ -#include "e-contact-list-editor.h" -#include "e-contact-list-model.h" - +#include <config.h> #include <bonobo/bonobo-ui-container.h> #include <bonobo/bonobo-ui-util.h> #include <gal/e-table/e-table-scrolled.h> -#include "widgets/misc/e-dateedit.h" +#include <gal/widgets/e-unicode.h> + +#include "e-contact-list-editor.h" +#include "e-contact-list-model.h" /* Signal IDs */ enum { @@ -46,10 +47,14 @@ static void create_ui (EContactListEditor *ce); static void set_editable (EContactListEditor *editor); static void command_state_changed (EContactListEditor *editor); static void close_dialog (EContactListEditor *cle); +static void extract_info(EContactListEditor *editor); +static void fill_in_info(EContactListEditor *editor); static void add_email_cb (GtkWidget *w, EContactListEditor *editor); static void remove_entry_cb (GtkWidget *w, EContactListEditor *editor); static void list_name_changed_cb (GtkWidget *w, EContactListEditor *editor); +static void visible_addrs_toggled_cb (GtkWidget *w, EContactListEditor *editor); + static gint app_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data); static gboolean table_drag_drop_cb (ETable *table, int row, int col, GdkDragContext *context, gint x, gint y, guint time, EContactListEditor *editor); @@ -203,12 +208,17 @@ e_contact_list_editor_init (EContactListEditor *editor) editor->gui = gui; editor->app = glade_xml_get_widget (gui, "contact list editor"); + editor->table = glade_xml_get_widget (gui, "contact-list-table"); + editor->model = gtk_object_get_data (GTK_OBJECT(editor->table), "model"); + editor->add_button = glade_xml_get_widget (editor->gui, "add-email-button"); editor->remove_button = glade_xml_get_widget (editor->gui, "remove-button"); - editor->email_entry =glade_xml_get_widget (gui, "email-entry"); - editor->list_name_entry =glade_xml_get_widget (gui, "list-name-entry"); - editor->model = gtk_object_get_data (GTK_OBJECT(editor->table), "model"); + + editor->email_entry = glade_xml_get_widget (gui, "email-entry"); + editor->list_name_entry = glade_xml_get_widget (gui, "list-name-entry"); + + editor->visible_addrs_checkbutton = glade_xml_get_widget (gui, "visible-addrs-checkbutton"); /* Construct the app */ bonobo_win = bonobo_window_new ("contact-list-editor", "Contact List Editor"); @@ -255,6 +265,8 @@ e_contact_list_editor_init (EContactListEditor *editor) "clicked", GTK_SIGNAL_FUNC(remove_entry_cb), editor); gtk_signal_connect (GTK_OBJECT(editor->list_name_entry), "changed", GTK_SIGNAL_FUNC(list_name_changed_cb), editor); + gtk_signal_connect (GTK_OBJECT(editor->visible_addrs_checkbutton), + "toggled", GTK_SIGNAL_FUNC(visible_addrs_toggled_cb), editor); e_table_drag_dest_set (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)), 0, drag_types, num_drag_types, GDK_ACTION_LINK); @@ -279,22 +291,95 @@ e_contact_list_editor_destroy (GtkObject *object) { } +typedef struct { + EContactListEditor *cle; + gboolean should_close; +} EditorCloseStruct; + +static void +list_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruct *ecs) +{ + EContactListEditor *cle = ecs->cle; + gboolean should_close = ecs->should_close; + + g_free (ecs); + + gtk_signal_emit (GTK_OBJECT (cle), contact_list_editor_signals[LIST_ADDED], + status, cle->card); + + if (status == E_BOOK_STATUS_SUCCESS) { + cle->is_new_list = FALSE; + + if (should_close) + close_dialog (cle); + } +} + +static void +list_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs) +{ + EContactListEditor *cle = ecs->cle; + gboolean should_close = ecs->should_close; + + g_free (ecs); + + gtk_signal_emit (GTK_OBJECT (cle), contact_list_editor_signals[LIST_MODIFIED], + status, cle->card); + + if (status == E_BOOK_STATUS_SUCCESS) { + if (should_close) + close_dialog (cle); + } +} + +static void +save_card (EContactListEditor *cle, gboolean should_close) +{ + extract_info (cle); + + if (cle->book) { + EditorCloseStruct *ecs = g_new(EditorCloseStruct, 1); + + ecs->cle = cle; + ecs->should_close = should_close; + + if (cle->is_new_list) + e_book_add_card (cle->book, cle->card, GTK_SIGNAL_FUNC(list_added_cb), ecs); + else + e_book_commit_card (cle->book, cle->card, GTK_SIGNAL_FUNC(list_modified_cb), ecs); + } +} + /* File/Close callback */ static void file_close_cb (GtkWidget *widget, gpointer data) { - EContactListEditor *cle; + EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data); - cle = E_CONTACT_LIST_EDITOR (data); close_dialog (cle); } +static void +file_save_cb (GtkWidget *widget, gpointer data) +{ + EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data); + + save_card (cle, FALSE); +} + +static void +tb_save_and_close_cb (GtkWidget *widget, gpointer data) +{ + EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data); + save_card (cle, TRUE); +} + static BonoboUIVerb verbs [] = { + BONOBO_UI_UNSAFE_VERB ("ContactListEditorSave", file_save_cb), + BONOBO_UI_UNSAFE_VERB ("ContactListEditorSaveClose", tb_save_and_close_cb), #if 0 - BONOBO_UI_UNSAFE_VERB ("ContactEditorSave", file_save_cb), BONOBO_UI_UNSAFE_VERB ("ContactEditorSaveAs", file_save_as_cb), - BONOBO_UI_UNSAFE_VERB ("ContactEditorSaveClose", tb_save_and_close_cb), BONOBO_UI_UNSAFE_VERB ("ContactEditorSendAs", file_send_as_cb), BONOBO_UI_UNSAFE_VERB ("ContactEditorSendTo", file_send_to_cb), BONOBO_UI_UNSAFE_VERB ("ContactEditorDelete", delete_cb), @@ -353,9 +438,7 @@ e_contact_list_editor_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) if (editor->card) gtk_object_unref(GTK_OBJECT(editor->card)); editor->card = e_card_duplicate(E_CARD(GTK_VALUE_OBJECT (*arg))); -#if 0 fill_in_info(editor); -#endif editor->changed = FALSE; break; @@ -399,10 +482,7 @@ e_contact_list_editor_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) break; case ARG_CARD: -#if 0 - e_card_simple_sync_card(editor->simple); extract_info(editor); -#endif GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(editor->card); break; @@ -436,10 +516,10 @@ e_contact_list_editor_raise (EContactListEditor *editor) } #define SPEC "<ETableSpecification no-headers=\"true\" cursor-mode=\"line\" selection-mode=\"single\"> \ - <ETableColumn model_col= \"0\" _title=\"Contact\" expansion=\"1.0\" minimum_width=\"20\" resizable=\"true\" cell=\"string\" compare=\"string\"/> \ + <ETableColumn model_col= \"0\" _title=\"Contact\" expansion=\"1.0\" minimum_width=\"20\" resizable=\"true\" cell=\"string\" compare=\"string\" /> \ <ETableState> \ <column source=\"0\"/> \ - <grouping> <leaf column=\"0\" ascending=\"true\"/> </grouping> \ + <grouping> </grouping> \ </ETableState> \ </ETableSpecification>" @@ -505,6 +585,15 @@ list_name_changed_cb (GtkWidget *w, EContactListEditor *editor) } static void +visible_addrs_toggled_cb (GtkWidget *w, EContactListEditor *editor) +{ + if (!editor->changed) { + editor->changed = TRUE; + command_state_changed (editor); + } +} + +static void set_editable (EContactListEditor *editor) { gtk_widget_set_sensitive (editor->email_entry, editor->editable); @@ -623,3 +712,99 @@ command_state_changed (EContactListEditor *editor) "sensitive", editor->editable && !editor->is_new_list ? "1" : "0", NULL); } + +static void +extract_info(EContactListEditor *editor) +{ + ECard *card = editor->card; + if (card) { + int i; + EList *email_list; + char *string = e_utf8_gtk_editable_get_chars(GTK_EDITABLE (editor->list_name_entry), 0, -1); + + if (string && *string) + gtk_object_set(GTK_OBJECT(card), + "file_as", string, + "full_name", string, + NULL); + + g_free (string); + + + gtk_object_set (GTK_OBJECT(card), + "evolution_list", GINT_TO_POINTER (TRUE), + "evolution_list_show_addresses", + GINT_TO_POINTER (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->visible_addrs_checkbutton))), + NULL); + + gtk_object_get (GTK_OBJECT(card), + "email", &email_list, + NULL); + + for (i = 0; i < e_table_model_row_count (editor->model); i ++) { + char *email = e_contact_list_model_get_email (E_CONTACT_LIST_MODEL(editor->model), i); + e_list_append (email_list, email); + g_free (email); + } + } +} + +static void +fill_in_info(EContactListEditor *editor) +{ + if (editor->card) { + char *file_as; + gboolean show_addresses = FALSE; + gboolean is_evolution_list = FALSE; + EList *email_list; + EIterator *email_iter; + + gtk_object_get (GTK_OBJECT (editor->card), + "file_as", &file_as, + "email", &email_list, + "evolution_list", &is_evolution_list, + "evolution_list_show_addresses", &show_addresses, + NULL); + + if (!editor->is_new_list && !is_evolution_list) { + g_warning ("Attempting to edit non-list card in the list editor.\n"); + return; + } + + gtk_editable_delete_text (GTK_EDITABLE (editor->list_name_entry), 0, -1); + if (file_as) { + int position = 0; + gchar *u = e_utf8_to_gtk_string (editor->list_name_entry, file_as); + gtk_editable_insert_text (GTK_EDITABLE (editor->list_name_entry), u, strlen (u), &position); + g_free (u); + } + + e_contact_list_model_remove_all (E_CONTACT_LIST_MODEL (editor->model)); + + email_iter = e_list_get_iterator (email_list); + + while (e_iterator_is_valid (email_iter)) { + const char *email = e_iterator_get (email_iter); + + if (!strncmp (email, "X-EVOLUTION-UID=", strlen ("X-EVOLUTION-UID"))) { + ECard *card; + const char *uid; + /* it's a serialized uid */ + uid = email + strlen ("X-EVOLUTION-UID="); + card = e_book_get_card (editor->book, uid); + if (card) { + ECardSimple *simple = e_card_simple_new (card); + gtk_object_unref (GTK_OBJECT (card)); + e_contact_list_model_add_card (E_CONTACT_LIST_MODEL (editor->model), + simple); + } + } + else { + e_contact_list_model_add_email (E_CONTACT_LIST_MODEL (editor->model), + email); + } + + e_iterator_next (email_iter); + } + } +} diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.h b/addressbook/gui/contact-list-editor/e-contact-list-editor.h index c697275f43..4aba6668f8 100644 --- a/addressbook/gui/contact-list-editor/e-contact-list-editor.h +++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.h @@ -66,6 +66,7 @@ struct _EContactListEditor GtkWidget *list_name_entry; GtkWidget *add_button; GtkWidget *remove_button; + GtkWidget *visible_addrs_checkbutton; /* Whether we are editing a new card or an existing one */ guint is_new_list : 1; diff --git a/addressbook/gui/contact-list-editor/e-contact-list-model.c b/addressbook/gui/contact-list-editor/e-contact-list-model.c index abc963b198..4e5a336e07 100644 --- a/addressbook/gui/contact-list-editor/e-contact-list-model.c +++ b/addressbook/gui/contact-list-editor/e-contact-list-model.c @@ -20,7 +20,7 @@ static int contact_list_row_count (ETableModel *etc) { EContactListModel *model = E_CONTACT_LIST_MODEL (etc); - return model->simple_count + model->email_count; + return model->data_count; } /* This function returns the value at a particular point in our ETableModel. */ @@ -29,10 +29,7 @@ contact_list_value_at (ETableModel *etc, int col, int row) { EContactListModel *model = E_CONTACT_LIST_MODEL (etc); - if (row < model->simple_count) - return model->simples[row]->string; - else - return model->emails [row - model->simple_count]; + return model->data[row]->string; } /* This function sets the value at a particular point in our ETableModel. */ @@ -87,18 +84,16 @@ contact_list_model_destroy (GtkObject *o) EContactListModel *model = E_CONTACT_LIST_MODEL (o); int i; - for (i = 0; i < model->simple_count; i ++) { - g_free (model->simples[i]->string); - gtk_object_unref (GTK_OBJECT(model->simples[i]->simple)); - g_free (model->simples[i]); + for (i = 0; i < model->data_count; i ++) { + g_free (model->data[i]->string); + if (model->data[i]->simple) + gtk_object_unref (GTK_OBJECT(model->data[i]->simple)); + g_free (model->data[i]); } - g_free (model->simples); - model->simple_count = 0; + g_free (model->data); - for (i = 0; i < model->email_count; i ++) - g_free (model->emails[i]); - g_free (model->emails); - model->email_count = 0; + model->data_count = 0; + model->data_alloc = 0; } static void @@ -127,13 +122,9 @@ e_contact_list_model_init (GtkObject *object) { EContactListModel *model = E_CONTACT_LIST_MODEL(object); - model->simple_alloc = 10; - model->simples = g_new (SimpleAndString*, model->simple_alloc); - model->simple_count = 0; - - model->email_alloc = 10; - model->emails = g_new (char*, model->email_alloc); - model->email_count = 0; + model->data_alloc = 10; + model->data_count = 0; + model->data = g_new (EContactListModelRow*, model->data_alloc); } GtkType @@ -180,12 +171,20 @@ void e_contact_list_model_add_email (EContactListModel *model, const char *email) { - if (model->email_count + 1 >= model->email_alloc) { - model->email_alloc *= 2; - model->emails = g_renew (char*, model->emails, model->email_alloc); + EContactListModelRow *new_row; + + if (model->data_count + 1 >= model->data_alloc) { + model->data_alloc *= 2; + model->data = g_renew (EContactListModelRow*, model->data, model->data_alloc); } - model->emails[model->email_count ++] = g_strdup (email); + new_row = g_new (EContactListModelRow, 1); + new_row->type = E_CONTACT_LIST_MODEL_ROW_EMAIL; + new_row->simple = NULL; + new_row->string = g_strdup (email); + + model->data[model->data_count ++] = new_row; + e_table_model_changed (E_TABLE_MODEL (model)); } @@ -193,6 +192,7 @@ void e_contact_list_model_add_card (EContactListModel *model, ECardSimple *simple) { + EContactListModelRow *new_row; char *email, *name; name = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_NAME_OR_ORG); @@ -204,19 +204,23 @@ e_contact_list_model_add_card (EContactListModel *model, } - if (model->simple_count + 1 >= model->simple_alloc) { - model->simple_alloc *= 2; - model->simples = g_renew (SimpleAndString*, model->simples, model->simple_alloc); + if (model->data_count + 1 >= model->data_alloc) { + model->data_alloc *= 2; + model->data = g_renew (EContactListModelRow*, model->data, model->data_alloc); } - model->simples[model->simple_count] = g_new (SimpleAndString, 1); + new_row = g_new (EContactListModelRow, 1); - model->simples[model->simple_count]->simple = simple; - model->simples[model->simple_count]->string = g_strconcat (name ? name : "", - email ? " <" : "", email ? email : "", email ? ">" : "", - NULL); + new_row->type = E_CONTACT_LIST_MODEL_ROW_CARD; + new_row->simple = simple; + if (FALSE /* XXX e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_EVOLUTION_LIST)*/) + new_row->string = g_strconcat ("<", name, ">", NULL); + else + new_row->string = g_strconcat (name ? name : "", + email ? " <" : "", email ? email : "", email ? ">" : "", + NULL); - model->simple_count++; + model->data[model->data_count++] = new_row; gtk_object_ref (GTK_OBJECT (simple)); @@ -226,17 +230,42 @@ e_contact_list_model_add_card (EContactListModel *model, void e_contact_list_model_remove_row (EContactListModel *model, int row) { - if (row < model->simple_count) { - g_free (model->simples[row]->string); - gtk_object_unref (GTK_OBJECT(model->simples[row]->simple)); - g_free (model->simples[row]); - memcpy (model->simples + row, model->simples + row + 1, model->simple_count - row); - model->simple_count --; - } - else { - int email_row = row - model->simple_count; - memcpy (model->emails + email_row, model->emails + email_row + 1, model->email_count - email_row); - model->email_count --; + g_free (model->data[row]->string); + if (model->data[row]->simple) + gtk_object_unref (GTK_OBJECT(model->data[row]->simple)); + g_free (model->data[row]); + memmove (model->data + row, model->data + row + 1, sizeof (EContactListModelRow*) * (model->data_count - row - 1)); + model->data_count --; + + e_table_model_changed (E_TABLE_MODEL (model)); +} + +void +e_contact_list_model_remove_all (EContactListModel *model) +{ + int i; + + for (i = 0; i < model->data_count; i ++) { + g_free (model->data[i]->string); + if (model->data[i]->simple) + gtk_object_unref (GTK_OBJECT(model->data[i]->simple)); + g_free (model->data[i]); + model->data[i] = NULL; } - e_table_model_row_deleted (E_TABLE_MODEL (model), row); + + model->data_count = 0; + + e_table_model_changed (E_TABLE_MODEL (model)); +} + + +char* +e_contact_list_model_get_email (EContactListModel *model, int row) +{ + EContactListModelRow *data = model->data[row]; + + if (data->type == E_CONTACT_LIST_MODEL_ROW_EMAIL) + return g_strdup (data->string); + else + return g_strconcat ("|X-EVOLUTION-UID=", e_card_simple_get_id (data->simple), NULL); } diff --git a/addressbook/gui/contact-list-editor/e-contact-list-model.h b/addressbook/gui/contact-list-editor/e-contact-list-model.h index 8665245501..7b1e092944 100644 --- a/addressbook/gui/contact-list-editor/e-contact-list-model.h +++ b/addressbook/gui/contact-list-editor/e-contact-list-model.h @@ -16,20 +16,23 @@ typedef struct _EContactListModel EContactListModel; typedef struct _EContactListModelClass EContactListModelClass; +typedef enum { + E_CONTACT_LIST_MODEL_ROW_EMAIL, + E_CONTACT_LIST_MODEL_ROW_CARD, +} EContactListModelRowType; + typedef struct { + EContactListModelRowType type; ECardSimple *simple; - char *string; -} SimpleAndString; + char *string; +} EContactListModelRow; struct _EContactListModel { ETableModel parent; - SimpleAndString **simples; - int simple_count; - int simple_alloc; - char **emails; - int email_count; - int email_alloc; + EContactListModelRow **data; + int data_count; + int data_alloc; }; @@ -42,8 +45,11 @@ GtkType e_contact_list_model_get_type (void); void e_contact_list_model_construct (EContactListModel *model); ETableModel *e_contact_list_model_new (void); -void e_contact_list_model_add_email (EContactListModel *model, const char *email); -void e_contact_list_model_add_card (EContactListModel *model, ECardSimple *simple); +void e_contact_list_model_add_email (EContactListModel *model, const char *email); +void e_contact_list_model_add_card (EContactListModel *model, ECardSimple *simple); void e_contact_list_model_remove_row (EContactListModel *model, int row); +void e_contact_list_model_remove_all (EContactListModel *model); +char *e_contact_list_model_get_row (EContactListModel *model, ECardSimple *simple); +char *e_contact_list_model_get_email (EContactListModel *model, int row); #endif /* _E_CONTACT_LIST_MODEL_H_ */ |