diff options
Diffstat (limited to 'addressbook/gui')
-rw-r--r-- | addressbook/gui/component/Makefile.am | 6 | ||||
-rw-r--r-- | addressbook/gui/component/addressbook-component.c | 12 | ||||
-rw-r--r-- | addressbook/gui/component/addressbook-config.c | 1446 | ||||
-rw-r--r-- | addressbook/gui/component/addressbook-view.c | 155 | ||||
-rw-r--r-- | addressbook/gui/component/addressbook.c | 99 | ||||
-rw-r--r-- | addressbook/gui/component/apps_evolution_addressbook.schemas.in.in | 18 | ||||
-rw-r--r-- | addressbook/gui/component/component-factory.c | 4 | ||||
-rw-r--r-- | addressbook/gui/contact-editor/e-contact-editor.c | 228 | ||||
-rw-r--r-- | addressbook/gui/contact-editor/e-contact-quick-add.c | 42 | ||||
-rw-r--r-- | addressbook/gui/contact-list-editor/contact-list-editor.glade | 15 | ||||
-rw-r--r-- | addressbook/gui/widgets/e-addressbook-view.c | 487 | ||||
-rw-r--r-- | addressbook/gui/widgets/e-addressbook-view.h | 5 | ||||
-rw-r--r-- | addressbook/gui/widgets/eab-contact-display.c | 27 |
13 files changed, 1297 insertions, 1247 deletions
diff --git a/addressbook/gui/component/Makefile.am b/addressbook/gui/component/Makefile.am index a2798ec665..adf772206c 100644 --- a/addressbook/gui/component/Makefile.am +++ b/addressbook/gui/component/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = select-names + INCLUDES = \ -DG_LOG_DOMAIN=\"evolution-addressbook\" \ -I$(top_srcdir) \ @@ -46,6 +48,7 @@ endif libevolution_addressbook_la_LIBADD = \ $(SMIME_LIB) \ $(top_builddir)/addressbook/printing/libecontactprint.la \ + $(top_builddir)/addressbook/gui/component/select-names/libeselectnames.la \ $(top_builddir)/shell/libeshell.la \ $(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \ $(top_builddir)/addressbook/gui/widgets/libeabwidgets.la \ @@ -57,6 +60,7 @@ libevolution_addressbook_la_LIBADD = \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ $(top_builddir)/widgets/menus/libmenus.la \ $(top_builddir)/a11y/addressbook/libevolution-addressbook-a11y.la \ + $(top_builddir)/camel/libcamel.la \ $(EVOLUTION_ADDRESSBOOK_LIBS) $(LDAP_LIBS) @@ -76,7 +80,7 @@ schema_DATA = $(schema_in_files:.schemas.in.in=-$(BASE_VERSION).schemas) install-data-local: if test -z "$(DESTDIR)" ; then \ for p in $(schema_DATA) ; do \ - GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $$p; \ + GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(srcdir)/$$p; \ done \ fi diff --git a/addressbook/gui/component/addressbook-component.c b/addressbook/gui/component/addressbook-component.c index a0c3c58c04..a82e6db02f 100644 --- a/addressbook/gui/component/addressbook-component.c +++ b/addressbook/gui/component/addressbook-component.c @@ -31,10 +31,6 @@ #include "addressbook-view.h" #include "addressbook/gui/contact-editor/eab-editor.h" #include "addressbook/gui/widgets/eab-gui-util.h" -#include "e-util/e-plugin.h" -#include "addressbook/gui/widgets/eab-popup.h" -#include "addressbook/gui/widgets/eab-menu.h" -#include "addressbook/gui/widgets/eab-config.h" #include "widgets/misc/e-task-bar.h" #include "widgets/misc/e-info-label.h" @@ -335,7 +331,6 @@ static void addressbook_component_init (AddressbookComponent *component) { AddressbookComponentPrivate *priv; - static int first = TRUE; priv = g_new0 (AddressbookComponentPrivate, 1); @@ -351,13 +346,6 @@ addressbook_component_init (AddressbookComponent *component) #ifdef ENABLE_SMIME smime_component_init (); #endif - - if (first) { - first = FALSE; - e_plugin_hook_register_type(eab_popup_hook_get_type()); - e_plugin_hook_register_type(eab_menu_hook_get_type()); - e_plugin_hook_register_type(eab_config_hook_get_type()); - } } diff --git a/addressbook/gui/component/addressbook-config.c b/addressbook/gui/component/addressbook-config.c index be06893c49..e29d58b245 100644 --- a/addressbook/gui/component/addressbook-config.c +++ b/addressbook/gui/component/addressbook-config.c @@ -3,8 +3,6 @@ * Authors: * Chris Toshok <toshok@ximian.com> * Chris Lahey <clahey@ximian.com> - * Michael Zucchi <notzed@ximian.com> - * And no doubt others ... **/ /*#define STANDALONE*/ @@ -18,19 +16,10 @@ #include <gtk/gtkcombo.h> #include <gtk/gtkdialog.h> #include <gtk/gtkentry.h> -#include <gtk/gtkrange.h> -#include <gtk/gtktreeview.h> -#include <gtk/gtkliststore.h> -#include <gtk/gtkscrolledwindow.h> -#include <gtk/gtktreeselection.h> -#include <gtk/gtkcellrenderertext.h> -#include <gtk/gtkcombobox.h> -#include <gtk/gtkoptionmenu.h> -#include <gtk/gtkspinbutton.h> -#include <gtk/gtkcelllayout.h> -#include <gtk/gtklabel.h> -#include <gtk/gtk.h> +#include <gtk/gtkmessagedialog.h> #include <libgnome/gnome-i18n.h> +#include <libgnomeui/gnome-druid.h> +#include <libgnomeui/gnome-druid-page.h> #include <bonobo/bonobo-generic-factory.h> @@ -44,9 +33,9 @@ #include "evolution-config-control.h" -#include "addressbook/gui/widgets/eab-config.h" +#include <gal/e-table/e-table-memory-store.h> +#include <gal/e-table/e-table-scrolled.h> -#define d(x) #ifdef HAVE_LDAP #include "ldap.h" @@ -72,48 +61,69 @@ GtkWidget* supported_bases_create_table (char *name, char *string1, char *string #define CALENTRY "calEntry" +typedef struct { + GtkWidget *notebook; + int page_num; +} FocusHelpClosure; + typedef struct _AddressbookSourceDialog AddressbookSourceDialog; +typedef void (*ModifyFunc)(GtkWidget *item, AddressbookSourceDialog *dialog); struct _AddressbookSourceDialog { GladeXML *gui; - EABConfig *config; /* the config manager */ - GtkWidget *window; + GtkWidget *druid; /* only used (obviously) in the druid */ /* Source selection (druid only) */ ESourceList *source_list; GSList *menu_source_groups; GtkWidget *group_optionmenu; - /* ESource we're currently editing */ + /* ESource we're currently editing (editor only) */ ESource *source; - /* The original source in edit mode. Also used to flag when we are in edit mode. */ - ESource *original_source; /* Source group we're creating/editing a source in */ ESourceGroup *source_group; /* info page fields */ + ModifyFunc general_modify_func; GtkWidget *host; GtkWidget *auth_optionmenu; AddressbookLDAPAuthType auth; GtkWidget *auth_principal; /* connecting page fields */ + ModifyFunc connecting_modify_func; GtkWidget *port_combo; GtkWidget *ssl_optionmenu; AddressbookLDAPSSLType ssl; /* searching page fields */ + ModifyFunc searching_modify_func; GtkWidget *rootdn; AddressbookLDAPScopeType scope; GtkWidget *scope_optionmenu; GtkWidget *timeout_scale; GtkWidget *limit_spinbutton; + /* new dialog stuff */ + GtkWidget *auth_frame; + GtkWidget *server_frame; + /* display name page fields */ GtkWidget *display_name; + gboolean display_name_changed; /* only used in the druid */ + + gboolean schema_query_successful; + + /* stuff for the account editor window */ + GtkWidget *ok_button; + GtkWidget *cancel_button; + GtkWidget *advanced_button_notebook; + GtkWidget *notebook; /* the toplevel notebook */ + + gboolean advanced; }; @@ -196,8 +206,98 @@ ldap_parse_ssl (const char *ssl) return ADDRESSBOOK_LDAP_SSL_WHENEVER_POSSIBLE; } +#endif + + + +static void +dialog_to_source (AddressbookSourceDialog *dialog, ESource *source, gboolean temporary) +{ + gchar *str; + + g_assert (source); + + e_source_set_name (source, gtk_entry_get_text (GTK_ENTRY (dialog->display_name))); + + if (!strcmp ("ldap://", e_source_group_peek_base_uri (dialog->source_group))) { +#ifdef HAVE_LDAP + if (dialog->auth != ADDRESSBOOK_LDAP_AUTH_NONE) + e_source_set_property (source, + dialog->auth == ADDRESSBOOK_LDAP_AUTH_SIMPLE_EMAIL ? "email_addr" : "binddn", + gtk_entry_get_text (GTK_ENTRY (dialog->auth_principal))); + str = g_strdup_printf ("%d", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (dialog->limit_spinbutton))); + e_source_set_property (source, "limit", str); + g_free (str); + + str = g_strdup_printf ("%f", gtk_adjustment_get_value (GTK_RANGE(dialog->timeout_scale)->adjustment)); + e_source_set_property (source, "timeout", str); + g_free (str); + + e_source_set_property (source, "ssl", ldap_unparse_ssl (dialog->ssl)); + e_source_set_property (source, "auth", ldap_unparse_auth (dialog->auth)); + str = g_strdup_printf ("%s:%s/%s?" /* trigraph prevention */ "?%s", + gtk_entry_get_text (GTK_ENTRY (dialog->host)), + gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (dialog->port_combo)->entry)), + gtk_entry_get_text (GTK_ENTRY (dialog->rootdn)), + ldap_unparse_scope (dialog->scope)); + e_source_set_relative_uri (source, str); + g_free (str); +#endif + }else if (g_str_has_prefix (e_source_group_peek_base_uri (dialog->source_group), "groupwise://") && + !e_source_peek_group (source)) { /* if this is an existing book we don't change anything else */ + + GSList *groupwise_source_list; + ESource *existing_source = NULL; + const char *property_value = NULL; + + groupwise_source_list = e_source_group_peek_sources(dialog->source_group); + if (groupwise_source_list) + existing_source = E_SOURCE (groupwise_source_list->data); + if (existing_source) { + property_value = e_source_get_property (existing_source, "auth"); + e_source_set_property (source, "auth", property_value); + property_value = e_source_get_property (existing_source, "user"); + e_source_set_property (source, "user", property_value); + property_value = e_source_get_property (existing_source, "use_ssl"); + e_source_set_property (source, "use_ssl", property_value); + } + e_source_set_property (source, "auth-domain", "Groupwise"); + str = g_strconcat (";", gtk_entry_get_text (GTK_ENTRY (dialog->display_name)), NULL); + e_source_set_relative_uri (source, str); + g_free (str); + + } else { + const gchar *relative_uri; + + relative_uri = e_source_peek_relative_uri (source); + if (!relative_uri || !strlen (relative_uri)) + e_source_set_relative_uri (source, e_source_peek_uid (source)); + } + + if (!temporary) { + if (!e_source_peek_group (source)) + e_source_group_add_source (dialog->source_group, source, -1); + + e_source_list_sync (dialog->source_list, NULL); + } +} + +static ESource * +dialog_to_temp_source (AddressbookSourceDialog *dialog) +{ + ESource *source; + + source = e_source_new ("", ""); + e_source_set_group (source, dialog->source_group); + dialog_to_source (dialog, source, TRUE); + + return source; +} + +#ifdef HAVE_LDAP static gboolean -source_to_uri_parts (ESource *source, gchar **host, gchar **rootdn, AddressbookLDAPScopeType *scope, gint *port) +source_to_uri_parts (ESource *source, gchar **host, gchar **rootdn, + AddressbookLDAPScopeType *scope, gint *port) { gchar *uri; LDAPURLDesc *lud; @@ -227,13 +327,71 @@ source_to_uri_parts (ESource *source, gchar **host, gchar **rootdn, AddressbookL ldap_free_urldesc (lud); return TRUE; } +#endif -static gboolean -source_group_is_remote (ESourceGroup *group) +#define SOURCE_PROP_STRING(source, prop) \ + (source && e_source_get_property (source, prop) ? e_source_get_property (source, prop) : "") + +static void +source_to_dialog (AddressbookSourceDialog *dialog) { - return strncmp ("ldap:", e_source_group_peek_base_uri (group), 5) == 0; + ESource *source = dialog->source; + const char *base_uri; + + gtk_entry_set_text (GTK_ENTRY (dialog->display_name), source ? e_source_peek_name (source) : ""); + base_uri = e_source_group_peek_base_uri (dialog->source_group); + if (source && base_uri && g_str_has_prefix (base_uri, "groupwise://")) + gtk_widget_set_sensitive (GTK_WIDGET(dialog->display_name), FALSE); + +#ifdef HAVE_LDAP + gtk_spin_button_set_value ( GTK_SPIN_BUTTON (dialog->limit_spinbutton), + g_strtod ( source && e_source_get_property (source, "limit") ? + e_source_get_property (source, "limit") : "100", NULL)); + gtk_adjustment_set_value (GTK_RANGE(dialog->timeout_scale)->adjustment, + g_strtod ( source && e_source_get_property (source, "timeout") ? + e_source_get_property (source, "timeout") : "3", NULL)); + + dialog->auth = source && e_source_get_property (source, "auth") ? + ldap_parse_auth (e_source_get_property (source, "auth")) : ADDRESSBOOK_LDAP_AUTH_NONE; + dialog->ssl = source && e_source_get_property (source, "ssl") ? + ldap_parse_ssl (e_source_get_property (source, "ssl")) : ADDRESSBOOK_LDAP_SSL_WHENEVER_POSSIBLE; + + if (dialog->auth != ADDRESSBOOK_LDAP_AUTH_NONE) + gtk_entry_set_text (GTK_ENTRY (dialog->auth_principal), + SOURCE_PROP_STRING (source, + dialog->auth == ADDRESSBOOK_LDAP_AUTH_SIMPLE_EMAIL ? "email_addr" : "binddn")); + + if (source && !strcmp ("ldap://", e_source_group_peek_base_uri (dialog->source_group))) { + gchar *host; + gchar *rootdn; + AddressbookLDAPScopeType scope; + gint port; + + if (source_to_uri_parts (source, &host, &rootdn, &scope, &port)) { + gchar *port_str; + + gtk_entry_set_text (GTK_ENTRY (dialog->host), host); + gtk_entry_set_text (GTK_ENTRY (dialog->rootdn), rootdn); + + dialog->scope = scope; + + port_str = g_strdup_printf ("%d", port); + gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (dialog->port_combo)->entry), port_str); + g_free (port_str); + + g_free (host); + g_free (rootdn); + } + } + + gtk_option_menu_set_history (GTK_OPTION_MENU(dialog->auth_optionmenu), dialog->auth); + gtk_option_menu_set_history (GTK_OPTION_MENU(dialog->scope_optionmenu), dialog->scope); + gtk_option_menu_set_history (GTK_OPTION_MENU(dialog->ssl_optionmenu), dialog->ssl); +#endif } +#ifdef HAVE_LDAP + /* ldap api foo */ static LDAP * addressbook_ldap_init (GtkWidget *window, ESource *source) @@ -296,35 +454,203 @@ addressbook_root_dse_query (AddressbookSourceDialog *dialog, LDAP *ldap, return ldap_error; } +#endif + +static void +addressbook_source_dialog_destroy (gpointer data, GObject *where_object_was) +{ + AddressbookSourceDialog *dialog = data; + + g_object_unref (dialog->gui); + g_object_unref (dialog->source_list); + g_slist_free (dialog->menu_source_groups); + g_free (dialog); +} + +static void +addressbook_add_server_dialog_finish (GtkWidget *widget, AddressbookSourceDialog *sdialog) +{ + sdialog->source = e_source_new ("", ""); + dialog_to_source (sdialog, sdialog->source, FALSE); + + /* tear down the widgets */ + gtk_widget_destroy (sdialog->window); +} + +static void +addressbook_add_server_dialog_cancel (GtkWidget *widget, AddressbookSourceDialog *dialog) +{ + gtk_widget_destroy (dialog->window); +} + +static void +auth_optionmenu_activated (GtkWidget *item, AddressbookSourceDialog *dialog) +{ + dialog->auth = g_list_index (gtk_container_get_children (GTK_CONTAINER (item->parent)), + item); + + dialog->general_modify_func (item, dialog); +} + +static void +add_auth_activate_cb (GtkWidget *item, AddressbookSourceDialog *dialog) +{ + g_signal_connect (item, "activate", + G_CALLBACK (auth_optionmenu_activated), dialog); +} + +static void +setup_general_tab (AddressbookSourceDialog *dialog, ModifyFunc modify_func) +{ + GtkWidget *menu; + + dialog->general_modify_func = modify_func; + dialog->host = glade_xml_get_widget (dialog->gui, "server-name-entry"); + + g_signal_connect (dialog->host, "changed", + G_CALLBACK (modify_func), dialog); + + dialog->auth_principal = glade_xml_get_widget (dialog->gui, "auth-entry"); + g_signal_connect (dialog->auth_principal, "changed", + G_CALLBACK (modify_func), dialog); + + dialog->auth_optionmenu = glade_xml_get_widget (dialog->gui, "auth-optionmenu"); + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU(dialog->auth_optionmenu)); + gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback)add_auth_activate_cb, dialog); +} + +static gboolean +general_tab_check (AddressbookSourceDialog *dialog) +{ + gboolean valid = TRUE; + const char *string; + + if (strcmp ("ldap://", e_source_group_peek_base_uri (dialog->source_group))) + return TRUE; + + string = gtk_entry_get_text (GTK_ENTRY (dialog->host)); + if (!string || !string[0]) + valid = FALSE; + + if (valid) { + if (dialog->auth != ADDRESSBOOK_LDAP_AUTH_NONE) { + string = gtk_entry_get_text (GTK_ENTRY (dialog->auth_principal)); + + if (!string || !string[0]) + valid = FALSE; + } + } + + return valid; +} + + +/* connecting page */ +static void +ssl_optionmenu_activated (GtkWidget *item, AddressbookSourceDialog *dialog) +{ + dialog->ssl = g_list_index (gtk_container_get_children (GTK_CONTAINER (item->parent)), + item); + + dialog->connecting_modify_func (item, dialog); +} + +static void +add_ssl_activate_cb (GtkWidget *item, AddressbookSourceDialog *dialog) +{ + g_signal_connect (item, "activate", + G_CALLBACK (ssl_optionmenu_activated), dialog); +} + +static void +port_changed_func (GtkWidget *item, AddressbookSourceDialog *dialog) +{ + /* if the port value is ldaps, set the SSL/TLS option menu to + Always and desensitize it */ + const char *string = gtk_entry_get_text (GTK_ENTRY (item)); + + dialog->connecting_modify_func (item, dialog); + + if (!strcmp (string, LDAPS_PORT_STRING)) { + dialog->ssl = ADDRESSBOOK_LDAP_SSL_ALWAYS; + gtk_option_menu_set_history (GTK_OPTION_MENU(dialog->ssl_optionmenu), + dialog->ssl); + + gtk_widget_set_sensitive (dialog->ssl_optionmenu, FALSE); + } + else { + gtk_widget_set_sensitive (dialog->ssl_optionmenu, TRUE); + } + +} + +static void +setup_connecting_tab (AddressbookSourceDialog *dialog, ModifyFunc modify_func) +{ + GtkWidget *menu; + + dialog->connecting_modify_func = modify_func; + + dialog->port_combo = glade_xml_get_widget (dialog->gui, "port-combo"); + + g_signal_connect (GTK_COMBO(dialog->port_combo)->entry, "changed", + G_CALLBACK (modify_func), dialog); + g_signal_connect (GTK_COMBO(dialog->port_combo)->entry, "changed", + G_CALLBACK (port_changed_func), dialog); + dialog->ssl_optionmenu = glade_xml_get_widget (dialog->gui, "ssl-optionmenu"); + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU(dialog->ssl_optionmenu)); + gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback)add_ssl_activate_cb, dialog); +} + +static gboolean +connecting_tab_check (AddressbookSourceDialog *dialog) +{ + gboolean valid = TRUE; + const char *string; + + string = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(dialog->port_combo)->entry)); + if (!string || !string[0]) + valid = FALSE; + + return valid; +} + + + +#ifdef HAVE_LDAP + /* searching page */ +static ETableMemoryStoreColumnInfo bases_table_columns[] = { + E_TABLE_MEMORY_STORE_STRING, + E_TABLE_MEMORY_STORE_TERMINATOR +}; + +#define BASES_TABLE_SPEC \ +"<ETableSpecification cursor-mode=\"line\" no-headers=\"true\"> \ + <ETableColumn model_col= \"0\" _title=\"Base\" expansion=\"1.0\" minimum_width=\"20\" resizable=\"true\" cell=\"string\" compare=\"string\"/> \ + <ETableState> \ + <column source=\"0\"/> \ + <grouping></grouping> \ + </ETableState> \ +</ETableSpecification>" + GtkWidget* supported_bases_create_table (char *name, char *string1, char *string2, int num1, int num2) { - GtkWidget *table, *scrolled; - GtkTreeSelection *selection; - GtkCellRenderer *renderer; - GtkListStore *model; - - scrolled = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); - - model = gtk_list_store_new (1, G_TYPE_STRING); - table = gtk_tree_view_new_with_model ((GtkTreeModel *) model); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes ((GtkTreeView *) table, -1, _("Base"), renderer, "text", 0, NULL); - gtk_tree_view_set_headers_visible ((GtkTreeView *) table, FALSE); - selection = gtk_tree_view_get_selection ((GtkTreeView *) table); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - gtk_container_add (GTK_CONTAINER (scrolled), table); - g_object_set_data((GObject *)scrolled, "table", table); - - return scrolled; + GtkWidget *table; + ETableModel *model; + + model = e_table_memory_store_new (bases_table_columns); + + table = e_table_scrolled_new (model, NULL, BASES_TABLE_SPEC, NULL); + + g_object_set_data (G_OBJECT (table), "model", model); + + return table; } static gboolean -do_ldap_root_dse_query (AddressbookSourceDialog *sdialog, GtkListStore *model, ESource *source) +do_ldap_root_dse_query (AddressbookSourceDialog *sdialog, ETableModel *model, ESource *source, char ***rvalues) { LDAP *ldap; char *attrs[2]; @@ -354,14 +680,12 @@ do_ldap_root_dse_query (AddressbookSourceDialog *sdialog, GtkListStore *model, E goto fail; } - for (i = 0; values[i]; i++) { - GtkTreeIter iter; + for (i = 0; values[i]; i++) + e_table_memory_store_insert (E_TABLE_MEMORY_STORE (model), + -1, GINT_TO_POINTER(i), values[i]); - gtk_list_store_append (model, &iter); - gtk_list_store_set (model, &iter, 0, values[i], -1); - } + *rvalues = values; - ldap_value_free (values); ldap_unbind_s (ldap); return TRUE; @@ -371,23 +695,26 @@ do_ldap_root_dse_query (AddressbookSourceDialog *sdialog, GtkListStore *model, E } static void -search_base_selection_model_changed (GtkTreeSelection *selection, GtkWidget *dialog) +search_base_selection_model_changed (ESelectionModel *selection_model, GtkWidget *dialog) { gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, - gtk_tree_selection_get_selected(selection, NULL, NULL)); + e_selection_model_selected_count (selection_model) == 1); } static void query_for_supported_bases (GtkWidget *button, AddressbookSourceDialog *sdialog) { - GtkTreeSelection *selection; - GtkListStore *model; - GtkTreeView *table; + ESelectionModel *selection_model; + ESource *source; GtkWidget *dialog; GtkWidget *supported_bases_table; + ETableModel *model; GladeXML *gui; - GtkTreeIter iter; + int id; + char **values; + + source = dialog_to_temp_source (sdialog); gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, "supported-bases-dialog", NULL); dialog = glade_xml_get_widget (gui, "supported-bases-dialog"); @@ -400,730 +727,571 @@ query_for_supported_bases (GtkWidget *button, AddressbookSourceDialog *sdialog) gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12); supported_bases_table = glade_xml_get_widget (gui, "supported-bases-table"); - gtk_widget_show_all (supported_bases_table); + gtk_widget_show (supported_bases_table); + selection_model = e_table_get_selection_model (e_table_scrolled_get_table (E_TABLE_SCROLLED(supported_bases_table))); + model = g_object_get_data (G_OBJECT (supported_bases_table), "model"); - table = g_object_get_data((GObject *)supported_bases_table, "table"); - model = (GtkListStore *)gtk_tree_view_get_model(table); - selection = gtk_tree_view_get_selection (table); - g_signal_connect (selection, "changed", G_CALLBACK (search_base_selection_model_changed), dialog); - search_base_selection_model_changed (selection, dialog); + g_signal_connect (selection_model, "selection_changed", + G_CALLBACK (search_base_selection_model_changed), dialog); - if (do_ldap_root_dse_query (sdialog, model, sdialog->source)) { - gtk_widget_show (dialog); - - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK - && gtk_tree_selection_get_selected(selection, (GtkTreeModel **)&model, &iter)) { - char *dn; - - gtk_tree_model_get ((GtkTreeModel *)model, &iter, 0, &dn, -1); - gtk_entry_set_text((GtkEntry *)sdialog->rootdn, dn); - g_free(dn); - } - } + search_base_selection_model_changed (selection_model, dialog); - gtk_widget_destroy (dialog); -} + if (do_ldap_root_dse_query (sdialog, model, source, &values)) { + gtk_widget_show (dialog); -#endif /* HAVE_LDAP */ + id = gtk_dialog_run (GTK_DIALOG (dialog)); -GtkWidget* -addressbook_config_create_new_source (GtkWidget *parent) -{ - return addressbook_config_edit_source(parent, NULL); -} + gtk_widget_hide (dialog); -/* ********************************************************************** */ + if (id == GTK_RESPONSE_OK) { + int i; + /* OK was clicked */ -static void -eabc_type_changed(GtkComboBox *dropdown, AddressbookSourceDialog *sdialog) -{ - int id = gtk_combo_box_get_active(dropdown); - GtkTreeModel *model; - GtkTreeIter iter; - - model = gtk_combo_box_get_model(dropdown); - if (id == -1 || !gtk_tree_model_iter_nth_child(model, &iter, NULL, id)) - return; - - /* TODO: when we change the group type, we lose all of the pre-filled dialog info */ - - gtk_tree_model_get(model, &iter, 1, &sdialog->source_group, -1); - /* HACK: doesn't work if you don't do this */ - e_source_set_absolute_uri(sdialog->source, NULL); - e_source_set_group(sdialog->source, sdialog->source_group); - - /* BIG HACK: We load the defaults for each type here. - I guess plugins will have to use the do it in their factory callbacks */ - if (!strncmp(e_source_group_peek_base_uri(sdialog->source_group), "groupwise:", 10)) { - GSList *l; - ESource *source; - char *tmp; - - l = e_source_group_peek_sources(sdialog->source_group); - if (l && l->data ) { - source = l->data; - e_source_set_property(sdialog->source, "auth", e_source_get_property(source, "auth")); - e_source_set_property(sdialog->source, "user", e_source_get_property(source, "user")); - e_source_set_property(sdialog->source, "user_ssl", e_source_get_property(source, "use_ssl")); + /* ugh. */ + for (i = 0; values[i]; i ++) { + if (e_selection_model_is_row_selected (selection_model, i)) { + gtk_entry_set_text (GTK_ENTRY (sdialog->rootdn), values[i]); + break; /* single selection, so we can quit when we've found it. */ + } + } } - e_source_set_property(sdialog->source, "auth-domain", "Groupwise"); - tmp = g_strconcat (";", e_source_peek_name(sdialog->source), NULL); - e_source_set_relative_uri (sdialog->source, tmp); - g_free (tmp); -#ifdef HAVE_LDAP - } else if (!strncmp(e_source_group_peek_base_uri(sdialog->source_group), "ldap:", 5)) { - char *tmp; - - tmp = g_strdup_printf ("%s:%s/%s?" /* trigraph prevention */ "?%s", - "", LDAP_PORT_STRING, - "", - "one"); - e_source_set_relative_uri (sdialog->source, tmp); - g_free (tmp); - e_source_set_property(sdialog->source, "timeout", "3"); - e_source_set_property(sdialog->source, "limit", "100"); -#endif - } else { - e_source_set_relative_uri (sdialog->source, e_source_peek_uid (sdialog->source)); - } - - e_config_target_changed((EConfig *)sdialog->config, E_CONFIG_TARGET_CHANGED_REBUILD); -} + ldap_value_free (values); -static GtkWidget * -eabc_general_type(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, struct _GtkWidget *old, void *data) -{ - AddressbookSourceDialog *sdialog = data; - GtkComboBox *dropdown; - GtkCellRenderer *cell; - GtkListStore *store; - GtkTreeIter iter; - GSList *l; - GtkWidget *w, *label; - int i, row; - - if (old) - return old; - - w = gtk_hbox_new(FALSE, 6); - label = gtk_label_new_with_mnemonic(_("_Type:")); - gtk_box_pack_start((GtkBox *)w, label, FALSE, FALSE, 0); - - dropdown = (GtkComboBox *)gtk_combo_box_new(); - cell = gtk_cell_renderer_text_new(); - store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER); - i = 0; - for (l=sdialog->menu_source_groups;l;l=g_slist_next(l)) { - ESourceGroup *group = l->data; - - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, 0, e_source_group_peek_name(group), 1, group, -1); - if (e_source_peek_group(sdialog->source) == group) - row = i; - i++; + e_table_memory_store_clear (E_TABLE_MEMORY_STORE (model)); } - gtk_cell_layout_pack_start((GtkCellLayout *)dropdown, cell, TRUE); - gtk_cell_layout_set_attributes((GtkCellLayout *)dropdown, cell, "text", 0, NULL); - gtk_combo_box_set_model(dropdown, (GtkTreeModel *)store); - gtk_combo_box_set_active(dropdown, -1); - gtk_combo_box_set_active(dropdown, row); - g_signal_connect(dropdown, "changed", G_CALLBACK(eabc_type_changed), sdialog); - gtk_widget_show((GtkWidget *)dropdown); - gtk_box_pack_start((GtkBox *)w, (GtkWidget *)dropdown, TRUE, TRUE, 0); - gtk_label_set_mnemonic_widget((GtkLabel *)label, (GtkWidget *)dropdown); - - gtk_box_pack_start((GtkBox *)parent, (GtkWidget *)w, FALSE, FALSE, 0); - - gtk_widget_show_all(w); + gtk_widget_destroy (dialog); - return (GtkWidget *)w; + g_object_unref (source); } static void -name_changed_cb(GtkWidget *w, AddressbookSourceDialog *sdialog) +scope_optionmenu_activated (GtkWidget *item, AddressbookSourceDialog *dialog) { - e_source_set_name (sdialog->source, gtk_entry_get_text (GTK_ENTRY (sdialog->display_name))); + dialog->scope = g_list_index (gtk_container_get_children (GTK_CONTAINER (item->parent)), + item); + + if (dialog->searching_modify_func) + dialog->searching_modify_func (item, dialog); } -static void -offline_status_changed_cb (GtkWidget *widget, AddressbookSourceDialog *sdialog) +static void +add_scope_activate_cb (GtkWidget *item, AddressbookSourceDialog *dialog) { - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) - e_source_set_property (sdialog->source, "offline_sync", "1"); - else - e_source_set_property (sdialog->source, "offline_sync", "0"); - + g_signal_connect (item, "activate", + G_CALLBACK (scope_optionmenu_activated), dialog); } -static GtkWidget * -eabc_general_name(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, struct _GtkWidget *old, void *data) +static void +setup_searching_tab (AddressbookSourceDialog *dialog, ModifyFunc modify_func) { - AddressbookSourceDialog *sdialog = data; - const char *uri; - GtkWidget *w; - GladeXML *gui; - + GtkWidget *menu; + GtkWidget *rootdn_button; - if (old) - return old; + dialog->searching_modify_func = modify_func; - gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, item->label, NULL); - w = glade_xml_get_widget(gui, item->label); - gtk_box_pack_start((GtkBox *)parent, w, FALSE, FALSE, 0); - sdialog->display_name = glade_xml_get_widget (gui, "account-editor-display-name-entry"); - g_signal_connect(sdialog->display_name, "changed", G_CALLBACK(name_changed_cb), sdialog); - gtk_entry_set_text((GtkEntry *)sdialog->display_name, e_source_peek_name(sdialog->source)); + dialog->rootdn = glade_xml_get_widget (dialog->gui, "rootdn-entry"); - /* Hardcoded: groupwise can't edit the name (or anything else) */ - if (sdialog->original_source) { - uri = e_source_group_peek_base_uri (sdialog->source_group); - if (uri && strncmp(uri, "groupwise:", 10) == 0) { - gtk_widget_set_sensitive (GTK_WIDGET(sdialog->display_name), FALSE); - } - } + if (modify_func) + g_signal_connect (dialog->rootdn, "changed", + G_CALLBACK (modify_func), dialog); + + dialog->scope_optionmenu = glade_xml_get_widget (dialog->gui, "scope-optionmenu"); - g_object_unref(gui); + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU(dialog->scope_optionmenu)); + gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback)add_scope_activate_cb, dialog); - return w; + dialog->timeout_scale = glade_xml_get_widget (dialog->gui, "timeout-scale"); + + if (modify_func) + g_signal_connect (GTK_RANGE(dialog->timeout_scale)->adjustment, + "value_changed", + G_CALLBACK (modify_func), dialog); + + dialog->limit_spinbutton = glade_xml_get_widget (dialog->gui, "download-limit-spinbutton"); + if (modify_func) + g_signal_connect (dialog->limit_spinbutton, "changed", + G_CALLBACK (modify_func), dialog); + + /* special handling for the "Show Supported Bases button" */ + rootdn_button = glade_xml_get_widget (dialog->gui, "rootdn-button"); + g_signal_connect (rootdn_button, "clicked", + G_CALLBACK(query_for_supported_bases), dialog); } - -static GtkWidget * -eabc_general_offline(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, struct _GtkWidget *old, void *data) +static gboolean +searching_tab_check (AddressbookSourceDialog *dialog) { - AddressbookSourceDialog *sdialog = data; - GtkWidget *offline_setting; - const char *offline_sync; - int row; - gboolean is_local_book; - - is_local_book = g_str_has_prefix (e_source_group_peek_base_uri (sdialog->source_group), "file:"); - offline_sync = e_source_get_property (sdialog->source, "offline_sync"); - if (old) - return old; - else { - row = ((GtkTable*)parent)->nrows; - offline_setting = gtk_check_button_new_with_label (N_("Copy book content locally for offline operation")); - gtk_widget_show (offline_setting); - gtk_container_add (GTK_CONTAINER (parent), offline_setting); - g_signal_connect (offline_setting, "toggled", G_CALLBACK (offline_status_changed_cb), sdialog); - - } - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (offline_setting), (offline_sync && g_str_equal (offline_sync, "1")) ? TRUE : FALSE); - if (is_local_book) - gtk_widget_hide (offline_setting); - return offline_setting; + gboolean valid = TRUE; + gdouble timeout = 3; -} + timeout = gtk_adjustment_get_value (GTK_RANGE(dialog->timeout_scale)->adjustment); -#ifdef HAVE_LDAP -static void -url_changed(AddressbookSourceDialog *sdialog) -{ - char *str; - - str = g_strdup_printf ("%s:%s/%s?" /* trigraph prevention */ "?%s", - gtk_entry_get_text (GTK_ENTRY (sdialog->host)), - gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (sdialog->port_combo)->entry)), - gtk_entry_get_text (GTK_ENTRY (sdialog->rootdn)), - ldap_unparse_scope (sdialog->scope)); - e_source_set_relative_uri (sdialog->source, str); - g_free (str); + if(!timeout) + return FALSE; + return valid; } -static void -host_changed_cb(GtkWidget *w, AddressbookSourceDialog *sdialog) -{ - url_changed(sdialog); -} +#endif -static void -port_entry_changed_cb(GtkWidget *w, AddressbookSourceDialog *sdialog) + +/* display name page */ +static gboolean +display_name_check (AddressbookSourceDialog *dialog) { - const char *port = gtk_entry_get_text((GtkEntry *)w); + gboolean valid = TRUE; + const char *string; - if (!strcmp (port, LDAPS_PORT_STRING)) { - sdialog->ssl = ADDRESSBOOK_LDAP_SSL_ALWAYS; - gtk_option_menu_set_history (GTK_OPTION_MENU(sdialog->ssl_optionmenu), sdialog->ssl); - gtk_widget_set_sensitive (sdialog->ssl_optionmenu, FALSE); - } else { - gtk_widget_set_sensitive (sdialog->ssl_optionmenu, TRUE); - } + string = gtk_entry_get_text (GTK_ENTRY (dialog->display_name)); + if (!string || !string[0]) + valid = FALSE; - url_changed(sdialog); + return valid; } -static void -ssl_optionmenu_changed_cb(GtkWidget *w, AddressbookSourceDialog *sdialog) + +static gboolean +source_group_is_remote (ESourceGroup *group) { - sdialog->ssl = gtk_option_menu_get_history((GtkOptionMenu *)w); - e_source_set_property (sdialog->source, "ssl", ldap_unparse_ssl (sdialog->ssl)); + return !strcmp ("ldap://", e_source_group_peek_base_uri (group)); } - -static GtkWidget * -eabc_general_host(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, struct _GtkWidget *old, void *data) +static void +add_folder_modify (GtkWidget *widget, AddressbookSourceDialog *sdialog) { - AddressbookSourceDialog *sdialog = data; - const char *tmp; - GtkWidget *w; - char *uri, port[16]; - LDAPURLDesc *lud; - GladeXML *gui; + gboolean valid = TRUE; + gboolean remote = FALSE; - if (!source_group_is_remote(sdialog->source_group)) - return NULL; + valid = display_name_check (sdialog); + remote = source_group_is_remote (sdialog->source_group); - gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, item->label, NULL); - w = glade_xml_get_widget(gui, item->label); - gtk_box_pack_start((GtkBox *)parent, w, FALSE, FALSE, 0); - uri = e_source_get_uri(sdialog->source); - if (ldap_url_parse(uri, &lud) != LDAP_SUCCESS) - lud = NULL; - g_free(uri); + remote = source_group_is_remote (sdialog->source_group); + if (sdialog->server_frame) + gtk_widget_set_sensitive (sdialog->server_frame, remote); + + if (sdialog->auth_frame) + gtk_widget_set_sensitive (sdialog->auth_frame, remote); - sdialog->host = glade_xml_get_widget (gui, "server-name-entry"); - gtk_entry_set_text((GtkEntry *)sdialog->host, lud && lud->lud_host ? lud->lud_host : ""); - g_signal_connect (sdialog->host, "changed", G_CALLBACK (host_changed_cb), sdialog); +#ifdef HAVE_LDAP + gtk_widget_set_sensitive (sdialog->auth_principal, sdialog->auth != ADDRESSBOOK_LDAP_AUTH_NONE); - sdialog->port_combo = glade_xml_get_widget (gui, "port-combo"); - sprintf(port, "%u", lud && lud->lud_port? lud->lud_port : LDAP_PORT); - gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (sdialog->port_combo)->entry), port); - g_signal_connect (GTK_COMBO(sdialog->port_combo)->entry, "changed", G_CALLBACK (port_entry_changed_cb), sdialog); + if (valid) + valid = general_tab_check (sdialog); + if (valid) + valid = connecting_tab_check (sdialog); - if (lud) - ldap_free_urldesc (lud); + gtk_widget_set_sensitive (glade_xml_get_widget (sdialog->gui, "details-label"), valid && remote); - sdialog->ssl_optionmenu = glade_xml_get_widget (gui, "ssl-optionmenu"); - tmp = e_source_get_property (sdialog->source, "ssl"); - sdialog->ssl = tmp ? ldap_parse_ssl (tmp) : ADDRESSBOOK_LDAP_SSL_WHENEVER_POSSIBLE; - gtk_option_menu_set_history (GTK_OPTION_MENU(sdialog->ssl_optionmenu), sdialog->ssl); - g_signal_connect(sdialog->ssl_optionmenu, "changed", G_CALLBACK(ssl_optionmenu_changed_cb), sdialog); + gtk_widget_set_sensitive (glade_xml_get_widget (sdialog->gui, "details-vbox"), valid && remote); - g_object_unref(gui); + if (valid) + valid = searching_tab_check (sdialog); +#endif - return w; + gtk_widget_set_sensitive (sdialog->ok_button, valid); } static void -auth_entry_changed_cb(GtkWidget *w, AddressbookSourceDialog *sdialog) +source_group_changed_cb (GtkWidget *widget, AddressbookSourceDialog *sdialog) { - const char *principal = gtk_entry_get_text((GtkEntry *)w); - - /* seems messy ... but the api is */ - switch (sdialog->auth) { - case ADDRESSBOOK_LDAP_AUTH_SIMPLE_BINDDN: - e_source_set_property(sdialog->source, "email_addr", NULL); - e_source_set_property(sdialog->source, "binddn", principal); - break; - case ADDRESSBOOK_LDAP_AUTH_SIMPLE_EMAIL: - e_source_set_property(sdialog->source, "binddn", NULL); - e_source_set_property(sdialog->source, "email_addr", principal); - break; - case ADDRESSBOOK_LDAP_AUTH_NONE: - default: - e_source_set_property(sdialog->source, "email_addr", NULL); - e_source_set_property(sdialog->source, "binddn", NULL); - break; - } + sdialog->source_group = g_slist_nth (sdialog->menu_source_groups, + gtk_option_menu_get_history (GTK_OPTION_MENU (sdialog->group_optionmenu)))->data; + if (sdialog->auth_frame) + add_folder_modify (widget, sdialog); } static void -auth_optionmenu_changed_cb(GtkWidget *w, AddressbookSourceDialog *sdialog) +source_group_menu_add_groups (GtkMenuShell *menu_shell, ESourceList *source_list) { - sdialog->auth = gtk_option_menu_get_history((GtkOptionMenu *)w); - e_source_set_property (sdialog->source, "auth", ldap_unparse_auth (sdialog->auth)); + GSList *groups, *sl; + + groups = e_source_list_peek_groups (source_list); + for (sl = groups; sl; sl = g_slist_next (sl)) { + GtkWidget *menu_item; + ESourceGroup *group = sl->data; + +#ifndef HAVE_LDAP + /* If LDAP isn't configured, skip LDAP groups */ + if (!strcmp ("ldap://", e_source_group_peek_base_uri (group))) + continue; +#endif + menu_item = gtk_menu_item_new_with_label (e_source_group_peek_name (group)); + gtk_widget_show (menu_item); + gtk_menu_shell_append (menu_shell, menu_item); - /* make sure the right property is set for the auth - ugh, funny api */ - auth_entry_changed_cb(sdialog->auth_principal, sdialog); + if (!strcmp ("exchange://", e_source_group_peek_base_uri (group))) + gtk_widget_set_sensitive (menu_item, FALSE); + + } } -static GtkWidget * -eabc_general_auth(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, struct _GtkWidget *old, void *data) +static AddressbookSourceDialog * +addressbook_add_server_dialog (void) { - AddressbookSourceDialog *sdialog = data; - GtkWidget *w; - const char *tmp; - GladeXML *gui; - - if (!source_group_is_remote(sdialog->source_group)) + AddressbookSourceDialog *sdialog = g_new0 (AddressbookSourceDialog, 1); + GConfClient *gconf_client; + GSList *source_groups; + + gconf_client = gconf_client_get_default (); + sdialog->source_list = e_source_list_new_for_gconf (gconf_client, "/apps/evolution/addressbook/sources"); + g_object_unref (gconf_client); + + source_groups = e_source_list_peek_groups (sdialog->source_list); + if (!source_groups) { + g_warning ("Addressbook source groups are missing! Check your GConf setup."); + g_free (sdialog); return NULL; + } - gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, item->label, NULL); - w = glade_xml_get_widget(gui, item->label); - gtk_box_pack_start((GtkBox *)parent, w, FALSE, FALSE, 0); + sdialog->menu_source_groups = g_slist_copy (source_groups); - sdialog->auth_optionmenu = glade_xml_get_widget (gui, "auth-optionmenu"); - tmp = e_source_get_property(sdialog->source, "auth"); - sdialog->auth = tmp ? ldap_parse_auth(tmp) : ADDRESSBOOK_LDAP_AUTH_NONE; - gtk_option_menu_set_history (GTK_OPTION_MENU(sdialog->auth_optionmenu), sdialog->auth); - g_signal_connect(sdialog->auth_optionmenu, "changed", G_CALLBACK(auth_optionmenu_changed_cb), sdialog); + sdialog->gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, "account-add-window", NULL); - sdialog->auth_principal = glade_xml_get_widget (gui, "auth-entry"); - switch (sdialog->auth) { - case ADDRESSBOOK_LDAP_AUTH_SIMPLE_EMAIL: - tmp = e_source_get_property(sdialog->source, "email_addr"); - break; - case ADDRESSBOOK_LDAP_AUTH_SIMPLE_BINDDN: - tmp = e_source_get_property(sdialog->source, "binddn"); - break; - case ADDRESSBOOK_LDAP_AUTH_NONE: - default: - tmp = ""; - break; - } - gtk_entry_set_text((GtkEntry *)sdialog->auth_principal, tmp?tmp:""); - g_signal_connect (sdialog->auth_principal, "changed", G_CALLBACK (auth_entry_changed_cb), sdialog); + sdialog->window = glade_xml_get_widget (sdialog->gui, "account-add-window"); + + gtk_widget_ensure_style (sdialog->window); + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (sdialog->window)->vbox), 0); + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (sdialog->window)->action_area), 12); - g_object_unref(gui); + sdialog->display_name = glade_xml_get_widget (sdialog->gui, "display-name-entry"); + g_signal_connect (sdialog->display_name, "changed", + G_CALLBACK (add_folder_modify), sdialog); - return w; -} - -static void -rootdn_changed_cb(GtkWidget *w, AddressbookSourceDialog *sdialog) -{ - url_changed(sdialog); -} +#ifndef HAVE_LDAP + for ( ; source_groups != NULL; source_groups = g_slist_next (source_groups)) + if (!strcmp ("ldap://", e_source_group_peek_base_uri (source_groups->data))) + sdialog->menu_source_groups = g_slist_remove (sdialog->menu_source_groups, source_groups->data); +#endif + + sdialog->group_optionmenu = glade_xml_get_widget (sdialog->gui, "group-optionmenu"); + if (!GTK_IS_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (sdialog->group_optionmenu)))) { + GtkWidget *menu = gtk_menu_new (); + gtk_option_menu_set_menu (GTK_OPTION_MENU (sdialog->group_optionmenu), menu); + gtk_widget_show (menu); + } -static void -scope_optionmenu_changed_cb(GtkWidget *w, AddressbookSourceDialog *sdialog) -{ - sdialog->scope = gtk_option_menu_get_history((GtkOptionMenu *)w); - url_changed(sdialog); -} + /* NOTE: This assumes that we have sources. If they don't exist, they're set up + * on startup of the Addressbook component. */ + source_group_menu_add_groups (GTK_MENU_SHELL (gtk_option_menu_get_menu ( + GTK_OPTION_MENU (sdialog->group_optionmenu))), sdialog->source_list); + gtk_option_menu_set_history (GTK_OPTION_MENU (sdialog->group_optionmenu), 0); + sdialog->source_group = e_source_list_peek_groups (sdialog->source_list)->data; + g_signal_connect (sdialog->group_optionmenu, "changed", + G_CALLBACK (source_group_changed_cb), sdialog); -static GtkWidget * -eabc_details_search(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, struct _GtkWidget *old, void *data) -{ - AddressbookSourceDialog *sdialog = data; - GtkWidget *w; - LDAPURLDesc *lud; - char *uri; - GladeXML *gui; + setup_general_tab (sdialog, add_folder_modify); +#ifdef HAVE_LDAP + setup_connecting_tab (sdialog, add_folder_modify); - if (!source_group_is_remote(sdialog->source_group)) - return NULL; + setup_searching_tab (sdialog, add_folder_modify); +#endif - gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, item->label, NULL); - w = glade_xml_get_widget(gui, item->label); - gtk_box_pack_start((GtkBox *)parent, w, FALSE, FALSE, 0); + sdialog->auth_frame = glade_xml_get_widget (sdialog->gui, "authentication-frame"); + sdialog->server_frame = glade_xml_get_widget (sdialog->gui, "server-frame"); - uri = e_source_get_uri(sdialog->source); - if (ldap_url_parse(uri, &lud) != LDAP_SUCCESS) - lud = NULL; - g_free(uri); + sdialog->ok_button = glade_xml_get_widget (sdialog->gui, "ok-button"); + g_signal_connect (sdialog->ok_button, "clicked", + G_CALLBACK(addressbook_add_server_dialog_finish), sdialog); - sdialog->rootdn = glade_xml_get_widget (gui, "rootdn-entry"); - gtk_entry_set_text((GtkEntry *)sdialog->rootdn, lud && lud->lud_dn ? lud->lud_dn : ""); - g_signal_connect (sdialog->rootdn, "changed", G_CALLBACK (rootdn_changed_cb), sdialog); + sdialog->cancel_button = glade_xml_get_widget (sdialog->gui, "cancel-button"); + g_signal_connect (sdialog->cancel_button, "clicked", + G_CALLBACK(addressbook_add_server_dialog_cancel), sdialog); - sdialog->scope_optionmenu = glade_xml_get_widget (gui, "scope-optionmenu"); - switch (lud->lud_scope) { - case LDAP_SCOPE_BASE: - sdialog->scope = ADDRESSBOOK_LDAP_SCOPE_BASE; - break; - default: - case LDAP_SCOPE_ONELEVEL: - sdialog->scope = ADDRESSBOOK_LDAP_SCOPE_ONELEVEL; - break; - case LDAP_SCOPE_SUBTREE: - sdialog->scope = ADDRESSBOOK_LDAP_SCOPE_SUBTREE; - break; - } - gtk_option_menu_set_history (GTK_OPTION_MENU(sdialog->scope_optionmenu), sdialog->scope); - g_signal_connect(sdialog->scope_optionmenu, "changed", G_CALLBACK(scope_optionmenu_changed_cb), sdialog); + g_object_weak_ref (G_OBJECT (sdialog->window), + addressbook_source_dialog_destroy, sdialog); - g_signal_connect (glade_xml_get_widget(gui, "rootdn-button"), "clicked", - G_CALLBACK(query_for_supported_bases), sdialog); + /* make sure we fill in the default values */ + source_to_dialog (sdialog); - if (lud) - ldap_free_urldesc (lud); + gtk_window_set_type_hint (GTK_WINDOW (sdialog->window), GDK_WINDOW_TYPE_HINT_DIALOG); + + add_folder_modify (sdialog->window, sdialog); - g_object_unref(gui); + gtk_widget_show_all (sdialog->window); - return w; + return sdialog; } static void -timeout_changed_cb(GtkWidget *w, AddressbookSourceDialog *sdialog) +editor_modify_cb (GtkWidget *item, AddressbookSourceDialog *dialog) { - char *timeout; + gboolean valid = TRUE; - timeout = g_strdup_printf("%f", gtk_adjustment_get_value(((GtkRange *)sdialog->timeout_scale)->adjustment)); - e_source_set_property(sdialog->source, "timeout", timeout); - g_free(timeout); + valid = display_name_check (dialog); +#ifdef HAVE_LDAP + if (valid) + valid = general_tab_check (dialog); + if (valid) + valid = connecting_tab_check (dialog); + if (valid) + valid = searching_tab_check (dialog); +#endif + + gtk_widget_set_sensitive (dialog->ok_button, valid); } static void -limit_changed_cb(GtkWidget *w, AddressbookSourceDialog *sdialog) +set_advanced_button_state (AddressbookSourceDialog *dialog) { - char limit[16]; + if (dialog->advanced) { + gtk_notebook_set_current_page (GTK_NOTEBOOK(dialog->advanced_button_notebook), 0); +#ifdef NEW_ADVANCED_UI + gtk_notebook_append_page (GTK_NOTEBOOK(dialog->notebook), dialog->objectclasses_tab, dialog->objectclasses_label); + gtk_notebook_append_page (GTK_NOTEBOOK(dialog->notebook), dialog->mappings_tab, dialog->mappings_label); + gtk_notebook_append_page (GTK_NOTEBOOK(dialog->notebook), dialog->dn_customization_tab, dialog->dn_customization_label); +#endif + } + else { +#ifdef NEW_ADVANCED_UI + gtk_notebook_set_current_page (GTK_NOTEBOOK(dialog->advanced_button_notebook), 1); + + /* hide the advanced tabs of the main notebook */ + gtk_notebook_remove_page (GTK_NOTEBOOK(dialog->notebook), 5); + gtk_notebook_remove_page (GTK_NOTEBOOK(dialog->notebook), 4); + gtk_notebook_remove_page (GTK_NOTEBOOK(dialog->notebook), 3); +#endif + } +} - sprintf(limit, "%d", gtk_spin_button_get_value_as_int((GtkSpinButton *)sdialog->limit_spinbutton)); - e_source_set_property(sdialog->source, "limit", limit); +#ifdef NEW_ADVANCED_UI +static void +advanced_button_clicked (GtkWidget *button, AddressbookSourceDialog *dialog) +{ + dialog->advanced = !dialog->advanced; + set_advanced_button_state (dialog); } -static GtkWidget * -eabc_details_limit(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, struct _GtkWidget *old, void *data) +static gboolean +do_schema_query (AddressbookSourceDialog *sdialog) { - AddressbookSourceDialog *sdialog = data; - GtkWidget *w; - const char *tmp; - GladeXML *gui; + LDAP *ldap; + int ldap_error; + char *schema_dn; + char *attrs[3]; + char **values; + int i; + AddressbookSource *source = addressbook_dialog_get_source (sdialog); + LDAPMessage *resp; + struct timeval timeout; - if (!source_group_is_remote(sdialog->source_group)) - return NULL; + ldap = addressbook_ldap_init (sdialog->window, source); + if (!ldap) + goto fail; - gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, item->label, NULL); - w = glade_xml_get_widget(gui, item->label); - gtk_box_pack_start((GtkBox *)parent, w, FALSE, FALSE, 0); + if (LDAP_SUCCESS != addressbook_ldap_auth (sdialog->window, source, ldap)) + goto fail; - sdialog->timeout_scale = glade_xml_get_widget (gui, "timeout-scale"); - tmp = e_source_get_property(sdialog->source, "timeout"); - gtk_adjustment_set_value(((GtkRange *)sdialog->timeout_scale)->adjustment, tmp?g_strtod(tmp, NULL):3.0); - g_signal_connect (GTK_RANGE(sdialog->timeout_scale)->adjustment, "value_changed", G_CALLBACK (timeout_changed_cb), sdialog); + attrs[0] = "subschemaSubentry"; + attrs[1] = NULL; - sdialog->limit_spinbutton = glade_xml_get_widget (gui, "download-limit-spinbutton"); - tmp = e_source_get_property(sdialog->source, "limit"); - gtk_spin_button_set_value((GtkSpinButton *)sdialog->limit_spinbutton, tmp?g_strtod(tmp, NULL):100.0); - g_signal_connect (sdialog->limit_spinbutton, "value_changed", G_CALLBACK (limit_changed_cb), sdialog); + ldap_error = addressbook_root_dse_query (sdialog->window, source, ldap, attrs, &resp); - g_object_unref(gui); + if (ldap_error != LDAP_SUCCESS) + goto fail; - return w; -} -#endif + values = ldap_get_values (ldap, resp, "subschemaSubentry"); + if (!values || values[0] == NULL) { + e_error_run ((GtkWindow *) sdialog->window, "addressbook:ldap-v3-schema", NULL); + goto fail; + } -static EConfigItem eabc_items[] = { - { E_CONFIG_BOOK, "", }, - { E_CONFIG_PAGE, "00.general", N_("General") }, - { E_CONFIG_SECTION, "00.general/10.display", N_("Addressbook") }, - { E_CONFIG_ITEM, "00.general/10.display/10.name", "hbox122", eabc_general_name }, - { E_CONFIG_ITEM, "00.general/10.display/20.offline", NULL, eabc_general_offline }, -#ifdef HAVE_LDAP - { E_CONFIG_SECTION, "00.general/20.server", N_("Server Information") }, - { E_CONFIG_ITEM, "00.general/20.server/00.host", "table31", eabc_general_host }, - { E_CONFIG_SECTION, "00.general/30.auth", N_("Authentication") }, - { E_CONFIG_ITEM, "00.general/30.auth/00.auth", "table32", eabc_general_auth }, - - { E_CONFIG_PAGE, "10.details", N_("Details") }, - { E_CONFIG_SECTION, "10.details/00.search", N_("Searching") }, - { E_CONFIG_ITEM, "10.details/00.search/00.search", "table33", eabc_details_search }, - { E_CONFIG_SECTION, "10.details/10.limit", N_("Downloading") }, - { E_CONFIG_ITEM, "10.details/10.limit/00.limit", "table34", eabc_details_limit }, -#endif - { 0 }, -}; + schema_dn = g_strdup (values[0]); -/* items needed for the 'new addressbook' window */ -static EConfigItem eabc_new_items[] = { - { E_CONFIG_ITEM, "00.general/10.display/00.type", NULL, eabc_general_type }, - { 0 }, -}; + ldap_value_free (values); + ldap_msgfree (resp); -static void -eabc_commit(EConfig *ec, GSList *items, void *data) -{ - AddressbookSourceDialog *sdialog = data; - xmlNodePtr xml; -#if d(!)0 - char *txt; -#endif - if (sdialog->original_source) { - d(printf("committing addressbook changes\n")); - - /* these api's kinda suck */ - xml = xmlNewNode(NULL, "dummy"); - e_source_dump_to_xml_node(sdialog->source, xml); - e_source_update_from_xml_node(sdialog->original_source, xml->children, NULL); - xmlFreeNode(xml); -#if d(!)0 - txt = e_source_to_standalone_xml(sdialog->original_source); - printf("source is now:\n%s\n", txt); - g_free(txt); -#endif - } else { - d(printf("committing new source\n")); - e_source_group_add_source(sdialog->source_group, sdialog->source, -1); - e_source_list_sync(sdialog->source_list, NULL); - } + attrs[0] = "objectClasses"; + attrs[1] = NULL; -#if d(!)0 - txt = e_source_to_standalone_xml(sdialog->source); - printf("running source is now:\n%s\n", txt); - g_free(txt); -#endif -} + timeout.tv_sec = (gint) gtk_adjustment_get_value (GTK_RANGE(sdialog->timeout_scale)->adjustment); + timeout.tv_usec = 0; -static void -eabc_free(EConfig *ec, GSList *items, void *data) -{ - AddressbookSourceDialog *sdialog = data; + ldap_error = ldap_search_ext_s (ldap, schema_dn, LDAP_SCOPE_BASE, + "(objectClass=subschema)", attrs, 0, + NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp); + if (LDAP_SUCCESS != ldap_error) { + e_error_run ((GtkWindow *) sdialog->window, "addressbook:ldap-get-schema", NULL); + goto fail; + } - g_slist_free(items); + if (!(values = ldap_get_values (ldap, resp, "objectClasses"))) { + e_error_run ((GtkWindow *) sdialog->window, "addressbook:ldap-invalid-schema", NULL); + goto fail; + } - g_object_unref(sdialog->source); - if (sdialog->original_source) - g_object_unref(sdialog->original_source); - if (sdialog->source_list) - g_object_unref(sdialog->source_list); - g_slist_free(sdialog->menu_source_groups); + for (i = 0; values[i]; i ++) { + int j; + int code; + const char *err; + LDAPObjectClass *oc = ldap_str2objectclass (values[i], &code, &err, 0); + + if (!oc) + continue; + + /* we fill in the default list of classes here */ + for (j = 0; oc->oc_names[j]; j ++) { + if (!g_strcasecmp (oc->oc_names[j], EVOLUTIONPERSON) || + !g_strcasecmp (oc->oc_names[j], INETORGPERSON) || + !g_strcasecmp (oc->oc_names[j], ORGANIZATIONALPERSON) || + !g_strcasecmp (oc->oc_names[j], PERSON) || + !g_strcasecmp (oc->oc_names[j], CALENTRY) || + !g_strcasecmp (oc->oc_names[j], TOP)) + g_ptr_array_add (sdialog->default_objectclasses, oc); + } - g_object_unref(sdialog->gui); + g_ptr_array_add (sdialog->server_objectclasses, oc); + } - g_free(sdialog); + addressbook_source_free (source); + ldap_unbind_s (ldap); + return TRUE; + + fail: + addressbook_source_free (source); + if (ldap) + ldap_unbind_s (ldap); + return FALSE; } -static gboolean -eabc_check_complete(EConfig *ec, const char *pageid, void *data) +static void +edit_dialog_switch_page (GtkNotebook *notebook, + GtkNotebookPage *page, guint page_num, + AddressbookSourceDialog *sdialog) { - AddressbookSourceDialog *sdialog = data; - int valid = TRUE; - const char *tmp; - ESource *source; + if (page_num >= 3 && !sdialog->schema_query_successful) { + int i; - d(printf("check complete, pageid = '%s'\n", pageid?pageid:"<all>")); - /* have name, and unique */ - tmp = e_source_peek_name(sdialog->source); - valid = tmp && tmp[0] != 0 - && ((source = e_source_group_peek_source_by_name(sdialog->source_group, tmp)) == NULL - || source == sdialog->original_source); + gtk_widget_set_sensitive (GTK_WIDGET (notebook), FALSE); -#ifdef HAVE_LDAP - if (valid && source_group_is_remote(sdialog->source_group)) { - char *uri = e_source_get_uri(sdialog->source); - LDAPURLDesc *lud; - - /* check host and port set */ - if (ldap_url_parse(uri, &lud) == LDAP_SUCCESS) { - valid = lud->lud_host != NULL - && lud->lud_host[0] != 0 - && lud->lud_port != 0; - ldap_free_urldesc (lud); - } else - valid = FALSE; - g_free(uri); - - /* check auth name provided if auth set */ - if (valid && (tmp = e_source_get_property(sdialog->source, "auth"))) { - switch (ldap_parse_auth(tmp)) { - case ADDRESSBOOK_LDAP_AUTH_SIMPLE_EMAIL: - tmp = e_source_get_property(sdialog->source, "email_addr"); - break; - case ADDRESSBOOK_LDAP_AUTH_SIMPLE_BINDDN: - tmp = e_source_get_property(sdialog->source, "binddn"); - break; - default: - tmp = "dummy"; - break; + sdialog->schema_query_successful = do_schema_query (sdialog); + + if (sdialog->schema_query_successful) { + /* fill in the objectclasses model */ + for (i = 0; i < sdialog->server_objectclasses->len; i ++) { + LDAPObjectClass *oc = g_ptr_array_index (sdialog->server_objectclasses, i); + e_table_memory_store_insert (E_TABLE_MEMORY_STORE (sdialog->objectclasses_server_model), + -1, oc, oc->oc_names[0]); } - valid = tmp && tmp[0]; + gtk_widget_set_sensitive (page->child, TRUE); } - - /* check timeout isn't too short (why don't we just force it?) */ - if (valid) { - tmp = e_source_get_property(sdialog->source, "timeout"); - valid = tmp && g_strtod(tmp, NULL) > 0.0; + else { + gtk_widget_set_sensitive (page->child, FALSE); } + + gtk_widget_set_sensitive (GTK_WIDGET (notebook), TRUE); } +} #endif - return valid; + +static gboolean +edit_dialog_store_change (AddressbookSourceDialog *sdialog) +{ + dialog_to_source (sdialog, sdialog->source, FALSE); + + /* check the display name for uniqueness */ + if (FALSE /* XXX */) { + return FALSE; + } + + return TRUE; } -/* debug only: */ -#if d(!)0 static void -source_changed(ESource *source, AddressbookSourceDialog *sdialog) +edit_dialog_cancel_clicked (GtkWidget *item, AddressbookSourceDialog *sdialog) { - char *xml; + gtk_widget_destroy (sdialog->window); +} - xml = e_source_to_standalone_xml(source); - printf("source changed:\n%s\n", xml); - g_free(xml); +static void +edit_dialog_ok_clicked (GtkWidget *item, AddressbookSourceDialog *sdialog) +{ + if (edit_dialog_store_change (sdialog)) { + gtk_widget_destroy (sdialog->window); + } } -#endif GtkWidget* addressbook_config_edit_source (GtkWidget *parent, ESource *source) { AddressbookSourceDialog *sdialog = g_new0 (AddressbookSourceDialog, 1); - EABConfig *ec; - int i; - GSList *items = NULL; - EABConfigTargetSource *target; - char *xml; - - sdialog->gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, "account-editor-notebook", NULL); - - if (source) { - sdialog->original_source = source; - g_object_ref(source); - sdialog->source_group = e_source_peek_group (source); - xml = e_source_to_standalone_xml(source); - sdialog->source = e_source_new_from_standalone_xml(xml); - g_free(xml); - } else { - GConfClient *gconf; - GSList *l; - - sdialog->source = e_source_new("", ""); - gconf = gconf_client_get_default(); - sdialog->source_list = e_source_list_new_for_gconf(gconf, "/apps/evolution/addressbook/sources"); - l = e_source_list_peek_groups(sdialog->source_list); - if (!l) { - g_warning ("Addressbook source groups are missing! Check your GConf setup."); - g_free (sdialog); - return NULL; - } + GConfClient *gconf_client; - sdialog->menu_source_groups = g_slist_copy(l); -#ifndef HAVE_LDAP - for (;l;l = g_slist_next(l)) - if (!strncmp("ldap:", e_source_group_peek_base_uri(l->data), 5)) - sdialog->menu_source_groups = g_slist_remove (sdialog->menu_source_groups, l->data); -#endif - sdialog->source_group = (ESourceGroup *)sdialog->menu_source_groups->data; - for (i=0;eabc_new_items[i].path;i++) - items = g_slist_prepend(items, &eabc_new_items[i]); - g_object_unref(gconf); - } + gconf_client = gconf_client_get_default (); + sdialog->source_list = e_source_list_new_for_gconf (gconf_client, "/apps/evolution/addressbook/sources"); + g_object_unref (gconf_client); + + sdialog->gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, "account-editor-window", NULL); + sdialog->window = glade_xml_get_widget (sdialog->gui, "account-editor-window"); + gtk_widget_realize (sdialog->window); + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (sdialog->window)->vbox), 0); + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (sdialog->window)->action_area), 12); - /* HACK: doesn't work if you don't do this */ - e_source_set_absolute_uri(sdialog->source, NULL); - e_source_set_group(sdialog->source, sdialog->source_group); + sdialog->source = source; + sdialog->source_group = e_source_peek_group (source); -#if d(!)0 - xml = e_source_to_standalone_xml(sdialog->source); - printf("but working standalone xml: %s\n", xml); - g_free(xml); - g_signal_connect(sdialog->source, "changed", source_changed, sdialog); + sdialog->display_name = glade_xml_get_widget (sdialog->gui, "account-editor-display-name-entry"); + g_signal_connect (sdialog->display_name, "changed", + G_CALLBACK (editor_modify_cb), sdialog); + + setup_general_tab (sdialog, editor_modify_cb); +#ifdef HAVE_LDAP + setup_connecting_tab (sdialog, editor_modify_cb); + + setup_searching_tab (sdialog, editor_modify_cb); #endif - sdialog->config = ec = eab_config_new(E_CONFIG_BOOK, "com.novell.evolution.addressbook.config.accountEditor"); + sdialog->notebook = glade_xml_get_widget (sdialog->gui, "account-editor-notebook"); - for (i=0;eabc_items[i].path;i++) - items = g_slist_prepend(items, &eabc_items[i]); + sdialog->ok_button = glade_xml_get_widget (sdialog->gui, "account-editor-ok-button"); + sdialog->cancel_button = glade_xml_get_widget (sdialog->gui, "account-editor-cancel-button"); + +#ifdef HAVE_LDAP + if (strcmp ("ldap://", e_source_group_peek_base_uri (sdialog->source_group))) { + gtk_widget_hide (glade_xml_get_widget (sdialog->gui, "account-editor-connecting-vbox")); + gtk_widget_hide (glade_xml_get_widget (sdialog->gui, "account-editor-searching-vbox")); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (sdialog->notebook), FALSE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (sdialog->notebook), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (glade_xml_get_widget (sdialog->gui, "account-editor-general-vbox")), 0); + gtk_window_set_default_size (GTK_WINDOW (sdialog->window), 332, 124); + } else { + gtk_widget_show (glade_xml_get_widget (sdialog->gui, "account-editor-connecting-vbox")); + gtk_widget_show (glade_xml_get_widget (sdialog->gui, "account-editor-searching-vbox")); + } +#else + gtk_widget_hide (glade_xml_get_widget (sdialog->gui, "account-editor-connecting-vbox")); + gtk_widget_hide (glade_xml_get_widget (sdialog->gui, "account-editor-searching-vbox")); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (sdialog->notebook), FALSE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (sdialog->notebook), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (glade_xml_get_widget (sdialog->gui, "account-editor-general-vbox")), 0); +#endif - e_config_add_items((EConfig *)ec, items, eabc_commit, NULL, eabc_free, sdialog); - e_config_add_page_check((EConfig *)ec, NULL, eabc_check_complete, sdialog); + source_to_dialog (sdialog); - target = eab_config_target_new_source(ec, sdialog->source); - e_config_set_target((EConfig *)ec, (EConfigTarget *)target); + set_advanced_button_state (sdialog); - if(source) - sdialog->window = e_config_create_window((EConfig *)ec, NULL, _("Address Book Properties")); - else - sdialog->window = e_config_create_window((EConfig *)ec, NULL, _("New Address Book")); + g_signal_connect (sdialog->ok_button, + "clicked", G_CALLBACK(edit_dialog_ok_clicked), sdialog); + g_signal_connect (sdialog->cancel_button, + "clicked", G_CALLBACK(edit_dialog_cancel_clicked), sdialog); + g_object_weak_ref (G_OBJECT (sdialog->window), + addressbook_source_dialog_destroy, sdialog); + gtk_widget_set_sensitive (sdialog->ok_button, FALSE); - /* forces initial validation */ - if (!sdialog->original_source) - e_config_target_changed((EConfig *)ec, E_CONFIG_TARGET_CHANGED_STATE); + gtk_widget_show (sdialog->window); return sdialog->window; } + +GtkWidget* +addressbook_config_create_new_source (GtkWidget *parent) +{ + AddressbookSourceDialog *dialog; + + dialog = addressbook_add_server_dialog (); + + return dialog ? dialog->window : NULL; +} diff --git a/addressbook/gui/component/addressbook-view.c b/addressbook/gui/component/addressbook-view.c index f8b4802c0d..368c0c4540 100644 --- a/addressbook/gui/component/addressbook-view.c +++ b/addressbook/gui/component/addressbook-view.c @@ -21,9 +21,7 @@ * Author: Chris Toshok (toshok@ximian.com) */ -#ifdef HAVE_CONFIG_H #include <config.h> -#endif #include <string.h> #include <glib.h> @@ -39,12 +37,11 @@ #include <bonobo/bonobo-ui-util.h> #include <bonobo/bonobo-exception.h> #include <gal/util/e-util.h> -#include <libedataserverui/e-source-selector.h> #include "widgets/misc/e-error.h" #include "widgets/misc/e-task-bar.h" #include "widgets/misc/e-info-label.h" - +#include "widgets/misc/e-source-selector.h" #include "e-util/e-passwords.h" #include "e-util/e-icon-factory.h" @@ -63,8 +60,6 @@ #include "addressbook/gui/merging/eab-contact-merging.h" #include "addressbook/printing/e-contact-print.h" #include "addressbook/util/eab-book-util.h" -#include "addressbook/gui/widgets/eab-popup.h" -#include "addressbook/gui/widgets/eab-menu.h" #define PARENT_TYPE G_TYPE_OBJECT static GObjectClass *parent_class = NULL; @@ -96,8 +91,6 @@ struct _AddressbookViewPrivate { ESourceList *source_list; char *passwd; EUserCreatableItemsHandler *creatable_items_handler; - - EABMenu *menu; }; enum DndTargetType { @@ -342,20 +335,14 @@ update_command_state (EABView *eav, AddressbookView *view) { AddressbookViewPrivate *priv = view->priv; BonoboUIComponent *uic; - EABMenuTargetSelect *target; if (eav != get_current_view (view)) return; g_object_ref (view); - target = eab_view_get_menu_target(eav, priv->menu); - e_menu_update_target((EMenu *)priv->menu, target); - uic = bonobo_control_get_ui_component (priv->folder_view_control); - /* TODO: this stuff can mostly be made to use the target bits instead */ - if (bonobo_ui_component_get_container (uic) != CORBA_OBJECT_NIL) { #define SET_SENSITIVE(verb,f) \ bonobo_ui_component_set_prop (uic, (verb), "sensitive", (f)(eav) ? "1" : "0", NULL) @@ -475,11 +462,9 @@ control_activate_cb (BonoboControl *control, if (activate) { control_activate (control, uic, view); - e_menu_activate((EMenu *)view->priv->menu, uic, activate); if (activate && v && v->model) eab_model_force_folder_bar_message (v->model); } else { - e_menu_activate((EMenu *)view->priv->menu, uic, activate); bonobo_ui_component_unset_container (uic, NULL); eab_view_discard_menus (v); } @@ -628,10 +613,45 @@ load_primary_selection (AddressbookView *view) } /* Folder popup menu callbacks */ + +static void +add_popup_menu_item (GtkMenu *menu, const char *label, const char *pixmap, + GCallback callback, gpointer user_data, gboolean sensitive) +{ + GtkWidget *item, *image; + + if (pixmap) { + item = gtk_image_menu_item_new_with_label (label); + + /* load the image */ + if (g_file_test (pixmap, G_FILE_TEST_EXISTS)) + image = gtk_image_new_from_file (pixmap); + else + image = gtk_image_new_from_stock (pixmap, GTK_ICON_SIZE_MENU); + + if (image) { + gtk_widget_show (image); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + } + } else { + item = gtk_menu_item_new_with_label (label); + } + + if (callback) + g_signal_connect (G_OBJECT (item), "activate", callback, user_data); + + if (!sensitive) + gtk_widget_set_sensitive (item, FALSE); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); +} + typedef struct { AddressbookView *view; ESource *selected_source; GtkWidget *toplevel; + GtkWidget *dialog; } BookRemovedClosure; static void @@ -641,6 +661,7 @@ book_removed (EBook *book, EBookStatus status, gpointer data) AddressbookView *view = closure->view; AddressbookViewPrivate *priv = view->priv; ESource *source = closure->selected_source; + GtkWidget *dialog = closure->dialog; GtkWidget *toplevel = closure->toplevel; g_free (closure); @@ -663,54 +684,73 @@ book_removed (EBook *book, EBookStatus status, gpointer data) "addressbook:remove-addressbook", NULL); } + + gtk_widget_destroy (dialog); } static void -delete_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) +delete_addressbook_cb (GtkWidget *widget, AddressbookView *view) { - AddressbookView *view = data; AddressbookViewPrivate *priv = view->priv; ESource *selected_source; + GtkWidget *dialog; EBook *book; GError *error = NULL; - GtkWindow *toplevel; selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector)); if (!selected_source) return; - toplevel = (GtkWindow *)gtk_widget_get_toplevel(ep->target->widget); + /* Create the confirmation dialog */ + dialog = gtk_message_dialog_new ( + GTK_WINDOW (gtk_widget_get_toplevel (widget)), + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + _("Address book '%s' will be removed. Are you sure you want to continue?"), + e_source_peek_name (selected_source)); +#if !GTK_CHECK_VERSION (2,4,0) + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); +#endif - if (e_error_run(toplevel, "addressbook:ask-delete-addressbook", e_source_peek_name(selected_source)) != GTK_RESPONSE_YES) + if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_YES) { + gtk_widget_destroy (dialog); return; + } /* Remove local data */ book = e_book_new (selected_source, &error); if (book) { BookRemovedClosure *closure = g_new (BookRemovedClosure, 1); - closure->toplevel = (GtkWidget *)toplevel; + closure->toplevel = gtk_widget_get_toplevel (widget); closure->view = view; closure->selected_source = selected_source; + closure->dialog = dialog; if (e_book_async_remove (book, book_removed, closure)) { - e_error_run (toplevel, "addressbook:remove-addressbook", NULL); + e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (widget)), + "addressbook:remove-addressbook", + NULL); + g_free (closure); + g_object_unref (book); } } + + gtk_widget_set_sensitive (dialog, FALSE); } static void -new_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) +new_addressbook_cb (GtkWidget *widget, AddressbookView *view) { - addressbook_config_create_new_source (gtk_widget_get_toplevel(ep->target->widget)); + addressbook_config_create_new_source (gtk_widget_get_toplevel (widget)); } static void -edit_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) +edit_addressbook_cb (GtkWidget *widget, AddressbookView *view) { - AddressbookView *view = data; AddressbookViewPrivate *priv = view->priv; ESource *selected_source; const char *uid; @@ -728,7 +768,7 @@ edit_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) char *uid_copy = g_strdup (uid); closure = g_new (EditorUidClosure, 1); - closure->editor = addressbook_config_edit_source (gtk_widget_get_toplevel(ep->target->widget), selected_source); + closure->editor = addressbook_config_edit_source (gtk_widget_get_toplevel (widget), selected_source); closure->uid = uid_copy; closure->view = view; @@ -753,41 +793,25 @@ primary_source_selection_changed_callback (ESourceSelector *selector, save_primary_selection (view); } -static EPopupItem abv_source_popups[] = { - { E_POPUP_ITEM, "10.new", N_("New Address Book"), new_addressbook_cb, NULL, "stock_contact", 0, 0 }, - { E_POPUP_ITEM, "20.delete", N_("Delete"), delete_addressbook_cb, NULL, "stock_delete", 0, EAB_POPUP_SOURCE_USER|EAB_POPUP_SOURCE_PRIMARY }, - { E_POPUP_BAR, "30.bar"}, - { E_POPUP_ITEM, "30.properties", N_("Properties..."), edit_addressbook_cb, NULL,"stock_folder-properties", 0, EAB_POPUP_SOURCE_PRIMARY }, -}; static void -abv_source_popup_free(EPopup *ep, GSList *list, void *data) -{ - g_slist_free(list); -} - -static gboolean -popup_event_callback(ESourceSelector *selector, ESource *source, GdkEventButton *event, AddressbookView *view) +fill_popup_menu_callback (ESourceSelector *selector, GtkMenu *menu, AddressbookView *view) { - EABPopup *ep; - EABPopupTargetSource *t; - GSList *menus = NULL; - int i; - GtkMenu *menu; - - ep = eab_popup_new("org.gnome.evolution.addressbook.source.popup"); - t = eab_popup_target_new_source(ep, selector); - t->target.widget = (GtkWidget *)view->priv->notebook; - - for (i=0;i<sizeof(abv_source_popups)/sizeof(abv_source_popups[0]);i++) - menus = g_slist_prepend(menus, &abv_source_popups[i]); - - e_popup_add_items((EPopup *)ep, menus, NULL, abv_source_popup_free, view); + AddressbookViewPrivate *priv = view->priv; + gboolean sensitive; + gboolean local_addressbook; + ESource *selected_source; + char *uri; - menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0); - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time()); + selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector)); + sensitive = selected_source ? TRUE : FALSE; - return TRUE; + uri = e_source_peek_relative_uri (selected_source); + local_addressbook = (uri && !strcmp ("system", uri)); + + add_popup_menu_item (menu, _("New Address Book"), NULL, G_CALLBACK (new_addressbook_cb), view, TRUE); + add_popup_menu_item (menu, _("Delete"), GTK_STOCK_DELETE, G_CALLBACK (delete_addressbook_cb), view, sensitive && !local_addressbook); + add_popup_menu_item (menu, _("Properties..."), NULL, G_CALLBACK (edit_addressbook_cb), view, sensitive); } static gboolean @@ -953,13 +977,15 @@ selector_tree_drag_data_received (GtkWidget *widget, { GtkTreePath *path = NULL; GtkTreeViewDropPosition pos; - gpointer target = NULL; + gpointer source, target = NULL; GtkTreeModel *model; GtkTreeIter iter; gboolean success = FALSE; + EBook *source_book, *target_book; MergeContext *merge_context; GList *contactlist; + GList *l; if (!gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget), x, y, &path, &pos)) @@ -1075,7 +1101,6 @@ addressbook_view_init (AddressbookView *view) { AddressbookViewPrivate *priv; GtkWidget *selector_scrolled_window; - AtkObject *a11y; view->priv = priv = g_new0 (AddressbookViewPrivate, 1); @@ -1102,7 +1127,6 @@ addressbook_view_init (AddressbookView *view) G_CALLBACK (source_list_changed_cb), view); priv->creatable_items_handler = e_user_creatable_items_handler_new ("contacts", NULL, NULL); - priv->menu = eab_menu_new("org.gnome.evolution.addressbook.view"); g_signal_connect (priv->folder_view_control, "activate", G_CALLBACK (control_activate_cb), view); @@ -1126,8 +1150,6 @@ addressbook_view_init (AddressbookView *view) g_signal_connect (priv->selector, "drag-drop", G_CALLBACK (selector_tree_drag_drop), view); g_signal_connect (priv->selector, "drag-data-received", G_CALLBACK (selector_tree_drag_data_received), view); gtk_drag_dest_set (priv->selector, GTK_DEST_DEFAULT_ALL, drag_types, num_drag_types, GDK_ACTION_COPY | GDK_ACTION_MOVE); - a11y = gtk_widget_get_accessible (GTK_WIDGET (priv->selector)); - atk_object_set_name (a11y, _("Contact Source Selector")); e_source_selector_show_selection (E_SOURCE_SELECTOR (priv->selector), FALSE); gtk_widget_show (priv->selector); @@ -1147,8 +1169,8 @@ addressbook_view_init (AddressbookView *view) g_signal_connect_object (priv->selector, "primary_selection_changed", G_CALLBACK (primary_source_selection_changed_callback), G_OBJECT (view), 0); - g_signal_connect_object (priv->selector, "popup_event", - G_CALLBACK (popup_event_callback), + g_signal_connect_object (priv->selector, "fill_popup_menu", + G_CALLBACK (fill_popup_menu_callback), G_OBJECT (view), 0); load_primary_selection (view); @@ -1194,9 +1216,6 @@ addressbook_view_dispose (GObject *object) if (priv->creatable_items_handler) g_object_unref (priv->creatable_items_handler); - if (priv->menu) - g_object_unref (priv->menu); - g_free (view->priv); view->priv = NULL; } diff --git a/addressbook/gui/component/addressbook.c b/addressbook/gui/component/addressbook.c index b389cfa78c..cbf908c17f 100644 --- a/addressbook/gui/component/addressbook.c +++ b/addressbook/gui/component/addressbook.c @@ -29,7 +29,7 @@ #include <libebook/e-book.h> #include "e-util/e-passwords.h" -#include "widgets/misc/e-error.h" + #include "addressbook.h" #define d(x) @@ -82,53 +82,45 @@ load_source_auth_cb (EBook *book, EBookStatus status, gpointer closure) /* the user clicked cancel in the password dialog */ if (status == E_BOOK_ERROR_CANCELLED) { - + if (e_book_check_static_capability (book, "anon-access")) { - - GtkWidget *dialog; - - /* XXX "LDAP" has to be removed from the folowing message - so that it wil valid for other servers which provide - anonymous access*/ - - dialog = gtk_message_dialog_new (NULL, - 0, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_OK, - _("Accessing LDAP Server anonymously")); - g_signal_connect (dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL); - gtk_widget_show (dialog); - data->cb (book, E_BOOK_ERROR_OK, data->closure); - free_load_source_data (data); - return; - } - } else if (status == E_BOOK_ERROR_INVALID_SERVER_VERSION) { - e_error_run (NULL, "addressbook:server-version", NULL); - status = E_BOOK_ERROR_OK; - if (data->cb) - data->cb (book, status, data->closure); + + GtkWidget *dialog; + + /* XXX "LDAP" has to be removed from the folowing message + so that it wil valid for other servers which provide + anonymous access*/ + + dialog = gtk_message_dialog_new (NULL, + 0, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + _("Accessing LDAP Server anonymously")); + g_signal_connect (dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL); + gtk_widget_show (dialog); + data->cb (book, E_BOOK_ERROR_OK, data->closure); free_load_source_data (data); return; - - } else { + } + } + else { gchar *uri = e_source_get_uri (data->source); gchar *stripped_uri = remove_parameters_from_uri (uri); const gchar *auth_domain = e_source_get_property (data->source, "auth-domain"); - const gchar *component_name; - + const gchar *component_name; + component_name = auth_domain ? auth_domain : "Addressbook"; - + e_passwords_forget_password (component_name, stripped_uri); addressbook_authenticate (book, TRUE, data->source, load_source_auth_cb, closure); - + g_free (stripped_uri); g_free (uri); return; } } - if (data->cb) - data->cb (book, status, data->closure); + data->cb (book, status, data->closure); free_load_source_data (data); } @@ -184,7 +176,6 @@ addressbook_authenticate (EBook *book, gboolean previous_failure, ESource *sourc if (!password) { char *prompt; - char *password_prompt; gboolean remember; char *failed_auth; guint32 flags = E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET|E_PASSWORDS_ONLINE; @@ -197,11 +188,8 @@ addressbook_authenticate (EBook *book, gboolean previous_failure, ESource *sourc failed_auth = ""; } - password_prompt = g_strdup_printf (_("Enter password for %s (user %s)"), - e_source_peek_name (source), user); - - prompt = g_strconcat (failed_auth, password_prompt, NULL); - g_free (password_prompt); + prompt = g_strdup_printf (_("%sEnter password for %s (user %s)"), + failed_auth, e_source_peek_name (source), user); remember = get_remember_password (source); pass_dup = e_passwords_ask_password (prompt, component_name, uri, prompt, @@ -221,28 +209,12 @@ addressbook_authenticate (EBook *book, gboolean previous_failure, ESource *sourc } else { /* they hit cancel */ - - cb (book, E_BOOK_ERROR_CANCELLED, closure); + cb (book, E_BOOK_ERROR_CANCELLED, closure); } g_free (uri); } - - -static void -auth_required_cb (EBook *book, gpointer data) -{ - LoadSourceData *load_source_data = g_new0(LoadSourceData, 1); - - load_source_data->source = g_object_ref (g_object_ref (e_book_get_source (book))); - load_source_data->cancelled = FALSE; - addressbook_authenticate (book, FALSE, load_source_data->source, - load_source_auth_cb, load_source_data); - - - -} static void load_source_cb (EBook *book, EBookStatus status, gpointer closure) { @@ -257,16 +229,17 @@ load_source_cb (EBook *book, EBookStatus status, gpointer closure) const gchar *auth; auth = e_source_get_property (load_source_data->source, "auth"); + + /* check if the addressbook needs authentication */ + if (auth && strcmp (auth, "none")) { - g_signal_connect (book, "auth_required", auth_required_cb, NULL); - - if (e_book_is_online (book)) { - addressbook_authenticate (book, FALSE, load_source_data->source, - load_source_auth_cb, closure); - return; - } + addressbook_authenticate (book, FALSE, load_source_data->source, + load_source_auth_cb, closure); + + return; } } + load_source_data->cb (book, status, load_source_data->closure); free_load_source_data (load_source_data); } diff --git a/addressbook/gui/component/apps_evolution_addressbook.schemas.in.in b/addressbook/gui/component/apps_evolution_addressbook.schemas.in.in index 010073331e..0de9b142f7 100644 --- a/addressbook/gui/component/apps_evolution_addressbook.schemas.in.in +++ b/addressbook/gui/component/apps_evolution_addressbook.schemas.in.in @@ -10,8 +10,8 @@ <type>string</type> <default></default> <locale name="C"> - <short>EFolderList XML for the list of completion URIs</short> - <long>EFolderList XML for the list of completion URIs.</long> + <short>EFolderList xml for the list of completion uris</short> + <long>EFolderList xml for the list of completion uris</long> </locale> </schema> @@ -22,8 +22,8 @@ <type>int</type> <default>3</default> <locale name="C"> - <short>Autocomplete length</short> - <long>The number of characters that must be typed before Evolution will attempt to autocomplete.</long> + <short>The number of characters that must be typed before evolution will attempt to autocomplete</short> + <long>The number of characters that must be typed before evolution will attempt to autocomplete</long> </locale> </schema> @@ -37,7 +37,7 @@ <default></default> <locale name="C"> <short>URI for the folder last used in the select names dialog</short> - <long>URI for the folder last used in the select names dialog.</long> + <long>URI for the folder last used in the select names dialog</long> </locale> </schema> @@ -49,8 +49,8 @@ <owner>evolution-addressbook</owner> <type>int</type> <locale name="C"> - <short>Vertical pane position</short> - <long>Position of the vertical pane, between the card and list views and the preview pane, in pixels.</long> + <short>Position of the vertical pane in main view</short> + <long>Position of the vertical pane in main view</long> </locale> </schema> @@ -61,8 +61,8 @@ <type>bool</type> <default>true</default> <locale name="C"> - <short>Show preview pane</short> - <long>Whether to show the preview pane.</long> + <short>Show the "Preview" pane</short> + <long>Show the "Preview" pane</long> </locale> </schema> diff --git a/addressbook/gui/component/component-factory.c b/addressbook/gui/component/component-factory.c index 4aaee9637b..382722785e 100644 --- a/addressbook/gui/component/component-factory.c +++ b/addressbook/gui/component/component-factory.c @@ -30,6 +30,7 @@ #include "autocompletion-config.h" #include "eab-popup-control.h" #include "eab-vcard-control.h" +#include "select-names/e-select-names-bonobo.h" #ifdef ENABLE_SMIME #include "smime/gui/certificate-manager.h" #endif @@ -41,6 +42,7 @@ #define VCARD_CONTROL_ID "OAFIID:GNOME_Evolution_Addressbook_VCard_Control:" BASE_VERSION #define COMPONENT_ID "OAFIID:GNOME_Evolution_Addressbook_Component:" BASE_VERSION #define ADDRESS_POPUP_ID "OAFIID:GNOME_Evolution_Addressbook_AddressPopup:" BASE_VERSION +#define SELECT_NAMES_ID "OAFIID:GNOME_Evolution_Addressbook_SelectNames:" BASE_VERSION #define COMPLETION_CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_Addressbook_Autocompletion_ConfigControl:" BASE_VERSION #define CERTIFICATE_MANAGER_CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_SMime_CertificateManager_ConfigControl:" BASE_VERSION @@ -65,6 +67,8 @@ factory (BonoboGenericFactory *factory, return BONOBO_OBJECT (eab_popup_control_new ()); if (strcmp (component_id, COMPLETION_CONFIG_CONTROL_ID) == 0) return BONOBO_OBJECT (autocompletion_config_control_new ()); + if (strcmp (component_id, SELECT_NAMES_ID) == 0) + return BONOBO_OBJECT (e_select_names_bonobo_new ()); #ifdef ENABLE_SMIME if (strcmp (component_id, CERTIFICATE_MANAGER_CONFIG_CONTROL_ID) == 0) return BONOBO_OBJECT (certificate_manager_config_control_new ()); diff --git a/addressbook/gui/contact-editor/e-contact-editor.c b/addressbook/gui/contact-editor/e-contact-editor.c index 2cd7984337..6d1e0581a6 100644 --- a/addressbook/gui/contact-editor/e-contact-editor.c +++ b/addressbook/gui/contact-editor/e-contact-editor.c @@ -34,18 +34,20 @@ #include <gtk/gtkstock.h> #include <gtk/gtkentry.h> #include <gtk/gtklabel.h> +#include <libgnomeui/gnome-popup-menu.h> #include <libgnomeui/gnome-window-icon.h> #include <libgnome/gnome-util.h> #include <libgnome/gnome-i18n.h> #include <libgnome/gnome-help.h> #include <gdk-pixbuf/gdk-pixbuf.h> -#include <libedataserverui/e-categories-dialog.h> +#include <gal/widgets/e-categories.h> #include <gal/widgets/e-gui-utils.h> #include <gal/e-text/e-entry.h> #include <libebook/e-address-western.h> -#include <libedataserverui/e-source-option-menu.h> + +#include <e-util/e-categories-master-list-wombat.h> #include <camel/camel.h> @@ -58,6 +60,7 @@ #include "widgets/misc/e-dateedit.h" #include "widgets/misc/e-image-chooser.h" #include "widgets/misc/e-url-entry.h" +#include "widgets/misc/e-source-option-menu.h" #include "shell/evolution-shell-component-utils.h" #include "e-util/e-icon-factory.h" @@ -117,8 +120,7 @@ enum { PROP_IS_NEW_CONTACT, PROP_EDITABLE, PROP_CHANGED, - PROP_WRITABLE_FIELDS, - PROP_REQUIRED_FIELDS + PROP_WRITABLE_FIELDS }; enum { @@ -286,13 +288,6 @@ e_contact_editor_class_init (EContactEditorClass *klass) E_TYPE_LIST, G_PARAM_READWRITE)); - g_object_class_install_property (object_class, PROP_REQUIRED_FIELDS, - g_param_spec_object ("required_fields", - _("Required Fields"), - /*_( */"XXX blurb" /*)*/, - E_TYPE_LIST, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, PROP_EDITABLE, g_param_spec_boolean ("editable", _("Editable"), @@ -1538,30 +1533,6 @@ extract_im (EContactEditor *editor) g_free (service_attr_list); } -static void -sensitize_im_types (EContactEditor *editor, GtkWidget *option_menu) -{ - GtkWidget *menu; - GList *item_list, *l; - gint i; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (option_menu)); - l = item_list = gtk_container_get_children (GTK_CONTAINER (menu)); - - for (i = 0; i < G_N_ELEMENTS (im_service); i++) { - GtkWidget *widget; - - if (!l) { - g_warning (G_STRLOC ": Unexpected end of im items in option menu"); - return; - } - - widget = l->data; - gtk_widget_set_sensitive (widget, is_field_supported (editor, im_service [i].field)); - - l = g_list_next (l); - } -} static void sensitize_im_record (EContactEditor *editor, gint record, gboolean enabled) @@ -1592,29 +1563,19 @@ sensitize_im_record (EContactEditor *editor, gint record, gboolean enabled) gtk_widget_set_sensitive (location_option_menu, enabled); #endif gtk_editable_set_editable (GTK_EDITABLE (name_entry), enabled); - sensitize_im_types (editor, service_option_menu); } static void sensitize_im (EContactEditor *editor) { gint i; - gboolean enabled; - gboolean no_ims_supported; - - enabled = editor->target_editable; - no_ims_supported = TRUE; - - for (i = 0; i < G_N_ELEMENTS (im_service); i++) - if (is_field_supported (editor, im_service[i].field)) { - no_ims_supported = FALSE; - break; - } - if (no_ims_supported) - enabled = FALSE; - for (i = 1; i <= IM_SLOTS; i++) { + gboolean enabled = TRUE; + + if (!editor->target_editable) + enabled = FALSE; + sensitize_im_record (editor, i, enabled); } } @@ -2158,6 +2119,7 @@ extract_simple_field (EContactEditor *editor, GtkWidget *widget, gint field_id) gtk_text_buffer_get_start_iter (buffer, &start); gtk_text_buffer_get_end_iter (buffer, &end); text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE); + e_contact_set (contact, field_id, text); g_free (text); } @@ -2478,27 +2440,37 @@ categories_clicked (GtkWidget *button, EContactEditor *editor) GtkDialog *dialog; int result; GtkWidget *entry = glade_xml_get_widget(editor->gui, "entry-categories"); - + ECategoriesMasterList *ecml; if (entry && GTK_IS_ENTRY(entry)) categories = g_strdup (gtk_entry_get_text(GTK_ENTRY(entry))); else if (editor->contact) categories = e_contact_get (editor->contact, E_CONTACT_CATEGORIES); - if (!(dialog = GTK_DIALOG (e_categories_dialog_new (categories)))) { + if (!(dialog = GTK_DIALOG (e_categories_new (categories)))) { e_error_run (NULL, "addressbook:edit-categories", NULL); g_free (categories); return; } + ecml = e_categories_master_list_wombat_new (); + g_object_set (dialog, + "header", _("This contact belongs to these categories:"), + "ecml", ecml, + NULL); + g_object_unref (ecml); gtk_widget_show(GTK_WIDGET(dialog)); result = gtk_dialog_run (dialog); g_free (categories); if (result == GTK_RESPONSE_OK) { - categories = e_categories_dialog_get_categories (E_CATEGORIES_DIALOG (dialog)); + g_object_get (dialog, + "categories", &categories, + NULL); if (entry && GTK_IS_ENTRY(entry)) gtk_entry_set_text (GTK_ENTRY (entry), categories); else e_contact_set (editor->contact, E_CONTACT_CATEGORIES, categories); + + g_free(categories); } gtk_widget_destroy(GTK_WIDGET(dialog)); } @@ -2763,29 +2735,17 @@ real_save_contact (EContactEditor *ce, gboolean should_close) static void save_contact (EContactEditor *ce, gboolean should_close) { - char *uid; - if (!ce->target_book) return; - + + if (!e_contact_editor_is_valid (EAB_EDITOR (ce))) + return; if (ce->target_editable && !e_book_is_writable (ce->source_book)) { if (e_error_run (GTK_WINDOW (ce->app), "addressbook:prompt-move", NULL) == GTK_RESPONSE_NO) return; } extract_all (ce); - - if (!e_contact_editor_is_valid (EAB_EDITOR (ce))) { - uid = e_contact_get (ce->contact, E_CONTACT_UID); - g_object_unref (ce->contact); - ce->contact = e_contact_new (); - if (uid) { - e_contact_set (ce->contact, E_CONTACT_UID, uid); - g_free (uid); - } - return; - } - real_save_contact (ce, should_close); } @@ -2808,42 +2768,6 @@ e_contact_editor_close (EABEditor *editor) } } -EContactField non_string_fields [] = { - E_CONTACT_FULL_NAME, - E_CONTACT_ADDRESS, - E_CONTACT_ADDRESS_HOME, - E_CONTACT_ADDRESS_WORK, - E_CONTACT_ADDRESS_OTHER, - E_CONTACT_EMAIL, - E_CONTACT_IM_AIM, - E_CONTACT_IM_GROUPWISE, - E_CONTACT_IM_JABBER, - E_CONTACT_IM_YAHOO, - E_CONTACT_IM_MSN, - E_CONTACT_IM_ICQ, - E_CONTACT_PHOTO, - E_CONTACT_LOGO, - E_CONTACT_X509_CERT, - E_CONTACT_CATEGORY_LIST, - E_CONTACT_BIRTH_DATE, - E_CONTACT_ANNIVERSARY - - -}; - -static gboolean -is_non_string_field (EContactField id) -{ - int count = sizeof (non_string_fields) / sizeof (EContactField); - int i; - for (i = 0; i < count; i++) - if (id == non_string_fields[i]) - return TRUE; - return FALSE; - -} - - /* insert checks here (date format, for instance, etc.) */ static gboolean e_contact_editor_is_valid (EABEditor *editor) @@ -2851,7 +2775,6 @@ e_contact_editor_is_valid (EABEditor *editor) EContactEditor *ce = E_CONTACT_EDITOR (editor); GtkWidget *widget; gboolean validation_error = FALSE; - EIterator *iter; GString *errmsg = g_string_new (_("The contact data is invalid:\n\n")); widget = glade_xml_get_widget (ce->gui, "dateedit-birthday"); @@ -2869,38 +2792,14 @@ e_contact_editor_is_valid (EABEditor *editor) validation_error = TRUE; } - iter = e_list_get_iterator (ce->required_fields); - for (e_iterator_last (iter); - e_iterator_is_valid (iter); - e_iterator_prev (iter)) { - const char *field_name = e_iterator_get (iter); - EContactField field_id = e_contact_field_id (field_name); - - if (is_non_string_field (field_id)) { - if (e_contact_get_const (ce->contact, field_id) == NULL) { - g_string_append_printf (errmsg, "%s'%s' is empty", - validation_error ? ",\n" : "", - e_contact_pretty_name (field_id)); - validation_error = TRUE; - break; - } - - } else { - - char *text = e_contact_get_const (ce->contact, field_id); - if (STRING_IS_EMPTY (text)) { - g_string_append_printf (errmsg, "%s'%s' is empty", - validation_error ? ",\n" : "", - e_contact_pretty_name (field_id)); - validation_error = TRUE; - break; - } - - - } + widget = glade_xml_get_widget (ce->gui, "entry-file-as"); + if (STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (widget)))) { + g_string_append_printf (errmsg, "%s'%s' is empty", + validation_error ? ",\n" : "", + e_contact_pretty_name (E_CONTACT_FILE_AS)); + validation_error = TRUE; } - - + if (validation_error) { g_string_append (errmsg, "."); e_error_run (GTK_WINDOW (ce->app), "addressbook:generic-error", @@ -3064,7 +2963,6 @@ e_contact_editor_init (EContactEditor *e_contact_editor) e_contact_editor->app = glade_xml_get_widget (gui, "contact editor"); widget = e_contact_editor->app; - gtk_widget_ensure_style (widget); gtk_window_set_type_hint (GTK_WINDOW (widget), GDK_WINDOW_TYPE_HINT_NORMAL); gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (widget)->vbox), 0); gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (widget)->action_area), 12); @@ -3123,10 +3021,7 @@ e_contact_editor_dispose (GObject *object) g_object_unref(e_contact_editor->writable_fields); e_contact_editor->writable_fields = NULL; } - if (e_contact_editor->required_fields) { - g_object_unref (e_contact_editor->required_fields); - e_contact_editor->required_fields = NULL; - } + if (e_contact_editor->contact) { g_object_unref(e_contact_editor->contact); e_contact_editor->contact = NULL; @@ -3178,24 +3073,6 @@ supported_fields_cb (EBook *book, EBookStatus status, } static void -required_fields_cb (EBook *book, EBookStatus status, - EList *fields, EContactEditor *ce) -{ - - if (!g_slist_find ((GSList*)eab_editor_get_all_editors (), ce)) { - g_warning ("supported_fields_cb called for book that's still around, but contact editor that's been destroyed."); - return; - } - - g_object_set (ce, - "required_fields", fields, - NULL); - - -} - - -static void contact_editor_destroy_notify (void *data, GObject *where_the_object_was) { @@ -3281,8 +3158,6 @@ e_contact_editor_set_property (GObject *object, guint prop_id, const GValue *val e_book_async_get_supported_fields (editor->target_book, (EBookEListCallback) supported_fields_cb, editor); - e_book_async_get_required_fields (editor->target_book, - (EBookEListCallback) required_fields_cb, editor); } writable = e_book_is_writable (editor->target_book); @@ -3321,8 +3196,6 @@ e_contact_editor_set_property (GObject *object, guint prop_id, const GValue *val e_book_async_get_supported_fields (editor->target_book, (EBookEListCallback) supported_fields_cb, editor); - e_book_async_get_required_fields (editor->target_book, - (EBookEListCallback) required_fields_cb, editor); if (!editor->is_new_contact) editor->changed = TRUE; @@ -3386,15 +3259,6 @@ e_contact_editor_set_property (GObject *object, guint prop_id, const GValue *val sensitize_all (editor); break; - case PROP_REQUIRED_FIELDS: - if (editor->required_fields) - g_object_unref (editor->required_fields); - editor->required_fields = g_value_get_object (value); - if (editor->required_fields) - g_object_ref (editor->required_fields); - else - editor->required_fields = e_list_new (NULL, NULL, NULL); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3440,12 +3304,6 @@ e_contact_editor_get_property (GObject *object, guint prop_id, GValue *value, GP else g_value_set_object (value, NULL); break; - case PROP_REQUIRED_FIELDS: - if (e_contact_editor->required_fields) - g_value_set_object (value, e_list_duplicate (e_contact_editor->required_fields)); - else - g_value_set_object (value, NULL); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3491,18 +3349,10 @@ e_contact_editor_create_date(gchar *name, gint int1, gint int2) { GtkWidget *widget = e_date_edit_new (); - AtkObject *a11y; - e_date_edit_set_allow_no_date_set (E_DATE_EDIT (widget), TRUE); e_date_edit_set_show_time (E_DATE_EDIT (widget), FALSE); e_date_edit_set_time (E_DATE_EDIT (widget), -1); - - a11y = gtk_widget_get_accessible (e_date_edit_get_entry (E_DATE_EDIT(widget))); - if (a11y != NULL) { - atk_object_set_name (a11y, string1); - } - gtk_widget_show (widget); return widget; } @@ -3518,12 +3368,6 @@ e_contact_editor_create_web(gchar *name, gint int1, gint int2) { GtkWidget *widget = e_url_entry_new (); - AtkObject *a11y = gtk_widget_get_accessible (e_url_entry_get_entry (widget)); - - if (a11y != NULL) { - atk_object_set_name (a11y, string1); - } - gtk_widget_show (widget); return widget; } diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.c b/addressbook/gui/contact-editor/e-contact-quick-add.c index d3765314ba..7a167dc5ff 100644 --- a/addressbook/gui/contact-editor/e-contact-quick-add.c +++ b/addressbook/gui/contact-editor/e-contact-quick-add.c @@ -268,26 +268,19 @@ static GtkWidget * build_quick_add_dialog (QuickAdd *qa) { GtkWidget *dialog; - GtkWidget *label; GtkTable *table; - const gint xpad=0, ypad=0; + const gint xpad=6, ypad=6; g_return_val_if_fail (qa != NULL, NULL); dialog = gtk_dialog_new_with_buttons (_("Contact Quick-Add"), NULL, /* XXX */ - GTK_DIALOG_NO_SEPARATOR, + (GtkDialogFlags) 0, _("_Edit Full"), QUICK_ADD_RESPONSE_EDIT_FULL, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); - gtk_widget_ensure_style (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); - g_signal_connect (dialog, "response", G_CALLBACK (clicked_cb), qa); qa->name_entry = gtk_entry_new (); @@ -300,34 +293,27 @@ build_quick_add_dialog (QuickAdd *qa) gtk_entry_set_text (GTK_ENTRY (qa->email_entry), qa->email); table = GTK_TABLE (gtk_table_new (2, 2, FALSE)); - gtk_table_set_row_spacings (table, 6); - gtk_table_set_col_spacings (table, 12); - label = gtk_label_new_with_mnemonic (_("_Full name:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - - gtk_table_attach (table, label, + gtk_table_attach (table, gtk_label_new_with_mnemonic (_("_Full Name:")), 0, 1, 0, 1, - GTK_FILL, 0, xpad, ypad); + 0, 0, xpad, ypad); gtk_table_attach (table, qa->name_entry, 1, 2, 0, 1, - GTK_EXPAND | GTK_FILL, 0, xpad, ypad); - - label = gtk_label_new_with_mnemonic (_("E-_mail:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - - gtk_table_attach (table, label, + GTK_EXPAND | GTK_FILL, GTK_EXPAND, xpad, ypad); + gtk_table_attach (table, gtk_label_new_with_mnemonic (_("E-_mail:")), 0, 1, 1, 2, - GTK_FILL, 0, xpad, ypad); + 0, 0, xpad, ypad); gtk_table_attach (table, qa->email_entry, 1, 2, 1, 2, - GTK_EXPAND | GTK_FILL, 0, xpad, ypad); + GTK_EXPAND | GTK_FILL, GTK_EXPAND, xpad, ypad); + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), + 6); + + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox),6); - gtk_container_set_border_width (GTK_CONTAINER (table), - 12); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), GTK_WIDGET (table), - FALSE, FALSE, 0); + TRUE, TRUE, 6); gtk_widget_show_all (GTK_WIDGET (table)); diff --git a/addressbook/gui/contact-list-editor/contact-list-editor.glade b/addressbook/gui/contact-list-editor/contact-list-editor.glade index bc5c2c18ee..30760f6108 100644 --- a/addressbook/gui/contact-list-editor/contact-list-editor.glade +++ b/addressbook/gui/contact-list-editor/contact-list-editor.glade @@ -11,11 +11,6 @@ <property name="modal">False</property> <property name="resizable">True</property> <property name="destroy_with_parent">False</property> - <property name="decorated">True</property> - <property name="skip_taskbar_hint">False</property> - <property name="skip_pager_hint">False</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> <property name="has_separator">True</property> <child internal-child="vbox"> @@ -37,7 +32,6 @@ <property name="label">gtk-cancel</property> <property name="use_stock">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> <property name="response_id">-6</property> </widget> </child> @@ -50,7 +44,6 @@ <property name="label">gtk-ok</property> <property name="use_stock">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> <property name="response_id">-5</property> </widget> </child> @@ -239,7 +232,6 @@ <property name="yalign">0.5</property> <property name="xpad">0</property> <property name="ypad">0</property> - <property name="mnemonic_widget">email-entry</property> </widget> <packing> <property name="padding">0</property> @@ -271,6 +263,7 @@ <widget class="Custom" id="contact-list-table"> <property name="visible">True</property> <property name="creation_function">e_contact_list_editor_create_table</property> + <property name="string1"></property> <property name="int1">0</property> <property name="int2">0</property> <property name="last_modification_time">Sat, 23 Jun 2001 06:00:16 GMT</property> @@ -289,7 +282,6 @@ <property name="label" translatable="yes">_Hide addresses when sending mail to this list</property> <property name="use_underline">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> <property name="active">False</property> <property name="inconsistent">False</property> <property name="draw_indicator">True</property> @@ -351,7 +343,6 @@ <property name="label">gtk-add</property> <property name="use_stock">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> </widget> </child> @@ -364,7 +355,6 @@ <property name="label">gtk-remove</property> <property name="use_stock">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> </widget> </child> @@ -374,10 +364,9 @@ <property name="tooltip" translatable="yes">Insert email adresses from Adress Book</property> <property name="can_default">True</property> <property name="can_focus">True</property> - <property name="label" translatable="yes">_Select</property> + <property name="label" translatable="yes">Select</property> <property name="use_underline">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> </widget> </child> </widget> diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c index 5f8397161b..b9f6b123e6 100644 --- a/addressbook/gui/widgets/e-addressbook-view.c +++ b/addressbook/gui/widgets/e-addressbook-view.c @@ -29,6 +29,7 @@ #include <gtk/gtkscrolledwindow.h> #include <gal/e-table/e-table-scrolled.h> #include <gal/e-table/e-table-model.h> +#include <gal/widgets/e-popup-menu.h> #include <gal/widgets/e-gui-utils.h> #include <gal/menus/gal-view-factory-etable.h> #include <gal/menus/gal-view-etable.h> @@ -43,12 +44,9 @@ #include "addressbook/printing/e-contact-print.h" #include "addressbook/printing/e-contact-print-envelope.h" #include "addressbook/gui/search/e-addressbook-search-dialog.h" -#include "addressbook/gui/widgets/eab-popup.h" -#include "addressbook/gui/widgets/eab-menu.h" #include "e-util/e-categories-master-list-wombat.h" -#include "e-util/e-print.h" -#include "libedataserver/e-sexp.h" +#include "e-util/e-sexp.h" #ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW #include <gal/widgets/e-treeview-selection-model.h> @@ -99,7 +97,7 @@ static void stop_state_changed (GtkObject *object, EABView *eav); static void writable_status (GtkObject *object, gboolean writable, EABView *eav); static void backend_died (GtkObject *object, EABView *eav); static void contact_changed (EABModel *model, gint index, EABView *eav); -static void contacts_removed (EABModel *model, gpointer data, EABView *eav); +static void contact_removed (EABModel *model, gint index, EABView *eav); static GList *get_selected_contacts (EABView *view); static void command_state_change (EABView *eav); @@ -436,8 +434,8 @@ eab_view_new (void) G_CALLBACK (backend_died), eav); g_signal_connect (eav->model, "contact_changed", G_CALLBACK (contact_changed), eav); - g_signal_connect (eav->model, "contacts_removed", - G_CALLBACK (contacts_removed), eav); + g_signal_connect (eav->model, "contact_removed", + G_CALLBACK (contact_removed), eav); eav->editable = FALSE; eav->query = g_strdup (SHOW_ALL_SEARCH); @@ -477,12 +475,16 @@ eab_view_new (void) g_signal_connect_swapped (eav->paned, "button_release_event", G_CALLBACK (get_paned_position), eav); + eav->widget = gtk_label_new ("empty label here"); + gtk_container_add (GTK_CONTAINER (eav->paned), eav->widget); + gtk_widget_show (eav->widget); + eav->contact_display = eab_contact_display_new (); eav->contact_display_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (eav->contact_display_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (eav->contact_display_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (eav->contact_display_window), GTK_SHADOW_IN); gtk_container_add (GTK_CONTAINER (eav->contact_display_window), eav->contact_display); - gtk_paned_add2 (GTK_PANED (eav->paned), eav->contact_display_window); + gtk_container_add (GTK_CONTAINER (eav->paned), eav->contact_display_window); gtk_widget_show (eav->contact_display); gtk_widget_show (eav->contact_display_window); gtk_widget_show (eav->paned); @@ -773,6 +775,7 @@ get_selection_model (EABView *view) /* Popup menu stuff */ typedef struct { EABView *view; + EPopupMenu *submenu; gpointer closure; } ContactAndBook; @@ -782,219 +785,371 @@ contact_and_book_get_selection_model (ContactAndBook *contact_and_book) return get_selection_model (contact_and_book->view); } +static void +contact_and_book_free (ContactAndBook *contact_and_book) +{ + EABView *view = contact_and_book->view; + ESelectionModel *selection; + + if (contact_and_book->submenu) + gal_view_instance_free_popup_menu (view->view_instance, + contact_and_book->submenu); + + selection = contact_and_book_get_selection_model (contact_and_book); + if (selection) + e_selection_model_right_click_up(selection); + + g_object_unref (view); +} + +static void +get_contact_list_1(gint model_row, + gpointer closure) +{ + ContactAndBook *contact_and_book; + GList **list; + EABView *view; + EContact *contact; + + contact_and_book = closure; + list = contact_and_book->closure; + view = contact_and_book->view; + + contact = eab_model_get_contact(view->model, model_row); + *list = g_list_prepend(*list, contact); +} + static GList * -get_contact_list (EABPopupTargetSelect *t) +get_contact_list (ContactAndBook *contact_and_book) { GList *list = NULL; - int i; + ESelectionModel *selection; - for (i=0;i<t->cards->len;i++) - list = g_list_prepend(list, t->cards->pdata[i]); + selection = contact_and_book_get_selection_model (contact_and_book); + + if (selection) { + contact_and_book->closure = &list; + e_selection_model_foreach (selection, get_contact_list_1, contact_and_book); + } return list; } static void -save_as (EPopup *ep, EPopupItem *pitem, void *data) +has_email_address_1(gint model_row, + gpointer closure) { - /*ContactAndBook *contact_and_book = data;*/ - GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target); + ContactAndBook *contact_and_book; + gboolean *has_email; + EABView *view; + const EContact *contact; + GList *email; + + contact_and_book = closure; + has_email = contact_and_book->closure; + view = contact_and_book->view; + + if (*has_email) + return; + + contact = eab_model_contact_at(view->model, model_row); + + email = e_contact_get (E_CONTACT (contact), E_CONTACT_EMAIL); + + if (g_list_length (email) > 0) + *has_email = TRUE; + + g_list_foreach (email, (GFunc)g_free, NULL); + g_list_free (email); +} + +static gboolean +get_has_email_address (ContactAndBook *contact_and_book) +{ + ESelectionModel *selection; + gboolean has_email = FALSE; + selection = contact_and_book_get_selection_model (contact_and_book); + + if (selection) { + contact_and_book->closure = &has_email; + e_selection_model_foreach (selection, has_email_address_1, contact_and_book); + } + + return has_email; +} + +static void +save_as (GtkWidget *widget, ContactAndBook *contact_and_book) +{ + GList *contacts = get_contact_list (contact_and_book); if (contacts) { eab_contact_list_save(_("Save as VCard..."), contacts, NULL); - g_list_free(contacts); + e_free_object_list(contacts); } } static void -send_as (EPopup *ep, EPopupItem *pitem, void *data) +send_as (GtkWidget *widget, ContactAndBook *contact_and_book) { - /*ContactAndBook *contact_and_book = data;*/ - GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target); - + GList *contacts = get_contact_list (contact_and_book); if (contacts) { eab_send_contact_list(contacts, EAB_DISPOSITION_AS_ATTACHMENT); - g_list_free(contacts); + e_free_object_list(contacts); } } static void -send_to (EPopup *ep, EPopupItem *pitem, void *data) +send_to (GtkWidget *widget, ContactAndBook *contact_and_book) + { - /*ContactAndBook *contact_and_book = data;*/ - GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target); + GList *contacts = get_contact_list (contact_and_book); if (contacts) { eab_send_contact_list(contacts, EAB_DISPOSITION_AS_TO); - g_list_free(contacts); + e_free_object_list(contacts); } } static void -print (EPopup *ep, EPopupItem *pitem, void *data) +print (GtkWidget *widget, ContactAndBook *contact_and_book) { - /*ContactAndBook *contact_and_book = data;*/ - EABPopupTargetSelect *t = (EABPopupTargetSelect *)ep->target; - - if (t->cards->len == 1) { - gtk_widget_show(e_contact_print_contact_dialog_new(t->cards->pdata[0])); - } else { - GList *contacts = get_contact_list(t); - - gtk_widget_show(e_contact_print_contact_list_dialog_new(contacts)); - g_list_free(contacts); + GList *contacts = get_contact_list (contact_and_book); + if (contacts) { + if (contacts->next) + gtk_widget_show(e_contact_print_contact_list_dialog_new(contacts)); + else + gtk_widget_show(e_contact_print_contact_dialog_new(contacts->data)); + e_free_object_list(contacts); } } +#if 0 /* Envelope printing is disabled for Evolution 1.0. */ static void -copy (EPopup *ep, EPopupItem *pitem, void *data) +print_envelope (GtkWidget *widget, ContactAndBook *contact_and_book) { - ContactAndBook *contact_and_book = data; + GList *cards = get_card_list (contact_and_book); + if (cards) { + gtk_widget_show(e_contact_list_print_envelope_dialog_new(contact_and_book->card)); + e_free_object_list(cards); + } +} +#endif +static void +copy (GtkWidget *widget, ContactAndBook *contact_and_book) +{ eab_view_copy (contact_and_book->view); } static void -paste (EPopup *ep, EPopupItem *pitem, void *data) +paste (GtkWidget *widget, ContactAndBook *contact_and_book) { - ContactAndBook *contact_and_book = data; - eab_view_paste (contact_and_book->view); } static void -cut (EPopup *ep, EPopupItem *pitem, void *data) +cut (GtkWidget *widget, ContactAndBook *contact_and_book) { - ContactAndBook *contact_and_book = data; - eab_view_cut (contact_and_book->view); } static void -delete (EPopup *ep, EPopupItem *pitem, void *data) +delete (GtkWidget *widget, ContactAndBook *contact_and_book) { - ContactAndBook *contact_and_book = data; + if (eab_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(contact_and_book->view->widget)))) { + EBook *book; + GList *list = get_contact_list(contact_and_book); + GList *iterator; + gboolean bulk_remove = FALSE; + + bulk_remove = e_book_check_static_capability (contact_and_book->view->model->book, + "bulk-remove"); + + g_object_get(contact_and_book->view->model, + "book", &book, + NULL); + + if (bulk_remove) { + GList *ids = NULL; + + for (iterator = list; iterator; iterator = iterator->next) { + EContact *contact = iterator->data; + ids = g_list_prepend (ids, (char*)e_contact_get_const (contact, E_CONTACT_UID)); + } - eab_view_delete_selection(contact_and_book->view); + /* Remove the cards all at once. */ + /* XXX no callback specified... ugh */ + e_book_async_remove_contacts (book, + ids, + NULL, + NULL); + + g_list_free (ids); + } + else { + for (iterator = list; iterator; iterator = iterator->next) { + EContact *contact = iterator->data; + /* Remove the card. */ + /* XXX no callback specified... ugh */ + e_book_async_remove_contact (book, + contact, + NULL, + NULL); + } + } + e_free_object_list(list); + g_object_unref(book); + } } static void -copy_to_folder (EPopup *ep, EPopupItem *pitem, void *data) +copy_to_folder (GtkWidget *widget, ContactAndBook *contact_and_book) { - ContactAndBook *contact_and_book = data; - eab_view_copy_to_folder (contact_and_book->view); } static void -move_to_folder (EPopup *ep, EPopupItem *pitem, void *data) +move_to_folder (GtkWidget *widget, ContactAndBook *contact_and_book) { - ContactAndBook *contact_and_book = data; - eab_view_move_to_folder (contact_and_book->view); } static void -new_card (EPopup *ep, EPopupItem *pitem, void *data) +free_popup_info (GtkWidget *w, ContactAndBook *contact_and_book) { - /*ContactAndBook *contact_and_book = data;*/ + contact_and_book_free (contact_and_book); +} + +static void +new_card (GtkWidget *widget, ContactAndBook *contact_and_book) +{ + EBook *book; EContact *contact = e_contact_new(); - eab_show_contact_editor (((EABPopupTargetSelect *)ep->target)->book, contact, TRUE, TRUE); + g_object_get(contact_and_book->view->model, + "book", &book, + NULL); + + eab_show_contact_editor (book, contact, TRUE, TRUE); + g_object_unref (book); g_object_unref (contact); } static void -new_list (EPopup *ep, EPopupItem *pitem, void *data) +new_list (GtkWidget *widget, ContactAndBook *contact_and_book) { - /*ContactAndBook *contact_and_book = data;*/ + EBook *book; EContact *contact = e_contact_new (); - eab_show_contact_list_editor (((EABPopupTargetSelect *)ep->target)->book, contact, TRUE, TRUE); + g_object_get(contact_and_book->view->model, + "book", &book, + NULL); + eab_show_contact_list_editor (book, contact, TRUE, TRUE); + g_object_unref(book); g_object_unref(contact); } -static EPopupItem eabv_popup_items[] = { - { E_POPUP_ITEM, "10.new", N_("New Contact..."), new_card, NULL, "stock_contact", 0, EAB_POPUP_SELECT_EDITABLE}, - { E_POPUP_ITEM, "15.newlist", N_("New Contact List..."), new_list, NULL, "stock_contact-list", 0, EAB_POPUP_SELECT_EDITABLE }, - - { E_POPUP_BAR, "20.bar" }, - { E_POPUP_ITEM, "30.saveas", N_("Save as VCard..."), save_as, NULL, "stock_save-as", 0, EAB_POPUP_SELECT_ANY }, - { E_POPUP_ITEM, "40.forward", N_("Forward Contact"), send_as, NULL, "stock_mail-forward", 0, EAB_POPUP_SELECT_ANY }, - { E_POPUP_ITEM, "50.mailto", N_("Send Message to Contact"), send_to, NULL, "stock_mail-send", 0, EAB_POPUP_SELECT_ANY|EAB_POPUP_SELECT_EMAIL }, - { E_POPUP_ITEM, "60.print", N_("Print"), print, NULL, "stock_print", 0, EAB_POPUP_SELECT_ANY }, - - { E_POPUP_BAR, "70.bar" }, - { E_POPUP_ITEM, "80.copyto", N_("Copy to Address Book..."), copy_to_folder, NULL, NULL, 0, EAB_POPUP_SELECT_ANY }, - { E_POPUP_ITEM, "90.moveto", N_("Move to Address Book..."), move_to_folder, NULL, NULL, 0, EAB_POPUP_SELECT_ANY|EAB_POPUP_SELECT_EDITABLE }, - - { E_POPUP_BAR, "a0.bar" }, - { E_POPUP_BAR, "b0.cut", N_("Cut"), cut, NULL, "stock_cut", 0, EAB_POPUP_SELECT_ANY|EAB_POPUP_SELECT_EDITABLE }, - { E_POPUP_ITEM, "c0.copy", N_("Copy"), copy, NULL, "stock_copy", 0, EAB_POPUP_SELECT_ANY }, - { E_POPUP_ITEM, "d0.paste", N_("Paste"), paste, NULL, "stock_paste", 0, EAB_POPUP_SELECT_EDITABLE }, - { E_POPUP_ITEM, "e0.delete", N_("Delete"), delete, NULL, "stock_delete", 0, EAB_POPUP_SELECT_EDITABLE|EAB_POPUP_SELECT_ANY }, -}; - +#if 0 static void -get_card_1(gint model_row, void *data) +sources (GtkWidget *widget, ContactAndBook *contact_and_book) { - ContactAndBook *contact_and_book = data; - EContact *contact; + BonoboControl *control; + GNOME_Evolution_ShellView shell_view; + CORBA_Environment ev; - contact = eab_model_get_contact(contact_and_book->view->model, model_row); - if (contact) - g_ptr_array_add((GPtrArray *)contact_and_book->closure, contact); -} + control = g_object_get_data (G_OBJECT (gcal), "control"); + if (control == NULL) + return; -static void -eabv_popup_free(EPopup *ep, GSList *list, void *data) -{ - ContactAndBook *cab = data; - ESelectionModel *selection; + shell_view = get_shell_view_interface (control); + if (shell_view == CORBA_OBJECT_NIL) + return; - /* NB: this looks strange to me */ - selection = contact_and_book_get_selection_model(cab); - if (selection) - e_selection_model_right_click_up(selection); + CORBA_exception_init (&ev); + + GNOME_Evolution_ShellView_showSettings (shell_view, &ev); + + if (BONOBO_EX (&ev)) + g_message ("control_util_show_settings(): Could not show settings"); - g_slist_free(list); - g_object_unref(cab->view); - g_free(cab); + CORBA_exception_free (&ev); } +#endif + +#define POPUP_READONLY_MASK 0x1 +#define POPUP_NOSELECTION_MASK 0x2 +#define POPUP_NOEMAIL_MASK 0x4 static void do_popup_menu(EABView *view, GdkEvent *event) { - EABPopup *ep; - EABPopupTargetSelect *t; - GSList *menus = NULL; - int i; - GtkMenu *menu; - GPtrArray *cards = g_ptr_array_new(); ContactAndBook *contact_and_book; + GtkMenu *popup; + EPopupMenu *submenu = NULL; ESelectionModel *selection_model; + gboolean selection = FALSE; + + EPopupMenu menu[] = { + E_POPUP_ITEM (N_("New Contact..."), G_CALLBACK(new_card), POPUP_READONLY_MASK), + E_POPUP_ITEM (N_("New Contact List..."), G_CALLBACK(new_list), POPUP_READONLY_MASK), + E_POPUP_SEPARATOR, +#if 0 + E_POPUP_ITEM (N_("Go to Folder..."), G_CALLBACK (goto_folder), 0), + E_POPUP_ITEM (N_("Import..."), G_CALLBACK (import), POPUP_READONLY_MASK), + E_POPUP_SEPARATOR, + E_POPUP_ITEM (N_("Search for Contacts..."), G_CALLBACK (search), 0), + E_POPUP_ITEM (N_("Address Book Sources..."), G_CALLBACK (sources), 0), + E_POPUP_SEPARATOR, + E_POPUP_ITEM (N_("Pilot Settings..."), G_CALLBACK (pilot_settings), 0), +#endif + E_POPUP_SEPARATOR, + E_POPUP_ITEM (N_("Save as VCard..."), G_CALLBACK(save_as), POPUP_NOSELECTION_MASK), + E_POPUP_ITEM (N_("Forward Contact"), G_CALLBACK(send_as), POPUP_NOSELECTION_MASK), + E_POPUP_ITEM (N_("Send Message to Contact"), G_CALLBACK(send_to), POPUP_NOSELECTION_MASK | POPUP_NOEMAIL_MASK), + E_POPUP_ITEM (N_("Print"), G_CALLBACK(print), POPUP_NOSELECTION_MASK), +#if 0 /* Envelope printing is disabled for Evolution 1.0. */ + E_POPUP_ITEM (N_("Print Envelope"), G_CALLBACK(print_envelope), POPUP_NOSELECTION_MASK), +#endif + E_POPUP_SEPARATOR, + + E_POPUP_ITEM (N_("Copy to Address Book..."), G_CALLBACK(copy_to_folder), POPUP_NOSELECTION_MASK), + E_POPUP_ITEM (N_("Move to Address Book..."), G_CALLBACK(move_to_folder), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK), + E_POPUP_SEPARATOR, + + E_POPUP_ITEM (N_("Cut"), G_CALLBACK (cut), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK), + E_POPUP_ITEM (N_("Copy"), G_CALLBACK (copy), POPUP_NOSELECTION_MASK), + E_POPUP_ITEM (N_("Paste"), G_CALLBACK (paste), POPUP_READONLY_MASK), + E_POPUP_ITEM (N_("Delete"), G_CALLBACK(delete), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK), + E_POPUP_SEPARATOR, + +#if 0 + E_POPUP_SUBMENU (N_("Current View"), submenu = gal_view_instance_get_popup_menu (view->view_instance), 0), +#endif + E_POPUP_TERMINATOR + }; contact_and_book = g_new(ContactAndBook, 1); contact_and_book->view = view; - g_object_ref(contact_and_book->view); + contact_and_book->submenu = submenu; - selection_model = contact_and_book_get_selection_model(contact_and_book); - if (selection_model) { - contact_and_book->closure = cards; - e_selection_model_foreach(selection_model, get_card_1, contact_and_book); - } + g_object_ref (contact_and_book->view); - ep = eab_popup_new("org.gnome.evolution.addressbook.view.popup"); - t = eab_popup_target_new_select(ep, view->book, !eab_model_editable(view->model), cards); - t->target.widget = (GtkWidget *)view; + selection_model = contact_and_book_get_selection_model (contact_and_book); + if (selection_model) + selection = e_selection_model_selected_count (selection_model) > 0; - for (i=0;i<sizeof(eabv_popup_items)/sizeof(eabv_popup_items[0]);i++) - menus = g_slist_prepend(menus, &eabv_popup_items[i]); + popup = e_popup_menu_create (menu, + 0, + (eab_model_editable (view->model) ? 0 : POPUP_READONLY_MASK) + + (selection ? 0 : POPUP_NOSELECTION_MASK) + + (get_has_email_address (contact_and_book) ? 0 : POPUP_NOEMAIL_MASK), + contact_and_book); - e_popup_add_items((EPopup *)ep, menus, NULL, eabv_popup_free, contact_and_book); + g_signal_connect (popup, "selection-done", + G_CALLBACK (free_popup_info), contact_and_book); + e_popup_menu (popup, event); - menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0); - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button.button:0, event?event->button.time:gtk_get_current_event_time()); } static void @@ -1189,23 +1344,13 @@ contact_changed (EABModel *model, gint index, EABView *eav) } static void -contacts_removed (EABModel *model, gpointer data, EABView *eav) +contact_removed (EABModel *model, gint index, EABView *eav) { - GArray *indices = (GArray *) data; - int count = indices->len; - gint i; - - for (i = 0; i < count; i ++) { - - - if (eav->displayed_contact == g_array_index (indices, gint, i)) { - - /* if the contact that's presently displayed is changed, clear the display */ - eab_contact_display_render (EAB_CONTACT_DISPLAY (eav->contact_display), NULL, - EAB_CONTACT_DISPLAY_RENDER_NORMAL); - eav->displayed_contact = -1; - break; - } + if (eav->displayed_contact == index) { + /* if the contact that's presently displayed is changed, clear the display */ + eab_contact_display_render (EAB_CONTACT_DISPLAY (eav->contact_display), NULL, + EAB_CONTACT_DISPLAY_RENDER_NORMAL); + eav->displayed_contact = -1; } } @@ -1739,7 +1884,7 @@ eab_view_print(EABView *view) NULL); print = e_contact_print_dialog_new(book, query); g_free(query); - gtk_widget_show(print); + gtk_widget_show_all(print); } else if (view->view_type == EAB_VIEW_TABLE) { GtkWidget *dialog; @@ -1747,7 +1892,7 @@ eab_view_print(EABView *view) ETable *etable; EContactPrintDialogWeakData *weak_data; - dialog = e_print_get_dialog (_("Print cards"), GNOME_PRINT_DIALOG_RANGE | GNOME_PRINT_DIALOG_COPIES); + dialog = gnome_print_dialog_new(NULL, "Print cards", GNOME_PRINT_DIALOG_RANGE | GNOME_PRINT_DIALOG_COPIES); gnome_print_dialog_construct_range_any(GNOME_PRINT_DIALOG(dialog), GNOME_PRINT_RANGE_ALL | GNOME_PRINT_RANGE_SELECTION, NULL, NULL, NULL); @@ -1807,8 +1952,9 @@ eab_view_print_preview(EABView *view) g_object_ref (printable); gtk_object_sink (GTK_OBJECT (printable)); - config = e_print_load_config (); - master = gnome_print_job_new (config); + master = gnome_print_job_new(NULL); + config = gnome_print_job_get_config (master); + gnome_print_config_set_int (config, GNOME_PRINT_KEY_NUM_COPIES, 1); pc = gnome_print_job_get_context( master ); e_printable_reset(printable); while (e_printable_data_left(printable)) { @@ -1843,43 +1989,12 @@ eab_view_print_preview(EABView *view) void eab_view_delete_selection(EABView *view) { - GList *list, *l; - - if (!eab_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(view->widget)))) - return; - - list = get_selected_contacts(view); - if (e_book_check_static_capability (view->book, "bulk-remove")) { - GList *ids = NULL; - - for (l=list;l;l=g_list_next(l)) { - EContact *contact = l->data; - - ids = g_list_prepend (ids, (char*)e_contact_get_const (contact, E_CONTACT_UID)); - } + ContactAndBook contact_and_book; - /* Remove the cards all at once. */ - /* XXX no callback specified... ugh */ - e_book_async_remove_contacts (view->book, - ids, - NULL, - NULL); - - g_list_free (ids); - } - else { - for (l=list;l;l=g_list_next(l)) { - EContact *contact = l->data; - /* Remove the card. */ - /* XXX no callback specified... ugh */ - e_book_async_remove_contact (view->book, - contact, - NULL, - NULL); - } - } + memset (&contact_and_book, 0, sizeof (contact_and_book)); + contact_and_book.view = view; - e_free_object_list(list); + delete (GTK_WIDGET (view), &contact_and_book); } static void @@ -2182,25 +2297,3 @@ eab_view_can_move_to_folder (EABView *view) { return view ? eab_view_selection_nonempty (view) && eab_model_editable (view->model) : FALSE; } - -EABMenuTargetSelect * -eab_view_get_menu_target (EABView *view, EABMenu *menu) -{ - GPtrArray *cards = g_ptr_array_new(); - ESelectionModel *selection_model; - EABMenuTargetSelect *t; - - selection_model = get_selection_model (view); - if (selection_model) { - ContactAndBook cab; - - cab.view = view; - cab.closure = cards; - e_selection_model_foreach(selection_model, get_card_1, &cab); - } - - t = eab_menu_target_new_select(menu, view->book, !eab_model_editable(view->model), cards); - t->target.widget = (GtkWidget *)view; - - return t; -} diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h index a55406915e..810252ea6b 100644 --- a/addressbook/gui/widgets/e-addressbook-view.h +++ b/addressbook/gui/widgets/e-addressbook-view.h @@ -32,9 +32,6 @@ G_BEGIN_DECLS -struct _EABMenu; -struct _EABMenuTargetSelect; - /* EABView - A card displaying information about a contact. * * The following arguments are available: @@ -157,8 +154,6 @@ gboolean eab_view_can_stop (EABView *view); gboolean eab_view_can_copy_to_folder (EABView *view); gboolean eab_view_can_move_to_folder (EABView *view); -struct _EABMenuTargetSelect *eab_view_get_menu_target (EABView *view, struct _EABMenu *menu); - G_END_DECLS; #endif /* __EAB_VIEW_H__ */ diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c index 145b755781..464d36ebbe 100644 --- a/addressbook/gui/widgets/eab-contact-display.c +++ b/addressbook/gui/widgets/eab-contact-display.c @@ -36,7 +36,7 @@ #include <gtkhtml/gtkhtml.h> #include <gtkhtml/gtkhtml-stream.h> -#define HANDLE_MAILTO_INTERNALLY 1 +/*#define HANDLE_MAILTO_INTERNALLY 1*/ #define PARENT_TYPE (GTK_TYPE_HTML) @@ -248,19 +248,6 @@ accum_attribute (GString *gstr, EContact *contact, const char *html_label, ECont } } -static void -accum_multival_attribute (GString *gstr, EContact *contact, const char *html_label, EContactField field, const char *icon, unsigned int html_flags) -{ - GList *val_list, *l; - - val_list = e_contact_get (contact, field); - for (l = val_list; l; l = l->next) { - const char *str = (const char *) l->data; - accum_name_value (gstr, html_label, str, icon, html_flags); - } - g_list_foreach (val_list, (GFunc) g_free, NULL); - g_list_free (val_list); -} static void render_contact_list (GtkHTMLStream *html_stream, EContact *contact) @@ -343,12 +330,12 @@ render_contact (GtkHTMLStream *html_stream, EContact *contact) g_string_assign (accum, ""); - accum_multival_attribute (accum, contact, _("AIM"), E_CONTACT_IM_AIM, AIM_ICON, 0); - accum_multival_attribute (accum, contact, _("GroupWise"), E_CONTACT_IM_GROUPWISE, GROUPWISE_ICON, 0); - accum_multival_attribute (accum, contact, _("ICQ"), E_CONTACT_IM_ICQ, ICQ_ICON, 0); - accum_multival_attribute (accum, contact, _("Jabber"), E_CONTACT_IM_JABBER, JABBER_ICON, 0); - accum_multival_attribute (accum, contact, _("MSN"), E_CONTACT_IM_MSN, MSN_ICON, 0); - accum_multival_attribute (accum, contact, _("Yahoo"), E_CONTACT_IM_YAHOO, YAHOO_ICON, 0); + accum_attribute (accum, contact, _("AIM"), E_CONTACT_IM_AIM_HOME_1, AIM_ICON, 0); + accum_attribute (accum, contact, _("GroupWise"), E_CONTACT_IM_GROUPWISE_HOME_1, GROUPWISE_ICON, 0); + accum_attribute (accum, contact, _("ICQ"), E_CONTACT_IM_ICQ_HOME_1, ICQ_ICON, 0); + accum_attribute (accum, contact, _("Jabber"), E_CONTACT_IM_JABBER_HOME_1, JABBER_ICON, 0); + accum_attribute (accum, contact, _("MSN"), E_CONTACT_IM_MSN_HOME_1, MSN_ICON, 0); + accum_attribute (accum, contact, _("Yahoo"), E_CONTACT_IM_YAHOO_HOME_1, YAHOO_ICON, 0); if (accum->len > 0) gtk_html_stream_printf (html_stream, accum->str); |