[evolution-data-server/openismus-work-master: 6/13] EBookClient, EDataBook: Added direct access APIs
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/openismus-work-master: 6/13] EBookClient, EDataBook: Added direct access APIs
- Date: Tue, 29 Jan 2013 07:25:31 +0000 (UTC)
commit 10eba53586e0e52f40a0d7956ba61790020950ba
Author: Tristan Van Berkom <tristanvb openismus com>
Date: Fri Nov 2 20:37:34 2012 +0900
EBookClient, EDataBook: Added direct access APIs
With direct access enabled, an EDataBook is created locally by
the client and used for read access directly instead of going over
the D-Bus.
EDataBook has been extended with APIs for reading the addressbook
directly (with sync and async variants that dont go over any IPC
but still need async/sync variants to wait for thread operations
to complete).
EDataBookDirect has been added to advertize some information over
the bus needed for setting up a direct connection to the addressbook,
backends supporting direct access are expected to implement the new
EBookBackend method ->get_direct_book() in order to advertize that
it supports direct access, backends can also optionally implement
->configure_direct().
This commit also splits up libebook into 2 libraries, lower level data types
such as EContact are split out into a libebook-contacts shared library
(This is important since now libebook depends on libedata-book in order
to instanciate an EDataBook directly)
addressbook/Makefile.am | 2 +-
addressbook/backends/file/Makefile.am | 1 +
addressbook/backends/google/Makefile.am | 1 +
addressbook/backends/google/e-book-google-utils.c | 2 +-
addressbook/backends/google/tests/phone-numbers.c | 2 +-
addressbook/backends/ldap/Makefile.am | 1 +
addressbook/backends/webdav/Makefile.am | 1 +
addressbook/libebook-contacts/Makefile.am | 141 ++
.../e-address-western.c | 0
.../e-address-western.h | 4 +-
.../e-book-contacts-enumtypes.c.template | 38 +
.../e-book-contacts-enumtypes.h.template | 27 +
.../libebook-contacts/e-book-contacts-marshal.list | 6 +
.../libebook-contacts/e-book-contacts-types.h | 112 ++
.../{libebook => libebook-contacts}/e-book-query.c | 0
.../{libebook => libebook-contacts}/e-book-query.h | 6 +-
.../{libebook => libebook-contacts}/e-contact.c | 1 -
.../{libebook => libebook-contacts}/e-contact.h | 6 +-
.../e-name-western-tables.h | 0
.../e-name-western-tables.h.in | 0
.../e-name-western.c | 0
.../e-name-western.h | 4 +-
.../e-source-backend-summary-setup.c | 6 +-
.../e-source-backend-summary-setup.h | 8 +-
.../{libebook => libebook-contacts}/e-vcard.c | 0
.../{libebook => libebook-contacts}/e-vcard.h | 4 +-
.../gen-western-table.py | 0
addressbook/libebook-contacts/libebook-contacts.h | 38 +
.../libebook-contacts/libebook-contacts.pc.in | 16 +
addressbook/libebook/Makefile.am | 36 +-
addressbook/libebook/e-book-client-view.h | 18 -
addressbook/libebook/e-book-client.c | 279 ++++-
addressbook/libebook/e-book-client.h | 5 +-
addressbook/libebook/e-book-types.h | 75 +--
addressbook/libebook/e-book.c | 2 -
addressbook/libebook/e-book.h | 3 +-
addressbook/libebook/e-destination.h | 2 +-
addressbook/libebook/libebook.h | 7 +-
addressbook/libebook/libebook.pc.in | 2 +-
addressbook/libedata-book/Makefile.am | 4 +-
addressbook/libedata-book/e-book-backend-cache.h | 2 +-
.../libedata-book/e-book-backend-db-cache.h | 2 +-
addressbook/libedata-book/e-book-backend-sexp.h | 2 +-
.../libedata-book/e-book-backend-sqlitedb-test.c | 2 +-
.../libedata-book/e-book-backend-sqlitedb.c | 4 +
.../libedata-book/e-book-backend-sqlitedb.h | 2 +-
addressbook/libedata-book/e-book-backend-summary.h | 2 +-
addressbook/libedata-book/e-book-backend.c | 48 +
addressbook/libedata-book/e-book-backend.h | 12 +-
addressbook/libedata-book/e-data-book-direct.c | 132 ++
addressbook/libedata-book/e-data-book-direct.h | 64 +
addressbook/libedata-book/e-data-book-view.h | 2 +-
addressbook/libedata-book/e-data-book.c | 902 ++++++++++++-
addressbook/libedata-book/e-data-book.h | 27 +
addressbook/libedata-book/libedata-book.h | 3 +-
addressbook/libegdbus/Makefile.am | 7 +-
addressbook/libegdbus/e-gdbus-book-direct.c | 1359 ++++++++++++++++++++
addressbook/libegdbus/e-gdbus-book-direct.h | 173 +++
calendar/backends/contacts/Makefile.am | 1 +
configure.ac | 9 +
docs/reference/addressbook/libebook/Makefile.am | 1 +
.../addressbook/libedata-book/Makefile.am | 1 +
tests/libebook/Makefile.am | 3 +-
tests/libebook/client/Makefile.am | 1 +
tests/libebook/vcard/Makefile.am | 1 +
vala/EBook-1.2.metadata | 23 -
vala/EBookContacts-1.2.metadata | 23 +
vala/Makefile.am | 39 +-
vala/libebook-1.2.deps | 2 +-
...stom.vala => libebook-contacts-1.2-custom.vala} | 0
vala/libebook-contacts-1.2.deps | 3 +
71 files changed, 3437 insertions(+), 275 deletions(-)
---
diff --git a/addressbook/Makefile.am b/addressbook/Makefile.am
index f61358d..62414f6 100644
--- a/addressbook/Makefile.am
+++ b/addressbook/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = libegdbus libebook libedata-book backends
+SUBDIRS = libegdbus libebook-contacts libedata-book libebook backends
-include $(top_srcdir)/git.mk
diff --git a/addressbook/backends/file/Makefile.am b/addressbook/backends/file/Makefile.am
index 92ca13d..de53c5d 100644
--- a/addressbook/backends/file/Makefile.am
+++ b/addressbook/backends/file/Makefile.am
@@ -21,6 +21,7 @@ libebookbackendfile_la_SOURCES = \
e-book-backend-file-factory.c
libebookbackendfile_la_LIBADD = \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
diff --git a/addressbook/backends/google/Makefile.am b/addressbook/backends/google/Makefile.am
index 5da07b1..6238c4e 100644
--- a/addressbook/backends/google/Makefile.am
+++ b/addressbook/backends/google/Makefile.am
@@ -34,6 +34,7 @@ libebookbackendgoogle_la_SOURCES = \
$(GOA_SOURCES)
libebookbackendgoogle_la_LIBADD = \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
diff --git a/addressbook/backends/google/e-book-google-utils.c b/addressbook/backends/google/e-book-google-utils.c
index db4d292..604bc6b 100644
--- a/addressbook/backends/google/e-book-google-utils.c
+++ b/addressbook/backends/google/e-book-google-utils.c
@@ -26,7 +26,7 @@
#include <errno.h>
#include <glib/gi18n-lib.h>
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
#include <gdata/gdata.h>
#include "e-book-google-utils.h"
diff --git a/addressbook/backends/google/tests/phone-numbers.c b/addressbook/backends/google/tests/phone-numbers.c
index b67fb66..a37f212 100644
--- a/addressbook/backends/google/tests/phone-numbers.c
+++ b/addressbook/backends/google/tests/phone-numbers.c
@@ -19,7 +19,7 @@
* Author: Philip Withnall <philip tecnocode co uk>
*/
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
#include <gdata/gdata.h>
#include "e-book-google-utils.h"
diff --git a/addressbook/backends/ldap/Makefile.am b/addressbook/backends/ldap/Makefile.am
index 5effe35..c0d9c7a 100644
--- a/addressbook/backends/ldap/Makefile.am
+++ b/addressbook/backends/ldap/Makefile.am
@@ -21,6 +21,7 @@ libebookbackendldap_la_SOURCES = \
e-source-ldap.h
libebookbackendldap_la_LIBADD = \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
diff --git a/addressbook/backends/webdav/Makefile.am b/addressbook/backends/webdav/Makefile.am
index 4c6d554..58ded89 100644
--- a/addressbook/backends/webdav/Makefile.am
+++ b/addressbook/backends/webdav/Makefile.am
@@ -19,6 +19,7 @@ libebookbackendwebdav_la_SOURCES = \
e-book-backend-webdav.c
libebookbackendwebdav_la_LIBADD = \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
diff --git a/addressbook/libebook-contacts/Makefile.am b/addressbook/libebook-contacts/Makefile.am
new file mode 100644
index 0000000..01c3d33
--- /dev/null
+++ b/addressbook/libebook-contacts/Makefile.am
@@ -0,0 +1,141 @@
+CLEANFILES=
+BUILT_SOURCES=
+
+ENUM_TYPES = e-book-contacts-types.h
+
+e-book-contacts-enumtypes.h: e-book-contacts-enumtypes.h.template $(ENUM_TYPES)
+ $(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template e-book-contacts-enumtypes.h.template $(ENUM_TYPES)) > $@
+
+e-book-contacts-enumtypes.c: e-book-contacts-enumtypes.c.template $(ENUM_TYPES)
+ $(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template e-book-contacts-enumtypes.c.template $(ENUM_TYPES)) > $@
+
+ENUM_GENERATED = e-book-contacts-enumtypes.h e-book-contacts-enumtypes.c
+
+# The marshallers
+MARSHAL_GENERATED = e-book-contacts-marshal.c e-book-contacts-marshal.h
+ EVO_MARSHAL_RULE@
+
+# The library
+lib_LTLIBRARIES = libebook-contacts-1.2.la
+
+libebook_contacts_1_2_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DLIBEBOOK_CONTACTS_COMPILATION \
+ -DLOCALEDIR=\""$(localedir)"\" \
+ -DG_LOG_DOMAIN=\"libebook-contacts\" \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/addressbook \
+ -I$(top_builddir) \
+ -I$(top_builddir)/addressbook \
+ $(EVOLUTION_ADDRESSBOOK_CFLAGS) \
+ $(CAMEL_CFLAGS) \
+ $(CODE_COVERAGE_CFLAGS) \
+ $(NULL)
+
+libebook_contacts_1_2_la_SOURCES = \
+ $(ENUM_GENERATED) \
+ $(MARSHAL_GENERATED) \
+ e-address-western.c \
+ e-name-western.c \
+ e-name-western-tables.h \
+ e-book-query.c \
+ e-contact.c \
+ e-vcard.c \
+ e-source-backend-summary-setup.c
+
+libebook_contacts_1_2_la_LIBADD = \
+ $(top_builddir)/camel/libcamel-1.2.la \
+ $(top_builddir)/libedataserver/libedataserver-1.2.la \
+ $(EVOLUTION_ADDRESSBOOK_LIBS) \
+ $(CAMEL_LIBS)
+
+libebook_contacts_1_2_la_LDFLAGS = \
+ -version-info $(LIBEBOOK_CONTACTS_CURRENT):$(LIBEBOOK_CONTACTS_REVISION):$(LIBEBOOK_CONTACTS_AGE) $(NO_UNDEFINED) \
+ $(CODE_COVERAGE_LDFLAGS) \
+ $(NULL)
+
+libebookcontactsincludedir = $(privincludedir)/libebook-contacts
+
+libebookcontactsinclude_HEADERS = \
+ libebook-contacts.h \
+ e-book-contacts-enumtypes.h \
+ e-book-contacts-types.h \
+ e-book-query.h \
+ e-address-western.h \
+ e-name-western.h \
+ e-contact.h \
+ e-vcard.h \
+ e-source-backend-summary-setup.h
+
+%-$(API_VERSION).pc: %.pc
+ cp $< $@
+
+e-name-western-tables.h: e-name-western-tables.h.in
+ $(AM_V_GEN) ($(PYTHON) ${srcdir}/gen-western-table.py < $< > $ tmp && mv $ tmp $@) || rm -f $ tmp
+
+BUILT_SOURCES += e-name-western-tables.h
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libebook-contacts-$(API_VERSION).pc
+
+
+-include $(INTROSPECTION_MAKEFILE)
+INTROSPECTION_GIRS =
+INTROSPECTION_SCANNER_ARGS = --add-include-path=$(top_builddir)/libedataserver \
+ --add-include-path=$(srcdir) --identifier-prefix=E --pkg-export \
+ libebook-contacts-1.2 --c-include="libebook-contacts/libebook-contacts.h" --warn-all
+INTROSPECTION_COMPILER_ARGS = --includedir=$(top_builddir)/libedataserver \
+ --includedir=$(srcdir)
+
+if HAVE_INTROSPECTION
+introspection_sources = $(libebook_contacts_1_2_la_SOURCES)
+EBookContacts-1.2.gir: libebook-contacts-1.2.la
+
+EBookContacts_1_2_gir_INCLUDES = GObject-2.0 GLib-2.0 libxml2-2.0 \
+ Gio-2.0 \
+ $(NULL)
+libxml_include = `$(PKG_CONFIG) --cflags libxml-2.0`
+EBookContacts_1_2_gir_CFLAGS = $(INCLUDES) \
+ $(libxml_include) \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/addressbook/ \
+ -I$(top_builddir)/addressbook/ \
+ -I$(top_srcdir)/addressbook/libebook-contacts \
+ -I$(top_builddir)/addressbook/libebook-contacts \
+ -DLIBEBOOK_CONTACTS_COMPILATION \
+ $(EVOLUTION_ADDRESSBOOK_CFLAGS) \
+ $(CAMEL_CFLAGS) \
+ $(NULL)
+EBookContacts_1_2_gir_SCANNERFLAGS = --include-uninstalled=$(top_builddir)/libedataserver/EDataServer-1.2.gir
+EBookContacts_1_2_gir_LIBS = \
+ libebook-contacts-1.2.la $(top_builddir)/libedataserver/libedataserver-1.2.la
+EBookContacts_1_2_gir_FILES = $(libebook_contacts_1_2_la_SOURCES) $(libebookcontactsinclude_HEADERS)
+
+INTROSPECTION_GIRS += EBookContacts-1.2.gir
+
+girdir = $(datadir)/gir-1.0
+dist_gir_DATA = $(INTROSPECTION_GIRS)
+
+typelibdir = $(libdir)/girepository-1.0
+typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+
+CLEANFILES += $(dist_gir_DATA) $(typelib_DATA)
+endif
+
+BUILT_SOURCES += $(ENUM_GENERATED) $(MARSHAL_GENERATED)
+CLEANFILES += $(BUILT_SOURCES)
+DISTCLEANFILES = $(pkgconfig_DATA)
+
+EXTRA_DIST = \
+ $(pkgconfig_DATA:-$(API_VERSION).pc=.pc.in) \
+ e-book-contacts-enumtypes.h.template \
+ e-book-contacts-enumtypes.c.template \
+ e-book-contacts-marshal.list \
+ e-name-western-tables.h.in \
+ gen-western-table.py
+
+dist-hook:
+ cd $(distdir); rm -f $(BUILT_SOURCES)
+
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/libebook/e-address-western.c b/addressbook/libebook-contacts/e-address-western.c
similarity index 100%
rename from addressbook/libebook/e-address-western.c
rename to addressbook/libebook-contacts/e-address-western.c
diff --git a/addressbook/libebook/e-address-western.h b/addressbook/libebook-contacts/e-address-western.h
similarity index 76%
rename from addressbook/libebook/e-address-western.h
rename to addressbook/libebook-contacts/e-address-western.h
index aab4c00..a4dd8de 100644
--- a/addressbook/libebook/e-address-western.h
+++ b/addressbook/libebook-contacts/e-address-western.h
@@ -1,5 +1,5 @@
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
#endif
#ifndef __E_ADDRESS_WESTERN_H__
diff --git a/addressbook/libebook-contacts/e-book-contacts-enumtypes.c.template b/addressbook/libebook-contacts/e-book-contacts-enumtypes.c.template
new file mode 100644
index 0000000..127154b
--- /dev/null
+++ b/addressbook/libebook-contacts/e-book-contacts-enumtypes.c.template
@@ -0,0 +1,38 @@
+/*** BEGIN file-header ***/
+#include "e-book-contacts-enumtypes.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+#include "@filename@"
+
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+ enum_name@_get_type (void)
+{
+ static GType the_type = 0;
+
+ if (the_type == 0) {
+ static const G Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@,
+ "@VALUENAME@",
+ "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ the_type = g_ type@_register_static (
+ g_intern_static_string ("@EnumName@"),
+ values);
+ }
+ return the_type;
+}
+
+/*** END value-tail ***/
diff --git a/addressbook/libebook-contacts/e-book-contacts-enumtypes.h.template b/addressbook/libebook-contacts/e-book-contacts-enumtypes.h.template
new file mode 100644
index 0000000..69ff145
--- /dev/null
+++ b/addressbook/libebook-contacts/e-book-contacts-enumtypes.h.template
@@ -0,0 +1,27 @@
+/*** BEGIN file-header ***/
+#ifndef E_BOOK_CONTACTS_ENUMTYPES_H
+#define E_BOOK_CONTACTS_ENUMTYPES_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* Enumerations from "@filename@" */
+
+/*** END file-production ***/
+
+/*** BEGIN enumeration-production ***/
+#define E_TYPE_ ENUMSHORT@ (@enum_name _get_type())
+GType @enum_name _get_type (void) G_GNUC_CONST;
+
+/*** END enumeration-production ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* E_BOOK_ENUMTYPES_H */
+/*** END file-tail ***/
+
diff --git a/addressbook/libebook-contacts/e-book-contacts-marshal.list b/addressbook/libebook-contacts/e-book-contacts-marshal.list
new file mode 100644
index 0000000..4f34146
--- /dev/null
+++ b/addressbook/libebook-contacts/e-book-contacts-marshal.list
@@ -0,0 +1,6 @@
+NONE:NONE
+NONE:BOOL
+NONE:POINTER
+NONE:STRING
+NONE:INT
+NONE:UINT,STRING
diff --git a/addressbook/libebook-contacts/e-book-contacts-types.h b/addressbook/libebook-contacts/e-book-contacts-types.h
new file mode 100644
index 0000000..0f2876d
--- /dev/null
+++ b/addressbook/libebook-contacts/e-book-contacts-types.h
@@ -0,0 +1,112 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * A client-side GObject which exposes the
+ * Evolution:BookListener interface.
+ *
+ * Author:
+ * Nat Friedman (nat ximian com)
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
+#endif
+
+#ifndef __E_BOOK_CONTACTS_TYPES_H__
+#define __E_BOOK_CONTACTS_TYPES_H__
+
+#include <libebook-contacts/e-contact.h>
+
+G_BEGIN_DECLS
+
+/**
+ * EBookClientViewFlags:
+ * @E_BOOK_CLIENT_VIEW_FLAGS_NONE:
+ * Symbolic value for no flags
+ * @E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL:
+ * If this flag is set then all contacts matching the view's query will
+ * be sent as notifications when starting the view, otherwise only future
+ * changes will be reported. The default for a #EBookClientView is %TRUE.
+ *
+ * Flags that control the behaviour of an #EBookClientView.
+ *
+ * Since: 3.4
+ */
+typedef enum {
+ E_BOOK_CLIENT_VIEW_FLAGS_NONE = 0,
+ E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL = (1 << 0),
+} EBookClientViewFlags;
+
+/**
+ * EDataBookStatus:
+ *
+ * XXX Document me!
+ *
+ * Since: 3.6
+ **/
+typedef enum {
+ E_DATA_BOOK_STATUS_SUCCESS,
+ E_DATA_BOOK_STATUS_BUSY,
+ 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,
+ E_DATA_BOOK_STATUS_INVALID_ARG,
+ E_DATA_BOOK_STATUS_NOT_SUPPORTED,
+ E_DATA_BOOK_STATUS_NOT_OPENED,
+ E_DATA_BOOK_STATUS_OUT_OF_SYNC
+} EDataBookStatus;
+
+typedef enum {
+ E_BOOK_VIEW_STATUS_OK,
+ E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED,
+ E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED,
+ E_BOOK_VIEW_ERROR_INVALID_QUERY,
+ E_BOOK_VIEW_ERROR_QUERY_REFUSED,
+ E_BOOK_VIEW_ERROR_OTHER_ERROR
+} EBookViewStatus;
+
+typedef enum {
+ E_BOOK_CHANGE_CARD_ADDED,
+ E_BOOK_CHANGE_CARD_DELETED,
+ E_BOOK_CHANGE_CARD_MODIFIED
+} EBookChangeType;
+
+typedef struct {
+ EBookChangeType change_type;
+ EContact *contact;
+} EBookChange;
+
+
+/**
+ * EBookIndexType:
+ * @E_BOOK_INDEX_PREFIX: An index suitable for searching contacts with a prefix pattern
+ * @E_BOOK_INDEX_SUFFIX: An index suitable for searching contacts with a suffix pattern
+ *
+ * The type of index defined by e_source_backend_summary_setup_set_indexed_fields()
+ */
+typedef enum {
+ E_BOOK_INDEX_PREFIX = 0,
+ E_BOOK_INDEX_SUFFIX
+} EBookIndexType;
+
+G_END_DECLS
+
+#endif /* __E_BOOK_CONTACTS_TYPES_H__ */
diff --git a/addressbook/libebook/e-book-query.c b/addressbook/libebook-contacts/e-book-query.c
similarity index 100%
rename from addressbook/libebook/e-book-query.c
rename to addressbook/libebook-contacts/e-book-query.c
diff --git a/addressbook/libebook/e-book-query.h b/addressbook/libebook-contacts/e-book-query.h
similarity index 90%
rename from addressbook/libebook/e-book-query.h
rename to addressbook/libebook-contacts/e-book-query.h
index 59c8987..d5a842f 100644
--- a/addressbook/libebook/e-book-query.h
+++ b/addressbook/libebook-contacts/e-book-query.h
@@ -1,12 +1,12 @@
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
#endif
#ifndef __E_BOOK_QUERY_H__
#define __E_BOOK_QUERY_H__
-#include <libebook/e-contact.h>
+#include <libebook-contacts/e-contact.h>
G_BEGIN_DECLS
diff --git a/addressbook/libebook/e-contact.c b/addressbook/libebook-contacts/e-contact.c
similarity index 99%
rename from addressbook/libebook/e-contact.c
rename to addressbook/libebook-contacts/e-contact.c
index b918d57..3749b67 100644
--- a/addressbook/libebook/e-contact.c
+++ b/addressbook/libebook-contacts/e-contact.c
@@ -30,7 +30,6 @@
#include <gio/gio.h>
#include <glib/gi18n-lib.h>
#include "e-contact.h"
-#include "e-book.h"
#include "e-name-western.h"
#ifdef G_OS_WIN32
diff --git a/addressbook/libebook/e-contact.h b/addressbook/libebook-contacts/e-contact.h
similarity index 98%
rename from addressbook/libebook/e-contact.h
rename to addressbook/libebook-contacts/e-contact.h
index 3e56547..e698aa6 100644
--- a/addressbook/libebook/e-contact.h
+++ b/addressbook/libebook-contacts/e-contact.h
@@ -6,8 +6,8 @@
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*/
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
#endif
#ifndef E_CONTACT_H
@@ -15,7 +15,7 @@
#include <time.h>
#include <stdio.h>
-#include <libebook/e-vcard.h>
+#include <libebook-contacts/e-vcard.h>
/* Standard GObject macros */
#define E_TYPE_CONTACT \
diff --git a/addressbook/libebook/e-name-western-tables.h b/addressbook/libebook-contacts/e-name-western-tables.h
similarity index 100%
rename from addressbook/libebook/e-name-western-tables.h
rename to addressbook/libebook-contacts/e-name-western-tables.h
diff --git a/addressbook/libebook/e-name-western-tables.h.in b/addressbook/libebook-contacts/e-name-western-tables.h.in
similarity index 100%
rename from addressbook/libebook/e-name-western-tables.h.in
rename to addressbook/libebook-contacts/e-name-western-tables.h.in
diff --git a/addressbook/libebook/e-name-western.c b/addressbook/libebook-contacts/e-name-western.c
similarity index 100%
rename from addressbook/libebook/e-name-western.c
rename to addressbook/libebook-contacts/e-name-western.c
diff --git a/addressbook/libebook/e-name-western.h b/addressbook/libebook-contacts/e-name-western.h
similarity index 71%
rename from addressbook/libebook/e-name-western.h
rename to addressbook/libebook-contacts/e-name-western.h
index e2515bf..e1e6f1e 100644
--- a/addressbook/libebook/e-name-western.h
+++ b/addressbook/libebook-contacts/e-name-western.h
@@ -1,8 +1,8 @@
#ifndef __E_NAME_WESTERN_H__
#define __E_NAME_WESTERN_H__
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
#endif
#include <glib.h>
diff --git a/addressbook/libebook/e-source-backend-summary-setup.c b/addressbook/libebook-contacts/e-source-backend-summary-setup.c
similarity index 99%
rename from addressbook/libebook/e-source-backend-summary-setup.c
rename to addressbook/libebook-contacts/e-source-backend-summary-setup.c
index 018a941..fc134a9 100644
--- a/addressbook/libebook/e-source-backend-summary-setup.c
+++ b/addressbook/libebook-contacts/e-source-backend-summary-setup.c
@@ -22,7 +22,7 @@
/**
* SECTION: e-source-backend-summary-setup
- * @include: libebook/libebook.h
+ * @include: libebook-contacts/libebook-contacts.h
* @short_description: #ESource extension to configure summary fields
*
* The #ESourceBackendSummarySetup extension configures which #EContactFields
@@ -32,7 +32,7 @@
* Access the extension as follows:
*
* |[
- * #include <libebook/libebook.h>
+ * #include <libebook-contacts/libebook-contacts.h>
*
* ESourceBackendSummarySetup *extension;
*
@@ -46,7 +46,7 @@
**/
#include "e-source-backend-summary-setup.h"
-#include "e-book-enumtypes.h"
+#include "e-book-contacts-enumtypes.h"
#define E_SOURCE_BACKEND_SUMMARY_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
diff --git a/addressbook/libebook/e-source-backend-summary-setup.h b/addressbook/libebook-contacts/e-source-backend-summary-setup.h
similarity index 93%
rename from addressbook/libebook/e-source-backend-summary-setup.h
rename to addressbook/libebook-contacts/e-source-backend-summary-setup.h
index ecea646..8950a0e 100644
--- a/addressbook/libebook/e-source-backend-summary-setup.h
+++ b/addressbook/libebook-contacts/e-source-backend-summary-setup.h
@@ -20,16 +20,16 @@
* Authors: Tristan Van Berkom <tristanvb openismus com>
*/
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
#endif
#ifndef E_SOURCE_BACKEND_SUMMARY_SETUP_H
#define E_SOURCE_BACKEND_SUMMARY_SETUP_H
#include <libedataserver/libedataserver.h>
-#include <libebook/e-contact.h>
-#include <libebook/e-book-types.h>
+#include <libebook-contacts/e-contact.h>
+#include <libebook-contacts/e-book-contacts-types.h>
/* Standard GObject macros */
#define E_TYPE_SOURCE_BACKEND_SUMMARY_SETUP \
diff --git a/addressbook/libebook/e-vcard.c b/addressbook/libebook-contacts/e-vcard.c
similarity index 100%
rename from addressbook/libebook/e-vcard.c
rename to addressbook/libebook-contacts/e-vcard.c
diff --git a/addressbook/libebook/e-vcard.h b/addressbook/libebook-contacts/e-vcard.h
similarity index 98%
rename from addressbook/libebook/e-vcard.h
rename to addressbook/libebook-contacts/e-vcard.h
index 5f4156c..9a39c0f 100644
--- a/addressbook/libebook/e-vcard.h
+++ b/addressbook/libebook-contacts/e-vcard.h
@@ -20,8 +20,8 @@
* Author: Chris Toshok (toshok ximian com)
*/
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
#endif
#ifndef _EVCARD_H
diff --git a/addressbook/libebook/gen-western-table.py b/addressbook/libebook-contacts/gen-western-table.py
similarity index 100%
rename from addressbook/libebook/gen-western-table.py
rename to addressbook/libebook-contacts/gen-western-table.py
diff --git a/addressbook/libebook-contacts/libebook-contacts.h b/addressbook/libebook-contacts/libebook-contacts.h
new file mode 100644
index 0000000..92f95f3
--- /dev/null
+++ b/addressbook/libebook-contacts/libebook-contacts.h
@@ -0,0 +1,38 @@
+/*
+ * libebook-contacts.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef LIBEBOOK_CONTACTS_H
+#define LIBEBOOK_CONTACTS_H
+
+#define __LIBEBOOK_CONTACTS_H_INSIDE__
+
+#include <libedataserver/libedataserver.h>
+
+#include <libebook-contacts/e-book-contacts-types.h>
+#include <libebook-contacts/e-book-query.h>
+#include <libebook-contacts/e-name-western.h>
+#include <libebook-contacts/e-address-western.h>
+#include <libebook-contacts/e-contact.h>
+#include <libebook-contacts/e-vcard.h>
+#include <libebook-contacts/e-book-contacts-enumtypes.h>
+#include <libebook-contacts/e-source-backend-summary-setup.h>
+
+#undef __LIBEBOOK_CONTACTS_H_INSIDE__
+
+#endif /* LIBEBOOK_CONTACTS_H */
+
diff --git a/addressbook/libebook-contacts/libebook-contacts.pc.in b/addressbook/libebook-contacts/libebook-contacts.pc.in
new file mode 100644
index 0000000..d1396fb
--- /dev/null
+++ b/addressbook/libebook-contacts/libebook-contacts.pc.in
@@ -0,0 +1,16 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+datarootdir= datarootdir@
+datadir= datadir@
+
+privincludedir= privincludedir@
+
+Name: libebook-contacts
+Description: Client library for evolution contacts and vcard structures
+Version: @VERSION@
+Requires: libedataserver-1.2
+Requires.private: camel-1.2
+Libs: -L${libdir} -lebook-contacts-1.2
+Cflags: -I${privincludedir}
diff --git a/addressbook/libebook/Makefile.am b/addressbook/libebook/Makefile.am
index 5e29354..e188256 100644
--- a/addressbook/libebook/Makefile.am
+++ b/addressbook/libebook/Makefile.am
@@ -38,25 +38,22 @@ libebook_1_2_la_CPPFLAGS = \
libebook_1_2_la_SOURCES = \
$(ENUM_GENERATED) \
$(MARSHAL_GENERATED) \
- e-address-western.c \
e-book-client.c \
e-book-client-view.c \
- e-book-query.c \
e-book-view-private.h \
e-book-view.c \
e-book.c \
- e-contact.c \
e-destination.c \
- e-name-western.c \
- e-name-western-tables.h \
- e-source-backend-summary-setup.c \
- e-vcard.c \
e-error.h
libebook_1_2_la_LIBADD = \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
+ $(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
$(top_builddir)/addressbook/libegdbus/libegdbus-book.la \
$(top_builddir)/camel/libcamel-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
+ $(top_builddir)/libebackend/libebackend-1.2.la \
+ $(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
$(EVOLUTION_ADDRESSBOOK_LIBS) \
$(CAMEL_LIBS)
@@ -69,28 +66,16 @@ libebookincludedir = $(privincludedir)/libebook
libebookinclude_HEADERS = \
libebook.h \
- e-address-western.h \
e-book-client.h \
e-book-client-view.h \
e-book-enumtypes.h \
- e-book-query.h \
e-book-view.h \
e-book-types.h \
- e-book.h \
- e-contact.h \
- e-destination.h \
- e-name-western.h \
- e-source-backend-summary-setup.h \
- e-vcard.h
+ e-book.h
%-$(API_VERSION).pc: %.pc
cp $< $@
-e-name-western-tables.h: e-name-western-tables.h.in
- $(AM_V_GEN) ($(PYTHON) ${srcdir}/gen-western-table.py < $< > $ tmp && mv $ tmp $@) || rm -f $ tmp
-
-BUILT_SOURCES += e-name-western-tables.h
-
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libebook-$(API_VERSION).pc
@@ -105,6 +90,7 @@ INTROSPECTION_SCANNER_ARGS = \
--c-include="libebook/libebook.h" \
$(NULL)
INTROSPECTION_COMPILER_ARGS = \
+ --includedir=$(top_builddir)/addressbook/libebook-contacts \
--includedir=$(top_builddir)/libedataserver \
--includedir=$(srcdir) \
$(NULL)
@@ -130,15 +116,15 @@ EBook_1_2_gir_CFLAGS = \
$(NULL)
EBook_1_2_gir_SCANNERFLAGS = \
--include-uninstalled=$(top_builddir)/libedataserver/EDataServer-1.2.gir \
+ --include-uninstalled=$(top_builddir)/addressbook/libebook-contacts/EBookContacts-1.2.gir \
$(NULL)
EBook_1_2_gir_LIBS = \
- libebook-1.2.la \
- $(top_builddir)/libedataserver/libedataserver-1.2.la \
- $(NULL)
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
+ $(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
+ libebook-1.2.la $(top_builddir)/libedataserver/libedataserver-1.2.la
EBook_1_2_gir_FILES = \
$(libebook_1_2_la_SOURCES) \
- $(libebookinclude_HEADERS) \
- $(NULL)
+ $(libebookinclude_HEADERS)
INTROSPECTION_GIRS += EBook-1.2.gir
diff --git a/addressbook/libebook/e-book-client-view.h b/addressbook/libebook/e-book-client-view.h
index 176df48..72a3344 100644
--- a/addressbook/libebook/e-book-client-view.h
+++ b/addressbook/libebook/e-book-client-view.h
@@ -55,24 +55,6 @@ typedef struct _EBookClientViewPrivate EBookClientViewPrivate;
struct _EBookClient;
/**
- * EBookClientViewFlags:
- * @E_BOOK_CLIENT_VIEW_FLAGS_NONE:
- * Symbolic value for no flags
- * @E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL:
- * If this flag is set then all contacts matching the view's query will
- * be sent as notifications when starting the view, otherwise only future
- * changes will be reported. The default for a #EBookClientView is %TRUE.
- *
- * Flags that control the behaviour of an #EBookClientView.
- *
- * Since: 3.4
- */
-typedef enum {
- E_BOOK_CLIENT_VIEW_FLAGS_NONE = 0,
- E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL = (1 << 0),
-} EBookClientViewFlags;
-
-/**
* EBookClientView:
*
* Contains only private data the should be read and manipulated using the
diff --git a/addressbook/libebook/e-book-client.c b/addressbook/libebook/e-book-client.c
index af2d4d1..ef46dcc 100644
--- a/addressbook/libebook/e-book-client.c
+++ b/addressbook/libebook/e-book-client.c
@@ -29,12 +29,15 @@
#include <libedataserver/libedataserver.h>
#include <libedataserver/e-client-private.h>
+#include <libebackend/libebackend.h>
+#include <libedata-book/libedata-book.h>
+
#include "e-book-client.h"
-#include "e-contact.h"
-#include "e-name-western.h"
#include "e-gdbus-book.h"
#include "e-gdbus-book-factory.h"
+#include "e-gdbus-book-view.h"
+#include "e-gdbus-book-direct.h"
#define E_BOOK_CLIENT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -43,6 +46,8 @@
struct _EBookClientPrivate {
GDBusProxy *dbus_proxy;
guint gone_signal_id;
+
+ EDataBook *direct_book;
};
G_DEFINE_TYPE (EBookClient, e_book_client, E_TYPE_CLIENT)
@@ -185,6 +190,71 @@ static GRecMutex book_factory_lock;
static void gdbus_book_factory_closed_cb (GDBusConnection *connection, gboolean remote_peer_vanished, GError *error, gpointer user_data);
+
+typedef struct {
+ EBookClient *client;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+ gpointer source_tag;
+ GCancellable *cancellable; /* Cancellable and only-if-exists only used */
+ gboolean only_if_exists; /* for chaining the async open call into 2 calls */
+} PropagateReadyData;
+
+static PropagateReadyData *
+propagate_ready_data_new (EBookClient *client,
+ GAsyncReadyCallback callback,
+ gpointer user_data,
+ gpointer source_tag,
+ GCancellable *cancellable)
+{
+ PropagateReadyData *data = g_slice_new0 (PropagateReadyData);
+
+ data->client = g_object_ref (client);
+ data->callback = callback;
+ data->user_data = user_data;
+ data->source_tag = source_tag;
+
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
+
+ return data;
+}
+
+static void
+propagate_ready_data_free (PropagateReadyData *data)
+{
+ if (data) {
+ g_object_unref (data->client);
+
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+
+ g_slice_free (PropagateReadyData, data);
+ }
+}
+
+static void
+propagate_direct_book_async_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+ PropagateReadyData *data = (PropagateReadyData *)user_data;
+
+ result = g_simple_async_result_new (G_OBJECT (data->client),
+ data->callback,
+ data->user_data,
+ data->source_tag);
+
+ g_object_ref (res);
+ g_simple_async_result_set_op_res_gpointer (result, res, g_object_unref);
+
+ g_simple_async_result_complete (result);
+ g_object_unref (result);
+
+ propagate_ready_data_free (data);
+}
+
static void
gdbus_book_factory_disconnect (GDBusConnection *connection)
{
@@ -478,13 +548,21 @@ static void
book_client_dispose (GObject *object)
{
EClient *client;
+ EBookClient *book_client;
client = E_CLIENT (object);
+ book_client = E_BOOK_CLIENT (object);
e_client_cancel_all (client);
gdbus_book_client_disconnect (E_BOOK_CLIENT (client));
+ if (book_client->priv->direct_book) {
+ e_data_book_close_sync (book_client->priv->direct_book, NULL, NULL);
+ g_object_unref (book_client->priv->direct_book);
+ book_client->priv->direct_book = NULL;
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_book_client_parent_class)->dispose (object);
}
@@ -713,6 +791,43 @@ book_client_set_backend_property_sync (EClient *client,
return res;
}
+
+static void book_client_open (EClient *client,
+ gboolean only_if_exists,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+static void
+direct_book_async_opened (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ PropagateReadyData *data = (PropagateReadyData *)user_data;
+ GError *error = NULL;
+
+ if (e_data_book_open_finish (E_DATA_BOOK (source_object), res, &error)) {
+
+ /* Open direct book succeeded, now proceed to open the real book over D-Bus */
+ e_client_proxy_call_boolean (E_CLIENT (data->client), data->only_if_exists,
+ data->cancellable, data->callback, data->user_data, book_client_open,
+ e_gdbus_book_call_open, e_gdbus_book_call_open_finish,
+ NULL, NULL, NULL, NULL);
+ } else {
+ /* Open failed, report error right away */
+ GSimpleAsyncResult *result;
+
+ result = g_simple_async_result_new_take_error (G_OBJECT (data->client),
+ data->callback,
+ data->user_data,
+ error);
+ g_simple_async_result_complete (result);
+ g_object_unref (result);
+ }
+
+ propagate_ready_data_free (data);
+}
+
static void
book_client_open (EClient *client,
gboolean only_if_exists,
@@ -720,13 +835,35 @@ book_client_open (EClient *client,
GAsyncReadyCallback callback,
gpointer user_data)
{
- e_client_proxy_call_boolean (
- client, only_if_exists,
- cancellable, callback, user_data,
- book_client_open,
- e_gdbus_book_call_open,
- e_gdbus_book_call_open_finish,
- NULL, NULL, NULL, NULL);
+ EBookClient *book_client;
+ PropagateReadyData *data;
+
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
+
+ book_client = E_BOOK_CLIENT (client);
+
+ if (book_client->priv->direct_book) {
+ data = propagate_ready_data_new (book_client,
+ callback,
+ user_data,
+ book_client_open,
+ cancellable);
+ data->only_if_exists = only_if_exists;
+
+ e_data_book_open (book_client->priv->direct_book,
+ only_if_exists,
+ cancellable,
+ direct_book_async_opened,
+ data);
+ } else {
+ e_client_proxy_call_boolean (
+ client, only_if_exists,
+ cancellable, callback, user_data,
+ book_client_open,
+ e_gdbus_book_call_open,
+ e_gdbus_book_call_open_finish,
+ NULL, NULL, NULL, NULL);
+ }
}
static gboolean
@@ -755,9 +892,14 @@ book_client_open_sync (EClient *client,
return FALSE;
}
+ if (book_client->priv->direct_book &&
+ !e_data_book_open_sync (book_client->priv->direct_book,
+ only_if_exists, cancellable, error))
+ return FALSE;
+
return e_client_proxy_call_sync_boolean__void (
- client, only_if_exists, cancellable, error,
- e_gdbus_book_call_open_sync);
+ client, only_if_exists, cancellable, error,
+ e_gdbus_book_call_open_sync);
}
static void
@@ -964,6 +1106,62 @@ e_book_client_new (ESource *source,
return client;
}
+/**
+ * e_book_client_new_direct:
+ * @source: An #ESource pointer
+ * @error: A #GError pointer
+ *
+ * Like e_book_client_new(), except creates the book client for
+ * direct read access to the underlying addressbook.
+ *
+ * Returns: a new but unopened #EBookClient.
+ *
+ * Since: 3.8
+ **/
+EBookClient *
+e_book_client_new_direct (ESourceRegistry *registry,
+ ESource *source,
+ GError **error)
+{
+ EBookClient *client;
+ EGdbusBookDirect *direct_config;
+ const gchar *backend_name, *backend_path, *config;
+
+ client = e_book_client_new (source, error);
+
+ if (!client)
+ return NULL;
+
+ direct_config =
+ e_gdbus_book_direct_proxy_new_sync (
+ g_dbus_proxy_get_connection (client->priv->dbus_proxy),
+ G_DBUS_PROXY_FLAGS_NONE,
+ ADDRESS_BOOK_DBUS_SERVICE_NAME,
+ g_dbus_proxy_get_object_path (client->priv->dbus_proxy),
+ NULL, NULL);
+
+ backend_path = e_gdbus_book_direct_get_backend_path (direct_config);
+ backend_name = e_gdbus_book_direct_get_backend_name (direct_config);
+ config = e_gdbus_book_direct_get_backend_config (direct_config);
+
+ if (backend_path && backend_path[0] &&
+ backend_name && backend_name[0]) {
+ client->priv->direct_book =
+ e_data_book_new_direct (registry, source,
+ backend_path,
+ backend_name,
+ config);
+ if (!client->priv->direct_book)
+ g_warning ("Failed to open addressbook in direct read access mode, falling back to normal read access mode");
+
+ } else
+ g_warning ("Direct read access mode not supported by the given backend, falling back to normal read access mode");
+
+ g_object_unref (direct_config);
+
+ return client;
+}
+
#define SELF_UID_PATH_ID "org.gnome.evolution-data-server.addressbook"
#define SELF_UID_KEY "self-contact-uid"
@@ -2031,6 +2229,15 @@ e_book_client_get_contact (EBookClient *client,
g_return_if_fail (uid != NULL);
+ if (client->priv->direct_book) {
+ PropagateReadyData *data = propagate_ready_data_new (client, callback, user_data,
+ e_book_client_get_contact, NULL);
+
+ e_data_book_get_contact (client->priv->direct_book, uid, cancellable,
+ propagate_direct_book_async_ready, data);
+ return;
+ }
+
safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
g_return_if_fail (safe_uid != NULL);
@@ -2072,6 +2279,12 @@ e_book_client_get_contact_finish (EBookClient *client,
g_return_val_if_fail (contact != NULL, FALSE);
+ if (client->priv->direct_book) {
+ GAsyncResult *res = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+ return e_data_book_get_contact_finish (client->priv->direct_book, res, contact, error);
+ }
+
res = e_client_proxy_call_finish_string (
E_CLIENT (client),
result, &vcard, error,
@@ -2118,6 +2331,9 @@ e_book_client_get_contact_sync (EBookClient *client,
g_return_val_if_fail (uid != NULL, FALSE);
g_return_val_if_fail (contact != NULL, FALSE);
+ if (client->priv->direct_book)
+ return e_data_book_get_contact_sync (client->priv->direct_book, uid, contact, cancellable, error);
+
if (client->priv->dbus_proxy == NULL) {
set_proxy_gone_error (error);
return FALSE;
@@ -2170,6 +2386,15 @@ e_book_client_get_contacts (EBookClient *client,
g_return_if_fail (sexp != NULL);
+ if (client->priv->direct_book) {
+ PropagateReadyData *data = propagate_ready_data_new (client, callback, user_data,
+ e_book_client_get_contacts, NULL);
+
+ e_data_book_get_contacts (client->priv->direct_book, sexp, cancellable,
+ propagate_direct_book_async_ready, data);
+ return;
+ }
+
e_client_proxy_call_string (
E_CLIENT (client),
e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
@@ -2209,6 +2434,14 @@ e_book_client_get_contacts_finish (EBookClient *client,
g_return_val_if_fail (contacts != NULL, FALSE);
+ if (client->priv->direct_book) {
+ GAsyncResult *direct_res =
+ g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+ return e_data_book_get_contacts_finish (client->priv->direct_book,
+ direct_res, contacts, error);
+ }
+
res = e_client_proxy_call_finish_strv (
E_CLIENT (client),
result, &vcards, error,
@@ -2266,6 +2499,10 @@ e_book_client_get_contacts_sync (EBookClient *client,
g_return_val_if_fail (sexp != NULL, FALSE);
g_return_val_if_fail (contacts != NULL, FALSE);
+ if (client->priv->direct_book)
+ return e_data_book_get_contacts_sync (client->priv->direct_book,
+ sexp, contacts, cancellable, error);
+
if (client->priv->dbus_proxy == NULL) {
set_proxy_gone_error (error);
return FALSE;
@@ -2324,6 +2561,15 @@ e_book_client_get_contacts_uids (EBookClient *client,
g_return_if_fail (sexp != NULL);
+ if (client->priv->direct_book) {
+ PropagateReadyData *data = propagate_ready_data_new (client, callback, user_data,
+ e_book_client_get_contacts_uids, NULL);
+
+ e_data_book_get_contacts_uids (client->priv->direct_book, sexp, cancellable,
+ propagate_direct_book_async_ready, data);
+ return;
+ }
+
e_client_proxy_call_string (
E_CLIENT (client),
e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
@@ -2363,6 +2609,14 @@ e_book_client_get_contacts_uids_finish (EBookClient *client,
g_return_val_if_fail (contacts_uids != NULL, FALSE);
+ if (client->priv->direct_book) {
+ GAsyncResult *direct_res =
+ g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+ return e_data_book_get_contacts_uids_finish (client->priv->direct_book,
+ direct_res, contacts_uids, error);
+ }
+
res = e_client_proxy_call_finish_strv (
E_CLIENT (client),
result, &uids, error,
@@ -2420,6 +2674,9 @@ e_book_client_get_contacts_uids_sync (EBookClient *client,
g_return_val_if_fail (sexp != NULL, FALSE);
g_return_val_if_fail (contacts_uids != NULL, FALSE);
+ if (client->priv->direct_book)
+ return e_data_book_get_contacts_uids_sync (client->priv->direct_book, sexp, contacts_uids, cancellable, error);
+
if (client->priv->dbus_proxy == NULL) {
set_proxy_gone_error (error);
return FALSE;
diff --git a/addressbook/libebook/e-book-client.h b/addressbook/libebook/e-book-client.h
index 26da1d6..085fbf3 100644
--- a/addressbook/libebook/e-book-client.h
+++ b/addressbook/libebook/e-book-client.h
@@ -27,9 +27,9 @@
#define E_BOOK_CLIENT_H
#include <libedataserver/libedataserver.h>
+#include <libebook-contacts/libebook-contacts.h>
#include <libebook/e-book-client-view.h>
-#include <libebook/e-contact.h>
/* Standard GObject macros */
#define E_TYPE_BOOK_CLIENT \
@@ -123,6 +123,9 @@ GError * e_book_client_error_create (EBookClientError code,
GType e_book_client_get_type (void) G_GNUC_CONST;
EBookClient * e_book_client_new (ESource *source,
GError **error);
+EBookClient * e_book_client_new_direct (ESourceRegistry *registry,
+ ESource *source,
+ GError **error);
gboolean e_book_client_get_self (ESourceRegistry *registry,
EContact **contact,
EBookClient **client,
diff --git a/addressbook/libebook/e-book-types.h b/addressbook/libebook/e-book-types.h
index f7d896f..0ba8067 100644
--- a/addressbook/libebook/e-book-types.h
+++ b/addressbook/libebook/e-book-types.h
@@ -16,7 +16,7 @@
#ifndef __E_BOOK_TYPES_H__
#define __E_BOOK_TYPES_H__
-#include <libebook/e-contact.h>
+#include <libebook-contacts/libebook-contacts.h>
G_BEGIN_DECLS
@@ -52,80 +52,9 @@ typedef enum {
E_BOOK_ERROR_NOT_SUPPORTED
} EBookStatus;
-/**
- * EDataBookStatus:
- *
- * XXX Document me!
- *
- * Since: 3.6
- **/
-typedef enum {
- E_DATA_BOOK_STATUS_SUCCESS,
- E_DATA_BOOK_STATUS_BUSY,
- 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,
- E_DATA_BOOK_STATUS_INVALID_ARG,
- E_DATA_BOOK_STATUS_NOT_SUPPORTED,
- E_DATA_BOOK_STATUS_NOT_OPENED,
- E_DATA_BOOK_STATUS_OUT_OF_SYNC
-} EDataBookStatus;
-
-#ifndef EDS_DISABLE_DEPRECATED
+#ifndef E_BOOK_DISABLE_DEPRECATED
#define E_BOOK_ERROR_CORBA_EXCEPTION E_BOOK_ERROR_DBUS_EXCEPTION
#endif
-typedef enum {
- E_BOOK_VIEW_STATUS_OK,
- E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED,
- E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED,
- E_BOOK_VIEW_ERROR_INVALID_QUERY,
- E_BOOK_VIEW_ERROR_QUERY_REFUSED,
- E_BOOK_VIEW_ERROR_OTHER_ERROR
-} EBookViewStatus;
-
-typedef enum {
- E_BOOK_CHANGE_CARD_ADDED,
- E_BOOK_CHANGE_CARD_DELETED,
- E_BOOK_CHANGE_CARD_MODIFIED
-} EBookChangeType;
-
-typedef struct {
- EBookChangeType change_type;
- EContact *contact;
-} EBookChange;
-
-/**
- * EBookIndexType:
- * @E_BOOK_INDEX_PREFIX: An index suitable for searching contacts with a prefix pattern
- * @E_BOOK_INDEX_SUFFIX: An index suitable for searching contacts with a suffix pattern
- *
- * The type of index defined for e_source_backend_summary_setup_set_indexed_fields()
- *
- * Since: 3.8
- */
-typedef enum {
- E_BOOK_INDEX_PREFIX = 0,
- E_BOOK_INDEX_SUFFIX
-} EBookIndexType;
-
-G_END_DECLS
#endif /* __E_BOOK_TYPES_H__ */
diff --git a/addressbook/libebook/e-book.c b/addressbook/libebook/e-book.c
index 3f7af4a..8829778 100644
--- a/addressbook/libebook/e-book.c
+++ b/addressbook/libebook/e-book.c
@@ -40,8 +40,6 @@
#include <glib/gi18n-lib.h>
#include "e-book.h"
#include "e-error.h"
-#include "e-contact.h"
-#include "e-name-western.h"
#include "e-book-view-private.h"
#include "e-book-marshal.h"
diff --git a/addressbook/libebook/e-book.h b/addressbook/libebook/e-book.h
index 91d12e8..868d07b 100644
--- a/addressbook/libebook/e-book.h
+++ b/addressbook/libebook/e-book.h
@@ -21,9 +21,8 @@
#define __E_BOOK_H__
#include <libedataserver/libedataserver.h>
+#include <libebook-contacts/libebook-contacts.h>
-#include <libebook/e-contact.h>
-#include <libebook/e-book-query.h>
#include <libebook/e-book-view.h>
#include <libebook/e-book-types.h>
diff --git a/addressbook/libebook/e-destination.h b/addressbook/libebook/e-destination.h
index 7cb65c5..7526037 100644
--- a/addressbook/libebook/e-destination.h
+++ b/addressbook/libebook/e-destination.h
@@ -32,8 +32,8 @@
#ifndef __E_DESTINATION_H__
#define __E_DESTINATION_H__
+#include <libebook-contacts/libebook-contacts.h>
#include <libebook/e-book.h>
-#include <libebook/e-contact.h>
#include <libebook/e-book-client.h>
#include <libxml/tree.h>
diff --git a/addressbook/libebook/libebook.h b/addressbook/libebook/libebook.h
index b1ddffc..ae1ad0e 100644
--- a/addressbook/libebook/libebook.h
+++ b/addressbook/libebook/libebook.h
@@ -22,20 +22,15 @@
#define __LIBEBOOK_H_INSIDE__
#include <libedataserver/libedataserver.h>
+#include <libebook-contacts/libebook-contacts.h>
-#include <libebook/e-address-western.h>
#include <libebook/e-book-client-view.h>
#include <libebook/e-book-client.h>
#include <libebook/e-book-enumtypes.h>
-#include <libebook/e-book-query.h>
#include <libebook/e-book-types.h>
#include <libebook/e-book-view.h>
#include <libebook/e-book.h>
-#include <libebook/e-contact.h>
#include <libebook/e-destination.h>
-#include <libebook/e-name-western.h>
-#include <libebook/e-source-backend-summary-setup.h>
-#include <libebook/e-vcard.h>
#undef __LIBEBOOK_H_INSIDE__
diff --git a/addressbook/libebook/libebook.pc.in b/addressbook/libebook/libebook.pc.in
index 993870b..81b5afd 100644
--- a/addressbook/libebook/libebook.pc.in
+++ b/addressbook/libebook/libebook.pc.in
@@ -10,7 +10,7 @@ privincludedir= privincludedir@
Name: libebook
Description: Client library for evolution address books
Version: @VERSION@
-Requires: libedataserver-1.2
+Requires: libedataserver-1.2 libebook-contacts-1.2
Requires.private: camel-1.2
Libs: -L${libdir} -lebook-1.2
Cflags: -I${privincludedir}
diff --git a/addressbook/libedata-book/Makefile.am b/addressbook/libedata-book/Makefile.am
index 8c422b3..fa3ab00 100644
--- a/addressbook/libedata-book/Makefile.am
+++ b/addressbook/libedata-book/Makefile.am
@@ -30,10 +30,11 @@ libedata_book_1_2_la_SOURCES = \
e-data-book.c \
e-data-book-factory.c \
e-data-book-view.c \
+ e-data-book-direct.c \
ximian-vcard.h
libedata_book_1_2_la_LIBADD = \
- $(top_builddir)/addressbook/libebook/libebook-1.2.la \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
$(top_builddir)/addressbook/libegdbus/libegdbus-book.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
$(top_builddir)/libebackend/libebackend-1.2.la \
@@ -58,6 +59,7 @@ libedata_bookinclude_HEADERS = \
e-book-backend.h \
e-data-book-factory.h \
e-data-book-view.h \
+ e-data-book-direct.h \
e-data-book.h \
e-book-backend-cache.h \
e-book-backend-sqlitedb.h \
diff --git a/addressbook/libedata-book/e-book-backend-cache.h b/addressbook/libedata-book/e-book-backend-cache.h
index 35b3d0f..ed0163a 100644
--- a/addressbook/libedata-book/e-book-backend-cache.h
+++ b/addressbook/libedata-book/e-book-backend-cache.h
@@ -27,7 +27,7 @@
#ifndef E_BOOK_BACKEND_CACHE_H
#define E_BOOK_BACKEND_CACHE_H
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
#include <libebackend/libebackend.h>
/* Standard GObject macros */
diff --git a/addressbook/libedata-book/e-book-backend-db-cache.h b/addressbook/libedata-book/e-book-backend-db-cache.h
index b26e5f1..41c47fb 100644
--- a/addressbook/libedata-book/e-book-backend-db-cache.h
+++ b/addressbook/libedata-book/e-book-backend-db-cache.h
@@ -26,7 +26,7 @@
#ifndef E_BOOK_BACKEND_DB_CACHE_H
#define E_BOOK_BACKEND_DB_CACHE_H
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
G_BEGIN_DECLS
diff --git a/addressbook/libedata-book/e-book-backend-sexp.h b/addressbook/libedata-book/e-book-backend-sexp.h
index cf98bbf..9f58207 100644
--- a/addressbook/libedata-book/e-book-backend-sexp.h
+++ b/addressbook/libedata-book/e-book-backend-sexp.h
@@ -28,7 +28,7 @@
#ifndef E_BOOK_BACKEND_SEXP_H
#define E_BOOK_BACKEND_SEXP_H
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
/* Standard GObject macros */
#define E_TYPE_BOOK_BACKEND_SEXP \
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb-test.c b/addressbook/libedata-book/e-book-backend-sqlitedb-test.c
index 1d26528..68e3b19 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb-test.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb-test.c
@@ -20,7 +20,7 @@
*/
#include <config.h>
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
#include "e-book-backend-sqlitedb.h"
static GMainLoop *main_loop;
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.c b/addressbook/libedata-book/e-book-backend-sqlitedb.c
index 1382de6..0531c9d 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.c
@@ -991,6 +991,10 @@ book_backend_sqlitedb_load (EBookBackendSqliteDB *ebsdb,
ebsdb->priv->db,
"PRAGMA case_sensitive_like = ON",
NULL, NULL, NULL);
+ book_backend_sql_exec (
+ ebsdb->priv->db,
+ "PRAGMA journal_mode = WAL",
+ NULL, NULL, NULL);
WRITER_UNLOCK (ebsdb);
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.h b/addressbook/libedata-book/e-book-backend-sqlitedb.h
index cfc33e6..a451415 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.h
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.h
@@ -26,7 +26,7 @@
#ifndef E_BOOK_BACKEND_SQLITEDB_H
#define E_BOOK_BACKEND_SQLITEDB_H
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
/* Standard GObject macros */
#define E_TYPE_BOOK_BACKEND_SQLITEDB \
diff --git a/addressbook/libedata-book/e-book-backend-summary.h b/addressbook/libedata-book/e-book-backend-summary.h
index c914616..b229d19 100644
--- a/addressbook/libedata-book/e-book-backend-summary.h
+++ b/addressbook/libedata-book/e-book-backend-summary.h
@@ -28,7 +28,7 @@
#ifndef E_BOOK_BACKEND_SUMMARY_H
#define E_BOOK_BACKEND_SUMMARY_H
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
/* Standard GObject macros */
#define E_TYPE_BOOK_BACKEND_SUMMARY \
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index 5c6525f..5f8ca21 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -1056,6 +1056,54 @@ e_book_backend_set_is_removed (EBookBackend *backend,
}
/**
+ * e_book_backend_get_direct_book:
+ * @backend: an #EBookBackend
+ *
+ * Tries to create an #EDataBookDirect for @backend if
+ * backend supports direct read access.
+ *
+ * Returns: (transfer full): A new #EDataBookDirect object, or %NULL if @backend does not support direct access
+ *
+ * Since: 3.8
+ */
+EDataBookDirect *
+e_book_backend_get_direct_book (EBookBackend *backend)
+{
+ g_return_val_if_fail (E_IS_BOOK_BACKEND (backend), NULL);
+
+ if (E_BOOK_BACKEND_GET_CLASS (backend)->get_direct_book)
+ return E_BOOK_BACKEND_GET_CLASS (backend)->get_direct_book (backend);
+
+ return NULL;
+}
+
+/**
+ * e_book_backend_configure_direct:
+ * @backend: an #EBookBackend
+ * @config: The configuration string for the given backend
+ *
+ * This method is called on @backend in direct read access mode.
+ * The @config argument is the same configuration string which
+ * the same backend reported in the #EDataBookDirect returned
+ * by e_book_backend_get_direct_book().
+ *
+ * The configuration string is optional and is used to ensure
+ * that direct access backends are properly configured to
+ * interface with the same data as the running server side backend.
+ *
+ * Since: 3.8
+ */
+void
+e_book_backend_configure_direct (EBookBackend *backend,
+ const gchar *config)
+{
+ g_return_if_fail (E_IS_BOOK_BACKEND (backend));
+
+ if (E_BOOK_BACKEND_GET_CLASS (backend)->configure_direct)
+ E_BOOK_BACKEND_GET_CLASS (backend)->configure_direct (backend, config);
+}
+
+/**
* e_book_backend_sync:
* @backend: an #EBookbackend
*
diff --git a/addressbook/libedata-book/e-book-backend.h b/addressbook/libedata-book/e-book-backend.h
index cafa765..100c8c7 100644
--- a/addressbook/libedata-book/e-book-backend.h
+++ b/addressbook/libedata-book/e-book-backend.h
@@ -26,11 +26,12 @@
#ifndef E_BOOK_BACKEND_H
#define E_BOOK_BACKEND_H
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
#include <libebackend/libebackend.h>
#include <libedata-book/e-data-book.h>
#include <libedata-book/e-data-book-view.h>
+#include <libedata-book/e-data-book-direct.h>
/* Standard GObject macros */
#define E_TYPE_BOOK_BACKEND \
@@ -211,6 +212,11 @@ struct _EBookBackendClass {
void (*notify_update) (EBookBackend *backend,
const EContact *contact);
+
+ EDataBookDirect *
+ (* get_direct_book) (EBookBackend *backend);
+ void (* configure_direct) (EBookBackend *backend, const gchar *config);
+
/* Notification signals */
void (*sync) (EBookBackend *backend);
};
@@ -317,6 +323,10 @@ void e_book_backend_notify_property_changed
const gchar *prop_name,
const gchar *prop_value);
+EDataBookDirect *
+ e_book_backend_get_direct_book (EBookBackend *backend);
+void e_book_backend_configure_direct (EBookBackend *backend, const gchar *config);
+
void e_book_backend_sync (EBookBackend *backend);
/* protected functions for subclasses */
diff --git a/addressbook/libedata-book/e-data-book-direct.c b/addressbook/libedata-book/e-data-book-direct.c
new file mode 100644
index 0000000..dcedf86
--- /dev/null
+++ b/addressbook/libedata-book/e-data-book-direct.c
@@ -0,0 +1,132 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Author: Tristan Van Berkom <tristanvb openismus com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "e-data-book-direct.h"
+#include "e-gdbus-book-direct.h"
+
+#define E_DATA_BOOK_DIRECT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_DATA_BOOK_DIRECT, EDataBookDirectPrivate))
+
+G_DEFINE_TYPE (EDataBookDirect, e_data_book_direct, G_TYPE_OBJECT);
+#define THRESHOLD_ITEMS 32 /* how many items can be hold in a cache, before propagated to UI */
+#define THRESHOLD_SECONDS 2 /* how long to wait until notifications are propagated to UI; in seconds */
+
+struct _EDataBookDirectPrivate {
+ EGdbusBookDirect *gdbus_object;
+};
+
+/* GObjectClass */
+static void
+e_data_book_direct_dispose (GObject *object)
+{
+ EDataBookDirect *direct = E_DATA_BOOK_DIRECT (object);
+
+ if (direct->priv->gdbus_object) {
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (direct->priv->gdbus_object));
+ g_object_unref (direct->priv->gdbus_object);
+ direct->priv->gdbus_object = NULL;
+ }
+
+ G_OBJECT_CLASS (e_data_book_direct_parent_class)->dispose (object);
+}
+
+static void
+e_data_book_direct_init (EDataBookDirect *direct)
+{
+ direct->priv = E_DATA_BOOK_DIRECT_GET_PRIVATE (direct);
+ direct->priv->gdbus_object = e_gdbus_book_direct_skeleton_new ();
+}
+
+static void
+e_data_book_direct_class_init (EDataBookDirectClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (EDataBookDirectPrivate));
+
+ object_class->dispose = e_data_book_direct_dispose;
+}
+
+/**
+ * e_data_book_direct_new:
+ * @backend_path: Full path to the installed backend shared library
+ * @backend_factory_name: Type name of the EBookBackendFactory implemented by the library
+ * @config: A backend specific configuration string
+ *
+ * Creates a #EDataBookDirect to report configuration data needed for direct
+ * read access.
+ *
+ * This is returned by e_book_backend_get_direct_book() for backends
+ * which support direct read access mode.
+ *
+ * Returns: (transfer full): A newly created #EDataBookDirect
+ *
+ * Since: 3.8
+ */
+EDataBookDirect *
+e_data_book_direct_new (const gchar *backend_path,
+ const gchar *backend_factory_name,
+ const gchar *config)
+{
+ EDataBookDirect *direct;
+
+ g_return_val_if_fail (backend_path && backend_path[0], NULL);
+ g_return_val_if_fail (backend_factory_name && backend_factory_name[0], NULL);
+
+ direct = g_object_new (E_TYPE_DATA_BOOK_DIRECT, NULL);
+
+ e_gdbus_book_direct_set_backend_path (direct->priv->gdbus_object, backend_path);
+ e_gdbus_book_direct_set_backend_name (direct->priv->gdbus_object, backend_factory_name);
+ e_gdbus_book_direct_set_backend_config (direct->priv->gdbus_object, config);
+
+ return direct;
+}
+
+/**
+ * e_data_book_direct_register_gdbus_object:
+ * @direct: An #EDataBookDirect
+ * @connection: The #GDBusConnection to register with
+ * @object_path: The object path to place the direct access configuration data
+ * @error: A location to store any error which might occur while registering
+ *
+ * Places @direct on the @connection at @object_path
+ *
+ * Since: 3.8
+ **/
+gboolean
+e_data_book_direct_register_gdbus_object (EDataBookDirect *direct,
+ GDBusConnection *connection,
+ const gchar *object_path,
+ GError **error)
+{
+ g_return_val_if_fail (E_IS_DATA_BOOK_DIRECT (direct), FALSE);
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (object_path != NULL, 0);
+
+ return g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (direct->priv->gdbus_object),
+ connection, object_path, error);
+}
diff --git a/addressbook/libedata-book/e-data-book-direct.h b/addressbook/libedata-book/e-data-book-direct.h
new file mode 100644
index 0000000..11e3ee8
--- /dev/null
+++ b/addressbook/libedata-book/e-data-book-direct.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Author: Tristan Van Berkom <tristanvb openismus com>
+ */
+
+#if !defined (__LIBEDATA_BOOK_H_INSIDE__) && !defined (LIBEDATA_BOOK_COMPILATION)
+#error "Only <libedata-book/libedata-book.h> should be included directly."
+#endif
+
+#ifndef __E_DATA_BOOK_DIRECT_H__
+#define __E_DATA_BOOK_DIRECT_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define E_TYPE_DATA_BOOK_DIRECT (e_data_book_direct_get_type ())
+#define E_DATA_BOOK_DIRECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_DATA_BOOK_DIRECT, EDataBookDirect))
+#define E_DATA_BOOK_DIRECT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_DATA_BOOK_DIRECT, EDataBookDirectClass))
+#define E_IS_DATA_BOOK_DIRECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_DATA_BOOK_DIRECT))
+#define E_IS_DATA_BOOK_DIRECT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_DATA_BOOK_DIRECT))
+#define E_DATA_BOOK_DIRECT_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_DATA_BOOK_DIRECT, EDataBookDirect))
+
+typedef struct _EDataBookDirect EDataBookDirect;
+typedef struct _EDataBookDirectClass EDataBookDirectClass;
+typedef struct _EDataBookDirectPrivate EDataBookDirectPrivate;
+
+struct _EDataBookDirect {
+ GObject parent;
+ EDataBookDirectPrivate *priv;
+};
+
+struct _EDataBookDirectClass {
+ GObjectClass parent;
+};
+
+GType e_data_book_direct_get_type (void);
+EDataBookDirect * e_data_book_direct_new (const gchar *backend_path,
+ const gchar *backend_factory_name,
+ const gchar *config);
+
+gboolean e_data_book_direct_register_gdbus_object (EDataBookDirect *direct,
+ GDBusConnection *connection,
+ const gchar *object_path,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __E_DATA_BOOK_DIRECT_H__ */
diff --git a/addressbook/libedata-book/e-data-book-view.h b/addressbook/libedata-book/e-data-book-view.h
index 5cda7ca..fe626e5 100644
--- a/addressbook/libedata-book/e-data-book-view.h
+++ b/addressbook/libedata-book/e-data-book-view.h
@@ -28,7 +28,7 @@
#ifndef E_DATA_BOOK_VIEW_H
#define E_DATA_BOOK_VIEW_H
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
#include <libedata-book/e-book-backend-sexp.h>
diff --git a/addressbook/libedata-book/e-data-book.c b/addressbook/libedata-book/e-data-book.c
index c6c2cc7..a4881a5 100644
--- a/addressbook/libedata-book/e-data-book.c
+++ b/addressbook/libedata-book/e-data-book.c
@@ -25,12 +25,13 @@
#include <glib/gi18n.h>
#include <gio/gio.h>
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.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-factory.h"
#include "e-book-backend-sexp.h"
#include "e-gdbus-book.h"
@@ -42,11 +43,15 @@
struct _EDataBookPrivate {
GDBusConnection *connection;
EGdbusBook *dbus_interface;
+ EModule *direct_module;
+ EDataBookDirect *direct_book;
+
EBookBackend *backend;
gchar *object_path;
GRecMutex pending_ops_lock;
GHashTable *pending_ops; /* opid to GCancellable for still running operations */
+ GHashTable *direct_ops; /* opid to DirectOperationData for still running operations */
};
enum {
@@ -111,8 +116,41 @@ typedef struct {
} d;
} OperationData;
+typedef struct {
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+ GCancellable *cancellable;
+ GSimpleAsyncResult *result;
+
+ gboolean is_sync_call;
+ gboolean sync_call_complete;
+ GMutex sync_result_mutex;
+ GCond sync_result_condition;
+} DirectOperationData;
+
+/* EModule's can never be free'd, however the use count can change
+ * Here we ensure that there is only one ever created by way of
+ * static variables and locks
+ */
+static GHashTable *modules_table = NULL;
+G_LOCK_DEFINE (modules_table);
+
+
/* Forward Declarations */
-static void e_data_book_initable_init (GInitableIface *interface);
+static void e_data_book_initable_init (GInitableIface *interface);
+static DirectOperationData *direct_operation_data_push (EDataBook *book,
+ OperationID opid,
+ GAsyncReadyCallback callback,
+ gpointer user_data,
+ GCancellable *cancellable,
+ gpointer source_tag,
+ gboolean sync_call);
+static void direct_operation_data_free (DirectOperationData *data);
+static void direct_operation_complete (DirectOperationData *data);
+static void direct_operation_wait (DirectOperationData *data);
+static void e_data_book_respond_close (EDataBook *book,
+ guint opid,
+ GError *error);
G_DEFINE_TYPE_WITH_CODE (
EDataBook,
@@ -122,6 +160,108 @@ G_DEFINE_TYPE_WITH_CODE (
G_TYPE_INITABLE,
e_data_book_initable_init))
+static EModule *
+load_module (const gchar *module_path)
+{
+ EModule *module = NULL;
+
+ G_LOCK (modules_table);
+
+ if (!modules_table)
+ modules_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ module = g_hash_table_lookup (modules_table, module_path);
+
+ if (!module) {
+ module = e_module_new (module_path);
+ if (!module)
+ g_warning ("Failed to open EModule at path: %s", module_path);
+ else
+ g_hash_table_insert (modules_table, g_strdup (module_path), module);
+ }
+
+ G_UNLOCK (modules_table);
+
+ return module;
+}
+
+static DirectOperationData *
+direct_operation_data_push (EDataBook *book,
+ OperationID opid,
+ GAsyncReadyCallback callback,
+ gpointer user_data,
+ GCancellable *cancellable,
+ gpointer source_tag,
+ gboolean sync_call)
+{
+ DirectOperationData *data;
+
+ data = g_slice_new (DirectOperationData);
+ data->callback = callback;
+ data->user_data = user_data;
+ data->cancellable = g_object_ref (cancellable);
+ data->result = g_simple_async_result_new (G_OBJECT (book),
+ data->callback,
+ data->user_data,
+ source_tag);
+ data->is_sync_call = sync_call;
+ data->sync_call_complete = FALSE;
+
+ if (data->is_sync_call) {
+ g_mutex_init (&data->sync_result_mutex);
+ g_cond_init (&data->sync_result_condition);
+ }
+
+ g_hash_table_insert (book->priv->direct_ops, GUINT_TO_POINTER (opid), data);
+
+ return data;
+}
+
+static void
+direct_operation_data_free (DirectOperationData *data)
+{
+ if (data) {
+ if (data->is_sync_call) {
+ g_mutex_clear (&data->sync_result_mutex);
+ g_cond_clear (&data->sync_result_condition);
+ }
+
+ g_object_unref (data->result);
+ g_object_unref (data->cancellable);
+ g_slice_free (DirectOperationData, data);
+ }
+}
+
+static void
+direct_operation_complete (DirectOperationData *data)
+{
+ /* If it was a sync call, we have the calling thread
+ * waiting on the sync call condition, it's up to
+ * the sync call to free the data with direct_operation_data_free().
+ *
+ * Otherwise for async calls we need to complete
+ * in the calling thread.
+ */
+ if (data->is_sync_call) {
+ g_mutex_lock (&data->sync_result_mutex);
+ data->sync_call_complete = TRUE;
+ g_cond_signal (&data->sync_result_condition);
+ g_mutex_unlock (&data->sync_result_mutex);
+ } else {
+ g_simple_async_result_complete_in_idle (data->result);
+ direct_operation_data_free (data);
+ }
+}
+
+static void
+direct_operation_wait (DirectOperationData *data)
+{
+ g_mutex_lock (&data->sync_result_mutex);
+ while (data->sync_call_complete == FALSE)
+ g_cond_wait (&data->sync_result_condition, &data->sync_result_mutex);
+ g_mutex_unlock (&data->sync_result_mutex);
+}
+
static gchar *
construct_bookview_path (void)
{
@@ -257,6 +397,10 @@ operation_thread (gpointer data,
case OP_CLOSE:
/* close just cancels all pending ops and frees data book */
e_book_backend_remove_client (backend, op->book);
+
+ /* Let direct calls return, notify the direct callers that it's closed */
+ e_data_book_respond_close (op->book, op->id, NULL);
+
case OP_CANCEL_ALL:
g_rec_mutex_lock (&op->book->priv->pending_ops_lock);
g_hash_table_foreach (op->book->priv->pending_ops, cancel_ops_cb, NULL);
@@ -288,17 +432,59 @@ op_new (OperationID op,
return data;
}
-static void
+static OperationData *
+op_direct_new (OperationID op,
+ EDataBook *book,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data,
+ gpointer source_tag,
+ gboolean sync_call,
+ DirectOperationData **ret_data)
+{
+ OperationData *data;
+ DirectOperationData *direct_data;
+
+ data = g_slice_new0 (OperationData);
+ data->op = op;
+ data->book = g_object_ref (book);
+ data->id = e_operation_pool_reserve_opid (ops_pool);
+
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
+ else
+ data->cancellable = g_cancellable_new ();
+
+ g_rec_mutex_lock (&book->priv->pending_ops_lock);
+ g_hash_table_insert (book->priv->pending_ops, GUINT_TO_POINTER (data->id), g_object_ref (data->cancellable));
+ direct_data = direct_operation_data_push (book, data->id, callback, user_data, data->cancellable, source_tag, sync_call);
+ g_rec_mutex_unlock (&book->priv->pending_ops_lock);
+
+ if (ret_data)
+ *ret_data = direct_data;
+
+ return data;
+}
+
+
+static DirectOperationData *
op_complete (EDataBook *book,
guint32 opid)
{
- g_return_if_fail (book != NULL);
+ DirectOperationData *direct_data;
+
+ g_return_val_if_fail (book != NULL, NULL);
e_operation_pool_release_opid (ops_pool, opid);
g_rec_mutex_lock (&book->priv->pending_ops_lock);
g_hash_table_remove (book->priv->pending_ops, GUINT_TO_POINTER (opid));
+ direct_data = g_hash_table_lookup (book->priv->direct_ops, GUINT_TO_POINTER (opid));
+ if (direct_data)
+ g_hash_table_steal (book->priv->direct_ops, GUINT_TO_POINTER (opid));
g_rec_mutex_unlock (&book->priv->pending_ops_lock);
+
+ return direct_data;
}
/**
@@ -792,12 +978,36 @@ e_data_book_respond_open (EDataBook *book,
guint opid,
GError *error)
{
- op_complete (book, opid);
+ DirectOperationData *data;
+
+ data = op_complete (book, opid);
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot open book: "));
- e_gdbus_book_emit_open_done (book->priv->dbus_interface, opid, error);
+ if (data) {
+ gboolean result = FALSE;
+
+ if (error)
+ g_simple_async_result_set_error (data->result,
+ error->domain,
+ error->code,
+ "%s", error->message);
+
+ else {
+ g_simple_async_result_set_check_cancellable (data->result,
+ data->cancellable);
+
+ if (!g_cancellable_is_cancelled (data->cancellable))
+ result = TRUE;
+ }
+
+ g_simple_async_result_set_op_res_gboolean (data->result, result);
+
+ /* Deliver the result to the caller */
+ direct_operation_complete (data);
+ } else
+ e_gdbus_book_emit_open_done (book->priv->dbus_interface, opid, error);
if (error)
g_error_free (error);
@@ -885,19 +1095,48 @@ e_data_book_respond_get_contact (EDataBook *book,
GError *error,
const gchar *vcard)
{
- gchar *gdbus_vcard = NULL;
+ DirectOperationData *data;
- op_complete (book, opid);
+ data = op_complete (book, opid);
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot get contact: "));
- e_gdbus_book_emit_get_contact_done (book->priv->dbus_interface, opid, error, e_util_ensure_gdbus_string (vcard, &gdbus_vcard));
+ if (data) {
+
+ if (error) {
+ g_simple_async_result_set_error (data->result,
+ error->domain,
+ error->code,
+ "%s", error->message);
+ } else {
+ g_simple_async_result_set_check_cancellable (data->result,
+ data->cancellable);
+
+ if (!g_cancellable_is_cancelled (data->cancellable)) {
+ EContact *contact;
+
+ contact = e_contact_new_from_vcard (vcard);
+
+ /* Give it an EContact for the return value */
+ g_simple_async_result_set_op_res_gpointer (data->result, contact, g_object_unref);
+ }
+ }
+
+ /* Deliver the result to the caller */
+ direct_operation_complete (data);
+
+ } else {
+ gchar *gdbus_vcard = NULL;
+
+ e_gdbus_book_emit_get_contact_done (book->priv->dbus_interface, opid, error,
+ e_util_ensure_gdbus_string (vcard, &gdbus_vcard));
+
+ g_free (gdbus_vcard);
+ }
if (error)
g_error_free (error);
-
- g_free (gdbus_vcard);
}
void
@@ -906,11 +1145,51 @@ e_data_book_respond_get_contact_list (EDataBook *book,
GError *error,
const GSList *cards)
{
- if (error) {
- /* Translators: This is prefix to a detailed error message */
+ DirectOperationData *data;
+
+ /* Translators: This is prefix to a detailed error message */
+ if (error)
g_prefix_error (&error, "%s", _("Cannot get contact list: "));
+
+ data = op_complete (book, opid);
+
+ if (data) {
+
+ if (error) {
+ g_simple_async_result_set_error (data->result,
+ error->domain,
+ error->code,
+ "%s", error->message);
+ } else {
+ g_simple_async_result_set_check_cancellable (data->result,
+ data->cancellable);
+
+ if (!g_cancellable_is_cancelled (data->cancellable)) {
+ EContact *contact;
+ const GSList *l;
+ GSList *contacts = NULL;
+
+ for (l = cards; l; l = l->next) {
+ const gchar *vcard = l->data;
+
+ contact = e_contact_new_from_vcard (vcard);
+ contacts = g_slist_prepend (contacts, contact);
+ }
+
+ contacts = g_slist_reverse (contacts);
+
+ /* Give it an EContact for the return value */
+ g_simple_async_result_set_op_res_gpointer (data->result, contacts,
+ (GDestroyNotify)e_util_free_object_slist);
+ }
+ }
+
+ /* Deliver the result to the caller */
+ direct_operation_complete (data);
+
+ } else if (error) {
+
e_gdbus_book_emit_get_contact_list_done (book->priv->dbus_interface, opid, error, NULL);
- g_error_free (error);
} else {
gchar **array;
const GSList *l;
@@ -925,6 +1204,9 @@ e_data_book_respond_get_contact_list (EDataBook *book,
g_strfreev (array);
}
+
+ if (error)
+ g_error_free (error);
}
/**
@@ -940,11 +1222,41 @@ e_data_book_respond_get_contact_list_uids (EDataBook *book,
GError *error,
const GSList *uids)
{
- if (error) {
- /* Translators: This is prefix to a detailed error message */
+ DirectOperationData *data;
+
+ /* Translators: This is prefix to a detailed error message */
+ if (error)
g_prefix_error (&error, "%s", _("Cannot get contact list uids: "));
+
+ data = op_complete (book, opid);
+
+ if (data) {
+
+ if (error) {
+ g_simple_async_result_set_error (data->result,
+ error->domain,
+ error->code,
+ "%s", error->message);
+ } else {
+ g_simple_async_result_set_check_cancellable (data->result,
+ data->cancellable);
+
+ if (!g_cancellable_is_cancelled (data->cancellable)) {
+ GSList *ret_uids = NULL;
+
+ ret_uids = e_util_copy_string_slist (NULL, uids);
+
+ g_simple_async_result_set_op_res_gpointer (data->result, ret_uids,
+ (GDestroyNotify)e_util_free_string_slist);
+ }
+ }
+
+ /* Deliver the result to the caller */
+ direct_operation_complete (data);
+
+ } else if (error) {
+
e_gdbus_book_emit_get_contact_list_uids_done (book->priv->dbus_interface, opid, error, NULL);
- g_error_free (error);
} else {
gchar **array;
const GSList *l;
@@ -959,6 +1271,10 @@ e_data_book_respond_get_contact_list_uids (EDataBook *book,
g_strfreev (array);
}
+
+ if (error)
+ g_error_free (error);
+
}
/**
@@ -1179,17 +1495,18 @@ static void
data_book_set_connection (EDataBook *book,
GDBusConnection *connection)
{
- g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
+ g_return_if_fail (connection == NULL ||
+ G_IS_DBUS_CONNECTION (connection));
g_return_if_fail (book->priv->connection == NULL);
- book->priv->connection = g_object_ref (connection);
+ if (connection)
+ book->priv->connection = g_object_ref (connection);
}
static void
data_book_set_object_path (EDataBook *book,
const gchar *object_path)
{
- g_return_if_fail (object_path != NULL);
g_return_if_fail (book->priv->object_path == NULL);
book->priv->object_path = g_strdup (object_path);
@@ -1273,6 +1590,16 @@ data_book_dispose (GObject *object)
priv->backend = NULL;
}
+ if (priv->direct_book) {
+ g_object_unref (priv->direct_book);
+ priv->direct_book = NULL;
+ }
+
+ if (priv->direct_module) {
+ g_type_module_unuse (G_TYPE_MODULE (priv->direct_module));
+ priv->direct_module = NULL;
+ }
+
/* Chain up to parent's dispose() metnod. */
G_OBJECT_CLASS (e_data_book_parent_class)->dispose (object);
}
@@ -1292,6 +1619,10 @@ data_book_finalize (GObject *object)
}
g_rec_mutex_clear (&priv->pending_ops_lock);
+ if (priv->direct_ops) {
+ g_hash_table_destroy (priv->direct_ops);
+ priv->direct_ops = NULL;
+ }
if (priv->dbus_interface) {
g_object_unref (priv->dbus_interface);
@@ -1311,11 +1642,74 @@ data_book_initable_init (GInitable *initable,
book = E_DATA_BOOK (initable);
- return e_gdbus_book_register_object (
- book->priv->dbus_interface,
- book->priv->connection,
- book->priv->object_path,
- error);
+ if (book->priv->connection && book->priv->object_path) {
+ book->priv->dbus_interface = e_gdbus_book_stub_new ();
+
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-open",
+ G_CALLBACK (impl_Book_open), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-refresh",
+ G_CALLBACK (impl_Book_refresh), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-get-contact",
+ G_CALLBACK (impl_Book_get_contact), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-get-contact-list",
+ G_CALLBACK (impl_Book_get_contact_list), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-get-contact-list-uids",
+ G_CALLBACK (impl_Book_get_contact_list_uids), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-add-contacts",
+ G_CALLBACK (impl_Book_add_contacts), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-remove-contacts",
+ G_CALLBACK (impl_Book_remove_contacts), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-modify-contacts",
+ G_CALLBACK (impl_Book_modify_contacts), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-get-backend-property",
+ G_CALLBACK (impl_Book_get_backend_property), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-set-backend-property",
+ G_CALLBACK (impl_Book_set_backend_property), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-get-view",
+ G_CALLBACK (impl_Book_get_view), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-cancel-operation",
+ G_CALLBACK (impl_Book_cancel_operation), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-cancel-all",
+ G_CALLBACK (impl_Book_cancel_all), book);
+ g_signal_connect (
+ book->priv->dbus_interface, "handle-close",
+ G_CALLBACK (impl_Book_close), book);
+
+ /* This will be NULL for a backend that does not support direct read access */
+ book->priv->direct_book =
+ e_book_backend_get_direct_book (book->priv->backend);
+
+ if (book->priv->direct_book) {
+
+ if (!e_data_book_direct_register_gdbus_object (
+ book->priv->direct_book,
+ book->priv->connection,
+ book->priv->object_path,
+ error))
+ return FALSE;
+ }
+
+ return e_gdbus_book_register_object (
+ book->priv->dbus_interface,
+ book->priv->connection,
+ book->priv->object_path,
+ error);
+ }
+
+ return TRUE;
}
static void
@@ -1382,58 +1776,14 @@ e_data_book_initable_init (GInitableIface *interface)
static void
e_data_book_init (EDataBook *ebook)
{
- EGdbusBook *dbus_interface;
-
ebook->priv = E_DATA_BOOK_GET_PRIVATE (ebook);
- ebook->priv->dbus_interface = e_gdbus_book_stub_new ();
ebook->priv->pending_ops = g_hash_table_new_full (
g_direct_hash, g_direct_equal, NULL, g_object_unref);
+ ebook->priv->direct_ops = g_hash_table_new_full (
+ g_direct_hash, g_direct_equal, NULL,
+ (GDestroyNotify)direct_operation_data_free);
g_rec_mutex_init (&ebook->priv->pending_ops_lock);
-
- dbus_interface = ebook->priv->dbus_interface;
- g_signal_connect (
- dbus_interface, "handle-open",
- G_CALLBACK (impl_Book_open), ebook);
- g_signal_connect (
- dbus_interface, "handle-refresh",
- G_CALLBACK (impl_Book_refresh), ebook);
- g_signal_connect (
- dbus_interface, "handle-get-contact",
- G_CALLBACK (impl_Book_get_contact), ebook);
- g_signal_connect (
- dbus_interface, "handle-get-contact-list",
- G_CALLBACK (impl_Book_get_contact_list), ebook);
- g_signal_connect (
- dbus_interface, "handle-get-contact-list-uids",
- G_CALLBACK (impl_Book_get_contact_list_uids), ebook);
- g_signal_connect (
- dbus_interface, "handle-add-contacts",
- G_CALLBACK (impl_Book_add_contacts), ebook);
- g_signal_connect (
- dbus_interface, "handle-remove-contacts",
- G_CALLBACK (impl_Book_remove_contacts), ebook);
- g_signal_connect (
- dbus_interface, "handle-modify-contacts",
- G_CALLBACK (impl_Book_modify_contacts), ebook);
- g_signal_connect (
- dbus_interface, "handle-get-backend-property",
- G_CALLBACK (impl_Book_get_backend_property), ebook);
- g_signal_connect (
- dbus_interface, "handle-set-backend-property",
- G_CALLBACK (impl_Book_set_backend_property), ebook);
- g_signal_connect (
- dbus_interface, "handle-get-view",
- G_CALLBACK (impl_Book_get_view), ebook);
- g_signal_connect (
- dbus_interface, "handle-cancel-operation",
- G_CALLBACK (impl_Book_cancel_operation), ebook);
- g_signal_connect (
- dbus_interface, "handle-cancel-all",
- G_CALLBACK (impl_Book_cancel_all), ebook);
- g_signal_connect (
- dbus_interface, "handle-close",
- G_CALLBACK (impl_Book_close), ebook);
}
/**
@@ -1468,6 +1818,61 @@ e_data_book_new (EBookBackend *backend,
NULL);
}
+EDataBook *
+e_data_book_new_direct (ESourceRegistry *registry,
+ ESource *source,
+ const gchar *backend_path,
+ const gchar *backend_name,
+ const gchar *config)
+{
+ EDataBook *book = NULL;
+ EModule *module;
+ EBookBackend *backend;
+ GType backend_type;
+ GType factory_type;
+ GTypeClass *factory_class;
+
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+ g_return_val_if_fail (E_IS_SOURCE (source), NULL);
+ g_return_val_if_fail (backend_path && backend_path[0], NULL);
+ g_return_val_if_fail (backend_name && backend_name[0], NULL);
+
+ module = load_module (backend_path);
+ if (!module)
+ goto new_direct_finish;
+
+ if (!g_type_module_use (G_TYPE_MODULE (module))) {
+ g_warning ("Failed to load EModule at path: %s", backend_path);
+ goto new_direct_finish;
+ }
+
+ factory_type = g_type_from_name (backend_name);
+ if (factory_type == 0) {
+ g_warning ("Failed to get backend factory '%s' from EModule at path: %s",
+ backend_name, backend_path);
+ g_type_module_unuse (G_TYPE_MODULE (module));
+ goto new_direct_finish;
+ }
+
+ factory_class = g_type_class_ref (factory_type);
+ backend_type = E_BOOK_BACKEND_FACTORY_CLASS (factory_class)->backend_type;
+ g_type_class_unref (factory_class);
+
+ backend = g_object_new (backend_type,
+ "registry", registry,
+ "source", source, NULL);
+
+ e_book_backend_configure_direct (backend, config);
+
+ book = g_object_new (E_TYPE_DATA_BOOK, "backend", backend, NULL);
+ book->priv->direct_module = module;
+ g_object_unref (backend);
+
+ new_direct_finish:
+
+ return book;
+}
+
/**
* e_data_book_get_backend:
* @book: an #EDataBook
@@ -1523,3 +1928,356 @@ e_data_book_get_object_path (EDataBook *book)
return book->priv->object_path;
}
+/*************************************************************************
+ * Direct Read Access APIs *
+ *************************************************************************/
+void
+e_data_book_open (EDataBook *book,
+ gboolean only_if_exists,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ OperationData *op;
+
+ g_return_if_fail (E_IS_DATA_BOOK (book));
+
+ op = op_direct_new (OP_OPEN, book, cancellable, callback, user_data, e_data_book_open, FALSE, NULL);
+ op->d.only_if_exists = only_if_exists;
+
+ e_operation_pool_push (ops_pool, op);
+}
+
+gboolean
+e_data_book_open_finish (EDataBook *book,
+ GAsyncResult *result,
+ GError **error)
+{
+ gboolean res;
+
+ g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ res = g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (result));
+ g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+
+ return res;
+}
+
+gboolean
+e_data_book_open_sync (EDataBook *book,
+ gboolean only_if_exists,
+ GCancellable *cancellable,
+ GError **error)
+{
+ DirectOperationData *data = NULL;
+ OperationData *op;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+
+ op = op_direct_new (OP_OPEN, book, cancellable, NULL, NULL, e_data_book_open_sync, TRUE, &data);
+ op->d.only_if_exists = only_if_exists;
+
+ e_operation_pool_push (ops_pool, op);
+
+ direct_operation_wait (data);
+ result = e_data_book_open_finish (book, G_ASYNC_RESULT (data->result), error);
+ direct_operation_data_free (data);
+
+ return result;
+}
+
+static void
+e_data_book_respond_close (EDataBook *book,
+ guint opid,
+ GError *error)
+{
+ DirectOperationData *data;
+
+ data = op_complete (book, opid);
+
+ if (data) {
+ gboolean result = FALSE;
+
+ if (error)
+ g_simple_async_result_set_error (data->result,
+ error->domain,
+ error->code,
+ "%s", error->message);
+
+ else {
+ if (!g_cancellable_is_cancelled (data->cancellable))
+ result = TRUE;
+
+ g_simple_async_result_set_check_cancellable (data->result,
+ data->cancellable);
+ }
+
+ g_simple_async_result_set_op_res_gboolean (data->result, result);
+
+ /* Deliver the result to the caller */
+ direct_operation_complete (data);
+ }
+
+ if (error)
+ g_error_free (error);
+}
+
+void
+e_data_book_close (EDataBook *book,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ OperationData *op;
+
+ g_return_if_fail (E_IS_DATA_BOOK (book));
+
+ op = op_direct_new (OP_CLOSE, book, cancellable, callback, user_data, e_data_book_close, FALSE, NULL);
+ e_operation_pool_push (ops_pool, op);
+}
+
+gboolean
+e_data_book_close_finish (EDataBook *book,
+ GAsyncResult *result,
+ GError **error)
+{
+ gboolean res;
+
+ g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ res = g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (result));
+ g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+
+ return res;
+}
+
+gboolean
+e_data_book_close_sync (EDataBook *book,
+ GCancellable *cancellable,
+ GError **error)
+{
+ DirectOperationData *data = NULL;
+ OperationData *op;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+
+ op = op_direct_new (OP_CLOSE, book, cancellable, NULL, NULL, e_data_book_close_sync, TRUE, &data);
+ e_operation_pool_push (ops_pool, op);
+
+ direct_operation_wait (data);
+ result = e_data_book_close_finish (book, G_ASYNC_RESULT (data->result), error);
+ direct_operation_data_free (data);
+
+ return result;
+}
+
+void
+e_data_book_get_contact (EDataBook *book,
+ const gchar *uid,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ OperationData *op;
+
+ g_return_if_fail (E_IS_DATA_BOOK (book));
+ g_return_if_fail (uid && uid[0]);
+
+ op = op_direct_new (OP_GET_CONTACT, book, cancellable, callback, user_data, e_data_book_get_contact, FALSE, NULL);
+ op->d.uid = g_strdup (uid);
+
+ e_operation_pool_push (ops_pool, op);
+}
+
+gboolean
+e_data_book_get_contact_finish (EDataBook *book,
+ GAsyncResult *result,
+ EContact **contact,
+ GError **error)
+{
+ EContact *ret_contact;
+
+ g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ ret_contact = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+ g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+
+ if (contact) {
+ if (ret_contact)
+ *contact = g_object_ref (ret_contact);
+ else
+ *contact = NULL;
+ }
+
+ return ret_contact != NULL;
+}
+
+gboolean
+e_data_book_get_contact_sync (EDataBook *book,
+ const gchar *uid,
+ EContact **contact,
+ GCancellable *cancellable,
+ GError **error)
+{
+ DirectOperationData *data = NULL;
+ OperationData *op;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+ g_return_val_if_fail (uid && uid[0], FALSE);
+
+ op = op_direct_new (OP_GET_CONTACT, book, cancellable, NULL, NULL, e_data_book_open_sync, TRUE, &data);
+ op->d.uid = g_strdup (uid);
+
+ e_operation_pool_push (ops_pool, op);
+
+ direct_operation_wait (data);
+ result = e_data_book_get_contact_finish (book, G_ASYNC_RESULT (data->result), contact, error);
+ direct_operation_data_free (data);
+
+ return result;
+}
+
+void
+e_data_book_get_contacts (EDataBook *book,
+ const gchar *sexp,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ OperationData *op;
+
+ g_return_if_fail (E_IS_DATA_BOOK (book));
+
+ op = op_direct_new (OP_GET_CONTACTS, book, cancellable, callback, user_data, e_data_book_get_contact, FALSE, NULL);
+ op->d.query = g_strdup (sexp);
+
+ e_operation_pool_push (ops_pool, op);
+}
+
+gboolean
+e_data_book_get_contacts_finish (EDataBook *book,
+ GAsyncResult *result,
+ GSList **contacts,
+ GError **error)
+{
+ GSList *ret_contacts;
+
+ g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ ret_contacts = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+ g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+
+ if (contacts) {
+ if (ret_contacts)
+ *contacts = e_util_copy_object_slist (NULL, ret_contacts);
+ else
+ *contacts = NULL;
+ }
+
+ /* How can we tell if it failed ? ... we need to check the error but
+ * GSimpleAsyncResult doesnt tell us if there was an error, only propagates it
+ */
+ return TRUE;
+}
+
+gboolean
+e_data_book_get_contacts_sync (EDataBook *book,
+ const gchar *sexp,
+ GSList **contacts,
+ GCancellable *cancellable,
+ GError **error)
+{
+ DirectOperationData *data = NULL;
+ OperationData *op;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+
+ op = op_direct_new (OP_GET_CONTACTS, book, cancellable, NULL, NULL, e_data_book_open_sync, TRUE, &data);
+ op->d.query = g_strdup (sexp);
+
+ e_operation_pool_push (ops_pool, op);
+
+ direct_operation_wait (data);
+ result = e_data_book_get_contacts_finish (book, G_ASYNC_RESULT (data->result), contacts, error);
+ direct_operation_data_free (data);
+
+ return result;
+}
+
+void
+e_data_book_get_contacts_uids (EDataBook *book,
+ const gchar *sexp,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ OperationData *op;
+
+ g_return_if_fail (E_IS_DATA_BOOK (book));
+
+ op = op_direct_new (OP_GET_CONTACTS_UIDS, book, cancellable, callback, user_data, e_data_book_get_contact, FALSE, NULL);
+ op->d.query = g_strdup (sexp);
+
+ e_operation_pool_push (ops_pool, op);
+}
+
+gboolean
+e_data_book_get_contacts_uids_finish (EDataBook *book,
+ GAsyncResult *result,
+ GSList **contacts_uids,
+ GError **error)
+{
+ GSList *ret_uids;
+
+ g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+ ret_uids = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+ g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+
+ if (contacts_uids) {
+ if (ret_uids)
+ *contacts_uids = e_util_copy_string_slist (NULL, ret_uids);
+ else
+ *contacts_uids = NULL;
+ }
+
+ /* How can we tell if it failed ? ... we need to check the error but
+ * GSimpleAsyncResult doesnt tell us if there was an error, only propagates it
+ */
+ return TRUE;
+}
+
+gboolean
+e_data_book_get_contacts_uids_sync (EDataBook *book,
+ const gchar *sexp,
+ GSList **contacts_uids,
+ GCancellable *cancellable,
+ GError **error)
+{
+ DirectOperationData *data = NULL;
+ OperationData *op;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+
+ op = op_direct_new (OP_GET_CONTACTS_UIDS, book, cancellable, NULL, NULL, e_data_book_open_sync, TRUE, &data);
+ op->d.query = g_strdup (sexp);
+
+ e_operation_pool_push (ops_pool, op);
+
+ direct_operation_wait (data);
+ result = e_data_book_get_contacts_uids_finish (book, G_ASYNC_RESULT (data->result), contacts_uids, error);
+ direct_operation_data_free (data);
+
+ return result;
+}
+
diff --git a/addressbook/libedata-book/e-data-book.h b/addressbook/libedata-book/e-data-book.h
index e0827b8..7f5b906 100644
--- a/addressbook/libedata-book/e-data-book.h
+++ b/addressbook/libedata-book/e-data-book.h
@@ -146,6 +146,11 @@ EDataBook * e_data_book_new (struct _EBookBackend *backend,
GDBusConnection *connection,
const gchar *object_path,
GError **error);
+EDataBook * e_data_book_new_direct (ESourceRegistry *registry,
+ ESource *source,
+ const gchar *backend_path,
+ const gchar *backend_name,
+ const gchar *config);
struct _EBookBackend *
e_data_book_get_backend (EDataBook *book);
GDBusConnection *
@@ -213,6 +218,28 @@ void e_data_book_report_backend_property_changed
gchar * e_data_book_string_slist_to_comma_string
(const GSList *strings);
+/* Direct read access apis */
+void e_data_book_open (EDataBook *book, gboolean only_if_exists, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_data_book_open_finish (EDataBook *book, GAsyncResult *result, GError **error);
+gboolean e_data_book_open_sync (EDataBook *book, gboolean only_if_exists, GCancellable *cancellable, GError **error);
+
+void e_data_book_close (EDataBook *book, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_data_book_close_finish (EDataBook *book, GAsyncResult *result, GError **error);
+gboolean e_data_book_close_sync (EDataBook *book, GCancellable *cancellable, GError **error);
+
+void e_data_book_get_contact (EDataBook *book, const gchar *uid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_data_book_get_contact_finish (EDataBook *book, GAsyncResult *result, EContact **contact, GError **error);
+gboolean e_data_book_get_contact_sync (EDataBook *book, const gchar *uid, EContact **contact, GCancellable *cancellable, GError **error);
+
+void e_data_book_get_contacts (EDataBook *book, const gchar *sexp, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_data_book_get_contacts_finish (EDataBook *book, GAsyncResult *result, GSList **contacts, GError **error);
+gboolean e_data_book_get_contacts_sync (EDataBook *book, const gchar *sexp, GSList **contacts, GCancellable *cancellable, GError **error);
+
+void e_data_book_get_contacts_uids (EDataBook *book, const gchar *sexp, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_data_book_get_contacts_uids_finish (EDataBook *book, GAsyncResult *result, GSList **contacts_uids, GError **error);
+gboolean e_data_book_get_contacts_uids_sync (EDataBook *book, const gchar *sexp, GSList **contacts_uids, GCancellable *cancellable, GError **error);
+
+
G_END_DECLS
#endif /* E_DATA_BOOK_H */
diff --git a/addressbook/libedata-book/libedata-book.h b/addressbook/libedata-book/libedata-book.h
index ecd52ec..ec15c83 100644
--- a/addressbook/libedata-book/libedata-book.h
+++ b/addressbook/libedata-book/libedata-book.h
@@ -21,7 +21,7 @@
#define __LIBEDATA_BOOK_H_INSIDE__
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
#include <libebackend/libebackend.h>
#include <libedata-book/e-book-backend-cache.h>
@@ -34,6 +34,7 @@
#include <libedata-book/e-book-backend.h>
#include <libedata-book/e-data-book-factory.h>
#include <libedata-book/e-data-book-view.h>
+#include <libedata-book/e-data-book-direct.h>
#include <libedata-book/e-data-book.h>
#undef __LIBEDATA_BOOK_H_INSIDE__
diff --git a/addressbook/libegdbus/Makefile.am b/addressbook/libegdbus/Makefile.am
index d176dac..28b248a 100644
--- a/addressbook/libegdbus/Makefile.am
+++ b/addressbook/libegdbus/Makefile.am
@@ -7,12 +7,15 @@ libegdbus_book_la_CPPFLAGS = \
-I$(top_srcdir) \
-I$(top_srcdir)/addressbook \
$(E_DATA_SERVER_CFLAGS) \
+ $(GIO_UNIX_CFLAGS) \
$(CODE_COVERAGE_CFLAGS) \
$(NULL)
libegdbus_book_la_SOURCES = \
e-gdbus-book.h \
e-gdbus-book.c \
+ e-gdbus-book-direct.h \
+ e-gdbus-book-direct.c \
e-gdbus-book-factory.h \
e-gdbus-book-factory.c \
e-gdbus-book-view.h \
@@ -20,7 +23,9 @@ libegdbus_book_la_SOURCES = \
libegdbus_book_la_LIBADD = \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
- $(E_DATA_SERVER_LIBS)
+ $(E_DATA_SERVER_LIBS) \
+ $(GIO_UNIX_LIBS)
+
libegdbus_book_la_LDFLAGS = $(NO_UNDEFINED) \
$(CODE_COVERAGE_LDFLAGS) \
diff --git a/addressbook/libegdbus/e-gdbus-book-direct.c b/addressbook/libegdbus/e-gdbus-book-direct.c
new file mode 100644
index 0000000..03107c5
--- /dev/null
+++ b/addressbook/libegdbus/e-gdbus-book-direct.c
@@ -0,0 +1,1359 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Author: Tristan Van Berkom <tristanvb openismus com>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "e-gdbus-book-direct.h"
+
+#include <string.h>
+#ifdef G_OS_UNIX
+# include <gio/gunixfdlist.h>
+#endif
+
+typedef struct
+{
+ GDBusArgInfo parent_struct;
+ gboolean use_gvariant;
+} _ExtendedGDBusArgInfo;
+
+typedef struct
+{
+ GDBusMethodInfo parent_struct;
+ const gchar *signal_name;
+ gboolean pass_fdlist;
+} _ExtendedGDBusMethodInfo;
+
+typedef struct
+{
+ GDBusSignalInfo parent_struct;
+ const gchar *signal_name;
+} _ExtendedGDBusSignalInfo;
+
+typedef struct
+{
+ GDBusPropertyInfo parent_struct;
+ const gchar *hyphen_name;
+ gboolean use_gvariant;
+} _ExtendedGDBusPropertyInfo;
+
+typedef struct
+{
+ GDBusInterfaceInfo parent_struct;
+ const gchar *hyphen_name;
+} _ExtendedGDBusInterfaceInfo;
+
+typedef struct
+{
+ const _ExtendedGDBusPropertyInfo *info;
+ guint prop_id;
+ GValue orig_value; /* the value before the change */
+} ChangedProperty;
+
+static void
+_changed_property_free (ChangedProperty *data)
+{
+ g_value_unset (&data->orig_value);
+ g_free (data);
+}
+
+static gboolean
+_g_strv_equal0 (gchar **a, gchar **b)
+{
+ gboolean ret = FALSE;
+ guint n;
+ if (a == NULL && b == NULL)
+ {
+ ret = TRUE;
+ goto out;
+ }
+ if (a == NULL || b == NULL)
+ goto out;
+ if (g_strv_length (a) != g_strv_length (b))
+ goto out;
+ for (n = 0; a[n] != NULL; n++)
+ if (g_strcmp0 (a[n], b[n]) != 0)
+ goto out;
+ ret = TRUE;
+out:
+ return ret;
+}
+
+static gboolean
+_g_variant_equal0 (GVariant *a, GVariant *b)
+{
+ gboolean ret = FALSE;
+ if (a == NULL && b == NULL)
+ {
+ ret = TRUE;
+ goto out;
+ }
+ if (a == NULL || b == NULL)
+ goto out;
+ ret = g_variant_equal (a, b);
+out:
+ return ret;
+}
+
+G_GNUC_UNUSED static gboolean
+_g_value_equal (const GValue *a, const GValue *b)
+{
+ gboolean ret = FALSE;
+ g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));
+ switch (G_VALUE_TYPE (a))
+ {
+ case G_TYPE_BOOLEAN:
+ ret = (g_value_get_boolean (a) == g_value_get_boolean (b));
+ break;
+ case G_TYPE_UCHAR:
+ ret = (g_value_get_uchar (a) == g_value_get_uchar (b));
+ break;
+ case G_TYPE_INT:
+ ret = (g_value_get_int (a) == g_value_get_int (b));
+ break;
+ case G_TYPE_UINT:
+ ret = (g_value_get_uint (a) == g_value_get_uint (b));
+ break;
+ case G_TYPE_INT64:
+ ret = (g_value_get_int64 (a) == g_value_get_int64 (b));
+ break;
+ case G_TYPE_UINT64:
+ ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));
+ break;
+ case G_TYPE_DOUBLE:
+ {
+ /* Avoid -Wfloat-equal warnings by doing a direct bit compare */
+ gdouble da = g_value_get_double (a);
+ gdouble db = g_value_get_double (b);
+ ret = memcmp (&da, &db, sizeof (gdouble)) == 0;
+ }
+ break;
+ case G_TYPE_STRING:
+ ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);
+ break;
+ case G_TYPE_VARIANT:
+ ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));
+ break;
+ default:
+ if (G_VALUE_TYPE (a) == G_TYPE_STRV)
+ ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));
+ else
+ g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));
+ break;
+ }
+ return ret;
+}
+
+/* ------------------------------------------------------------------------
+ * Code for interface org.gnome.evolution.dataserver.AddressBookDirect
+ * ------------------------------------------------------------------------
+ */
+
+/**
+ * SECTION:EGdbusBookDirect
+ * @title: EGdbusBookDirect
+ * @short_description: Generated C code for the org.gnome.evolution.dataserver.AddressBookDirect D-Bus interface
+ *
+ * This section contains code for working with the <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link> D-Bus interface in C.
+ */
+
+/* ---- Introspection data for org.gnome.evolution.dataserver.AddressBookDirect ---- */
+
+static const _ExtendedGDBusPropertyInfo _e_gdbus_book_direct_property_info_backend_path =
+{
+ {
+ -1,
+ (gchar *) "BackendPath",
+ (gchar *) "s",
+ G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
+ NULL
+ },
+ "backend-path",
+ FALSE
+};
+
+static const _ExtendedGDBusPropertyInfo _e_gdbus_book_direct_property_info_backend_name =
+{
+ {
+ -1,
+ (gchar *) "BackendName",
+ (gchar *) "s",
+ G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
+ NULL
+ },
+ "backend-name",
+ FALSE
+};
+
+static const _ExtendedGDBusPropertyInfo _e_gdbus_book_direct_property_info_backend_config =
+{
+ {
+ -1,
+ (gchar *) "BackendConfig",
+ (gchar *) "s",
+ G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
+ NULL
+ },
+ "backend-config",
+ FALSE
+};
+
+static const _ExtendedGDBusPropertyInfo * const _e_gdbus_book_direct_property_info_pointers[] =
+{
+ &_e_gdbus_book_direct_property_info_backend_path,
+ &_e_gdbus_book_direct_property_info_backend_name,
+ &_e_gdbus_book_direct_property_info_backend_config,
+ NULL
+};
+
+static const _ExtendedGDBusInterfaceInfo _e_gdbus_book_direct_interface_info =
+{
+ {
+ -1,
+ (gchar *) "org.gnome.evolution.dataserver.AddressBookDirect",
+ NULL,
+ NULL,
+ (GDBusPropertyInfo **) &_e_gdbus_book_direct_property_info_pointers,
+ NULL
+ },
+ "address-book-direct",
+};
+
+
+/**
+ * e_gdbus_book_direct_interface_info:
+ *
+ * Gets a machine-readable description of the <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link> D-Bus interface.
+ *
+ * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.
+ */
+GDBusInterfaceInfo *
+e_gdbus_book_direct_interface_info (void)
+{
+ return (GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct;
+}
+
+/**
+ * e_gdbus_book_direct_override_properties:
+ * @klass: The class structure for a #GObject<!-- -->-derived class.
+ * @property_id_begin: The property id to assign to the first overridden property.
+ *
+ * Overrides all #GObject properties in the #EGdbusBookDirect interface for a concrete class.
+ * The properties are overridden in the order they are defined.
+ *
+ * Returns: The last property id.
+ */
+guint
+e_gdbus_book_direct_override_properties (GObjectClass *klass, guint property_id_begin)
+{
+ g_object_class_override_property (klass, property_id_begin++, "backend-path");
+ g_object_class_override_property (klass, property_id_begin++, "backend-name");
+ g_object_class_override_property (klass, property_id_begin++, "backend-config");
+ return property_id_begin - 1;
+}
+
+
+
+/**
+ * EGdbusBookDirect:
+ *
+ * Abstract interface type for the D-Bus interface <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link>.
+ */
+
+/**
+ * EGdbusBookDirectIface:
+ * @parent_iface: The parent interface.
+ * @get_backend_config: Getter for the #EGdbusBookDirect:backend-config property.
+ * @get_backend_name: Getter for the #EGdbusBookDirect:backend-name property.
+ * @get_backend_path: Getter for the #EGdbusBookDirect:backend-path property.
+ *
+ * Virtual table for the D-Bus interface <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link>.
+ */
+typedef EGdbusBookDirectIface EGdbusBookDirectInterface;
+G_DEFINE_INTERFACE (EGdbusBookDirect, e_gdbus_book_direct, G_TYPE_OBJECT);
+
+static void
+e_gdbus_book_direct_default_init (EGdbusBookDirectIface *iface)
+{
+ /* GObject properties for D-Bus properties: */
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("backend-path", "BackendPath", "BackendPath", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("backend-name", "BackendName", "BackendName", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("backend-config", "BackendConfig", "BackendConfig", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+/**
+ * e_gdbus_book_direct_get_backend_path: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets the value of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendPath">"BackendPath"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * <warning>The returned value is only valid until the property changes so on the client-side it is only safe to use this function on the thread where @object was constructed. Use e_gdbus_book_direct_dup_backend_path() if on another thread.</warning>
+ *
+ * Returns: (transfer none): The property value or %NULL if the property is not set. Do not free the returned value, it belongs to @object.
+ */
+const gchar *
+e_gdbus_book_direct_get_backend_path (EGdbusBookDirect *object)
+{
+ return E_GDBUS_BOOK_DIRECT_GET_IFACE (object)->get_backend_path (object);
+}
+
+/**
+ * e_gdbus_book_direct_dup_backend_path: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets a copy of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendPath">"BackendPath"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * Returns: (transfer full): The property value or %NULL if the property is not set. The returned value should be freed with g_free().
+ */
+gchar *
+e_gdbus_book_direct_dup_backend_path (EGdbusBookDirect *object)
+{
+ gchar *value;
+ g_object_get (G_OBJECT (object), "backend-path", &value, NULL);
+ return value;
+}
+
+/**
+ * e_gdbus_book_direct_set_backend_path: (skip)
+ * @object: A #EGdbusBookDirect.
+ * @value: The value to set.
+ *
+ * Sets the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendPath">"BackendPath"</link> D-Bus property to @value.
+ *
+ * Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.
+ */
+void
+e_gdbus_book_direct_set_backend_path (EGdbusBookDirect *object, const gchar *value)
+{
+ g_object_set (G_OBJECT (object), "backend-path", value, NULL);
+}
+
+/**
+ * e_gdbus_book_direct_get_backend_name: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets the value of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendName">"BackendName"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * <warning>The returned value is only valid until the property changes so on the client-side it is only safe to use this function on the thread where @object was constructed. Use e_gdbus_book_direct_dup_backend_name() if on another thread.</warning>
+ *
+ * Returns: (transfer none): The property value or %NULL if the property is not set. Do not free the returned value, it belongs to @object.
+ */
+const gchar *
+e_gdbus_book_direct_get_backend_name (EGdbusBookDirect *object)
+{
+ return E_GDBUS_BOOK_DIRECT_GET_IFACE (object)->get_backend_name (object);
+}
+
+/**
+ * e_gdbus_book_direct_dup_backend_name: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets a copy of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendName">"BackendName"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * Returns: (transfer full): The property value or %NULL if the property is not set. The returned value should be freed with g_free().
+ */
+gchar *
+e_gdbus_book_direct_dup_backend_name (EGdbusBookDirect *object)
+{
+ gchar *value;
+ g_object_get (G_OBJECT (object), "backend-name", &value, NULL);
+ return value;
+}
+
+/**
+ * e_gdbus_book_direct_set_backend_name: (skip)
+ * @object: A #EGdbusBookDirect.
+ * @value: The value to set.
+ *
+ * Sets the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendName">"BackendName"</link> D-Bus property to @value.
+ *
+ * Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.
+ */
+void
+e_gdbus_book_direct_set_backend_name (EGdbusBookDirect *object, const gchar *value)
+{
+ g_object_set (G_OBJECT (object), "backend-name", value, NULL);
+}
+
+/**
+ * e_gdbus_book_direct_get_backend_config: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets the value of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendConfig">"BackendConfig"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * <warning>The returned value is only valid until the property changes so on the client-side it is only safe to use this function on the thread where @object was constructed. Use e_gdbus_book_direct_dup_backend_config() if on another thread.</warning>
+ *
+ * Returns: (transfer none): The property value or %NULL if the property is not set. Do not free the returned value, it belongs to @object.
+ */
+const gchar *
+e_gdbus_book_direct_get_backend_config (EGdbusBookDirect *object)
+{
+ return E_GDBUS_BOOK_DIRECT_GET_IFACE (object)->get_backend_config (object);
+}
+
+/**
+ * e_gdbus_book_direct_dup_backend_config: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets a copy of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendConfig">"BackendConfig"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * Returns: (transfer full): The property value or %NULL if the property is not set. The returned value should be freed with g_free().
+ */
+gchar *
+e_gdbus_book_direct_dup_backend_config (EGdbusBookDirect *object)
+{
+ gchar *value;
+ g_object_get (G_OBJECT (object), "backend-config", &value, NULL);
+ return value;
+}
+
+/**
+ * e_gdbus_book_direct_set_backend_config: (skip)
+ * @object: A #EGdbusBookDirect.
+ * @value: The value to set.
+ *
+ * Sets the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendConfig">"BackendConfig"</link> D-Bus property to @value.
+ *
+ * Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.
+ */
+void
+e_gdbus_book_direct_set_backend_config (EGdbusBookDirect *object, const gchar *value)
+{
+ g_object_set (G_OBJECT (object), "backend-config", value, NULL);
+}
+
+/* ------------------------------------------------------------------------ */
+
+/**
+ * EGdbusBookDirectProxy:
+ *
+ * The #EGdbusBookDirectProxy structure contains only private data and should only be accessed using the provided API.
+ */
+
+/**
+ * EGdbusBookDirectProxyClass:
+ * @parent_class: The parent class.
+ *
+ * Class structure for #EGdbusBookDirectProxy.
+ */
+
+struct _EGdbusBookDirectProxyPrivate
+{
+ GData *qdata;
+};
+
+static void e_gdbus_book_direct_proxy_iface_init (EGdbusBookDirectIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (EGdbusBookDirectProxy, e_gdbus_book_direct_proxy, G_TYPE_DBUS_PROXY,
+ G_IMPLEMENT_INTERFACE (E_GDBUS_TYPE_BOOK_DIRECT, e_gdbus_book_direct_proxy_iface_init));
+
+static void
+e_gdbus_book_direct_proxy_finalize (GObject *object)
+{
+ EGdbusBookDirectProxy *proxy = E_GDBUS_BOOK_DIRECT_PROXY (object);
+ g_datalist_clear (&proxy->priv->qdata);
+ G_OBJECT_CLASS (e_gdbus_book_direct_proxy_parent_class)->finalize (object);
+}
+
+static void
+e_gdbus_book_direct_proxy_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ const _ExtendedGDBusPropertyInfo *info;
+ GVariant *variant;
+ g_assert (prop_id != 0 && prop_id - 1 < 3);
+ info = _e_gdbus_book_direct_property_info_pointers[prop_id - 1];
+ variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (object), info->parent_struct.name);
+ if (info->use_gvariant)
+ {
+ g_value_set_variant (value, variant);
+ }
+ else
+ {
+ if (variant != NULL)
+ g_dbus_gvariant_to_gvalue (variant, value);
+ }
+ if (variant != NULL)
+ g_variant_unref (variant);
+}
+
+static void
+e_gdbus_book_direct_proxy_set_property_cb (GDBusProxy *proxy,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ const _ExtendedGDBusPropertyInfo *info = user_data;
+ GError *error;
+ error = NULL;
+ if (!g_dbus_proxy_call_finish (proxy, res, &error))
+ {
+ g_warning ("Error setting property `%s' on interface org.gnome.evolution.dataserver.AddressBookDirect: %s (%s, %d)",
+ info->parent_struct.name,
+ error->message, g_quark_to_string (error->domain), error->code);
+ g_error_free (error);
+ }
+}
+
+static void
+e_gdbus_book_direct_proxy_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ const _ExtendedGDBusPropertyInfo *info;
+ GVariant *variant;
+ g_assert (prop_id != 0 && prop_id - 1 < 3);
+ info = _e_gdbus_book_direct_property_info_pointers[prop_id - 1];
+ variant = g_dbus_gvalue_to_gvariant (value, G_VARIANT_TYPE (info->parent_struct.signature));
+ g_dbus_proxy_call (G_DBUS_PROXY (object),
+ "org.freedesktop.DBus.Properties.Set",
+ g_variant_new ("(ssv)", "org.gnome.evolution.dataserver.AddressBookDirect", info->parent_struct.name, variant),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL, (GAsyncReadyCallback) e_gdbus_book_direct_proxy_set_property_cb, (GDBusPropertyInfo *) &info->parent_struct);
+ g_variant_unref (variant);
+}
+
+static void
+e_gdbus_book_direct_proxy_g_signal (GDBusProxy *proxy,
+ const gchar *sender_name,
+ const gchar *signal_name,
+ GVariant *parameters)
+{
+ _ExtendedGDBusSignalInfo *info;
+ GVariantIter iter;
+ GVariant *child;
+ GValue *paramv;
+ guint num_params;
+ guint n;
+ guint signal_id;
+ info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct, signal_name);
+ if (info == NULL)
+ return;
+ num_params = g_variant_n_children (parameters);
+ paramv = g_new0 (GValue, num_params + 1);
+ g_value_init (¶mv[0], E_GDBUS_TYPE_BOOK_DIRECT);
+ g_value_set_object (¶mv[0], proxy);
+ g_variant_iter_init (&iter, parameters);
+ n = 1;
+ while ((child = g_variant_iter_next_value (&iter)) != NULL)
+ {
+ _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];
+ if (arg_info->use_gvariant)
+ {
+ g_value_init (¶mv[n], G_TYPE_VARIANT);
+ g_value_set_variant (¶mv[n], child);
+ n++;
+ }
+ else
+ g_dbus_gvariant_to_gvalue (child, ¶mv[n++]);
+ g_variant_unref (child);
+ }
+ signal_id = g_signal_lookup (info->signal_name, E_GDBUS_TYPE_BOOK_DIRECT);
+ g_signal_emitv (paramv, signal_id, 0, NULL);
+ for (n = 0; n < num_params + 1; n++)
+ g_value_unset (¶mv[n]);
+ g_free (paramv);
+}
+
+static void
+e_gdbus_book_direct_proxy_g_properties_changed (GDBusProxy *_proxy,
+ GVariant *changed_properties,
+ const gchar *const *invalidated_properties)
+{
+ EGdbusBookDirectProxy *proxy = E_GDBUS_BOOK_DIRECT_PROXY (_proxy);
+ guint n;
+ const gchar *key;
+ GVariantIter *iter;
+ _ExtendedGDBusPropertyInfo *info;
+ g_variant_get (changed_properties, "a{sv}", &iter);
+ while (g_variant_iter_next (iter, "{&sv}", &key, NULL))
+ {
+ info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct, key);
+ g_datalist_remove_data (&proxy->priv->qdata, key);
+ if (info != NULL)
+ g_object_notify (G_OBJECT (proxy), info->hyphen_name);
+ }
+ g_variant_iter_free (iter);
+ for (n = 0; invalidated_properties[n] != NULL; n++)
+ {
+ info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct, invalidated_properties[n]);
+ g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]);
+ if (info != NULL)
+ g_object_notify (G_OBJECT (proxy), info->hyphen_name);
+ }
+}
+
+static const gchar *
+e_gdbus_book_direct_proxy_get_backend_path (EGdbusBookDirect *object)
+{
+ EGdbusBookDirectProxy *proxy = E_GDBUS_BOOK_DIRECT_PROXY (object);
+ GVariant *variant;
+ const gchar *value = NULL;
+ variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "BackendPath");
+ if (variant != NULL)
+ {
+ value = g_variant_get_string (variant, NULL);
+ g_variant_unref (variant);
+ }
+ return value;
+}
+
+static const gchar *
+e_gdbus_book_direct_proxy_get_backend_name (EGdbusBookDirect *object)
+{
+ EGdbusBookDirectProxy *proxy = E_GDBUS_BOOK_DIRECT_PROXY (object);
+ GVariant *variant;
+ const gchar *value = NULL;
+ variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "BackendName");
+ if (variant != NULL)
+ {
+ value = g_variant_get_string (variant, NULL);
+ g_variant_unref (variant);
+ }
+ return value;
+}
+
+static const gchar *
+e_gdbus_book_direct_proxy_get_backend_config (EGdbusBookDirect *object)
+{
+ EGdbusBookDirectProxy *proxy = E_GDBUS_BOOK_DIRECT_PROXY (object);
+ GVariant *variant;
+ const gchar *value = NULL;
+ variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "BackendConfig");
+ if (variant != NULL)
+ {
+ value = g_variant_get_string (variant, NULL);
+ g_variant_unref (variant);
+ }
+ return value;
+}
+
+static void
+e_gdbus_book_direct_proxy_init (EGdbusBookDirectProxy *proxy)
+{
+ proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, E_GDBUS_TYPE_BOOK_DIRECT_PROXY, EGdbusBookDirectProxyPrivate);
+ g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), e_gdbus_book_direct_interface_info ());
+}
+
+static void
+e_gdbus_book_direct_proxy_class_init (EGdbusBookDirectProxyClass *klass)
+{
+ GObjectClass *gobject_class;
+ GDBusProxyClass *proxy_class;
+
+ g_type_class_add_private (klass, sizeof (EGdbusBookDirectProxyPrivate));
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = e_gdbus_book_direct_proxy_finalize;
+ gobject_class->get_property = e_gdbus_book_direct_proxy_get_property;
+ gobject_class->set_property = e_gdbus_book_direct_proxy_set_property;
+
+ proxy_class = G_DBUS_PROXY_CLASS (klass);
+ proxy_class->g_signal = e_gdbus_book_direct_proxy_g_signal;
+ proxy_class->g_properties_changed = e_gdbus_book_direct_proxy_g_properties_changed;
+
+
+ e_gdbus_book_direct_override_properties (gobject_class, 1);
+}
+
+static void
+e_gdbus_book_direct_proxy_iface_init (EGdbusBookDirectIface *iface)
+{
+ iface->get_backend_path = e_gdbus_book_direct_proxy_get_backend_path;
+ iface->get_backend_name = e_gdbus_book_direct_proxy_get_backend_name;
+ iface->get_backend_config = e_gdbus_book_direct_proxy_get_backend_config;
+}
+
+/**
+ * e_gdbus_book_direct_proxy_new:
+ * @connection: A #GDBusConnection.
+ * @flags: Flags from the #GDBusProxyFlags enumeration.
+ * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
+ * @object_path: An object path.
+ * @cancellable: (allow-none): A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
+ * @user_data: User data to pass to @callback.
+ *
+ * Asynchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link>. See g_dbus_proxy_new() for more details.
+ *
+ * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
+ * You can then call e_gdbus_book_direct_proxy_new_finish() to get the result of the operation.
+ *
+ * See e_gdbus_book_direct_proxy_new_sync() for the synchronous, blocking version of this constructor.
+ */
+void
+e_gdbus_book_direct_proxy_new (
+ GDBusConnection *connection,
+ GDBusProxyFlags flags,
+ const gchar *name,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_async_initable_new_async (E_GDBUS_TYPE_BOOK_DIRECT_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.gnome.evolution.dataserver.AddressBookDirect", NULL);
+}
+
+/**
+ * e_gdbus_book_direct_proxy_new_finish:
+ * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to e_gdbus_book_direct_proxy_new().
+ * @error: Return location for error or %NULL
+ *
+ * Finishes an operation started with e_gdbus_book_direct_proxy_new().
+ *
+ * Returns: (transfer full) (type EGdbusBookDirectProxy): The constructed proxy object or %NULL if @error is set.
+ */
+EGdbusBookDirect *
+e_gdbus_book_direct_proxy_new_finish (
+ GAsyncResult *res,
+ GError **error)
+{
+ GObject *ret;
+ GObject *source_object;
+ source_object = g_async_result_get_source_object (res);
+ ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
+ g_object_unref (source_object);
+ if (ret != NULL)
+ return E_GDBUS_BOOK_DIRECT (ret);
+ else
+ return NULL;
+}
+
+/**
+ * e_gdbus_book_direct_proxy_new_sync:
+ * @connection: A #GDBusConnection.
+ * @flags: Flags from the #GDBusProxyFlags enumeration.
+ * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
+ * @object_path: An object path.
+ * @cancellable: (allow-none): A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL
+ *
+ * Synchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link>. See g_dbus_proxy_new_sync() for more details.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * See e_gdbus_book_direct_proxy_new() for the asynchronous version of this constructor.
+ *
+ * Returns: (transfer full) (type EGdbusBookDirectProxy): The constructed proxy object or %NULL if @error is set.
+ */
+EGdbusBookDirect *
+e_gdbus_book_direct_proxy_new_sync (
+ GDBusConnection *connection,
+ GDBusProxyFlags flags,
+ const gchar *name,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GInitable *ret;
+ ret = g_initable_new (E_GDBUS_TYPE_BOOK_DIRECT_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.gnome.evolution.dataserver.AddressBookDirect", NULL);
+ if (ret != NULL)
+ return E_GDBUS_BOOK_DIRECT (ret);
+ else
+ return NULL;
+}
+
+
+/**
+ * e_gdbus_book_direct_proxy_new_for_bus:
+ * @bus_type: A #GBusType.
+ * @flags: Flags from the #GDBusProxyFlags enumeration.
+ * @name: A bus name (well-known or unique).
+ * @object_path: An object path.
+ * @cancellable: (allow-none): A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
+ * @user_data: User data to pass to @callback.
+ *
+ * Like e_gdbus_book_direct_proxy_new() but takes a #GBusType instead of a #GDBusConnection.
+ *
+ * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
+ * You can then call e_gdbus_book_direct_proxy_new_for_bus_finish() to get the result of the operation.
+ *
+ * See e_gdbus_book_direct_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.
+ */
+void
+e_gdbus_book_direct_proxy_new_for_bus (
+ GBusType bus_type,
+ GDBusProxyFlags flags,
+ const gchar *name,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_async_initable_new_async (E_GDBUS_TYPE_BOOK_DIRECT_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.gnome.evolution.dataserver.AddressBookDirect", NULL);
+}
+
+/**
+ * e_gdbus_book_direct_proxy_new_for_bus_finish:
+ * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to e_gdbus_book_direct_proxy_new_for_bus().
+ * @error: Return location for error or %NULL
+ *
+ * Finishes an operation started with e_gdbus_book_direct_proxy_new_for_bus().
+ *
+ * Returns: (transfer full) (type EGdbusBookDirectProxy): The constructed proxy object or %NULL if @error is set.
+ */
+EGdbusBookDirect *
+e_gdbus_book_direct_proxy_new_for_bus_finish (
+ GAsyncResult *res,
+ GError **error)
+{
+ GObject *ret;
+ GObject *source_object;
+ source_object = g_async_result_get_source_object (res);
+ ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
+ g_object_unref (source_object);
+ if (ret != NULL)
+ return E_GDBUS_BOOK_DIRECT (ret);
+ else
+ return NULL;
+}
+
+/**
+ * e_gdbus_book_direct_proxy_new_for_bus_sync:
+ * @bus_type: A #GBusType.
+ * @flags: Flags from the #GDBusProxyFlags enumeration.
+ * @name: A bus name (well-known or unique).
+ * @object_path: An object path.
+ * @cancellable: (allow-none): A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL
+ *
+ * Like e_gdbus_book_direct_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * See e_gdbus_book_direct_proxy_new_for_bus() for the asynchronous version of this constructor.
+ *
+ * Returns: (transfer full) (type EGdbusBookDirectProxy): The constructed proxy object or %NULL if @error is set.
+ */
+EGdbusBookDirect *
+e_gdbus_book_direct_proxy_new_for_bus_sync (
+ GBusType bus_type,
+ GDBusProxyFlags flags,
+ const gchar *name,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GInitable *ret;
+ ret = g_initable_new (E_GDBUS_TYPE_BOOK_DIRECT_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.gnome.evolution.dataserver.AddressBookDirect", NULL);
+ if (ret != NULL)
+ return E_GDBUS_BOOK_DIRECT (ret);
+ else
+ return NULL;
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+/**
+ * EGdbusBookDirectSkeleton:
+ *
+ * The #EGdbusBookDirectSkeleton structure contains only private data and should only be accessed using the provided API.
+ */
+
+/**
+ * EGdbusBookDirectSkeletonClass:
+ * @parent_class: The parent class.
+ *
+ * Class structure for #EGdbusBookDirectSkeleton.
+ */
+
+struct _EGdbusBookDirectSkeletonPrivate
+{
+ GValue *properties;
+ GList *changed_properties;
+ GSource *changed_properties_idle_source;
+ GMainContext *context;
+ GMutex lock;
+};
+
+static void
+_e_gdbus_book_direct_skeleton_handle_method_call (
+ GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (user_data);
+ _ExtendedGDBusMethodInfo *info;
+ GVariantIter iter;
+ GVariant *child;
+ GValue *paramv;
+ guint num_params;
+ guint num_extra;
+ guint n;
+ guint signal_id;
+ GValue return_value = G_VALUE_INIT;
+ info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);
+ g_assert (info != NULL);
+ num_params = g_variant_n_children (parameters);
+ num_extra = info->pass_fdlist ? 3 : 2; paramv = g_new0 (GValue, num_params + num_extra);
+ n = 0;
+ g_value_init (¶mv[n], E_GDBUS_TYPE_BOOK_DIRECT);
+ g_value_set_object (¶mv[n++], skeleton);
+ g_value_init (¶mv[n], G_TYPE_DBUS_METHOD_INVOCATION);
+ g_value_set_object (¶mv[n++], invocation);
+ if (info->pass_fdlist)
+ {
+#ifdef G_OS_UNIX
+ g_value_init (¶mv[n], G_TYPE_UNIX_FD_LIST);
+ g_value_set_object (¶mv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)));
+#else
+ g_assert_not_reached ();
+#endif
+ }
+ g_variant_iter_init (&iter, parameters);
+ while ((child = g_variant_iter_next_value (&iter)) != NULL)
+ {
+ _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra];
+ if (arg_info->use_gvariant)
+ {
+ g_value_init (¶mv[n], G_TYPE_VARIANT);
+ g_value_set_variant (¶mv[n], child);
+ n++;
+ }
+ else
+ g_dbus_gvariant_to_gvalue (child, ¶mv[n++]);
+ g_variant_unref (child);
+ }
+ signal_id = g_signal_lookup (info->signal_name, E_GDBUS_TYPE_BOOK_DIRECT);
+ g_value_init (&return_value, G_TYPE_BOOLEAN);
+ g_signal_emitv (paramv, signal_id, 0, &return_value);
+ if (!g_value_get_boolean (&return_value))
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);
+ g_value_unset (&return_value);
+ for (n = 0; n < num_params + num_extra; n++)
+ g_value_unset (¶mv[n]);
+ g_free (paramv);
+}
+
+static GVariant *
+_e_gdbus_book_direct_skeleton_handle_get_property (
+ GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *property_name,
+ GError **error,
+ gpointer user_data)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (user_data);
+ GValue value = G_VALUE_INIT;
+ GParamSpec *pspec;
+ _ExtendedGDBusPropertyInfo *info;
+ GVariant *ret;
+ ret = NULL;
+ info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct, property_name);
+ g_assert (info != NULL);
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
+ if (pspec == NULL)
+ {
+ g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
+ }
+ else
+ {
+ g_value_init (&value, pspec->value_type);
+ g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value);
+ ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));
+ g_value_unset (&value);
+ }
+ return ret;
+}
+
+static gboolean
+_e_gdbus_book_direct_skeleton_handle_set_property (
+ GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *property_name,
+ GVariant *variant,
+ GError **error,
+ gpointer user_data)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (user_data);
+ GValue value = G_VALUE_INIT;
+ GParamSpec *pspec;
+ _ExtendedGDBusPropertyInfo *info;
+ gboolean ret;
+ ret = FALSE;
+ info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct, property_name);
+ g_assert (info != NULL);
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
+ if (pspec == NULL)
+ {
+ g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
+ }
+ else
+ {
+ if (info->use_gvariant)
+ g_value_set_variant (&value, variant);
+ else
+ g_dbus_gvariant_to_gvalue (variant, &value);
+ g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value);
+ g_value_unset (&value);
+ ret = TRUE;
+ }
+ return ret;
+}
+
+static const GDBusInterfaceVTable _e_gdbus_book_direct_skeleton_vtable =
+{
+ _e_gdbus_book_direct_skeleton_handle_method_call,
+ _e_gdbus_book_direct_skeleton_handle_get_property,
+ _e_gdbus_book_direct_skeleton_handle_set_property
+};
+
+static GDBusInterfaceInfo *
+e_gdbus_book_direct_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton)
+{
+ return e_gdbus_book_direct_interface_info ();
+}
+
+static GDBusInterfaceVTable *
+e_gdbus_book_direct_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton)
+{
+ return (GDBusInterfaceVTable *) &_e_gdbus_book_direct_skeleton_vtable;
+}
+
+static GVariant *
+e_gdbus_book_direct_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (_skeleton);
+
+ GVariantBuilder builder;
+ guint n;
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+ if (_e_gdbus_book_direct_interface_info.parent_struct.properties == NULL)
+ goto out;
+ for (n = 0; _e_gdbus_book_direct_interface_info.parent_struct.properties[n] != NULL; n++)
+ {
+ GDBusPropertyInfo *info = _e_gdbus_book_direct_interface_info.parent_struct.properties[n];
+ if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)
+ {
+ GVariant *value;
+ value = _e_gdbus_book_direct_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "org.gnome.evolution.dataserver.AddressBookDirect", info->name, NULL, skeleton);
+ if (value != NULL)
+ {
+ g_variant_take_ref (value);
+ g_variant_builder_add (&builder, "{sv}", info->name, value);
+ g_variant_unref (value);
+ }
+ }
+ }
+out:
+ return g_variant_builder_end (&builder);
+}
+
+static gboolean _e_gdbus_book_direct_emit_changed (gpointer user_data);
+
+static void
+e_gdbus_book_direct_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (_skeleton);
+ gboolean emit_changed = FALSE;
+
+ g_mutex_lock (&skeleton->priv->lock);
+ if (skeleton->priv->changed_properties_idle_source != NULL)
+ {
+ g_source_destroy (skeleton->priv->changed_properties_idle_source);
+ skeleton->priv->changed_properties_idle_source = NULL;
+ emit_changed = TRUE;
+ }
+ g_mutex_unlock (&skeleton->priv->lock);
+
+ if (emit_changed)
+ _e_gdbus_book_direct_emit_changed (skeleton);
+}
+
+static void e_gdbus_book_direct_skeleton_iface_init (EGdbusBookDirectIface *iface);
+G_DEFINE_TYPE_WITH_CODE (EGdbusBookDirectSkeleton, e_gdbus_book_direct_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
+ G_IMPLEMENT_INTERFACE (E_GDBUS_TYPE_BOOK_DIRECT, e_gdbus_book_direct_skeleton_iface_init));
+
+static void
+e_gdbus_book_direct_skeleton_finalize (GObject *object)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+ guint n;
+ for (n = 0; n < 3; n++)
+ g_value_unset (&skeleton->priv->properties[n]);
+ g_free (skeleton->priv->properties);
+ g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);
+ if (skeleton->priv->changed_properties_idle_source != NULL)
+ g_source_destroy (skeleton->priv->changed_properties_idle_source);
+ g_main_context_unref (skeleton->priv->context);
+ g_mutex_clear (&skeleton->priv->lock);
+ G_OBJECT_CLASS (e_gdbus_book_direct_skeleton_parent_class)->finalize (object);
+}
+
+static void
+e_gdbus_book_direct_skeleton_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+ g_assert (prop_id != 0 && prop_id - 1 < 3);
+ g_mutex_lock (&skeleton->priv->lock);
+ g_value_copy (&skeleton->priv->properties[prop_id - 1], value);
+ g_mutex_unlock (&skeleton->priv->lock);
+}
+
+static gboolean
+_e_gdbus_book_direct_emit_changed (gpointer user_data)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (user_data);
+ GList *l;
+ GVariantBuilder builder;
+ GVariantBuilder invalidated_builder;
+ guint num_changes;
+
+ g_mutex_lock (&skeleton->priv->lock);
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));
+ for (l = skeleton->priv->changed_properties, num_changes = 0; l != NULL; l = l->next)
+ {
+ ChangedProperty *cp = l->data;
+ GVariant *variant;
+ const GValue *cur_value;
+
+ cur_value = &skeleton->priv->properties[cp->prop_id - 1];
+ if (!_g_value_equal (cur_value, &cp->orig_value))
+ {
+ variant = g_dbus_gvalue_to_gvariant (cur_value, G_VARIANT_TYPE (cp->info->parent_struct.signature));
+ g_variant_builder_add (&builder, "{sv}", cp->info->parent_struct.name, variant);
+ g_variant_unref (variant);
+ num_changes++;
+ }
+ }
+ if (num_changes > 0)
+ {
+ GList *connections, *ll;
+ GVariant *signal_variant;
+ signal_variant = g_variant_ref_sink (g_variant_new ("(sa{sv}as)", "org.gnome.evolution.dataserver.AddressBookDirect",
+ &builder, &invalidated_builder));
+ connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));
+ for (ll = connections; ll != NULL; ll = ll->next)
+ {
+ GDBusConnection *connection = ll->data;
+
+ g_dbus_connection_emit_signal (connection,
+ NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)),
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ signal_variant,
+ NULL);
+ }
+ g_variant_unref (signal_variant);
+ g_list_free_full (connections, g_object_unref);
+ }
+ else
+ {
+ g_variant_builder_clear (&builder);
+ g_variant_builder_clear (&invalidated_builder);
+ }
+ g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);
+ skeleton->priv->changed_properties = NULL;
+ skeleton->priv->changed_properties_idle_source = NULL;
+ g_mutex_unlock (&skeleton->priv->lock);
+ return FALSE;
+}
+
+static void
+_e_gdbus_book_direct_schedule_emit_changed (EGdbusBookDirectSkeleton *skeleton, const _ExtendedGDBusPropertyInfo *info, guint prop_id, const GValue *orig_value)
+{
+ ChangedProperty *cp;
+ GList *l;
+ cp = NULL;
+ for (l = skeleton->priv->changed_properties; l != NULL; l = l->next)
+ {
+ ChangedProperty *i_cp = l->data;
+ if (i_cp->info == info)
+ {
+ cp = i_cp;
+ break;
+ }
+ }
+ if (cp == NULL)
+ {
+ cp = g_new0 (ChangedProperty, 1);
+ cp->prop_id = prop_id;
+ cp->info = info;
+ skeleton->priv->changed_properties = g_list_prepend (skeleton->priv->changed_properties, cp);
+ g_value_init (&cp->orig_value, G_VALUE_TYPE (orig_value));
+ g_value_copy (orig_value, &cp->orig_value);
+ }
+}
+
+static void
+e_gdbus_book_direct_skeleton_notify (GObject *object,
+ GParamSpec *pspec)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+ g_mutex_lock (&skeleton->priv->lock);
+ if (skeleton->priv->changed_properties != NULL &&
+ skeleton->priv->changed_properties_idle_source == NULL)
+ {
+ skeleton->priv->changed_properties_idle_source = g_idle_source_new ();
+ g_source_set_priority (skeleton->priv->changed_properties_idle_source, G_PRIORITY_DEFAULT);
+ g_source_set_callback (skeleton->priv->changed_properties_idle_source, _e_gdbus_book_direct_emit_changed, g_object_ref (skeleton), (GDestroyNotify) g_object_unref);
+ g_source_attach (skeleton->priv->changed_properties_idle_source, skeleton->priv->context);
+ g_source_unref (skeleton->priv->changed_properties_idle_source);
+ }
+ g_mutex_unlock (&skeleton->priv->lock);
+}
+
+static void
+e_gdbus_book_direct_skeleton_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+ g_assert (prop_id != 0 && prop_id - 1 < 3);
+ g_mutex_lock (&skeleton->priv->lock);
+ g_object_freeze_notify (object);
+ if (!_g_value_equal (value, &skeleton->priv->properties[prop_id - 1]))
+ {
+ if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL)
+ _e_gdbus_book_direct_schedule_emit_changed (skeleton, _e_gdbus_book_direct_property_info_pointers[prop_id - 1], prop_id, &skeleton->priv->properties[prop_id - 1]);
+ g_value_copy (value, &skeleton->priv->properties[prop_id - 1]);
+ g_object_notify_by_pspec (object, pspec);
+ }
+ g_mutex_unlock (&skeleton->priv->lock);
+ g_object_thaw_notify (object);
+}
+
+static void
+e_gdbus_book_direct_skeleton_init (EGdbusBookDirectSkeleton *skeleton)
+{
+ skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, E_GDBUS_TYPE_BOOK_DIRECT_SKELETON, EGdbusBookDirectSkeletonPrivate);
+ g_mutex_init (&skeleton->priv->lock);
+ skeleton->priv->context = g_main_context_ref_thread_default ();
+ skeleton->priv->properties = g_new0 (GValue, 3);
+ g_value_init (&skeleton->priv->properties[0], G_TYPE_STRING);
+ g_value_init (&skeleton->priv->properties[1], G_TYPE_STRING);
+ g_value_init (&skeleton->priv->properties[2], G_TYPE_STRING);
+}
+
+static const gchar *
+e_gdbus_book_direct_skeleton_get_backend_path (EGdbusBookDirect *object)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+ const gchar *value;
+ g_mutex_lock (&skeleton->priv->lock);
+ value = g_value_get_string (&(skeleton->priv->properties[0]));
+ g_mutex_unlock (&skeleton->priv->lock);
+ return value;
+}
+
+static const gchar *
+e_gdbus_book_direct_skeleton_get_backend_name (EGdbusBookDirect *object)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+ const gchar *value;
+ g_mutex_lock (&skeleton->priv->lock);
+ value = g_value_get_string (&(skeleton->priv->properties[1]));
+ g_mutex_unlock (&skeleton->priv->lock);
+ return value;
+}
+
+static const gchar *
+e_gdbus_book_direct_skeleton_get_backend_config (EGdbusBookDirect *object)
+{
+ EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+ const gchar *value;
+ g_mutex_lock (&skeleton->priv->lock);
+ value = g_value_get_string (&(skeleton->priv->properties[2]));
+ g_mutex_unlock (&skeleton->priv->lock);
+ return value;
+}
+
+static void
+e_gdbus_book_direct_skeleton_class_init (EGdbusBookDirectSkeletonClass *klass)
+{
+ GObjectClass *gobject_class;
+ GDBusInterfaceSkeletonClass *skeleton_class;
+
+ g_type_class_add_private (klass, sizeof (EGdbusBookDirectSkeletonPrivate));
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = e_gdbus_book_direct_skeleton_finalize;
+ gobject_class->get_property = e_gdbus_book_direct_skeleton_get_property;
+ gobject_class->set_property = e_gdbus_book_direct_skeleton_set_property;
+ gobject_class->notify = e_gdbus_book_direct_skeleton_notify;
+
+
+ e_gdbus_book_direct_override_properties (gobject_class, 1);
+
+ skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);
+ skeleton_class->get_info = e_gdbus_book_direct_skeleton_dbus_interface_get_info;
+ skeleton_class->get_properties = e_gdbus_book_direct_skeleton_dbus_interface_get_properties;
+ skeleton_class->flush = e_gdbus_book_direct_skeleton_dbus_interface_flush;
+ skeleton_class->get_vtable = e_gdbus_book_direct_skeleton_dbus_interface_get_vtable;
+}
+
+static void
+e_gdbus_book_direct_skeleton_iface_init (EGdbusBookDirectIface *iface)
+{
+ iface->get_backend_path = e_gdbus_book_direct_skeleton_get_backend_path;
+ iface->get_backend_name = e_gdbus_book_direct_skeleton_get_backend_name;
+ iface->get_backend_config = e_gdbus_book_direct_skeleton_get_backend_config;
+}
+
+/**
+ * e_gdbus_book_direct_skeleton_new:
+ *
+ * Creates a skeleton object for the D-Bus interface <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link>.
+ *
+ * Returns: (transfer full) (type EGdbusBookDirectSkeleton): The skeleton object.
+ */
+EGdbusBookDirect *
+e_gdbus_book_direct_skeleton_new (void)
+{
+ return E_GDBUS_BOOK_DIRECT (g_object_new (E_GDBUS_TYPE_BOOK_DIRECT_SKELETON, NULL));
+}
+
diff --git a/addressbook/libegdbus/e-gdbus-book-direct.h b/addressbook/libegdbus/e-gdbus-book-direct.h
new file mode 100644
index 0000000..9395d45
--- /dev/null
+++ b/addressbook/libegdbus/e-gdbus-book-direct.h
@@ -0,0 +1,173 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Author: Tristan Van Berkom <tristanvb openismus com>
+ */
+
+#ifndef E_GDBUS_BOOK_DIRECT_H
+#define E_GDBUS_BOOK_DIRECT_H
+
+#include <gio/gio.h>
+
+#include <libedataserver/libedataserver.h>
+
+G_BEGIN_DECLS
+
+
+/* ------------------------------------------------------------------------ */
+/* Declarations for org.gnome.evolution.dataserver.AddressBookDirect */
+
+#define E_GDBUS_TYPE_BOOK_DIRECT (e_gdbus_book_direct_get_type ())
+#define E_GDBUS_BOOK_DIRECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_GDBUS_TYPE_BOOK_DIRECT, EGdbusBookDirect))
+#define E_GDBUS_IS_BOOK_DIRECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_GDBUS_TYPE_BOOK_DIRECT))
+#define E_GDBUS_BOOK_DIRECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), E_GDBUS_TYPE_BOOK_DIRECT, EGdbusBookDirectIface))
+
+struct _EGdbusBookDirect;
+typedef struct _EGdbusBookDirect EGdbusBookDirect;
+typedef struct _EGdbusBookDirectIface EGdbusBookDirectIface;
+
+struct _EGdbusBookDirectIface
+{
+ GTypeInterface parent_iface;
+
+ const gchar * (*get_backend_config) (EGdbusBookDirect *object);
+
+ const gchar * (*get_backend_name) (EGdbusBookDirect *object);
+
+ const gchar * (*get_backend_path) (EGdbusBookDirect *object);
+
+};
+
+GType e_gdbus_book_direct_get_type (void) G_GNUC_CONST;
+
+GDBusInterfaceInfo *e_gdbus_book_direct_interface_info (void);
+guint e_gdbus_book_direct_override_properties (GObjectClass *klass, guint property_id_begin);
+
+
+/* D-Bus property accessors: */
+const gchar *e_gdbus_book_direct_get_backend_path (EGdbusBookDirect *object);
+gchar *e_gdbus_book_direct_dup_backend_path (EGdbusBookDirect *object);
+void e_gdbus_book_direct_set_backend_path (EGdbusBookDirect *object, const gchar *value);
+
+const gchar *e_gdbus_book_direct_get_backend_name (EGdbusBookDirect *object);
+gchar *e_gdbus_book_direct_dup_backend_name (EGdbusBookDirect *object);
+void e_gdbus_book_direct_set_backend_name (EGdbusBookDirect *object, const gchar *value);
+
+const gchar *e_gdbus_book_direct_get_backend_config (EGdbusBookDirect *object);
+gchar *e_gdbus_book_direct_dup_backend_config (EGdbusBookDirect *object);
+void e_gdbus_book_direct_set_backend_config (EGdbusBookDirect *object, const gchar *value);
+
+
+/* ---- */
+
+#define E_GDBUS_TYPE_BOOK_DIRECT_PROXY (e_gdbus_book_direct_proxy_get_type ())
+#define E_GDBUS_BOOK_DIRECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_GDBUS_TYPE_BOOK_DIRECT_PROXY, EGdbusBookDirectProxy))
+#define E_GDBUS_BOOK_DIRECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_GDBUS_TYPE_BOOK_DIRECT_PROXY, EGdbusBookDirectProxyClass))
+#define E_GDBUS_BOOK_DIRECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_GDBUS_TYPE_BOOK_DIRECT_PROXY, EGdbusBookDirectProxyClass))
+#define E_GDBUS_IS_BOOK_DIRECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_GDBUS_TYPE_BOOK_DIRECT_PROXY))
+#define E_GDBUS_IS_BOOK_DIRECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_GDBUS_TYPE_BOOK_DIRECT_PROXY))
+
+typedef struct _EGdbusBookDirectProxy EGdbusBookDirectProxy;
+typedef struct _EGdbusBookDirectProxyClass EGdbusBookDirectProxyClass;
+typedef struct _EGdbusBookDirectProxyPrivate EGdbusBookDirectProxyPrivate;
+
+struct _EGdbusBookDirectProxy
+{
+ /*< private >*/
+ GDBusProxy parent_instance;
+ EGdbusBookDirectProxyPrivate *priv;
+};
+
+struct _EGdbusBookDirectProxyClass
+{
+ GDBusProxyClass parent_class;
+};
+
+GType e_gdbus_book_direct_proxy_get_type (void) G_GNUC_CONST;
+
+void e_gdbus_book_direct_proxy_new (
+ GDBusConnection *connection,
+ GDBusProxyFlags flags,
+ const gchar *name,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+EGdbusBookDirect *e_gdbus_book_direct_proxy_new_finish (
+ GAsyncResult *res,
+ GError **error);
+EGdbusBookDirect *e_gdbus_book_direct_proxy_new_sync (
+ GDBusConnection *connection,
+ GDBusProxyFlags flags,
+ const gchar *name,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GError **error);
+
+void e_gdbus_book_direct_proxy_new_for_bus (
+ GBusType bus_type,
+ GDBusProxyFlags flags,
+ const gchar *name,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+EGdbusBookDirect *e_gdbus_book_direct_proxy_new_for_bus_finish (
+ GAsyncResult *res,
+ GError **error);
+EGdbusBookDirect *e_gdbus_book_direct_proxy_new_for_bus_sync (
+ GBusType bus_type,
+ GDBusProxyFlags flags,
+ const gchar *name,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GError **error);
+
+
+/* ---- */
+
+#define E_GDBUS_TYPE_BOOK_DIRECT_SKELETON (e_gdbus_book_direct_skeleton_get_type ())
+#define E_GDBUS_BOOK_DIRECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_GDBUS_TYPE_BOOK_DIRECT_SKELETON, EGdbusBookDirectSkeleton))
+#define E_GDBUS_BOOK_DIRECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_GDBUS_TYPE_BOOK_DIRECT_SKELETON, EGdbusBookDirectSkeletonClass))
+#define E_GDBUS_BOOK_DIRECT_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_GDBUS_TYPE_BOOK_DIRECT_SKELETON, EGdbusBookDirectSkeletonClass))
+#define E_GDBUS_IS_BOOK_DIRECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_GDBUS_TYPE_BOOK_DIRECT_SKELETON))
+#define E_GDBUS_IS_BOOK_DIRECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_GDBUS_TYPE_BOOK_DIRECT_SKELETON))
+
+typedef struct _EGdbusBookDirectSkeleton EGdbusBookDirectSkeleton;
+typedef struct _EGdbusBookDirectSkeletonClass EGdbusBookDirectSkeletonClass;
+typedef struct _EGdbusBookDirectSkeletonPrivate EGdbusBookDirectSkeletonPrivate;
+
+struct _EGdbusBookDirectSkeleton
+{
+ /*< private >*/
+ GDBusInterfaceSkeleton parent_instance;
+ EGdbusBookDirectSkeletonPrivate *priv;
+};
+
+struct _EGdbusBookDirectSkeletonClass
+{
+ GDBusInterfaceSkeletonClass parent_class;
+};
+
+GType e_gdbus_book_direct_skeleton_get_type (void) G_GNUC_CONST;
+
+EGdbusBookDirect *e_gdbus_book_direct_skeleton_new (void);
+
+
+G_END_DECLS
+
+#endif /* E_GDBUS_BOOK_DIRECT_H */
diff --git a/calendar/backends/contacts/Makefile.am b/calendar/backends/contacts/Makefile.am
index 02acf51..9e7fa18 100644
--- a/calendar/backends/contacts/Makefile.am
+++ b/calendar/backends/contacts/Makefile.am
@@ -26,6 +26,7 @@ libecalbackendcontacts_la_LIBADD = \
$(top_builddir)/calendar/libecal/libecal-1.2.la \
$(top_builddir)/calendar/libedata-cal/libedata-cal-1.2.la \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
$(top_builddir)/libebackend/libebackend-1.2.la \
$(EVOLUTION_CALENDAR_LIBS) \
diff --git a/configure.ac b/configure.ac
index 1128e30..dfeb365 100644
--- a/configure.ac
+++ b/configure.ac
@@ -124,6 +124,10 @@ LIBEBOOK_CURRENT=17
LIBEBOOK_REVISION=1
LIBEBOOK_AGE=3
+LIBEBOOK_CONTACTS_CURRENT=0
+LIBEBOOK_CONTACTS_REVISION=0
+LIBEBOOK_CONTACTS_AGE=0
+
LIBCAMEL_CURRENT=43
LIBCAMEL_REVISION=0
LIBCAMEL_AGE=0
@@ -144,6 +148,9 @@ AC_SUBST(LIBECAL_AGE)
AC_SUBST(LIBEDATACAL_CURRENT)
AC_SUBST(LIBEDATACAL_REVISION)
AC_SUBST(LIBEDATACAL_AGE)
+AC_SUBST(LIBEBOOK_CONTACTS_CURRENT)
+AC_SUBST(LIBEBOOK_CONTACTS_REVISION)
+AC_SUBST(LIBEBOOK_CONTACTS_AGE)
AC_SUBST(LIBEBOOK_CURRENT)
AC_SUBST(LIBEBOOK_REVISION)
AC_SUBST(LIBEBOOK_AGE)
@@ -1577,6 +1584,8 @@ evolution-data-server.pc
addressbook/Makefile
addressbook/libebook/Makefile
addressbook/libebook/libebook.pc
+addressbook/libebook-contacts/Makefile
+addressbook/libebook-contacts/libebook-contacts.pc
addressbook/libedata-book/Makefile
addressbook/libedata-book/libedata-book.pc
addressbook/libegdbus/Makefile
diff --git a/docs/reference/addressbook/libebook/Makefile.am b/docs/reference/addressbook/libebook/Makefile.am
index 1d96640..c8bf347 100644
--- a/docs/reference/addressbook/libebook/Makefile.am
+++ b/docs/reference/addressbook/libebook/Makefile.am
@@ -31,6 +31,7 @@ GTKDOC_CFLAGS = \
$(CAMEL_CFLAGS)
GTKDOC_LIBS = \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
$(EVOLUTION_ADDRESSBOOK_LIBS) \
diff --git a/docs/reference/addressbook/libedata-book/Makefile.am b/docs/reference/addressbook/libedata-book/Makefile.am
index e984856..0e71940 100644
--- a/docs/reference/addressbook/libedata-book/Makefile.am
+++ b/docs/reference/addressbook/libedata-book/Makefile.am
@@ -32,6 +32,7 @@ GTKDOC_CFLAGS = \
GTKDOC_LIBS = \
$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
$(top_builddir)/libebackend/libebackend-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
diff --git a/tests/libebook/Makefile.am b/tests/libebook/Makefile.am
index 7fff918..3dd07bb 100644
--- a/tests/libebook/Makefile.am
+++ b/tests/libebook/Makefile.am
@@ -2,8 +2,6 @@ SUBDIRS = vcard client
@GNOME_CODE_COVERAGE_RULES@
-### EBook Tests (deprecated) ###
-
noinst_LTLIBRARIES = libebook-test-utils.la
libebook_test_utils_la_SOURCES = ebook-test-utils.c ebook-test-utils.h
@@ -23,6 +21,7 @@ libebook_test_utils_la_CPPFLAGS = \
$(NULL)
libebook_test_utils_la_LIBADD = \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
$(top_builddir)/tests/test-server-utils/libetestserverutils.la \
$(EVOLUTION_ADDRESSBOOK_LIBS) \
diff --git a/tests/libebook/client/Makefile.am b/tests/libebook/client/Makefile.am
index d67ad31..679334a 100644
--- a/tests/libebook/client/Makefile.am
+++ b/tests/libebook/client/Makefile.am
@@ -18,6 +18,7 @@ libclient_test_utils_la_CPPFLAGS = \
$(NULL)
libclient_test_utils_la_LIBADD = \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
$(top_builddir)/tests/test-server-utils/libetestserverutils.la \
$(EVOLUTION_ADDRESSBOOK_LIBS) \
diff --git a/tests/libebook/vcard/Makefile.am b/tests/libebook/vcard/Makefile.am
index bc20146..1f510bc 100644
--- a/tests/libebook/vcard/Makefile.am
+++ b/tests/libebook/vcard/Makefile.am
@@ -9,6 +9,7 @@ dump_vcard_CPPFLAGS = \
$(CAMEL_CFLAGS)
dump_vcard_LDADD = \
+ $(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
$(EVOLUTION_ADDRESSBOOK_LIBS) \
diff --git a/vala/EBook-1.2.metadata b/vala/EBook-1.2.metadata
index 8e0106c..69015ed 100644
--- a/vala/EBook-1.2.metadata
+++ b/vala/EBook-1.2.metadata
@@ -1,26 +1,3 @@
BookClientView.objects_added#signal.object type="GLib.List<weak void*>"
BookClientView.objects_removed#signal.object type="GLib.List<weak void*>"
BookClientView.objects_modified#signal.object type="GLib.List<weak void*>"
-Contact.get skip
-Contact.get_const skip
-Contact.set skip
-ContactName.family unowned=false
-ContactName.given unowned=false
-ContactName.additional unowned=false
-ContactName.prefixes unowned=false
-ContactName.suffixes unowned=false
-ContactAddress.address_format unowned=false
-ContactAddress.code unowned=false
-ContactAddress.country unowned=false
-ContactAddress.ext unowned=false
-ContactAddress.locality unowned=false
-ContactAddress.po unowned=false
-ContactAddress.region unowned=false
-ContactAddress.street unowned=false
-ContactPhoto.get_inlined nullable=true
-ContactPhoto.get_mime_type nullable=true
-ContactPhoto.get_uri nullable=true
-VCard.get_attribute nullable=true
-VCard.get_attribute_if_parsed nullable=true
-VCardAttribute.get_group nullable=true
-VCardAttribute.get_value nullable=true
diff --git a/vala/EBookContacts-1.2.metadata b/vala/EBookContacts-1.2.metadata
new file mode 100644
index 0000000..7b30232
--- /dev/null
+++ b/vala/EBookContacts-1.2.metadata
@@ -0,0 +1,23 @@
+Contact.get skip
+Contact.get_const skip
+Contact.set skip
+ContactName.family unowned=false
+ContactName.given unowned=false
+ContactName.additional unowned=false
+ContactName.prefixes unowned=false
+ContactName.suffixes unowned=false
+ContactAddress.address_format unowned=false
+ContactAddress.code unowned=false
+ContactAddress.country unowned=false
+ContactAddress.ext unowned=false
+ContactAddress.locality unowned=false
+ContactAddress.po unowned=false
+ContactAddress.region unowned=false
+ContactAddress.street unowned=false
+ContactPhoto.get_inlined nullable=true
+ContactPhoto.get_mime_type nullable=true
+ContactPhoto.get_uri nullable=true
+VCard.get_attribute nullable=true
+VCard.get_attribute_if_parsed nullable=true
+VCardAttribute.get_group nullable=true
+VCardAttribute.get_value nullable=true
diff --git a/vala/Makefile.am b/vala/Makefile.am
index 44913da..5265332 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -2,15 +2,21 @@ vapidir = $(datarootdir)/vala/vapi
vapi_DATA = \
libedataserver-1.2.vapi \
libebook-1.2.vapi \
+ libebook-contacts-1.2.vapi \
+ libecalendar-1.2.vapi \
$(NULL)
dist_vapi_DATA = \
libedataserver-1.2.deps \
libebook-1.2.deps \
+ libebook-contacts-1.2.deps \
+ libecalendar-1.2.deps \
$(NULL)
EXTRA_DIST = \
EBook-1.2.metadata \
- libebook-1.2-custom.vala \
+ EBookContacts-1.2.metadata \
+ libebook-contacts-1.2-custom.vala \
+ ECalendar-1.2.metadata \
EDataServer-1.2.metadata \
$(NULL)
@@ -32,18 +38,45 @@ libedataserver-1.2.vapi: $(top_builddir)/libedataserver/EDataServer-1.2.gir lib
$< \
$(NULL)
-libebook-1.2.vapi: $(top_builddir)/addressbook/libebook/EBook-1.2.gir libedataserver-1.2.vapi libebook-1.2-custom.vala libebook-1.2.deps
+libecalendar-1.2.vapi: $(top_builddir)/calendar/libecal/ECalendar-1.2.gir libedataserver-1.2.vapi
+ $(VAPIGEN_V)$(VAPIGEN) \
+ --vapidir=. \
+ --girdir=$(top_builddir)/libedataserver \
+ --pkg libedataserver-1.2 \
+ --pkg gio-2.0 \
+ --pkg libxml-2.0 \
+ --library libecalendar-1.2 \
+ --metadatadir=$(srcdir) \
+ $< \
+ $(NULL)
+
+libebook-contacts-1.2.vapi: $(top_builddir)/addressbook/libebook-contacts/EBookContacts-1.2.gir libedataserver-1.2.vapi libebook-contacts-1.2-custom.vala
+ $(VAPIGEN_V)$(VAPIGEN) \
+ --vapidir=. \
+ --vapidir=$(srcdir) \
+ --girdir=$(top_builddir)/libedataserver \
+ --pkg libedataserver-1.2 \
+ --pkg gio-2.0 \
+ --pkg libxml-2.0 \
+ --library libebook-contacts-1.2 \
+ --metadatadir=$(srcdir) \
+ $< \
+ $(srcdir)/libebook-contacts-1.2-custom.vala \
+ $(NULL)
+
+libebook-1.2.vapi: $(top_builddir)/addressbook/libebook/EBook-1.2.gir libedataserver-1.2.vapi libebook-contacts-1.2.vapi
$(VAPIGEN_V)$(VAPIGEN) \
--vapidir=. \
--vapidir=$(srcdir) \
--girdir=$(top_builddir)/libedataserver \
+ --girdir=$(top_builddir)/addressbook/libebook-contacts \
--pkg libedataserver-1.2 \
+ --pkg libebook-contacts-1.2 \
--pkg gio-2.0 \
--pkg libxml-2.0 \
--library libebook-1.2 \
--metadatadir=$(srcdir) \
$< \
- $(srcdir)/libebook-1.2-custom.vala \
$(NULL)
CLEANFILES = \
diff --git a/vala/libebook-1.2.deps b/vala/libebook-1.2.deps
index ef26377..dd769f0 100644
--- a/vala/libebook-1.2.deps
+++ b/vala/libebook-1.2.deps
@@ -1,3 +1,3 @@
-libedataserver-1.2
+libebook-contacts-1.2
libxml-2.0
gio-2.0
diff --git a/vala/libebook-1.2-custom.vala b/vala/libebook-contacts-1.2-custom.vala
similarity index 100%
rename from vala/libebook-1.2-custom.vala
rename to vala/libebook-contacts-1.2-custom.vala
diff --git a/vala/libebook-contacts-1.2.deps b/vala/libebook-contacts-1.2.deps
new file mode 100644
index 0000000..ef26377
--- /dev/null
+++ b/vala/libebook-contacts-1.2.deps
@@ -0,0 +1,3 @@
+libedataserver-1.2
+libxml-2.0
+gio-2.0
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]