From 47912d36f7826239b9eb93d5db3fc26daed612f8 Mon Sep 17 00:00:00 2001 From: Chris Toshok Date: Fri, 30 Jul 2004 18:06:17 +0000 Subject: [ fixes #61365 and other misc issues with the addressbook source editors ] 2004-07-30 Chris Toshok [ fixes #61365 and other misc issues with the addressbook source editors ] * gui/component/ldap-config.glade: change the supported-bases-dialog to be initially hidden. * gui/component/addressbook-view.c (editor_weak_notify): new function, remove the editor from our hash. (source_list_changed_cb): destroy the editors for given sources if they're up when the source disappears. (edit_addressbook_cb): add the editor (and some other misc info we need) to our uid_to_editor hash so we can look it up later. only create the editor if one doesn't exist for the given source. (destroy_editor): GHFunc that destroys the widgets. (addressbook_view_dispose): destroy uid_to_editor. (addressbook_view_init): init uid_to_editor. * gui/component/addressbook-config.h: change return values for _edit_source and _new_source - they both return GtkWidget*s now. * gui/component/addressbook-config.c (addressbook_ldap_init): attempt set the protocol version to LDAPv3. This makes the ldap_auth stuff work if the server requires v3. (addressbook_root_dse_query): we don't need the separate window arg, since all of this now happens *before* the supported bases dialog is shown. we just use the source dialog's window for the various error dialogs. (do_ldap_root_dse_query): same. (query_for_supported_bases): same, and set the supported bases dialog as transient-for the source dialog, and make it modal. Lastly, don't make the editor modal. (addressbook_config_edit_source): return the editor's window. (addressbook_config_create_new_source): same. svn path=/trunk/; revision=26778 --- addressbook/ChangeLog | 36 +++++++++++ addressbook/gui/component/addressbook-config.c | 45 +++++++++----- addressbook/gui/component/addressbook-config.h | 4 +- addressbook/gui/component/addressbook-view.c | 86 ++++++++++++++++++++++++-- addressbook/gui/component/ldap-config.glade | 1 - 5 files changed, 151 insertions(+), 21 deletions(-) diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index f7b4e76070..d926c54bc3 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,39 @@ +2004-07-30 Chris Toshok + + [ fixes #61365 and other misc issues with the addressbook source + editors ] + + * gui/component/ldap-config.glade: change the + supported-bases-dialog to be initially hidden. + + * gui/component/addressbook-view.c (editor_weak_notify): new + function, remove the editor from our hash. + (source_list_changed_cb): destroy the editors for given sources if + they're up when the source disappears. + (edit_addressbook_cb): add the editor (and some other misc info we + need) to our uid_to_editor hash so we can look it up later. only + create the editor if one doesn't exist for the given source. + (destroy_editor): GHFunc that destroys the widgets. + (addressbook_view_dispose): destroy uid_to_editor. + (addressbook_view_init): init uid_to_editor. + + * gui/component/addressbook-config.h: change return values for + _edit_source and _new_source - they both return GtkWidget*s now. + + * gui/component/addressbook-config.c (addressbook_ldap_init): + attempt set the protocol version to LDAPv3. This makes the + ldap_auth stuff work if the server requires v3. + (addressbook_root_dse_query): we don't need the separate window + arg, since all of this now happens *before* the supported bases + dialog is shown. we just use the source dialog's window for the + various error dialogs. + (do_ldap_root_dse_query): same. + (query_for_supported_bases): same, and set the supported bases + dialog as transient-for the source dialog, and make it modal. + Lastly, don't make the editor modal. + (addressbook_config_edit_source): return the editor's window. + (addressbook_config_create_new_source): same. + 2004-07-26 JP Rosevear * gui/component/ldap-config.glade: change contacts group to diff --git a/addressbook/gui/component/addressbook-config.c b/addressbook/gui/component/addressbook-config.c index 0ed3b67b28..60d0afe432 100644 --- a/addressbook/gui/component/addressbook-config.c +++ b/addressbook/gui/component/addressbook-config.c @@ -393,15 +393,24 @@ addressbook_ldap_init (GtkWidget *window, ESource *source) LDAP *ldap; gchar *host; gint port; + int ldap_error; + int protocol_version = LDAP_VERSION3; if (!source_to_uri_parts (source, &host, NULL, NULL, &port)) return NULL; - if (!(ldap = ldap_init (host, port))) + if (!(ldap = ldap_init (host, port))) { e_error_run ((GtkWindow *) window, "addressbook:ldap-init", NULL); + goto done; + } + + ldap_error = ldap_set_option (ldap, LDAP_OPT_PROTOCOL_VERSION, &protocol_version); + if (LDAP_OPT_SUCCESS != ldap_error) + g_warning ("failed to set protocol version to LDAPv3"); /* XXX do TLS if it's configured in */ + done: g_free (host); return ldap; } @@ -420,7 +429,7 @@ addressbook_ldap_auth (GtkWidget *window, LDAP *ldap) } static int -addressbook_root_dse_query (AddressbookSourceDialog *dialog, GtkWindow *window, LDAP *ldap, +addressbook_root_dse_query (AddressbookSourceDialog *dialog, LDAP *ldap, char **attrs, LDAPMessage **resp) { int ldap_error; @@ -434,7 +443,7 @@ addressbook_root_dse_query (AddressbookSourceDialog *dialog, GtkWindow *window, "(objectclass=*)", attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, resp); if (LDAP_SUCCESS != ldap_error) - e_error_run ((GtkWindow *) window, "addressbook:ldap-search-base", NULL); + e_error_run (GTK_WINDOW (dialog->window), "addressbook:ldap-search-base", NULL); return ldap_error; } @@ -635,7 +644,7 @@ supported_bases_create_table (char *name, char *string1, char *string2, int num1 } static gboolean -do_ldap_root_dse_query (AddressbookSourceDialog *sdialog, GtkWidget *dialog, ETableModel *model, ESource *source, char ***rvalues) +do_ldap_root_dse_query (AddressbookSourceDialog *sdialog, ETableModel *model, ESource *source, char ***rvalues) { LDAP *ldap; char *attrs[2]; @@ -644,24 +653,24 @@ do_ldap_root_dse_query (AddressbookSourceDialog *sdialog, GtkWidget *dialog, ETa LDAPMessage *resp; int i; - ldap = addressbook_ldap_init (dialog, source); + ldap = addressbook_ldap_init (sdialog->window, source); if (!ldap) return FALSE; - if (LDAP_SUCCESS != addressbook_ldap_auth (dialog, ldap)) + if (LDAP_SUCCESS != addressbook_ldap_auth (sdialog->window, ldap)) goto fail; attrs[0] = "namingContexts"; attrs[1] = NULL; - ldap_error = addressbook_root_dse_query (sdialog, GTK_WINDOW (dialog), ldap, attrs, &resp); + ldap_error = addressbook_root_dse_query (sdialog, ldap, attrs, &resp); if (ldap_error != LDAP_SUCCESS) goto fail; values = ldap_get_values (ldap, resp, "namingContexts"); if (!values || values[0] == NULL) { - e_error_run ((GtkWindow *) dialog, "addressbook:ldap-search-base", NULL); + e_error_run (GTK_WINDOW (sdialog->window), "addressbook:ldap-search-base", NULL); goto fail; } @@ -704,6 +713,9 @@ query_for_supported_bases (GtkWidget *button, AddressbookSourceDialog *sdialog) gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, "supported-bases-dialog", NULL); dialog = glade_xml_get_widget (gui, "supported-bases-dialog"); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (sdialog->window)); + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + gtk_widget_realize (dialog); gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 0); gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12); @@ -718,7 +730,9 @@ query_for_supported_bases (GtkWidget *button, AddressbookSourceDialog *sdialog) search_base_selection_model_changed (selection_model, dialog); - if (do_ldap_root_dse_query (sdialog, dialog, model, source, &values)) { + if (do_ldap_root_dse_query (sdialog, model, source, &values)) { + gtk_widget_show (dialog); + id = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_hide (dialog); @@ -741,6 +755,8 @@ query_for_supported_bases (GtkWidget *button, AddressbookSourceDialog *sdialog) e_table_memory_store_clear (E_TABLE_MEMORY_STORE (model)); } + gtk_widget_destroy (dialog); + g_object_unref (source); } @@ -974,7 +990,6 @@ addressbook_add_server_dialog (void) source_to_dialog (sdialog); gtk_window_set_type_hint (GTK_WINDOW (sdialog->window), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_modal (GTK_WINDOW (sdialog->window), TRUE); add_folder_modify (sdialog->window, sdialog); @@ -1181,7 +1196,7 @@ edit_dialog_ok_clicked (GtkWidget *item, AddressbookSourceDialog *sdialog) } } -void +GtkWidget* addressbook_config_edit_source (GtkWidget *parent, ESource *source) { AddressbookSourceDialog *sdialog = g_new0 (AddressbookSourceDialog, 1); @@ -1249,15 +1264,17 @@ addressbook_config_edit_source (GtkWidget *parent, ESource *source) gtk_widget_set_sensitive (sdialog->ok_button, FALSE); - gtk_window_set_modal (GTK_WINDOW (sdialog->window), TRUE); - gtk_widget_show (sdialog->window); + + return sdialog->window; } -void +GtkWidget* addressbook_config_create_new_source (GtkWidget *parent) { AddressbookSourceDialog *dialog; dialog = addressbook_add_server_dialog (); + + return dialog->window; } diff --git a/addressbook/gui/component/addressbook-config.h b/addressbook/gui/component/addressbook-config.h index b5800bc123..8818fd08d7 100644 --- a/addressbook/gui/component/addressbook-config.h +++ b/addressbook/gui/component/addressbook-config.h @@ -46,7 +46,7 @@ typedef enum { ADDRESSBOOK_LDAP_SSL_NEVER } AddressbookLDAPSSLType; -void addressbook_config_edit_source (GtkWidget *parent, ESource *source); -void addressbook_config_create_new_source (GtkWidget *parent); +GtkWidget* addressbook_config_edit_source (GtkWidget *parent, ESource *source); +GtkWidget* addressbook_config_create_new_source (GtkWidget *parent); #endif /* __ADDRESSBOOK_CONFIG_H__ */ diff --git a/addressbook/gui/component/addressbook-view.c b/addressbook/gui/component/addressbook-view.c index cfedd0b949..9b3db0c3b2 100644 --- a/addressbook/gui/component/addressbook-view.c +++ b/addressbook/gui/component/addressbook-view.c @@ -84,6 +84,8 @@ struct _AddressbookViewPrivate { GConfClient *gconf_client; GHashTable *uid_to_view; + GHashTable *uid_to_editor; + EBook *book; guint activity_id; ESourceList *source_list; @@ -112,6 +114,22 @@ static void addressbook_view_init (AddressbookView *view); static void addressbook_view_class_init (AddressbookViewClass *klass); static void addressbook_view_dispose (GObject *object); +typedef struct { + GtkWidget *editor; + char *uid; + AddressbookView *view; +} EditorUidClosure; + +static void +editor_weak_notify (gpointer data, GObject *o) +{ + EditorUidClosure *closure = data; + AddressbookViewPrivate *priv = closure->view->priv; + + g_hash_table_remove (priv->uid_to_editor, + closure->uid); +} + static EABView * get_current_view (AddressbookView *view) { @@ -469,15 +487,14 @@ source_list_changed_cb (ESourceList *source_list, AddressbookView *view) uids = NULL; g_hash_table_foreach (priv->uid_to_view, (GHFunc)gather_uids_foreach, &uids); - for (l = uids; l; l = l->next) { char *uid = l->data; if (e_source_list_peek_source_by_uid (source_list, uid)) { /* the source still exists, do nothing */ } else { - /* the source no longer exists, remove the - view and remove it from our hash table. */ + /* the source no longer exists, remove its + view remove it from our hash table. */ v = g_hash_table_lookup (priv->uid_to_view, uid); g_hash_table_remove (priv->uid_to_view, uid); @@ -487,6 +504,27 @@ source_list_changed_cb (ESourceList *source_list, AddressbookView *view) g_object_unref (v); } } + g_list_free (uids); + + uids = NULL; + g_hash_table_foreach (priv->uid_to_editor, (GHFunc)gather_uids_foreach, &uids); + for (l = uids; l; l = l->next) { + char *uid = l->data; + if (e_source_list_peek_source_by_uid (source_list, uid)) { + /* the source still exists, do nothing */ + } + else { + /* the source no longer exists, remove its + editor remove it from our hash table. */ + EditorUidClosure *closure = g_hash_table_lookup (priv->uid_to_editor, + uid); + g_object_weak_unref (G_OBJECT (closure->editor), + editor_weak_notify, closure); + gtk_widget_destroy (closure->editor); + g_hash_table_remove (priv->uid_to_editor, uid); + } + } + g_list_free (uids); /* make sure we've got the current view selected and updated properly */ @@ -676,13 +714,34 @@ edit_addressbook_cb (GtkWidget *widget, AddressbookView *view) { AddressbookViewPrivate *priv = view->priv; ESource *selected_source; + const char *uid;; + EditorUidClosure *closure; selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector)); if (!selected_source) return; - addressbook_config_edit_source (gtk_widget_get_toplevel (widget), selected_source); + uid = e_source_peek_uid (selected_source); + + closure = g_hash_table_lookup (priv->uid_to_editor, uid); + if (!closure) { + char *uid_copy = g_strdup (uid); + + closure = g_new (EditorUidClosure, 1); + closure->editor = addressbook_config_edit_source (gtk_widget_get_toplevel (widget), selected_source); + closure->uid = uid_copy; + closure->view = view; + + g_hash_table_insert (priv->uid_to_editor, + uid_copy, + closure); + + g_object_weak_ref (G_OBJECT (closure->editor), + editor_weak_notify, closure); + } + + gtk_window_present (GTK_WINDOW (closure->editor)); } /* Callbacks. */ @@ -1010,6 +1069,7 @@ addressbook_view_init (AddressbookView *view) priv->gconf_client = addressbook_component_peek_gconf_client (addressbook_component_peek ()); priv->uid_to_view = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); + priv->uid_to_editor = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_free); priv->notebook = gtk_notebook_new (); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE); @@ -1078,6 +1138,19 @@ addressbook_view_init (AddressbookView *view) load_uri_for_selection (E_SOURCE_SELECTOR (priv->selector), view); } +static void +destroy_editor (char *key, + gpointer value, + gpointer nada) +{ + EditorUidClosure *closure = value; + + g_object_weak_unref (G_OBJECT (closure->editor), + editor_weak_notify, closure); + + gtk_widget_destroy (GTK_WIDGET (closure->editor)); +} + static void addressbook_view_dispose (GObject *object) { @@ -1096,6 +1169,11 @@ addressbook_view_dispose (GObject *object) if (priv->uid_to_view) g_hash_table_destroy (priv->uid_to_view); + if (priv->uid_to_editor) { + g_hash_table_foreach (priv->uid_to_editor, (GHFunc)destroy_editor, NULL); + g_hash_table_destroy (priv->uid_to_editor); + } + if (priv->creatable_items_handler) g_object_unref (priv->creatable_items_handler); diff --git a/addressbook/gui/component/ldap-config.glade b/addressbook/gui/component/ldap-config.glade index 21687321c9..c95c4e364b 100644 --- a/addressbook/gui/component/ldap-config.glade +++ b/addressbook/gui/component/ldap-config.glade @@ -2578,7 +2578,6 @@ - True Supported Search Bases GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER -- cgit