summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoss Burton <ross@linux.intel.com>2009-06-15 08:54:43 +0100
committerRoss Burton <ross@linux.intel.com>2009-08-17 13:01:53 +0100
commitf296cb9c794c649f431a8d1210bd92d91086fc5d (patch)
treeb99a3ffe832d0e55c7218a0114f1fc6178732148
parent84a1355a10557a912676d92a53167a070cb5dabc (diff)
downloadevolution-data-server-f296cb9c794c649f431a8d1210bd92d91086fc5d.tar.gz
Port libedata-book to DBus
-rw-r--r--addressbook/libedata-book/Makefile.am60
-rw-r--r--addressbook/libedata-book/e-book-backend-sync.h1
-rw-r--r--addressbook/libedata-book/e-book-backend.c60
-rw-r--r--addressbook/libedata-book/e-book-backend.h3
-rw-r--r--addressbook/libedata-book/e-data-book-factory.c663
-rw-r--r--addressbook/libedata-book/e-data-book-factory.h51
-rw-r--r--addressbook/libedata-book/e-data-book-types.h99
-rw-r--r--addressbook/libedata-book/e-data-book-view.c790
-rw-r--r--addressbook/libedata-book/e-data-book-view.h47
-rw-r--r--addressbook/libedata-book/e-data-book.c1289
-rw-r--r--addressbook/libedata-book/e-data-book.h157
-rw-r--r--addressbook/libedata-book/glib-gen.mak42
-rw-r--r--addressbook/libedata-book/libedata-book.pc.in5
-rw-r--r--addressbook/libedata-book/opid.c75
-rw-r--r--addressbook/libedata-book/opid.h28
-rw-r--r--addressbook/libedata-book/org.gnome.evolution.dataserver.AddressBook.service.in3
16 files changed, 1533 insertions, 1840 deletions
diff --git a/addressbook/libedata-book/Makefile.am b/addressbook/libedata-book/Makefile.am
index 6389ce4ba..cf8f0b88a 100644
--- a/addressbook/libedata-book/Makefile.am
+++ b/addressbook/libedata-book/Makefile.am
@@ -1,36 +1,29 @@
AM_CPPFLAGS = \
-DG_LOG_DOMAIN=\"libedata-book\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
-I$(top_srcdir) \
-I$(top_builddir) \
-I$(top_srcdir)/addressbook \
-I$(top_builddir)/addressbook \
$(DB_CFLAGS) \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
+ $(EVOLUTION_ADDRESSBOOK_CFLAGS)
-# The corba stubs and skels
-CORBA_GENERATED_C = \
- Evolution-DataServer-Addressbook-common.c \
- Evolution-DataServer-Addressbook-skels.c \
- Evolution-DataServer-Addressbook-stubs.c
-CORBA_GENERATED_H = \
- Evolution-DataServer-Addressbook.h
-
-CORBA_GENERATED = $(CORBA_GENERATED_C) $(CORBA_GENERATED_H)
+# The library
+lib_LTLIBRARIES = libedata-book-1.2.la
-idls = \
- $(srcdir)/../idl/Evolution-DataServer-Addressbook.idl
+DBUS_GENERATED_H = e-data-book-glue.h e-data-book-factory-glue.h e-data-book-view-glue.h
+%-glue.h: %.xml
+ dbus-binding-tool --mode=glib-server --output=$@ --prefix=$(subst -,_,$*) $^
-idl_flags = $(IDL_INCLUDES)
+include glib-gen.mak
+glib_enum_headers=e-data-book-types.h
+glib_enum_define=E_DATA_BOOK
+glib_enum_prefix=e_data_book
-$(CORBA_GENERATED_H): $(idls)
- $(ORBIT_IDL) $(idl_flags) $(srcdir)/../idl/Evolution-DataServer-Addressbook.idl
-$(CORBA_GENERATED_C): $(CORBA_GENERATED_H)
-
-# The library
-lib_LTLIBRARIES = libedata-book-1.2.la
+ENUM_GENERATED = e-data-book-enumtypes.h e-data-book-enumtypes.c
libedata_book_1_2_la_SOURCES = \
- $(CORBA_GENERATED_C) \
+ $(DBUS_GENERATED_H) \
e-book-backend-factory.c \
e-book-backend-sexp.c \
e-book-backend-summary.c \
@@ -38,10 +31,11 @@ libedata_book_1_2_la_SOURCES = \
e-book-backend-db-cache.c \
e-book-backend-sync.c \
e-book-backend.c \
- e-data-book-factory.c \
e-data-book-view.c \
e-data-book.c \
- ximian-vcard.h
+ ximian-vcard.h \
+ opid.c opid.h \
+ $(ENUM_GENERATED)
libedata_book_1_2_la_LIBADD = \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
@@ -56,7 +50,6 @@ libedata_book_1_2_la_LDFLAGS = \
libedata_bookincludedir = $(privincludedir)/libedata-book
libedata_bookinclude_HEADERS = \
- $(CORBA_GENERATED_H) \
e-book-backend-factory.h \
e-book-backend-sexp.h \
e-book-backend-summary.h \
@@ -75,12 +68,27 @@ libedata_bookinclude_HEADERS = \
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libedata-book-$(API_VERSION).pc
-BUILT_SOURCES = $(CORBA_GENERATED)
-CLEANFILES = $(BUILT_SOURCES)
+service_in_files = org.gnome.evolution.dataserver.AddressBook.service.in
+servicedir = $(datadir)/dbus-1/services
+service_DATA = $(service_in_files:.service.in=.service)
+@EVO_SUBST_SERVICE_RULE@
+
+BUILT_SOURCES = $(DBUS_GENERATED_H) $(ENUM_GENERATED)
+CLEANFILES = $(BUILT_SOURCES) $(service_DATA)
DISTCLEANFILES = $(pkgconfig_DATA)
EXTRA_DIST = \
- $(pkgconfig_DATA:-$(API_VERSION).pc=.pc.in)
+ e-data-book-factory.xml \
+ e-data-book-view.xml \
+ e-data-book.xml \
+ $(pkgconfig_DATA:-$(API_VERSION).pc=.pc.in) \
+ $(service_in_files)
dist-hook:
cd $(distdir); rm -f $(BUILT_SOURCES)
+
+factorydir = $(libexecdir)
+factory_PROGRAMS = e-addressbook-factory
+
+e_addressbook_factory_SOURCES = e-data-book-factory.c e-data-book-factory.h
+e_addressbook_factory_LDADD = libedata-book-1.2.la
diff --git a/addressbook/libedata-book/e-book-backend-sync.h b/addressbook/libedata-book/e-book-backend-sync.h
index b51d46181..589fa62d4 100644
--- a/addressbook/libedata-book/e-book-backend-sync.h
+++ b/addressbook/libedata-book/e-book-backend-sync.h
@@ -6,7 +6,6 @@
#define __E_BOOK_BACKEND_SYNC_H__
#include <glib.h>
-#include <libedata-book/Evolution-DataServer-Addressbook.h>
#include <libedata-book/e-data-book-types.h>
#include <libedata-book/e-book-backend.h>
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index 7ef6da85d..61460e24c 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -9,6 +9,7 @@
#include <config.h>
#include "e-data-book-view.h"
+#include "e-data-book.h"
#include "e-book-backend.h"
struct _EBookBackendPrivate {
@@ -571,12 +572,7 @@ e_book_backend_add_client (EBookBackend *backend,
g_return_val_if_fail (E_IS_BOOK_BACKEND (backend), FALSE);
g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
- bonobo_object_set_immortal (BONOBO_OBJECT (book), TRUE);
-
g_object_weak_ref (G_OBJECT (book), book_destroy_cb, backend);
-
- ORBit_small_listen_for_broken (e_data_book_get_listener (book), G_CALLBACK (listener_died_cb), book);
-
g_mutex_lock (backend->priv->clients_mutex);
backend->priv->clients = g_list_prepend (backend->priv->clients, book);
g_mutex_unlock (backend->priv->clients_mutex);
@@ -629,29 +625,7 @@ e_book_backend_remove_client (EBookBackend *backend,
gboolean
e_book_backend_has_out_of_proc_clients (EBookBackend *backend)
{
- GList *l;
-
- g_mutex_lock (backend->priv->clients_mutex);
-
- if (!backend->priv->clients) {
- g_mutex_unlock (backend->priv->clients_mutex);
-
- return FALSE;
- }
-
- for (l = backend->priv->clients; l; l = l->next) {
- if (ORBit_small_get_connection_status (e_data_book_get_listener (l->data)) != ORBIT_CONNECTION_IN_PROC) {
- g_mutex_unlock (backend->priv->clients_mutex);
-
- return TRUE;
- }
- }
-
- g_mutex_unlock (backend->priv->clients_mutex);
-
- /* If we get here, all remaining clients are in proc */
-
- return FALSE;
+ return TRUE;
}
/**
@@ -815,13 +789,13 @@ e_book_backend_sync (EBookBackend *backend)
*
* Return value: A new #GNOME_Evolution_Addressbook_BookChangeItem.
**/
-GNOME_Evolution_Addressbook_BookChangeItem*
-e_book_backend_change_add_new (const gchar *vcard)
+EDataBookChange *
+e_book_backend_change_add_new (const char *vcard)
{
- GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc();
+ EDataBookChange *new_change = g_new (EDataBookChange, 1);
- new_change->changeType= GNOME_Evolution_Addressbook_ContactAdded;
- new_change->vcard = CORBA_string_dup (vcard);
+ new_change->change_type = E_DATA_BOOK_BACKEND_CHANGE_ADDED;
+ new_change->vcard = g_strdup (vcard);
return new_change;
}
@@ -835,13 +809,13 @@ e_book_backend_change_add_new (const gchar *vcard)
*
* Return value: A new #GNOME_Evolution_Addressbook_BookChangeItem.
**/
-GNOME_Evolution_Addressbook_BookChangeItem*
-e_book_backend_change_modify_new (const gchar *vcard)
+EDataBookChange *
+e_book_backend_change_modify_new (const char *vcard)
{
- GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc();
+ EDataBookChange *new_change = g_new (EDataBookChange, 1);
- new_change->changeType= GNOME_Evolution_Addressbook_ContactModified;
- new_change->vcard = CORBA_string_dup (vcard);
+ new_change->change_type = E_DATA_BOOK_BACKEND_CHANGE_MODIFIED;
+ new_change->vcard = g_strdup (vcard);
return new_change;
}
@@ -855,13 +829,13 @@ e_book_backend_change_modify_new (const gchar *vcard)
*
* Return value: A new #GNOME_Evolution_Addressbook_BookChangeItem.
**/
-GNOME_Evolution_Addressbook_BookChangeItem*
-e_book_backend_change_delete_new (const gchar *vcard)
+EDataBookChange *
+e_book_backend_change_delete_new (const char *vcard)
{
- GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc();
+ EDataBookChange *new_change = g_new (EDataBookChange, 1);
- new_change->changeType= GNOME_Evolution_Addressbook_ContactDeleted;
- new_change->vcard = CORBA_string_dup (vcard);
+ new_change->change_type = E_DATA_BOOK_BACKEND_CHANGE_DELETED;
+ new_change->vcard = g_strdup (vcard);
return new_change;
}
diff --git a/addressbook/libedata-book/e-book-backend.h b/addressbook/libedata-book/e-book-backend.h
index 6ece62e8d..27d03b7ce 100644
--- a/addressbook/libedata-book/e-book-backend.h
+++ b/addressbook/libedata-book/e-book-backend.h
@@ -25,9 +25,10 @@
#include <glib.h>
#include <glib-object.h>
#include <libebook/e-contact.h>
-#include <libedata-book/Evolution-DataServer-Addressbook.h>
#include <libedata-book/e-data-book-types.h>
#include <libedata-book/e-data-book.h>
+#include <libedataserver/e-list.h>
+#include <libedataserver/e-source.h>
G_BEGIN_DECLS
diff --git a/addressbook/libedata-book/e-data-book-factory.c b/addressbook/libedata-book/e-data-book-factory.c
index 5f1410a93..a3bd588eb 100644
--- a/addressbook/libedata-book/e-data-book-factory.c
+++ b/addressbook/libedata-book/e-data-book-factory.c
@@ -1,82 +1,87 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2006 OpenedHand Ltd
+ * Copyright (C) 2009 Intel Corporation
*
- * Author:
- * Nat Friedman (nat@ximian.com)
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
*
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * This library 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 this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ross Burton <ross@linux.intel.com>
*/
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
-
+#include <stdlib.h>
#include <string.h>
-
-#include <bonobo-activation/bonobo-activation.h>
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-arg.h>
-#include "libebackend/e-data-server-module.h"
+#include <glib-object.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <libebackend/e-data-server-module.h>
+#include "e-book-backend-factory.h"
#include "e-data-book-factory.h"
+#include "e-data-book.h"
+#include "e-book-backend.h"
+#include "e-book-backend-factory.h"
-#include <backends/groupwise/e-book-backend-groupwise.h>
+static void impl_BookFactory_getBook(EDataBookFactory *factory, const char *IN_uri, DBusGMethodInvocation *context);
+#include "e-data-book-factory-glue.h"
-#define DEFAULT_E_DATA_BOOK_FACTORY_OAF_ID "OAFIID:GNOME_Evolution_DataServer_BookFactory:" BASE_VERSION
+static gchar *nm_dbus_escape_object_path (const gchar *utf8_string);
-static BonoboObjectClass *e_data_book_factory_parent_class;
+static GMainLoop *loop;
+static EDataBookFactory *factory;
+extern DBusGConnection *connection;
-typedef struct {
- gchar *uri;
- GNOME_Evolution_Addressbook_BookListener listener;
-} EDataBookFactoryQueuedRequest;
+/* Convenience macro to test and set a GError/return on failure */
+#define g_set_error_val_if_fail(test, returnval, error, domain, code) G_STMT_START{ \
+ if G_LIKELY (test) {} else { \
+ g_set_error (error, domain, code, #test); \
+ g_warning(#test " failed"); \
+ return (returnval); \
+ } \
+ }G_STMT_END
-struct _EDataBookFactoryPrivate {
- GMutex *map_mutex;
+G_DEFINE_TYPE(EDataBookFactory, e_data_book_factory, G_TYPE_OBJECT);
+
+#define E_DATA_BOOK_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_DATA_BOOK_FACTORY, EDataBookFactoryPrivate))
+struct _EDataBookFactoryPrivate {
+ /* TODO: as the factory is not threaded these locks could be removed */
+ GMutex *backend_lock;
GHashTable *backends;
- GHashTable *active_server_map;
- /* OAFIID of the factory */
- gchar *iid;
+ GMutex *books_lock;
+ /* A hash of object paths for book URIs to EDataBooks */
+ GHashTable *books;
- /* Whether the factory has been registered with OAF yet */
- guint registered : 1;
+ GMutex *connections_lock;
+ /* This is a hash of client addresses to GList* of EDataBooks */
+ GHashTable *connections;
- gint mode;
+ guint exit_timeout;
};
-/* Signal IDs */
-enum {
- LAST_BOOK_GONE,
- LAST_SIGNAL
-};
-
-static guint factory_signals[LAST_SIGNAL];
-
-static gchar *
-e_data_book_factory_canonicalize_uri (const gchar *uri)
+/* Create the EDataBookFactory error quark */
+GQuark
+e_data_book_factory_error_quark (void)
{
- /* FIXME: What do I do here? */
-
- return g_strdup (uri);
-}
-
-static gchar *
-e_data_book_factory_extract_proto_from_uri (const gchar *uri)
-{
- gchar *proto;
- gchar *p;
-
- p = strchr (uri, ':');
-
- if (p == NULL)
- return NULL;
-
- proto = g_malloc0 (p - uri + 1);
-
- strncpy (proto, uri, p - uri);
-
- return proto;
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("e_data_book_factory_error");
+ return quark;
}
/**
@@ -86,7 +91,7 @@ e_data_book_factory_extract_proto_from_uri (const gchar *uri)
*
* Registers @backend_factory with @factory.
**/
-void
+static void
e_data_book_factory_register_backend (EDataBookFactory *book_factory,
EBookBackendFactory *backend_factory)
{
@@ -106,46 +111,6 @@ e_data_book_factory_register_backend (EDataBookFactory *book_factory,
g_strdup (proto), backend_factory);
}
-static void
-out_of_proc_check (gpointer key, gpointer value, gpointer data)
-{
- gboolean *out_of_proc = data;
-
- if ((*out_of_proc))
- return;
-
- *out_of_proc = e_book_backend_has_out_of_proc_clients (value);
-}
-
-/**
- * e_data_book_factory_get_n_backends:
- * @factory: An addressbook factory.
- *
- * Queries the number of running addressbook backends in an addressbook factory.
- *
- * Return value: Number of running backends.
- **/
-gint
-e_data_book_factory_get_n_backends (EDataBookFactory *factory)
-{
- gint n_backends;
- gboolean out_of_proc = FALSE;
-
- g_return_val_if_fail (factory != NULL, -1);
- g_return_val_if_fail (E_IS_DATA_BOOK_FACTORY (factory), -1);
-
- g_mutex_lock (factory->priv->map_mutex);
- g_hash_table_foreach (factory->priv->active_server_map, out_of_proc_check, &out_of_proc);
-
- if (!out_of_proc)
- n_backends = 0;
- else
- n_backends = g_hash_table_size (factory->priv->active_server_map);
- g_mutex_unlock (factory->priv->map_mutex);
-
- return n_backends;
-}
-
/**
* e_data_book_factory_register_backends:
* @book_factory: an #EDataBookFactory
@@ -153,7 +118,7 @@ e_data_book_factory_get_n_backends (EDataBookFactory *factory)
* Register the backends supported by the Evolution Data Server,
* with @book_factory.
**/
-void
+static void
e_data_book_factory_register_backends (EDataBookFactory *book_factory)
{
GList *factories, *f;
@@ -166,72 +131,47 @@ e_data_book_factory_register_backends (EDataBookFactory *book_factory)
}
e_data_server_extension_list_free (factories);
+ e_data_server_module_remove_unused ();
}
static void
-dump_active_server_map_entry (gpointer key, gpointer value, gpointer data)
-{
- gchar *uri;
- EBookBackend *backend;
-
- uri = key;
- backend = E_BOOK_BACKEND (value);
-
- g_message (" %s: %p", uri, (gpointer) backend);
-}
-
-/**
- * e_data_book_factory_dump_active_backends:
- * @factory: an #EDataBookFactory
- *
- * Dump the list of active backends registered with @factory
- * to stdout. This is a debugging function.
- **/
-void
-e_data_book_factory_dump_active_backends (EDataBookFactory *factory)
+e_data_book_factory_class_init (EDataBookFactoryClass *e_data_book_factory_class)
{
- g_message ("Active PAS backends");
-
- g_mutex_lock (factory->priv->map_mutex);
- g_hash_table_foreach (factory->priv->active_server_map,
- dump_active_server_map_entry,
- NULL);
- g_mutex_unlock (factory->priv->map_mutex);
+ g_type_class_add_private (e_data_book_factory_class, sizeof (EDataBookFactoryPrivate));
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (e_data_book_factory_class), &dbus_glib_e_data_book_factory_object_info);
}
-/* Callback used when a backend loses its last connected client */
+/* Instance init */
static void
-backend_last_client_gone_cb (EBookBackend *backend, gpointer data)
+e_data_book_factory_init (EDataBookFactory *factory)
{
- EDataBookFactory *factory;
- ESource *source;
- gchar *uri;
+ factory->priv = E_DATA_BOOK_FACTORY_GET_PRIVATE (factory);
- factory = E_DATA_BOOK_FACTORY (data);
+ factory->priv->backend_lock = g_mutex_new ();
+ factory->priv->backends = g_hash_table_new (g_str_hash, g_str_equal);
- /* Remove the backend from the active server map */
+ factory->priv->books_lock = g_mutex_new ();
+ factory->priv->books = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- source = e_book_backend_get_source (backend);
- if (source)
- uri = e_source_get_uri (source);
- else
- uri = NULL;
-
- if (uri) {
- g_mutex_lock (factory->priv->map_mutex);
- g_hash_table_remove (factory->priv->active_server_map, uri);
- g_mutex_unlock (factory->priv->map_mutex);
- }
+ factory->priv->connections_lock = g_mutex_new ();
+ factory->priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- if (g_hash_table_size (factory->priv->active_server_map) == 0) {
- /* Notify upstream if there are no more backends */
- g_signal_emit (G_OBJECT (factory), factory_signals[LAST_BOOK_GONE], 0);
- }
-
- g_free (uri);
+ e_data_server_module_init ();
+ e_data_book_factory_register_backends (factory);
}
-
+/* TODO: write dispose to kill hash */
+static char *
+e_data_book_factory_extract_proto_from_uri (const char *uri)
+{
+ char *proto, *p;
+ p = strchr (uri, ':');
+ if (p == NULL)
+ return NULL;
+ proto = g_malloc0 (p - uri + 1);
+ strncpy (proto, uri, p - uri);
+ return proto;
+}
static EBookBackendFactory*
e_data_book_factory_lookup_backend_factory (EDataBookFactory *factory,
@@ -239,336 +179,219 @@ e_data_book_factory_lookup_backend_factory (EDataBookFactory *factory,
{
EBookBackendFactory *backend_factory;
gchar *proto;
- gchar *canonical_uri;
-
- g_assert (factory != NULL);
- g_assert (E_IS_DATA_BOOK_FACTORY (factory));
- g_assert (uri != NULL);
- canonical_uri = e_data_book_factory_canonicalize_uri (uri);
- if (canonical_uri == NULL)
- return NULL;
+ g_return_val_if_fail (E_IS_DATA_BOOK_FACTORY (factory), NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
- proto = e_data_book_factory_extract_proto_from_uri (canonical_uri);
+ proto = e_data_book_factory_extract_proto_from_uri (uri);
if (proto == NULL) {
- g_free (canonical_uri);
+ g_warning ("Cannot extract protocol from URI %s", uri);
return NULL;
}
backend_factory = g_hash_table_lookup (factory->priv->backends, proto);
g_free (proto);
- g_free (canonical_uri);
return backend_factory;
}
-static EBookBackend *
-e_data_book_factory_launch_backend (EDataBookFactory *book_factory,
- EBookBackendFactory *backend_factory,
- GNOME_Evolution_Addressbook_BookListener listener,
- const gchar *uri)
+static char *
+make_path_name (const char* uri)
{
- EBookBackend *backend;
+ char *s, *path;
+ s = nm_dbus_escape_object_path (uri);
+ path = g_strdup_printf ("/org/gnome/evolution/dataserver/addressbook/%s", s);
+ g_free (s);
+ return path;
+}
- backend = e_book_backend_factory_new_backend (backend_factory);
- if (!backend)
- return NULL;
+static void
+my_remove (char *key, GObject *dead)
+{
+ g_mutex_lock (factory->priv->books_lock);
+ g_hash_table_remove (factory->priv->books, key);
+ g_mutex_unlock (factory->priv->books_lock);
- g_hash_table_insert (book_factory->priv->active_server_map,
- g_strdup (uri),
- backend);
+ g_free (key);
- g_signal_connect (backend, "last_client_gone",
- G_CALLBACK (backend_last_client_gone_cb),
- book_factory);
+ /* If there are no open books, start a timer to quit */
+ if (factory->priv->exit_timeout == 0 && g_hash_table_size (factory->priv->books) == 0) {
+ factory->priv->exit_timeout = g_timeout_add (10000, (GSourceFunc)g_main_loop_quit, loop);
+ }
+}
- return backend;
+static void
+book_closed_cb (EDataBook *book, const char *client)
+{
+ GList *list;
+
+ list = g_hash_table_lookup (factory->priv->connections, client);
+ list = g_list_remove (list, book);
+ g_hash_table_insert (factory->priv->connections, g_strdup (client), list);
}
-static GNOME_Evolution_Addressbook_Book
-impl_GNOME_Evolution_Addressbook_BookFactory_getBook (PortableServer_Servant servant,
- const CORBA_char *source_xml,
- const GNOME_Evolution_Addressbook_BookListener listener,
- CORBA_Environment *ev)
+static void
+impl_BookFactory_getBook(EDataBookFactory *factory, const char *IN_uri, DBusGMethodInvocation *context)
{
- EDataBookFactory *factory = E_DATA_BOOK_FACTORY (bonobo_object (servant));
- GNOME_Evolution_Addressbook_Book corba_book;
- EBookBackend *backend;
- EDataBook *book = NULL;
+ EDataBook *book;
+ EDataBookFactoryPrivate *priv = factory->priv;
ESource *source;
- gchar *uri;
-
- printf ("impl_GNOME_Evolution_Addressbook_BookFactory_getBook\n");
+ char *path, *sender;
+ GList *list;
- source = e_source_new_from_standalone_xml (source_xml);
- if (!source) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Addressbook_BookFactory_ProtocolNotSupported,
- NULL);
- return CORBA_OBJECT_NIL;
+ if (IN_uri == NULL || IN_uri[0] == '\0') {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_NO_SUCH_BOOK, _("Empty URI")));
+ return;
}
- uri = e_source_get_uri (source);
- if (!uri) {
- g_object_unref (source);
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Addressbook_BookFactory_ProtocolNotSupported,
- NULL);
- return CORBA_OBJECT_NIL;
+ /* Remove a pending exit */
+ if (priv->exit_timeout) {
+ g_source_remove (priv->exit_timeout);
+ priv->exit_timeout = 0;
}
- printf (" + %s\n", uri);
-
- /* Look up the backend and create one if needed */
- g_mutex_lock (factory->priv->map_mutex);
-
- backend = g_hash_table_lookup (factory->priv->active_server_map, uri);
-
- if (!backend) {
- EBookBackendFactory* backend_factory;
-
- backend_factory = e_data_book_factory_lookup_backend_factory (factory, uri);
-
- if (backend_factory == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Addressbook_BookFactory_ProtocolNotSupported,
- NULL);
-
- g_mutex_unlock (factory->priv->map_mutex);
-
- g_free (uri);
- return CORBA_OBJECT_NIL;
- }
- backend = e_data_book_factory_launch_backend (factory, backend_factory, listener, uri);
+ g_mutex_lock (priv->books_lock);
+
+ source = e_source_new_with_absolute_uri ("", IN_uri);
+ path = make_path_name (IN_uri);
+ book = g_hash_table_lookup (priv->books, path);
+ if (book == NULL) {
+ EBookBackend *backend = NULL;
+ backend = e_book_backend_factory_new_backend (e_data_book_factory_lookup_backend_factory (factory, IN_uri));
+ book = e_data_book_new (backend, source, book_closed_cb);
+ e_book_backend_set_mode (backend, 2); /* TODO: very odd */
+ g_hash_table_insert (priv->books, g_strdup(path), book);
+ dbus_g_connection_register_g_object (connection, path, G_OBJECT (book));
+ g_object_weak_ref (G_OBJECT (book), (GWeakNotify)my_remove, g_strdup (path));
+ g_object_unref (backend); /* The book takes a reference to the backend */
+ } else {
+ g_object_ref (book);
}
+ g_object_unref (source);
- g_free (uri);
-
- if (backend) {
- g_mutex_unlock (factory->priv->map_mutex);
+ /* Update the hash of open connections */
+ g_mutex_lock (priv->connections_lock);
+ sender = dbus_g_method_get_sender (context);
+ list = g_hash_table_lookup (priv->connections, sender);
+ list = g_list_prepend (list, book);
+ g_hash_table_insert (priv->connections, sender, list);
+ g_mutex_unlock (priv->connections_lock);
- book = e_data_book_new (backend, source, listener);
+ g_mutex_unlock (priv->books_lock);
- e_book_backend_add_client (backend, book);
- e_book_backend_set_mode (backend, factory->priv->mode);
- corba_book = bonobo_object_corba_objref (BONOBO_OBJECT (book));
- }
- else {
- /* probably need a more descriptive exception here */
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Addressbook_BookFactory_ProtocolNotSupported,
- NULL);
- g_mutex_unlock (factory->priv->map_mutex);
-
- corba_book = CORBA_OBJECT_NIL;
- }
-
- g_object_unref (source);
- if (book)
- printf (" => %p\n", (gpointer) book);
- return corba_book;
+ dbus_g_method_return (context, path);
}
static void
-e_data_book_factory_construct (EDataBookFactory *factory)
+name_owner_changed (DBusGProxy *proxy,
+ const char *name,
+ const char *prev_owner,
+ const char *new_owner,
+ EDataBookFactory *factory)
{
- /* nothing to do here.. */
+ if (strcmp (new_owner, "") == 0 && strcmp (name, prev_owner) == 0) {
+ char *key;
+ GList *list = NULL;
+ g_mutex_lock (factory->priv->connections_lock);
+ if (g_hash_table_lookup_extended (factory->priv->connections, prev_owner, (gpointer)&key, (gpointer)&list)) {
+ g_list_foreach (list, (GFunc)g_object_unref, NULL);
+ g_list_free (list);
+ g_hash_table_remove (factory->priv->connections, prev_owner);
+ }
+ g_mutex_unlock (factory->priv->connections_lock);
+ }
}
-/**
- * e_data_book_factory_new:
- *
- * Create a new #EDataBookFactory.
- *
- * Return value: A new #EDataBookFactory.
- **/
-EDataBookFactory *
-e_data_book_factory_new (void)
+/* Convenience function to print an error and exit */
+static void
+die (const char *prefix, GError *error)
{
- static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
- static PortableServer_POA poa = NULL;
- EDataBookFactory *factory;
-
- g_static_mutex_lock (&mutex);
- if (poa == NULL)
- poa = bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL);
- g_static_mutex_unlock (&mutex);
-
- factory = g_object_new (E_TYPE_DATA_BOOK_FACTORY, "poa", poa, NULL);
-
- e_data_book_factory_construct (factory);
-
- return factory;
+ g_error("%s: %s", prefix, error->message);
+ g_error_free (error);
+ exit(1);
}
-/**
- * e_data_book_factory_activate:
- * @factory: an #EDataBookFactory
- * @iid: the OAF ID of the factory to activate
- *
- * Activates the factory specified by @iid, using Bonobo.
- *
- * Return value: %TRUE for success, %FALSE otherwise.
- **/
-gboolean
-e_data_book_factory_activate (EDataBookFactory *factory, const gchar *iid)
-{
- EDataBookFactoryPrivate *priv;
- Bonobo_RegistrationResult result;
- gchar *tmp_iid;
-
- g_return_val_if_fail (factory != NULL, FALSE);
- g_return_val_if_fail (E_IS_DATA_BOOK_FACTORY (factory), FALSE);
-
- priv = factory->priv;
-
- g_return_val_if_fail (!priv->registered, FALSE);
-
- /* if iid is NULL, use the default factory OAFIID */
- if (iid)
- tmp_iid = g_strdup (iid);
- else
- tmp_iid = g_strdup (DEFAULT_E_DATA_BOOK_FACTORY_OAF_ID);
-
- result = bonobo_activation_active_server_register (tmp_iid, bonobo_object_corba_objref (BONOBO_OBJECT (factory)));
-
- switch (result) {
- case Bonobo_ACTIVATION_REG_SUCCESS:
- priv->registered = TRUE;
- priv->iid = tmp_iid;
- return TRUE;
- case Bonobo_ACTIVATION_REG_NOT_LISTED:
- g_message ("Error registering the PAS factory: not listed");
- break;
- case Bonobo_ACTIVATION_REG_ALREADY_ACTIVE:
- g_message ("Error registering the PAS factory: already active");
- break;
- case Bonobo_ACTIVATION_REG_ERROR:
- default:
- g_message ("Error registering the PAS factory: generic error");
- break;
- }
+#define E_DATA_BOOK_FACTORY_SERVICE_NAME "org.gnome.evolution.dataserver.AddressBook"
- g_free (tmp_iid);
- return FALSE;
-}
-static void
-set_backend_online_status (gpointer key, gpointer value, gpointer data)
+int
+main (int argc, char **argv)
{
- EBookBackend *backend;
+ GError *error = NULL;
+ DBusGProxy *bus_proxy;
+ guint32 request_name_ret;
- backend = E_BOOK_BACKEND (value);
- e_book_backend_set_mode (backend, GPOINTER_TO_INT (data));
-}
+ g_type_init ();
+ if (!g_thread_supported ()) g_thread_init (NULL);
+ dbus_g_thread_init ();
-/**
- * e_data_book_factory_set_backend_mode:
- * @factory: an #EDataBookFactory
- * @mode: a connection status
- *
- * Sets all the backends associated with @factory to be either online
- * or offline. @mode should be passed as 1 for offline, or 2 for
- * online.
- **/
-void
-e_data_book_factory_set_backend_mode (EDataBookFactory *factory, gint mode)
-{
- EDataBookFactoryPrivate *priv = factory->priv;
+ loop = g_main_loop_new (NULL, FALSE);
- g_mutex_lock (priv->map_mutex);
- priv->mode = mode;
- g_hash_table_foreach (priv->active_server_map, set_backend_online_status, GINT_TO_POINTER (priv->mode));
- g_mutex_unlock (priv->map_mutex);
-
-}
-static void
-e_data_book_factory_init (EDataBookFactory *factory)
-{
- GHashTable *active_server_map;
- GHashTable *backends;
+ /* Obtain a connection to the session bus */
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (connection == NULL)
+ die ("Failed to open connection to bus", error);
- active_server_map = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_object_unref);
+ bus_proxy = dbus_g_proxy_new_for_name (connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
- backends = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) NULL);
+ if (!org_freedesktop_DBus_request_name (bus_proxy, E_DATA_BOOK_FACTORY_SERVICE_NAME,
+ 0, &request_name_ret, &error))
+ die ("Failed to get name", error);
- factory->priv = g_new0 (EDataBookFactoryPrivate, 1);
+ if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ g_error ("Got result code %u from requesting name", request_name_ret);
+ exit (1);
+ }
- factory->priv->map_mutex = g_mutex_new();
- factory->priv->active_server_map = active_server_map;
- factory->priv->backends = backends;
- factory->priv->registered = FALSE;
-}
+ factory = g_object_new (E_TYPE_DATA_BOOK_FACTORY, NULL);
+ dbus_g_connection_register_g_object (connection,
+ "/org/gnome/evolution/dataserver/addressbook/BookFactory",
+ G_OBJECT (factory));
-static void
-e_data_book_factory_dispose (GObject *object)
-{
- EDataBookFactory *factory = E_DATA_BOOK_FACTORY (object);
- EDataBookFactoryPrivate *priv = factory->priv;
+ dbus_g_proxy_add_signal (bus_proxy, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (bus_proxy, "NameOwnerChanged", G_CALLBACK (name_owner_changed), factory, NULL);
- g_hash_table_remove_all (priv->active_server_map);
- g_hash_table_remove_all (priv->backends);
+ g_main_loop_run (loop);
- if (priv->registered) {
- bonobo_activation_active_server_unregister (
- priv->iid, bonobo_object_corba_objref (
- BONOBO_OBJECT (factory)));
- priv->registered = FALSE;
- }
+ dbus_g_connection_unref (connection);
- if (G_OBJECT_CLASS (e_data_book_factory_parent_class)->dispose)
- G_OBJECT_CLASS (e_data_book_factory_parent_class)->dispose (object);
+ return 0;
}
-static void
-e_data_book_factory_finalize (GObject *object)
+/* Stolen from http://cvs.gnome.org/viewcvs/NetworkManager/utils/nm-utils.c */
+static gchar *nm_dbus_escape_object_path (const gchar *utf8_string)
{
- EDataBookFactory *factory = E_DATA_BOOK_FACTORY (object);
- EDataBookFactoryPrivate *priv = factory->priv;
+ const gchar *p;
+ GString *string;
- g_mutex_free (priv->map_mutex);
- g_hash_table_destroy (priv->active_server_map);
- g_hash_table_destroy (priv->backends);
- g_free (priv->iid);
- g_free (priv);
+ g_return_val_if_fail (utf8_string != NULL, NULL);
+ g_return_val_if_fail (g_utf8_validate (utf8_string, -1, NULL), NULL);
- if (G_OBJECT_CLASS (e_data_book_factory_parent_class)->finalize)
- G_OBJECT_CLASS (e_data_book_factory_parent_class)->finalize (object);
-}
+ string = g_string_sized_new ((strlen (utf8_string) + 1) * 2);
-static void
-e_data_book_factory_class_init (EDataBookFactoryClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- POA_GNOME_Evolution_Addressbook_BookFactory__epv *epv;
-
- e_data_book_factory_parent_class = g_type_class_peek_parent (klass);
+ for (p = utf8_string; *p != '\0'; p = g_utf8_next_char (p))
+ {
+ gunichar character;
- object_class->dispose = e_data_book_factory_dispose;
- object_class->finalize = e_data_book_factory_finalize;
+ character = g_utf8_get_char (p);
- factory_signals[LAST_BOOK_GONE] =
- g_signal_new ("last_book_gone",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EDataBookFactoryClass, last_book_gone),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ if (((character >= ((gunichar) 'a')) &&
+ (character <= ((gunichar) 'z'))) ||
+ ((character >= ((gunichar) 'A')) &&
+ (character <= ((gunichar) 'Z'))) ||
+ ((character >= ((gunichar) '0')) &&
+ (character <= ((gunichar) '9'))))
+ {
+ g_string_append_c (string, (gchar) character);
+ continue;
+ }
- epv = &klass->epv;
+ g_string_append_printf (string, "_%x_", character);
+ }
- epv->getBook = impl_GNOME_Evolution_Addressbook_BookFactory_getBook;
+ return g_string_free (string, FALSE);
}
-
-BONOBO_TYPE_FUNC_FULL (
- EDataBookFactory,
- GNOME_Evolution_Addressbook_BookFactory,
- BONOBO_TYPE_OBJECT,
- e_data_book_factory)
diff --git a/addressbook/libedata-book/e-data-book-factory.h b/addressbook/libedata-book/e-data-book-factory.h
index 01048c614..d90a061e1 100644
--- a/addressbook/libedata-book/e-data-book-factory.h
+++ b/addressbook/libedata-book/e-data-book-factory.h
@@ -1,15 +1,28 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2006 OpenedHand Ltd
+ * Copyright (C) 2009 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <bonobo/bonobo-object.h>
-#include <libedata-book/Evolution-DataServer-Addressbook.h>
-#include <libedata-book/e-book-backend.h>
-#include <libedata-book/e-book-backend-factory.h>
-
#ifndef __E_DATA_BOOK_FACTORY_H__
#define __E_DATA_BOOK_FACTORY_H__
+#include <glib-object.h>
+
G_BEGIN_DECLS
#define E_TYPE_DATA_BOOK_FACTORY (e_data_book_factory_get_type ())
@@ -22,34 +35,22 @@ G_BEGIN_DECLS
typedef struct _EDataBookFactoryPrivate EDataBookFactoryPrivate;
typedef struct {
- BonoboObject parent_object;
+ GObject parent;
EDataBookFactoryPrivate *priv;
} EDataBookFactory;
typedef struct {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Addressbook_BookFactory__epv epv;
-
- /* Notification signals */
- void (* last_book_gone) (EDataBookFactory *factory);
+ GObjectClass parent;
} EDataBookFactoryClass;
-EDataBookFactory *e_data_book_factory_new (void);
-
-void e_data_book_factory_register_backend (EDataBookFactory *factory,
- EBookBackendFactory *backend_factory);
-
-gint e_data_book_factory_get_n_backends (EDataBookFactory *factory);
-
-void e_data_book_factory_register_backends (EDataBookFactory *factory);
-
-void e_data_book_factory_dump_active_backends (EDataBookFactory *factory);
+typedef enum {
+ E_DATA_BOOK_FACTORY_ERROR_GENERIC
+} EDataBookFactoryError;
-gboolean e_data_book_factory_activate (EDataBookFactory *factory, const gchar *iid);
-void e_data_book_factory_set_backend_mode (EDataBookFactory *factory, gint mode);
+GQuark e_data_book_factory_error_quark (void);
+#define E_DATA_BOOK_FACTORY_ERROR e_data_book_factory_error_quark ()
-GType e_data_book_factory_get_type (void);
+GType e_data_book_factory_get_type (void);
G_END_DECLS
diff --git a/addressbook/libedata-book/e-data-book-types.h b/addressbook/libedata-book/e-data-book-types.h
index 30ced269e..618fb7b72 100644
--- a/addressbook/libedata-book/e-data-book-types.h
+++ b/addressbook/libedata-book/e-data-book-types.h
@@ -1,11 +1,24 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * Blanket header containing the typedefs for object types used in the
- * PAS stuff, so we can disentangle the #includes.
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2006 OpenedHand Ltd
+ * Copyright (C) 2009 Intel Corporation
*
- * Author: Chris Toshok <toshok@ximian.com>
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
*
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * This library 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 this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Chris Toshok <toshok@ximian.com>
+ * Author: Ross Burton <ross@linux.intel.com>
*/
#ifndef __E_DATA_BOOK_TYPES_H__
@@ -31,6 +44,84 @@ typedef struct _EBookBackendSyncClass EBookBackendSyncClass;
typedef struct _EDataBook EDataBook;
typedef struct _EDataBookClass EDataBookClass;
+typedef enum {
+ E_DATA_BOOK_STATUS_SUCCESS,
+ E_DATA_BOOK_STATUS_REPOSITORY_OFFLINE,
+ E_DATA_BOOK_STATUS_PERMISSION_DENIED,
+ E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND,
+ E_DATA_BOOK_STATUS_CONTACTID_ALREADY_EXISTS,
+ E_DATA_BOOK_STATUS_AUTHENTICATION_FAILED,
+ E_DATA_BOOK_STATUS_AUTHENTICATION_REQUIRED,
+ E_DATA_BOOK_STATUS_UNSUPPORTED_FIELD,
+ E_DATA_BOOK_STATUS_UNSUPPORTED_AUTHENTICATION_METHOD,
+ E_DATA_BOOK_STATUS_TLS_NOT_AVAILABLE,
+ E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
+ E_DATA_BOOK_STATUS_BOOK_REMOVED,
+ E_DATA_BOOK_STATUS_OFFLINE_UNAVAILABLE,
+ E_DATA_BOOK_STATUS_SEARCH_SIZE_LIMIT_EXCEEDED,
+ E_DATA_BOOK_STATUS_SEARCH_TIME_LIMIT_EXCEEDED,
+ E_DATA_BOOK_STATUS_INVALID_QUERY,
+ E_DATA_BOOK_STATUS_QUERY_REFUSED,
+ E_DATA_BOOK_STATUS_COULD_NOT_CANCEL,
+ E_DATA_BOOK_STATUS_OTHER_ERROR,
+ E_DATA_BOOK_STATUS_INVALID_SERVER_VERSION,
+ E_DATA_BOOK_STATUS_NO_SPACE,
+} EDataBookStatus;
+
+/* Some hacks so the backends compile without change */
+#define GNOME_Evolution_Addressbook_CallStatus EDataBookStatus
+#define GNOME_Evolution_Addressbook_BookMode EDataBookMode
+
+#define GNOME_Evolution_Addressbook_Success E_DATA_BOOK_STATUS_SUCCESS
+#define GNOME_Evolution_Addressbook_RepositoryOffline E_DATA_BOOK_STATUS_REPOSITORY_OFFLINE
+#define GNOME_Evolution_Addressbook_PermissionDenied E_DATA_BOOK_STATUS_PERMISSION_DENIED
+#define GNOME_Evolution_Addressbook_ContactNotFound E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND
+#define GNOME_Evolution_Addressbook_ContactIdAlreadyExists E_DATA_BOOK_STATUS_CONTACTID_ALREADY_EXISTS
+#define GNOME_Evolution_Addressbook_AuthenticationFailed E_DATA_BOOK_STATUS_AUTHENTICATION_FAILED
+#define GNOME_Evolution_Addressbook_AuthenticationRequired E_DATA_BOOK_STATUS_AUTHENTICATION_REQUIRED
+#define GNOME_Evolution_Addressbook_UnsupportedField E_DATA_BOOK_STATUS_UNSUPPORTED_FIELD
+#define GNOME_Evolution_Addressbook_UnsupportedAuthenticationMethod E_DATA_BOOK_STATUS_UNSUPPORTED_AUTHENTICATION_METHOD
+#define GNOME_Evolution_Addressbook_TLSNotAvailable E_DATA_BOOK_STATUS_TLS_NOT_AVAILABLE
+#define GNOME_Evolution_Addressbook_NoSuchBook E_DATA_BOOK_STATUS_NO_SUCH_BOOK
+#define GNOME_Evolution_Addressbook_BookRemoved E_DATA_BOOK_STATUS_BOOK_REMOVED
+#define GNOME_Evolution_Addressbook_OfflineUnavailable E_DATA_BOOK_STATUS_BOOK_REMOVED
+#define GNOME_Evolution_Addressbook_SearchSizeLimitExceeded E_DATA_BOOK_STATUS_SEARCH_SIZE_LIMIT_EXCEEDED
+#define GNOME_Evolution_Addressbook_SearchTimeLimitExceeded E_DATA_BOOK_STATUS_SEARCH_TIME_LIMIT_EXCEEDED
+#define GNOME_Evolution_Addressbook_InvalidQuery E_DATA_BOOK_STATUS_INVALID_QUERY
+#define GNOME_Evolution_Addressbook_QueryRefused E_DATA_BOOK_STATUS_QUERY_REFUSED
+#define GNOME_Evolution_Addressbook_CouldNotCancel E_DATA_BOOK_STATUS_COULD_NOT_CANCEL
+#define GNOME_Evolution_Addressbook_OtherError E_DATA_BOOK_STATUS_OTHER_ERROR
+#define GNOME_Evolution_Addressbook_InvalidServerVersion E_DATA_BOOK_STATUS_INVALID_SERVER_VERSION
+#define GNOME_Evolution_Addressbook_NoSpace E_DATA_BOOK_STATUS_NO_SPACE
+
+typedef enum {
+ E_DATA_BOOK_MODE_LOCAL,
+ E_DATA_BOOK_MODE_REMOTE,
+ E_DATA_BOOK_MODE_ANY,
+} EDataBookMode;
+
+#define GNOME_Evolution_Addressbook_MODE_LOCAL E_DATA_BOOK_MODE_LOCAL
+#define GNOME_Evolution_Addressbook_MODE_REMOTE E_DATA_BOOK_MODE_REMOTE
+#define GNOME_Evolution_Addressbook_MODE_ANY E_DATA_BOOK_MODE_ANY
+
+typedef enum {
+ E_DATA_BOOK_BACKEND_CHANGE_ADDED,
+ E_DATA_BOOK_BACKEND_CHANGE_DELETED,
+ E_DATA_BOOK_BACKEND_CHANGE_MODIFIED
+} EDataBookChangeType;
+
+typedef struct {
+ EDataBookChangeType change_type;
+ char *vcard;
+} EDataBookChange;
+
+/* Transition typedef */
+typedef EDataBookChange GNOME_Evolution_Addressbook_BookChangeItem;
+
+#define GNOME_Evolution_Addressbook_ContactAdded E_DATA_BOOK_BACKEND_CHANGE_ADDED
+#define GNOME_Evolution_Addressbook_ContactDeleted E_DATA_BOOK_BACKEND_CHANGE_DELETED
+#define GNOME_Evolution_Addressbook_ContactModified E_DATA_BOOK_BACKEND_CHANGE_MODIFIED
+
G_END_DECLS
#endif /* __E_DATA_BOOK_TYPES_H__ */
diff --git a/addressbook/libedata-book/e-data-book-view.c b/addressbook/libedata-book/e-data-book-view.c
index 94ef8a651..c3861dd34 100644
--- a/addressbook/libedata-book/e-data-book-view.c
+++ b/addressbook/libedata-book/e-data-book-view.c
@@ -1,8 +1,23 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * pas-book-view.c
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2006 OpenedHand Ltd
+ * Copyright (C) 2009 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ross Burton <ross@linux.intel.com>
*/
#ifdef HAVE_CONFIG_H
@@ -10,218 +25,244 @@
#endif
#include <string.h>
-#include <glib.h>
-#include <bonobo/bonobo-main.h>
-#include "e-book-backend.h"
-#include "e-book-backend-sexp.h"
+#include <dbus/dbus.h>
+#include <libebook/e-contact.h>
#include "e-data-book-view.h"
-#define d(x)
-
-static BonoboObjectClass *e_data_book_view_parent_class;
+extern DBusGConnection *connection;
-struct _EDataBookViewPrivate {
- GNOME_Evolution_Addressbook_BookViewListener listener;
+static gboolean impl_BookView_start (EDataBookView *view, GError **error);
+static gboolean impl_BookView_stop (EDataBookView *view, GError **error);
+static gboolean impl_BookView_dispose (EDataBookView *view, GError **eror);
-#define DEFAULT_INITIAL_THRESHOLD 20
-#define DEFAULT_THRESHOLD_MAX 3000
+#include "e-data-book-view-glue.h"
- GMutex *mutex;
+static void reset_array (GArray *array);
- GMutex *pending_mutex;
+G_DEFINE_TYPE (EDataBookView, e_data_book_view, G_TYPE_OBJECT);
+#define E_DATA_BOOK_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_DATA_BOOK_VIEW, EDataBookViewPrivate))
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard adds;
- gint next_threshold;
- gint threshold_max;
- gint threshold_min;
-
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard changes;
- CORBA_sequence_GNOME_Evolution_Addressbook_ContactId removes;
+#define THRESHOLD 32
+struct _EDataBookViewPrivate {
+ EDataBook *book;
EBookBackend *backend;
- gchar *card_query;
+
+ char* card_query;
EBookBackendSExp *card_sexp;
+ int max_results;
+
+ gboolean running;
+ GMutex *pending_mutex;
+
+ GArray *adds;
+ GArray *changes;
+ GArray *removes;
+
GHashTable *ids;
+ guint idle_id;
+};
- gint max_results;
+enum {
+ CONTACTS_ADDED,
+ CONTACTS_CHANGED,
+ CONTACTS_REMOVED,
+ STATUS_MESSAGE,
+ COMPLETE,
+ LAST_SIGNAL
};
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void e_data_book_view_dispose (GObject *object);
+static void e_data_book_view_finalize (GObject *object);
+
static void
-view_listener_died_cb (gpointer cnx, gpointer user_data)
+e_data_book_view_class_init (EDataBookViewClass *klass)
{
- EDataBookView *book_view = E_DATA_BOOK_VIEW (user_data);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- if (book_view) {
- e_book_backend_stop_book_view (e_data_book_view_get_backend (book_view), book_view);
- bonobo_object_unref (book_view);
- }
+ object_class->dispose = e_data_book_view_dispose;
+ object_class->finalize = e_data_book_view_finalize;
+
+ signals[CONTACTS_ADDED] =
+ g_signal_new ("contacts-added",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1, G_TYPE_STRV);
+
+ signals[CONTACTS_CHANGED] =
+ g_signal_new ("contacts-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1, G_TYPE_STRV);
+
+ signals[CONTACTS_REMOVED] =
+ g_signal_new ("contacts-removed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1, G_TYPE_STRV);
+
+ signals[STATUS_MESSAGE] =
+ g_signal_new ("status-message",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ signals[COMPLETE] =
+ g_signal_new ("complete",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ g_type_class_add_private (klass, sizeof (EDataBookViewPrivate));
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), &dbus_glib_e_data_book_view_object_info);
}
static void
-send_pending_adds (EDataBookView *book_view, gboolean reset)
+e_data_book_view_init (EDataBookView *book_view)
{
- CORBA_Environment ev;
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard *adds;
-
- adds = &book_view->priv->adds;
- if (adds->_length == 0)
- return;
+ EDataBookViewPrivate *priv = E_DATA_BOOK_VIEW_GET_PRIVATE (book_view);
+ book_view->priv = priv;
- CORBA_exception_init (&ev);
+ priv->running = FALSE;
+ priv->pending_mutex = g_mutex_new ();
- GNOME_Evolution_Addressbook_BookViewListener_notifyContactsAdded (
- book_view->priv->listener, adds, &ev);
+ priv->adds = g_array_sized_new (TRUE, TRUE, sizeof (char*), THRESHOLD);
+ priv->changes = g_array_sized_new (TRUE, TRUE, sizeof (char*), THRESHOLD);
+ priv->removes = g_array_sized_new (TRUE, TRUE, sizeof (char*), THRESHOLD);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("send_pending_adds: Exception signaling BookViewListener!\n");
- }
+ priv->ids = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+}
- CORBA_exception_free (&ev);
+static void
+book_destroyed_cb (gpointer data, GObject *dead)
+{
+ EDataBookView *view = E_DATA_BOOK_VIEW (data);
+ EDataBookViewPrivate *priv = view->priv;
- CORBA_free (adds->_buffer);
- adds->_buffer = NULL;
- adds->_maximum = 0;
- adds->_length = 0;
+ /* The book has just died, so unset the pointer so we don't try and remove a
+ dead weak reference. */
+ view->priv->book = NULL;
- if (reset)
- book_view->priv->next_threshold = book_view->priv->threshold_min;
+ /* If the view is running stop it here. */
+ if (priv->running) {
+ e_book_backend_stop_book_view (priv->backend, view);
+ priv->running = FALSE;
+ }
}
static void
-send_pending_changes (EDataBookView *book_view)
+send_pending_adds (EDataBookView *view)
{
- CORBA_Environment ev;
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard *changes;
+ EDataBookViewPrivate *priv = view->priv;
- changes = &book_view->priv->changes;
- if (changes->_length == 0)
+ if (priv->adds->len == 0)
return;
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookViewListener_notifyContactsChanged (
- book_view->priv->listener, changes, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("send_pending_changes: Exception signaling BookViewListener!\n");
- }
-
- CORBA_exception_free (&ev);
-
- CORBA_free (changes->_buffer);
- changes->_buffer = NULL;
- changes->_maximum = 0;
- changes->_length = 0;
+ g_signal_emit (view, signals[CONTACTS_ADDED], 0, priv->adds->data);
+ reset_array (priv->adds);
}
static void
-send_pending_removes (EDataBookView *book_view)
+send_pending_changes (EDataBookView *view)
{
- CORBA_Environment ev;
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard *removes;
+ EDataBookViewPrivate *priv = view->priv;
- removes = &book_view->priv->removes;
- if (removes->_length == 0)
+ if (priv->changes->len == 0)
return;
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookViewListener_notifyContactsRemoved (
- book_view->priv->listener, removes, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("send_pending_removes: Exception signaling BookViewListener!\n");
- }
+ g_signal_emit (view, signals[CONTACTS_CHANGED], 0, priv->changes->data);
+ reset_array (priv->changes);
+}
- CORBA_exception_free (&ev);
+static void
+send_pending_removes (EDataBookView *view)
+{
+ EDataBookViewPrivate *priv = view->priv;
- CORBA_free (removes->_buffer);
- removes->_buffer = NULL;
- removes->_maximum = 0;
- removes->_length = 0;
-}
+ if (priv->removes->len == 0)
+ return;
-#define MAKE_REALLOC(type) \
-static void \
-CORBA_sequence_ ## type ## _realloc (CORBA_sequence_ ## type *seq, \
- CORBA_unsigned_long new_max) \
-{ \
- type *new_buf; \
- gint i; \
- new_buf = CORBA_sequence_ ## type ## _allocbuf (new_max); \
- for (i = 0; i < seq->_maximum; i ++) \
- new_buf[i] = CORBA_string_dup (seq->_buffer[i]); \
- CORBA_free (seq->_buffer); \
- seq->_buffer = new_buf; \
- seq->_maximum = new_max; \
+ g_signal_emit (view, signals[CONTACTS_REMOVED], 0, priv->removes->data);
+ reset_array (priv->removes);
}
-MAKE_REALLOC (GNOME_Evolution_Addressbook_VCard)
-MAKE_REALLOC (GNOME_Evolution_Addressbook_ContactId)
-
+/*
+ * Queue @vcard to be sent as a change notification. This takes ownership of
+ * @vcard.
+ */
static void
-notify_change (EDataBookView *book_view, const gchar *vcard)
+notify_change (EDataBookView *view, char *vcard)
{
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard *changes;
+ EDataBookViewPrivate *priv = view->priv;
+ send_pending_adds (view);
+ send_pending_removes (view);
- send_pending_adds (book_view, TRUE);
- send_pending_removes (book_view);
+ g_array_append_val (priv->changes, vcard);
+}
- changes = &book_view->priv->changes;
+/*
+ * Queue @id to be sent as a change notification. This takes ownership of @id.
+ */
+static void
+notify_remove (EDataBookView *view, char *id)
+{
+ EDataBookViewPrivate *priv = view->priv;
- if (changes->_length == changes->_maximum) {
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard_realloc (
- changes, 2 * (changes->_maximum + 1));
- }
+ send_pending_adds (view);
+ send_pending_changes (view);
- changes->_buffer[changes->_length++] = CORBA_string_dup (vcard);
+ g_array_append_val (priv->removes, id);
+ g_hash_table_remove (priv->ids, id);
}
+/*
+ * Queue @id and @vcard to be sent as a change notification. This takes ownership of
+ * @vcard but not @id.
+ */
static void
-notify_remove (EDataBookView *book_view, const gchar *id)
+notify_add (EDataBookView *view, const char *id, char *vcard)
{
- CORBA_sequence_GNOME_Evolution_Addressbook_ContactId *removes;
-
- send_pending_adds (book_view, TRUE);
- send_pending_changes (book_view);
-
- removes = &book_view->priv->removes;
+ EDataBookViewPrivate *priv = view->priv;
+ send_pending_changes (view);
+ send_pending_removes (view);
- if (removes->_length == removes->_maximum) {
- CORBA_sequence_GNOME_Evolution_Addressbook_ContactId_realloc (
- removes, 2 * (removes->_maximum + 1));
+ if (priv->adds->len == THRESHOLD) {
+ send_pending_adds (view);
}
-
- removes->_buffer[removes->_length++] = CORBA_string_dup (id);
- g_hash_table_remove (book_view->priv->ids, id);
+ g_array_append_val (priv->adds, vcard);
+ g_hash_table_insert (priv->ids, g_strdup (id),
+ GUINT_TO_POINTER (1));
}
static void
-notify_add (EDataBookView *book_view, const gchar *id, const gchar *vcard)
+reset_array (GArray *array)
{
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard *adds;
- EDataBookViewPrivate *priv = book_view->priv;
-
- send_pending_changes (book_view);
- send_pending_removes (book_view);
-
- adds = &priv->adds;
-
- if (adds->_length == adds->_maximum) {
- send_pending_adds (book_view, FALSE);
-
- adds->_buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf (priv->next_threshold);
- adds->_maximum = priv->next_threshold;
-
- if (priv->next_threshold < priv->threshold_max) {
- priv->next_threshold = MIN (2 * priv->next_threshold,
- priv->threshold_max);
+ gint i = 0;
+ gchar *tmp = NULL;
+
+ /* Free stored strings */
+ for (i = 0; i < array->len; i++)
+ {
+ tmp = g_array_index (array, gchar *, i);
+ g_free (tmp);
}
- }
- adds->_buffer[adds->_length++] = CORBA_string_dup (vcard);
- g_hash_table_insert (book_view->priv->ids, g_strdup (id),
- GUINT_TO_POINTER (1));
+ /* Force the array size to 0 */
+ g_array_set_size (array, 0);
}
/**
@@ -237,24 +278,24 @@ notify_add (EDataBookView *book_view, const gchar *id, const gchar *vcard)
**/
void
e_data_book_view_notify_update (EDataBookView *book_view,
- EContact *contact)
+ EContact *contact)
{
+ EDataBookViewPrivate *priv = book_view->priv;
gboolean currently_in_view, want_in_view;
- const gchar *id=NULL;
+ const gchar *id;
gchar *vcard;
- g_mutex_lock (book_view->priv->pending_mutex);
+ if (!priv->running)
+ return;
+
+ g_mutex_lock (priv->pending_mutex);
id = e_contact_get_const (contact, E_CONTACT_UID);
- if (!id) {
- g_mutex_unlock (book_view->priv->pending_mutex);
- return;
- }
currently_in_view =
- g_hash_table_lookup (book_view->priv->ids, id) != NULL;
- want_in_view = e_book_backend_sexp_match_contact (
- book_view->priv->card_sexp, contact);
+ g_hash_table_lookup (priv->ids, id) != NULL;
+ want_in_view =
+ e_book_backend_sexp_match_contact (priv->card_sexp, contact);
if (want_in_view) {
vcard = e_vcard_to_string (E_VCARD (contact),
@@ -264,15 +305,13 @@ e_data_book_view_notify_update (EDataBookView *book_view,
notify_change (book_view, vcard);
else
notify_add (book_view, id, vcard);
-
- g_free (vcard);
} else {
if (currently_in_view)
- notify_remove (book_view, id);
+ notify_remove (book_view, g_strdup (id));
/* else nothing; we're removing a card that wasn't there */
}
- g_mutex_unlock (book_view->priv->pending_mutex);
+ g_mutex_unlock (priv->pending_mutex);
}
/**
@@ -291,25 +330,22 @@ e_data_book_view_notify_update (EDataBookView *book_view,
void
e_data_book_view_notify_update_vcard (EDataBookView *book_view, gchar *vcard)
{
+ EDataBookViewPrivate *priv = book_view->priv;
gboolean currently_in_view, want_in_view;
- const gchar *id = NULL;
+ const gchar *id;
EContact *contact;
- g_mutex_lock (book_view->priv->pending_mutex);
+ if (!priv->running)
+ return;
+
+ g_mutex_lock (priv->pending_mutex);
contact = e_contact_new_from_vcard (vcard);
id = e_contact_get_const (contact, E_CONTACT_UID);
- if (!id) {
- free (vcard);
- g_object_unref (contact);
- g_mutex_unlock (book_view->priv->pending_mutex);
- return;
- }
-
currently_in_view =
- g_hash_table_lookup (book_view->priv->ids, id) != NULL;
+ g_hash_table_lookup (priv->ids, id) != NULL;
want_in_view =
- e_book_backend_sexp_match_contact (book_view->priv->card_sexp, contact);
+ e_book_backend_sexp_match_contact (priv->card_sexp, contact);
if (want_in_view) {
if (currently_in_view)
@@ -318,12 +354,15 @@ e_data_book_view_notify_update_vcard (EDataBookView *book_view, gchar *vcard)
notify_add (book_view, id, vcard);
} else {
if (currently_in_view)
- notify_remove (book_view, id);
+ notify_remove (book_view, g_strdup (id));
+ else
+ /* else nothing; we're removing a card that wasn't there */
+ g_free (vcard);
}
-
- g_free (vcard);
+ /* Do this last so that id is still valid when notify_ is called */
g_object_unref (contact);
- g_mutex_unlock (book_view->priv->pending_mutex);
+
+ g_mutex_unlock (priv->pending_mutex);
}
/**
@@ -349,20 +388,23 @@ e_data_book_view_notify_update_vcard (EDataBookView *book_view, gchar *vcard)
void
e_data_book_view_notify_update_prefiltered_vcard (EDataBookView *book_view, const gchar *id, gchar *vcard)
{
+ EDataBookViewPrivate *priv = book_view->priv;
gboolean currently_in_view;
- g_mutex_lock (book_view->priv->pending_mutex);
+ if (!priv->running)
+ return;
+
+ g_mutex_lock (priv->pending_mutex);
currently_in_view =
- g_hash_table_lookup (book_view->priv->ids, id) != NULL;
+ g_hash_table_lookup (priv->ids, id) != NULL;
if (currently_in_view)
notify_change (book_view, vcard);
else
notify_add (book_view, id, vcard);
- g_free (vcard);
- g_mutex_unlock (book_view->priv->pending_mutex);
+ g_mutex_unlock (priv->pending_mutex);
}
/**
@@ -374,15 +416,19 @@ e_data_book_view_notify_update_prefiltered_vcard (EDataBookView *book_view, cons
* was removed from @book_view.
**/
void
-e_data_book_view_notify_remove (EDataBookView *book_view,
- const gchar *id)
+e_data_book_view_notify_remove (EDataBookView *book_view, const gchar *id)
{
- g_mutex_lock (book_view->priv->pending_mutex);
+ EDataBookViewPrivate *priv = E_DATA_BOOK_VIEW_GET_PRIVATE (book_view);
+
+ if (!priv->running)
+ return;
- if (g_hash_table_lookup (book_view->priv->ids, id))
- notify_remove (book_view, id);
+ g_mutex_lock (priv->pending_mutex);
- g_mutex_unlock (book_view->priv->pending_mutex);
+ if (g_hash_table_lookup (priv->ids, id))
+ notify_remove (book_view, g_strdup (id));
+
+ g_mutex_unlock (priv->pending_mutex);
}
/**
@@ -395,29 +441,25 @@ e_data_book_view_notify_remove (EDataBookView *book_view,
* in sync with the backend's.
**/
void
-e_data_book_view_notify_complete (EDataBookView *book_view,
- GNOME_Evolution_Addressbook_CallStatus status)
+e_data_book_view_notify_complete (EDataBookView *book_view, EDataBookStatus status)
{
- CORBA_Environment ev;
+ EDataBookViewPrivate *priv = book_view->priv;
+
+ if (!priv->running)
+ return;
- g_mutex_lock (book_view->priv->pending_mutex);
+ g_mutex_lock (priv->pending_mutex);
- send_pending_adds (book_view, TRUE);
+ send_pending_adds (book_view);
send_pending_changes (book_view);
send_pending_removes (book_view);
- g_mutex_unlock (book_view->priv->pending_mutex);
-
- CORBA_exception_init (&ev);
+ g_mutex_unlock (priv->pending_mutex);
- GNOME_Evolution_Addressbook_BookViewListener_notifySequenceComplete (
- book_view->priv->listener, status, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_view_notify_complete: Exception signaling BookViewListener!\n");
- }
+ /* We're done now, so tell the backend to stop? TODO: this is a bit different to
+ how the CORBA backend works... */
- CORBA_exception_free (&ev);
+ g_signal_emit (book_view, signals[COMPLETE], 0, status);
}
/**
@@ -430,86 +472,160 @@ e_data_book_view_notify_complete (EDataBookView *book_view,
* reporting.
**/
void
-e_data_book_view_notify_status_message (EDataBookView *book_view,
- const gchar *message)
+e_data_book_view_notify_status_message (EDataBookView *book_view, const gchar *message)
{
- CORBA_Environment ev;
+ EDataBookViewPrivate *priv = E_DATA_BOOK_VIEW_GET_PRIVATE (book_view);
- CORBA_exception_init (&ev);
+ if (!priv->running)
+ return;
- GNOME_Evolution_Addressbook_BookViewListener_notifyProgress (
- book_view->priv->listener, message, 0, &ev);
+ g_signal_emit (book_view, signals[STATUS_MESSAGE], 0, message);
+}
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_view_notify_status_message: Exception signaling BookViewListener!\n");
- }
+/**
+ * e_data_book_view_new:
+ * @book: The #EDataBook to search
+ * @path: The object path that this book view should have
+ * @card_query: The query as a string
+ * @card_sexp: The query as an #EBookBackendSExp
+ * @max_results: The maximum number of results to return
+ *
+ * Create a new #EDataBookView for the given #EBook, filtering on #card_sexp,
+ * and place it on DBus at the object path #path.
+ */
+EDataBookView *
+e_data_book_view_new (EDataBook *book, const gchar *path, const gchar *card_query, EBookBackendSExp *card_sexp, gint max_results)
+{
+ EDataBookView *view;
+ EDataBookViewPrivate *priv;
- CORBA_exception_free (&ev);
+ view = g_object_new (E_TYPE_DATA_BOOK_VIEW, NULL);
+ priv = view->priv;
+
+ priv->book = book;
+ /* Attach a weak reference to the book, so if it dies the book view is destroyed too */
+ g_object_weak_ref (G_OBJECT (priv->book), book_destroyed_cb, view);
+ priv->backend = g_object_ref (e_data_book_get_backend (book));
+ priv->card_query = g_strdup (card_query);
+ priv->card_sexp = card_sexp;
+ priv->max_results = max_results;
+
+ dbus_g_connection_register_g_object (connection, path, G_OBJECT (view));
+
+ return view;
}
static void
-e_data_book_view_construct (EDataBookView *book_view,
- EBookBackend *backend,
- GNOME_Evolution_Addressbook_BookViewListener listener,
- const gchar *card_query,
- EBookBackendSExp *card_sexp,
- gint max_results)
+e_data_book_view_dispose (GObject *object)
{
- EDataBookViewPrivate *priv;
- CORBA_Environment ev;
+ EDataBookView *book_view = E_DATA_BOOK_VIEW (object);
+ EDataBookViewPrivate *priv = book_view->priv;
- g_return_if_fail (book_view != NULL);
- g_return_if_fail (listener != CORBA_OBJECT_NIL);
+ if (priv->book) {
+ /* Remove the weak reference */
+ g_object_weak_unref (G_OBJECT (priv->book), book_destroyed_cb, book_view);
+ priv->book = NULL;
+ }
- priv = book_view->priv;
+ if (priv->backend) {
+ e_book_backend_remove_book_view (priv->backend, book_view);
+ g_object_unref (priv->backend);
+ priv->backend = NULL;
+ }
- CORBA_exception_init (&ev);
+ if (priv->card_sexp) {
+ g_object_unref (priv->card_sexp);
+ priv->card_sexp = NULL;
+ }
- priv->listener = bonobo_object_dup_ref (listener, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("Unable to duplicate listener object in pas-book-view.c\n");
- CORBA_exception_free (&ev);
- return;
+ if (priv->idle_id) {
+ g_source_remove (priv->idle_id);
+ priv->idle_id = 0;
}
- CORBA_exception_free (&ev);
+ G_OBJECT_CLASS (e_data_book_view_parent_class)->dispose (object);
+}
- priv->backend = backend;
- priv->card_query = g_strdup (card_query);
- priv->card_sexp = card_sexp;
- priv->max_results = max_results;
+static void
+e_data_book_view_finalize (GObject *object)
+{
+ EDataBookView *book_view = E_DATA_BOOK_VIEW (object);
+ EDataBookViewPrivate *priv = book_view->priv;
- ORBit_small_listen_for_broken (e_data_book_view_get_listener (book_view), G_CALLBACK (view_listener_died_cb), book_view);
+ reset_array (priv->adds);
+ reset_array (priv->changes);
+ reset_array (priv->removes);
+ g_array_free (priv->adds, TRUE);
+ g_array_free (priv->changes, TRUE);
+ g_array_free (priv->removes, TRUE);
+
+ g_free (priv->card_query);
+
+ g_mutex_free (priv->pending_mutex);
+
+ g_hash_table_destroy (priv->ids);
+
+ G_OBJECT_CLASS (e_data_book_view_parent_class)->finalize (object);
}
-static void
-impl_GNOME_Evolution_Addressbook_BookView_start (PortableServer_Servant servant,
- CORBA_Environment *ev)
+static gboolean
+bookview_idle_start (gpointer data)
{
- EDataBookView *view = E_DATA_BOOK_VIEW (bonobo_object (servant));
+ EDataBookView *book_view = data;
+
+ book_view->priv->running = TRUE;
+ book_view->priv->idle_id = 0;
- e_book_backend_start_book_view (e_data_book_view_get_backend (view), view);
+ e_book_backend_start_book_view (book_view->priv->backend, book_view);
+ return FALSE;
}
-static void
-impl_GNOME_Evolution_Addressbook_BookView_stop (PortableServer_Servant servant,
- CORBA_Environment *ev)
+static gboolean
+impl_BookView_start (EDataBookView *book_view, GError **error)
{
- EDataBookView *view = E_DATA_BOOK_VIEW (bonobo_object (servant));
+ book_view->priv->idle_id = g_idle_add (bookview_idle_start, book_view);
+ return TRUE;
+}
+
+static gboolean
+bookview_idle_stop (gpointer data)
+{
+ EDataBookView *book_view = data;
+
+ e_book_backend_stop_book_view (book_view->priv->backend, book_view);
- e_book_backend_stop_book_view (e_data_book_view_get_backend (view), view);
+ book_view->priv->running = FALSE;
+ book_view->priv->idle_id = 0;
+
+ return FALSE;
}
-static void
-impl_GNOME_Evolution_Addressbook_BookView_dispose (PortableServer_Servant servant,
- CORBA_Environment *ev)
+static gboolean
+impl_BookView_stop (EDataBookView *book_view, GError **error)
{
- EDataBookView *view = E_DATA_BOOK_VIEW (bonobo_object (servant));
+ if (book_view->priv->idle_id)
+ g_source_remove (book_view->priv->idle_id);
- d(printf("in impl_GNOME_Evolution_Addressbook_BookView_dispose\n"));
- ORBit_small_unlisten_for_broken (e_data_book_view_get_listener (view), G_CALLBACK (view_listener_died_cb));
+ book_view->priv->idle_id = g_idle_add (bookview_idle_stop, book_view);
+ return TRUE;
+}
- bonobo_object_unref (view);
+static gboolean
+impl_BookView_dispose (EDataBookView *book_view, GError **eror)
+{
+ g_object_unref (book_view);
+
+ return TRUE;
+}
+
+void
+e_data_book_view_set_thresholds (EDataBookView *book_view,
+ int minimum_grouping_threshold,
+ int maximum_grouping_threshold)
+{
+ g_return_if_fail (E_IS_DATA_BOOK_VIEW (book_view));
+
+ g_debug ("e_data_book_view_set_thresholds does nothing in eds-dbus");
}
/**
@@ -524,7 +640,7 @@ impl_GNOME_Evolution_Addressbook_BookView_dispose (PortableServer_Servant servan
const gchar *
e_data_book_view_get_card_query (EDataBookView *book_view)
{
- g_return_val_if_fail (book_view, NULL);
+ g_return_val_if_fail (E_IS_DATA_BOOK_VIEW (book_view), NULL);
return book_view->priv->card_query;
}
@@ -580,93 +696,6 @@ e_data_book_view_get_backend (EDataBookView *book_view)
}
/**
- * e_data_book_view_get_mutex:
- * @book_view: an #EDataBookView
- *
- * Gets the internal mutex of @book_view.
- *
- * Return value: The #GMutex for @book_view.
- **/
-GMutex*
-e_data_book_view_get_mutex (EDataBookView *book_view)
-{
- g_return_val_if_fail (E_IS_DATA_BOOK_VIEW (book_view), NULL);
-
- return book_view->priv->mutex;
-}
-
-/**
- * e_data_book_view_get_listener:
- * @book_view: an #EDataBookView
- *
- * Gets the CORBA listener that @book_view is dispatching
- * events to.
- *
- * Return value: The CORBA book view listener.
- **/
-GNOME_Evolution_Addressbook_BookViewListener
-e_data_book_view_get_listener (EDataBookView *book_view)
-{
- g_return_val_if_fail (E_IS_DATA_BOOK_VIEW (book_view), CORBA_OBJECT_NIL);
-
- return book_view->priv->listener;
-}
-
-/**
- * e_data_book_view_set_thresholds:
- * @book_view: an #EDataBookView
- * @minimum_grouping_threshold: the minimum threshold
- * @maximum_grouping_threshold: the maximum threshold
- *
- * Sets the thresholds for grouping add events together
- * for efficiency reasons. The minimum threshold specifies
- * how many adds must be grouped (as long as there are
- * pending adds), and the maximum threshold specifies
- * the maximum number of adds that can be grouped.
- **/
-void
-e_data_book_view_set_thresholds (EDataBookView *book_view,
- gint minimum_grouping_threshold,
- gint maximum_grouping_threshold)
-{
- book_view->priv->threshold_min = minimum_grouping_threshold;
- book_view->priv->threshold_max = maximum_grouping_threshold;
-}
-
-/**
- * e_data_book_view_new:
- * @backend: an #EBookBackend to view
- * @listener: a CORBA listener to reveive notifications
- * @card_query: an s-expression representing the query
- * @card_sexp:
- * @max_results: the maximum number of results for the query
- *
- * Return value: A new #EDataBookView.
- **/
-EDataBookView *
-e_data_book_view_new (EBookBackend *backend,
- GNOME_Evolution_Addressbook_BookViewListener listener,
- const gchar *card_query,
- EBookBackendSExp *card_sexp,
- gint max_results)
-{
- static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
- static PortableServer_POA poa = NULL;
- EDataBookView *book_view;
-
- g_static_mutex_lock (&mutex);
- if (poa == NULL)
- poa = bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_OBJECT, NULL);
- g_static_mutex_unlock (&mutex);
-
- book_view = g_object_new (E_TYPE_DATA_BOOK_VIEW, "poa", poa, NULL);
-
- e_data_book_view_construct (book_view, backend, listener, card_query, card_sexp, max_results);
-
- return book_view;
-}
-
-/**
* e_data_book_view_ref
* @book_view: an #EBookView
*
@@ -676,7 +705,7 @@ e_data_book_view_new (EBookBackend *backend,
void
e_data_book_view_ref (EDataBookView *book_view)
{
- bonobo_object_ref (book_view);
+ g_object_ref (book_view);
}
/**
@@ -689,78 +718,5 @@ e_data_book_view_ref (EDataBookView *book_view)
void
e_data_book_view_unref (EDataBookView *book_view)
{
- bonobo_object_unref (book_view);
+ g_object_unref (book_view);
}
-
-static void
-e_data_book_view_dispose (GObject *object)
-{
- EDataBookView *book_view = E_DATA_BOOK_VIEW (object);
-
- d(printf ("disposing of EDataBookView\n"));
- if (book_view->priv) {
- bonobo_object_release_unref (book_view->priv->listener, NULL);
-
- if (book_view->priv->adds._buffer)
- CORBA_free (book_view->priv->adds._buffer);
- if (book_view->priv->changes._buffer)
- CORBA_free (book_view->priv->changes._buffer);
- if (book_view->priv->removes._buffer)
- CORBA_free (book_view->priv->removes._buffer);
-
- g_free (book_view->priv->card_query);
- g_object_unref (book_view->priv->card_sexp);
-
- g_mutex_free (book_view->priv->pending_mutex);
-
- g_mutex_free (book_view->priv->mutex);
-
- g_hash_table_destroy (book_view->priv->ids);
-
- g_free (book_view->priv);
- book_view->priv = NULL;
- }
-
- if (G_OBJECT_CLASS (e_data_book_view_parent_class)->dispose)
- G_OBJECT_CLASS (e_data_book_view_parent_class)->dispose (object);
-}
-
-static void
-e_data_book_view_class_init (EDataBookViewClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- POA_GNOME_Evolution_Addressbook_BookView__epv *epv;
-
- e_data_book_view_parent_class = g_type_class_peek_parent (klass);
-
- object_class->dispose = e_data_book_view_dispose;
-
- epv = &klass->epv;
-
- epv->start = impl_GNOME_Evolution_Addressbook_BookView_start;
- epv->stop = impl_GNOME_Evolution_Addressbook_BookView_stop;
- epv->dispose = impl_GNOME_Evolution_Addressbook_BookView_dispose;
-
-}
-
-static void
-e_data_book_view_init (EDataBookView *book_view)
-{
- book_view->priv = g_new0 (EDataBookViewPrivate, 1);
-
- book_view->priv->pending_mutex = g_mutex_new();
- book_view->priv->mutex = g_mutex_new();
-
- book_view->priv->threshold_min = DEFAULT_INITIAL_THRESHOLD;
- book_view->priv->threshold_max = DEFAULT_THRESHOLD_MAX;
- book_view->priv->next_threshold = book_view->priv->threshold_min;
-
- book_view->priv->ids = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, NULL);
-}
-
-BONOBO_TYPE_FUNC_FULL (
- EDataBookView,
- GNOME_Evolution_Addressbook_BookView,
- BONOBO_TYPE_OBJECT,
- e_data_book_view)
diff --git a/addressbook/libedata-book/e-data-book-view.h b/addressbook/libedata-book/e-data-book-view.h
index 1bdfafac1..160a44338 100644
--- a/addressbook/libedata-book/e-data-book-view.h
+++ b/addressbook/libedata-book/e-data-book-view.h
@@ -1,23 +1,35 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * A wrapper object which exports the GNOME_Evolution_Addressbook_Book CORBA interface
- * and which maintains a request queue.
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2006 OpenedHand Ltd
+ * Copyright (C) 2009 Intel Corporation
*
- * Author:
- * Nat Friedman (nat@ximian.com)
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
*
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * This library 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 this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Nat Friedman <nat@ximian.com>
+ * Author: Ross Burton <ross@linux.intel.com>
*/
#ifndef __E_DATA_BOOK_VIEW_H__
#define __E_DATA_BOOK_VIEW_H__
-#include <bonobo/bonobo-object.h>
#include <glib.h>
#include <glib-object.h>
#include <libebook/e-contact.h>
-#include <libedata-book/Evolution-DataServer-Addressbook.h>
#include <libedata-book/e-data-book-types.h>
+#include <libedata-book/e-book-backend.h>
+#include <libedata-book/e-book-backend-sexp.h>
G_BEGIN_DECLS
@@ -31,21 +43,19 @@ G_BEGIN_DECLS
typedef struct _EDataBookViewPrivate EDataBookViewPrivate;
struct _EDataBookView {
- BonoboObject parent_object;
+ GObject parent;
EDataBookViewPrivate *priv;
};
struct _EDataBookViewClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Addressbook_BookView__epv epv;
+ GObjectClass parent;
};
-EDataBookView *e_data_book_view_new (EBookBackend *backend,
- GNOME_Evolution_Addressbook_BookViewListener listener,
- const gchar *card_query,
- EBookBackendSExp *card_sexp,
- gint max_results);
+EDataBookView *e_data_book_view_new (EDataBook *book,
+ const gchar *path,
+ const gchar *card_query,
+ EBookBackendSExp *card_sexp,
+ gint max_results);
void e_data_book_view_set_thresholds (EDataBookView *book_view,
gint minimum_grouping_threshold,
@@ -55,9 +65,6 @@ const gchar * e_data_book_view_get_card_query (EDataBookView
EBookBackendSExp* e_data_book_view_get_card_sexp (EDataBookView *book_view);
gint e_data_book_view_get_max_results (EDataBookView *book_view);
EBookBackend* e_data_book_view_get_backend (EDataBookView *book_view);
-GNOME_Evolution_Addressbook_BookViewListener e_data_book_view_get_listener (EDataBookView *book_view);
-GMutex* e_data_book_view_get_mutex (EDataBookView *book_view);
-
void e_data_book_view_notify_update (EDataBookView *book_view,
EContact *contact);
@@ -70,7 +77,7 @@ void e_data_book_view_notify_update_prefiltered_vcard (EDataBookView
void e_data_book_view_notify_remove (EDataBookView *book_view,
const gchar *id);
void e_data_book_view_notify_complete (EDataBookView *book_view,
- GNOME_Evolution_Addressbook_CallStatus);
+ EDataBookStatus status);
void e_data_book_view_notify_status_message (EDataBookView *book_view,
const gchar *message);
void e_data_book_view_ref (EDataBookView *book_view);
diff --git a/addressbook/libedata-book/e-data-book.c b/addressbook/libedata-book/e-data-book.c
index 224cd8974..4d770cf81 100644
--- a/addressbook/libedata-book/e-data-book.c
+++ b/addressbook/libedata-book/e-data-book.c
@@ -1,1012 +1,697 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * pas-book.c
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2006 OpenedHand Ltd
+ * Copyright (C) 2009 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ross Burton <ross@linux.intel.com>
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-arg.h>
-#include "libedataserver/e-list.h"
-#include <libebook/e-contact.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include "e-data-book-enumtypes.h"
+#include "e-data-book-factory.h"
+#include "e-data-book.h"
#include "e-data-book-view.h"
-#include "e-book-backend.h"
#include "e-book-backend-sexp.h"
-#include "e-data-book.h"
-
-static BonoboObjectClass *e_data_book_parent_class;
-POA_GNOME_Evolution_Addressbook_Book__vepv e_data_book_vepv;
-
-struct _EDataBookPrivate {
- EBookBackend *backend;
- GNOME_Evolution_Addressbook_BookListener listener;
- ESource *source;
+#include "opid.h"
+
+DBusGConnection *connection;
+
+/* DBus glue */
+static void impl_AddressBook_Book_open(EDataBook *book, gboolean only_if_exists, DBusGMethodInvocation *context);
+static void impl_AddressBook_Book_remove(EDataBook *book, DBusGMethodInvocation *context);
+static void impl_AddressBook_Book_getContact(EDataBook *book, const char *IN_uid, DBusGMethodInvocation *context);
+static void impl_AddressBook_Book_getContactList(EDataBook *book, const char *query, DBusGMethodInvocation *context);
+static void impl_AddressBook_Book_authenticateUser(EDataBook *book, const char *IN_user, const char *IN_passwd, const char *IN_auth_method, DBusGMethodInvocation *context);
+static void impl_AddressBook_Book_addContact(EDataBook *book, const char *IN_vcard, DBusGMethodInvocation *context);
+static void impl_AddressBook_Book_modifyContact(EDataBook *book, const char *IN_vcard, DBusGMethodInvocation *context);
+static void impl_AddressBook_Book_removeContacts(EDataBook *book, const char **IN_uids, DBusGMethodInvocation *context);
+static gboolean impl_AddressBook_Book_getStaticCapabilities(EDataBook *book, char **OUT_capabilities, GError **error);
+static void impl_AddressBook_Book_getSupportedFields(EDataBook *book, DBusGMethodInvocation *context);
+static void impl_AddressBook_Book_getRequiredFields(EDataBook *book, DBusGMethodInvocation *context);
+static void impl_AddressBook_Book_getSupportedAuthMethods(EDataBook *book, DBusGMethodInvocation *context);
+static void impl_AddressBook_Book_getBookView (EDataBook *book, const char *search, const guint max_results, DBusGMethodInvocation *context);
+static void impl_AddressBook_Book_getChanges(EDataBook *book, const char *IN_change_id, DBusGMethodInvocation *context);
+static gboolean impl_AddressBook_Book_cancelOperation(EDataBook *book, GError **error);
+static void impl_AddressBook_Book_close(EDataBook *book, DBusGMethodInvocation *context);
+#include "e-data-book-glue.h"
+
+static void return_status_and_list (guint32 opid, EDataBookStatus status, GList *list, gboolean free_data);
+
+enum {
+ WRITABLE,
+ CONNECTION,
+ AUTH_REQUIRED,
+ LAST_SIGNAL
};
-static void
-impl_GNOME_Evolution_Addressbook_Book_open (PortableServer_Servant servant,
- const CORBA_long opid,
- const CORBA_boolean only_if_exists,
- CORBA_Environment *ev)
-{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
-
- printf ("impl_GNOME_Evolution_Addressbook_Book_open (%p)\n", (gpointer) book);
-
- e_book_backend_open (e_data_book_get_backend (book), book, opid, only_if_exists);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_remove (PortableServer_Servant servant,
- const CORBA_long opid,
- CORBA_Environment *ev)
-{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
-
- printf ("impl_GNOME_Evolution_Addressbook_Book_remove\n");
-
- e_book_backend_remove (e_data_book_get_backend (book), book, opid);
-}
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static GThreadPool *op_pool;
+
+typedef enum {
+ OP_OPEN,
+ OP_AUTHENTICATE,
+ OP_ADD_CONTACT,
+ OP_GET_CONTACT,
+ OP_GET_CONTACTS,
+ OP_MODIFY_CONTACT,
+ OP_REMOVE_CONTACTS,
+ OP_GET_CHANGES,
+} OperationID;
+
+typedef struct {
+ OperationID op;
+ guint32 id; /* operation id */
+ EDataBook *book; /* book */
+ union {
+ /* OP_OPEN */
+ gboolean only_if_exists;
+ /* OP_AUTHENTICATE */
+ struct {
+ char *username;
+ char *password;
+ char *method;
+ } auth;
+ /* OP_ADD_CONTACT */
+ /* OP_MODIFY_CONTACT */
+ char *vcard;
+ /* OP_GET_CONTACT */
+ char *uid;
+ /* OP_GET_CONTACTS */
+ char *query;
+ /* OP_MODIFY_CONTACT */
+ char **vcards;
+ /* OP_REMOVE_CONTACTS */
+ GList *ids;
+ /* OP_GET_CHANGES */
+ char *change_id;
+ };
+} OperationData;
static void
-impl_GNOME_Evolution_Addressbook_Book_getContact (PortableServer_Servant servant,
- const CORBA_long opid,
- const CORBA_char *id,
- CORBA_Environment *ev)
-{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
-
- printf ("impl_GNOME_Evolution_Addressbook_Book_getContact\n");
+operation_thread (gpointer data, gpointer user_data)
+{
+ OperationData *op = data;
+ EBookBackend *backend;
+
+ backend = e_data_book_get_backend (op->book);
+
+ switch (op->op) {
+ case OP_OPEN:
+ e_book_backend_open (backend, op->book, op->id, op->only_if_exists);
+ break;
+ case OP_AUTHENTICATE:
+ e_book_backend_authenticate_user (backend, op->book, op->id,
+ op->auth.username,
+ op->auth.password,
+ op->auth.method);
+ g_free (op->auth.username);
+ g_free (op->auth.password);
+ g_free (op->auth.method);
+ break;
+ case OP_ADD_CONTACT:
+ e_book_backend_create_contact (backend, op->book, op->id, op->vcard);
+ g_free (op->vcard);
+ break;
+ case OP_GET_CONTACT:
+ e_book_backend_get_contact (backend, op->book, op->id, op->uid);
+ g_free (op->uid);
+ break;
+ case OP_GET_CONTACTS:
+ e_book_backend_get_contact_list (backend, op->book, op->id, op->query);
+ g_free (op->query);
+ break;
+ case OP_MODIFY_CONTACT:
+ e_book_backend_modify_contact (backend, op->book, op->id, op->vcard);
+ g_free (op->vcard);
+ break;
+ case OP_REMOVE_CONTACTS:
+ e_book_backend_remove_contacts (backend, op->book, op->id, op->ids);
+ g_list_foreach (op->ids, (GFunc)g_free, NULL);
+ g_list_free (op->ids);
+ break;
+ case OP_GET_CHANGES:
+ e_book_backend_get_changes (backend, op->book, op->id, op->change_id);
+ g_free (op->change_id);
+ break;
+ }
- e_book_backend_get_contact (e_data_book_get_backend (book), book, opid, id);
+ g_object_unref (op->book);
+ g_slice_free (OperationData, op);
}
-static void
-impl_GNOME_Evolution_Addressbook_Book_getContactList (PortableServer_Servant servant,
- const CORBA_long opid,
- const CORBA_char *query,
- CORBA_Environment *ev)
+static OperationData *
+op_new (OperationID op, EDataBook *book, DBusGMethodInvocation *context)
{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
+ OperationData *data;
- printf ("impl_GNOME_Evolution_Addressbook_Book_getContactList\n");
+ data = g_slice_new0 (OperationData);
+ data->op = op;
+ data->book = g_object_ref (book);
+ data->id = opid_store (context);
- e_book_backend_get_contact_list (e_data_book_get_backend (book), book, opid, query);
+ return data;
}
-static void
-impl_GNOME_Evolution_Addressbook_Book_authenticateUser (PortableServer_Servant servant,
- const CORBA_long opid,
- const gchar * user,
- const gchar * passwd,
- const gchar * auth_method,
- CORBA_Environment *ev)
-{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
- e_book_backend_authenticate_user (e_data_book_get_backend (book), book,
- opid, user, passwd, auth_method);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_addContact (PortableServer_Servant servant,
- const CORBA_long opid,
- const CORBA_char *vcard,
- CORBA_Environment *ev)
+/* Create the EDataBook error quark */
+GQuark
+e_data_book_error_quark (void)
{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
-
- e_book_backend_create_contact (e_data_book_get_backend (book), book, opid, vcard);
+ static GQuark quark = 0;
+ if (G_UNLIKELY (quark == 0))
+ quark = g_quark_from_static_string ("e-data-book-error");
+ return quark;
}
-static void
-impl_GNOME_Evolution_Addressbook_Book_removeContacts (PortableServer_Servant servant,
- const CORBA_long opid,
- const GNOME_Evolution_Addressbook_ContactIdList *ids,
- CORBA_Environment *ev)
-{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
- gint i;
- GList *id_list = NULL;
-
- for (i = 0; i < ids->_length; i ++)
- id_list = g_list_append (id_list, ids->_buffer[i]);
- e_book_backend_remove_contacts (e_data_book_get_backend (book), book, opid, id_list);
-
- g_list_free (id_list);
-}
+/* Generate the GObject boilerplate */
+G_DEFINE_TYPE(EDataBook, e_data_book, G_TYPE_OBJECT)
static void
-impl_GNOME_Evolution_Addressbook_Book_modifyContact (PortableServer_Servant servant,
- const CORBA_long opid,
- const CORBA_char *vcard,
- CORBA_Environment *ev)
+e_data_book_dispose (GObject *object)
{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
-
- e_book_backend_modify_contact (e_data_book_get_backend (book), book, opid, vcard);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_getBookView (PortableServer_Servant servant,
- const CORBA_long opid,
- const GNOME_Evolution_Addressbook_BookViewListener listener,
- const CORBA_char *search,
- const GNOME_Evolution_Addressbook_stringlist* requested_fields,
- const CORBA_long max_results,
- CORBA_Environment *ev)
-{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
- EBookBackend *backend = e_data_book_get_backend (book);
- EBookBackendSExp *card_sexp;
- EDataBookView *view;
-
- g_warning ("impl_GNOME_Evolution_Addressbook_Book_getBookView (%s)\n", search);
-
- /* we handle this entirely here, since it doesn't require any
- backend involvement now that we have e_data_book_view_start to
- actually kick off the search. */
+ EDataBook *book = E_DATA_BOOK (object);
- card_sexp = e_book_backend_sexp_new (search);
- if (!card_sexp) {
- e_data_book_respond_get_book_view (book, opid, GNOME_Evolution_Addressbook_InvalidQuery, NULL);
- return;
+ if (book->backend) {
+ g_object_unref (book->backend);
+ book->backend = NULL;
}
- /* XXX still need to add requested_fields here */
- view = e_data_book_view_new (backend, listener, search, card_sexp, max_results);
-
- if (!view) {
- g_object_unref (card_sexp);
- e_data_book_respond_get_book_view (book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);
- return;
+ if (book->source) {
+ g_object_unref (book->source);
+ book->source = NULL;
}
- e_book_backend_add_book_view (backend, view);
-
- e_data_book_respond_get_book_view (book, opid, GNOME_Evolution_Addressbook_Success, view);
+ G_OBJECT_CLASS (e_data_book_parent_class)->dispose (object);
}
static void
-impl_GNOME_Evolution_Addressbook_Book_getChanges (PortableServer_Servant servant,
- const CORBA_long opid,
- const CORBA_char *change_id,
- CORBA_Environment *ev)
+e_data_book_class_init (EDataBookClass *e_data_book_class)
{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
+ GObjectClass *object_class = G_OBJECT_CLASS (e_data_book_class);
- e_book_backend_get_changes (e_data_book_get_backend (book), book, opid, change_id);
-}
-
-static gchar *
-impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
- gchar *temp;
- gchar *ret_val;
-
- temp = e_book_backend_get_static_capabilities (book->priv->backend);
- ret_val = CORBA_string_dup(temp);
- g_free(temp);
- return ret_val;
-}
+ object_class->dispose = e_data_book_dispose;
+ signals[WRITABLE] =
+ g_signal_new ("writable",
+ G_OBJECT_CLASS_TYPE (e_data_book_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ signals[CONNECTION] =
+ g_signal_new ("connection",
+ G_OBJECT_CLASS_TYPE (e_data_book_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ signals[AUTH_REQUIRED] =
+ g_signal_new ("auth-required",
+ G_OBJECT_CLASS_TYPE (e_data_book_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (e_data_book_class), &dbus_glib_e_data_book_object_info);
+
+ dbus_g_error_domain_register (E_DATA_BOOK_ERROR, NULL, E_TYPE_DATA_BOOK_STATUS);
+
+ op_pool = g_thread_pool_new (operation_thread, NULL, 10, FALSE, NULL);
+ /* Kill threads which don't do anything for 10 seconds */
+ g_thread_pool_set_max_idle_time (10 * 1000);
+}
+
+/* Instance init */
static void
-impl_GNOME_Evolution_Addressbook_Book_getRequiredFields (PortableServer_Servant servant,
- const CORBA_long opid,
- CORBA_Environment *ev)
-
+e_data_book_init (EDataBook *ebook)
{
-
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
-
- e_book_backend_get_required_fields (e_data_book_get_backend (book), book, opid);
-
}
-static void
-impl_GNOME_Evolution_Addressbook_Book_getSupportedFields (PortableServer_Servant servant,
- const CORBA_long opid,
- CORBA_Environment *ev)
+EDataBook *
+e_data_book_new (EBookBackend *backend, ESource *source, EDataBookClosedCallback closed_cb)
{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
-
- e_book_backend_get_supported_fields (e_data_book_get_backend (book), book, opid);
+ EDataBook *book;
+ book = g_object_new (E_TYPE_DATA_BOOK, NULL);
+ book->backend = g_object_ref (backend);
+ book->source = g_object_ref (source);
+ book->closed_cb = closed_cb;
+ return book;
}
-static void
-impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods (PortableServer_Servant servant,
- const CORBA_long opid,
- CORBA_Environment *ev)
+ESource*
+e_data_book_get_source (EDataBook *book)
{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
+ g_return_val_if_fail (book != NULL, NULL);
- e_book_backend_get_supported_auth_methods (e_data_book_get_backend (book), book, opid);
+ return book->source;
}
-static GNOME_Evolution_Addressbook_CallStatus
-impl_GNOME_Evolution_Addressbook_Book_cancelOperation (PortableServer_Servant servant,
- CORBA_Environment *ev)
+EBookBackend*
+e_data_book_get_backend (EDataBook *book)
{
- EDataBook *book = E_DATA_BOOK (bonobo_object (servant));
+ g_return_val_if_fail (book != NULL, NULL);
- return e_book_backend_cancel_operation (e_data_book_get_backend (book), book);
+ return book->backend;
}
-/**
- * e_data_book_get_backend:
- * @book: an #EDataBook
- *
- * Gets the #EBookBackend being used to store data for @book.
- *
- * Return value: The #EBookBackend being used.
- **/
-EBookBackend *
-e_data_book_get_backend (EDataBook *book)
+static void
+impl_AddressBook_Book_open(EDataBook *book, gboolean only_if_exists, DBusGMethodInvocation *context)
{
- g_return_val_if_fail (book && E_IS_DATA_BOOK (book), NULL);
+ OperationData *op;
- return book->priv->backend;
+ op = op_new (OP_OPEN, book, context);
+ op->only_if_exists = only_if_exists;
+ g_thread_pool_push (op_pool, op, NULL);
}
-/**
- * e_data_book_get_listener:
- * @book: an #EDataBook
- *
- * Gets the CORBA listener associated with @book.
- *
- * Return value: A #GNOME_Evolution_Addressbook_BookListener.
- **/
-GNOME_Evolution_Addressbook_BookListener
-e_data_book_get_listener (EDataBook *book)
+void
+e_data_book_respond_open (EDataBook *book, guint opid, EDataBookStatus status)
{
- g_return_val_if_fail (book && E_IS_DATA_BOOK (book), CORBA_OBJECT_NIL);
+ DBusGMethodInvocation *context = opid_fetch (opid);
- return book->priv->listener;
+ if (status != E_DATA_BOOK_STATUS_SUCCESS) {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, status, _("Cannot open book")));
+ } else {
+ dbus_g_method_return (context);
+ }
}
-/**
- * e_data_book_get_source:
- * @book: an #EDataBook
- *
- * Gets the #ESource associated with @book.
- *
- * Return value: An #ESource.
- **/
-ESource *
-e_data_book_get_source (EDataBook *book)
+static void
+impl_AddressBook_Book_remove(EDataBook *book, DBusGMethodInvocation *context)
{
- return book->priv->source;
+ e_book_backend_remove (book->backend, book, opid_store (context));
}
-/**
- * e_data_book_respond_open:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- *
- * Respond to an 'open' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
void
-e_data_book_respond_open (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status)
+e_data_book_respond_remove (EDataBook *book, guint opid, EDataBookStatus status)
{
- CORBA_Environment ev;
+ DBusGMethodInvocation *context = opid_fetch (opid);
- CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (book->priv->listener, opid, status, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_respond_open: Exception "
- "responding to BookListener!\n");
+ if (status != E_DATA_BOOK_STATUS_SUCCESS) {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, status, _("Cannot remove book")));
+ } else {
+ dbus_g_method_return (context);
}
-
- CORBA_exception_free (&ev);
}
-/**
- * e_data_book_respond_remove:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- *
- * Respond to a 'remove' request to remove all of @book's data,
- * specified by @opid, indicating @status as the outcome.
- **/
-void
-e_data_book_respond_remove (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status)
+static void
+impl_AddressBook_Book_getContact (EDataBook *book, const char *IN_uid, DBusGMethodInvocation *context)
{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyBookRemoved (book->priv->listener, opid, status, &ev);
+ OperationData *op;
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_respond_remove: Exception "
- "responding to BookListener!\n");
+ if (IN_uid == NULL) {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND, _("Cannot get contact")));
+ return;
}
- CORBA_exception_free (&ev);
+ op = op_new (OP_GET_CONTACT, book, context);
+ op->uid = g_strdup (IN_uid);
+ g_thread_pool_push (op_pool, op, NULL);
}
-/**
- * e_data_book_respond_create:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- * @contact: the contact created, or %NULL
- *
- * Respond to a 'create' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
void
-e_data_book_respond_create (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- EContact *contact)
+e_data_book_respond_get_contact (EDataBook *book, guint32 opid, EDataBookStatus status, const gchar *vcard)
{
- CORBA_Environment ev;
+ DBusGMethodInvocation *context = opid_fetch (opid);
- if (status == GNOME_Evolution_Addressbook_Success) {
- e_book_backend_notify_update (book->priv->backend, contact);
- e_book_backend_notify_complete (book->priv->backend);
+ if (status != E_DATA_BOOK_STATUS_SUCCESS) {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, status, _("Cannot get contact")));
+ } else {
+ dbus_g_method_return (context, vcard);
}
+}
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyContactCreated (
- book->priv->listener, opid, status,
- status == GNOME_Evolution_Addressbook_Success ? e_contact_get_const (contact, E_CONTACT_UID) : "",
- &ev);
+static void
+impl_AddressBook_Book_getContactList (EDataBook *book, const char *query, DBusGMethodInvocation *context)
+{
+ OperationData *op;
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_respond_create: Exception "
- "responding to BookListener!\n");
+ if (query == NULL || query[0] == '\0') {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_INVALID_QUERY, _("Empty query")));
+ return;
}
- CORBA_exception_free (&ev);
+ op = op_new (OP_GET_CONTACTS, book, context);
+ op->query = g_strdup (query);
+ g_thread_pool_push (op_pool, op, NULL);
}
-/**
- * e_data_book_respond_remove_contacts:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- * @ids: a list of contact IDs removed
- *
- * Respond to a 'remove contacts' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
void
-e_data_book_respond_remove_contacts (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- GList *ids)
+e_data_book_respond_get_contact_list (EDataBook *book, guint32 opid, EDataBookStatus status, GList *cards)
{
- CORBA_Environment ev;
- GList *i;
-
- CORBA_exception_init (&ev);
-
- if (ids) {
- for (i = ids; i; i = i->next)
- e_book_backend_notify_remove (book->priv->backend, i->data);
- e_book_backend_notify_complete (book->priv->backend);
- }
-
- GNOME_Evolution_Addressbook_BookListener_notifyContactsRemoved (
- book->priv->listener, opid, status, &ev);
+ return_status_and_list (opid, status, cards, TRUE);
+}
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_respond_remove: Exception "
- "responding to BookListener!\n");
- }
+static void
+impl_AddressBook_Book_authenticateUser(EDataBook *book, const char *IN_user, const char *IN_passwd, const char *IN_auth_method, DBusGMethodInvocation *context)
+{
+ OperationData *op;
- CORBA_exception_free (&ev);
+ op = op_new (OP_AUTHENTICATE, book, context);
+ op->auth.username = g_strdup (IN_user);
+ op->auth.password = g_strdup (IN_passwd);
+ op->auth.method = g_strdup (IN_auth_method);
+ g_thread_pool_push (op_pool, op, NULL);
}
-/**
- * e_data_book_respond_modify:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- * @contact: the modified #EContact
- *
- * Respond to a 'modify' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
void
-e_data_book_respond_modify (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- EContact *contact)
+e_data_book_respond_authenticate_user (EDataBook *book, guint32 opid, EDataBookStatus status)
{
- CORBA_Environment ev;
+ DBusGMethodInvocation *context = opid_fetch (opid);
- if (status == GNOME_Evolution_Addressbook_Success) {
- e_book_backend_notify_update (book->priv->backend, contact);
- e_book_backend_notify_complete (book->priv->backend);
+ if (status != E_DATA_BOOK_STATUS_SUCCESS) {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, status, _("Cannot authenticate user")));
+ } else {
+ dbus_g_method_return (context);
}
+}
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyContactModified (
- book->priv->listener, opid, status, &ev);
+static void
+impl_AddressBook_Book_addContact (EDataBook *book, const char *IN_vcard, DBusGMethodInvocation *context)
+{
+ OperationData *op;
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_respond_modify: Exception "
- "responding to BookListener!\n");
+ if (IN_vcard == NULL || IN_vcard[0] == '\0') {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_INVALID_QUERY, _("Cannot add contact")));
+ return;
}
- CORBA_exception_free (&ev);
+ op = op_new (OP_ADD_CONTACT, book, context);
+ op->vcard = g_strdup (IN_vcard);
+ g_thread_pool_push (op_pool, op, NULL);
}
-/**
- * e_data_book_respond_authenticate_user:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- *
- * Respond to an 'authenticate' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
void
-e_data_book_respond_authenticate_user (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status)
+e_data_book_respond_create (EDataBook *book, guint32 opid, EDataBookStatus status, EContact *contact)
{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
+ DBusGMethodInvocation *context = opid_fetch (opid);
- GNOME_Evolution_Addressbook_BookListener_notifyAuthenticationResult (
- book->priv->listener, opid, status, &ev);
+ if (status != E_DATA_BOOK_STATUS_SUCCESS) {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, status, _("Cannot add contact")));
+ } else {
+ e_book_backend_notify_update (e_data_book_get_backend (book), contact);
+ e_book_backend_notify_complete (e_data_book_get_backend (book));
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_respond_authenticate_user: Exception "
- "responding to BookListener!\n");
+ dbus_g_method_return (context, e_contact_get_const (contact, E_CONTACT_UID));
}
-
- CORBA_exception_free (&ev);
}
-/**
- * e_data_book_respond_get_required_fields:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- * @fields: a list of required field names
- *
- * Respond to a 'get required fields' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
-void
-e_data_book_respond_get_required_fields (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- GList *fields)
+static void
+impl_AddressBook_Book_modifyContact (EDataBook *book, const char *IN_vcard, DBusGMethodInvocation *context)
{
+ OperationData *op;
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_stringlist stringlist;
- gint num_fields;
- gint i;
- GList *iter;
-
- CORBA_exception_init (&ev);
-
- num_fields = g_list_length (fields);
-
- stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_fields);
- stringlist._maximum = num_fields;
- stringlist._length = num_fields;
-
- for (i = 0, iter = fields; iter; iter = iter->next, i ++) {
- stringlist._buffer[i] = CORBA_string_dup ((gchar *)iter->data);
+ if (IN_vcard == NULL) {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_INVALID_QUERY, _("Cannot modify contact")));
+ return;
}
- printf ("calling GNOME_Evolution_Addressbook_BookListener_notifyRequiredFields\n");
-
- GNOME_Evolution_Addressbook_BookListener_notifyRequiredFields (
- book->priv->listener, opid, status,
- &stringlist,
- &ev);
-
- CORBA_exception_free (&ev);
-
- CORBA_free(stringlist._buffer);
+ op = op_new (OP_MODIFY_CONTACT, book, context);
+ op->vcard = g_strdup (IN_vcard);
+ g_thread_pool_push (op_pool, op, NULL);
}
-/**
- * e_data_book_respond_get_supported_fields:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- * @fields: a list of supported field names
- *
- * Respond to a 'get supported fields' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
void
-e_data_book_respond_get_supported_fields (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- GList *fields)
+e_data_book_respond_modify (EDataBook *book, guint32 opid, EDataBookStatus status, EContact *contact)
{
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_stringlist stringlist;
- gint num_fields;
- gint i;
- GList *iter;
+ DBusGMethodInvocation *context = opid_fetch (opid);
- CORBA_exception_init (&ev);
+ if (status != E_DATA_BOOK_STATUS_SUCCESS) {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, status, _("Cannot modify contact")));
+ } else {
+ e_book_backend_notify_update (e_data_book_get_backend (book), contact);
+ e_book_backend_notify_complete (e_data_book_get_backend (book));
- num_fields = g_list_length (fields);
+ dbus_g_method_return (context);
+ }
+}
- stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_fields);
- stringlist._maximum = num_fields;
- stringlist._length = num_fields;
+static void
+impl_AddressBook_Book_removeContacts(EDataBook *book, const char **IN_uids, DBusGMethodInvocation *context)
+{
+ OperationData *op;
- for (i = 0, iter = fields; iter; iter = iter->next, i ++) {
- stringlist._buffer[i] = CORBA_string_dup ((gchar *)iter->data);
+ /* Allow an empty array to be removed */
+ if (IN_uids == NULL) {
+ dbus_g_method_return (context);
+ return;
}
- printf ("calling GNOME_Evolution_Addressbook_BookListener_notifySupportedFields\n");
-
- GNOME_Evolution_Addressbook_BookListener_notifySupportedFields (
- book->priv->listener, opid, status,
- &stringlist,
- &ev);
+ op = op_new (OP_REMOVE_CONTACTS, book, context);
- CORBA_exception_free (&ev);
+ for (; *IN_uids; IN_uids++) {
+ op->ids = g_list_prepend (op->ids, g_strdup (*IN_uids));
+ }
- CORBA_free(stringlist._buffer);
+ g_thread_pool_push (op_pool, op, NULL);
}
-/**
- * e_data_book_respond_get_supported_auth_methods:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- * @auth_methods: a list of names for supported auth methods
- *
- * Respond to a 'get supported auth methods' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
void
-e_data_book_respond_get_supported_auth_methods (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- GList *auth_methods)
+e_data_book_respond_remove_contacts (EDataBook *book, guint32 opid, EDataBookStatus status, GList *ids)
{
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_stringlist stringlist;
- gint num_auth_methods;
- GList *iter;
- gint i;
-
- CORBA_exception_init (&ev);
+ DBusGMethodInvocation *context = opid_fetch (opid);
- num_auth_methods = g_list_length (auth_methods);
+ if (status != E_DATA_BOOK_STATUS_SUCCESS) {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, status, _("Cannot remove contacts")));
+ } else {
+ GList *i;
- stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_auth_methods);
- stringlist._maximum = num_auth_methods;
- stringlist._length = num_auth_methods;
+ for (i = ids; i; i = i->next)
+ e_book_backend_notify_remove (e_data_book_get_backend (book), i->data);
+ e_book_backend_notify_complete (e_data_book_get_backend (book));
- for (i = 0, iter = auth_methods; iter; iter = iter->next, i ++) {
- stringlist._buffer[i] = CORBA_string_dup ((gchar *)iter->data);
+ dbus_g_method_return (context);
}
+}
- GNOME_Evolution_Addressbook_BookListener_notifySupportedAuthMethods (
- book->priv->listener, opid, status,
- &stringlist,
- &ev);
-
- CORBA_exception_free (&ev);
-
- CORBA_free(stringlist._buffer);
+static gboolean
+impl_AddressBook_Book_getStaticCapabilities(EDataBook *book, char **OUT_capabilities, GError **error)
+{
+ *OUT_capabilities = e_book_backend_get_static_capabilities (e_data_book_get_backend (book));
+ return TRUE;
}
static void
-view_destroy(gpointer data, GObject *where_object_was)
+impl_AddressBook_Book_getSupportedFields(EDataBook *book, DBusGMethodInvocation *context)
{
- EDataBook *book = (EDataBook *)data;
- e_book_backend_remove_book_view (book->priv->backend, (EDataBookView*)where_object_was);
+ e_book_backend_get_supported_fields (e_data_book_get_backend (book), book, opid_store (context));
}
-/**
- * e_data_book_respond_get_book_view:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- * @book_view: the #EDataBookView created
- *
- * Respond to a 'get book view' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
void
-e_data_book_respond_get_book_view (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- EDataBookView *book_view)
+e_data_book_respond_get_supported_fields (EDataBook *book, guint32 opid, EDataBookStatus status, GList *fields)
{
- CORBA_Environment ev;
- CORBA_Object object = CORBA_OBJECT_NIL;
-
- printf ("e_data_book_respond_get_book_view\n");
-
- CORBA_exception_init (&ev);
-
- if (book_view) {
- object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view));
-
- g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
- }
-
- GNOME_Evolution_Addressbook_BookListener_notifyViewRequested (
- book->priv->listener, opid, status, object, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_respond_get_book_view: Exception "
- "responding to BookListener!\n");
- }
-
- CORBA_exception_free (&ev);
+ return_status_and_list (opid, status, fields, FALSE);
}
-/**
- * e_data_book_respond_get_contact:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- * @vcard: the found VCard, or %NULL
- *
- * Respond to a 'get contact' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
-void
-e_data_book_respond_get_contact (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- const gchar *vcard)
+static void
+impl_AddressBook_Book_getRequiredFields(EDataBook *book, DBusGMethodInvocation *context)
{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyContactRequested (book->priv->listener,
- opid,
- status,
- vcard,
- &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("could not notify listener of get-contact response");
-
- CORBA_exception_free (&ev);
+ e_book_backend_get_required_fields (e_data_book_get_backend (book), book, opid_store (context));
}
-/**
- * e_data_book_respond_get_contact_list:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- * @card_list: a list of VCard strings
- *
- * Respond to a 'get contact list' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
void
-e_data_book_respond_get_contact_list (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- GList *card_list)
+e_data_book_respond_get_required_fields (EDataBook *book, guint32 opid, EDataBookStatus status, GList *fields)
{
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_stringlist stringlist;
- gint num_cards;
- gint i;
- GList *l;
-
- CORBA_exception_init (&ev);
-
- num_cards = g_list_length (card_list);
-
- stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_cards);
- stringlist._maximum = num_cards;
- stringlist._length = num_cards;
-
- for (i = 0, l = card_list; l; l = l->next, i ++)
- stringlist._buffer[i] = CORBA_string_dup (l->data);
-
- g_list_foreach (card_list, (GFunc)g_free, NULL);
- g_list_free (card_list);
-
- GNOME_Evolution_Addressbook_BookListener_notifyContactListRequested (book->priv->listener,
- opid,
- status,
- &stringlist,
- &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("could not notify listener of get-contact-list response");
-
- CORBA_exception_free (&ev);
+ return_status_and_list (opid, status, fields, FALSE);
+}
- CORBA_free(stringlist._buffer);
+static void
+impl_AddressBook_Book_getSupportedAuthMethods(EDataBook *book, DBusGMethodInvocation *context)
+{
+ e_book_backend_get_supported_auth_methods (e_data_book_get_backend (book), book, opid_store (context));
}
-/**
- * e_data_book_respond_get_changes:
- * @book: an #EDataBook
- * @opid: the operation ID that generated the response
- * @status: the outcome of the operation
- * @changes: a list of GNOME_Evolution_Addressbook_BookChangeItem items
- *
- * Respond to a 'get changes' request specified by @opid on @book,
- * indicating @status as the outcome.
- **/
void
-e_data_book_respond_get_changes (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- GList *changes)
+e_data_book_respond_get_supported_auth_methods (EDataBook *book, guint32 opid, EDataBookStatus status, GList *auth_methods)
{
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_BookChangeList changelist;
- gint num_changes;
- gint i;
- GList *l;
+ return_status_and_list (opid, status, auth_methods, FALSE);
+}
- CORBA_exception_init (&ev);
+static char*
+construct_bookview_path (void)
+{
+ static volatile guint counter = 1;
- num_changes = g_list_length (changes);
+ return g_strdup_printf ("/org/gnome/evolution/dataserver/addressbook/BookView/%d/%d",
+ getpid (),
+ g_atomic_int_exchange_and_add ((int*)&counter, 1));
+}
- changelist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_BookChangeItem_allocbuf (num_changes);
- changelist._maximum = num_changes;
- changelist._length = num_changes;
+static void
+impl_AddressBook_Book_getBookView (EDataBook *book, const char *search, const guint max_results, DBusGMethodInvocation *context)
+{
+ EBookBackend *backend = e_data_book_get_backend (book);
+ EBookBackendSExp *card_sexp;
+ EDataBookView *book_view;
+ char *path;
- for (i = 0, l = changes; l; l = l->next, i ++) {
- GNOME_Evolution_Addressbook_BookChangeItem *change = (GNOME_Evolution_Addressbook_BookChangeItem*)l->data;
- changelist._buffer[i] = *change;
- changelist._buffer[i].vcard = CORBA_string_dup (change->vcard);
+ card_sexp = e_book_backend_sexp_new (search);
+ if (!card_sexp) {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_INVALID_QUERY, _("Invalid query")));
+ return;
}
- g_list_foreach (changes, (GFunc)CORBA_free, NULL);
- g_list_free (changes);
+ path = construct_bookview_path ();
+ book_view = e_data_book_view_new (book, path, search, card_sexp, max_results);
- GNOME_Evolution_Addressbook_BookListener_notifyChangesRequested (book->priv->listener,
- opid,
- status,
- &changelist,
- &ev);
+ e_book_backend_add_book_view (backend, book_view);
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("could not notify listener of get-changes response");
+ dbus_g_method_return (context, path);
+ g_free (path);
+}
- CORBA_exception_free (&ev);
+static void
+impl_AddressBook_Book_getChanges(EDataBook *book, const char *IN_change_id, DBusGMethodInvocation *context)
+{
+ OperationData *op;
- CORBA_free(changelist._buffer);
+ op = op_new (OP_GET_CHANGES, book, context);
+ op->change_id = g_strdup (IN_change_id);
+ g_thread_pool_push (op_pool, op, NULL);
}
-/**
- * e_data_book_report_writable:
- * @book: an #EDataBook
- * @writable: %TRUE if @book is writeable, %FALSE otherwise
- *
- * Notify listeners that @book's writeable status has changed
- * to @writable.
- **/
void
-e_data_book_report_writable (EDataBook *book,
- gboolean writable)
+e_data_book_respond_get_changes (EDataBook *book, guint32 opid, EDataBookStatus status, GList *changes)
{
- CORBA_Environment ev;
+ DBusGMethodInvocation *context = opid_fetch (opid);
- CORBA_exception_init (&ev);
+ if (status != E_DATA_BOOK_STATUS_SUCCESS) {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, status, _("Cannot get changes")));
+ } else {
+ /* The DBus interface to this is a(us), an array of structs of unsigned ints
+ and strings. In dbus-glib this is a GPtrArray of GValueArray of unsigned
+ int and strings. */
+ GPtrArray *array;
- GNOME_Evolution_Addressbook_BookListener_notifyWritable (
- book->priv->listener, (CORBA_boolean) writable, &ev);
+ array = g_ptr_array_new ();
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_report_writable: Exception "
- "responding to BookListener!\n");
- }
+ while (changes != NULL) {
+ EDataBookChange *change = (EDataBookChange *) changes->data;
+ GValueArray *vals;
- CORBA_exception_free (&ev);
-}
+ vals = g_value_array_new (2);
-/**
- * e_data_book_report_connection_status:
- * @book: an #EDataBook
- * @is_online: %TRUE if the book is connected, %FALSE otherwise
- *
- * Notify listeners that @book's online status has changed
- * to @is_online.
- **/
-void
-e_data_book_report_connection_status (EDataBook *book,
- gboolean is_online)
-{
- CORBA_Environment ev;
+ g_value_array_append (vals, NULL);
+ g_value_init (g_value_array_get_nth (vals, 0), G_TYPE_UINT);
+ g_value_set_uint (g_value_array_get_nth (vals, 0), change->change_type);
- CORBA_exception_init (&ev);
+ g_value_array_append (vals, NULL);
+ g_value_init (g_value_array_get_nth (vals, 1), G_TYPE_STRING);
+ g_value_take_string (g_value_array_get_nth (vals, 1), change->vcard);
+ /* Now change->vcard is owned by the GValue */
- GNOME_Evolution_Addressbook_BookListener_notifyConnectionStatus (
- book->priv->listener, (CORBA_boolean) is_online, &ev);
+ g_free (change);
+ changes = g_list_remove (changes, change);
+ }
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_report_connection_status: Exception "
- "responding to BookListener!\n");
+ dbus_g_method_return (context, array);
+ g_ptr_array_foreach (array, (GFunc)g_value_array_free, NULL);
+ g_ptr_array_free (array, TRUE);
}
-
- CORBA_exception_free (&ev);
-
}
-/**
- * e_data_book_report_connection_status:
- * @book: an #EDataBook
- *
- * Notify listeners that @book requires authentication.
- **/
-void
-e_data_book_report_auth_required (EDataBook *book)
+static gboolean
+impl_AddressBook_Book_cancelOperation(EDataBook *book, GError **error)
{
-
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyAuthRequired (
- book->priv->listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_data_book_report_auth_required: Exception "
- "responding to BookListener!\n");
+ if (!e_book_backend_cancel_operation (e_data_book_get_backend (book), book)) {
+ g_set_error (error, E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_COULD_NOT_CANCEL, "Failed to cancel operation");
+ return FALSE;
}
- CORBA_exception_free (&ev);
-
+ return TRUE;
}
static void
-e_data_book_construct (EDataBook *book,
- EBookBackend *backend,
- ESource *source,
- GNOME_Evolution_Addressbook_BookListener listener)
+impl_AddressBook_Book_close(EDataBook *book, DBusGMethodInvocation *context)
{
- EDataBookPrivate *priv;
- CORBA_Environment ev;
+ char *sender;
- g_return_if_fail (book != NULL);
- g_return_if_fail (source != NULL);
+ sender = dbus_g_method_get_sender (context);
- priv = book->priv;
+ book->closed_cb (book, sender);
- CORBA_exception_init (&ev);
- book->priv->listener = CORBA_Object_duplicate (listener, &ev);
+ g_free (sender);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_message ("e_data_book_construct(): could not duplicate the listener");
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_exception_free (&ev);
-
- g_object_ref (source);
+ g_object_unref (book);
- priv->backend = g_object_ref(backend);
- priv->source = source;
+ dbus_g_method_return (context);
}
-/**
- * e_data_book_new:
- * @backend: an #EBookBackend
- * @source: an #ESource
- * @listener: a #GNOME_Evolution_Addressbook_BookListener CORBA object
- *
- * Create a new #EDataBook using @backend for storage, @source as the
- * storage location and @listener for reporting status.
- *
- * Return value: A new #EDataBook.
- **/
-EDataBook *
-e_data_book_new (EBookBackend *backend,
- ESource *source,
- GNOME_Evolution_Addressbook_BookListener listener)
+void
+e_data_book_report_writable (EDataBook *book, gboolean writable)
{
- static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
- static PortableServer_POA poa = NULL;
- EDataBook *book;
-
- g_static_mutex_lock (&mutex);
- if (poa == NULL)
- poa = bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL);
- g_static_mutex_unlock (&mutex);
-
- book = g_object_new (E_TYPE_DATA_BOOK, "poa", poa, NULL);
-
- e_data_book_construct (book, backend, source, listener);
+ g_return_if_fail (book != NULL);
- return book;
+ g_signal_emit (book, signals[WRITABLE], 0, writable);
}
-static void
-e_data_book_dispose (GObject *object)
+void
+e_data_book_report_connection_status (EDataBook *book, gboolean connected)
{
- EDataBook *book = E_DATA_BOOK (object);
-
- if (book->priv) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- CORBA_Object_release (book->priv->listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("e_data_book_construct(): could not release the listener");
+ g_return_if_fail (book != NULL);
- CORBA_exception_free (&ev);
+ g_signal_emit (book, signals[CONNECTION], 0, connected);
+}
- g_object_unref (book->priv->source);
- g_object_unref (book->priv->backend);
- g_free (book->priv);
- book->priv = NULL;
- }
+void
+e_data_book_report_auth_required (EDataBook *book)
+{
+ g_return_if_fail (book != NULL);
- if (G_OBJECT_CLASS (e_data_book_parent_class)->dispose)
- G_OBJECT_CLASS (e_data_book_parent_class)->dispose (object);
+ g_signal_emit (book, signals[AUTH_REQUIRED], 0);
}
static void
-e_data_book_class_init (EDataBookClass *klass)
+return_status_and_list (guint32 opid, EDataBookStatus status, GList *list, gboolean free_data)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- POA_GNOME_Evolution_Addressbook_Book__epv *epv;
-
- e_data_book_parent_class = g_type_class_peek_parent (klass);
+ DBusGMethodInvocation *context = opid_fetch (opid);
- object_class->dispose = e_data_book_dispose;
-
- epv = &klass->epv;
+ if (status == E_DATA_BOOK_STATUS_SUCCESS) {
+ char **array;
+ GList *l;
+ int i = 0;
- epv->open = impl_GNOME_Evolution_Addressbook_Book_open;
- epv->remove = impl_GNOME_Evolution_Addressbook_Book_remove;
- epv->getContact = impl_GNOME_Evolution_Addressbook_Book_getContact;
- epv->getContactList = impl_GNOME_Evolution_Addressbook_Book_getContactList;
- epv->authenticateUser = impl_GNOME_Evolution_Addressbook_Book_authenticateUser;
- epv->addContact = impl_GNOME_Evolution_Addressbook_Book_addContact;
- epv->removeContacts = impl_GNOME_Evolution_Addressbook_Book_removeContacts;
- epv->modifyContact = impl_GNOME_Evolution_Addressbook_Book_modifyContact;
- epv->getStaticCapabilities = impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities;
- epv->getSupportedFields = impl_GNOME_Evolution_Addressbook_Book_getSupportedFields;
- epv->getRequiredFields = impl_GNOME_Evolution_Addressbook_Book_getRequiredFields;
- epv->getSupportedAuthMethods = impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods;
- epv->getBookView = impl_GNOME_Evolution_Addressbook_Book_getBookView;
- epv->getChanges = impl_GNOME_Evolution_Addressbook_Book_getChanges;
- epv->cancelOperation = impl_GNOME_Evolution_Addressbook_Book_cancelOperation;
+ array = g_new0 (char*, g_list_length (list) + 1);
+ for (l = list; l != NULL; l = l->next) {
+ array[i++] = l->data;
+ }
-}
+ dbus_g_method_return (context, array);
-static void
-e_data_book_init (EDataBook *book)
-{
- book->priv = g_new0 (EDataBookPrivate, 1);
+ if (free_data) {
+ g_strfreev (array);
+ } else {
+ g_free (array);
+ }
+ } else {
+ dbus_g_method_return_error (context, g_error_new (E_DATA_BOOK_ERROR, status, _("Cannot complete operation")));
+ }
}
-
-BONOBO_TYPE_FUNC_FULL (
- EDataBook,
- GNOME_Evolution_Addressbook_Book,
- BONOBO_TYPE_OBJECT,
- e_data_book)
diff --git a/addressbook/libedata-book/e-data-book.h b/addressbook/libedata-book/e-data-book.h
index 5b26b7815..d7c9d7dca 100644
--- a/addressbook/libedata-book/e-data-book.h
+++ b/addressbook/libedata-book/e-data-book.h
@@ -1,109 +1,112 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * A wrapper object which exports the GNOME_Evolution_Addressbook_Book CORBA interface
- * and which maintains a request queue.
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2006 OpenedHand Ltd
+ * Copyright (C) 2009 Intel Corporation
*
- * Author:
- * Nat Friedman (nat@ximian.com)
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
*
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * This library 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 this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ross Burton <ross@linux.intel.com>
*/
#ifndef __E_DATA_BOOK_H__
#define __E_DATA_BOOK_H__
-#include <bonobo/bonobo-object.h>
-#include "libedataserver/e-list.h"
-#include "libedataserver/e-source.h"
-#include <libedata-book/Evolution-DataServer-Addressbook.h>
-#include <libedata-book/e-data-book-types.h>
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include <libedataserver/e-source.h>
+#include "e-book-backend.h"
+#include "e-data-book-types.h"
G_BEGIN_DECLS
#define E_TYPE_DATA_BOOK (e_data_book_get_type ())
#define E_DATA_BOOK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_DATA_BOOK, EDataBook))
-#define E_DATA_BOOK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_DATA_BOOK, EDataBookClass))
+#define E_DATA_BOOK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_DATA_BOOK, EDataBookClass))
#define E_IS_DATA_BOOK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_DATA_BOOK))
#define E_IS_DATA_BOOK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_DATA_BOOK))
#define E_DATA_BOOK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_TYPE_DATA_BOOK, EDataBookClass))
-typedef struct _EDataBookPrivate EDataBookPrivate;
+typedef void (* EDataBookClosedCallback) (EDataBook *book, const char *client);
struct _EDataBook {
- BonoboObject parent_object;
- EDataBookPrivate *priv;
+ GObject parent;
+ EBookBackend *backend;
+ ESource *source;
+ /* TODO: move to private data */
+ EDataBookClosedCallback closed_cb;
};
struct _EDataBookClass {
- BonoboObjectClass parent_class;
-
- POA_GNOME_Evolution_Addressbook_Book__epv epv;
-
- /* Padding for future expansion */
- void (*_pas_reserved0) (void);
- void (*_pas_reserved1) (void);
- void (*_pas_reserved2) (void);
- void (*_pas_reserved3) (void);
- void (*_pas_reserved4) (void);
+ GObjectClass parent;
};
-EDataBook *e_data_book_new (EBookBackend *backend,
- ESource *source,
- GNOME_Evolution_Addressbook_BookListener listener);
-GNOME_Evolution_Addressbook_BookListener e_data_book_get_listener (EDataBook *book);
+GQuark e_data_book_error_quark (void);
+#define E_DATA_BOOK_ERROR e_data_book_error_quark ()
+
+EDataBook *e_data_book_new (EBookBackend *backend,
+ ESource *source,
+ EDataBookClosedCallback closed_cb);
EBookBackend *e_data_book_get_backend (EDataBook *book);
ESource *e_data_book_get_source (EDataBook *book);
-void e_data_book_respond_open (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status);
-void e_data_book_respond_remove (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status);
-void e_data_book_respond_create (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- EContact *contact);
-void e_data_book_respond_remove_contacts (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- GList *ids);
-void e_data_book_respond_modify (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- EContact *contact);
-void e_data_book_respond_authenticate_user (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status);
-void e_data_book_respond_get_supported_fields (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- GList *fields);
-void e_data_book_respond_get_required_fields (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- GList *fields);
-void e_data_book_respond_get_supported_auth_methods (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- GList *fields);
-
-void e_data_book_respond_get_book_view (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- EDataBookView *book_view);
-void e_data_book_respond_get_contact (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- const gchar *vcard);
-void e_data_book_respond_get_contact_list (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
+void e_data_book_respond_open (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status);
+void e_data_book_respond_remove (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status);
+void e_data_book_respond_create (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status,
+ EContact *contact);
+void e_data_book_respond_remove_contacts (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status,
+ GList *ids);
+void e_data_book_respond_modify (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status,
+ EContact *contact);
+void e_data_book_respond_authenticate_user (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status);
+void e_data_book_respond_get_supported_fields (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status,
+ GList *fields);
+void e_data_book_respond_get_required_fields (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status,
+ GList *fields);
+void e_data_book_respond_get_supported_auth_methods (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status,
+ GList *fields);
+
+void e_data_book_respond_get_contact (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status,
+ const gchar *vcard);
+void e_data_book_respond_get_contact_list (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status,
GList *cards);
-void e_data_book_respond_get_changes (EDataBook *book,
- guint32 opid,
- GNOME_Evolution_Addressbook_CallStatus status,
- GList *changes);
+void e_data_book_respond_get_changes (EDataBook *book,
+ guint32 opid,
+ EDataBookStatus status,
+ GList *changes);
void e_data_book_report_writable (EDataBook *book,
gboolean writable);
diff --git a/addressbook/libedata-book/glib-gen.mak b/addressbook/libedata-book/glib-gen.mak
new file mode 100644
index 000000000..f510d80b1
--- /dev/null
+++ b/addressbook/libedata-book/glib-gen.mak
@@ -0,0 +1,42 @@
+# these are the variables your Makefile.am should set
+# the example is based on the colorbalance interface
+
+#glib_enum_headers=$(colorbalance_headers)
+#glib_enum_define=GST_COLOR_BALANCE
+#glib_enum_prefix=gst_color_balance
+
+# these are all the rules generating the relevant files
+%-marshal.h: %-marshal.list
+ glib-genmarshal --header --prefix=$(glib_enum_prefix)_marshal $^ > $*-marshal.h.tmp
+ mv $*-marshal.h.tmp $*-marshal.h
+
+%-marshal.c: %-marshal.list
+ echo "#include \"$*-marshal.h\"" >> $*-marshal.c.tmp
+ glib-genmarshal --body --prefix=$(glib_enum_prefix)_marshal $^ >> $*-marshal.c.tmp
+ mv $*-marshal.c.tmp $*-marshal.c
+
+%-enumtypes.h: $(glib_enum_headers)
+ glib-mkenums \
+ --fhead "#ifndef __$(glib_enum_define)_ENUM_TYPES_H__\n#define __$(glib_enum_define)_ENUM_TYPES_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
+ --fprod "/* enumerations from \"@filename@\" */\n" \
+ --vhead "GType @enum_name@_get_type (void);\n#define E_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
+ --ftail "G_END_DECLS\n\n#endif /* __$(glib_enum_define)_ENUM_TYPES_H__ */" \
+ $^ > $@
+
+%-enumtypes.c: $(glib_enum_headers)
+ @if test "x$(glib_enum_headers)" == "x"; then echo "ERROR: glib_enum_headers is empty, please fix Makefile"; exit 1; fi
+ glib-mkenums \
+ --fhead "#include <$*.h>\n#include \"$*-enumtypes.h\"" \
+ --fprod "\n/* enumerations from \"@filename@\" */" \
+ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \
+ $^ > $@
+
+# a hack rule to make sure .Plo files exist because they get include'd
+# from Makefile's
+.deps/%-marshal.Plo:
+ touch $@
+
+.deps/%-enumtypes.Plo:
+ touch $@
diff --git a/addressbook/libedata-book/libedata-book.pc.in b/addressbook/libedata-book/libedata-book.pc.in
index 8ab451e2d..d99e1b82d 100644
--- a/addressbook/libedata-book/libedata-book.pc.in
+++ b/addressbook/libedata-book/libedata-book.pc.in
@@ -5,14 +5,11 @@ includedir=@includedir@
datarootdir=@datarootdir@
datadir=@datadir@
-idldir=@idldir@
-IDL_INCLUDES=-I${idldir} @IDL_INCLUDES@
-
privincludedir=@privincludedir@
Name: libedatabook
Description: Backend library for evolution address books
Version: @VERSION@
-Requires: libbonobo-2.0 >= @LIBBONOBO_REQUIRED@ libedataserver-1.2 libebackend-1.2 libebook-1.2
+Requires: libedataserver-1.2 libebook-1.2 dbus-glib-1
Libs: -L${libdir} -ledata-book-1.2
Cflags: -I${privincludedir}
diff --git a/addressbook/libedata-book/opid.c b/addressbook/libedata-book/opid.c
new file mode 100644
index 000000000..127e0c18a
--- /dev/null
+++ b/addressbook/libedata-book/opid.c
@@ -0,0 +1,75 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006 OpenedHand Ltd
+ * Copyright (C) 2009 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ross Burton <ross@linux.intel.com>
+ */
+
+#include "opid.h"
+
+G_LOCK_DEFINE_STATIC (lock);
+static int counter = 0;
+static GHashTable *hash = NULL;
+
+static void
+opid_init (void)
+{
+ counter = 1;
+ hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+}
+
+guint32
+opid_store (gpointer p)
+{
+ int id;
+
+ g_return_val_if_fail (p, 0);
+
+ G_LOCK (lock);
+
+ if (G_UNLIKELY (hash == NULL))
+ opid_init ();
+
+ do {
+ id = counter++;
+ } while (g_hash_table_lookup (hash, GINT_TO_POINTER (id)) != NULL);
+
+ g_hash_table_insert (hash, GINT_TO_POINTER (id), p);
+
+ G_UNLOCK (lock);
+
+ return id;
+}
+
+gpointer
+opid_fetch (guint32 id)
+{
+ gpointer p;
+
+ G_LOCK (lock);
+
+ if (G_UNLIKELY (hash == NULL))
+ opid_init ();
+
+ p = g_hash_table_lookup (hash, GINT_TO_POINTER (id));
+
+ g_hash_table_remove (hash, GINT_TO_POINTER (id));
+
+ G_UNLOCK (lock);
+
+ return p;
+}
diff --git a/addressbook/libedata-book/opid.h b/addressbook/libedata-book/opid.h
new file mode 100644
index 000000000..20bbf1af0
--- /dev/null
+++ b/addressbook/libedata-book/opid.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006 OpenedHand Ltd
+ * Copyright (C) 2009 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library 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 this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ross Burton <ross@linux.intel.com>
+ */
+
+#include <glib.h>
+
+/* Stupid EDS internal API */
+
+guint32 opid_store (gpointer p);
+
+gpointer opid_fetch (guint32 id);
diff --git a/addressbook/libedata-book/org.gnome.evolution.dataserver.AddressBook.service.in b/addressbook/libedata-book/org.gnome.evolution.dataserver.AddressBook.service.in
new file mode 100644
index 000000000..092831154
--- /dev/null
+++ b/addressbook/libedata-book/org.gnome.evolution.dataserver.AddressBook.service.in
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.gnome.evolution.dataserver.AddressBook
+Exec=@LIBEXECDIR@/e-addressbook-factory