diff options
Diffstat (limited to 'modules/addressbook/e-book-shell-backend.c')
-rw-r--r-- | modules/addressbook/e-book-shell-backend.c | 524 |
1 files changed, 524 insertions, 0 deletions
diff --git a/modules/addressbook/e-book-shell-backend.c b/modules/addressbook/e-book-shell-backend.c new file mode 100644 index 0000000000..bfa19826ef --- /dev/null +++ b/modules/addressbook/e-book-shell-backend.c @@ -0,0 +1,524 @@ +/* + * e-book-shell-backend.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "e-book-shell-backend.h" + +#include <string.h> +#include <glib/gi18n.h> +#include <libebook/libebook.h> + +#include "shell/e-shell.h" +#include "shell/e-shell-window.h" + +#include "addressbook/gui/widgets/eab-gui-util.h" +#include "addressbook/gui/widgets/e-addressbook-view.h" +#include "addressbook/gui/contact-editor/e-contact-editor.h" +#include "addressbook/gui/contact-editor/e-contact-quick-add.h" +#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h" +#include "addressbook/importers/evolution-addressbook-importers.h" + +#include "autocompletion-config.h" + +#include "e-book-shell-content.h" +#include "e-book-shell-migrate.h" +#include "e-book-shell-view.h" + +#ifdef ENABLE_SMIME +#include "smime/gui/component.h" +#include "smime/gui/certificate-manager.h" +#endif + +#define E_BOOK_SHELL_BACKEND_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_BOOK_SHELL_BACKEND, EBookShellBackendPrivate)) + +struct _EBookShellBackendPrivate { + gint placeholder; +}; + +G_DEFINE_DYNAMIC_TYPE ( + EBookShellBackend, + e_book_shell_backend, + E_TYPE_SHELL_BACKEND) + +static void +book_shell_backend_init_importers (void) +{ + EImportClass *import_class; + EImportImporter *importer; + + import_class = g_type_class_ref (e_import_get_type ()); + + importer = evolution_ldif_importer_peek (); + e_import_class_add_importer (import_class, importer, NULL, NULL); + + importer = evolution_vcard_importer_peek (); + e_import_class_add_importer (import_class, importer, NULL, NULL); + + importer = evolution_csv_outlook_importer_peek (); + e_import_class_add_importer (import_class, importer, NULL, NULL); + + importer = evolution_csv_mozilla_importer_peek (); + e_import_class_add_importer (import_class, importer, NULL, NULL); + + importer = evolution_csv_evolution_importer_peek (); + e_import_class_add_importer (import_class, importer, NULL, NULL); +} + +static void +book_shell_backend_new_contact_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + EShell *shell = user_data; + EClient *client; + EContact *contact; + EABEditor *editor; + GError *error = NULL; + + client = e_client_cache_get_client_finish ( + E_CLIENT_CACHE (source_object), result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + /* XXX Handle errors better. */ + if (error != NULL) { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + goto exit; + } + + contact = e_contact_new (); + + editor = e_contact_editor_new ( + shell, E_BOOK_CLIENT (client), contact, TRUE, TRUE); + + eab_editor_show (editor); + + g_object_unref (contact); + g_object_unref (client); + +exit: + g_object_unref (shell); +} + +static void +book_shell_backend_new_contact_list_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + EShell *shell = user_data; + EClient *client; + EContact *contact; + EABEditor *editor; + GError *error = NULL; + + client = e_client_cache_get_client_finish ( + E_CLIENT_CACHE (source_object), result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + /* XXX Handle errors better. */ + if (error != NULL) { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + goto exit; + } + + contact = e_contact_new (); + + editor = e_contact_list_editor_new ( + shell, E_BOOK_CLIENT (client), contact, TRUE, TRUE); + + eab_editor_show (editor); + + g_object_unref (contact); + g_object_unref (client); + +exit: + g_object_unref (shell); +} + +static void +action_contact_new_cb (GtkAction *action, + EShellWindow *shell_window) +{ + EShell *shell; + ESource *source = NULL; + ESourceRegistry *registry; + EClientCache *client_cache; + const gchar *action_name; + + /* This callback is used for both contacts and contact lists. */ + + shell = e_shell_window_get_shell (shell_window); + client_cache = e_shell_get_client_cache (shell); + + if (g_strcmp0 (e_shell_window_get_active_view (shell_window), "addressbook") == 0) { + EShellView *shell_view = e_shell_window_get_shell_view (shell_window, "addressbook"); + + if (shell_view && E_IS_BOOK_SHELL_VIEW (shell_view)) { + EBookShellContent *book_shell_content; + EAddressbookView *view; + EAddressbookModel *model; + EBookClient *book_client; + + book_shell_content = NULL; + g_object_get (G_OBJECT (shell_view), "shell-content", &book_shell_content, NULL); + g_return_if_fail (book_shell_content != NULL); + + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + model = e_addressbook_view_get_model (view); + book_client = e_addressbook_model_get_client (model); + g_return_if_fail (book_client != NULL); + + source = g_object_ref (e_client_get_source (E_CLIENT (book_client))); + + g_object_unref (book_shell_content); + } + } + + if (!source) { + registry = e_shell_get_registry (shell); + source = e_source_registry_ref_default_address_book (registry); + } + + /* Use a callback function appropriate for the action. */ + action_name = gtk_action_get_name (action); + if (strcmp (action_name, "contact-new") == 0) + e_client_cache_get_client ( + client_cache, source, + E_SOURCE_EXTENSION_ADDRESS_BOOK, + NULL, + book_shell_backend_new_contact_cb, + g_object_ref (shell)); + if (strcmp (action_name, "contact-new-list") == 0) + e_client_cache_get_client ( + client_cache, source, + E_SOURCE_EXTENSION_ADDRESS_BOOK, + NULL, + book_shell_backend_new_contact_list_cb, + g_object_ref (shell)); + + g_object_unref (source); +} + +static void +action_address_book_new_cb (GtkAction *action, + EShellWindow *shell_window) +{ + EShell *shell; + ESourceRegistry *registry; + GtkWidget *config; + GtkWidget *dialog; + const gchar *icon_name; + + shell = e_shell_window_get_shell (shell_window); + + registry = e_shell_get_registry (shell); + config = e_book_source_config_new (registry, NULL); + + dialog = e_source_config_dialog_new (E_SOURCE_CONFIG (config)); + + gtk_window_set_transient_for ( + GTK_WINDOW (dialog), GTK_WINDOW (shell_window)); + + icon_name = gtk_action_get_icon_name (action); + gtk_window_set_icon_name (GTK_WINDOW (dialog), icon_name); + + gtk_window_set_title (GTK_WINDOW (dialog), _("New Address Book")); + + gtk_widget_show (dialog); +} + +static GtkActionEntry item_entries[] = { + + { "contact-new", + "contact-new", + NC_("New", "_Contact"), + "<Shift><Control>c", + N_("Create a new contact"), + G_CALLBACK (action_contact_new_cb) }, + + { "contact-new-list", + "stock_contact-list", + NC_("New", "Contact _List"), + "<Shift><Control>l", + N_("Create a new contact list"), + G_CALLBACK (action_contact_new_cb) } +}; + +static GtkActionEntry source_entries[] = { + + { "address-book-new", + "address-book-new", + NC_("New", "Address _Book"), + NULL, + N_("Create a new address book"), + G_CALLBACK (action_address_book_new_cb) } +}; + +static gboolean +book_shell_backend_init_preferences (EShell *shell) +{ + GtkWidget *preferences_window; + + /* This is a main loop idle callback. */ + + preferences_window = e_shell_get_preferences_window (shell); + + e_preferences_window_add_page ( + E_PREFERENCES_WINDOW (preferences_window), + "contacts", + "preferences-autocompletion", + _("Contacts"), + "index#contacts", + autocompletion_config_new, + 200); + +#ifdef ENABLE_SMIME + preferences_window = e_shell_get_preferences_window (shell); + e_preferences_window_add_page ( + E_PREFERENCES_WINDOW (preferences_window), + "certificates", + "preferences-certificates", + _("Certificates"), + "mail-encryption-s-mime-manage", + e_cert_manager_config_new, + 700); +#endif + + return FALSE; +} + +static void +book_shell_backend_quick_add_email_cb (EShell *shell, + const gchar *email) +{ + EClientCache *client_cache; + + /* XXX This is an ugly hack but it's the only way I could think + * of to integrate this feature with other shell modules. */ + + client_cache = e_shell_get_client_cache (shell); + e_contact_quick_add_email (client_cache, email, NULL, NULL); +} + +static void +book_shell_backend_quick_add_vcard_cb (EShell *shell, + const gchar *vcard) +{ + EClientCache *client_cache; + + /* XXX This is an ugly hack but it's the only way I could think + * of to integrate this feature with other shell modules. */ + + client_cache = e_shell_get_client_cache (shell); + e_contact_quick_add_vcard (client_cache, vcard, NULL, NULL); +} + +static gboolean +book_shell_backend_handle_uri_cb (EShellBackend *shell_backend, + const gchar *uri) +{ + SoupURI *soup_uri; + const gchar *cp; + gchar *source_uid = NULL; + gchar *contact_uid = NULL; + + if (!g_str_has_prefix (uri, "contacts:")) + return FALSE; + + soup_uri = soup_uri_new (uri); + + if (soup_uri == NULL) + return FALSE; + + cp = soup_uri_get_query (soup_uri); + + if (cp == NULL) { + soup_uri_free (soup_uri); + return FALSE; + } + + while (*cp != '\0') { + gchar *header; + gchar *content; + gsize length; + gsize content_length; + + length = strcspn (cp, "=&"); + + /* If it's malformed, give up. */ + if (cp[length] != '=') + break; + + header = (gchar *) cp; + header[length] = '\0'; + cp += length + 1; + + content_length = strcspn (cp, "&"); + content = g_strndup (cp, content_length); + + if (g_ascii_strcasecmp (header, "source-uid") == 0) + source_uid = g_strdup (content); + + if (g_ascii_strcasecmp (header, "contact-uid") == 0) + contact_uid = g_strdup (content); + + g_free (content); + + cp += content_length; + if (*cp == '&') { + cp++; + if (strcmp (cp, "amp;")) + cp += 4; + } + } + + /* FIXME */ + /*addressbook_view_edit_contact (view, source_uid, contact_uid);*/ + + g_free (source_uid); + g_free (contact_uid); + + soup_uri_free (soup_uri); + + return TRUE; +} + +static void +book_shell_backend_window_added_cb (EShellBackend *shell_backend, + GtkWindow *window) +{ + const gchar *backend_name; + + if (!E_IS_SHELL_WINDOW (window)) + return; + + backend_name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name; + + e_shell_window_register_new_item_actions ( + E_SHELL_WINDOW (window), backend_name, + item_entries, G_N_ELEMENTS (item_entries)); + + e_shell_window_register_new_source_actions ( + E_SHELL_WINDOW (window), backend_name, + source_entries, G_N_ELEMENTS (source_entries)); +} + +static void +book_shell_backend_constructed (GObject *object) +{ + EShell *shell; + EShellBackend *shell_backend; + + shell_backend = E_SHELL_BACKEND (object); + shell = e_shell_backend_get_shell (shell_backend); + + /* XXX Why is this here? Address books aren't the only + * things that use S/MIME. Maybe put it in EShell? */ +#ifdef ENABLE_SMIME + smime_component_init (); +#endif + + book_shell_backend_init_importers (); + + g_signal_connect ( + shell, "event::contact-quick-add-email", + G_CALLBACK (book_shell_backend_quick_add_email_cb), NULL); + + g_signal_connect_swapped ( + shell, "event::contact-quick-add-vcard", + G_CALLBACK (book_shell_backend_quick_add_vcard_cb), NULL); + + g_signal_connect_swapped ( + shell, "handle-uri", + G_CALLBACK (book_shell_backend_handle_uri_cb), + shell_backend); + + g_signal_connect_swapped ( + shell, "window-added", + G_CALLBACK (book_shell_backend_window_added_cb), + shell_backend); + + /* Initialize preferences after the main loop starts so + * that all EPlugins and EPluginHooks are loaded first. */ + g_idle_add ((GSourceFunc) book_shell_backend_init_preferences, shell); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_book_shell_backend_parent_class)->constructed (object); +} + +static void +e_book_shell_backend_class_init (EBookShellBackendClass *class) +{ + GObjectClass *object_class; + EShellBackendClass *shell_backend_class; + + g_type_class_add_private (class, sizeof (EBookShellBackendPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = book_shell_backend_constructed; + + shell_backend_class = E_SHELL_BACKEND_CLASS (class); + shell_backend_class->shell_view_type = E_TYPE_BOOK_SHELL_VIEW; + shell_backend_class->name = "addressbook"; + shell_backend_class->aliases = "contacts"; + shell_backend_class->schemes = ""; + shell_backend_class->sort_order = 300; + shell_backend_class->preferences_page = "contacts"; + shell_backend_class->start = NULL; + shell_backend_class->migrate = e_book_shell_backend_migrate; +} + +static void +e_book_shell_backend_class_finalize (EBookShellBackendClass *class) +{ +} + +static void +e_book_shell_backend_init (EBookShellBackend *book_shell_backend) +{ + book_shell_backend->priv = + E_BOOK_SHELL_BACKEND_GET_PRIVATE (book_shell_backend); +} + +void +e_book_shell_backend_type_register (GTypeModule *type_module) +{ + /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration + * function, so we have to wrap it with a public function in + * order to register types from a separate compilation unit. */ + e_book_shell_backend_register_type (type_module); +} |