From 653cfffc0e00dfb59b36813c1b45c53d3f773c65 Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Tue, 21 Oct 2003 18:49:34 +0000 Subject: Merge new-ui-branch to the trunk. svn path=/trunk/; revision=22965 --- addressbook/gui/component/addressbook-component.c | 653 ++++------------------ 1 file changed, 95 insertions(+), 558 deletions(-) (limited to 'addressbook/gui/component/addressbook-component.c') diff --git a/addressbook/gui/component/addressbook-component.c b/addressbook/gui/component/addressbook-component.c index cdfeeb9755..c323a1bd78 100644 --- a/addressbook/gui/component/addressbook-component.c +++ b/addressbook/gui/component/addressbook-component.c @@ -1,7 +1,7 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* addressbook-component.c * - * Copyright (C) 2000 Ximian, Inc. + * Copyright (C) 2003 Ettore Perazzoli * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -17,633 +17,170 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * - * Author: Ettore Perazzoli + * Author: Ettore Perazzoli */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "evolution-shell-component.h" -#include "evolution-shell-component-dnd.h" -#include "evolution-storage.h" -#include "e-folder-list.h" - -#include "ebook/e-book.h" -#include "ebook/e-card.h" -#include "ebook/e-book-util.h" - -#include "addressbook-config.h" -#include "addressbook-storage.h" -#include "addressbook-component.h" -#include "addressbook.h" -#include "addressbook/gui/merging/e-card-merging.h" -#include "addressbook/gui/widgets/e-addressbook-util.h" - - - -#define GNOME_EVOLUTION_ADDRESSBOOK_COMPONENT_ID "OAFIID:GNOME_Evolution_Addressbook_ShellComponent" - -EvolutionShellClient *global_shell_client = NULL; +/* EPFIXME: Add autocompletion setting. */ -EvolutionShellClient * -addressbook_component_get_shell_client (void) -{ - return global_shell_client; -} -static char *accepted_dnd_types[] = { - "text/x-vcard", - NULL -}; +#include -static const EvolutionShellComponentFolderType folder_types[] = { - { "contacts", "evolution-contacts.png", N_("Contacts"), N_("Folder containing contact information"), - TRUE, accepted_dnd_types, NULL }, - { "contacts/ldap", "ldap.png", N_("LDAP Server"), N_("LDAP server containing contact information"), - FALSE, accepted_dnd_types, NULL }, - { "contacts/public", "evolution-contacts.png", N_("Public Contacts"), N_("Public folder containing contact information"), - FALSE, accepted_dnd_types, NULL }, - { NULL } -}; +#include "addressbook-component.h" -#define IS_CONTACT_TYPE(x) (g_ascii_strcasecmp((x), "contacts") == 0 || g_ascii_strcasecmp ((x), "contacts/ldap") == 0 || g_ascii_strcasecmp((x), "contacts/public") == 0) - -/* EvolutionShellComponent methods and signals. */ - -static EvolutionShellComponentResult -create_view (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - const char *view_info, - BonoboControl **control_return, - void *closure) -{ - BonoboControl *control; +#include "addressbook.h" - if (!IS_CONTACT_TYPE (type)) - return EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE; +#include "widgets/misc/e-source-selector.h" - control = addressbook_new_control (); - bonobo_control_set_property (control, NULL, "folder_uri", TC_CORBA_string, physical_uri, NULL); +#include +#include - *control_return = control; - return EVOLUTION_SHELL_COMPONENT_OK; -} +#define PARENT_TYPE bonobo_object_get_type () +static BonoboObjectClass *parent_class = NULL; -static void -create_folder (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - const GNOME_Evolution_ShellComponentListener listener, - void *closure) -{ - CORBA_Environment ev; - GNOME_Evolution_ShellComponentListener_Result result; +struct _AddressbookComponentPrivate { + GConfClient *gconf_client; + ESourceList *source_list; +}; - if (!IS_CONTACT_TYPE (type)) - result = GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE; - else - result = GNOME_Evolution_ShellComponentListener_OK; - CORBA_exception_init(&ev); - GNOME_Evolution_ShellComponentListener_notifyResult(listener, result, &ev); - CORBA_exception_free(&ev); -} +/* Utility functions. */ static void -remove_folder (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - const GNOME_Evolution_ShellComponentListener listener, - void *closure) +load_uri_for_selection (ESourceSelector *selector, + BonoboControl *view_control) { - CORBA_Environment ev; - char *db_path, *summary_path, *subdir_path; - struct stat sb; - int rv; - - CORBA_exception_init(&ev); - - if (!IS_CONTACT_TYPE (type)) { - GNOME_Evolution_ShellComponentListener_notifyResult (listener, - GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE, - &ev); - CORBA_exception_free(&ev); - return; - } - - if (!strncmp (physical_uri, "ldap://", 7)) { - GNOME_Evolution_ShellComponentListener_notifyResult (listener, - GNOME_Evolution_ShellComponentListener_UNSUPPORTED_OPERATION, - &ev); - CORBA_exception_free(&ev); - return; - } - if (strncmp (physical_uri, "file://", 7)) { - GNOME_Evolution_ShellComponentListener_notifyResult (listener, - GNOME_Evolution_ShellComponentListener_INVALID_URI, - &ev); - CORBA_exception_free(&ev); - return; - } - - subdir_path = g_build_filename (physical_uri + 7, "subfolders", NULL); - rv = stat (subdir_path, &sb); - g_free (subdir_path); - if (rv != -1) { - GNOME_Evolution_ShellComponentListener_notifyResult (listener, - GNOME_Evolution_ShellComponentListener_HAS_SUBFOLDERS, - &ev); - CORBA_exception_free(&ev); - return; - } - - db_path = g_build_filename (physical_uri + 7, "addressbook.db", NULL); - summary_path = g_build_filename (physical_uri + 7, "addressbook.db.summary", NULL); - rv = unlink (db_path); - - if (rv == 0 || (rv == -1 && errno == ENOENT)) - rv = unlink (summary_path); + ESource *selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (selector)); - if (rv == 0 || (rv == -1 && errno == ENOENT)) { - GNOME_Evolution_ShellComponentListener_notifyResult (listener, - GNOME_Evolution_ShellComponentListener_OK, - &ev); - } - else { - GNOME_Evolution_ShellComponentListener_notifyResult (listener, - GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED, - &ev); + if (selected_source != NULL) { + char *uri = e_source_get_uri (selected_source); + bonobo_control_set_property (view_control, NULL, "folder_uri", TC_CORBA_string, uri, NULL); + g_free (uri); } - - g_free (db_path); - g_free (summary_path); - - CORBA_exception_free(&ev); } -/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ -/* This code is cut & pasted from calendar/gui/component-factory.c */ +/* Callbacks. */ -static GNOME_Evolution_ShellComponentListener_Result -xfer_file (GnomeVFSURI *base_src_uri, - GnomeVFSURI *base_dest_uri, - const char *file_name, - int remove_source) +static void +primary_source_selection_changed_callback (ESourceSelector *selector, + BonoboControl *view_control) { - GnomeVFSURI *src_uri, *dest_uri; - GnomeVFSHandle *hin, *hout; - GnomeVFSResult result; - GnomeVFSFileInfo file_info; - GnomeVFSFileSize size; - char *buffer; - - src_uri = gnome_vfs_uri_append_file_name (base_src_uri, file_name); - - result = gnome_vfs_open_uri (&hin, src_uri, GNOME_VFS_OPEN_READ); - if (result == GNOME_VFS_ERROR_NOT_FOUND) { - gnome_vfs_uri_unref (src_uri); - return GNOME_Evolution_ShellComponentListener_OK; /* No need to xfer anything. */ - } - if (result != GNOME_VFS_OK) { - gnome_vfs_uri_unref (src_uri); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } + load_uri_for_selection (selector, view_control); +} - result = gnome_vfs_get_file_info_uri (src_uri, &file_info, GNOME_VFS_FILE_INFO_DEFAULT); - if (result != GNOME_VFS_OK) { - gnome_vfs_uri_unref (src_uri); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } - dest_uri = gnome_vfs_uri_append_file_name (base_dest_uri, file_name); +/* Evolution::Component CORBA methods. */ - result = gnome_vfs_create_uri (&hout, dest_uri, GNOME_VFS_OPEN_WRITE, FALSE, 0600); - if (result != GNOME_VFS_OK) { - gnome_vfs_close (hin); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } +static void +impl_createControls (PortableServer_Servant servant, + Bonobo_Control *corba_sidebar_control, + Bonobo_Control *corba_view_control, + CORBA_Environment *ev) +{ + AddressbookComponent *addressbook_component = ADDRESSBOOK_COMPONENT (bonobo_object_from_servant (servant)); + GtkWidget *selector; + GtkWidget *selector_scrolled_window; + BonoboControl *sidebar_control; + BonoboControl *view_control; - /* write source file to destination file */ - buffer = g_malloc (file_info.size); - result = gnome_vfs_read (hin, buffer, file_info.size, &size); - if (result != GNOME_VFS_OK) { - gnome_vfs_close (hin); - gnome_vfs_close (hout); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - g_free (buffer); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } + selector = e_source_selector_new (addressbook_component->priv->source_list); + e_source_selector_show_selection (E_SOURCE_SELECTOR (selector), FALSE); + gtk_widget_show (selector); - result = gnome_vfs_write (hout, buffer, file_info.size, &size); - if (result != GNOME_VFS_OK) { - gnome_vfs_close (hin); - gnome_vfs_close (hout); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - g_free (buffer); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } + selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (selector_scrolled_window), selector); + gtk_widget_show (selector_scrolled_window); - if (remove_source) { - char *text_uri; + sidebar_control = bonobo_control_new (selector_scrolled_window); - /* Sigh, we have to do this as there is no gnome_vfs_unlink_uri(). :-( */ + view_control = addressbook_new_control (); + g_signal_connect_object (selector, "primary_selection_changed", + G_CALLBACK (primary_source_selection_changed_callback), + G_OBJECT (view_control), 0); + load_uri_for_selection (E_SOURCE_SELECTOR (selector), view_control); - text_uri = gnome_vfs_uri_to_string (src_uri, GNOME_VFS_URI_HIDE_NONE); - result = gnome_vfs_unlink (text_uri); - g_free (text_uri); - } + *corba_sidebar_control = CORBA_Object_duplicate (BONOBO_OBJREF (sidebar_control), ev); + *corba_view_control = CORBA_Object_duplicate (BONOBO_OBJREF (view_control), ev); +} - gnome_vfs_close (hin); - gnome_vfs_close (hout); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - g_free (buffer); - return GNOME_Evolution_ShellComponentListener_OK; -} +/* GObject methods. */ static void -xfer_folder (EvolutionShellComponent *shell_component, - const char *source_physical_uri, - const char *destination_physical_uri, - const char *type, - gboolean remove_source, - const GNOME_Evolution_ShellComponentListener listener, - void *closure) +impl_dispose (GObject *object) { - CORBA_Environment ev; - - GnomeVFSURI *src_uri; - GnomeVFSURI *dest_uri; - GnomeVFSResult result; - GNOME_Evolution_ShellComponentListener_Result e_result; - - CORBA_exception_init (&ev); - - if (!IS_CONTACT_TYPE (type)) { - GNOME_Evolution_ShellComponentListener_notifyResult (listener, - GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE, - &ev); - CORBA_exception_free(&ev); - return; - } - - if (!strncmp (source_physical_uri, "ldap://", 7) - || !strncmp (destination_physical_uri, "ldap://", 7)) { - GNOME_Evolution_ShellComponentListener_notifyResult (listener, - GNOME_Evolution_ShellComponentListener_UNSUPPORTED_OPERATION, - &ev); - CORBA_exception_free(&ev); - return; - } - - if (strncmp (source_physical_uri, "file://", 7) - || strncmp (destination_physical_uri, "file://", 7)) { - GNOME_Evolution_ShellComponentListener_notifyResult (listener, - GNOME_Evolution_ShellComponentListener_INVALID_URI, - &ev); - CORBA_exception_free(&ev); - return; - } + AddressbookComponentPrivate *priv = ADDRESSBOOK_COMPONENT (object)->priv; - /* check URIs */ - src_uri = gnome_vfs_uri_new (source_physical_uri); - dest_uri = gnome_vfs_uri_new (destination_physical_uri); - if (!src_uri || ! dest_uri) { - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_INVALID_URI, - &ev); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - CORBA_exception_free (&ev); - return; + if (priv->source_list != NULL) { + g_object_unref (priv->source_list); + priv->source_list = NULL; } - e_result = xfer_file (src_uri, dest_uri, "addressbook.db", remove_source); - - if ((e_result == GNOME_Evolution_ShellComponentListener_OK) && remove_source) { - char *summary_uri; - - summary_uri = g_strconcat (source_physical_uri, "/addressbook.db.summary", NULL); - result = gnome_vfs_unlink (summary_uri); - if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_NOT_FOUND) - e_result = GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - g_free (summary_uri); + if (priv->gconf_client != NULL) { + g_object_unref (priv->gconf_client); + priv->gconf_client = NULL; } - GNOME_Evolution_ShellComponentListener_notifyResult (listener, e_result, &ev); - - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - - CORBA_exception_free (&ev); -} - -static char* -get_dnd_selection (EvolutionShellComponent *shell_component, - const char *physical_uri, - int type, - int *format_return, - const char **selection_return, - int *selection_length_return, - void *closure) -{ - /* g_print ("should get dnd selection for %s\n", physical_uri); */ - return NULL; + (* G_OBJECT_CLASS (parent_class)->dispose) (object); } -static int owner_count = 0; - static void -owner_set_cb (EvolutionShellComponent *shell_component, - EvolutionShellClient *shell_client, - const char *evolution_homedir, - gpointer user_data) +impl_finalize (GObject *object) { - owner_count ++; + AddressbookComponentPrivate *priv = ADDRESSBOOK_COMPONENT (object)->priv; - if (global_shell_client == NULL) - global_shell_client = shell_client; + g_free (priv); - addressbook_storage_setup (shell_component, evolution_homedir); + (* G_OBJECT_CLASS (parent_class)->finalize) (object); } -static void -owner_unset_cb (EvolutionShellComponent *shell_component, - GNOME_Evolution_Shell shell_interface, - gpointer user_data) -{ - owner_count --; - - if (owner_count == 0) - global_shell_client = NULL; - addressbook_storage_cleanup (); -} +/* Initialization. */ -/* FIXME We should perhaps take the time to figure out if the book is editable. */ static void -new_item_cb (EBook *book, gpointer closure) +addressbook_component_class_init (AddressbookComponentClass *class) { - gboolean is_list = GPOINTER_TO_INT (closure); - ECard *card; - - if (book == NULL) - return; - - card = e_card_new (""); - if (is_list) - e_addressbook_show_contact_list_editor (book, card, TRUE, TRUE); - else - e_addressbook_show_contact_editor (book, card, TRUE, TRUE); - g_object_unref (card); -} + POA_GNOME_Evolution_Component__epv *epv = &class->epv; + GObjectClass *object_class = G_OBJECT_CLASS (class); -static void -user_create_new_item_cb (EvolutionShellComponent *shell_component, - const char *id, - const char *parent_folder_physical_uri, - const char *parent_folder_type, - gpointer data) -{ - gboolean is_contact_list; - if (!strcmp (id, "contact")) { - is_contact_list = FALSE; - } else if (!strcmp (id, "contact_list")) { - is_contact_list = TRUE; - } else { - g_warning ("Don't know how to create item of type \"%s\"", id); - return; - } - if (IS_CONTACT_TYPE (parent_folder_type)) { - e_book_use_address_book_by_uri (parent_folder_physical_uri, - new_item_cb, GINT_TO_POINTER (is_contact_list)); - } else { - e_book_use_default_book (new_item_cb, GINT_TO_POINTER (is_contact_list)); - } -} + epv->createControls = impl_createControls; - -/* Destination side DnD */ + object_class->dispose = impl_dispose; + object_class->finalize = impl_finalize; -static CORBA_boolean -destination_folder_handle_motion (EvolutionShellComponentDndDestinationFolder *folder, - const char *physical_uri, - const char *folder_type, - const GNOME_Evolution_ShellComponentDnd_DestinationFolder_Context * destination_context, - GNOME_Evolution_ShellComponentDnd_Action * suggested_action_return, - gpointer user_data) -{ - *suggested_action_return = GNOME_Evolution_ShellComponentDnd_ACTION_MOVE; - return TRUE; + parent_class = g_type_class_peek_parent (class); } static void -dnd_drop_book_open_cb (EBook *book, EBookStatus status, GList *card_list) -{ - GList *l; - - for (l = card_list; l; l = l->next) { - ECard *card = l->data; - - e_card_merging_book_add_card (book, card, NULL /* XXX */, NULL); - } -} - -static CORBA_boolean -destination_folder_handle_drop (EvolutionShellComponentDndDestinationFolder *folder, - const char *physical_uri, - const char *folder_type, - const GNOME_Evolution_ShellComponentDnd_DestinationFolder_Context * destination_context, - const GNOME_Evolution_ShellComponentDnd_Action action, - const GNOME_Evolution_ShellComponentDnd_Data * data, - gpointer user_data) +addressbook_component_init (AddressbookComponent *component) { - EBook *book; - GList *card_list; - char *expanded_uri; - - if (action == GNOME_Evolution_ShellComponentDnd_ACTION_LINK) - return FALSE; /* we can't create links in our addressbook format */ - - /* g_print ("in destination_folder_handle_drop (%s)\n", physical_uri); */ - - card_list = e_card_load_cards_from_string_with_default_charset (data->bytes._buffer, "ISO-8859-1"); - - expanded_uri = e_book_expand_uri (physical_uri); + AddressbookComponentPrivate *priv; - book = e_book_new (); - addressbook_load_uri (book, expanded_uri, - (EBookCallback)dnd_drop_book_open_cb, card_list); + priv = g_new0 (AddressbookComponentPrivate, 1); - g_free (expanded_uri); + /* EPFIXME: Should use a custom one instead? Also we should add + addressbook_component_peek_gconf_client(). */ + priv->gconf_client = gconf_client_get_default (); - return TRUE; -} - - -/* Quitting. */ + priv->source_list = e_source_list_new_for_gconf (priv->gconf_client, + "/apps/evolution/addressbook/sources"); -static gboolean -request_quit (EvolutionShellComponent *shell_component, - void *data) -{ - if (! e_contact_editor_request_close_all () - || ! e_contact_list_editor_request_close_all ()) - return FALSE; - else - return TRUE; + component->priv = priv; } - -/* The factory function. */ - -static void -add_creatable_item (EvolutionShellComponent *shell_component, - const char *id, - const char *description, - const char *menu_description, - const char *tooltip, - char menu_shortcut, - const char *icon_name) -{ - char *icon_path; - GdkPixbuf *icon; - - if (icon_name == NULL) { - icon_path = NULL; - icon = NULL; - } else { - icon_path = g_build_filename (EVOLUTION_IMAGESDIR, icon_name, NULL); - icon = gdk_pixbuf_new_from_file (icon_path, NULL); - } - - evolution_shell_component_add_user_creatable_item (shell_component, - id, - description, - menu_description, - tooltip, - "contacts", - menu_shortcut, - icon); - - if (icon != NULL) - gdk_pixbuf_unref (icon); - g_free (icon_path); -} +/* Public API. */ -static BonoboObject * -create_component (void) +AddressbookComponent * +addressbook_component_peek (void) { - EvolutionShellComponent *shell_component; - EvolutionShellComponentDndDestinationFolder *destination_interface; - - shell_component = evolution_shell_component_new (folder_types, NULL, - create_view, create_folder, - remove_folder, xfer_folder, - NULL, NULL, - get_dnd_selection, - request_quit, - NULL); - - destination_interface = evolution_shell_component_dnd_destination_folder_new (destination_folder_handle_motion, - destination_folder_handle_drop, - shell_component); - - bonobo_object_add_interface (BONOBO_OBJECT (shell_component), - BONOBO_OBJECT (destination_interface)); - - add_creatable_item (shell_component, "contact", - _("New Contact"), _("_Contact"), - _("Create a new contact"), 'c', - "evolution-contacts-mini.png"); - add_creatable_item (shell_component, "contact_list", - _("New Contact List"), _("Contact _List"), - _("Create a new contact list"), 'l', - "contact-list-16.png"); - - g_signal_connect (shell_component, "owner_set", - G_CALLBACK (owner_set_cb), NULL); - g_signal_connect (shell_component, "owner_unset", - G_CALLBACK (owner_unset_cb), NULL); - g_signal_connect (shell_component, "user_create_new_item", - G_CALLBACK (user_create_new_item_cb), NULL); - - return BONOBO_OBJECT (shell_component); -} + static AddressbookComponent *component = NULL; -static void -ensure_completion_uris_exist() -{ - /* Initialize the completion uris if they aren't set yet. The - default set is just the local Contacts folder. */ - EConfigListener *db; - char *val; - - db = e_book_get_config_database (); - - val = e_config_listener_get_string (db, "/apps/evolution/addressbook/completion/uris"); - - if (val && !*val) { - g_free (val); - val = NULL; - } - - if (!val) { - EFolderListItem f[2]; - char *dirname, *uri; - /* in the case where the user is running for the first - time, populate the list with the local contact - folder */ - dirname = g_build_filename (g_get_home_dir (), "evolution/local/Contacts", NULL); - uri = g_strdup_printf ("file://%s", dirname); - - f[0].uri = "evolution:/local/Contacts"; - f[0].physical_uri = uri; - f[0].display_name = _("Contacts"); - - memset (&f[1], 0, sizeof (f[1])); - - val = e_folder_list_create_xml (f); - - g_free (dirname); - g_free (uri); - e_config_listener_set_string (db, "/apps/evolution/addressbook/completion/uris", val); - } + if (component == NULL) + component = g_object_new (addressbook_component_get_type (), NULL); - g_free (val); + return component; } - -/* FIXME this is wrong. */ -BonoboObject * -addressbook_component_init (void) -{ - ensure_completion_uris_exist (); - return create_component (); -} +BONOBO_TYPE_FUNC_FULL (AddressbookComponent, GNOME_Evolution_Component, PARENT_TYPE, addressbook_component) -- cgit v1.2.3