diff options
-rw-r--r-- | addressbook/ChangeLog | 63 | ||||
-rw-r--r-- | addressbook/backend/ebook/e-book-util.c | 55 | ||||
-rw-r--r-- | addressbook/backend/ebook/e-book-util.h | 2 | ||||
-rw-r--r-- | addressbook/gui/component/addressbook-component.c | 48 | ||||
-rw-r--r-- | addressbook/gui/component/addressbook.c | 11 | ||||
-rw-r--r-- | addressbook/gui/component/select-names/e-select-names-completion.c | 54 | ||||
-rw-r--r-- | addressbook/gui/component/select-names/e-select-names-completion.h | 3 | ||||
-rw-r--r-- | addressbook/gui/component/select-names/e-select-names-manager.c | 115 | ||||
-rw-r--r-- | addressbook/gui/component/select-names/e-select-names-manager.h | 2 |
9 files changed, 281 insertions, 72 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index 189c8529a8..8907fad318 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,66 @@ +2002-05-24 Chris Toshok <toshok@ximian.com> + + [ #24189 ] + * gui/component/select-names/e-select-names-manager.c + (focus_out_cb): ifdef out the body of this because it only works + with a single completion book. not sure what to do here, but it + doesn't impact most usage scenarios. + (completion_popup_cb): same. + (e_select_names_manager_entry_new): add the books that have been + loaded successfully by the time this entry is created. + (open_book_cb): add the opened book to the entries that have + already been created, and store it in our list so that entries + that are created in the future can catch up. + (read_completion_books_from_db): slurp in the folder list from the + config db and load all the uris. + (uris_listener): listener function - when there's a change it + calls _clear_books on all the created entries, and clears our + list. It then re-reads the books from the db. + (e_select_names_manager_new): create our bonobo listener and call + read_completion_books_from_db. + (e_select_names_manager_init): init completion_books. + (e_select_names_manager_destroy): free our list of + completion_books. + + * gui/component/select-names/e-select-names-manager.h: switch from + a single EBook to a GList of completion_books here. + + * gui/component/select-names/e-select-names-completion.c + (e_select_names_completion_add_book): deal with the case where + there's an active query (by effectively restarting it.) This is + quite a contrived edge case. + (e_select_names_completion_clear_books): stop the current query + and clear our list of books. + (e_select_names_completion_new): track change to prototype, and + axe the majority of this method since an EBook* isn't passed + anymore. + (e_select_names_completion_clear_book_data): split this code out + from the destroy method so it can be called from _clear_books. + + * gui/component/select-names/e-select-names-completion.h: the + constructor no longer takes an EBook -- pass in as many as you + want using _add_book. Also, add prototype for _clear_books. + + * gui/component/addressbook.c (load_uri_cb): when + storing/retrieving passwords, use the cleaned (without params) + version of the uri, so changing things like download limit don't + cause the user to be prompted for a password again. + + * gui/component/addressbook-component.c + (ensure_completion_uris_exist): new function - probably doesn't + belong in this file. Make sure the basic local Contacts folder + exists in the completion uris. + (addressbook_component_factory_init): call + ensure_completion_uris_exist. + + * backend/ebook/e-book-util.h: add prototype for + e_book_get_default_book_uri. + + * backend/ebook/e-book-util.c (e_book_get_default_book_uri): new + function, just return the default contacts uri. + (e_book_load_default_book): change + to use e_book_get_default_book_uri. + 2002-05-23 Chris Toshok <toshok@ximian.com> * gui/component/addressbook-config.c (addressbook_root_dse_query): diff --git a/addressbook/backend/ebook/e-book-util.c b/addressbook/backend/ebook/e-book-util.c index d3de9840f8..62694a8563 100644 --- a/addressbook/backend/ebook/e-book-util.c +++ b/addressbook/backend/ebook/e-book-util.c @@ -242,44 +242,55 @@ e_book_default_book_open (EBook *book, EBookStatus status, gpointer closure) gboolean e_book_load_default_book (EBook *book, EBookCallback open_response, gpointer closure) { - char *val, *uri; + char *uri; gboolean rv; - CORBA_Environment ev; - Bonobo_ConfigDatabase config_db; + DefaultBookClosure *default_book_closure; g_return_val_if_fail (book != NULL, FALSE); g_return_val_if_fail (E_IS_BOOK (book), FALSE); g_return_val_if_fail (open_response != NULL, FALSE); + uri = e_book_get_default_book_uri (); + + default_book_closure = g_new (DefaultBookClosure, 1); + + default_book_closure->closure = closure; + default_book_closure->open_response = open_response; + + rv = e_book_load_uri (book, uri, + e_book_default_book_open, default_book_closure); + g_free (uri); + + if (!rv) { + g_warning ("Couldn't load default addressbook"); + } + + return rv; +} + +char* +e_book_get_default_book_uri () +{ + CORBA_Environment ev; + char *val, *uri; + Bonobo_ConfigDatabase config_db; + CORBA_exception_init (&ev); config_db = e_book_get_config_database (&ev); val = bonobo_config_get_string (config_db, "/DefaultFolders/contacts_uri", &ev); CORBA_exception_free (&ev); if (val) { - DefaultBookClosure *default_book_closure = g_new (DefaultBookClosure, 1); - default_book_closure->closure = closure; - default_book_closure->open_response = open_response; - - /* Sigh. FIXME. */ - if (!strncmp (val, "file:", 5)) - uri = g_strconcat (val, "/addressbook.db", NULL); - else - uri = g_strdup (val); - rv = e_book_load_uri (book, uri, - e_book_default_book_open, default_book_closure); - g_free (uri); - g_free (val); + uri = val; } else { - rv = e_book_load_local_address_book (book, open_response, closure); - } - - if (!rv) { - g_warning ("Couldn't load default addressbook"); + char *filename; + filename = gnome_util_prepend_user_home ("evolution/local/Contacts/addressbook.db"); + uri = g_strdup_printf ("file://%s", filename); + g_free (filename); } - return rv; + return uri; } /* diff --git a/addressbook/backend/ebook/e-book-util.h b/addressbook/backend/ebook/e-book-util.h index 33f90c399f..fe80b7e02c 100644 --- a/addressbook/backend/ebook/e-book-util.h +++ b/addressbook/backend/ebook/e-book-util.h @@ -42,6 +42,7 @@ typedef void (*EBookHaveAddressCallback) (EBook *book, const gchar *addr, ECard /* expand file:///foo/foo/ to file:///foo/foo/addressbook.db */ char *e_book_expand_uri (const char *uri); + gboolean e_book_load_address_book_by_uri (EBook *book, const char *uri, EBookCallback open_response, @@ -58,6 +59,7 @@ void e_book_use_local_address_book (EBookCommonCallback gboolean e_book_load_default_book (EBook *book, EBookCallback open_response, gpointer closure); +char *e_book_get_default_book_uri (void); /* Bonoboconf database interface. */ Bonobo_ConfigDatabase e_book_get_config_database (CORBA_Environment *ev); diff --git a/addressbook/gui/component/addressbook-component.c b/addressbook/gui/component/addressbook-component.c index 54940faeab..ed135f98db 100644 --- a/addressbook/gui/component/addressbook-component.c +++ b/addressbook/gui/component/addressbook-component.c @@ -39,6 +39,7 @@ #include "evolution-shell-component.h" #include "evolution-shell-component-dnd.h" #include "evolution-storage.h" +#include "e-folder-list.h" #include "ebook/e-book.h" #include "ebook/e-card.h" @@ -590,6 +591,48 @@ create_component (void) return BONOBO_OBJECT (shell_component); } +static void +ensure_completion_uris_exist() +{ + /* Initialize the completion uris if they aren't set yet. The + default set is just the local Contacts folder. */ + Bonobo_ConfigDatabase db; + CORBA_Environment ev; + char *val; + + CORBA_exception_init (&ev); + + db = addressbook_config_database (&ev); + + val = bonobo_config_get_string (db, "/Addressbook/Completion/uris", &ev); + + if (!val) { + EFolderListItem f[2]; + char *dirname, *uri; + /* in the case where the user is running for the first + time, populate the list with the local contact + folder */ + dirname = gnome_util_prepend_user_home("evolution/local/Contacts"); + uri = g_strdup_printf ("file://%s", dirname); + + f[0].uri = "evolution:/local/Contacts"; + f[0].physical_uri = uri; + f[0].display_name = _("Contacts"); + + memset (&f[1], 0, sizeof (f[1])); + + val = e_folder_list_create_xml (f); + + g_free (dirname); + g_free (uri); + bonobo_config_set_string (db, "/Addressbook/Completion/uris", val, &ev); + + g_free (val); + } + + CORBA_exception_free (&ev); +} + /* FIXME this should probably be renamed as we don't use factories anymore. */ void @@ -606,4 +649,9 @@ addressbook_component_factory_init (void) bonobo_object_corba_objref (object)); if (result == OAF_REG_ERROR) g_error ("Cannot register -- %s", GNOME_EVOLUTION_ADDRESSBOOK_COMPONENT_ID); + + /* XXX this could probably go someplace else, but I'll leave + it here for now since it's a component init time + operation. */ + ensure_completion_uris_exist (); } diff --git a/addressbook/gui/component/addressbook.c b/addressbook/gui/component/addressbook.c index b74b946098..8c585917d4 100644 --- a/addressbook/gui/component/addressbook.c +++ b/addressbook/gui/component/addressbook.c @@ -632,8 +632,13 @@ load_uri_cb (EBook *book, EBookStatus status, gpointer closure) source->auth != ADDRESSBOOK_LDAP_AUTH_NONE) { const char *password; char *pass_dup = NULL; + char *uri = g_strdup (e_book_get_uri (book)); + char *semicolon = strchr (uri, ';'); - password = e_passwords_get_password (e_book_get_uri (book)); + if (semicolon) + *semicolon = '\0'; + + password = e_passwords_get_password (uri); if (!password) { char *prompt; @@ -647,7 +652,7 @@ load_uri_cb (EBook *book, EBookStatus status, gpointer closure) source->name, source->email_addr); remember = source->remember_passwd; pass_dup = e_passwords_ask_password ( - prompt, e_book_get_uri (book), prompt, TRUE, + prompt, uri, prompt, TRUE, E_PASSWORDS_REMEMBER_FOREVER, &remember, NULL); if (remember != source->remember_passwd) { @@ -657,6 +662,8 @@ load_uri_cb (EBook *book, EBookStatus status, gpointer closure) g_free (prompt); } + g_free (uri); + if (password || pass_dup) { char *user; 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 cbfc1d56c6..7b29cd2472 100644 --- a/addressbook/gui/component/select-names/e-select-names-completion.c +++ b/addressbook/gui/component/select-names/e-select-names-completion.c @@ -734,14 +734,10 @@ e_select_names_completion_init (ESelectNamesCompletion *comp) } static void -e_select_names_completion_destroy (GtkObject *object) +e_select_names_completion_clear_book_data (ESelectNamesCompletion *comp) { - ESelectNamesCompletion *comp = E_SELECT_NAMES_COMPLETION (object); GList *l; - if (comp->priv->text_model) - gtk_object_unref (GTK_OBJECT (comp->priv->text_model)); - for (l = comp->priv->book_data; l; l = l->next) { ESelectNamesCompletionBookData *book_data = l->data; @@ -763,6 +759,17 @@ e_select_names_completion_destroy (GtkObject *object) g_free (book_data); } g_list_free (comp->priv->book_data); +} + +static void +e_select_names_completion_destroy (GtkObject *object) +{ + ESelectNamesCompletion *comp = E_SELECT_NAMES_COMPLETION (object); + + if (comp->priv->text_model) + gtk_object_unref (GTK_OBJECT (comp->priv->text_model)); + + e_select_names_completion_clear_book_data (comp); g_free (comp->priv->waiting_query); g_free (comp->priv->query_text); @@ -1227,33 +1234,14 @@ e_select_names_completion_book_ready (EBook *book, EBookStatus status, ESelectNa */ ECompletion * -e_select_names_completion_new (EBook *book, ESelectNamesTextModel *text_model) +e_select_names_completion_new (ESelectNamesTextModel *text_model) { ESelectNamesCompletion *comp; - g_return_val_if_fail (book == NULL || E_IS_BOOK (book), NULL); g_return_val_if_fail (E_IS_SELECT_NAMES_TEXT_MODEL (text_model), NULL); comp = (ESelectNamesCompletion *) gtk_type_new (e_select_names_completion_get_type ()); - if (book == NULL) { - ESelectNamesCompletionBookData *book_data = g_new0 (ESelectNamesCompletionBookData, 1); - - book_data->book = e_book_new (); - book_data->comp = comp; - gtk_object_ref (GTK_OBJECT (book_data->book)); - gtk_object_sink (GTK_OBJECT (book_data->book)); - - comp->priv->book_data = g_list_append (comp->priv->book_data, book_data); - comp->priv->books_not_ready++; - - gtk_object_ref (GTK_OBJECT (comp)); /* ref ourself before our async call */ - e_book_load_local_address_book (book_data->book, (EBookCallback) e_select_names_completion_book_ready, comp); - - } else { - e_select_names_completion_add_book (comp, book); - } - comp->priv->text_model = text_model; gtk_object_ref (GTK_OBJECT (text_model)); @@ -1273,6 +1261,22 @@ e_select_names_completion_add_book (ESelectNamesCompletion *comp, EBook *book) check_capabilities (comp, book); gtk_object_ref (GTK_OBJECT (book_data->book)); comp->priv->book_data = g_list_append (comp->priv->book_data, book_data); + + /* if the user is typing as we're adding books, restart the + query after the new book has been added */ + if (comp->priv->query_text && *comp->priv->query_text) { + char *query_text = g_strdup (comp->priv->query_text); + e_select_names_completion_stop_query (comp); + e_select_names_completion_start_query (comp, query_text); + g_free (query_text); + } +} + +void +e_select_names_completion_clear_books (ESelectNamesCompletion *comp) +{ + e_select_names_completion_stop_query (comp); + e_select_names_completion_clear_book_data (comp); } gboolean diff --git a/addressbook/gui/component/select-names/e-select-names-completion.h b/addressbook/gui/component/select-names/e-select-names-completion.h index 86522fa5ce..ae5a8db471 100644 --- a/addressbook/gui/component/select-names/e-select-names-completion.h +++ b/addressbook/gui/component/select-names/e-select-names-completion.h @@ -56,8 +56,9 @@ struct _ESelectNamesCompletionClass { GtkType e_select_names_completion_get_type (void); -ECompletion *e_select_names_completion_new (EBook *, ESelectNamesTextModel *); +ECompletion *e_select_names_completion_new (ESelectNamesTextModel *); void e_select_names_completion_add_book (ESelectNamesCompletion *, EBook *); +void e_select_names_completion_clear_books (ESelectNamesCompletion *); gboolean e_select_names_completion_get_match_contact_lists (ESelectNamesCompletion *); void e_select_names_completion_set_match_contact_lists (ESelectNamesCompletion *, gboolean); 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 53978ac502..29de56cb1a 100644 --- a/addressbook/gui/component/select-names/e-select-names-manager.c +++ b/addressbook/gui/component/select-names/e-select-names-manager.c @@ -15,12 +15,14 @@ #include <gal/e-text/e-entry.h> +#include <libgnome/gnome-i18n.h> #include "e-select-names-manager.h" #include "e-select-names-model.h" #include "e-select-names-text-model.h" #include "e-select-names.h" #include "e-select-names-completion.h" #include "e-select-names-popup.h" +#include "e-folder-list.h" #include <addressbook/backend/ebook/e-destination.h> #include <addressbook/gui/component/addressbook.h> #include <bonobo-conf/bonobo-config-database.h> @@ -51,6 +53,7 @@ typedef struct { EEntry *entry; ESelectNamesManager *manager; ESelectNamesModel *model; + ECompletion *comp; guint cleaning_tag; } ESelectNamesManagerEntry; @@ -175,6 +178,8 @@ focus_in_cb (GtkWidget *w, GdkEventFocus *ev, gpointer user_data) static gint focus_out_cb (GtkWidget *w, GdkEventFocus *ev, gpointer user_data) { +#if 0 + /* XXX fix me */ ESelectNamesManagerEntry *entry = user_data; gboolean visible = e_entry_completion_popup_is_visible (entry->entry); @@ -183,17 +188,20 @@ focus_out_cb (GtkWidget *w, GdkEventFocus *ev, gpointer user_data) if (entry->cleaning_tag == 0) entry->cleaning_tag = gtk_timeout_add (100, clean_cb, entry); } - +#endif return FALSE; } static void completion_popup_cb (EEntry *w, gint visible, gpointer user_data) { +#if 0 + /* XXX fix me */ ESelectNamesManagerEntry *entry = user_data; if (!visible && !GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (entry->entry->canvas))) e_select_names_model_cardify_all (entry->model, entry->manager->completion_book, 0); +#endif } static void @@ -232,7 +240,7 @@ e_select_names_manager_entry_new (ESelectNamesManager *manager, ESelectNamesMode { ESelectNamesManagerEntry *entry; ETextModel *text_model; - ECompletion *comp; + GList *l; g_return_val_if_fail (E_IS_SELECT_NAMES_MANAGER (manager), NULL); g_return_val_if_fail (E_IS_SELECT_NAMES_MODEL (model), NULL); @@ -252,13 +260,15 @@ e_select_names_manager_entry_new (ESelectNamesManager *manager, ESelectNamesMode gtk_object_ref (GTK_OBJECT (entry->entry)); - comp = e_select_names_completion_new (NULL, E_SELECT_NAMES_TEXT_MODEL (text_model)); - if (manager->completion_book) - e_select_names_completion_add_book (E_SELECT_NAMES_COMPLETION (comp), - manager->completion_book); + entry->comp = e_select_names_completion_new (E_SELECT_NAMES_TEXT_MODEL (text_model)); - e_entry_enable_completion_full (entry->entry, comp, 50, completion_handler); + for (l = manager->completion_books; l; l = l->next) { + EBook *book = l->data; + e_select_names_completion_add_book (E_SELECT_NAMES_COMPLETION(entry->comp), book); + } + e_entry_enable_completion_full (entry->entry, entry->comp, 50, completion_handler); + entry->manager = manager; entry->model = model; @@ -287,7 +297,7 @@ e_select_names_manager_entry_new (ESelectNamesManager *manager, ESelectNamesMode gtk_object_set_data (GTK_OBJECT (entry->entry), "entry_info", entry); gtk_object_set_data (GTK_OBJECT (entry->entry), "select_names_model", model); gtk_object_set_data (GTK_OBJECT (entry->entry), "select_names_text_model", text_model); - gtk_object_set_data (GTK_OBJECT (entry->entry), "completion_handler", comp); + gtk_object_set_data (GTK_OBJECT (entry->entry), "completion_handler", entry->comp); return entry; } @@ -359,14 +369,77 @@ e_select_names_manager_discard_saved_models (ESelectNamesManager *manager) static void open_book_cb (EBook *book, EBookStatus status, ESelectNamesManager *manager) { - if (status != E_BOOK_STATUS_SUCCESS) { + if (status == E_BOOK_STATUS_SUCCESS) { + GList *l; + for (l = manager->entries; l; l = l->next) { + ESelectNamesManagerEntry *entry = l->data; + e_select_names_completion_add_book (E_SELECT_NAMES_COMPLETION(entry->comp), book); + } + + manager->completion_books = g_list_append (manager->completion_books, book); + } + else { gtk_object_unref (GTK_OBJECT (book)); - manager->completion_book = NULL; } gtk_object_unref (GTK_OBJECT (manager)); /* unref ourself (matches ref before the load_uri call below) */ } +static void +read_completion_books_from_db (ESelectNamesManager *manager) +{ + Bonobo_ConfigDatabase db; + CORBA_Environment ev; + char *val; + + CORBA_exception_init (&ev); + + db = addressbook_config_database (&ev); + + val = bonobo_config_get_string (db, "/Addressbook/Completion/uris", &ev); + + CORBA_exception_free (&ev); + + if (val) { + EFolderListItem *folders = e_folder_list_parse_xml (val); + EFolderListItem *f; + + for (f = folders; f && f->physical_uri; f++) { + char *uri; + EBook *book = e_book_new (); + gtk_object_ref (GTK_OBJECT (manager)); /* ref ourself before our async call */ + + if (!strncmp (f->physical_uri, "file:", 5)) + uri = g_strdup_printf ("%s/addressbook.db", f->physical_uri); + else + uri = g_strdup (f->physical_uri); + addressbook_load_uri (book, uri, (EBookCallback)open_book_cb, manager); + } + e_folder_list_free_items (folders); + + g_free (val); + } +} + +static void +uris_listener (BonoboListener *listener, char *event_name, + CORBA_any *any, CORBA_Environment *ev, + gpointer user_data) +{ + ESelectNamesManager *manager = E_SELECT_NAMES_MANAGER (user_data); + GList *l; + for (l = manager->entries; l; l = l->next) { + ESelectNamesManagerEntry *entry = l->data; + e_select_names_completion_clear_books (E_SELECT_NAMES_COMPLETION (entry->comp)); + } + + g_list_foreach (manager->completion_books, (GFunc)gtk_object_unref, NULL); + g_list_free (manager->completion_books); + manager->completion_books = NULL; + + read_completion_books_from_db (manager); +} + /** * e_select_names_manager_new: * @VCard: a string in vCard format @@ -379,24 +452,19 @@ e_select_names_manager_new (void) ESelectNamesManager *manager = E_SELECT_NAMES_MANAGER(gtk_type_new(e_select_names_manager_get_type())); Bonobo_ConfigDatabase db; CORBA_Environment ev; - char *val; CORBA_exception_init (&ev); db = addressbook_config_database (&ev); - val = bonobo_config_get_string (db, "/Addressbook/Completion/uri", &ev); - CORBA_exception_free (&ev); - if (val) { - manager->completion_book = e_book_new (); - gtk_object_ref (GTK_OBJECT (manager)); /* ref ourself before our async call */ - addressbook_load_uri (manager->completion_book, val, (EBookCallback)open_book_cb, manager); - g_free (val); - } - else - manager->completion_book = NULL; + bonobo_event_source_client_add_listener (db, uris_listener, + "Bonobo/ConfigDatabase:change/Addressbook/Completion:", + NULL, + manager); + + read_completion_books_from_db (manager); return manager; } @@ -550,6 +618,7 @@ e_select_names_manager_init (ESelectNamesManager *manager) { manager->sections = NULL; manager->entries = NULL; + manager->completion_books = NULL; } static void @@ -571,6 +640,10 @@ e_select_names_manager_destroy (GtkObject *object) g_list_foreach (manager->entries, (GFunc) e_select_names_manager_entry_free, NULL); g_list_free (manager->entries); manager->entries = NULL; + + g_list_foreach (manager->completion_books, (GFunc) gtk_object_unref, NULL); + g_list_free (manager->completion_books); + manager->completion_books = NULL; } static void 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 9fdad2c304..30b4be35a4 100644 --- a/addressbook/gui/component/select-names/e-select-names-manager.h +++ b/addressbook/gui/component/select-names/e-select-names-manager.h @@ -32,7 +32,7 @@ struct _ESelectNamesManager { ESelectNames *names; - EBook *completion_book; + GList *completion_books; }; struct _ESelectNamesManagerClass { |