diff options
Diffstat (limited to 'addressbook/gui/component')
29 files changed, 4173 insertions, 2972 deletions
diff --git a/addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in b/addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in deleted file mode 100644 index 823d5bd89f..0000000000 --- a/addressbook/gui/component/GNOME_Evolution_Addressbook.server.in.in +++ /dev/null @@ -1,136 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@" - type="shlib" - location="@COMPONENTDIR_IN_SERVER_FILE@/libevolution-addressbook@SOEXT@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Address Book"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_VCard_Control:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Bonobo/Control:1.0"/> - <item value="IDL:Bonobo/PersistStream:1.0"/> - </oaf_attribute> - - <oaf_attribute name="bonobo:supported_mime_types" type="stringv"> - <item value="text/vcard"/> - <item value="text/x-vcard"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Address Book card viewer"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Component:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Component:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Address Book component"/> - - <oaf_attribute name="evolution:component_alias" type="string" value="contacts"/> - - <oaf_attribute name="evolution:menu_label" type="string" _value="C_ontacts"/> - <oaf_attribute name="evolution:menu_accelerator" type="string" value="*Control*2"/> - <oaf_attribute name="evolution:button_label" type="string" _value="Contacts"/> - <oaf_attribute name="evolution:button_tooltips" type="string" _value="Contacts"/> - <oaf_attribute name="evolution:button_sort_order" type="string" value="-9"/> - <oaf_attribute name="evolution:button_icon" type="string" value="x-office-address-book"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressWidget:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:BonoboControl/address-widget:@VERSION@"/> - <item value="IDL:GNOME/Control:1.0"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Address Book address viewer"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressPopup:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:BonoboControl/address-widget:@VERSION@"/> - <item value="IDL:GNOME/Control:1.0"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Address Book address popup"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_SMime_CertificateManager_ConfigControl:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/ConfigControl:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="evolution2:config_item:title" type="string" - _value="Certificates"/> - - <oaf_attribute name="evolution2:config_item:description" type="string" - _value="Manage your S/MIME certificates here"/> - - <oaf_attribute name="evolution2:config_item:icon_name" type="string" - value="preferences-certificates"/> - - <oaf_attribute name="evolution2:config_item:priority" type="string" value="-6"/> - - <oaf_attribute name="name" type="string" - _value="Evolution S/MIME Certificate Management Control"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Autocompletion_ConfigControl:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Addressbook_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/ConfigControl:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="evolution2:config_item:title" type="string" - _value="Autocompletion"/> - - <oaf_attribute name="evolution2:config_item:description" type="string" - _value="Configure autocomplete here"/> - - <oaf_attribute name="evolution2:config_item:icon_name" type="string" - value="preferences-autocompletion"/> - - <oaf_attribute name="evolution2:config_item:type" type="stringv"> - <item value="contacts"/> - </oaf_attribute> - - <oaf_attribute name="evolution2:config_item:priority" type="string" value="-9"/> - - <oaf_attribute name="name" type="string" - _value="Evolution folder settings configuration control"/> -</oaf_server> - -</oaf_info> diff --git a/addressbook/gui/component/Makefile.am b/addressbook/gui/component/Makefile.am index b7870eddc7..42b22639dc 100644 --- a/addressbook/gui/component/Makefile.am +++ b/addressbook/gui/component/Makefile.am @@ -1,19 +1,18 @@ -if OS_WIN32 -WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libevolution-mail.la -endif - INCLUDES = \ -DG_LOG_DOMAIN=\"evolution-addressbook\" \ -I$(top_srcdir) \ -I$(top_srcdir)/widgets \ -I$(top_srcdir)/shell \ -I$(top_builddir)/shell \ + -I$(top_srcdir)/widgets/menus \ -I$(top_srcdir)/widgets/misc \ -I$(top_srcdir)/addressbook/util \ -I$(top_srcdir)/addressbook/gui/contact-editor \ -I$(top_srcdir)/addressbook/gui/contact-list-editor \ -I$(top_srcdir)/addressbook/gui/widgets \ -I$(top_srcdir)/a11y/addressbook \ + -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \ + -DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \ -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \ -DEVOLUTION_UIDIR=\""$(evolutionuidir)"\" \ @@ -21,32 +20,39 @@ INCLUDES = \ $(LDAP_CFLAGS) \ $(EVOLUTION_ADDRESSBOOK_CFLAGS) -component_LTLIBRARIES = libevolution-addressbook.la - -libevolution_addressbook_la_SOURCES = \ - addressbook-component.c \ - addressbook-component.h \ - addressbook-config.c \ - addressbook-config.h \ - addressbook-migrate.c \ - addressbook-migrate.h \ - autocompletion-config.c \ - autocompletion-config.h \ - addressbook.c \ - addressbook.h \ - addressbook-view.c \ - addressbook-view.h \ - component-factory.c - -# $(top_builddir)/addressbook/printing/libecontactprint.la +module_LTLIBRARIES = libevolution-module-addressbook.la + +libevolution_module_addressbook_la_SOURCES = \ + evolution-module-addressbook.c \ + addressbook-config.c \ + addressbook-config.h \ + autocompletion-config.c \ + autocompletion-config.h \ + eab-composer-util.c \ + eab-composer-util.h \ + e-book-shell-backend.c \ + e-book-shell-backend.h \ + e-book-shell-content.c \ + e-book-shell-content.h \ + e-book-shell-migrate.c \ + e-book-shell-migrate.h \ + e-book-shell-sidebar.c \ + e-book-shell-sidebar.h \ + e-book-shell-view.c \ + e-book-shell-view.h \ + e-book-shell-view-actions.c \ + e-book-shell-view-actions.h \ + e-book-shell-view-private.c \ + e-book-shell-view-private.h if ENABLE_SMIME SMIME_LIB=$(top_builddir)/smime/gui/libevolution-smime.la endif -libevolution_addressbook_la_LIBADD = \ +libevolution_module_addressbook_la_LIBADD = \ $(SMIME_LIB) \ $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/composer/libcomposer.la \ $(top_builddir)/addressbook/printing/libecontactprint.la \ $(top_builddir)/shell/libeshell.la \ $(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \ @@ -58,15 +64,13 @@ libevolution_addressbook_la_LIBADD = \ $(top_builddir)/widgets/table/libetable.la \ $(top_builddir)/widgets/text/libetext.la \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ - $(top_builddir)/widgets/misc/libefilterbar.la \ $(top_builddir)/widgets/menus/libmenus.la \ - $(top_builddir)/a11y/addressbook/libevolution-addressbook-a11y.la \ $(top_builddir)/addressbook/importers/libevolution-addressbook-importers.la \ - $(WIN32_BOOTSTRAP_LIBS) \ $(EVOLUTION_ADDRESSBOOK_LIBS) $(LDAP_LIBS) -libevolution_addressbook_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) +libevolution_module_addressbook_la_LDFLAGS = \ + -module -avoid-version $(NO_UNDEFINED) # GConf schemas @@ -94,23 +98,14 @@ install-data-local: fi endif -server_in_files = GNOME_Evolution_Addressbook.server.in.in -server_DATA = $(server_in_files:.server.in.in=.server) -@EVO_SERVER_RULE@ -@INTLTOOL_SERVER_RULE@ - glade_DATA = \ ldap-config.glade -BUILT_SOURCES = $(server_DATA) -CLEANFILES = $(BUILT_SOURCES) - DISTCLEANFILES = $(schema_DATA) EXTRA_DIST = \ $(glade_DATA) \ $(schema_in_files) \ - $(server_in_files) \ openldap-extract.h dist-hook: diff --git a/addressbook/gui/component/addressbook-component.c b/addressbook/gui/component/addressbook-component.c deleted file mode 100644 index 2c1d5caa9b..0000000000 --- a/addressbook/gui/component/addressbook-component.c +++ /dev/null @@ -1,529 +0,0 @@ -/* - * 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/> - * - * - * Authors: - * Ettore Perazzoli <ettore@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* EPFIXME: Add autocompletion setting. */ - -#include <config.h> - -#include "addressbook-component.h" -#include "addressbook-config.h" -#include "addressbook-migrate.h" -#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 "e-util/e-import.h" -#include "addressbook/gui/widgets/eab-popup.h" -#include "addressbook/gui/widgets/eab-menu.h" -#include "addressbook/gui/widgets/eab-config.h" -#include "addressbook/importers/evolution-addressbook-importers.h" - -#include "misc/e-task-bar.h" -#include "misc/e-info-label.h" - -#include "shell/e-component-view.h" - -#include <string.h> -#include <gtk/gtk.h> -#include <glib/gi18n-lib.h> -#include <gconf/gconf-client.h> -#include <e-util/e-util.h> -#include <libedataserver/e-url.h> - -#ifdef ENABLE_SMIME -#include "smime/gui/component.h" -#endif - -#define LDAP_BASE_URI "ldap://" -#define PERSONAL_RELATIVE_URI "system" - -#define PARENT_TYPE bonobo_object_get_type () -static BonoboObjectClass *parent_class = NULL; - -struct _AddressbookComponentPrivate { - GConfClient *gconf_client; - char *base_directory; - GList *views; -}; - -static void -ensure_sources (AddressbookComponent *component) -{ - ESourceList *source_list; - ESourceGroup *on_this_computer; - ESource *personal_source; - char *base_uri, *base_uri_proto, base_uri_proto_seventh; - const gchar *base_dir; - - personal_source = NULL; - - if (!e_book_get_addressbooks (&source_list, NULL)) { - g_warning ("Could not get addressbook source list from GConf!"); - return; - } - - base_dir = addressbook_component_peek_base_directory (component); - base_uri = g_build_filename (base_dir, "local", NULL); - - base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL); - if (strlen (base_uri_proto) >= 7) { - /* compare only file:// part. If user home dir name changes we do not want to create - one more group */ - base_uri_proto_seventh = base_uri_proto[7]; - base_uri_proto[7] = 0; - } else { - base_uri_proto_seventh = -1; - } - - on_this_computer = e_source_list_ensure_group (source_list, _("On This Computer"), base_uri_proto, TRUE); - e_source_list_ensure_group (source_list, _("On LDAP Servers"), LDAP_BASE_URI, FALSE); - - if (base_uri_proto_seventh != -1) { - base_uri_proto[7] = base_uri_proto_seventh; - } - - if (on_this_computer) { - /* make sure "Personal" shows up as a source under - this group */ - GSList *sources = e_source_group_peek_sources (on_this_computer); - GSList *s; - for (s = sources; s; s = s->next) { - ESource *source = E_SOURCE (s->data); - const gchar *relative_uri; - - relative_uri = e_source_peek_relative_uri (source); - if (relative_uri == NULL) - continue; - if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) { - personal_source = source; - break; - } - } - /* Make sure we have the correct base uri. This can change when user's - homedir name changes */ - if (strcmp (base_uri_proto, e_source_group_peek_base_uri (on_this_computer))) { - e_source_group_set_base_uri (on_this_computer, base_uri_proto); - - /* *sigh* . We shouldn't need this sync call here as set_base_uri - call results in synching to gconf, but that happens in idle loop - and too late to prevent user seeing "Can not Open ... because of invalid uri" error.*/ - e_source_list_sync (source_list,NULL); - } - } - - if (personal_source) { - /* ensure the source name is in current locale, not read from configuration */ - e_source_set_name (personal_source, _("Personal")); - } else { - /* Create the default Person addressbook */ - ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI); - e_source_group_add_source (on_this_computer, source, -1); - g_object_unref (source); - - e_source_set_property (source, "completion", "true"); - - personal_source = source; - } - - g_object_unref (on_this_computer); - g_free (base_uri_proto); - g_free (base_uri); -} - -static void -view_destroyed_cb (gpointer data, GObject *where_the_object_was) -{ - AddressbookComponent *addressbook_component = data; - AddressbookComponentPrivate *priv; - GList *l; - - priv = addressbook_component->priv; - - for (l = priv->views; l; l = l->next) { - AddressbookView *view = l->data; - if (G_OBJECT (view) == where_the_object_was) { - priv->views = g_list_remove (priv->views, view); - break; - } - } -} - -/* Evolution::Component CORBA methods. */ - -static GNOME_Evolution_ComponentView -impl_createView (PortableServer_Servant servant, - GNOME_Evolution_ShellView parent, - CORBA_boolean select_item, - CORBA_Environment *ev) -{ - AddressbookComponent *addressbook_component = ADDRESSBOOK_COMPONENT (bonobo_object_from_servant (servant)); - AddressbookComponentPrivate *priv = addressbook_component->priv; - AddressbookView *view = addressbook_view_new (); - EComponentView *component_view; - - g_object_weak_ref (G_OBJECT (view), view_destroyed_cb, addressbook_component); - priv->views = g_list_append (priv->views, view); - - component_view = e_component_view_new_controls (parent, "contacts", - bonobo_control_new (addressbook_view_peek_sidebar (view)), - addressbook_view_peek_folder_view (view), - bonobo_control_new (addressbook_view_peek_statusbar (view))); - - return BONOBO_OBJREF(component_view); - -} - -static GNOME_Evolution_CreatableItemTypeList * -impl__get_userCreatableItems (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc (); - - list->_length = 3; - list->_maximum = list->_length; - list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length); - - CORBA_sequence_set_release (list, FALSE); - - list->_buffer[0].id = (char *) "contact"; - list->_buffer[0].description = _("New Contact"); - list->_buffer[0].menuDescription = (char *) C_("New", "_Contact"); - list->_buffer[0].tooltip = _("Create a new contact"); - list->_buffer[0].menuShortcut = 'c'; - list->_buffer[0].iconName = (char *) "contact-new"; - list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT; - - list->_buffer[1].id = (char *) "contact_list"; - list->_buffer[1].description = _("New Contact List"); - list->_buffer[1].menuDescription = (char *) C_("New", "Contact _List"); - list->_buffer[1].tooltip = _("Create a new contact list"); - list->_buffer[1].menuShortcut = 'l'; - list->_buffer[1].iconName = (char *) "stock_contact-list"; - list->_buffer[1].type = GNOME_Evolution_CREATABLE_OBJECT; - - list->_buffer[2].id = (char *) "address_book"; - list->_buffer[2].description = _("New Address Book"); - list->_buffer[2].menuDescription = (char *) C_("New", "Address _Book"); - list->_buffer[2].tooltip = _("Create a new address book"); - list->_buffer[2].menuShortcut = '\0'; - list->_buffer[2].iconName = (char *) "address-book-new"; - list->_buffer[2].type = GNOME_Evolution_CREATABLE_FOLDER; - - return list; -} - -static void -book_loaded_cb (EBook *book, EBookStatus status, gpointer data) -{ - EContact *contact; - char *item_type_name = data; - - if (status != E_BOOK_ERROR_OK) { - /* XXX we really need a dialog here, but we don't have - access to the ESource so we can't use - eab_load_error_dialog. fun! */ - return; - } - - contact = e_contact_new (); - - if (!strcmp (item_type_name, "contact")) { - eab_show_contact_editor (book, contact, TRUE, TRUE); - } - else if (!strcmp (item_type_name, "contact_list")) { - eab_show_contact_list_editor (book, contact, TRUE, TRUE); - } - - g_object_unref (book); - g_object_unref (contact); - - g_free (item_type_name); -} - -static void -impl_requestCreateItem (PortableServer_Servant servant, - const CORBA_char *item_type_name, - CORBA_Environment *ev) -{ - EBook *book; - GConfClient *gconf_client; - ESourceList *source_list; - char *uid; - - if (!item_type_name || - (strcmp (item_type_name, "address_book") && - strcmp (item_type_name, "contact") && - strcmp (item_type_name, "contact_list"))) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UnknownType, NULL); - return; - } - - if (!strcmp (item_type_name, "address_book")) { - addressbook_config_create_new_source (NULL); - return; - } - - gconf_client = gconf_client_get_default(); - uid = gconf_client_get_string (gconf_client, "/apps/evolution/addressbook/display/primary_addressbook", - NULL); - g_object_unref (gconf_client); - if (!e_book_get_addressbooks (&source_list, NULL)) { - g_warning ("Could not get addressbook source list from GConf!"); - g_free (uid); - return; - } - if (uid) { - ESource *source = e_source_list_peek_source_by_uid(source_list, uid); - if (source) { - book = e_book_new (source, NULL); - } - else { - book = e_book_new_default_addressbook (NULL); - } - g_free (uid); - } - else { - book = e_book_new_default_addressbook (NULL); - } - - e_book_async_open (book, FALSE, book_loaded_cb, g_strdup (item_type_name)); -} - -static void -impl_handleURI (PortableServer_Servant servant, - const char* uri, - CORBA_Environment *ev) -{ - AddressbookComponent *addressbook_component = ADDRESSBOOK_COMPONENT (bonobo_object_from_servant (servant)); - AddressbookComponentPrivate *priv; - AddressbookView *view = NULL; - - GList *l; - char *src_uid = NULL; - char *contact_uid = NULL; - - priv = addressbook_component->priv; - l = g_list_last (priv->views); - if (!l) - return; - - view = l->data; - - if (!strncmp (uri, "contacts:", 9)) { - EUri *euri = e_uri_new (uri); - const char *p; - char *header, *content; - size_t len, clen; - - p = euri->query; - if (p) { - while (*p) { - len = strcspn (p, "=&"); - - /* If it's malformed, give up. */ - if (p[len] != '=') - break; - - header = (char *) p; - header[len] = '\0'; - p += len + 1; - - clen = strcspn (p, "&"); - - content = g_strndup (p, clen); - - if (!g_ascii_strcasecmp (header, "source-uid")) { - src_uid = g_strdup (content); - } else if (!g_ascii_strcasecmp (header, "contact-uid")) { - contact_uid = g_strdup (content); - } - - g_free (content); - - p += clen; - if (*p == '&') { - p++; - if (!strcmp (p, "amp;")) - p += 4; - } - } - - addressbook_view_edit_contact (view, src_uid, contact_uid); - - g_free (src_uid); - g_free (contact_uid); - } - e_uri_free (euri); - } - -} - -static void -impl_upgradeFromVersion (PortableServer_Servant servant, short major, short minor, short revision, CORBA_Environment *ev) -{ - GError *err = NULL; - - if (!addressbook_migrate (addressbook_component_peek (), major, minor, revision, &err)) { - GNOME_Evolution_Component_UpgradeFailed *failedex; - - failedex = GNOME_Evolution_Component_UpgradeFailed__alloc(); - failedex->what = CORBA_string_dup(_("Failed upgrading Address Book settings or folders.")); - failedex->why = CORBA_string_dup(err->message); - CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex); - } - - if (err) - g_error_free(err); -} - -static CORBA_boolean -impl_requestQuit (PortableServer_Servant servant, CORBA_Environment *ev) -{ - return eab_editor_request_close_all (); -} - -/* GObject methods. */ - -static void -impl_dispose (GObject *object) -{ - AddressbookComponentPrivate *priv = ADDRESSBOOK_COMPONENT (object)->priv; - GList *l; - - if (priv->gconf_client != NULL) { - g_object_unref (priv->gconf_client); - priv->gconf_client = NULL; - } - - for (l = priv->views; l; l = l->next) { - AddressbookView *view = l->data; - g_object_weak_unref (G_OBJECT (view), view_destroyed_cb, ADDRESSBOOK_COMPONENT (object)); - } - g_list_free (priv->views); - priv->views = NULL; - (* G_OBJECT_CLASS (parent_class)->dispose) (object); -} - -static void -impl_finalize (GObject *object) -{ - AddressbookComponentPrivate *priv = ADDRESSBOOK_COMPONENT (object)->priv; - - g_free (priv); - - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - - -/* Initialization. */ - -static void -addressbook_component_class_init (AddressbookComponentClass *class) -{ - POA_GNOME_Evolution_Component__epv *epv = &class->epv; - GObjectClass *object_class = G_OBJECT_CLASS (class); - - bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - - epv->createView = impl_createView; - epv->_get_userCreatableItems = impl__get_userCreatableItems; - epv->requestCreateItem = impl_requestCreateItem; - epv->upgradeFromVersion = impl_upgradeFromVersion; - epv->requestQuit = impl_requestQuit; - epv->handleURI = impl_handleURI; - - object_class->dispose = impl_dispose; - object_class->finalize = impl_finalize; - - parent_class = g_type_class_peek_parent (class); -} - -static void -addressbook_component_init (AddressbookComponent *component) -{ - AddressbookComponentPrivate *priv; - static int first = TRUE; - - priv = g_new0 (AddressbookComponentPrivate, 1); - - /* EPFIXME: Should use a custom one instead? */ - priv->gconf_client = gconf_client_get_default (); - - priv->base_directory = g_build_filename (e_get_user_data_dir (), "addressbook", NULL); - - component->priv = priv; - - ensure_sources (component); - -#ifdef ENABLE_SMIME - smime_component_init (); -#endif - - if (first) { - EImportClass *klass; - - 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()); - - klass = g_type_class_ref(e_import_get_type()); - e_import_class_add_importer(klass, evolution_ldif_importer_peek(), NULL, NULL); - e_import_class_add_importer(klass, evolution_vcard_importer_peek(), NULL, NULL); - e_import_class_add_importer(klass, evolution_csv_outlook_importer_peek(), NULL, NULL); - e_import_class_add_importer(klass, evolution_csv_mozilla_importer_peek(), NULL, NULL); - e_import_class_add_importer(klass, evolution_csv_evolution_importer_peek(), NULL, NULL); - } -} - - -/* Public API. */ - -AddressbookComponent * -addressbook_component_peek (void) -{ - static AddressbookComponent *component = NULL; - - if (component == NULL) - component = g_object_new (addressbook_component_get_type (), NULL); - - return component; -} - -GConfClient* -addressbook_component_peek_gconf_client (AddressbookComponent *component) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_COMPONENT (component), NULL); - - return component->priv->gconf_client; -} - -const char * -addressbook_component_peek_base_directory (AddressbookComponent *component) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_COMPONENT (component), NULL); - - return component->priv->base_directory; -} - -BONOBO_TYPE_FUNC_FULL (AddressbookComponent, GNOME_Evolution_Component, PARENT_TYPE, addressbook_component) diff --git a/addressbook/gui/component/addressbook-component.h b/addressbook/gui/component/addressbook-component.h deleted file mode 100644 index 222ace82d7..0000000000 --- a/addressbook/gui/component/addressbook-component.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * 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/> - * - * - * Authors: - * Ettore Perazzoli <ettore@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _ADDRESSBOOK_COMPONENT_H_ -#define _ADDRESSBOOK_COMPONENT_H_ - -#include <bonobo/bonobo-object.h> - -#include "Evolution.h" -#include "e-activity-handler.h" -#include <libedataserver/e-source-list.h> - -#define ADDRESSBOOK_TYPE_COMPONENT (addressbook_component_get_type ()) -#define ADDRESSBOOK_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ADDRESSBOOK_TYPE_COMPONENT, AddressbookComponent)) -#define ADDRESSBOOK_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ADDRESSBOOK_TYPE_COMPONENT, AddressbookComponentClass)) -#define ADDRESSBOOK_IS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ADDRESSBOOK_TYPE_COMPONENT)) -#define ADDRESSBOOK_IS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), ADDRESSBOOK_TYPE_COMPONENT)) - - -typedef struct _AddressbookComponent AddressbookComponent; -typedef struct _AddressbookComponentPrivate AddressbookComponentPrivate; -typedef struct _AddressbookComponentClass AddressbookComponentClass; - -struct _AddressbookComponent { - BonoboObject parent; - - AddressbookComponentPrivate *priv; -}; - -struct _AddressbookComponentClass { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Component__epv epv; -}; - - -GType addressbook_component_get_type (void); - -AddressbookComponent *addressbook_component_peek (void); - -GConfClient *addressbook_component_peek_gconf_client (AddressbookComponent *component); -const char *addressbook_component_peek_base_directory (AddressbookComponent *component); - -#endif /* _ADDRESSBOOK_COMPONENT_H_ */ diff --git a/addressbook/gui/component/addressbook-config.c b/addressbook/gui/component/addressbook-config.c index ebb2d18b5d..c786a40a13 100644 --- a/addressbook/gui/component/addressbook-config.c +++ b/addressbook/gui/component/addressbook-config.c @@ -34,8 +34,6 @@ #include <gtk/gtk.h> #include <glib/gi18n.h> -#include <bonobo/bonobo-generic-factory.h> - #ifdef G_OS_WIN32 /* Include <windows.h> early and work around DATADIR lossage */ #define DATADIR crap_DATADIR @@ -46,7 +44,6 @@ #include <glade/glade.h> #include "addressbook.h" -#include "addressbook-component.h" #include "addressbook-config.h" #include "e-util/e-error.h" @@ -72,8 +69,6 @@ #define LDAPS_PORT_STRING "636" #define GLADE_FILE_NAME "ldap-config.glade" -#define CONFIG_CONTROL_FACTORY_ID "OAFIID:GNOME_Evolution_Addressbook_ConfigControlFactory:" BASE_VERSION -#define LDAP_CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_LDAPStorage_ConfigControl:" BASE_VERSION GtkWidget* supported_bases_create_table (char *name, char *string1, char *string2, int num1, int num2); diff --git a/addressbook/gui/component/addressbook-config.h b/addressbook/gui/component/addressbook-config.h index e06e98f887..2814e8c839 100644 --- a/addressbook/gui/component/addressbook-config.h +++ b/addressbook/gui/component/addressbook-config.h @@ -24,7 +24,8 @@ #ifndef __ADDRESSBOOK_CONFIG_H__ #define __ADDRESSBOOK_CONFIG_H__ -#include "evolution-config-control.h" +#include <gtk/gtk.h> +#include <libedataserver/e-source.h> typedef enum { ADDRESSBOOK_LDAP_AUTH_NONE, diff --git a/addressbook/gui/component/addressbook-view.c b/addressbook/gui/component/addressbook-view.c deleted file mode 100644 index e6b99c6405..0000000000 --- a/addressbook/gui/component/addressbook-view.c +++ /dev/null @@ -1,1534 +0,0 @@ -/* - * 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/> - * - * - * Authors: - * Chris Toshok <toshok@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <gtk/gtk.h> -#include <glib/gi18n.h> -#include <gdk/gdkkeysyms.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-ui-util.h> -#include <bonobo/bonobo-exception.h> -#include <e-util/e-util.h> -#include <libedataserverui/e-source-selector.h> -#include <libedataserverui/e-passwords.h> - -#include "e-util/e-error.h" -#include "e-util/e-request.h" -#include "misc/e-task-bar.h" -#include "misc/e-info-label.h" - -#include "e-util/e-icon-factory.h" -#include "e-util/e-util-private.h" -#include "shell/e-user-creatable-items-handler.h" - -#include "evolution-shell-component-utils.h" -#include "e-activity-handler.h" -#include "e-contact-editor.h" -#include "addressbook-config.h" -#include "addressbook.h" -#include "addressbook-view.h" -#include "addressbook-component.h" -#include "addressbook/gui/widgets/e-addressbook-view.h" -#include "addressbook/gui/widgets/eab-gui-util.h" -#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; - -#define d(x) - -struct _AddressbookViewPrivate { - GtkWidget *notebook; - BonoboControl *folder_view_control; - - GtkWidget *statusbar_widget; - EActivityHandler *activity_handler; - - GtkWidget *info_widget; - GtkWidget *sidebar_widget; - GtkWidget *selector; - - GConfClient *gconf_client; - - GHashTable *uid_to_view; - GHashTable *uid_to_editor; - - EBook *book; - guint activity_id; - ESourceList *source_list; - char *passwd; - EUserCreatableItemsHandler *creatable_items_handler; - - EABMenu *menu; -}; - -enum DndTargetType { - DND_TARGET_TYPE_VCARD_LIST, - DND_TARGET_TYPE_SOURCE_VCARD_LIST -}; -#define VCARD_TYPE "text/x-vcard" -#define SOURCE_VCARD_TYPE "text/x-source-vcard" -static GtkTargetEntry drag_types[] = { - { (gchar *) SOURCE_VCARD_TYPE, 0, DND_TARGET_TYPE_SOURCE_VCARD_LIST }, - { (gchar *) VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD_LIST } -}; -static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]); - -static void set_status_message (EABView *eav, const char *message, AddressbookView *view); -static void search_result (EABView *eav, EBookViewStatus status, AddressbookView *view); - -static void activate_source (AddressbookView *view, ESource *source); - -static void addressbook_view_init (AddressbookView *view); -static void addressbook_view_class_init (AddressbookViewClass *klass); -static void addressbook_view_dispose (GObject *object); - -static ESource *find_first_source (ESourceList *source_list); -static ESource *get_primary_source (AddressbookView *view); - -typedef struct { - GtkWidget *editor; - char *uid; - AddressbookView *view; -} EditorUidClosure; - -static void -editor_weak_notify (gpointer data, GObject *o) -{ - EditorUidClosure *closure = data; - AddressbookViewPrivate *priv = closure->view->priv; - - g_hash_table_remove (priv->uid_to_editor, - closure->uid); -} - -static EABView * -get_current_view (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - - return EAB_VIEW (gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), - gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook)))); -} - -static void -save_all_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - - if (v) - eab_view_save_as (v, TRUE); -} - -static void -save_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_save_as(v, FALSE); -} - -static void -view_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_view(v); -} - -static void -delete_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_delete_selection(v, TRUE); -} - -static void -print_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_print (v, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); -} - -static void -print_preview_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_print (v, GTK_PRINT_OPERATION_ACTION_PREVIEW); -} - -static void -stop_loading_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_stop(v); -} - -static void -cut_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_cut(v); -} - -static void -copy_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_copy(v); -} - -static void -paste_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_paste(v); -} - -static void -select_all_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_select_all (v); -} - -static void -send_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_send (v); -} - -static void -send_contact_to_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_send_to (v); -} - -static void -copy_all_contacts_to_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - - if (v) - eab_view_copy_to_folder (v, TRUE); -} - -static void -copy_contact_to_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_copy_to_folder (v, FALSE); -} - -static void -move_all_contacts_to_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_move_to_folder (v, TRUE); -} - -static void -move_contact_to_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - EABView *v = get_current_view (view); - if (v) - eab_view_move_to_folder (v, FALSE); -} - -static void -forget_passwords_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - e_passwords_forget_passwords(); -} - -static void -new_addressbook_folder (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - addressbook_config_create_new_source (gtk_widget_get_toplevel(priv->notebook)); -} - -static void -new_folder_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - new_addressbook_folder (view); -} - -static void -delete_addressbook_folder (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - ESource *selected_source; - 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 (priv->notebook); - - if (e_error_run (toplevel, "addressbook:ask-delete-addressbook", - e_source_peek_name(selected_source), NULL) != GTK_RESPONSE_YES) - return; - - /* Remove local data */ - book = e_book_new (selected_source, &error); - if (book) { - if (e_book_remove (book, NULL)) { - if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (priv->selector), - selected_source)) - e_source_selector_unselect_source (E_SOURCE_SELECTOR (priv->selector), - selected_source); - - e_source_group_remove_source (e_source_peek_group (selected_source), selected_source); - - e_source_list_sync (priv->source_list, NULL); - } - else { - e_error_run (toplevel, "addressbook:remove-addressbook", NULL); - } - g_object_unref (book); - } - else { - g_warning ("error removing addressbook : %s", error->message); - g_error_free (error); - } -} - -static void -delete_folder_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - if (view) - delete_addressbook_folder (view); - -} - -static void -edit_addressbook_folder (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - ESource *selected_source; - const char *uid; - EditorUidClosure *closure; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector)); - if (!selected_source) - return; - - uid = e_source_peek_uid (selected_source); - - closure = g_hash_table_lookup (priv->uid_to_editor, uid); - if (!closure) { - char *uid_copy = g_strdup (uid); - - closure = g_new (EditorUidClosure, 1); - closure->editor = addressbook_config_edit_source (gtk_widget_get_toplevel(priv->notebook), selected_source); - closure->uid = uid_copy; - closure->view = view; - - g_hash_table_insert (priv->uid_to_editor, - uid_copy, - closure); - - g_object_weak_ref (G_OBJECT (closure->editor), - editor_weak_notify, closure); - } - - gtk_window_present (GTK_WINDOW (closure->editor)); - -} - -static void -edit_folder_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - if (view) - edit_addressbook_folder (view); - -} - -static void -rename_addressbook_folder (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - ESource *source; - const char *old_name; - char *prompt, *new_name; - gboolean done = FALSE; - - source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector)); - old_name = e_source_peek_name(source); - prompt = g_strdup_printf (_("Rename the \"%s\" folder to:"), old_name); - - while (!done) { - new_name = e_request_string (NULL, _("Rename Folder"), prompt, old_name); - if (new_name == NULL || !strcmp (old_name, new_name)) { - done = TRUE; - } else if (strchr(new_name, '/') != NULL) { - e_error_run (NULL, - "addressbook:no-rename-folder", old_name, new_name, _("Folder names cannot contain '/'"), NULL); - done = TRUE; - } else if (e_source_group_peek_source_by_name(e_source_peek_group(source), new_name)) { - e_error_run (NULL, "addressbook:no-rename-folder-exists", old_name, new_name, NULL); - } else { - e_source_set_name (source, new_name); - done = TRUE; - } - } - g_free (new_name); - -} - -static void -rename_folder_cb (BonoboUIComponent *uih, void *user_data, const char *path) -{ - AddressbookView *view = (AddressbookView *) user_data; - if (view) - rename_addressbook_folder (view); -} - -static gboolean -folder_can_delete (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - ESource *source ; - const char *source_uri; - - source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector)); - if(source) { - source_uri = e_source_peek_relative_uri (source); - if (source_uri && !strcmp("system", source_uri)) - return 0; - else - return 1; - } - else - return 0; -} - -static void -set_status_message (EABView *eav, const char *message, AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - EActivityHandler *activity_handler = priv->activity_handler; - - if (!message || !*message) { - if (priv->activity_id != 0) { - e_activity_handler_operation_finished (activity_handler, priv->activity_id); - priv->activity_id = 0; - } - } else if (priv->activity_id == 0) { - char *clientid = g_strdup_printf ("%p", (gpointer) view); - - priv->activity_id = e_activity_handler_operation_started ( - activity_handler, clientid, message, TRUE); - - g_free (clientid); - } else { - e_activity_handler_operation_progressing (activity_handler, priv->activity_id, message, -1.0); - } - -} - -static void -set_folder_bar_message (EABView *eav, const char *message, AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - EABView *current_view = get_current_view (view); - - if (eav == current_view) { - ESource *source = eav->source; - - if (source) { - const char *name = e_source_peek_name (source); - - e_info_label_set_info((EInfoLabel*)priv->info_widget, name, message); - } - } -} - -static void -search_result (EABView *eav, EBookViewStatus status, AddressbookView *view) -{ - eab_search_result_dialog (NULL /* XXX */, status); -} - -static void -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) - - SET_SENSITIVE ("/commands/ContactsSaveAsVCard", eab_view_can_save_as); - SET_SENSITIVE ("/commands/ContactsView", eab_view_can_view); - - /* Print Contact */ - SET_SENSITIVE ("/commands/ContactsPrint", eab_view_can_print); - SET_SENSITIVE ("/commands/ContactsPrintPreview", eab_view_can_print); - - /* Delete Contact */ - SET_SENSITIVE ("/commands/ContactDelete", eab_view_can_delete); - SET_SENSITIVE ("/commands/ContactsCut", eab_view_can_cut); - - SET_SENSITIVE ("/commands/ContactsCopy", eab_view_can_copy); - SET_SENSITIVE ("/commands/ContactsPaste", eab_view_can_paste); - SET_SENSITIVE ("/commands/ContactsSelectAll", eab_view_can_select_all); - SET_SENSITIVE ("/commands/ContactsSendContactToOther", eab_view_can_send); - SET_SENSITIVE ("/commands/ContactsSendMessageToContact", eab_view_can_send_to); - SET_SENSITIVE ("/commands/ContactsMoveToFolder", eab_view_can_move_to_folder); - SET_SENSITIVE ("/commands/ContactsCopyToFolder", eab_view_can_copy_to_folder); - - bonobo_ui_component_set_prop (uic, ("/commands/FolderDelete"), "sensitive", folder_can_delete(view) ? "1" : "0", NULL); - - /* Stop */ - SET_SENSITIVE ("/commands/ContactStop", eab_view_can_stop); -#undef SET_SENSITIVE - } - - g_object_unref (view); -} - -static BonoboUIVerb verbs [] = { - BONOBO_UI_UNSAFE_VERB ("ContactsPrint", print_cb), - BONOBO_UI_UNSAFE_VERB ("ContactsPrintPreview", print_preview_cb), - BONOBO_UI_UNSAFE_VERB ("ContactsSaveAsVCard", save_contact_cb), - BONOBO_UI_UNSAFE_VERB ("ContactsView", view_contact_cb), - - BONOBO_UI_UNSAFE_VERB ("ContactDelete", delete_contact_cb), - BONOBO_UI_UNSAFE_VERB ("ContactStop", stop_loading_cb), - - BONOBO_UI_UNSAFE_VERB ("ContactsCut", cut_contacts_cb), - BONOBO_UI_UNSAFE_VERB ("ContactsCopy", copy_contacts_cb), - BONOBO_UI_UNSAFE_VERB ("ContactsPaste", paste_contacts_cb), - BONOBO_UI_UNSAFE_VERB ("ContactsSelectAll", select_all_contacts_cb), - - BONOBO_UI_UNSAFE_VERB ("ContactsSendContactToOther", send_contact_cb), - BONOBO_UI_UNSAFE_VERB ("ContactsSendMessageToContact", send_contact_to_cb), - BONOBO_UI_UNSAFE_VERB ("ContactsMoveToFolder", move_contact_to_cb), - BONOBO_UI_UNSAFE_VERB ("ContactsCopyToFolder", copy_contact_to_cb), - BONOBO_UI_UNSAFE_VERB ("ContactsForgetPasswords", forget_passwords_cb), - /* ContactsViewPreview is a toggle */ - - BONOBO_UI_UNSAFE_VERB ("FolderCreate", new_folder_cb), - BONOBO_UI_UNSAFE_VERB ("FolderCopy", copy_all_contacts_to_cb), - BONOBO_UI_UNSAFE_VERB ("FolderMove", move_all_contacts_to_cb), - BONOBO_UI_UNSAFE_VERB ("FolderSave", save_all_contacts_cb), - BONOBO_UI_UNSAFE_VERB ("FolderDelete", delete_folder_cb), - BONOBO_UI_UNSAFE_VERB ("FolderRename", rename_folder_cb), - BONOBO_UI_UNSAFE_VERB ("ChangeFolderProperties", edit_folder_cb), - - BONOBO_UI_VERB_END -}; - -static EPixmap pixmaps [] = { - E_PIXMAP ("/commands/ChangeFolderProperties", "document-properties", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/ContactDelete", "edit-delete", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/ContactsCopy", "edit-copy", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/ContactsCut", "edit-cut", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/ContactsPaste", "edit-paste", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/ContactsPrint", "document-print", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/ContactsPrintPreview", "document-print-preview", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/ContactsSaveAsVCard", "document-save-as", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/ContactsSendContactToOther", "mail-forward", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/ContactsSendMessageToContact", "mail-message-new", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/FolderCopy", "edit-copy", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/FolderDelete", "edit-delete", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/FolderMove", "folder-move", GTK_ICON_SIZE_MENU), - E_PIXMAP ("/commands/FolderSave", "document-save-as", GTK_ICON_SIZE_MENU), - - E_PIXMAP ("/Toolbar/ContactsPrint", "document-print", GTK_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/ContactDelete", "edit-delete", GTK_ICON_SIZE_LARGE_TOOLBAR), - - E_PIXMAP_END -}; - -static void -control_activate (BonoboControl *control, - BonoboUIComponent *uic, - AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - Bonobo_UIContainer remote_ui_container; - EABView *v = get_current_view (view); - char *xmlfile; - - remote_ui_container = bonobo_control_get_remote_ui_container (control, NULL); - bonobo_ui_component_set_container (uic, remote_ui_container, NULL); - bonobo_object_release_unref (remote_ui_container, NULL); - - bonobo_ui_component_add_verb_list_with_data ( - uic, verbs, view); - - bonobo_ui_component_freeze (uic, NULL); - - xmlfile = g_build_filename (EVOLUTION_UIDIR, - "evolution-addressbook.xml", - NULL); - bonobo_ui_util_set_ui (uic, PREFIX, - xmlfile, - "evolution-addressbook", NULL); - g_free (xmlfile); - - if (v) - eab_view_setup_menus (v, uic); - - e_pixmaps_update (uic, pixmaps); - - e_user_creatable_items_handler_activate (priv->creatable_items_handler, uic); - - bonobo_ui_component_thaw (uic, NULL); - - if (v) - update_command_state (v, view); -} - -static void -control_activate_cb (BonoboControl *control, - gboolean activate, - AddressbookView *view) -{ - BonoboUIComponent *uic; - EABView *v = get_current_view (view); - - uic = bonobo_control_get_ui_component (control); - g_return_if_fail (uic != NULL); - - 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); - } -} - -static void -gather_uids_foreach (char *key, - gpointer value, - GList **list) -{ - (*list) = g_list_prepend (*list, key); -} - -static void -source_list_changed_cb (ESourceList *source_list, AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - GList *uids, *l; - EABView *v; - - uids = NULL; - g_hash_table_foreach (priv->uid_to_view, (GHFunc)gather_uids_foreach, &uids); - for (l = uids; l; l = l->next) { - char *uid = l->data; - if (e_source_list_peek_source_by_uid (source_list, uid)) { - /* the source still exists, do nothing */ - } - else { - /* the source no longer exists, remove its - view remove it from our hash table. */ - v = g_hash_table_lookup (priv->uid_to_view, - uid); - gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook), - gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), - GTK_WIDGET (v))); - g_hash_table_remove (priv->uid_to_view, uid); - } - } - g_list_free (uids); - - uids = NULL; - g_hash_table_foreach (priv->uid_to_editor, (GHFunc)gather_uids_foreach, &uids); - for (l = uids; l; l = l->next) { - char *uid = l->data; - if (e_source_list_peek_source_by_uid (source_list, uid)) { - /* the source still exists, do nothing */ - } - else { - /* the source no longer exists, remove its - editor remove it from our hash table. */ - EditorUidClosure *closure = g_hash_table_lookup (priv->uid_to_editor, - uid); - g_object_weak_unref (G_OBJECT (closure->editor), - editor_weak_notify, closure); - gtk_widget_destroy (closure->editor); - g_hash_table_remove (priv->uid_to_editor, uid); - } - } - g_list_free (uids); - - /* make sure we've got the current view selected and updated - properly */ - v = get_current_view (view); - if (v) { - eab_view_setup_menus (v, bonobo_control_get_ui_component (priv->folder_view_control)); - update_command_state (v, view); - } -} - -static void -load_uri_for_selection (ESourceSelector *selector, - AddressbookView *view, - gboolean force) -{ - ESource *selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (selector)); - ESource *primary = get_primary_source (view); - - if (selected_source != NULL && - ((primary && (!g_str_equal (e_source_peek_uid (primary),e_source_peek_uid (selected_source) )))||force)) - activate_source (view, selected_source); -} - -static ESource * -find_first_source (ESourceList *source_list) -{ - GSList *groups, *sources, *l, *m; - - groups = e_source_list_peek_groups (source_list); - for (l = groups; l; l = l->next) { - ESourceGroup *group = l->data; - - sources = e_source_group_peek_sources (group); - for (m = sources; m; m = m->next) { - ESource *source = m->data; - - return source; - } - } - - return NULL; -} - -static void -save_primary_selection (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - ESource *source; - - source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector)); - if (!source) - return; - - /* Save the selection for next time we start up */ - gconf_client_set_string (priv->gconf_client, - "/apps/evolution/addressbook/display/primary_addressbook", - e_source_peek_uid (source), NULL); -} - -static ESource * -get_primary_source (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - ESource *source; - char *uid; - - uid = gconf_client_get_string (priv->gconf_client, - "/apps/evolution/addressbook/display/primary_addressbook", - NULL); - if (uid) { - source = e_source_list_peek_source_by_uid (priv->source_list, uid); - g_free (uid); - } else { - /* Try to create a default if there isn't one */ - source = find_first_source (priv->source_list); - } - - return source; -} - -static void -load_primary_selection (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - ESource *source; - - source = get_primary_source (view); - if (source) - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (priv->selector), source); -} - -/* Folder popup menu callbacks */ -typedef struct { - AddressbookView *view; - ESource *selected_source; - GtkWidget *toplevel; -} BookRemovedClosure; - -static void -book_removed (EBook *book, EBookStatus status, gpointer data) -{ - BookRemovedClosure *closure = data; - AddressbookView *view = closure->view; - AddressbookViewPrivate *priv = view->priv; - ESource *source = closure->selected_source; - GtkWidget *toplevel = closure->toplevel; - - g_free (closure); - - g_object_unref (book); - - if (E_BOOK_ERROR_OK == status) { - /* Remove source */ - if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (priv->selector), - source)) - e_source_selector_unselect_source (E_SOURCE_SELECTOR (priv->selector), - source); - - e_source_group_remove_source (e_source_peek_group (source), source); - - e_source_list_sync (priv->source_list, NULL); - } - else { - e_error_run (GTK_WINDOW (toplevel), - "addressbook:remove-addressbook", - NULL); - } -} - -static void -delete_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) -{ - AddressbookView *view = data; - AddressbookViewPrivate *priv = view->priv; - ESource *selected_source; - 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); - - if (e_error_run (toplevel, "addressbook:ask-delete-addressbook", e_source_peek_name(selected_source), NULL) != GTK_RESPONSE_YES) - return; - - /* Remove local data */ - book = e_book_new (selected_source, &error); - if (book) { - BookRemovedClosure *closure = g_new (BookRemovedClosure, 1); - - closure->toplevel = (GtkWidget *)toplevel; - closure->view = view; - closure->selected_source = selected_source; - - if (e_book_async_remove (book, book_removed, closure)) { - e_error_run (toplevel, "addressbook:remove-addressbook", NULL); - g_free (closure); - g_object_unref (book); - } - } -} - -static void -new_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) -{ - addressbook_config_create_new_source (gtk_widget_get_toplevel(ep->target->widget)); -} - -static void -rename_addressbook_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - AddressbookView *view = data; - ESourceSelector *selector; - - selector = E_SOURCE_SELECTOR (view->priv->selector); - e_source_selector_edit_primary_selection (selector); -} - -static void -save_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) -{ - AddressbookView *view = data; - EABView *v = get_current_view (view); - if (v) - eab_view_save_as (v, TRUE); -} - -static void -edit_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) -{ - AddressbookView *view = data; - if (view) - edit_addressbook_folder (view); -} - -/* Callbacks. */ - -static void -primary_source_selection_changed_callback (ESourceSelector *selector, - AddressbookView *view) -{ - load_uri_for_selection (selector, view, FALSE); - save_primary_selection (view); -} - -static EPopupItem abv_source_popups[] = { - { E_POPUP_ITEM, (gchar *) "10.new", (gchar *) N_("_New Address Book"), new_addressbook_cb, NULL, (gchar *) "address-book-new", 0, 0 }, - { E_POPUP_ITEM, (gchar *) "20.saveasvcard", (gchar *) N_("Save As vCard..."), save_addressbook_cb, NULL, (gchar *) "document-save-as", 0, EAB_POPUP_SOURCE_PRIMARY }, - { E_POPUP_ITEM, (gchar *) "25.rename", (gchar *) N_("_Rename..."), rename_addressbook_cb, NULL, NULL, 0, EAB_POPUP_SOURCE_PRIMARY }, - - { E_POPUP_BAR, (gchar *) "30.bar" }, - { E_POPUP_ITEM, (gchar *) "30.delete", (gchar *) N_("_Delete"), delete_addressbook_cb, NULL, (gchar *) "edit-delete", 0, EAB_POPUP_SOURCE_USER|EAB_POPUP_SOURCE_PRIMARY }, - - { E_POPUP_BAR, (gchar *) "99.bar" }, - { E_POPUP_ITEM, (gchar *) "99.properties", (gchar *) N_("_Properties"), edit_addressbook_cb, NULL, (gchar *) "document-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) -{ - EABPopup *ep; - EABPopupTargetSource *t; - GSList *menus = NULL; - int i; - GtkMenu *menu; - - /** @HookPoint-EABPopup:Addressbook Source Selector Context Menu - * @Id: org.gnome.evolution.addressbook.source.popup - * @Class: org.gnome.evolution.addresbook.popup:1.0 - * @Target: EABPopupTargetSource - * - * The context menu on the source selector in the contacts window. - */ - - 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); - - 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()); - - return TRUE; -} - -typedef struct -{ - guint remove_from_source : 1; - guint copy_done : 1; - gint pending_removals; - - EContact *current_contact; - GList *remaining_contacts; - - EBook *source_book; - EBook *target_book; -} -MergeContext; - -static void -destroy_merge_context (MergeContext *merge_context) -{ - if (merge_context->source_book) - g_object_unref (merge_context->source_book); - if (merge_context->target_book) - g_object_unref (merge_context->target_book); - - g_free (merge_context); -} - -static void -removed_contact_cb (EBook *book, EBookStatus status, gpointer closure) -{ - MergeContext *merge_context = closure; - - merge_context->pending_removals--; - - if (merge_context->copy_done && merge_context->pending_removals == 0) { - /* Finished */ - - destroy_merge_context (merge_context); - } -} - -static void -merged_contact_cb (EBook *book, EBookStatus status, const char *id, gpointer closure) -{ - MergeContext *merge_context = closure; - - if (merge_context->remove_from_source && status == E_BOOK_ERROR_OK) { - /* Remove previous contact from source */ - - e_book_async_remove_contact (merge_context->source_book, merge_context->current_contact, - removed_contact_cb, merge_context); - merge_context->pending_removals++; - } - - g_object_unref (merge_context->current_contact); - - if (merge_context->remaining_contacts) { - /* Copy next contact */ - - merge_context->current_contact = merge_context->remaining_contacts->data; - merge_context->remaining_contacts = g_list_delete_link (merge_context->remaining_contacts, - merge_context->remaining_contacts); - eab_merging_book_add_contact (merge_context->target_book, merge_context->current_contact, - merged_contact_cb, merge_context); - } else if (merge_context->pending_removals == 0) { - /* Finished */ - - destroy_merge_context (merge_context); - } else { - /* Finished, but have pending removals */ - - merge_context->copy_done = TRUE; - } -} - -static gboolean -selector_tree_data_dropped (ESourceSelector *selector, - GtkSelectionData *data, - ESource *destination, - GdkDragAction action, - guint info, - AddressbookView *view) -{ - EBook *source_book, *target_book; - MergeContext *merge_context = NULL; - GList *contactlist; - EABView *v; - - target_book = e_book_new (destination, NULL); - if (!target_book) { - g_message (G_STRLOC ":Couldn't create EBook."); - return FALSE; - } - e_book_open (target_book, FALSE, NULL); - - eab_book_and_contact_list_from_string ((char *)data->data, &source_book, &contactlist); - - v = get_current_view (view); - g_object_get (v->model, "book",&source_book, NULL); - - /* Set up merge context */ - - merge_context = g_new0 (MergeContext, 1); - - merge_context->source_book = source_book; - merge_context->target_book = target_book; - - merge_context->current_contact = contactlist->data; - merge_context->remaining_contacts = g_list_delete_link (contactlist, contactlist); - - merge_context->remove_from_source = action == GDK_ACTION_MOVE ? TRUE : FALSE; - - /* Start merge */ - - eab_merging_book_add_contact (target_book, merge_context->current_contact, - merged_contact_cb, merge_context); - - return TRUE; -} - -static void -destroy_callback(gpointer data, GObject *where_object_was) -{ - AddressbookView *view = data; - g_object_unref (view); -} - -GType -addressbook_view_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (AddressbookViewClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) addressbook_view_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EABView), - 0, /* n_preallocs */ - (GInstanceInitFunc) addressbook_view_init, - }; - - type = g_type_register_static (PARENT_TYPE, "AddressbookView", &info, 0); - } - - return type; -} - -static void -addressbook_view_class_init (AddressbookViewClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = addressbook_view_dispose; - - parent_class = g_type_class_peek_parent (klass); -} - -static gboolean -source_selector_key_press_event_callback (GtkWidget *widget, GdkEventKey *event, AddressbookView *view) -{ - if (event->keyval == GDK_Delete) { - delete_addressbook_folder (view); - return TRUE; - } - return FALSE; -} - -static void -addressbook_view_init (AddressbookView *view) -{ - AddressbookViewPrivate *priv; - GtkWidget *selector_scrolled_window; - AtkObject *a11y; - - view->priv = - priv = g_new0 (AddressbookViewPrivate, 1); - - priv->gconf_client = addressbook_component_peek_gconf_client (addressbook_component_peek ()); - - priv->uid_to_view = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_object_unref); - priv->uid_to_editor = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_free); - - priv->notebook = gtk_notebook_new (); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE); - gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE); - - g_object_weak_ref (G_OBJECT (priv->notebook), destroy_callback, view); - - /* Create the control. */ - priv->folder_view_control = bonobo_control_new (priv->notebook); - - gtk_widget_show (priv->notebook); - - e_book_get_addressbooks (&priv->source_list, NULL); - g_signal_connect (priv->source_list, - "changed", - 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); - - priv->activity_handler = e_activity_handler_new (); - - priv->statusbar_widget = e_task_bar_new (); - gtk_widget_show (priv->statusbar_widget); - - e_activity_handler_attach_task_bar (priv->activity_handler, - E_TASK_BAR (priv->statusbar_widget)); - - priv->info_widget = e_info_label_new("x-office-address-book"); - e_info_label_set_info((EInfoLabel*)priv->info_widget, _("Contacts"), ""); - gtk_widget_show (priv->info_widget); - - priv->selector = e_source_selector_new (priv->source_list); - - g_signal_connect ( - priv->selector, "data-dropped", - G_CALLBACK (selector_tree_data_dropped), 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); - - selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (selector_scrolled_window), GTK_SHADOW_IN); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (selector_scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (selector_scrolled_window), priv->selector); - gtk_widget_show (selector_scrolled_window); - - priv->sidebar_widget = gtk_vbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX (priv->sidebar_widget), priv->info_widget, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX (priv->sidebar_widget), selector_scrolled_window, TRUE, TRUE, 0); - gtk_widget_show (priv->sidebar_widget); - - g_signal_connect_object (priv->selector, "primary_selection_changed", - G_CALLBACK (primary_source_selection_changed_callback), - G_OBJECT (view), 0); - g_signal_connect_after (priv->selector, "key_press_event", - G_CALLBACK (source_selector_key_press_event_callback), - G_OBJECT (view)); - g_signal_connect_object (priv->selector, "popup_event", - G_CALLBACK (popup_event_callback), - G_OBJECT (view), 0); - - load_primary_selection (view); - load_uri_for_selection (E_SOURCE_SELECTOR (priv->selector), view, TRUE); -} - -static void -destroy_editor (char *key, - gpointer value, - gpointer nada) -{ - EditorUidClosure *closure = value; - - g_object_weak_unref (G_OBJECT (closure->editor), - editor_weak_notify, closure); - - gtk_widget_destroy (GTK_WIDGET (closure->editor)); -} - -static void -addressbook_view_dispose (GObject *object) -{ - AddressbookView *view = ADDRESSBOOK_VIEW (object); - AddressbookViewPrivate *priv = view->priv; - - if (view->priv) { - if (priv->book) - g_object_unref (priv->book); - - g_free(priv->passwd); - - if (priv->source_list) - g_object_unref (priv->source_list); - - if (priv->uid_to_view) - g_hash_table_destroy (priv->uid_to_view); - - if (priv->uid_to_editor) { - g_hash_table_foreach (priv->uid_to_editor, (GHFunc)destroy_editor, NULL); - g_hash_table_destroy (priv->uid_to_editor); - } - - if (priv->creatable_items_handler) - g_object_unref (priv->creatable_items_handler); - - if (priv->menu) - g_object_unref (priv->menu); - - g_free (view->priv); - view->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - (* G_OBJECT_CLASS (parent_class)->dispose) (object); -} - -typedef struct { - EABView *view; - ESource *source; -} BookOpenData; - -static void -book_open_cb (EBook *book, EBookStatus status, gpointer closure) -{ - BookOpenData *data = closure; - EABView *view = data->view; - ESource *source = data->source; - - g_free (data); - - /* we always set the "source" property on the EABView, since - we use it to reload a previously failed book. */ - g_object_set(view, - "source", source, - NULL); - - if (status == E_BOOK_ERROR_OK) { - g_object_set(view, - "book", book, - NULL); - - if (view->model) - eab_model_force_folder_bar_message (view->model); - } - else if (status != E_BOOK_ERROR_CANCELLED) { - eab_load_error_dialog (NULL /* XXX */, source, status); - } - - - g_object_unref (source); -} - -static void -activate_source (AddressbookView *view, - ESource *source) -{ - AddressbookViewPrivate *priv = view->priv; - const char *uid; - GtkWidget *uid_view; - EBook *book; - BookOpenData *data; - - uid = e_source_peek_uid (source); - uid_view = g_hash_table_lookup (priv->uid_to_view, uid); - - if (uid_view) { - /* there is a view for this uid. make - sure that the view actually - contains an EBook (if it doesn't - contain an EBook a previous load - failed. try to load it again */ - g_object_get (uid_view, - "book", &book, - NULL); - - if (book) { - g_object_unref (book); - } - else { - g_object_get (uid_view, - "source", &source, - NULL); - - /* source can be NULL here, if - a previous load hasn't - actually made it to - book_open_cb yet. */ - if (source) { - book = e_book_new (source, NULL); - - if (!book) { - g_object_unref (source); - } - else { - data = g_new (BookOpenData, 1); - data->view = g_object_ref (uid_view); - data->source = source; /* transfer the ref we get back from g_object_get */ - - addressbook_load (book, book_open_cb, data); - } - } - } - } - else { - /* we don't have a view for this uid already - set up. */ - GtkWidget *label = gtk_label_new (uid); - GError *error = NULL; - - uid_view = eab_view_new (); - - gtk_widget_show (uid_view); - gtk_widget_show (label); - - g_object_set (uid_view, "type", EAB_VIEW_TABLE, NULL); - - gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), - uid_view, - label); - - g_hash_table_insert (priv->uid_to_view, g_strdup (uid), uid_view); - - g_signal_connect (uid_view, "status_message", - G_CALLBACK(set_status_message), view); - - g_signal_connect (uid_view, "search_result", - G_CALLBACK(search_result), view); - - g_signal_connect (uid_view, "folder_bar_message", - G_CALLBACK(set_folder_bar_message), view); - - g_signal_connect (uid_view, "command_state_change", - G_CALLBACK(update_command_state), view); - - book = e_book_new (source, &error); - - if (book) { - data = g_new (BookOpenData, 1); - data->view = g_object_ref (uid_view); - data->source = g_object_ref (source); - - addressbook_load (book, book_open_cb, data); - } - else { - g_warning ("error loading addressbook : %s", error->message); - g_error_free (error); - } - } - - gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), - gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), - uid_view)); - - if (EAB_VIEW (uid_view)->model) - eab_model_force_folder_bar_message (EAB_VIEW (uid_view)->model); - - /* change menus/toolbars to reflect the new view, assuming we are already displayed */ - if (bonobo_ui_component_get_container (bonobo_control_get_ui_component (priv->folder_view_control)) != CORBA_OBJECT_NIL) { - eab_view_setup_menus (EAB_VIEW (uid_view), bonobo_control_get_ui_component (priv->folder_view_control)); - update_command_state (EAB_VIEW (uid_view), view); - } -} - -AddressbookView * -addressbook_view_new (void) -{ - return g_object_new (ADDRESSBOOK_TYPE_VIEW, NULL); -} - -EActivityHandler* -addressbook_view_peek_activity_handler (AddressbookView *view) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL); - - return view->priv->activity_handler; -} - -GtkWidget* -addressbook_view_peek_info_label (AddressbookView *view) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL); - - return view->priv->info_widget; -} - -GtkWidget* -addressbook_view_peek_sidebar (AddressbookView *view) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL); - - return view->priv->sidebar_widget; -} - -GtkWidget* -addressbook_view_peek_statusbar (AddressbookView *view) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL); - - return view->priv->statusbar_widget; -} - -BonoboControl* -addressbook_view_peek_folder_view (AddressbookView *view) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL); - - return view->priv->folder_view_control; -} - -void -addressbook_view_edit_contact (AddressbookView* view, - const char* source_uid, - const char* contact_uid) -{ - AddressbookViewPrivate *priv = view->priv; - - ESource* source = NULL; - EContact* contact = NULL; - EBook* book = NULL; - - if (!source_uid || !contact_uid) - return; - - source = e_source_list_peek_source_by_uid (priv->source_list, source_uid); - if (!source) - return; - - /* FIXME: Can I unref this book? */ - book = e_book_new (source, NULL); - if (!book) - return; - - if (!e_book_open (book, TRUE, NULL)) { - g_object_unref (book); - return; - } - - e_book_get_contact (book, contact_uid, &contact, NULL); - - if (!contact) { - g_object_unref (book); - return; - } - eab_show_contact_editor (book, contact, FALSE, FALSE); - g_object_unref (contact); - g_object_unref (book); -} diff --git a/addressbook/gui/component/addressbook-view.h b/addressbook/gui/component/addressbook-view.h deleted file mode 100644 index 08bbbb3e99..0000000000 --- a/addressbook/gui/component/addressbook-view.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * 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/> - * - * - * Authors: - * Chris Toshok <toshok@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _ADDRESSBOOK_VIEW_H_ -#define _ADDRESSBOOK_VIEW_H_ - -#include <bonobo/bonobo-control.h> - -#define ADDRESSBOOK_TYPE_VIEW (addressbook_view_get_type ()) -#define ADDRESSBOOK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ADDRESSBOOK_TYPE_VIEW, AddressbookView)) -#define ADDRESSBOOK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ADDRESSBOOK_TYPE_VIEW, AddressbookViewClass)) -#define ADDRESSBOOK_IS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ADDRESSBOOK_TYPE_VIEW)) -#define ADDRESSBOOK_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), ADDRESSBOOK_TYPE_VIEW)) - - -typedef struct _AddressbookView AddressbookView; -typedef struct _AddressbookViewPrivate AddressbookViewPrivate; -typedef struct _AddressbookViewClass AddressbookViewClass; - -struct _AddressbookView { - GObject parent; - - AddressbookViewPrivate *priv; -}; - -struct _AddressbookViewClass { - GObjectClass parent_class; -}; - - -GType addressbook_view_get_type (void); - -AddressbookView *addressbook_view_new (void); - -EActivityHandler *addressbook_view_peek_activity_handler (AddressbookView *view); -GtkWidget *addressbook_view_peek_info_label (AddressbookView *view); -GtkWidget *addressbook_view_peek_sidebar (AddressbookView *view); -GtkWidget *addressbook_view_peek_statusbar (AddressbookView *view); -BonoboControl *addressbook_view_peek_folder_view (AddressbookView *view); - -void addressbook_view_edit_contact (AddressbookView* view, - const char* source_id, - const char* contact_id); - -#endif /* _ADDRESSBOOK_VIEW_H_ */ diff --git a/addressbook/gui/component/addressbook.c b/addressbook/gui/component/addressbook.c deleted file mode 100644 index f36012ab94..0000000000 --- a/addressbook/gui/component/addressbook.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * 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/> - * - * - * Authors: - * Chris Lahey <clahey@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include <config.h> - -#include <string.h> - -#include <gtk/gtk.h> -#include <glib/gi18n.h> -#include <libebook/e-book.h> -#include <libedataserver/e-url.h> -#include <libedataserverui/e-passwords.h> - -#include "e-util/e-error.h" -#include "addressbook.h" - -#define d(x) - -static void addressbook_authenticate (EBook *book, gboolean previous_failure, - ESource *source, EBookCallback cb, gpointer closure); -static void auth_required_cb (EBook *book, gpointer data); - -typedef struct { - EBookCallback cb; - ESource *source; - gpointer closure; - guint cancelled : 1; -} LoadSourceData; - -static void -free_load_source_data (LoadSourceData *data) -{ - if (data->source) - g_object_unref (data->source); - g_free (data); -} - -/*this function removes of anything present after semicolon -in uri*/ - -static gchar* -remove_parameters_from_uri (const gchar *uri) -{ - char *euri_str; - EUri *euri; - - euri = e_uri_new (uri); - euri_str = e_uri_to_string (euri, FALSE); - e_uri_free (euri); - return euri_str; -} - -static void -load_source_auth_cb (EBook *book, EBookStatus status, gpointer closure) -{ - LoadSourceData *data = closure; - gboolean was_in = g_object_get_data (G_OBJECT (book), "authenticated") != NULL; - - g_object_set_data (G_OBJECT (book), "authenticated", NULL); - - if (data->cancelled) { - free_load_source_data (data); - return; - } - - if (status != E_BOOK_ERROR_OK) { - - /* 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, - "%s", _("Accessing LDAP Server anonymously")); - g_signal_connect (dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL); - gtk_widget_show (dialog); - status = E_BOOK_ERROR_OK; - - goto done; - } - } else if (status == E_BOOK_ERROR_INVALID_SERVER_VERSION) { - e_error_run (NULL, "addressbook:server-version", NULL); - status = E_BOOK_ERROR_OK; - goto done; - } else if (status == E_BOOK_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD) { - goto done; - } else { - if (status == E_BOOK_ERROR_AUTHENTICATION_FAILED) { - const gchar *uri = e_book_get_uri (book); - gchar *stripped_uri = remove_parameters_from_uri (uri); - const gchar *auth_domain = e_source_get_property (data->source, "auth-domain"); - const gchar *component_name; - - component_name = auth_domain ? auth_domain : "Addressbook"; - - e_passwords_forget_password (component_name, stripped_uri); - - g_free (stripped_uri); - } else if (was_in) { - /* We already tried to authenticate to the server, and it failed with - other reason than with E_BOOK_ERROR_AUTHENTICATION_FAILED, thus stop - poking with the server and report error to the user. */ - goto done; - } - - g_object_set_data (G_OBJECT (book), "authenticated", GINT_TO_POINTER (1)); - addressbook_authenticate (book, TRUE, data->source, load_source_auth_cb, closure); - return; - } - } - -done: - if (data->cb) - data->cb (book, status, data->closure); - - free_load_source_data (data); -} - -static gboolean -get_remember_password (ESource *source) -{ - const gchar *value; - - value = e_source_get_property (source, "remember_password"); - if (value && !g_ascii_strcasecmp (value, "true")) - return TRUE; - - return FALSE; -} - -static void -set_remember_password (ESource *source, gboolean value) -{ - e_source_set_property (source, "remember_password", - value ? "true" : "false"); -} - -static void -addressbook_authenticate (EBook *book, gboolean previous_failure, ESource *source, - EBookCallback cb, gpointer closure) -{ - const char *password = NULL; - char *pass_dup = NULL; - const gchar *auth; - const gchar *user; - gchar *uri = remove_parameters_from_uri(e_book_get_uri (book)); - const gchar *auth_domain = e_source_get_property (source, "auth-domain"); - const gchar *component_name; - - component_name = auth_domain ? auth_domain : "Addressbook"; - - password = e_passwords_get_password (component_name, uri); - - auth = e_source_get_property (source, "auth"); - - if (auth && !strcmp ("ldap/simple-binddn", auth)) { - user = e_source_get_property (source, "binddn"); - } - else if (auth && !strcmp ("plain/password", auth)) { - user = e_source_get_property (source, "user"); - if (!user) { - user = e_source_get_property (source, "username"); - } - } - else { - user = e_source_get_property (source, "email_addr"); - } - if (!user) - user = ""; - - if (!password) { - char *prompt; - char *password_prompt; - gboolean remember; - const gchar *failed_auth; - guint32 flags = E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET|E_PASSWORDS_ONLINE; - - if (previous_failure) { - failed_auth = _("Failed to authenticate.\n"); - flags |= E_PASSWORDS_REPROMPT; - } - else { - 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); - - remember = get_remember_password (source); - pass_dup = e_passwords_ask_password ( - _("Enter password"), component_name, - uri, prompt, flags, &remember, NULL); - if (remember != get_remember_password (source)) - set_remember_password (source, remember); - - g_free (prompt); - } - - if (password || pass_dup) { - e_book_async_authenticate_user (book, user, password ? password : pass_dup, - e_source_get_property (source, "auth"), - cb, closure); - g_free (pass_dup); - } - else { - /* they hit cancel */ - 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) -{ - LoadSourceData *load_source_data = closure; - - if (load_source_data->cancelled) { - free_load_source_data (load_source_data); - return; - } - - if (status == E_BOOK_ERROR_OK && book != NULL) { - const gchar *auth; - - auth = e_source_get_property (load_source_data->source, "auth"); - if (auth && strcmp (auth, "none")) { - g_signal_connect (book, "auth_required", G_CALLBACK(auth_required_cb), NULL); - - if (e_book_is_online (book)) { - 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); -} - -guint -addressbook_load (EBook *book, - EBookCallback cb, gpointer closure) -{ - LoadSourceData *load_source_data = g_new0 (LoadSourceData, 1); - - load_source_data->cb = cb; - load_source_data->closure = closure; - load_source_data->source = g_object_ref (g_object_ref (e_book_get_source (book))); - load_source_data->cancelled = FALSE; - - e_book_async_open (book, FALSE, load_source_cb, load_source_data); - - return GPOINTER_TO_UINT (load_source_data); -} - -void -addressbook_load_cancel (guint id) -{ - LoadSourceData *load_source_data = GUINT_TO_POINTER (id); - - load_source_data->cancelled = TRUE; -} - -static void -default_book_cb (EBook *book, EBookStatus status, gpointer closure) -{ - LoadSourceData *load_source_data = closure; - - if (status == E_BOOK_ERROR_OK) - load_source_data->source = g_object_ref (e_book_get_source (book)); - - load_source_cb (book, status, closure); -} - -void -addressbook_load_default_book (EBookCallback cb, gpointer closure) -{ - LoadSourceData *load_source_data = g_new (LoadSourceData, 1); - EBook *book; - - load_source_data->cb = cb; - load_source_data->source = NULL; - load_source_data->closure = closure; - load_source_data->cancelled = FALSE; - - book = e_book_new_default_addressbook (NULL); - if (!book) - load_source_cb (NULL, E_BOOK_ERROR_OTHER_ERROR, load_source_data); /* XXX we should just use a GError and it's error code here */ - else - e_book_async_open (book, FALSE, default_book_cb, load_source_data); -} diff --git a/addressbook/gui/component/autocompletion-config.c b/addressbook/gui/component/autocompletion-config.c index f45f2228e1..548c0cbd7e 100644 --- a/addressbook/gui/component/autocompletion-config.c +++ b/addressbook/gui/component/autocompletion-config.c @@ -22,45 +22,31 @@ * */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - #include "autocompletion-config.h" -#include "Evolution.h" - -#include <bonobo/bonobo-exception.h> - +#include <gtk/gtk.h> +#include <glib/gi18n.h> #include <libedataserver/e-source-list.h> #include <libedataserverui/e-source-selector.h> #include <libedataserverui/e-name-selector-entry.h> -#include <gtk/gtk.h> -#include <glib/gi18n.h> - - -typedef struct { - EvolutionConfigControl *config_control; - GtkWidget *control_widget; - - ESourceList *source_list; - GConfClient *gconf; -} AutocompletionConfig; +#include "widgets/misc/e-preferences-window.h" static void -source_selection_changed (ESourceSelector *selector, - AutocompletionConfig *ac) +source_selection_changed_cb (ESourceSelector *source_selector) { + ESourceList *source_list; GSList *selection; GSList *l; GSList *groups; + source_list = e_source_selector_get_source_list (source_selector); + /* first we clear all the completion flags from all sources */ - for (groups = e_source_list_peek_groups (ac->source_list); groups; groups = groups->next) { + for (groups = e_source_list_peek_groups (source_list); groups; groups = groups->next) { ESourceGroup *group = E_SOURCE_GROUP (groups->data); GSList *sources; + for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) { ESource *source = E_SOURCE (sources->data); @@ -70,149 +56,82 @@ source_selection_changed (ESourceSelector *selector, /* then we loop over the selector's selection, setting the property on those sources */ - selection = e_source_selector_get_selection (selector); + selection = e_source_selector_get_selection (source_selector); for (l = selection; l; l = l->next) { - e_source_set_property (E_SOURCE (l->data), "completion", "true"); + ESource *source = E_SOURCE (l->data); + + e_source_set_property (source, "completion", "true"); } e_source_selector_free_selection (selection); - e_source_list_sync (ac->source_list, NULL); /* XXX we should pop up a dialog if this fails */ -} - -static void -config_control_destroy_notify (void *data, - GObject *where_the_config_control_was) -{ - AutocompletionConfig *ac = (AutocompletionConfig *) data; - - g_object_unref (ac->source_list); - g_object_unref (ac->gconf); - - g_free (ac); + /* XXX we should pop up a dialog if this fails */ + e_source_list_sync (source_list, NULL); } static void -initialize_selection (AutocompletionConfig *ac) +initialize_selection (ESourceSelector *source_selector) { + ESourceList *source_list; GSList *groups; - for (groups = e_source_list_peek_groups (ac->source_list); groups; groups = groups->next) { + source_list = e_source_selector_get_source_list (source_selector); + + for (groups = e_source_list_peek_groups (source_list); groups; groups = groups->next) { ESourceGroup *group = E_SOURCE_GROUP (groups->data); GSList *sources; + for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) { ESource *source = E_SOURCE (sources->data); - const char *completion = e_source_get_property (source, "completion"); + const char *completion; + + completion = e_source_get_property (source, "completion"); if (completion && !g_ascii_strcasecmp (completion, "true")) - e_source_selector_select_source (E_SOURCE_SELECTOR (ac->control_widget), - source); + e_source_selector_select_source (source_selector, source); } } } -static GtkWidget * -add_section (GtkWidget *vbox, const gchar *caption, gboolean expand) -{ - GtkWidget *label, *hbox, *itembox; - gchar *txt; - - g_return_val_if_fail (vbox != NULL, NULL); - g_return_val_if_fail (caption != NULL, NULL); - - txt = g_strconcat ("<b>", caption, "</b>", NULL); - - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_label_set_markup (GTK_LABEL (label), txt); - - g_free (txt); - - /* bold caption of the section */ - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - - hbox = gtk_hbox_new (FALSE, 12); - - /* space on the left for the items in the section */ - gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (""), FALSE, FALSE, 0); - - /* itembox, here will all section items go */ - itembox = gtk_vbox_new (FALSE, 2); - gtk_box_pack_start (GTK_BOX (hbox), itembox, TRUE, TRUE, 0); - - gtk_box_pack_start (GTK_BOX (vbox), hbox, expand, expand, 0); - - return itembox; -} - -static void -show_address_check_toggled_cb (GtkToggleButton *check, AutocompletionConfig *ac) +void +autocompletion_config_init (EShell *shell) { - g_return_if_fail (check != NULL); - g_return_if_fail (ac != NULL); - g_return_if_fail (ac->gconf != NULL); - - gconf_client_set_bool (ac->gconf, FORCE_SHOW_ADDRESS, gtk_toggle_button_get_active (check), NULL); -} - -EvolutionConfigControl* -autocompletion_config_control_new (void) -{ - AutocompletionConfig *ac; - CORBA_Environment ev; - GtkWidget *scrolledwin, *vbox, *itembox, *w; - - ac = g_new0 (AutocompletionConfig, 1); - - CORBA_exception_init (&ev); - - ac->gconf = gconf_client_get_default (); - - vbox = gtk_vbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); - - itembox = add_section (vbox, _("Autocompletion"), FALSE); + ESourceList *source_list; + GtkWidget *scrolled_window; + GtkWidget *source_selector; + GtkWidget *preferences_window; - w = gtk_check_button_new_with_mnemonic (_("Always _show address of the autocompleted contact")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), gconf_client_get_bool (ac->gconf, FORCE_SHOW_ADDRESS, NULL)); - g_signal_connect (w, "toggled", (GCallback)show_address_check_toggled_cb, ac); - gtk_box_pack_start (GTK_BOX (itembox), w, FALSE, FALSE, 0); + g_return_if_fail (E_IS_SHELL (shell)); - itembox = add_section (vbox, _("Look up in address books"), TRUE); + source_list = e_source_list_new_for_gconf_default ( + "/apps/evolution/addressbook/sources"); - ac->source_list = e_source_list_new_for_gconf_default ("/apps/evolution/addressbook/sources"); /* XXX should we watch for the source list to change and update it in the control? what about our local changes? */ /* g_signal_connect (ac->source_list, "changed", G_CALLBACK (source_list_changed), ac); */ - scrolledwin = gtk_scrolled_window_new (NULL, NULL); - - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwin), - GTK_SHADOW_IN); - - ac->control_widget = e_source_selector_new (ac->source_list); - - gtk_container_add (GTK_CONTAINER (scrolledwin), ac->control_widget); - - initialize_selection (ac); - - gtk_widget_show (ac->control_widget); - gtk_widget_show (scrolledwin); - - gtk_widget_show_all (vbox); - gtk_box_pack_start (GTK_BOX (itembox), scrolledwin, TRUE, TRUE, 0); - - ac->config_control = evolution_config_control_new (vbox); - - g_signal_connect (ac->control_widget, "selection_changed", - G_CALLBACK (source_selection_changed), ac); - - g_object_weak_ref (G_OBJECT (ac->config_control), config_control_destroy_notify, ac); - - CORBA_exception_free (&ev); - - return ac->config_control; + scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (scrolled_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN); + gtk_widget_show (scrolled_window); + + source_selector = e_source_selector_new (source_list); + g_signal_connect ( + source_selector, "selection_changed", + G_CALLBACK (source_selection_changed_cb), NULL); + gtk_container_add (GTK_CONTAINER (scrolled_window), source_selector); + gtk_widget_show (source_selector); + + initialize_selection (E_SOURCE_SELECTOR (source_selector)); + + preferences_window = e_shell_get_preferences_window (shell); + + e_preferences_window_add_page ( + E_PREFERENCES_WINDOW (preferences_window), + "autocompletion", + "preferences-autocompletion", + _("Autocompletion"), + scrolled_window, + 200); } - diff --git a/addressbook/gui/component/autocompletion-config.h b/addressbook/gui/component/autocompletion-config.h index 0690604bc7..5769bdce9d 100644 --- a/addressbook/gui/component/autocompletion-config.h +++ b/addressbook/gui/component/autocompletion-config.h @@ -25,8 +25,13 @@ #ifndef _AUTOCOMPLETION_CONFIG_H #define _AUTOCOMPLETION_CONFIG_H -#include "evolution-config-control.h" +#include <glib.h> +#include <shell/e-shell.h> -EvolutionConfigControl* autocompletion_config_control_new (void); +G_BEGIN_DECLS + +void autocompletion_config_init (EShell *shell); + +G_END_DECLS #endif /* _AUTOCOMPLETION_CONFIG_H */ diff --git a/addressbook/gui/component/component-factory.c b/addressbook/gui/component/component-factory.c deleted file mode 100644 index 4d02cc3e6b..0000000000 --- a/addressbook/gui/component/component-factory.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * component-factory.c - Factory for Evolution's Addressbook component. - * - * 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/> - * - * - * Authors: - * Ettore Perazzoli <ettore@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include <config.h> - -#include <string.h> -#include "addressbook.h" -#include "addressbook-component.h" -#include "addressbook-config.h" -#include "addressbook-view.h" -#include "autocompletion-config.h" -#include "eab-popup-control.h" -#ifdef ENABLE_SMIME -#include "smime/gui/certificate-manager.h" -#endif -#include <bonobo/bonobo-shlib-factory.h> - - -#define FACTORY_ID "OAFIID:GNOME_Evolution_Addressbook_Factory:" BASE_VERSION - -#define COMPONENT_ID "OAFIID:GNOME_Evolution_Addressbook_Component:" BASE_VERSION -#define ADDRESS_POPUP_ID "OAFIID:GNOME_Evolution_Addressbook_AddressPopup:" 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 - -#define d(x) - - -static BonoboObject * -factory (BonoboGenericFactory *factory, - const char *component_id, - void *closure) -{ - d(printf ("asked to activate component_id `%s'\n", component_id)); - - if (strcmp (component_id, COMPONENT_ID) == 0) { - BonoboObject *object = BONOBO_OBJECT (addressbook_component_peek ()); - bonobo_object_ref (object); - return object; - } - if (strcmp (component_id, ADDRESS_POPUP_ID) == 0) - return BONOBO_OBJECT (eab_popup_control_new ()); - if (strcmp (component_id, COMPLETION_CONFIG_CONTROL_ID) == 0) - return BONOBO_OBJECT (autocompletion_config_control_new ()); -#ifdef ENABLE_SMIME - if (strcmp (component_id, CERTIFICATE_MANAGER_CONFIG_CONTROL_ID) == 0) - return BONOBO_OBJECT (certificate_manager_config_control_new ()); -#endif - - g_warning (FACTORY_ID ": Don't know what to do with %s", component_id); - return NULL; -} - -BONOBO_ACTIVATION_SHLIB_FACTORY (FACTORY_ID, "Evolution Addressbook component factory", factory, NULL) diff --git a/addressbook/gui/component/e-book-shell-backend.c b/addressbook/gui/component/e-book-shell-backend.c new file mode 100644 index 0000000000..68af7ed03b --- /dev/null +++ b/addressbook/gui/component/e-book-shell-backend.c @@ -0,0 +1,576 @@ +/* + * 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) + * + */ + +#include "e-book-shell-backend.h" + +#include <config.h> + +#include <string.h> +#include <glib/gi18n.h> +#include <libebook/e-book.h> +#include <libedataserver/e-url.h> +#include <libedataserver/e-source.h> +#include <libedataserver/e-source-group.h> + +#include "shell/e-shell.h" +#include "shell/e-shell-window.h" + +#include "e-util/e-import.h" +#include "addressbook/gui/widgets/eab-gui-util.h" +#include "addressbook/gui/contact-editor/e-contact-editor.h" +#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h" +#include "addressbook/importers/evolution-addressbook-importers.h" + +#include "eab-config.h" +#include "addressbook-config.h" +#include "autocompletion-config.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)) + +#define LDAP_BASE_URI "ldap://" +#define PERSONAL_RELATIVE_URI "system" + +struct _EBookShellBackendPrivate { + ESourceList *source_list; +}; + +enum { + PROP_0, + PROP_SOURCE_LIST +}; + +static gpointer parent_class; +static GType book_shell_backend_type; + +static void +book_shell_backend_ensure_sources (EShellBackend *shell_backend) +{ + /* XXX This is basically the same algorithm across all backends. + * Maybe we could somehow integrate this into EShellBackend? */ + + EBookShellBackendPrivate *priv; + ESourceGroup *on_this_computer; + ESourceGroup *on_ldap_servers; + ESource *personal; + GSList *groups, *iter; + const gchar *data_dir; + const gchar *name; + gchar *base_uri; + gchar *filename; + + on_this_computer = NULL; + on_ldap_servers = NULL; + personal = NULL; + + priv = E_BOOK_SHELL_BACKEND_GET_PRIVATE (shell_backend); + + if (!e_book_get_addressbooks (&priv->source_list, NULL)) { + g_warning ("Could not get addressbook sources from GConf!"); + return; + } + + data_dir = e_shell_backend_get_data_dir (shell_backend); + filename = g_build_filename (data_dir, "local", NULL); + base_uri = g_filename_to_uri (filename, NULL, NULL); + g_free (filename); + + groups = e_source_list_peek_groups (priv->source_list); + for (iter = groups; iter != NULL; iter = iter->next) { + ESourceGroup *source_group = iter->data; + const gchar *group_base_uri; + + group_base_uri = e_source_group_peek_base_uri (source_group); + + /* Compare only "file://" part. If the user's home + * changes, we do not want to create another group. */ + if (on_this_computer == NULL && + strncmp (base_uri, group_base_uri, 7) == 0) + on_this_computer = source_group; + + else if (on_ldap_servers == NULL && + strcmp (LDAP_BASE_URI, group_base_uri) == 0) + on_ldap_servers = source_group; + } + + name = _("On This Computer"); + + if (on_this_computer != NULL) { + GSList *sources; + const gchar *group_base_uri; + + /* Force the group name to the current locale. */ + e_source_group_set_name (on_this_computer, name); + + sources = e_source_group_peek_sources (on_this_computer); + group_base_uri = e_source_group_peek_base_uri (on_this_computer); + + /* Make sure this group includes a "Personal" source. */ + for (iter = sources; iter != NULL; iter = iter->next) { + ESource *source = iter->data; + const gchar *relative_uri; + + relative_uri = e_source_peek_relative_uri (source); + if (relative_uri == NULL) + continue; + + if (strcmp (PERSONAL_RELATIVE_URI, relative_uri) != 0) + continue; + + personal = source; + break; + } + + /* Make sure we have the correct base URI. This can + * change when the user's home directory changes. */ + if (strcmp (base_uri, group_base_uri) != 0) { + e_source_group_set_base_uri ( + on_this_computer, base_uri); + + /* XXX We shouldn't need this sync call here as + * set_base_uri() results in synching to GConf, + * but that happens in an idle loop and too late + * to prevent the user from seeing a "Cannot + * Open ... because of invalid URI" error. */ + e_source_list_sync (priv->source_list, NULL); + } + + } else { + ESourceGroup *source_group; + + source_group = e_source_group_new (name, base_uri); + e_source_list_add_group (priv->source_list, source_group, -1); + g_object_unref (source_group); + } + + name = _("Personal"); + + if (personal == NULL) { + ESource *source; + + /* Create the default Personal address book. */ + source = e_source_new (name, PERSONAL_RELATIVE_URI); + e_source_group_add_source (on_this_computer, source, -1); + e_source_set_property (source, "completion", "true"); + g_object_unref (source); + } else { + /* Force the source name to the current locale. */ + e_source_set_name (personal, name); + } + + name = _("On LDAP Servers"); + + if (on_ldap_servers == NULL) { + ESourceGroup *source_group; + + source_group = e_source_group_new (name, LDAP_BASE_URI); + e_source_list_add_group (priv->source_list, source_group, -1); + g_object_unref (source_group); + } else { + /* Force the group name to the current locale. */ + e_source_group_set_name (on_ldap_servers, name); + } + + g_free (base_uri); +} + +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_book_loaded_cb (EBook *book, + EBookStatus status, + gpointer user_data) +{ + EContact *contact; + GtkAction *action; + GtkWidget *editor; + const gchar *action_name; + + /* XXX Handle errors better. */ + if (status != E_BOOK_ERROR_OK) + return; + + contact = e_contact_new (); + action = GTK_ACTION (user_data); + action_name = gtk_action_get_name (action); + + if (strcmp (action_name, "contact-new") == 0) + editor = e_contact_editor_new (book, contact, TRUE, TRUE); + + if (strcmp (action_name, "contact-new-list") == 0) + editor = e_contact_list_editor_new (book, contact, TRUE, TRUE); + + eab_editor_show (EAB_EDITOR (editor)); + + g_object_unref (contact); + g_object_unref (book); +} + +static void +action_contact_new_cb (GtkAction *action, + EShellWindow *shell_window) +{ + EShell *shell; + EBook *book = NULL; + GConfClient *client; + ESourceList *source_list; + const gchar *key; + gchar *uid; + + /* This callback is used for both contacts and contact lists. */ + + if (!e_book_get_addressbooks (&source_list, NULL)) { + g_warning ("Could not get addressbook sources from GConf!"); + return; + } + + shell = e_shell_window_get_shell (shell_window); + client = e_shell_get_gconf_client (shell); + + key = "/apps/evolution/addressbook/display/primary_addressbook"; + uid = gconf_client_get_string (client, key, NULL); + + if (uid != NULL) { + ESource *source; + + source = e_source_list_peek_source_by_uid (source_list, uid); + if (source != NULL) + book = e_book_new (source, NULL); + g_free (uid); + } + + if (book == NULL) + book = e_book_new_default_addressbook (NULL); + + e_book_async_open ( + book, FALSE, book_shell_backend_book_loaded_cb, action); +} + +static void +action_address_book_new_cb (GtkAction *action, + EShellWindow *shell_window) +{ + addressbook_config_create_new_source (NULL); +} + +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", + N_("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_handle_uri_cb (EShellBackend *shell_backend, + const gchar *uri) +{ + EUri *euri; + const gchar *cp; + gchar *source_uid = NULL; + gchar *contact_uid = NULL; + + if (!g_str_has_prefix (uri, "contacts:")) + return FALSE; + + euri = e_uri_new (uri); + cp = euri->query; + + if (cp == NULL) { + e_uri_free (euri); + 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); + + e_uri_free (euri); + + return TRUE; +} + +static void +book_shell_backend_window_created_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_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SOURCE_LIST: + g_value_set_object ( + value, + e_book_shell_backend_get_source_list ( + E_BOOK_SHELL_BACKEND (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +book_shell_backend_dispose (GObject *object) +{ + EBookShellBackendPrivate *priv; + + priv = E_BOOK_SHELL_BACKEND_GET_PRIVATE (object); + + if (priv->source_list != NULL) { + g_object_unref (priv->source_list); + priv->source_list = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +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 (); + certificate_manager_config_init (shell); +#endif + + book_shell_backend_init_importers (); + book_shell_backend_ensure_sources (shell_backend); + + e_plugin_hook_register_type (eab_config_get_type ()); + + g_signal_connect_swapped ( + shell, "handle-uri", + G_CALLBACK (book_shell_backend_handle_uri_cb), + shell_backend); + + g_signal_connect_swapped ( + shell, "window-created", + G_CALLBACK (book_shell_backend_window_created_cb), + shell_backend); + + autocompletion_config_init (shell); +} + +static gboolean +book_shell_backend_is_busy (EShellBackend *shell_backend) +{ + return !eab_editor_request_close_all (); +} + +static gboolean +book_shell_backend_shutdown (EShellBackend *shell_backend) +{ + /* FIXME */ + return TRUE; +} + +static void +book_shell_backend_class_init (EBookShellBackendClass *class) +{ + GObjectClass *object_class; + EShellBackendClass *shell_backend_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EBookShellBackendPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->get_property = book_shell_backend_get_property; + object_class->dispose = book_shell_backend_dispose; + 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->start = NULL; + shell_backend_class->is_busy = book_shell_backend_is_busy; + shell_backend_class->shutdown = book_shell_backend_shutdown; + shell_backend_class->migrate = e_book_shell_backend_migrate; + + g_object_class_install_property ( + object_class, + PROP_SOURCE_LIST, + g_param_spec_object ( + "source-list", + _("Source List"), + _("The registry of address books"), + E_TYPE_SOURCE_LIST, + G_PARAM_READABLE)); +} + +static void +book_shell_backend_init (EBookShellBackend *book_shell_backend) +{ + book_shell_backend->priv = + E_BOOK_SHELL_BACKEND_GET_PRIVATE (book_shell_backend); +} + +GType +e_book_shell_backend_get_type (void) +{ + return book_shell_backend_type; +} + +void +e_book_shell_backend_register_type (GTypeModule *type_module) +{ + const GTypeInfo type_info = { + sizeof (EBookShellBackendClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) book_shell_backend_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EBookShellBackend), + 0, /* n_preallocs */ + (GInstanceInitFunc) book_shell_backend_init, + NULL /* value_table */ + }; + + book_shell_backend_type = g_type_module_register_type ( + type_module, E_TYPE_SHELL_BACKEND, + "EBookShellBackend", &type_info, 0); +} + +ESourceList * +e_book_shell_backend_get_source_list (EBookShellBackend *book_shell_backend) +{ + g_return_val_if_fail ( + E_IS_BOOK_SHELL_BACKEND (book_shell_backend), NULL); + + return book_shell_backend->priv->source_list; +} diff --git a/addressbook/gui/component/e-book-shell-backend.h b/addressbook/gui/component/e-book-shell-backend.h new file mode 100644 index 0000000000..c61e43b814 --- /dev/null +++ b/addressbook/gui/component/e-book-shell-backend.h @@ -0,0 +1,70 @@ +/* + * e-book-shell-backend.h + * + * 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) + * + */ + +#ifndef E_BOOK_SHELL_BACKEND_H +#define E_BOOK_SHELL_BACKEND_H + +#include <shell/e-shell-backend.h> +#include <libedataserver/e-source-list.h> + +/* Standard GObject macros */ +#define E_TYPE_BOOK_SHELL_BACKEND \ + (e_book_shell_backend_get_type ()) +#define E_BOOK_SHELL_BACKEND(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_BOOK_SHELL_BACKEND, EBookShellBackend)) +#define E_BOOK_SHELL_BACKEND_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_BOOK_SHELL_BACKEND, EBookShellBackendClass)) +#define E_IS_BOOK_SHELL_BACKEND(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_BOOK_SHELL_BACKEND)) +#define E_IS_BOOK_SHELL_BACKEND_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_BOOK_SHELL_BACKEND)) +#define E_BOOK_SHELL_BACKEND_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_BOOK_SHELL_BACKEND, EBookShellBackendClass)) + +G_BEGIN_DECLS + +typedef struct _EBookShellBackend EBookShellBackend; +typedef struct _EBookShellBackendClass EBookShellBackendClass; +typedef struct _EBookShellBackendPrivate EBookShellBackendPrivate; + +struct _EBookShellBackend { + EShellBackend parent; + EBookShellBackendPrivate *priv; +}; + +struct _EBookShellBackendClass { + EShellBackendClass parent_class; +}; + +GType e_book_shell_backend_get_type (void); +void e_book_shell_backend_register_type + (GTypeModule *type_module); +ESourceList * e_book_shell_backend_get_source_list + (EBookShellBackend *book_shell_backend); + +G_END_DECLS + +#endif /* E_BOOK_SHELL_BACKEND_H */ diff --git a/addressbook/gui/component/e-book-shell-content.c b/addressbook/gui/component/e-book-shell-content.c new file mode 100644 index 0000000000..cce03b1575 --- /dev/null +++ b/addressbook/gui/component/e-book-shell-content.c @@ -0,0 +1,492 @@ +/* + * e-book-shell-content.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) + * + */ + +#include "e-book-shell-content.h" + +#include <glib/gi18n.h> + +#include "e-util/gconf-bridge.h" + +#define E_BOOK_SHELL_CONTENT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_BOOK_SHELL_CONTENT, EBookShellContentPrivate)) + +struct _EBookShellContentPrivate { + GtkWidget *paned; + GtkWidget *notebook; + GtkWidget *preview; +}; + +enum { + PROP_0, + PROP_CURRENT_VIEW, + PROP_PREVIEW_CONTACT, + PROP_PREVIEW_VISIBLE +}; + +static gpointer parent_class; +static GType book_shell_view_type; + +static void +book_shell_content_send_message_cb (EBookShellContent *book_shell_content, + EDestination *destination, + EABContactDisplay *display) +{ + GList node = { destination, NULL, NULL }; + + eab_send_as_to (&node); +} + +static void +book_shell_content_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CURRENT_VIEW: + e_book_shell_content_set_current_view ( + E_BOOK_SHELL_CONTENT (object), + g_value_get_object (value)); + return; + + case PROP_PREVIEW_CONTACT: + e_book_shell_content_set_preview_contact ( + E_BOOK_SHELL_CONTENT (object), + g_value_get_object (value)); + return; + + case PROP_PREVIEW_VISIBLE: + e_book_shell_content_set_preview_visible ( + E_BOOK_SHELL_CONTENT (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +book_shell_content_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CURRENT_VIEW: + g_value_set_object ( + value, e_book_shell_content_get_current_view ( + E_BOOK_SHELL_CONTENT (object))); + return; + + case PROP_PREVIEW_CONTACT: + g_value_set_object ( + value, e_book_shell_content_get_preview_contact ( + E_BOOK_SHELL_CONTENT (object))); + return; + + case PROP_PREVIEW_VISIBLE: + g_value_set_boolean ( + value, e_book_shell_content_get_preview_visible ( + E_BOOK_SHELL_CONTENT (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +book_shell_content_dispose (GObject *object) +{ + EBookShellContentPrivate *priv; + + priv = E_BOOK_SHELL_CONTENT_GET_PRIVATE (object); + + if (priv->paned != NULL) { + g_object_unref (priv->paned); + priv->paned = NULL; + } + + if (priv->notebook != NULL) { + g_object_unref (priv->notebook); + priv->notebook = NULL; + } + + if (priv->preview != NULL) { + g_object_unref (priv->preview); + priv->preview = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +book_shell_content_constructed (GObject *object) +{ + EBookShellContentPrivate *priv; + GConfBridge *bridge; + GtkWidget *container; + GtkWidget *widget; + const gchar *key; + + priv = E_BOOK_SHELL_CONTENT_GET_PRIVATE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + container = GTK_WIDGET (object); + + widget = gtk_vpaned_new (); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->paned = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_notebook_new (); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); + gtk_paned_add1 (GTK_PANED (container), widget); + priv->notebook = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_paned_add2 (GTK_PANED (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = eab_contact_display_new (); + eab_contact_display_set_mode ( + EAB_CONTACT_DISPLAY (widget), + EAB_CONTACT_DISPLAY_RENDER_NORMAL); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->preview = g_object_ref (widget); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + priv->preview, "send-message", + G_CALLBACK (book_shell_content_send_message_cb), object); + + /* Bind GObject properties to GConf keys. */ + + bridge = gconf_bridge_get (); + + object = G_OBJECT (priv->paned); + key = "/apps/evolution/addressbook/display/vpane_position"; + gconf_bridge_bind_property_delayed (bridge, key, object, "position"); +} + +static guint32 +book_shell_content_check_state (EShellContent *shell_content) +{ + EBookShellContent *book_shell_content; + ESelectionModel *selection_model; + EAddressbookModel *model; + EAddressbookView *view; + guint32 state = 0; + gint n_contacts; + gint n_selected; + + book_shell_content = E_BOOK_SHELL_CONTENT (shell_content); + view = e_book_shell_content_get_current_view (book_shell_content); + model = e_addressbook_view_get_model (view); + + selection_model = e_addressbook_view_get_selection_model (view); + n_contacts = (selection_model != NULL) ? + e_selection_model_row_count (selection_model) : 0; + n_selected = (selection_model != NULL) ? + e_selection_model_selected_count (selection_model) : 0; + + /* FIXME Finish the rest of the flags. */ + if (n_selected == 1) + state |= E_BOOK_SHELL_CONTENT_SELECTION_SINGLE; + if (n_selected > 1) + state |= E_BOOK_SHELL_CONTENT_SELECTION_MULTIPLE; + if (e_addressbook_model_can_stop (model)) + state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY; + if (e_addressbook_model_get_editable (model)) + state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE; + if (n_contacts == 0) + state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY; + + return state; +} + +static void +book_shell_content_class_init (EBookShellContentClass *class) +{ + GObjectClass *object_class; + EShellContentClass *shell_content_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EBookShellContentPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = book_shell_content_set_property; + object_class->get_property = book_shell_content_get_property; + object_class->dispose = book_shell_content_dispose; + object_class->constructed = book_shell_content_constructed; + + shell_content_class = E_SHELL_CONTENT_CLASS (class); + shell_content_class->check_state = book_shell_content_check_state; + + g_object_class_install_property ( + object_class, + PROP_CURRENT_VIEW, + g_param_spec_object ( + "current-view", + _("Current View"), + _("The currently selected address book view"), + E_TYPE_ADDRESSBOOK_VIEW, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_PREVIEW_CONTACT, + g_param_spec_object ( + "preview-contact", + _("Previewed Contact"), + _("The contact being shown in the preview pane"), + E_TYPE_CONTACT, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_PREVIEW_VISIBLE, + g_param_spec_boolean ( + "preview-visible", + _("Preview is Visible"), + _("Whether the preview pane is visible"), + TRUE, + G_PARAM_READWRITE)); +} + +static void +book_shell_content_init (EBookShellContent *book_shell_content) +{ + book_shell_content->priv = + E_BOOK_SHELL_CONTENT_GET_PRIVATE (book_shell_content); + + /* Postpone widget construction until we have a shell view. */ +} + +GType +e_book_shell_content_get_type (void) +{ + return book_shell_view_type; +} + +void +e_book_shell_content_register_type (GTypeModule *type_module) +{ + static const GTypeInfo type_info = { + sizeof (EBookShellContentClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) book_shell_content_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EBookShellContent), + 0, /* n_preallocs */ + (GInstanceInitFunc) book_shell_content_init, + NULL /* value_table */ + }; + + book_shell_view_type = g_type_module_register_type ( + type_module, E_TYPE_SHELL_CONTENT, + "EBookShellContent", &type_info, 0); +} + +GtkWidget * +e_book_shell_content_new (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return g_object_new ( + E_TYPE_BOOK_SHELL_CONTENT, + "shell-view", shell_view, NULL); +} + +void +e_book_shell_content_insert_view (EBookShellContent *book_shell_content, + EAddressbookView *addressbook_view) +{ + GtkNotebook *notebook; + GtkWidget *child; + + g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content)); + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (addressbook_view)); + + notebook = GTK_NOTEBOOK (book_shell_content->priv->notebook); + child = GTK_WIDGET (addressbook_view); + gtk_notebook_append_page (notebook, child, NULL); +} + +void +e_book_shell_content_remove_view (EBookShellContent *book_shell_content, + EAddressbookView *addressbook_view) +{ + GtkNotebook *notebook; + GtkWidget *child; + gint page_num; + + g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content)); + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (addressbook_view)); + + notebook = GTK_NOTEBOOK (book_shell_content->priv->notebook); + child = GTK_WIDGET (addressbook_view); + page_num = gtk_notebook_page_num (notebook, child); + g_return_if_fail (page_num >= 0); + + gtk_notebook_remove_page (notebook, page_num); +} + +EAddressbookView * +e_book_shell_content_get_current_view (EBookShellContent *book_shell_content) +{ + GtkNotebook *notebook; + GtkWidget *widget; + gint page_num; + + g_return_val_if_fail ( + E_IS_BOOK_SHELL_CONTENT (book_shell_content), NULL); + + notebook = GTK_NOTEBOOK (book_shell_content->priv->notebook); + page_num = gtk_notebook_get_current_page (notebook); + widget = gtk_notebook_get_nth_page (notebook, page_num); + g_return_val_if_fail (widget != NULL, NULL); + + return E_ADDRESSBOOK_VIEW (widget); +} + +void +e_book_shell_content_set_current_view (EBookShellContent *book_shell_content, + EAddressbookView *addressbook_view) +{ + GtkNotebook *notebook; + GtkWidget *child; + gint page_num; + + g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content)); + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (addressbook_view)); + + notebook = GTK_NOTEBOOK (book_shell_content->priv->notebook); + child = GTK_WIDGET (addressbook_view); + page_num = gtk_notebook_page_num (notebook, child); + g_return_if_fail (page_num >= 0); + + gtk_notebook_set_current_page (notebook, page_num); + g_object_notify (G_OBJECT (book_shell_content), "current-view"); +} + +EContact * +e_book_shell_content_get_preview_contact (EBookShellContent *book_shell_content) +{ + EABContactDisplay *display; + + g_return_val_if_fail ( + E_IS_BOOK_SHELL_CONTENT (book_shell_content), NULL); + + display = EAB_CONTACT_DISPLAY (book_shell_content->priv->preview); + + return eab_contact_display_get_contact (display); +} + +void +e_book_shell_content_set_preview_contact (EBookShellContent *book_shell_content, + EContact *preview_contact) +{ + EABContactDisplay *display; + + g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content)); + + display = EAB_CONTACT_DISPLAY (book_shell_content->priv->preview); + + eab_contact_display_set_contact (display, preview_contact); + g_object_notify (G_OBJECT (book_shell_content), "preview-contact"); +} + +gboolean +e_book_shell_content_get_preview_visible (EBookShellContent *book_shell_content) +{ + GtkPaned *paned; + GtkWidget *child; + + g_return_val_if_fail ( + E_IS_BOOK_SHELL_CONTENT (book_shell_content), FALSE); + + paned = GTK_PANED (book_shell_content->priv->paned); + child = gtk_paned_get_child2 (paned); + + return GTK_WIDGET_VISIBLE (child); +} + +void +e_book_shell_content_set_preview_visible (EBookShellContent *book_shell_content, + gboolean preview_visible) +{ + GtkPaned *paned; + GtkWidget *child; + + g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content)); + + paned = GTK_PANED (book_shell_content->priv->paned); + child = gtk_paned_get_child2 (paned); + + if (preview_visible) + gtk_widget_show (child); + else + gtk_widget_hide (child); + + g_object_notify (G_OBJECT (book_shell_content), "preview-visible"); +} + +void +e_book_shell_content_clipboard_copy (EBookShellContent *book_shell_content) +{ + EAddressbookView *addressbook_view; + GtkHTML *html; + gchar *selection; + + g_return_if_fail (E_IS_BOOK_SHELL_CONTENT (book_shell_content)); + + html = GTK_HTML (book_shell_content->priv->preview); + addressbook_view = + e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (addressbook_view != NULL); + + if (!GTK_WIDGET_HAS_FOCUS (html)) { + e_addressbook_view_copy (addressbook_view); + return; + } + + selection = gtk_html_get_selection_html (html, NULL); + if (selection != NULL) + gtk_html_copy (html); + g_free (selection); +} diff --git a/addressbook/gui/component/e-book-shell-content.h b/addressbook/gui/component/e-book-shell-content.h new file mode 100644 index 0000000000..ac5ab10e8b --- /dev/null +++ b/addressbook/gui/component/e-book-shell-content.h @@ -0,0 +1,110 @@ +/* + * e-book-shell-content.h + * + * 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) + * + */ + +#ifndef E_BOOK_SHELL_CONTENT_H +#define E_BOOK_SHELL_CONTENT_H + +#include <libebook/e-contact.h> + +#include "shell/e-shell-content.h" +#include "shell/e-shell-view.h" + +#include "addressbook/gui/component/eab-composer-util.h" +#include "addressbook/gui/widgets/e-addressbook-view.h" + +/* Standard GObject macros */ +#define E_TYPE_BOOK_SHELL_CONTENT \ + (e_book_shell_content_get_type ()) +#define E_BOOK_SHELL_CONTENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_BOOK_SHELL_CONTENT, EBookShellContent)) +#define E_BOOK_SHELL_CONTENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_BOOK_SHELL_CONTENT, EBookShellContentClass)) +#define E_IS_BOOK_SHELL_CONTENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_BOOK_SHELL_CONTENT)) +#define E_IS_BOOK_SHELL_CONTENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_BOOK_SHELL_CONTENT)) +#define E_BOOK_SHELL_CONTENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_BOOK_SHELL_CONTENT, EBookShellContentClass)) + +G_BEGIN_DECLS + +typedef struct _EBookShellContent EBookShellContent; +typedef struct _EBookShellContentClass EBookShellContentClass; +typedef struct _EBookShellContentPrivate EBookShellContentPrivate; + +enum { + E_BOOK_SHELL_CONTENT_SELECTION_SINGLE = 1 << 0, + E_BOOK_SHELL_CONTENT_SELECTION_MULTIPLE = 1 << 1, + E_BOOK_SHELL_CONTENT_SELECTION_HAS_EMAIL = 1 << 2, + E_BOOK_SHELL_CONTENT_SELECTION_IS_CONTACT_LIST = 1 << 3, + E_BOOK_SHELL_CONTENT_SELECTION_HAS_HTTP_URI = 1 << 4, + E_BOOK_SHELL_CONTENT_SELECTION_HAS_MAILTO_URI = 1 << 5, + E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY = 1 << 6, + E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE = 1 << 7, + E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY = 1 << 8 +}; + +struct _EBookShellContent { + EShellContent parent; + EBookShellContentPrivate *priv; +}; + +struct _EBookShellContentClass { + EShellContentClass parent_class; +}; + +GType e_book_shell_content_get_type (void); +void e_book_shell_content_register_type + (GTypeModule *type_module); +GtkWidget * e_book_shell_content_new(EShellView *shell_view); +void e_book_shell_content_insert_view + (EBookShellContent *book_shell_content, + EAddressbookView *addressbook_view); +void e_book_shell_content_remove_view + (EBookShellContent *book_shell_content, + EAddressbookView *addressbook_view); +EAddressbookView * + e_book_shell_content_get_current_view + (EBookShellContent *book_shell_content); +void e_book_shell_content_set_current_view + (EBookShellContent *book_shell_content, + EAddressbookView *addressbook_view); +EContact * e_book_shell_content_get_preview_contact + (EBookShellContent *book_shell_content); +void e_book_shell_content_set_preview_contact + (EBookShellContent *book_shell_content, + EContact *preview_contact); +gboolean e_book_shell_content_get_preview_visible + (EBookShellContent *book_shell_content); +void e_book_shell_content_set_preview_visible + (EBookShellContent *book_shell_content, + gboolean preview_visible); +void e_book_shell_content_clipboard_copy + (EBookShellContent *book_shell_content); + +G_END_DECLS + +#endif /* E_BOOK_SHELL_CONTENT_H */ diff --git a/addressbook/gui/component/addressbook-migrate.c b/addressbook/gui/component/e-book-shell-migrate.c index ca691761c9..2c9aa6afb0 100644 --- a/addressbook/gui/component/addressbook-migrate.c +++ b/addressbook/gui/component/e-book-shell-migrate.c @@ -1,4 +1,6 @@ /* + * e-book-shell-backend-migrate.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 @@ -45,7 +47,7 @@ #include "e-util/e-xml-utils.h" #include "e-util/e-folder-map.h" -#include "addressbook-migrate.h" +#include "e-book-shell-migrate.h" /*#define SLOW_MIGRATION*/ @@ -57,7 +59,7 @@ typedef struct { ESourceList *source_list; - AddressbookComponent *component; + const gchar *data_dir; GtkWidget *window; GtkWidget *label; @@ -450,14 +452,12 @@ create_groups (MigrationContext *context, GSList *groups; ESourceGroup *group; char *base_uri, *base_uri_proto; - const gchar *base_dir; *on_this_computer = NULL; *on_ldap_servers = NULL; *personal_source = NULL; - base_dir = addressbook_component_peek_base_directory (context->component); - base_uri = g_build_filename (base_dir, "local", NULL); + base_uri = g_build_filename (context->data_dir, "local", NULL); base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL); @@ -744,12 +744,17 @@ get_source_by_name (ESourceList *source_list, const char *name) static gboolean migrate_completion_folders (MigrationContext *context) { - char *uris_xml = gconf_client_get_string (addressbook_component_peek_gconf_client (context->component), - "/apps/evolution/addressbook/completion/uris", - NULL); + GConfClient *client; + const gchar *key; + gchar *uris_xml; printf ("trying to migrate completion folders\n"); + client = gconf_client_get_default (); + key = "/apps/evolution/addressbook/completion/uris"; + uris_xml = gconf_client_get_string (client, key, NULL); + g_object_unref (client); + if (uris_xml) { xmlDoc *doc = xmlParseMemory (uris_xml, strlen (uris_xml)); xmlNode *root; @@ -1076,17 +1081,20 @@ migrate_pilot_data (const char *old_path, const char *new_path) g_dir_close (dir); } -static MigrationContext* -migration_context_new (AddressbookComponent *component) +static MigrationContext * +migration_context_new (const gchar *data_dir) { MigrationContext *context = g_new (MigrationContext, 1); /* set up the mapping from old uris to new uids */ - context->folder_uid_map = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_free); + context->folder_uid_map = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); e_book_get_addressbooks (&context->source_list, NULL); - context->component = component; + context->data_dir = data_dir; return context; } @@ -1103,16 +1111,24 @@ migration_context_free (MigrationContext *context) g_free (context); } -int -addressbook_migrate (AddressbookComponent *component, int major, int minor, int revision, GError **err) +gboolean +e_book_shell_backend_migrate (EShellBackend *shell_backend, + gint major, + gint minor, + gint micro, + GError **error) { ESourceGroup *on_this_computer; ESourceGroup *on_ldap_servers; ESource *personal_source; - MigrationContext *context = migration_context_new (component); + MigrationContext *context; gboolean need_dialog = FALSE; + const gchar *data_dir; + + g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), FALSE); - printf ("addressbook_migrate (%d.%d.%d)\n", major, minor, revision); + data_dir = e_shell_backend_get_data_dir (shell_backend); + context = migration_context_new (data_dir); /* we call this unconditionally now - create_groups either creates the groups/sources or it finds the necessary @@ -1123,7 +1139,7 @@ addressbook_migrate (AddressbookComponent *component, int major, int minor, int if (major == 1 /* we only need the most recent upgrade point here. further decomposition will happen below. */ - && (minor < 5 || (minor == 5 && revision <= 10))) + && (minor < 5 || (minor == 5 && micro <= 10))) need_dialog = TRUE; if (need_dialog) @@ -1131,7 +1147,7 @@ addressbook_migrate (AddressbookComponent *component, int major, int minor, int if (major == 1) { - if (minor < 5 || (minor == 5 && revision <= 2)) { + if (minor < 5 || (minor == 5 && micro <= 2)) { /* initialize our dialog */ dialog_set_label (context, _("The location and hierarchy of the Evolution contact " @@ -1146,7 +1162,7 @@ addressbook_migrate (AddressbookComponent *component, int major, int minor, int migrate_completion_folders (context); } - if (minor < 5 || (minor == 5 && revision <= 7)) { + if (minor < 5 || (minor == 5 && micro <= 7)) { dialog_set_label (context, _("The format of mailing list contacts has changed.\n\n" "Please be patient while Evolution migrates your " @@ -1155,7 +1171,7 @@ addressbook_migrate (AddressbookComponent *component, int major, int minor, int migrate_contact_lists_for_local_folders (context, on_this_computer); } - if (minor < 5 || (minor == 5 && revision <= 8)) { + if (minor < 5 || (minor == 5 && micro <= 8)) { dialog_set_label (context, _("The way Evolution stores some phone numbers has changed.\n\n" "Please be patient while Evolution migrates your " @@ -1164,15 +1180,14 @@ addressbook_migrate (AddressbookComponent *component, int major, int minor, int migrate_company_phone_for_local_folders (context, on_this_computer); } - if (minor < 5 || (minor == 5 && revision <= 10)) { + if (minor < 5 || (minor == 5 && micro <= 10)) { char *old_path, *new_path; dialog_set_label (context, _("Evolution's Palm Sync changelog and map files have changed.\n\n" "Please be patient while Evolution migrates your Pilot Sync data...")); old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Contacts", NULL); - new_path = g_build_filename (addressbook_component_peek_base_directory (component), - "local", "system", NULL); + new_path = g_build_filename (data_dir, "local", "system", NULL); migrate_pilot_data (old_path, new_path); g_free (new_path); g_free (old_path); @@ -1184,7 +1199,7 @@ addressbook_migrate (AddressbookComponent *component, int major, int minor, int during one phase of development, as they take precedent over relative uris (but aren't updated when editing an ESource). */ - if (minor == 5 && revision <= 11) { + if (minor == 5 && micro <= 11) { GSList *g; for (g = e_source_list_peek_groups (context->source_list); g; g = g->next) { ESourceGroup *group = g->data; diff --git a/addressbook/gui/component/addressbook.h b/addressbook/gui/component/e-book-shell-migrate.h index 0dbd4d7a3d..cb6128910a 100644 --- a/addressbook/gui/component/addressbook.h +++ b/addressbook/gui/component/e-book-shell-migrate.h @@ -1,4 +1,6 @@ /* + * e-book-shell-migrate.h + * * 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 @@ -14,22 +16,26 @@ * * * Authors: + * Chris Toshok (toshok@ximian.com) * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -#ifndef __ADDRESSBOOK_H__ -#define __ADDRESSBOOK_H__ +#ifndef E_BOOK_SHELL_MIGRATE_H +#define E_BOOK_SHELL_MIGRATE_H + +#include <glib.h> +#include <shell/e-shell-backend.h> + +G_BEGIN_DECLS -#include <bonobo/bonobo-control.h> -#include <e-util/e-config-listener.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-moniker-util.h> -#include <libebook/e-book.h> +gboolean e_book_shell_backend_migrate (EShellBackend *shell_backend, + gint major, + gint minor, + gint micro, + GError **error); -guint addressbook_load (EBook *book, EBookCallback cb, gpointer closure); -void addressbook_load_cancel (guint id); -void addressbook_load_default_book (EBookCallback open_response, gpointer closure); +G_END_DECLS -#endif /* __ADDRESSBOOK_H__ */ +#endif /* E_BOOK_SHELL_MIGRATE_H */ diff --git a/addressbook/gui/component/e-book-shell-sidebar.c b/addressbook/gui/component/e-book-shell-sidebar.c new file mode 100644 index 0000000000..fc283e28d7 --- /dev/null +++ b/addressbook/gui/component/e-book-shell-sidebar.c @@ -0,0 +1,232 @@ +/* + * e-book-shell-sidebar.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) + * + */ + +#include "e-book-shell-sidebar.h" + +#include <string.h> +#include <glib/gi18n.h> + +#include "e-book-shell-view.h" +#include "e-book-shell-backend.h" +#include "e-addressbook-selector.h" + +#define E_BOOK_SHELL_SIDEBAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebarPrivate)) + +struct _EBookShellSidebarPrivate { + GtkWidget *selector; +}; + +enum { + PROP_0, + PROP_SELECTOR +}; + +static gpointer parent_class; +static GType book_shell_sidebar_type; + +static void +book_shell_sidebar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SELECTOR: + g_value_set_object ( + value, e_book_shell_sidebar_get_selector ( + E_BOOK_SHELL_SIDEBAR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +book_shell_sidebar_dispose (GObject *object) +{ + EBookShellSidebarPrivate *priv; + + priv = E_BOOK_SHELL_SIDEBAR_GET_PRIVATE (object); + + if (priv->selector != NULL) { + g_object_unref (priv->selector); + priv->selector = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +book_shell_sidebar_constructed (GObject *object) +{ + EBookShellSidebarPrivate *priv; + EShellView *shell_view; + EShellBackend *shell_backend; + EShellSidebar *shell_sidebar; + ESourceList *source_list; + GtkContainer *container; + GtkWidget *widget; + + priv = E_BOOK_SHELL_SIDEBAR_GET_PRIVATE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + shell_sidebar = E_SHELL_SIDEBAR (object); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_backend = e_shell_view_get_shell_backend (shell_view); + + source_list = e_book_shell_backend_get_source_list ( + E_BOOK_SHELL_BACKEND (shell_backend)); + + container = GTK_CONTAINER (shell_sidebar); + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_container_add (container, widget); + gtk_widget_show (widget); + + container = GTK_CONTAINER (widget); + + widget = e_addressbook_selector_new (source_list); + e_source_selector_show_selection (E_SOURCE_SELECTOR (widget), FALSE); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->selector = g_object_ref (widget); + gtk_widget_show (widget); +} + +static guint32 +book_shell_sidebar_check_state (EShellSidebar *shell_sidebar) +{ + EBookShellSidebar *book_shell_sidebar; + ESourceSelector *selector; + ESource *source; + gboolean is_system = FALSE; + guint32 state = 0; + + book_shell_sidebar = E_BOOK_SHELL_SIDEBAR (shell_sidebar); + selector = e_book_shell_sidebar_get_selector (book_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + + if (source != NULL) { + const gchar *uri; + + uri = e_source_peek_relative_uri (source); + is_system = (uri == NULL || strcmp (uri, "system") == 0); + } + + if (source != NULL) + state |= E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE; + if (is_system) + state |= E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM; + + return state; +} + +static void +book_shell_sidebar_class_init (EBookShellSidebarClass *class) +{ + GObjectClass *object_class; + EShellSidebarClass *shell_sidebar_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EBookShellSidebarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->get_property = book_shell_sidebar_get_property; + object_class->dispose = book_shell_sidebar_dispose; + object_class->constructed = book_shell_sidebar_constructed; + + shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class); + shell_sidebar_class->check_state = book_shell_sidebar_check_state; + + g_object_class_install_property ( + object_class, + PROP_SELECTOR, + g_param_spec_object ( + "selector", + _("Source Selector Widget"), + _("This widget displays groups of address books"), + E_TYPE_SOURCE_SELECTOR, + G_PARAM_READABLE)); +} + +static void +book_shell_sidebar_init (EBookShellSidebar *book_shell_sidebar) +{ + book_shell_sidebar->priv = + E_BOOK_SHELL_SIDEBAR_GET_PRIVATE (book_shell_sidebar); + + /* Postpone widget construction until we have a shell view. */ +} + +GType +e_book_shell_sidebar_get_type (void) +{ + return book_shell_sidebar_type; +} + +void +e_book_shell_sidebar_register_type (GTypeModule *type_module) +{ + static const GTypeInfo type_info = { + sizeof (EBookShellSidebarClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) book_shell_sidebar_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EBookShellSidebar), + 0, /* n_preallocs */ + (GInstanceInitFunc) book_shell_sidebar_init, + NULL /* value_table */ + }; + + book_shell_sidebar_type = g_type_module_register_type ( + type_module, E_TYPE_SHELL_SIDEBAR, + "EBookShellSidebar", &type_info, 0); +} + +GtkWidget * +e_book_shell_sidebar_new (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return g_object_new ( + E_TYPE_BOOK_SHELL_SIDEBAR, + "shell-view", shell_view, NULL); +} + +ESourceSelector * +e_book_shell_sidebar_get_selector (EBookShellSidebar *book_shell_sidebar) +{ + g_return_val_if_fail ( + E_IS_BOOK_SHELL_SIDEBAR (book_shell_sidebar), NULL); + + return E_SOURCE_SELECTOR (book_shell_sidebar->priv->selector); +} diff --git a/addressbook/gui/component/e-book-shell-sidebar.h b/addressbook/gui/component/e-book-shell-sidebar.h new file mode 100644 index 0000000000..716523f971 --- /dev/null +++ b/addressbook/gui/component/e-book-shell-sidebar.h @@ -0,0 +1,79 @@ +/* + * e-book-shell-sidebar.h + * + * 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) + * + */ + +#ifndef E_BOOK_SHELL_SIDEBAR_H +#define E_BOOK_SHELL_SIDEBAR_H + +#include <libedataserverui/e-source-selector.h> + +#include <shell/e-shell-sidebar.h> +#include <shell/e-shell-view.h> + +/* Standard GObject macros */ +#define E_TYPE_BOOK_SHELL_SIDEBAR \ + (e_book_shell_sidebar_get_type ()) +#define E_BOOK_SHELL_SIDEBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebar)) +#define E_BOOK_SHELL_SIDEBAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebarClass)) +#define E_IS_BOOK_SHELL_SIDEBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_BOOK_SHELL_SIDEBAR)) +#define E_IS_BOOK_SHELL_SIDEBAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_BOOK_SHELL_SIDEBAR)) +#define E_BOOK_SHELL_SIDEBAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebarClass)) + +G_BEGIN_DECLS + +typedef struct _EBookShellSidebar EBookShellSidebar; +typedef struct _EBookShellSidebarClass EBookShellSidebarClass; +typedef struct _EBookShellSidebarPrivate EBookShellSidebarPrivate; + +enum { + E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0, + E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM = 1 << 1 +}; + +struct _EBookShellSidebar { + EShellSidebar parent; + EBookShellSidebarPrivate *priv; +}; + +struct _EBookShellSidebarClass { + EShellSidebarClass parent_class; +}; + +GType e_book_shell_sidebar_get_type (void); +void e_book_shell_sidebar_register_type + (GTypeModule *type_module); +GtkWidget * e_book_shell_sidebar_new(EShellView *shell_view); +ESourceSelector * + e_book_shell_sidebar_get_selector + (EBookShellSidebar *book_shell_sidebar); + +G_END_DECLS + +#endif /* E_BOOK_SHELL_SIDEBAR_H */ diff --git a/addressbook/gui/component/e-book-shell-view-actions.c b/addressbook/gui/component/e-book-shell-view-actions.c new file mode 100644 index 0000000000..35d0e8f8c8 --- /dev/null +++ b/addressbook/gui/component/e-book-shell-view-actions.c @@ -0,0 +1,982 @@ +/* + * e-book-shell-view-actions.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) + * + */ + +#include "e-book-shell-view-private.h" + +#include <e-util/e-error.h> +#include <e-util/e-util.h> +#include <filter/filter-rule.h> + +#include <addressbook-config.h> + +static void +action_address_book_copy_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_copy_to_folder (view, TRUE); +} + +static void +action_address_book_delete_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EBookShellBackend *book_shell_backend; + EBookShellSidebar *book_shell_sidebar; + ESource *source; + ESourceSelector *selector; + ESourceGroup *source_group; + ESourceList *source_list; + EBook *book; + gint response; + GError *error = NULL; + + shell_view = E_SHELL_VIEW (book_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + book_shell_backend = book_shell_view->priv->book_shell_backend; + source_list = e_book_shell_backend_get_source_list (book_shell_backend); + + book_shell_sidebar = book_shell_view->priv->book_shell_sidebar; + selector = e_book_shell_sidebar_get_selector (book_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (source != NULL); + + response = e_error_run ( + GTK_WINDOW (shell_window), + "addressbook:ask-delete-addressbook", + e_source_peek_name (source)); + + if (response != GTK_RESPONSE_YES) + return; + + book = e_book_new (source, &error); + if (error != NULL) { + g_warning ("Error removing addressbook: %s", error->message); + g_error_free (error); + return; + } + + if (!e_book_remove (book, NULL)) { + e_error_run ( + GTK_WINDOW (shell_window), + "addressbook:remove-addressbook", NULL); + g_object_unref (book); + return; + } + + if (e_source_selector_source_is_selected (selector, source)) + e_source_selector_unselect_source (selector, source); + + source_group = e_source_peek_group (source); + e_source_group_remove_source (source_group, source); + + e_source_list_sync (source_list, NULL); + + g_object_unref (book); +} + +static void +action_address_book_move_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_move_to_folder (view, TRUE); +} + +static void +action_address_book_new_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + + shell_view = E_SHELL_VIEW (book_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + addressbook_config_create_new_source (GTK_WIDGET (shell_window)); +} + +static void +action_address_book_properties_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EBookShellSidebar *book_shell_sidebar; + ESource *source; + ESourceSelector *selector; + EditorUidClosure *closure; + GHashTable *uid_to_editor; + const gchar *uid; + + shell_view = E_SHELL_VIEW (book_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + book_shell_sidebar = book_shell_view->priv->book_shell_sidebar; + selector = e_book_shell_sidebar_get_selector (book_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (source != NULL); + + uid = e_source_peek_uid (source); + uid_to_editor = book_shell_view->priv->uid_to_editor; + + closure = g_hash_table_lookup (uid_to_editor, uid); + if (closure == NULL) { + GtkWidget *editor; + + editor = addressbook_config_edit_source ( + GTK_WIDGET (shell_window), source); + + closure = g_new (EditorUidClosure, 1); + closure->editor = editor; + closure->uid = g_strdup (uid); + closure->view = book_shell_view; + + g_hash_table_insert (uid_to_editor, closure->uid, closure); + + g_object_weak_ref ( + G_OBJECT (closure->editor), (GWeakNotify) + e_book_shell_view_editor_weak_notify, closure); + } + + gtk_window_present (GTK_WINDOW (closure->editor)); +} + +static void +action_address_book_rename_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellSidebar *book_shell_sidebar; + ESourceSelector *selector; + + book_shell_sidebar = book_shell_view->priv->book_shell_sidebar; + selector = e_book_shell_sidebar_get_selector (book_shell_sidebar); + + e_source_selector_edit_primary_selection (selector); +} + +static void +action_address_book_save_as_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_save_as (view, TRUE); +} + +static void +action_address_book_stop_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_stop (view); +} + +static void +action_contact_clipboard_copy_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + + book_shell_content = book_shell_view->priv->book_shell_content; + e_book_shell_content_clipboard_copy (book_shell_content); +} + +static void +action_contact_clipboard_cut_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_cut (view); +} + +static void +action_contact_clipboard_paste_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_paste (view); +} + +static void +action_contact_copy_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_copy_to_folder (view, FALSE); +} + +static void +action_contact_delete_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_delete_selection (view, TRUE); +} + +static void +action_contact_forward_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + GList *list, *iter; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + list = e_addressbook_view_get_selected (view); + g_return_if_fail (list != NULL); + + /* Convert the list of contacts to a list of destinations. */ + for (iter = list; iter != NULL; iter = iter->next) { + EContact *contact = iter->data; + EDestination *destination; + + destination = e_destination_new (); + e_destination_set_contact (destination, contact, 0); + g_object_unref (contact); + + iter->data = destination; + } + + eab_send_as_attachment (list); + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); +} + +static void +action_contact_move_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_move_to_folder (view, FALSE); +} + +static void +action_contact_new_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + EAddressbookModel *model; + EContact *contact; + GtkWidget *editor; + EBook *book; + + book_shell_content = book_shell_view->priv->book_shell_content; + 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 = e_addressbook_model_get_book (model); + g_return_if_fail (book != NULL); + + contact = e_contact_new (); + editor = e_contact_editor_new (book, contact, TRUE, TRUE); + eab_editor_show (EAB_EDITOR (editor)); + g_object_unref (contact); +} + +static void +action_contact_new_list_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + EAddressbookModel *model; + EContact *contact; + GtkWidget *editor; + EBook *book; + + book_shell_content = book_shell_view->priv->book_shell_content; + 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 = e_addressbook_model_get_book (model); + g_return_if_fail (book != NULL); + + contact = e_contact_new (); + editor = e_contact_list_editor_new (book, contact, TRUE, TRUE); + eab_editor_show (EAB_EDITOR (editor)); + g_object_unref (contact); +} + +static void +action_contact_open_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_view (view); +} + +static void +action_contact_preview_cb (GtkToggleAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + gboolean visible; + + book_shell_content = book_shell_view->priv->book_shell_content; + visible = gtk_toggle_action_get_active (action); + e_book_shell_content_set_preview_visible (book_shell_content, visible); +} + +static void +action_contact_print_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + GtkPrintOperationAction print_action; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG; + e_addressbook_view_print (view, print_action); +} + +static void +action_contact_print_preview_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + GtkPrintOperationAction print_action; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW; + e_addressbook_view_print (view, print_action); +} + +static void +action_contact_save_as_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_save_as (view, FALSE); +} + +static void +action_contact_select_all_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + e_addressbook_view_select_all (view); +} + +static void +action_contact_send_message_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + GList *list, *iter; + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + g_return_if_fail (view != NULL); + + list = e_addressbook_view_get_selected (view); + g_return_if_fail (list != NULL); + + /* Convert the list of contacts to a list of destinations. */ + for (iter = list; iter != NULL; iter = iter->next) { + EContact *contact = iter->data; + EDestination *destination; + + destination = e_destination_new (); + e_destination_set_contact (destination, contact, 0); + g_object_unref (contact); + + iter->data = destination; + } + + eab_send_as_to (list); + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); +} + +static void +action_gal_save_custom_view_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EShellView *shell_view; + EAddressbookView *address_view; + GalViewInstance *view_instance; + + /* All shell views respond to the activation of this action, + * which is defined by EShellWindow. But only the currently + * active shell view proceeds with saving the custom view. */ + shell_view = E_SHELL_VIEW (book_shell_view); + if (!e_shell_view_is_active (shell_view)) + return; + + book_shell_content = book_shell_view->priv->book_shell_content; + address_view = e_book_shell_content_get_current_view (book_shell_content); + view_instance = e_addressbook_view_get_view_instance (address_view); + gal_view_instance_save_as (view_instance); +} + +static void +action_search_execute_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EShellView *shell_view; + + /* All shell views respond to the activation of this action, + * which is defined by EShellWindow. But only the currently + * active shell view proceeds with executing the search. */ + shell_view = E_SHELL_VIEW (book_shell_view); + if (!e_shell_view_is_active (shell_view)) + return; + + e_book_shell_view_execute_search (book_shell_view); +} + +static void +action_search_filter_cb (GtkRadioAction *action, + GtkRadioAction *current, + EBookShellView *book_shell_view) +{ + e_book_shell_view_execute_search (book_shell_view); +} + +static GtkActionEntry contact_entries[] = { + + { "address-book-copy", + GTK_STOCK_COPY, + N_("Co_py All Contacts To..."), + NULL, + N_("Copy the contacts of the selected address book to another"), + G_CALLBACK (action_address_book_copy_cb) }, + + { "address-book-delete", + GTK_STOCK_DELETE, + N_("Del_ete Address Book"), + NULL, + N_("Delete the selected address book"), + G_CALLBACK (action_address_book_delete_cb) }, + + { "address-book-move", + "folder-move", + N_("Mo_ve All Contacts To..."), + NULL, + N_("Move the contacts of the selected address book to another"), + G_CALLBACK (action_address_book_move_cb) }, + + { "address-book-new", + "address-book-new", + N_("_New Address Book"), + NULL, + N_("Create a new address book"), + G_CALLBACK (action_address_book_new_cb) }, + + { "address-book-properties", + GTK_STOCK_PROPERTIES, + N_("Address _Book Properties"), + NULL, + N_("Show properties of the selected address book"), + G_CALLBACK (action_address_book_properties_cb) }, + + { "address-book-rename", + NULL, + N_("_Rename..."), + "F2", + N_("Rename the selected address book"), + G_CALLBACK (action_address_book_rename_cb) }, + + { "address-book-save-as", + GTK_STOCK_SAVE_AS, + N_("S_ave Address Book as vCard"), + NULL, + N_("Save the contacts of the selected address book as a vCard"), + G_CALLBACK (action_address_book_save_as_cb) }, + + { "address-book-stop", + GTK_STOCK_STOP, + NULL, + NULL, + N_("Stop loading"), + G_CALLBACK (action_address_book_stop_cb) }, + + { "contact-clipboard-copy", + GTK_STOCK_COPY, + NULL, + NULL, + N_("Copy the selection"), + G_CALLBACK (action_contact_clipboard_copy_cb) }, + + { "contact-clipboard-cut", + GTK_STOCK_CUT, + NULL, + NULL, + N_("Cut the selection"), + G_CALLBACK (action_contact_clipboard_cut_cb) }, + + { "contact-clipboard-paste", + GTK_STOCK_PASTE, + NULL, + NULL, + N_("Paste the clipboard"), + G_CALLBACK (action_contact_clipboard_paste_cb) }, + + { "contact-copy", + NULL, + N_("_Copy Contact To..."), + "<Control><Shift>y", + N_("Copy selected contacts to another address book"), + G_CALLBACK (action_contact_copy_cb) }, + + { "contact-delete", + GTK_STOCK_DELETE, + N_("_Delete Contact"), + "<Control>d", + N_("Delete selected contacts"), + G_CALLBACK (action_contact_delete_cb) }, + + { "contact-forward", + "mail-forward", + N_("_Forward Contact..."), + NULL, + N_("Send selected contacts to another person"), + G_CALLBACK (action_contact_forward_cb) }, + + { "contact-move", + NULL, + N_("_Move Contact To..."), + "<Control><Shift>v", + N_("Move selected contacts to another address book"), + G_CALLBACK (action_contact_move_cb) }, + + { "contact-new", + "contact-new", + N_("_New Contact..."), + NULL, + N_("Create a new contact"), + G_CALLBACK (action_contact_new_cb) }, + + { "contact-new-list", + "stock_contact-list", + N_("New Contact _List..."), + NULL, + N_("Create a new contact list"), + G_CALLBACK (action_contact_new_list_cb) }, + + { "contact-open", + NULL, + N_("_Open"), + "<Control>o", + N_("View the current contact"), + G_CALLBACK (action_contact_open_cb) }, + + { "contact-save-as", + GTK_STOCK_SAVE_AS, + N_("Save as vCard..."), + NULL, + N_("Save selected contacts as a vCard"), + G_CALLBACK (action_contact_save_as_cb) }, + + { "contact-select-all", + GTK_STOCK_SELECT_ALL, + NULL, + NULL, + N_("Select all contacts"), + G_CALLBACK (action_contact_select_all_cb) }, + + { "contact-send-message", + "mail-message-new", + N_("_Send Message to Contact..."), + NULL, + N_("Send a message to the selected contacts"), + G_CALLBACK (action_contact_send_message_cb) }, + + /*** Menus ***/ + + { "actions-menu", + NULL, + N_("_Actions"), + NULL, + NULL, + NULL } +}; + +static EPopupActionEntry contact_popup_entries[] = { + + { "address-book-popup-delete", + N_("_Delete"), + "address-book-delete" }, + + { "address-book-popup-properties", + N_("_Properties"), + "address-book-properties" }, + + { "address-book-popup-rename", + NULL, + "address-book-rename" }, + + { "address-book-popup-save-as", + N_("_Save as vCard..."), + "address-book-save-as" }, + + { "contact-popup-clipboard-copy", + NULL, + "contact-clipboard-copy" }, + + { "contact-popup-clipboard-cut", + NULL, + "contact-clipboard-cut" }, + + { "contact-popup-clipboard-paste", + NULL, + "contact-clipboard-paste" }, + + { "contact-popup-copy", + NULL, + "contact-copy" }, + + { "contact-popup-delete", + NULL, + "contact-delete" }, + + { "contact-popup-forward", + NULL, + "contact-forward" }, + + { "contact-popup-move", + NULL, + "contact-move" }, + + { "contact-popup-open", + NULL, + "contact-open" }, + + { "contact-popup-save-as", + NULL, + "contact-save-as" }, + + { "contact-popup-send-message", + NULL, + "contact-send-message" }, +}; + +static GtkToggleActionEntry contact_toggle_entries[] = { + + { "contact-preview", + NULL, + N_("Contact _Preview"), + "<Control>m", + N_("Show contact preview window"), + G_CALLBACK (action_contact_preview_cb), + TRUE } +}; + +static GtkRadioActionEntry contact_filter_entries[] = { + + { "contact-filter-any-category", + NULL, + N_("Any Category"), + NULL, + NULL, + CONTACT_FILTER_ANY_CATEGORY }, + + { "contact-filter-unmatched", + NULL, + N_("Unmatched"), + NULL, + NULL, + CONTACT_FILTER_UNMATCHED } +}; + +static GtkRadioActionEntry contact_search_entries[] = { + + { "contact-search-any-field-contains", + NULL, + N_("Any field contains"), + NULL, + NULL, /* XXX Add a tooltip! */ + CONTACT_SEARCH_ANY_FIELD_CONTAINS }, + + { "contact-search-email-begins-with", + NULL, + N_("Email begins with"), + NULL, + NULL, /* XXX Add a tooltip! */ + CONTACT_SEARCH_EMAIL_BEGINS_WITH }, + + { "contact-search-name-contains", + NULL, + N_("Name contains"), + NULL, + NULL, /* XXX Add a tooltip! */ + CONTACT_SEARCH_NAME_CONTAINS } +}; + +static GtkActionEntry lockdown_printing_entries[] = { + + { "contact-print", + GTK_STOCK_PRINT, + NULL, + "<Control>p", + N_("Print selected contacts"), + G_CALLBACK (action_contact_print_cb) }, + + { "contact-print-preview", + GTK_STOCK_PRINT_PREVIEW, + NULL, + NULL, + N_("Preview the contacts to be printed"), + G_CALLBACK (action_contact_print_preview_cb) } +}; + +static EPopupActionEntry lockdown_printing_popup_entries[] = { + + { "contact-popup-print", + NULL, + "contact-print" } +}; + +void +e_book_shell_view_actions_init (EBookShellView *book_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + GtkActionGroup *action_group; + GConfBridge *bridge; + GtkAction *action; + GObject *object; + const gchar *key; + + shell_view = E_SHELL_VIEW (book_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + /* Contact Actions */ + action_group = ACTION_GROUP (CONTACTS); + gtk_action_group_add_actions ( + action_group, contact_entries, + G_N_ELEMENTS (contact_entries), book_shell_view); + e_action_group_add_popup_actions ( + action_group, contact_popup_entries, + G_N_ELEMENTS (contact_popup_entries)); + gtk_action_group_add_toggle_actions ( + action_group, contact_toggle_entries, + G_N_ELEMENTS (contact_toggle_entries), book_shell_view); + gtk_action_group_add_radio_actions ( + action_group, contact_search_entries, + G_N_ELEMENTS (contact_search_entries), + CONTACT_SEARCH_NAME_CONTAINS, + NULL, NULL); + + /* Lockdown Printing Actions */ + action_group = ACTION_GROUP (LOCKDOWN_PRINTING); + gtk_action_group_add_actions ( + action_group, lockdown_printing_entries, + G_N_ELEMENTS (lockdown_printing_entries), book_shell_view); + e_action_group_add_popup_actions ( + action_group, lockdown_printing_popup_entries, + G_N_ELEMENTS (lockdown_printing_popup_entries)); + + /* Bind GObject properties to GConf keys. */ + + bridge = gconf_bridge_get (); + + object = G_OBJECT (ACTION (CONTACT_PREVIEW)); + key = "/apps/evolution/addressbook/display/show_preview"; + gconf_bridge_bind_property (bridge, key, object, "active"); + + /* Fine tuning. */ + + action = ACTION (CONTACT_DELETE); + g_object_set (action, "short-label", _("Delete"), NULL); + + g_signal_connect ( + ACTION (GAL_SAVE_CUSTOM_VIEW), "activate", + G_CALLBACK (action_gal_save_custom_view_cb), book_shell_view); + + g_signal_connect ( + ACTION (SEARCH_EXECUTE), "activate", + G_CALLBACK (action_search_execute_cb), book_shell_view); +} + +void +e_book_shell_view_update_search_filter (EBookShellView *book_shell_view) +{ + EShellView *shell_view; + EShellContent *shell_content; + EShellWindow *shell_window; + GtkActionGroup *action_group; + GtkRadioAction *radio_action; + GList *list, *iter; + GSList *group; + gint ii; + + shell_view = E_SHELL_VIEW (book_shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + action_group = ACTION_GROUP (CONTACTS_FILTER); + e_action_group_remove_all_actions (action_group); + + /* Add the standard filter actions. */ + gtk_action_group_add_radio_actions ( + action_group, contact_filter_entries, + G_N_ELEMENTS (contact_filter_entries), + CONTACT_FILTER_ANY_CATEGORY, + G_CALLBACK (action_search_filter_cb), + book_shell_view); + + /* Retrieve the radio group from an action we just added. */ + list = gtk_action_group_list_actions (action_group); + radio_action = GTK_RADIO_ACTION (list->data); + group = gtk_radio_action_get_group (radio_action); + g_list_free (list); + + /* Build the category actions. */ + + list = e_categories_get_list (); + for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) { + const gchar *category_name = iter->data; + const gchar *filename; + GtkAction *action; + gchar *action_name; + + action_name = g_strdup_printf ( + "contact-filter-category-%d", ii); + radio_action = gtk_radio_action_new ( + action_name, category_name, NULL, NULL, ii); + g_free (action_name); + + /* Convert the category icon file to a themed icon name. */ + filename = e_categories_get_icon_file_for (category_name); + if (filename != NULL && *filename != '\0') { + gchar *basename; + gchar *cp; + + basename = g_path_get_basename (filename); + + /* Lose the file extension. */ + if ((cp = strrchr (basename, '.')) != NULL) + *cp = '\0'; + + g_object_set ( + radio_action, "icon-name", basename, NULL); + + g_free (basename); + } + + gtk_radio_action_set_group (radio_action, group); + group = gtk_radio_action_get_group (radio_action); + + /* The action group takes ownership of the action. */ + action = GTK_ACTION (radio_action); + gtk_action_group_add_action (action_group, action); + g_object_unref (radio_action); + } + g_list_free (list); + + /* Use any action in the group; doesn't matter which. */ + e_shell_content_set_filter_action (shell_content, radio_action); + + ii = CONTACT_FILTER_UNMATCHED; + e_shell_content_add_filter_separator_after (shell_content, ii); +} diff --git a/addressbook/gui/component/e-book-shell-view-actions.h b/addressbook/gui/component/e-book-shell-view-actions.h new file mode 100644 index 0000000000..8e3d31f7bf --- /dev/null +++ b/addressbook/gui/component/e-book-shell-view-actions.h @@ -0,0 +1,91 @@ +/* + * e-book-shell-view-actions.h + * + * 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) + * + */ + +#ifndef E_BOOK_SHELL_VIEW_ACTIONS_H +#define E_BOOK_SHELL_VIEW_ACTIONS_H + +#include <shell/e-shell-window-actions.h> + +/* Address Book Actions */ +#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_COPY(window) \ + E_SHELL_WINDOW_ACTION ((window), "address-book-copy") +#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_DELETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "address-book-delete") +#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_MOVE(window) \ + E_SHELL_WINDOW_ACTION ((window), "address-book-move") +#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_PROPERTIES(window) \ + E_SHELL_WINDOW_ACTION ((window), "address-book-properties") +#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_RENAME(window) \ + E_SHELL_WINDOW_ACTION ((window), "address-book-rename") +#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_SAVE_AS(window) \ + E_SHELL_WINDOW_ACTION ((window), "address-book-save-as") +#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_STOP(window) \ + E_SHELL_WINDOW_ACTION ((window), "address-book-stop") + +/* Contact Actions */ +#define E_SHELL_WINDOW_ACTION_CONTACT_CLIPBOARD_COPY(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-clipboard-copy") +#define E_SHELL_WINDOW_ACTION_CONTACT_CLIPBOARD_CUT(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-clipboard-cut") +#define E_SHELL_WINDOW_ACTION_CONTACT_CLIPBOARD_PASTE(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-clipboard-paste") +#define E_SHELL_WINDOW_ACTION_CONTACT_COPY(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-copy") +#define E_SHELL_WINDOW_ACTION_CONTACT_DELETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-delete") +#define E_SHELL_WINDOW_ACTION_CONTACT_FORWARD(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-forward") +#define E_SHELL_WINDOW_ACTION_CONTACT_MOVE(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-move") +#define E_SHELL_WINDOW_ACTION_CONTACT_NEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-new") +#define E_SHELL_WINDOW_ACTION_CONTACT_NEW_LIST(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-new-list") +#define E_SHELL_WINDOW_ACTION_CONTACT_OPEN(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-open") +#define E_SHELL_WINDOW_ACTION_CONTACT_PREVIEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-preview") +#define E_SHELL_WINDOW_ACTION_CONTACT_PRINT(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-print") +#define E_SHELL_WINDOW_ACTION_CONTACT_PRINT_PREVIEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-print-preview") +#define E_SHELL_WINDOW_ACTION_CONTACT_SAVE_AS(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-save-as") +#define E_SHELL_WINDOW_ACTION_CONTACT_SELECT_ALL(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-select-all") +#define E_SHELL_WINDOW_ACTION_CONTACT_SEND_MESSAGE(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-send-message") + +/* Search Actions */ +#define E_SHELL_WINDOW_ACTION_CONTACT_SEARCH_ANY_FIELD_CONTAINS(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-search-any-field-contains") +#define E_SHELL_WINDOW_ACTION_CONTACT_SEARCH_EMAIL_BEGINS_WITH(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-search-email-begins-with") +#define E_SHELL_WINDOW_ACTION_CONTACT_SEARCH_NAME_CONTAINS(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-search-name-contains") + +/* Action Groups */ +#define E_SHELL_WINDOW_ACTION_GROUP_CONTACTS(window) \ + E_SHELL_WINDOW_ACTION_GROUP ((window), "contacts") +#define E_SHELL_WINDOW_ACTION_GROUP_CONTACTS_FILTER(window) \ + E_SHELL_WINDOW_ACTION_GROUP ((window), "contacts-filter") + +#endif /* E_BOOK_SHELL_VIEW_ACTIONS_H */ diff --git a/addressbook/gui/component/e-book-shell-view-private.c b/addressbook/gui/component/e-book-shell-view-private.c new file mode 100644 index 0000000000..ec3562e87a --- /dev/null +++ b/addressbook/gui/component/e-book-shell-view-private.c @@ -0,0 +1,621 @@ +/* + * e-book-shell-view-private.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) + * + */ + +#include "e-book-shell-view-private.h" + +#include "widgets/menus/gal-view-factory-etable.h" +#include "addressbook/gui/widgets/gal-view-factory-minicard.h" + +#include "addressbook.h" + +static void +open_contact (EBookShellView *book_shell_view, + EContact *contact, + gboolean is_new_contact, + EAddressbookView *view) +{ + EAddressbookModel *model; + GtkWidget *editor; + EBook *book; + gboolean editable; + + model = e_addressbook_view_get_model (view); + book = e_addressbook_model_get_book (model); + editable = e_addressbook_model_get_editable (model); + + if (e_contact_get (contact, E_CONTACT_IS_LIST)) + editor = e_contact_list_editor_new ( + book, contact, is_new_contact, editable); + else + editor = e_contact_editor_new ( + book, contact, is_new_contact, editable); + + eab_editor_show (EAB_EDITOR (editor)); +} + +static void +popup_event (EBookShellView *book_shell_view, + GdkEventButton *event) +{ + EShellView *shell_view; + const gchar *widget_path; + + widget_path = "/contact-popup"; + shell_view = E_SHELL_VIEW (book_shell_view); + + e_shell_view_show_popup_menu (shell_view, widget_path, event); +} + +static void +book_shell_view_selection_change_foreach (gint row, + EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *view; + EAddressbookModel *model; + EContact *contact; + + /* XXX A "foreach" function is kind of a silly way to retrieve + * the one and only selected contact, but this is the only + * means that ESelectionModel provides. */ + + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + model = e_addressbook_view_get_model (view); + contact = e_addressbook_model_get_contact (model, row); + + e_book_shell_content_set_preview_contact (book_shell_content, contact); +} + +static void +selection_change (EBookShellView *book_shell_view, + EAddressbookView *view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *current_view; + ESelectionModel *selection_model; + EShellView *shell_view; + gint n_selected; + + shell_view = E_SHELL_VIEW (book_shell_view); + book_shell_content = book_shell_view->priv->book_shell_content; + current_view = e_book_shell_content_get_current_view (book_shell_content); + + if (view != current_view) + return; + + e_shell_view_update_actions (shell_view); + + selection_model = e_addressbook_view_get_selection_model (view); + + n_selected = (selection_model != NULL) ? + e_selection_model_selected_count (selection_model) : 0; + + if (n_selected == 1) + e_selection_model_foreach ( + selection_model, (EForeachFunc) + book_shell_view_selection_change_foreach, + book_shell_view); + else + e_book_shell_content_set_preview_contact ( + book_shell_content, NULL); +} + +static void +contact_changed (EBookShellView *book_shell_view, + EContact *contact) +{ + EBookShellContent *book_shell_content; + EContact *preview_contact; + + book_shell_content = book_shell_view->priv->book_shell_content; + + preview_contact = + e_book_shell_content_get_preview_contact (book_shell_content); + + if (contact != preview_contact) + return; + + /* Re-render the same contact. */ + e_book_shell_content_set_preview_contact (book_shell_content, contact); +} + +static void +contacts_removed (EBookShellView *book_shell_view, + GArray *removed_indices, + EAddressbookModel *model) +{ + EBookShellContent *book_shell_content; + EContact *preview_contact; + + book_shell_content = book_shell_view->priv->book_shell_content; + + preview_contact = + e_book_shell_content_get_preview_contact (book_shell_content); + + if (preview_contact == NULL) + return; + + /* Is the displayed contact still in the model? */ + if (e_addressbook_model_find (model, preview_contact) < 0) + return; + + /* If not, clear the contact display. */ + e_book_shell_content_set_preview_contact (book_shell_content, NULL); +} + +static void +book_open_cb (EBook *book, + EBookStatus status, + gpointer user_data) +{ + EAddressbookView *view = user_data; + EAddressbookModel *model; + ESource *source; + + source = e_book_get_source (book); + model = e_addressbook_view_get_model (view); + + if (status == E_BOOK_ERROR_OK) { + e_addressbook_model_set_book (model, book); + e_addressbook_model_force_folder_bar_message (model); + } else if (status != E_BOOK_ERROR_CANCELLED) + eab_load_error_dialog (NULL /* XXX */, source, status); +} + +static void +book_shell_view_activate_selected_source (EBookShellView *book_shell_view, + ESourceSelector *selector) +{ + EShellView *shell_view; + EBookShellContent *book_shell_content; + EAddressbookView *view; + EAddressbookModel *model; + ESource *source; + GalViewInstance *view_instance; + GHashTable *hash_table; + GtkWidget *widget; + const gchar *uid; + gchar *view_id; + + shell_view = E_SHELL_VIEW (book_shell_view); + book_shell_content = book_shell_view->priv->book_shell_content; + source = e_source_selector_peek_primary_selection (selector); + + if (source == NULL) + return; + + uid = e_source_peek_uid (source); + hash_table = book_shell_view->priv->uid_to_view; + widget = g_hash_table_lookup (hash_table, uid); + + if (widget != NULL) { + EBook *book; + + /* There is a view for this UID. Make sure the view + * actually contains an EBook. The absence of an EBook + * suggests a previous load failed, so try again. */ + view = E_ADDRESSBOOK_VIEW (widget); + model = e_addressbook_view_get_model (view); + source = e_addressbook_view_get_source (view); + + if (e_addressbook_model_get_book (model) == NULL) { + book = e_book_new (source, NULL); + + if (book != NULL) + addressbook_load (book, book_open_cb, view); + } + + } else { + EBook *book; + + /* Create a view for this UID. */ + widget = e_addressbook_view_new (shell_view, source); + gtk_widget_show (widget); + + e_book_shell_content_insert_view ( + book_shell_content, + E_ADDRESSBOOK_VIEW (widget)); + + g_hash_table_insert ( + hash_table, g_strdup (uid), + g_object_ref (widget)); + + g_signal_connect_swapped ( + widget, "open-contact", + G_CALLBACK (open_contact), book_shell_view); + + g_signal_connect_swapped ( + widget, "popup-event", + G_CALLBACK (popup_event), book_shell_view); + + g_signal_connect_swapped ( + widget, "command-state-change", + G_CALLBACK (e_shell_view_update_actions), + book_shell_view); + + g_signal_connect_swapped ( + widget, "selection-change", + G_CALLBACK (selection_change), book_shell_view); + + book = e_book_new (source, NULL); + view = E_ADDRESSBOOK_VIEW (widget); + + if (book != NULL) + addressbook_load (book, book_open_cb, view); + + model = e_addressbook_view_get_model (view); + + g_signal_connect_swapped ( + model, "contact-changed", + G_CALLBACK (contact_changed), book_shell_view); + + g_signal_connect_swapped ( + model, "contacts-removed", + G_CALLBACK (contacts_removed), book_shell_view); + } + + e_book_shell_content_set_current_view ( + book_shell_content, E_ADDRESSBOOK_VIEW (widget)); + + /* XXX We have to keep the addressbook selector informed of the + * current view so it can move contacts via drag-and-drop. */ + e_addressbook_selector_set_current_view ( + E_ADDRESSBOOK_SELECTOR (selector), + E_ADDRESSBOOK_VIEW (widget)); + + view_instance = e_addressbook_view_get_view_instance (view); + view_id = gal_view_instance_get_current_view_id (view_instance); + e_shell_view_set_view_id (shell_view, view_id); + g_free (view_id); + + e_addressbook_model_force_folder_bar_message (model); + selection_change (book_shell_view, view); +} + +static gboolean +book_shell_view_show_popup_menu (GdkEventButton *event, + EShellView *shell_view) +{ + const gchar *widget_path; + + widget_path = "/address-book-popup"; + e_shell_view_show_popup_menu (shell_view, widget_path, event); + + return TRUE; +} + +static gboolean +book_shell_view_selector_button_press_event_cb (EShellView *shell_view, + GdkEventButton *event) +{ + /* XXX Use ESourceSelector's "popup-event" signal instead. */ + + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) + return book_shell_view_show_popup_menu (event, shell_view); + + return FALSE; +} + +static gboolean +book_shell_view_selector_popup_menu_cb (EShellView *shell_view) +{ + /* XXX Use ESourceSelector's "popup-event" signal instead. */ + + return book_shell_view_show_popup_menu (NULL, shell_view); +} + +static gboolean +book_shell_view_selector_key_press_event_cb (EShellView *shell_view, + GdkEventKey *event) +{ + EShellWindow *shell_window; + + /* Needed for the ACTION() macro. */ + shell_window = e_shell_view_get_shell_window (shell_view); + + if (event->keyval == GDK_Delete) { + gtk_action_activate (ACTION (ADDRESS_BOOK_DELETE)); + return TRUE; + } + + return FALSE; +} + +static void +book_shell_view_load_view_collection (EShellViewClass *shell_view_class) +{ + GalViewCollection *collection; + GalViewFactory *factory; + ETableSpecification *spec; + const gchar *base_dir; + gchar *filename; + + collection = shell_view_class->view_collection; + + base_dir = EVOLUTION_ETSPECDIR; + spec = e_table_specification_new (); + filename = g_build_filename (base_dir, ETSPEC_FILENAME, NULL); + if (!e_table_specification_load_from_file (spec, filename)) + g_critical ("Unable to load ETable specification file " + "for address book"); + g_free (filename); + + factory = gal_view_factory_etable_new (spec); + gal_view_collection_add_factory (collection, factory); + g_object_unref (factory); + g_object_unref (spec); + + factory = gal_view_factory_minicard_new (); + gal_view_collection_add_factory (collection, factory); + g_object_unref (factory); + + gal_view_collection_load (collection); +} + +static void +book_shell_view_notify_view_id_cb (EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EAddressbookView *address_view; + GalViewInstance *view_instance; + const gchar *view_id; + + book_shell_content = book_shell_view->priv->book_shell_content; + address_view = e_book_shell_content_get_current_view (book_shell_content); + view_instance = e_addressbook_view_get_view_instance (address_view); + view_id = e_shell_view_get_view_id (E_SHELL_VIEW (book_shell_view)); + + /* A NULL view ID implies we're in a custom view. But you can + * only get to a custom view via the "Define Views" dialog, which + * would have already modified the view instance appropriately. + * Furthermore, there's no way to refer to a custom view by ID + * anyway, since custom views have no IDs. */ + if (view_id == NULL) + return; + + gal_view_instance_set_current_view_id (view_instance, view_id); +} + +void +e_book_shell_view_private_init (EBookShellView *book_shell_view, + EShellViewClass *shell_view_class) +{ + EBookShellViewPrivate *priv = book_shell_view->priv; + GHashTable *uid_to_view; + GHashTable *uid_to_editor; + + uid_to_view = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + + uid_to_editor = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); + + priv->uid_to_view = uid_to_view; + priv->uid_to_editor = uid_to_editor; + + if (!gal_view_collection_loaded (shell_view_class->view_collection)) + book_shell_view_load_view_collection (shell_view_class); + + g_signal_connect ( + book_shell_view, "notify::view-id", + G_CALLBACK (book_shell_view_notify_view_id_cb), NULL); +} + +void +e_book_shell_view_private_constructed (EBookShellView *book_shell_view) +{ + EBookShellViewPrivate *priv = book_shell_view->priv; + EShellContent *shell_content; + EShellSidebar *shell_sidebar; + EShellBackend *shell_backend; + EShellView *shell_view; + EShellWindow *shell_window; + ESourceSelector *selector; + + shell_view = E_SHELL_VIEW (book_shell_view); + shell_backend = e_shell_view_get_shell_backend (shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + e_shell_window_add_action_group (shell_window, "contacts"); + e_shell_window_add_action_group (shell_window, "contacts-filter"); + + /* Cache these to avoid lots of awkward casting. */ + priv->book_shell_backend = g_object_ref (shell_backend); + priv->book_shell_content = g_object_ref (shell_content); + priv->book_shell_sidebar = g_object_ref (shell_sidebar); + + selector = e_book_shell_sidebar_get_selector ( + E_BOOK_SHELL_SIDEBAR (shell_sidebar)); + + g_signal_connect_swapped ( + selector, "button-press-event", + G_CALLBACK (book_shell_view_selector_button_press_event_cb), + book_shell_view); + + g_signal_connect_swapped ( + selector, "key-press-event", + G_CALLBACK (book_shell_view_selector_key_press_event_cb), + book_shell_view); + + g_signal_connect_swapped ( + selector, "popup-menu", + G_CALLBACK (book_shell_view_selector_popup_menu_cb), + book_shell_view); + + g_signal_connect_swapped ( + selector, "primary-selection-changed", + G_CALLBACK (book_shell_view_activate_selected_source), + book_shell_view); + + e_categories_register_change_listener ( + G_CALLBACK (e_book_shell_view_update_search_filter), + book_shell_view); + + e_book_shell_view_actions_init (book_shell_view); + book_shell_view_activate_selected_source (book_shell_view, selector); + e_book_shell_view_update_search_filter (book_shell_view); +} + +void +e_book_shell_view_private_dispose (EBookShellView *book_shell_view) +{ + EBookShellViewPrivate *priv = book_shell_view->priv; + + DISPOSE (priv->book_shell_backend); + DISPOSE (priv->book_shell_content); + DISPOSE (priv->book_shell_sidebar); + + g_hash_table_remove_all (priv->uid_to_view); + g_hash_table_remove_all (priv->uid_to_editor); +} + +void +e_book_shell_view_private_finalize (EBookShellView *book_shell_view) +{ + EBookShellViewPrivate *priv = book_shell_view->priv; + + g_hash_table_destroy (priv->uid_to_view); + g_hash_table_destroy (priv->uid_to_editor); +} + +void +e_book_shell_view_execute_search (EBookShellView *book_shell_view) +{ + EBookShellContent *book_shell_content; + EShellView *shell_view; + EShellWindow *shell_window; + EShellContent *shell_content; + GtkAction *action; + GString *string; + EAddressbookView *view; + EAddressbookModel *model; + FilterRule *rule; + const gchar *format; + const gchar *text; + gchar *query; + gchar *temp; + gint value; + + shell_view = E_SHELL_VIEW (book_shell_view); + if (!e_shell_view_is_active (shell_view)) + return; + + shell_content = e_shell_view_get_shell_content (shell_view); + text = e_shell_content_get_search_text (shell_content); + + shell_window = e_shell_view_get_shell_window (shell_view); + action = ACTION (CONTACT_SEARCH_ANY_FIELD_CONTAINS); + value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); + + if (text == NULL || *text == '\0') { + text = ""; + value = CONTACT_SEARCH_ANY_FIELD_CONTAINS; + } + + switch (value) { + case CONTACT_SEARCH_NAME_CONTAINS: + format = "(contains \"full_name\" %s)"; + break; + + case CONTACT_SEARCH_EMAIL_BEGINS_WITH: + format = "(beginswith \"email\" %s)"; + break; + + default: + text = ""; + /* fall through */ + + case CONTACT_SEARCH_ANY_FIELD_CONTAINS: + format = "(contains \"x-evolution-any-field\" %s)"; + break; + } + + /* Build the query. */ + string = g_string_new (""); + e_sexp_encode_string (string, text); + query = g_strdup_printf (format, string->str); + g_string_free (string, TRUE); + + /* Apply selected filter. */ + value = e_shell_content_get_filter_value (shell_content); + switch (value) { + case CONTACT_FILTER_ANY_CATEGORY: + break; + + case CONTACT_FILTER_UNMATCHED: + temp = g_strdup_printf ( + "(and (not (and (exists \"CATEGORIES\") " + "(not (is \"CATEGORIES\" \"\")))) %s)", + query); + g_free (query); + query = temp; + break; + + default: + { + GList *categories; + const gchar *category_name; + + categories = e_categories_get_list (); + category_name = g_list_nth_data (categories, value); + g_list_free (categories); + + temp = g_strdup_printf ( + "(and (is \"category_list\" \"%s\") %s)", + category_name, query); + g_free (query); + query = temp; + } + } + + /* XXX This is wrong. We need to programmatically construct a + * FilterRule, tell it to build code, and pass the resulting + * expression string to EAddressbookModel. */ + rule = filter_rule_new (); + e_shell_content_set_search_rule (shell_content, rule); + g_object_unref (rule); + + /* Submit the query. */ + book_shell_content = book_shell_view->priv->book_shell_content; + view = e_book_shell_content_get_current_view (book_shell_content); + model = e_addressbook_view_get_model (view); + e_addressbook_model_set_query (model, query); + g_free (query); + + e_book_shell_content_set_preview_contact (book_shell_content, NULL); +} + +void +e_book_shell_view_editor_weak_notify (EditorUidClosure *closure, + GObject *where_the_object_was) +{ + GHashTable *hash_table; + + hash_table = closure->view->priv->uid_to_editor; + g_hash_table_remove (hash_table, closure->uid); +} diff --git a/addressbook/gui/component/e-book-shell-view-private.h b/addressbook/gui/component/e-book-shell-view-private.h new file mode 100644 index 0000000000..b4701aea81 --- /dev/null +++ b/addressbook/gui/component/e-book-shell-view-private.h @@ -0,0 +1,129 @@ +/* + * e-book-shell-view-private.h + * + * 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) + * + */ + +#ifndef E_BOOK_SHELL_VIEW_PRIVATE_H +#define E_BOOK_SHELL_VIEW_PRIVATE_H + +#include "e-book-shell-view.h" + +#include <string.h> +#include <glib/gi18n.h> +#include <gdk/gdkkeysyms.h> +#include <libebook/e-book.h> +#include <libedataserver/e-categories.h> +#include <libedataserver/e-sexp.h> +#include <libedataserverui/e-source-selector.h> + +#include "e-util/gconf-bridge.h" +#include "shell/e-shell-content.h" +#include "shell/e-shell-sidebar.h" +#include "misc/e-popup-action.h" + +#include "addressbook/gui/contact-editor/e-contact-editor.h" +#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h" +#include "addressbook/gui/widgets/eab-gui-util.h" +#include "addressbook/gui/widgets/e-addressbook-view.h" +#include "addressbook/gui/widgets/e-addressbook-selector.h" + +#include "e-book-shell-backend.h" +#include "e-book-shell-content.h" +#include "e-book-shell-sidebar.h" +#include "e-book-shell-view-actions.h" + +#define E_BOOK_SHELL_VIEW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_BOOK_SHELL_VIEW, EBookShellViewPrivate)) + +/* Shorthand, requires a variable named "shell_window". */ +#define ACTION(name) \ + (E_SHELL_WINDOW_ACTION_##name (shell_window)) +#define ACTION_GROUP(name) \ + (E_SHELL_WINDOW_ACTION_GROUP_##name (shell_window)) + +/* For use in dispose() methods. */ +#define DISPOSE(obj) \ + G_STMT_START { \ + if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \ + } G_STMT_END + +/* ETable Specifications */ +#define ETSPEC_FILENAME "e-addressbook-view.etspec" + +G_BEGIN_DECLS + +typedef struct _EditorUidClosure EditorUidClosure; + +struct _EditorUidClosure { + GtkWidget *editor; + gchar *uid; + EBookShellView *view; +}; + +/* List these in the order to be displayed. + * Positive values are reserved for categories. */ +enum { + CONTACT_FILTER_ANY_CATEGORY = -2, + CONTACT_FILTER_UNMATCHED = -1 +}; + +/* List these in the order to be displayed. */ +enum { + CONTACT_SEARCH_NAME_CONTAINS, + CONTACT_SEARCH_EMAIL_BEGINS_WITH, + CONTACT_SEARCH_ANY_FIELD_CONTAINS +}; + +struct _EBookShellViewPrivate { + + /* These are just for convenience. */ + EBookShellBackend *book_shell_backend; + EBookShellContent *book_shell_content; + EBookShellSidebar *book_shell_sidebar; + + GHashTable *uid_to_view; + GHashTable *uid_to_editor; +}; + +void e_book_shell_view_private_init + (EBookShellView *book_shell_view, + EShellViewClass *shell_view_class); +void e_book_shell_view_private_constructed + (EBookShellView *book_shell_view); +void e_book_shell_view_private_dispose + (EBookShellView *book_shell_view); +void e_book_shell_view_private_finalize + (EBookShellView *book_shell_view); + +/* Private Utilities */ + +void e_book_shell_view_actions_init + (EBookShellView *book_shell_view); +void e_book_shell_view_execute_search + (EBookShellView *book_shell_view); +void e_book_shell_view_editor_weak_notify + (EditorUidClosure *closure, + GObject *where_the_object_was); +void e_book_shell_view_update_search_filter + (EBookShellView *book_shell_view); + +G_END_DECLS + +#endif /* E_BOOK_SHELL_VIEW_PRIVATE_H */ diff --git a/addressbook/gui/component/e-book-shell-view.c b/addressbook/gui/component/e-book-shell-view.c new file mode 100644 index 0000000000..ea48bb534c --- /dev/null +++ b/addressbook/gui/component/e-book-shell-view.c @@ -0,0 +1,318 @@ +/* + * e-book-shell-view.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) + * + */ + +#include "e-book-shell-view-private.h" + +static gpointer parent_class; +static GType book_shell_view_type; + +static void +book_shell_view_source_list_changed_cb (EBookShellView *book_shell_view, + ESourceList *source_list) +{ + EBookShellViewPrivate *priv = book_shell_view->priv; + EBookShellContent *book_shell_content; + EShellView *shell_view; + GList *keys, *iter; + + shell_view = E_SHELL_VIEW (book_shell_view); + book_shell_content = book_shell_view->priv->book_shell_content; + + keys = g_hash_table_get_keys (priv->uid_to_view); + for (iter = keys; iter != NULL; iter = iter->next) { + gchar *uid = iter->data; + EAddressbookView *view; + + /* If the source still exists, move on. */ + if (e_source_list_peek_source_by_uid (source_list, uid)) + continue; + + /* Remove the view for the deleted source. */ + view = g_hash_table_lookup (priv->uid_to_view, uid); + e_book_shell_content_remove_view (book_shell_content, view); + g_hash_table_remove (priv->uid_to_view, uid); + } + g_list_free (keys); + + keys = g_hash_table_get_keys (priv->uid_to_editor); + for (iter = keys; iter != NULL; iter = iter->next) { + gchar *uid = iter->data; + EditorUidClosure *closure; + + /* If the source still exists, move on. */ + if (e_source_list_peek_source_by_uid (source_list, uid)) + continue; + + /* Remove the editor for the deleted source. */ + closure = g_hash_table_lookup (priv->uid_to_editor, uid); + g_object_weak_unref ( + G_OBJECT (closure->editor), (GWeakNotify) + e_book_shell_view_editor_weak_notify, closure); + gtk_widget_destroy (closure->editor); + g_hash_table_remove (priv->uid_to_editor, uid); + } + g_list_free (keys); + + e_shell_view_update_actions (shell_view); +} + +static void +book_shell_view_dispose (GObject *object) +{ + EBookShellView *book_shell_view; + + book_shell_view = E_BOOK_SHELL_VIEW (object); + e_book_shell_view_private_dispose (book_shell_view); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +book_shell_view_finalize (GObject *object) +{ + EBookShellView *book_shell_view; + + book_shell_view = E_BOOK_SHELL_VIEW (object); + e_book_shell_view_private_finalize (book_shell_view); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +book_shell_view_constructed (GObject *object) +{ + EBookShellView *book_shell_view; + EBookShellBackend *book_shell_backend; + ESourceList *source_list; + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + book_shell_view = E_BOOK_SHELL_VIEW (object); + e_book_shell_view_private_constructed (book_shell_view); + + book_shell_backend = book_shell_view->priv->book_shell_backend; + source_list = e_book_shell_backend_get_source_list (book_shell_backend); + + g_signal_connect_swapped ( + source_list, "changed", + G_CALLBACK (book_shell_view_source_list_changed_cb), + book_shell_view); +} + +static void +book_shell_view_update_actions (EShellView *shell_view) +{ + EBookShellViewPrivate *priv; + EShellContent *shell_content; + EShellSidebar *shell_sidebar; + EShellWindow *shell_window; + GtkAction *action; + const gchar *label; + gboolean sensitive; + guint32 state; + + /* Be descriptive. */ + gboolean any_contacts_selected; + gboolean has_primary_source; + gboolean multiple_contacts_selected; + gboolean primary_source_is_system; + gboolean single_contact_selected; + gboolean selection_is_contact_list; + gboolean selection_has_email; + gboolean source_is_busy; + gboolean source_is_editable; + gboolean source_is_empty; + + priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view); + + shell_window = e_shell_view_get_shell_window (shell_view); + + shell_content = e_shell_view_get_shell_content (shell_view); + state = e_shell_content_check_state (shell_content); + + single_contact_selected = + (state & E_BOOK_SHELL_CONTENT_SELECTION_SINGLE); + multiple_contacts_selected = + (state & E_BOOK_SHELL_CONTENT_SELECTION_MULTIPLE); + selection_has_email = + (state & E_BOOK_SHELL_CONTENT_SELECTION_HAS_EMAIL); + selection_is_contact_list = + (state & E_BOOK_SHELL_CONTENT_SELECTION_IS_CONTACT_LIST); + source_is_busy = + (state & E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY); + source_is_editable = + (state & E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE); + source_is_empty = + (state & E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY); + + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + state = e_shell_sidebar_check_state (shell_sidebar); + + has_primary_source = + (state & E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE); + primary_source_is_system = + (state & E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM); + + any_contacts_selected = + (single_contact_selected || multiple_contacts_selected); + + action = ACTION (ADDRESS_BOOK_DELETE); + sensitive = has_primary_source && !primary_source_is_system; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (ADDRESS_BOOK_RENAME); + sensitive = has_primary_source; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (ADDRESS_BOOK_STOP); + sensitive = source_is_busy; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_CLIPBOARD_COPY); + sensitive = any_contacts_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_CLIPBOARD_CUT); + sensitive = source_is_editable && any_contacts_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_CLIPBOARD_PASTE); + sensitive = source_is_editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_COPY); + sensitive = any_contacts_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_DELETE); + sensitive = source_is_editable && any_contacts_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_FORWARD); + sensitive = any_contacts_selected; + gtk_action_set_sensitive (action, sensitive); + if (multiple_contacts_selected) + label = _("_Forward Contacts"); + else + label = _("_Forward Contact"); + g_object_set (action, "label", label, NULL); + + action = ACTION (CONTACT_MOVE); + sensitive = source_is_editable && any_contacts_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_OPEN); + sensitive = any_contacts_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_PRINT); + sensitive = any_contacts_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_PRINT_PREVIEW); + sensitive = any_contacts_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_SAVE_AS); + sensitive = any_contacts_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_SELECT_ALL); + sensitive = !(source_is_empty); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_SEND_MESSAGE); + sensitive = any_contacts_selected && selection_has_email; + gtk_action_set_sensitive (action, sensitive); + if (multiple_contacts_selected) + label = _("_Send Message to Contacts"); + else if (selection_is_contact_list) + label = _("_Send Message to List"); + else + label = _("_Send Message to Contact"); + g_object_set (action, "label", label, NULL); +} + +static void +book_shell_view_class_init (EBookShellViewClass *class) +{ + GObjectClass *object_class; + EShellViewClass *shell_view_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EBookShellViewPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->dispose = book_shell_view_dispose; + object_class->finalize = book_shell_view_finalize; + object_class->constructed = book_shell_view_constructed; + + shell_view_class = E_SHELL_VIEW_CLASS (class); + shell_view_class->label = _("Contacts"); + shell_view_class->icon_name = "x-office-address-book"; + shell_view_class->ui_definition = "evolution-contacts.ui"; + shell_view_class->ui_manager_id = "org.gnome.evolution.contacts"; + shell_view_class->search_options = "/contact-search-options"; + shell_view_class->search_rules = "addresstypes.xml"; + shell_view_class->new_shell_content = e_book_shell_content_new; + shell_view_class->new_shell_sidebar = e_book_shell_sidebar_new; + shell_view_class->update_actions = book_shell_view_update_actions; +} + +static void +book_shell_view_init (EBookShellView *book_shell_view, + EShellViewClass *shell_view_class) +{ + book_shell_view->priv = + E_BOOK_SHELL_VIEW_GET_PRIVATE (book_shell_view); + + e_book_shell_view_private_init (book_shell_view, shell_view_class); +} + +GType +e_book_shell_view_get_type (void) +{ + return book_shell_view_type; +} + +void +e_book_shell_view_register_type (GTypeModule *type_module) +{ + const GTypeInfo type_info = { + sizeof (EBookShellViewClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) book_shell_view_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EBookShellView), + 0, /* n_preallocs */ + (GInstanceInitFunc) book_shell_view_init, + NULL /* value_table */ + }; + + book_shell_view_type = g_type_module_register_type ( + type_module, E_TYPE_SHELL_VIEW, + "EBookShellView", &type_info, 0); +} diff --git a/addressbook/gui/component/e-book-shell-view.h b/addressbook/gui/component/e-book-shell-view.h new file mode 100644 index 0000000000..33a0c8a75d --- /dev/null +++ b/addressbook/gui/component/e-book-shell-view.h @@ -0,0 +1,66 @@ +/* + * e-book-shell-view.h + * + * 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) + * + */ + +#ifndef E_BOOK_SHELL_VIEW_H +#define E_BOOK_SHELL_VIEW_H + +#include <shell/e-shell-view.h> + +/* Standard GObject macros */ +#define E_TYPE_BOOK_SHELL_VIEW \ + (e_book_shell_view_get_type ()) +#define E_BOOK_SHELL_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_BOOK_SHELL_VIEW, EBookShellView)) +#define E_BOOK_SHELL_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_BOOK_SHELL_VIEW, EBookShellViewClass)) +#define E_IS_BOOK_SHELL_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_BOOK_SHELL_VIEW)) +#define E_IS_BOOK_SHELL_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_BOOK_SHELL_VIEW)) +#define E_BOOK_SHELL_VIEW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_BOOK_SHELL_VIEW, EBookShellViewClass)) + +G_BEGIN_DECLS + +typedef struct _EBookShellView EBookShellView; +typedef struct _EBookShellViewClass EBookShellViewClass; +typedef struct _EBookShellViewPrivate EBookShellViewPrivate; + +struct _EBookShellView { + EShellView parent; + EBookShellViewPrivate *priv; +}; + +struct _EBookShellViewClass { + EShellViewClass parent_class; +}; + +GType e_book_shell_view_get_type (void); +void e_book_shell_view_register_type (GTypeModule *type_module); + +G_END_DECLS + +#endif /* E_BOOK_SHELL_VIEW_H */ diff --git a/addressbook/gui/component/eab-composer-util.c b/addressbook/gui/component/eab-composer-util.c new file mode 100644 index 0000000000..46d28b0790 --- /dev/null +++ b/addressbook/gui/component/eab-composer-util.c @@ -0,0 +1,197 @@ +/* + * 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) + * + */ + +#include "eab-composer-util.h" + +#include <string.h> +#include <glib/gi18n.h> +#include <libebook/e-contact.h> +#include <libebook/e-destination.h> + +#include "composer/e-msg-composer.h" +#include "addressbook/util/eab-book-util.h" +#include "addressbook/gui/widgets/eab-gui-util.h" + +void +eab_send_as_to (GList *destinations) +{ + EMsgComposer *composer; + EComposerHeaderTable *table; + GPtrArray *to_array; + GPtrArray *bcc_array; + + union { + gpointer *pdata; + EDestination **destinations; + } convert; + + if (destinations == NULL) + return; + + composer = e_msg_composer_new (); + table = e_msg_composer_get_header_table (composer); + + to_array = g_ptr_array_new (); + bcc_array = g_ptr_array_new (); + + /* Sort contacts into "To" and "Bcc" destinations. */ + while (destinations != NULL) { + EDestination *destination = destinations->data; + + if (e_destination_is_evolution_list (destination)) { + if (e_destination_list_show_addresses (destination)) + g_ptr_array_add (to_array, destination); + else + g_ptr_array_add (bcc_array, destination); + } else + g_ptr_array_add (to_array, destination); + + destinations = g_list_next (destinations); + } + + /* Add sentinels to each array. */ + g_ptr_array_add (to_array, NULL); + g_ptr_array_add (bcc_array, NULL); + + /* XXX Acrobatics like this make me question whether NULL-terminated + * arrays are really the best argument type for passing a list of + * destinations to the header table. */ + + /* Add "To" destinations. */ + convert.pdata = to_array->pdata; + e_composer_header_table_set_destinations_to ( + table, convert.destinations); + g_ptr_array_free (to_array, FALSE); + e_destination_freev (convert.destinations); + + /* Add "Bcc" destinations. */ + convert.pdata = bcc_array->pdata; + e_composer_header_table_set_destinations_bcc ( + table, convert.destinations); + g_ptr_array_free (bcc_array, FALSE); + e_destination_freev (convert.destinations); + + gtk_widget_show (GTK_WIDGET (composer)); +} + +static const char * +get_email (EContact *contact, EContactField field_id, gchar **to_free) +{ + char *name = NULL, *mail = NULL; + const char *value = e_contact_get_const (contact, field_id); + + *to_free = NULL; + + if (eab_parse_qp_email (value, &name, &mail)) { + *to_free = g_strdup_printf ("%s <%s>", name, mail); + value = *to_free; + } + + g_free (name); + g_free (mail); + + return value; +} + +void +eab_send_as_attachment (GList *destinations) +{ + EMsgComposer *composer; + EComposerHeaderTable *table; + CamelMimePart *attachment; + GList *contacts, *iter; + gchar *data; + + if (destinations == NULL) + return; + + composer = e_msg_composer_new (); + table = e_msg_composer_get_header_table (composer); + + attachment = camel_mime_part_new (); + + contacts = g_list_copy (destinations); + for (iter = contacts; iter != NULL; iter = iter->next) + iter->data = e_destination_get_contact (iter->data); + data = eab_contact_list_to_string (contacts); + g_list_free (contacts); + + camel_mime_part_set_content ( + attachment, data, strlen (data), "text/x-vcard"); + + if (destinations->next != NULL) + camel_mime_part_set_description ( + attachment, _("Multiple vCards")); + else { + EContact *contact; + const gchar *file_as; + gchar *description; + + contact = e_destination_get_contact (destinations->data); + file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS); + description = g_strdup_printf (_("vCard for %s"), file_as); + camel_mime_part_set_description (attachment, description); + g_free (description); + } + + camel_mime_part_set_disposition (attachment, "attachment"); + + e_msg_composer_attach (composer, attachment); + camel_object_unref (attachment); + + if (destinations->next != NULL) + e_composer_header_table_set_subject ( + table, _("Contact information")); + else { + EContact *contact; + gchar *tempstr; + const gchar *tempstr2; + gchar *tempfree = NULL; + + contact = e_destination_get_contact (destinations->data); + tempstr2 = e_contact_get_const (contact, E_CONTACT_FILE_AS); + if (!tempstr2 || !*tempstr2) + tempstr2 = e_contact_get_const (contact, E_CONTACT_FULL_NAME); + if (!tempstr2 || !*tempstr2) + tempstr2 = e_contact_get_const (contact, E_CONTACT_ORG); + if (!tempstr2 || !*tempstr2) { + g_free (tempfree); + tempstr2 = get_email (contact, E_CONTACT_EMAIL_1, &tempfree); + } + if (!tempstr2 || !*tempstr2) { + g_free (tempfree); + tempstr2 = get_email (contact, E_CONTACT_EMAIL_2, &tempfree); + } + if (!tempstr2 || !*tempstr2) { + g_free (tempfree); + tempstr2 = get_email (contact, E_CONTACT_EMAIL_3, &tempfree); + } + + if (!tempstr2 || !*tempstr2) + tempstr = g_strdup_printf (_("Contact information")); + else + tempstr = g_strdup_printf (_("Contact information for %s"), tempstr2); + + e_composer_header_table_set_subject (table, tempstr); + + g_free (tempstr); + g_free (tempfree); + } + + gtk_widget_show (GTK_WIDGET (composer)); +} diff --git a/addressbook/gui/component/addressbook-migrate.h b/addressbook/gui/component/eab-composer-util.h index 5727b3d0ab..4aec23074d 100644 --- a/addressbook/gui/component/addressbook-migrate.h +++ b/addressbook/gui/component/eab-composer-util.h @@ -1,5 +1,4 @@ /* - * * 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 @@ -13,21 +12,20 @@ * 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/> * - * - * Authors: - * Chris Toshok (toshok@ximian.com) - * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -#ifndef _ADDRESSBOOK_MIGRATE_H_ -#define _ADDRESSBOOK_MIGRATE_H_ +#ifndef EAB_COMPOSER_UTIL_H +#define EAB_COMPOSER_UTIL_H + +#include <gtk/gtk.h> -#include "addressbook-component.h" +G_BEGIN_DECLS -struct _GError; +void eab_send_as_to (GList *destinations); +void eab_send_as_attachment (GList *destinations); -int addressbook_migrate (AddressbookComponent *component, int major, int minor, int revision, struct _GError **err); +G_END_DECLS -#endif /* _ADDRESSBOOK_MIGRATE_H_ */ +#endif /* EAB_COMPOSER_UTIL_H */ diff --git a/addressbook/gui/component/evolution-module-addressbook.c b/addressbook/gui/component/evolution-module-addressbook.c new file mode 100644 index 0000000000..3089133e43 --- /dev/null +++ b/addressbook/gui/component/evolution-module-addressbook.c @@ -0,0 +1,45 @@ +/* + * evolution-module-addressbook.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) + * + */ + +#include "e-book-shell-backend.h" +#include "e-book-shell-content.h" +#include "e-book-shell-sidebar.h" +#include "e-book-shell-view.h" + +/* Module Entry Points */ +void e_module_load (GTypeModule *type_module); +void e_module_unload (GTypeModule *type_module); + +G_MODULE_EXPORT void +e_module_load (GTypeModule *type_module) +{ + /* Register dynamically loaded types. */ + + e_book_shell_backend_register_type (type_module); + e_book_shell_content_register_type (type_module); + e_book_shell_sidebar_register_type (type_module); + e_book_shell_view_register_type (type_module); +} + +G_MODULE_EXPORT void +e_module_unload (GTypeModule *type_module) +{ +} |