1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
4  * Copyright (C) 2006 OpenedHand Ltd
5  * Copyright (C) 2009 Intel Corporation
6  *
7  * This library is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14  * for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  * Authors: Ross Burton <ross@linux.intel.com>
20  */
21 
22 /* e-book deprecated since 3.2, use e-book-client instead */
23 
24 /**
25  * SECTION:e-book
26  *
27  * The old asynchronous API was deprecated since 3.0 and is replaced with
28  * their an equivalent version which has a detailed #GError
29  * structure in the asynchronous callback, instead of a status code only.
30  *
31  * As an example, e_book_async_open() is replaced by e_book_open_async().
32  *
33  * Deprecated: 3.2: Use #EBookClient instead.
34  */
35 
36 #include "evolution-data-server-config.h"
37 
38 #include <unistd.h>
39 #include <string.h>
40 #include <glib/gi18n-lib.h>
41 #include "e-book.h"
42 #include "e-error.h"
43 #include "e-book-view-private.h"
44 
45 struct _EBookPrivate {
46 	EBookClient *client;
47 	gulong backend_died_handler_id;
48 	gulong notify_online_handler_id;
49 	gulong notify_readonly_handler_id;
50 
51 	ESource *source;
52 	gchar *cap;
53 };
54 
55 typedef struct {
56 	EBook *book;
57 	gpointer callback; /* TODO union */
58 	gpointer excallback;
59 	gpointer closure;
60 	gpointer data;
61 } AsyncData;
62 
63 enum {
64 	PROP_0,
65 	PROP_SOURCE
66 };
67 
68 enum {
69 	WRITABLE_STATUS,
70 	CONNECTION_STATUS,
71 	AUTH_REQUIRED,
72 	BACKEND_DIED,
73 	LAST_SIGNAL
74 };
75 
76 static guint signals[LAST_SIGNAL];
77 
78 static void	e_book_initable_init		(GInitableIface *iface);
79 
G_DEFINE_TYPE_WITH_CODE(EBook,e_book,G_TYPE_OBJECT,G_ADD_PRIVATE (EBook)G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,e_book_initable_init))80 G_DEFINE_TYPE_WITH_CODE (
81 	EBook, e_book, G_TYPE_OBJECT,
82 	G_ADD_PRIVATE (EBook)
83 	G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, e_book_initable_init))
84 
85 G_DEFINE_QUARK (e-book-error-quark, e_book_error)
86 
87 static void
88 book_backend_died_cb (EClient *client,
89                       EBook *book)
90 {
91 	/* Echo the signal emission from the EBookClient. */
92 	g_signal_emit (book, signals[BACKEND_DIED], 0);
93 }
94 
95 static void
book_notify_online_cb(EClient * client,GParamSpec * pspec,EBook * book)96 book_notify_online_cb (EClient *client,
97                        GParamSpec *pspec,
98                        EBook *book)
99 {
100 	gboolean online = e_client_is_online (client);
101 
102 	g_signal_emit (book, signals[CONNECTION_STATUS], 0, online);
103 }
104 
105 static void
book_notify_readonly_cb(EClient * client,GParamSpec * pspec,EBook * book)106 book_notify_readonly_cb (EClient *client,
107                          GParamSpec *pspec,
108                          EBook *book)
109 {
110 	gboolean writable = !e_client_is_readonly (client);
111 
112 	g_signal_emit (book, signals[WRITABLE_STATUS], 0, writable);
113 }
114 
115 static void
book_set_source(EBook * book,ESource * source)116 book_set_source (EBook *book,
117                  ESource *source)
118 {
119 	g_return_if_fail (E_IS_SOURCE (source));
120 	g_return_if_fail (book->priv->source == NULL);
121 
122 	book->priv->source = g_object_ref (source);
123 }
124 
125 static void
book_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)126 book_set_property (GObject *object,
127                    guint property_id,
128                    const GValue *value,
129                    GParamSpec *pspec)
130 {
131 	switch (property_id) {
132 		case PROP_SOURCE:
133 			book_set_source (
134 				E_BOOK (object),
135 				g_value_get_object (value));
136 			return;
137 	}
138 
139 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
140 }
141 
142 static void
book_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)143 book_get_property (GObject *object,
144                    guint property_id,
145                    GValue *value,
146                    GParamSpec *pspec)
147 {
148 	switch (property_id) {
149 		case PROP_SOURCE:
150 			g_value_set_object (
151 				value, e_book_get_source (
152 				E_BOOK (object)));
153 			return;
154 	}
155 
156 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
157 }
158 
159 static void
book_dispose(GObject * object)160 book_dispose (GObject *object)
161 {
162 	EBookPrivate *priv;
163 
164 	priv = E_BOOK (object)->priv;
165 
166 	if (priv->client != NULL) {
167 		g_signal_handler_disconnect (
168 			priv->client,
169 			priv->backend_died_handler_id);
170 		g_signal_handler_disconnect (
171 			priv->client,
172 			priv->notify_online_handler_id);
173 		g_signal_handler_disconnect (
174 			priv->client,
175 			priv->notify_readonly_handler_id);
176 		g_object_unref (priv->client);
177 		priv->client = NULL;
178 	}
179 
180 	g_clear_object (&priv->source);
181 
182 	/* Chain up to parent's dispose() method. */
183 	G_OBJECT_CLASS (e_book_parent_class)->dispose (object);
184 }
185 
186 static void
book_finalize(GObject * object)187 book_finalize (GObject *object)
188 {
189 	EBookPrivate *priv;
190 
191 	priv = E_BOOK (object)->priv;
192 
193 	g_free (priv->cap);
194 
195 	/* Chain up to parent's finalize() method. */
196 	G_OBJECT_CLASS (e_book_parent_class)->finalize (object);
197 }
198 
199 static gboolean
book_initable_init(GInitable * initable,GCancellable * cancellable,GError ** error)200 book_initable_init (GInitable *initable,
201                     GCancellable *cancellable,
202                     GError **error)
203 {
204 	EBook *book = E_BOOK (initable);
205 	ESource *source;
206 
207 	source = e_book_get_source (book);
208 
209 	book->priv->client = e_book_client_new (source, error);
210 
211 	if (book->priv->client == NULL)
212 		return FALSE;
213 
214 	book->priv->backend_died_handler_id = g_signal_connect (
215 		book->priv->client, "backend-died",
216 		G_CALLBACK (book_backend_died_cb), book);
217 
218 	book->priv->notify_online_handler_id = g_signal_connect (
219 		book->priv->client, "notify::online",
220 		G_CALLBACK (book_notify_online_cb), book);
221 
222 	book->priv->notify_readonly_handler_id = g_signal_connect (
223 		book->priv->client, "notify::readonly",
224 		G_CALLBACK (book_notify_readonly_cb), book);
225 
226 	return TRUE;
227 }
228 
229 static void
e_book_class_init(EBookClass * class)230 e_book_class_init (EBookClass *class)
231 {
232 	GObjectClass *object_class;
233 
234 	object_class = G_OBJECT_CLASS (class);
235 	object_class->set_property = book_set_property;
236 	object_class->get_property = book_get_property;
237 	object_class->dispose = book_dispose;
238 	object_class->finalize = book_finalize;
239 
240 	g_object_class_install_property (
241 		object_class,
242 		PROP_SOURCE,
243 		g_param_spec_object (
244 			"source",
245 			"Source",
246 			"The data source for this EBook",
247 			E_TYPE_SOURCE,
248 			G_PARAM_READWRITE |
249 			G_PARAM_CONSTRUCT_ONLY |
250 			G_PARAM_STATIC_STRINGS));
251 
252 	signals[WRITABLE_STATUS] = g_signal_new (
253 		"writable_status",
254 		G_OBJECT_CLASS_TYPE (object_class),
255 		G_SIGNAL_RUN_LAST,
256 		G_STRUCT_OFFSET (EBookClass, writable_status),
257 		NULL, NULL, NULL,
258 		G_TYPE_NONE, 1,
259 		G_TYPE_BOOLEAN);
260 
261 	signals[CONNECTION_STATUS] = g_signal_new (
262 		"connection_status",
263 		G_OBJECT_CLASS_TYPE (object_class),
264 		G_SIGNAL_RUN_LAST,
265 		G_STRUCT_OFFSET (EBookClass, connection_status),
266 		NULL, NULL, NULL,
267 		G_TYPE_NONE, 1,
268 		G_TYPE_BOOLEAN);
269 
270 	signals[BACKEND_DIED] = g_signal_new (
271 		"backend_died",
272 		G_OBJECT_CLASS_TYPE (object_class),
273 		G_SIGNAL_RUN_LAST,
274 		G_STRUCT_OFFSET (EBookClass, backend_died),
275 		NULL, NULL, NULL,
276 		G_TYPE_NONE, 0);
277 }
278 
279 static void
e_book_initable_init(GInitableIface * iface)280 e_book_initable_init (GInitableIface *iface)
281 {
282 	iface->init = book_initable_init;
283 }
284 
285 static void
e_book_init(EBook * book)286 e_book_init (EBook *book)
287 {
288 	book->priv = e_book_get_instance_private (book);
289 }
290 
291 /**
292  * e_book_add_contact:
293  * @book: an #EBook
294  * @contact: an #EContact
295  * @error: a #GError to set on failure
296  *
297  * Adds @contact to @book.
298  *
299  * Returns: %TRUE if successful, %FALSE otherwise.
300  *
301  * Deprecated: 3.2: Use e_book_client_add_contact_sync() instead.
302  **/
303 gboolean
e_book_add_contact(EBook * book,EContact * contact,GError ** error)304 e_book_add_contact (EBook *book,
305                     EContact *contact,
306                     GError **error)
307 {
308 	gchar *added_uid = NULL;
309 	gboolean success;
310 
311 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
312 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
313 
314 	success = e_book_client_add_contact_sync (
315 		book->priv->client, contact, E_BOOK_OPERATION_FLAG_NONE, &added_uid, NULL, error);
316 
317 	if (added_uid != NULL) {
318 		e_contact_set (contact, E_CONTACT_UID, added_uid);
319 		g_free (added_uid);
320 	}
321 
322 	return success;
323 }
324 
325 static void
add_contact_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)326 add_contact_reply (GObject *source_object,
327                    GAsyncResult *result,
328                    gpointer user_data)
329 {
330 	AsyncData *data = user_data;
331 	EBookIdCallback cb = data->callback;
332 	EBookIdAsyncCallback excb = data->excallback;
333 	gchar *added_uid = NULL;
334 	GError *error = NULL;
335 
336 	e_book_client_add_contact_finish (
337 		E_BOOK_CLIENT (source_object), result, &added_uid, &error);
338 
339 	if (cb != NULL && error == NULL)
340 		cb (data->book, E_BOOK_ERROR_OK, added_uid, data->closure);
341 	if (cb != NULL && error != NULL)
342 		cb (data->book, error->code, NULL, data->closure);
343 	if (excb != NULL)
344 		excb (data->book, error, added_uid, data->closure);
345 
346 	if (error != NULL)
347 		g_error_free (error);
348 
349 	g_free (added_uid);
350 
351 	g_object_unref (data->book);
352 	g_slice_free (AsyncData, data);
353 }
354 
355 /**
356  * e_book_async_add_contact:
357  * @book: an #EBook
358  * @contact: an #EContact
359  * @cb: (scope async): function to call when the operation finishes
360  * @closure: data to pass to callback function
361  *
362  * Adds @contact to @book without blocking.
363  *
364  * Returns: %TRUE if the operation was started, %FALSE otherwise.
365  *
366  * Deprecated: 3.0: Use e_book_add_contact_async() instead.
367  **/
368 gboolean
e_book_async_add_contact(EBook * book,EContact * contact,EBookIdCallback cb,gpointer closure)369 e_book_async_add_contact (EBook *book,
370                           EContact *contact,
371                           EBookIdCallback cb,
372                           gpointer closure)
373 {
374 	AsyncData *data;
375 
376 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
377 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
378 
379 	data = g_slice_new0 (AsyncData);
380 	data->book = g_object_ref (book);
381 	data->callback = cb;
382 	data->closure = closure;
383 
384 	e_book_client_add_contact (
385 		book->priv->client, contact, E_BOOK_OPERATION_FLAG_NONE, NULL,
386 		add_contact_reply, data);
387 
388 	return TRUE;
389 }
390 
391 /**
392  * e_book_add_contact_async:
393  * @book: an #EBook
394  * @contact: an #EContact
395  * @cb: (scope async): function to call when the operation finishes
396  * @closure: data to pass to callback function
397  *
398  * Adds @contact to @book without blocking.
399  *
400  * Returns: %TRUE if the operation was started, %FALSE otherwise.
401  *
402  * Since: 2.32
403  *
404  * Deprecated: 3.2: Use e_book_client_add_contact() and
405  *                  e_book_client_add_contact_finish() instead.
406  **/
407 gboolean
e_book_add_contact_async(EBook * book,EContact * contact,EBookIdAsyncCallback cb,gpointer closure)408 e_book_add_contact_async (EBook *book,
409                           EContact *contact,
410                           EBookIdAsyncCallback cb,
411                           gpointer closure)
412 {
413 	AsyncData *data;
414 
415 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
416 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
417 
418 	data = g_slice_new0 (AsyncData);
419 	data->book = g_object_ref (book);
420 	data->excallback = cb;
421 	data->closure = closure;
422 
423 	e_book_client_add_contact (
424 		book->priv->client, contact, E_BOOK_OPERATION_FLAG_NONE, NULL,
425 		add_contact_reply, data);
426 
427 	return TRUE;
428 }
429 
430 /**
431  * e_book_commit_contact:
432  * @book: an #EBook
433  * @contact: an #EContact
434  * @error: a #GError to set on failure
435  *
436  * Applies the changes made to @contact to the stored version in
437  * @book.
438  *
439  * Returns: %TRUE if successful, %FALSE otherwise
440  *
441  * Deprecated: 3.2: Use e_book_client_modify_contact_sync() instead.
442  **/
443 gboolean
e_book_commit_contact(EBook * book,EContact * contact,GError ** error)444 e_book_commit_contact (EBook *book,
445                        EContact *contact,
446                        GError **error)
447 {
448 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
449 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
450 
451 	return e_book_client_modify_contact_sync (
452 		book->priv->client, contact, E_BOOK_OPERATION_FLAG_NONE, NULL, error);
453 }
454 
455 static void
modify_contacts_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)456 modify_contacts_reply (GObject *source_object,
457                        GAsyncResult *result,
458                        gpointer user_data)
459 {
460 	AsyncData *data = user_data;
461 	EBookCallback cb = data->callback;
462 	EBookAsyncCallback excb = data->excallback;
463 	GError *error = NULL;
464 
465 	e_book_client_modify_contact_finish (
466 		E_BOOK_CLIENT (source_object), result, &error);
467 
468 	if (cb != NULL && error == NULL)
469 		cb (data->book, E_BOOK_ERROR_OK, data->closure);
470 	if (cb != NULL && error != NULL)
471 		cb (data->book, error->code, data->closure);
472 	if (excb != NULL)
473 		excb (data->book, error, data->closure);
474 
475 	if (error != NULL)
476 		g_error_free (error);
477 
478 	g_object_unref (data->book);
479 	g_slice_free (AsyncData, data);
480 }
481 
482 /**
483  * e_book_async_commit_contact:
484  * @book: an #EBook
485  * @contact: an #EContact
486  * @cb: (scope async): function to call when the operation finishes
487  * @closure: data to pass to callback function
488  *
489  * Applies the changes made to @contact to the stored version in
490  * @book without blocking.
491  *
492  * Returns: %TRUE if the operation was started, %FALSE otherwise.
493  *
494  * Deprecated: 3.0: Use e_book_commit_contact_async() instead.
495  **/
496 gboolean
e_book_async_commit_contact(EBook * book,EContact * contact,EBookCallback cb,gpointer closure)497 e_book_async_commit_contact (EBook *book,
498                              EContact *contact,
499                              EBookCallback cb,
500                              gpointer closure)
501 {
502 	AsyncData *data;
503 
504 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
505 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
506 
507 	data = g_slice_new0 (AsyncData);
508 	data->book = g_object_ref (book);
509 	data->callback = cb;
510 	data->closure = closure;
511 
512 	e_book_client_modify_contact (
513 		book->priv->client, contact, E_BOOK_OPERATION_FLAG_NONE, NULL,
514 		modify_contacts_reply, data);
515 
516 	return TRUE;
517 }
518 
519 /**
520  * e_book_commit_contact_async:
521  * @book: an #EBook
522  * @contact: an #EContact
523  * @cb: (scope async): function to call when the operation finishes
524  * @closure: data to pass to callback function
525  *
526  * Applies the changes made to @contact to the stored version in
527  * @book without blocking.
528  *
529  * Returns: %TRUE if the operation was started, %FALSE otherwise.
530  *
531  * Since: 2.32
532  *
533  * Deprecated: 3.2: Use e_book_client_modify_contact() and
534  *                  e_book_client_modify_contact_finish() instead.
535  **/
536 gboolean
e_book_commit_contact_async(EBook * book,EContact * contact,EBookAsyncCallback cb,gpointer closure)537 e_book_commit_contact_async (EBook *book,
538                              EContact *contact,
539                              EBookAsyncCallback cb,
540                              gpointer closure)
541 {
542 	AsyncData *data;
543 
544 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
545 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
546 
547 	data = g_slice_new0 (AsyncData);
548 	data->book = g_object_ref (book);
549 	data->excallback = cb;
550 	data->closure = closure;
551 
552 	e_book_client_modify_contact (
553 		book->priv->client, contact, E_BOOK_OPERATION_FLAG_NONE, NULL,
554 		modify_contacts_reply, data);
555 
556 	return TRUE;
557 }
558 
559 /**
560  * e_book_get_required_fields:
561  * @book: an #EBook
562  * @fields: (out) (transfer full) (element-type utf8): a #GList of fields
563  *          to set on success
564  * @error: a #GError to set on failure
565  *
566  * Gets a list of fields that are required to be filled in for
567  * all contacts in this @book. The list will contain pointers
568  * to allocated strings, and both the #GList and the strings
569  * must be freed by the caller.
570  *
571  * Returns: %TRUE if successful, %FALSE otherwise.
572  *
573  * Deprecated: 3.2: Use e_client_get_backend_property_sync() on
574  * an #EBookClient object with #E_BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS instead.
575  **/
576 gboolean
e_book_get_required_fields(EBook * book,GList ** fields,GError ** error)577 e_book_get_required_fields (EBook *book,
578                             GList **fields,
579                             GError **error)
580 {
581 	gchar *prop_value = NULL;
582 	gboolean success;
583 
584 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
585 
586 	if (fields != NULL)
587 		*fields = NULL;
588 
589 	success = e_client_get_backend_property_sync (
590 		E_CLIENT (book->priv->client),
591 		E_BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS,
592 		&prop_value, NULL, error);
593 
594 	if (success && fields != NULL) {
595 		GQueue queue = G_QUEUE_INIT;
596 		gchar **strv;
597 		gint ii;
598 
599 		strv = g_strsplit (prop_value, ",", -1);
600 
601 		for (ii = 0; strv != NULL && strv[ii] != NULL; ii++)
602 			g_queue_push_tail (&queue, strv[ii]);
603 
604 		/* The GQueue now owns the strings in the string array,
605 		 * so use g_free() instead of g_strfreev() to free just
606 		 * the array itself. */
607 		g_free (strv);
608 
609 		/* Transfer ownership of the GQueue content. */
610 		*fields = g_queue_peek_head_link (&queue);
611 	}
612 
613 	g_free (prop_value);
614 
615 	return success;
616 }
617 
618 static void
get_required_fields_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)619 get_required_fields_reply (GObject *source_object,
620                            GAsyncResult *result,
621                            gpointer user_data)
622 {
623 	AsyncData *data = user_data;
624 	EBookEListCallback cb = data->callback;
625 	EBookEListAsyncCallback excb = data->excallback;
626 	EList *elist;
627 	gchar *prop_value = NULL;
628 	GError *error = NULL;
629 
630 	e_client_get_backend_property_finish (
631 		E_CLIENT (source_object), result, &prop_value, &error);
632 
633 	/* Sanity check. */
634 	g_return_if_fail (
635 		((prop_value != NULL) && (error == NULL)) ||
636 		((prop_value == NULL) && (error != NULL)));
637 
638 	/* In the event of an error, we pass an empty EList. */
639 	elist = e_list_new (NULL, (EListFreeFunc) g_free, NULL);
640 
641 	if (prop_value != NULL) {
642 		gchar **strv;
643 		gint ii;
644 
645 		strv = g_strsplit (prop_value, ",", -1);
646 		for (ii = 0; strv != NULL && strv[ii] != NULL; ii++) {
647 			gchar *utf8 = e_util_utf8_make_valid (strv[ii]);
648 			e_list_append (elist, utf8);
649 		}
650 		g_strfreev (strv);
651 	}
652 
653 	if (cb != NULL && error == NULL)
654 		cb (data->book, E_BOOK_ERROR_OK, elist, data->closure);
655 	if (cb != NULL && error != NULL)
656 		cb (data->book, error->code, elist, data->closure);
657 	if (excb != NULL)
658 		excb (data->book, error, elist, data->closure);
659 
660 	g_object_unref (elist);
661 
662 	if (error != NULL)
663 		g_error_free (error);
664 
665 	g_object_unref (data->book);
666 	g_slice_free (AsyncData, data);
667 }
668 
669 /**
670  * e_book_async_get_required_fields:
671  * @book: an #EBook
672  * @cb: (scope async): function to call when the operation finishes
673  * @closure: data to pass to callback function
674  *
675  * Gets a list of fields that are required to be filled in for
676  * all contacts in this @book. This function does not block.
677  *
678  * Returns: %TRUE if the operation was started, %FALSE otherwise.
679  *
680  * Deprecated: 3.0: Use e_book_get_required_fields_async() instead.
681  **/
682 gboolean
e_book_async_get_required_fields(EBook * book,EBookEListCallback cb,gpointer closure)683 e_book_async_get_required_fields (EBook *book,
684                                   EBookEListCallback cb,
685                                   gpointer closure)
686 {
687 	AsyncData *data;
688 
689 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
690 
691 	data = g_slice_new0 (AsyncData);
692 	data->book = g_object_ref (book);
693 	data->callback = cb;
694 	data->closure = closure;
695 
696 	e_client_get_backend_property (
697 		E_CLIENT (book->priv->client),
698 		E_BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS,
699 		NULL, get_required_fields_reply, data);
700 
701 	return TRUE;
702 }
703 
704 /**
705  * e_book_get_required_fields_async:
706  * @book: an #EBook
707  * @cb: (scope async): function to call when the operation finishes
708  * @closure: data to pass to callback function
709  *
710  * Gets a list of fields that are required to be filled in for
711  * all contacts in this @book. This function does not block.
712  *
713  * Returns: %TRUE if the operation was started, %FALSE otherwise.
714  *
715  * Since: 2.32
716  *
717  * Deprecated: 3.2: Use e_client_get_backend_property() and
718  *                  e_client_get_backend_property_finish() on an
719  *                  #EBookClient object with
720  *                  #E_BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS instead.
721  **/
722 gboolean
e_book_get_required_fields_async(EBook * book,EBookEListAsyncCallback cb,gpointer closure)723 e_book_get_required_fields_async (EBook *book,
724                                   EBookEListAsyncCallback cb,
725                                   gpointer closure)
726 {
727 	AsyncData *data;
728 
729 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
730 
731 	data = g_slice_new0 (AsyncData);
732 	data->book = g_object_ref (book);
733 	data->excallback = cb;
734 	data->closure = closure;
735 
736 	e_client_get_backend_property (
737 		E_CLIENT (book->priv->client),
738 		E_BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS,
739 		NULL, get_required_fields_reply, data);
740 
741 	return TRUE;
742 }
743 
744 /**
745  * e_book_get_supported_fields:
746  * @book: an #EBook
747  * @fields: (out) (transfer full) (element-type utf8): a #GList of fields
748  *          to set on success
749  * @error: a #GError to set on failure
750  *
751  * Gets a list of fields that can be stored for contacts
752  * in this @book. Other fields may be discarded. The list
753  * will contain pointers to allocated strings, and both the
754  * #GList and the strings must be freed by the caller.
755  *
756  * Returns: %TRUE if successful, %FALSE otherwise
757  *
758  * Deprecated: 3.2: Use e_client_get_backend_property_sync() on
759  * an #EBookClient object with #E_BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS instead.
760  **/
761 gboolean
e_book_get_supported_fields(EBook * book,GList ** fields,GError ** error)762 e_book_get_supported_fields (EBook *book,
763                              GList **fields,
764                              GError **error)
765 {
766 	gchar *prop_value = NULL;
767 	gboolean success;
768 
769 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
770 
771 	if (fields != NULL)
772 		*fields = NULL;
773 
774 	success = e_client_get_backend_property_sync (
775 		E_CLIENT (book->priv->client),
776 		E_BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS,
777 		&prop_value, NULL, error);
778 
779 	if (success && fields != NULL) {
780 		GQueue queue = G_QUEUE_INIT;
781 		gchar **strv;
782 		gint ii;
783 
784 		strv = g_strsplit (prop_value, ",", -1);
785 
786 		for (ii = 0; strv != NULL && strv[ii] != NULL; ii++)
787 			g_queue_push_tail (&queue, strv[ii]);
788 
789 		/* The GQueue now owns the strings in the string array,
790 		 * so use g_free() instead of g_strfreev() to free just
791 		 * the array itself. */
792 		g_free (strv);
793 
794 		/* Transfer ownership of the GQueue content. */
795 		*fields = g_queue_peek_head_link (&queue);
796 	}
797 
798 	g_free (prop_value);
799 
800 	return success;
801 }
802 
803 static void
get_supported_fields_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)804 get_supported_fields_reply (GObject *source_object,
805                             GAsyncResult *result,
806                             gpointer user_data)
807 {
808 	AsyncData *data = user_data;
809 	EBookEListCallback cb = data->callback;
810 	EBookEListAsyncCallback excb = data->excallback;
811 	EList *elist;
812 	gchar *prop_value = NULL;
813 	GError *error = NULL;
814 
815 	e_client_get_backend_property_finish (
816 		E_CLIENT (source_object), result, &prop_value, &error);
817 
818 	/* Sanity check. */
819 	g_return_if_fail (
820 		((prop_value != NULL) && (error == NULL)) ||
821 		((prop_value == NULL) && (error != NULL)));
822 
823 	/* In the event of an error, we pass an empty EList. */
824 	elist = e_list_new (NULL, (EListFreeFunc) g_free, NULL);
825 
826 	if (prop_value != NULL) {
827 		gchar **strv;
828 		gint ii;
829 
830 		strv = g_strsplit (prop_value, ",", -1);
831 		for (ii = 0; strv != NULL && strv[ii] != NULL; ii++) {
832 			gchar *utf8 = e_util_utf8_make_valid (strv[ii]);
833 			e_list_append (elist, utf8);
834 		}
835 		g_strfreev (strv);
836 	}
837 
838 	if (cb != NULL && error == NULL)
839 		cb (data->book, E_BOOK_ERROR_OK, elist, data->closure);
840 	if (cb != NULL && error != NULL)
841 		cb (data->book, error->code, elist, data->closure);
842 	if (excb != NULL)
843 		excb (data->book, error, elist, data->closure);
844 
845 	g_object_unref (elist);
846 
847 	if (error != NULL)
848 		g_error_free (error);
849 
850 	g_object_unref (data->book);
851 	g_slice_free (AsyncData, data);
852 }
853 
854 /**
855  * e_book_async_get_supported_fields:
856  * @book: an #EBook
857  * @cb: (scope async): function to call when the operation finishes
858  * @closure: data to pass to callback function
859  *
860  * Gets a list of fields that can be stored for contacts
861  * in this @book. Other fields may be discarded. This
862  * function does not block.
863  *
864  * Returns: %TRUE if successful, %FALSE otherwise.
865  *
866  * Deprecated: 3.0: Use e_book_get_supported_fields_async() instead.
867  **/
868 gboolean
e_book_async_get_supported_fields(EBook * book,EBookEListCallback cb,gpointer closure)869 e_book_async_get_supported_fields (EBook *book,
870                                    EBookEListCallback cb,
871                                    gpointer closure)
872 {
873 	AsyncData *data;
874 
875 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
876 
877 	data = g_slice_new0 (AsyncData);
878 	data->book = g_object_ref (book);
879 	data->callback = cb;
880 	data->closure = closure;
881 
882 	e_client_get_backend_property (
883 		E_CLIENT (book->priv->client),
884 		E_BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS,
885 		NULL, get_supported_fields_reply, data);
886 
887 	return TRUE;
888 }
889 
890 /**
891  * e_book_get_supported_fields_async:
892  * @book: an #EBook
893  * @cb: (scope async): function to call when the operation finishes
894  * @closure: data to pass to callback function
895  *
896  * Gets a list of fields that can be stored for contacts
897  * in this @book. Other fields may be discarded. This
898  * function does not block.
899  *
900  * Returns: %TRUE if successful, %FALSE otherwise.
901  *
902  * Since: 2.32
903  *
904  * Deprecated: 3.2: Use e_client_get_backend_property() and
905  *                  e_client_get_backend_property_finish() on an
906  *                  #EBookClient object with
907  *                  #E_BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS instead.
908  **/
909 gboolean
e_book_get_supported_fields_async(EBook * book,EBookEListAsyncCallback cb,gpointer closure)910 e_book_get_supported_fields_async (EBook *book,
911                                    EBookEListAsyncCallback cb,
912                                    gpointer closure)
913 {
914 	AsyncData *data;
915 
916 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
917 
918 	data = g_slice_new0 (AsyncData);
919 	data->book = g_object_ref (book);
920 	data->excallback = cb;
921 	data->closure = closure;
922 
923 	e_client_get_backend_property (
924 		E_CLIENT (book->priv->client),
925 		E_BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS,
926 		NULL, get_supported_fields_reply, data);
927 
928 	return TRUE;
929 }
930 
931 /**
932  * e_book_get_supported_auth_methods:
933  * @book: an #EBook
934  * @auth_methods: (out) (transfer full) (element-type utf8): a #GList of
935  *                auth methods to set on success
936  * @error: a #GError to set on failure
937  *
938  * Queries @book for the list of authentication methods it supports.
939  * The list will contain pointers to allocated strings, and both the
940  * #GList and the strings must be freed by the caller.
941  *
942  * Returns: %TRUE if successful, %FALSE otherwise
943  *
944  * Deprecated: 3.2: The property is no longer supported.
945  **/
946 gboolean
e_book_get_supported_auth_methods(EBook * book,GList ** auth_methods,GError ** error)947 e_book_get_supported_auth_methods (EBook *book,
948                                    GList **auth_methods,
949                                    GError **error)
950 {
951 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
952 
953 	if (auth_methods != NULL)
954 		*auth_methods = NULL;
955 
956 	return TRUE;
957 }
958 
959 /**
960  * e_book_async_get_supported_auth_methods:
961  * @book: an #EBook
962  * @cb: (scope async): function to call when the operation finishes
963  * @closure: data to pass to callback function
964  *
965  * Queries @book for the list of authentication methods it supports.
966  * This function does not block.
967  *
968  * Returns: %TRUE if successful, %FALSE otherwise.
969  *
970  * Deprecated: 3.0: The property is no longer supported.
971  **/
972 gboolean
e_book_async_get_supported_auth_methods(EBook * book,EBookEListCallback cb,gpointer closure)973 e_book_async_get_supported_auth_methods (EBook *book,
974                                          EBookEListCallback cb,
975                                          gpointer closure)
976 {
977 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
978 
979 	if (cb != NULL) {
980 		/* Pass the callback an empty list. */
981 		EList *elist = e_list_new (NULL, NULL, NULL);
982 		cb (book, E_BOOK_ERROR_OK, elist, closure);
983 		g_object_unref (elist);
984 	}
985 
986 	return TRUE;
987 }
988 
989 /**
990  * e_book_get_supported_auth_methods_async:
991  * @book: an #EBook
992  * @cb: (scope async): function to call when the operation finishes
993  * @closure: data to pass to callback function
994  *
995  * Queries @book for the list of authentication methods it supports.
996  * This function does not block.
997  *
998  * Returns: %TRUE if successful, %FALSE otherwise.
999  *
1000  * Since: 2.32
1001  *
1002  * Deprecated: 3.2: The property is no longer supported.
1003  **/
1004 gboolean
e_book_get_supported_auth_methods_async(EBook * book,EBookEListAsyncCallback cb,gpointer closure)1005 e_book_get_supported_auth_methods_async (EBook *book,
1006                                          EBookEListAsyncCallback cb,
1007                                          gpointer closure)
1008 {
1009 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1010 
1011 	if (cb != NULL) {
1012 		/* Pass the callback an empty list. */
1013 		EList *elist = e_list_new (NULL, NULL, NULL);
1014 		cb (book, NULL, elist, closure);
1015 		g_object_unref (elist);
1016 	}
1017 
1018 	return TRUE;
1019 }
1020 
1021 /**
1022  * e_book_get_contact:
1023  * @book: an #EBook
1024  * @id: a unique string ID specifying the contact
1025  * @contact: (out) (transfer full): an #EContact
1026  * @error: a #GError to set on failure
1027  *
1028  * Fills in @contact with the contents of the vcard in @book
1029  * corresponding to @id.
1030  *
1031  * Returns: %TRUE if successful, %FALSE otherwise
1032  *
1033  * Deprecated: 3.2: Use e_book_client_get_contact_sync() instead.
1034  **/
1035 gboolean
e_book_get_contact(EBook * book,const gchar * id,EContact ** contact,GError ** error)1036 e_book_get_contact (EBook *book,
1037                     const gchar *id,
1038                     EContact **contact,
1039                     GError **error)
1040 {
1041 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1042 	g_return_val_if_fail (id != NULL, FALSE);
1043 	g_return_val_if_fail (contact != NULL, FALSE);
1044 
1045 	return e_book_client_get_contact_sync (
1046 		book->priv->client, id, contact, NULL, error);
1047 }
1048 
1049 static void
get_contact_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)1050 get_contact_reply (GObject *source_object,
1051                    GAsyncResult *result,
1052                    gpointer user_data)
1053 {
1054 	AsyncData *data = user_data;
1055 	EBookContactCallback cb = data->callback;
1056 	EBookContactAsyncCallback excb = data->excallback;
1057 	EContact *contact = NULL;
1058 	GError *error = NULL;
1059 
1060 	if (!e_book_client_get_contact_finish (
1061 		E_BOOK_CLIENT (source_object), result, &contact, &error)) {
1062 
1063 		if (!error)
1064 			error = g_error_new_literal (
1065 				E_CLIENT_ERROR,
1066 				E_CLIENT_ERROR_OTHER_ERROR,
1067 				_("Unknown error"));
1068 	}
1069 
1070 	if (cb != NULL && error == NULL)
1071 		cb (data->book, E_BOOK_ERROR_OK, contact, data->closure);
1072 	if (cb != NULL && error != NULL)
1073 		cb (data->book, error->code, NULL, data->closure);
1074 	if (excb != NULL)
1075 		excb (data->book, error, contact, data->closure);
1076 
1077 	if (contact != NULL)
1078 		g_object_unref (contact);
1079 
1080 	if (error != NULL)
1081 		g_error_free (error);
1082 
1083 	g_object_unref (data->book);
1084 	g_slice_free (AsyncData, data);
1085 }
1086 
1087 /**
1088  * e_book_async_get_contact:
1089  * @book: an #EBook
1090  * @id: a unique string ID specifying the contact
1091  * @cb: (scope async): function to call when operation finishes
1092  * @closure: data to pass to callback function
1093  *
1094  * Retrieves a contact specified by @id from @book.
1095  *
1096  * Returns: %TRUE if successful, %FALSE otherwise
1097  *
1098  * Deprecated: 3.0: Use e_book_get_contact_async() instead.
1099  **/
1100 gboolean
e_book_async_get_contact(EBook * book,const gchar * id,EBookContactCallback cb,gpointer closure)1101 e_book_async_get_contact (EBook *book,
1102                           const gchar *id,
1103                           EBookContactCallback cb,
1104                           gpointer closure)
1105 {
1106 	AsyncData *data;
1107 
1108 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1109 	g_return_val_if_fail (id != NULL, FALSE);
1110 
1111 	data = g_slice_new0 (AsyncData);
1112 	data->book = g_object_ref (book);
1113 	data->callback = cb;
1114 	data->closure = closure;
1115 
1116 	e_book_client_get_contact (
1117 		E_BOOK_CLIENT (book->priv->client),
1118 		id, NULL, get_contact_reply, data);
1119 
1120 	return TRUE;
1121 }
1122 
1123 /**
1124  * e_book_get_contact_async:
1125  * @book: an #EBook
1126  * @id: a unique string ID specifying the contact
1127  * @cb: (scope async): function to call when operation finishes
1128  * @closure: data to pass to callback function
1129  *
1130  * Retrieves a contact specified by @id from @book.
1131  *
1132  * Returns: %TRUE if successful, %FALSE otherwise
1133  *
1134  * Since: 2.32
1135  *
1136  * Deprecated: 3.2: Use e_book_client_get_contact() and
1137  *                  e_book_client_get_contact_finish() instead.
1138  **/
1139 gboolean
e_book_get_contact_async(EBook * book,const gchar * id,EBookContactAsyncCallback cb,gpointer closure)1140 e_book_get_contact_async (EBook *book,
1141                           const gchar *id,
1142                           EBookContactAsyncCallback cb,
1143                           gpointer closure)
1144 {
1145 	AsyncData *data;
1146 
1147 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1148 	g_return_val_if_fail (id != NULL, FALSE);
1149 
1150 	data = g_slice_new0 (AsyncData);
1151 	data->book = g_object_ref (book);
1152 	data->excallback = cb;
1153 	data->closure = closure;
1154 
1155 	e_book_client_get_contact (
1156 		E_BOOK_CLIENT (book->priv->client),
1157 		id, NULL, get_contact_reply, data);
1158 
1159 	return TRUE;
1160 }
1161 
1162 /**
1163  * e_book_remove_contact:
1164  * @book: an #EBook
1165  * @id: a string
1166  * @error: a #GError to set on failure
1167  *
1168  * Removes the contact with id @id from @book.
1169  *
1170  * Returns: %TRUE if successful, %FALSE otherwise
1171  *
1172  * Deprecated: 3.2: Use e_book_client_remove_contact_by_uid_sync() or
1173  *                  e_book_client_remove_contact_sync() instead.
1174  **/
1175 gboolean
e_book_remove_contact(EBook * book,const gchar * id,GError ** error)1176 e_book_remove_contact (EBook *book,
1177                        const gchar *id,
1178                        GError **error)
1179 {
1180 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1181 	g_return_val_if_fail (id != NULL, FALSE);
1182 
1183 	return e_book_client_remove_contact_by_uid_sync (
1184 		book->priv->client, id, E_BOOK_OPERATION_FLAG_NONE, NULL, error);
1185 }
1186 
1187 static void
remove_contact_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)1188 remove_contact_reply (GObject *source_object,
1189                       GAsyncResult *result,
1190                       gpointer user_data)
1191 {
1192 	AsyncData *data = user_data;
1193 	EBookCallback cb = data->callback;
1194 	EBookAsyncCallback excb = data->excallback;
1195 	GError *error = NULL;
1196 
1197 	e_book_client_remove_contact_finish (
1198 		E_BOOK_CLIENT (source_object), result, &error);
1199 
1200 	if (cb != NULL && error == NULL)
1201 		cb (data->book, E_BOOK_ERROR_OK, data->closure);
1202 	if (cb != NULL && error != NULL)
1203 		cb (data->book, error->code, data->closure);
1204 	if (excb != NULL)
1205 		excb (data->book, error, data->closure);
1206 
1207 	if (error != NULL)
1208 		g_error_free (error);
1209 
1210 	g_object_unref (data->book);
1211 	g_slice_free (AsyncData, data);
1212 }
1213 
1214 /**
1215  * e_book_remove_contacts:
1216  * @book: an #EBook
1217  * @ids: (element-type utf8): an #GList of const gchar *id's
1218  * @error: a #GError to set on failure
1219  *
1220  * Removes the contacts with ids from the list @ids from @book.  This is
1221  * always more efficient than calling e_book_remove_contact() if you
1222  * have more than one id to remove, as some backends can implement it
1223  * as a batch request.
1224  *
1225  * Returns: %TRUE if successful, %FALSE otherwise
1226  *
1227  * Deprecated: 3.2: Use e_book_client_remove_contacts_sync() instead.
1228  **/
1229 gboolean
e_book_remove_contacts(EBook * book,GList * ids,GError ** error)1230 e_book_remove_contacts (EBook *book,
1231                         GList *ids,
1232                         GError **error)
1233 {
1234 	GSList *slist = NULL;
1235 	gboolean success;
1236 
1237 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1238 	g_return_val_if_fail (ids != NULL, FALSE);
1239 
1240 	/* XXX Never use GSList in a public API. */
1241 	while (ids != NULL) {
1242 		slist = g_slist_prepend (slist, ids->data);
1243 		ids = g_list_next (ids);
1244 	}
1245 	slist = g_slist_reverse (slist);
1246 
1247 	success = e_book_client_remove_contacts_sync (
1248 		book->priv->client, slist, E_BOOK_OPERATION_FLAG_NONE, NULL, error);
1249 
1250 	g_slist_free (slist);
1251 
1252 	return success;
1253 }
1254 
1255 /**
1256  * e_book_async_remove_contact:
1257  * @book: an #EBook
1258  * @contact: an #EContact
1259  * @cb: (scope async): a function to call when the operation finishes
1260  * @closure: data to pass to callback function
1261  *
1262  * Removes @contact from @book.
1263  *
1264  * Returns: %TRUE if successful, %FALSE otherwise
1265  *
1266  * Deprecated: 3.0: Use e_book_remove_contact_async() instead.
1267  **/
1268 gboolean
e_book_async_remove_contact(EBook * book,EContact * contact,EBookCallback cb,gpointer closure)1269 e_book_async_remove_contact (EBook *book,
1270                              EContact *contact,
1271                              EBookCallback cb,
1272                              gpointer closure)
1273 {
1274 	AsyncData *data;
1275 
1276 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1277 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
1278 
1279 	data = g_slice_new0 (AsyncData);
1280 	data->book = g_object_ref (book);
1281 	data->callback = cb;
1282 	data->closure = closure;
1283 
1284 	e_book_client_remove_contact (
1285 		E_BOOK_CLIENT (book->priv->client),
1286 		contact, E_BOOK_OPERATION_FLAG_NONE,
1287 		NULL, remove_contact_reply, data);
1288 
1289 	return TRUE;
1290 }
1291 
1292 /**
1293  * e_book_remove_contact_async:
1294  * @book: an #EBook
1295  * @contact: an #EContact
1296  * @cb: (scope async): a function to call when the operation finishes
1297  * @closure: data to pass to callback function
1298  *
1299  * Removes @contact from @book.
1300  *
1301  * Returns: %TRUE if successful, %FALSE otherwise
1302  *
1303  * Since: 2.32
1304  *
1305  * Deprecated: 3.2: Use e_book_client_remove_contact() and
1306  *                  e_book_client_remove_contact_finish() instead.
1307  **/
1308 gboolean
e_book_remove_contact_async(EBook * book,EContact * contact,EBookAsyncCallback cb,gpointer closure)1309 e_book_remove_contact_async (EBook *book,
1310                              EContact *contact,
1311                              EBookAsyncCallback cb,
1312                              gpointer closure)
1313 {
1314 	AsyncData *data;
1315 
1316 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1317 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
1318 
1319 	data = g_slice_new0 (AsyncData);
1320 	data->book = g_object_ref (book);
1321 	data->excallback = cb;
1322 	data->closure = closure;
1323 
1324 	e_book_client_remove_contact (
1325 		E_BOOK_CLIENT (book->priv->client),
1326 		contact, E_BOOK_OPERATION_FLAG_NONE,
1327 		NULL, remove_contact_reply, data);
1328 
1329 	return TRUE;
1330 }
1331 
1332 static void
remove_contact_by_id_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)1333 remove_contact_by_id_reply (GObject *source_object,
1334                             GAsyncResult *result,
1335                             gpointer user_data)
1336 {
1337 	AsyncData *data = user_data;
1338 	EBookCallback cb = data->callback;
1339 	EBookAsyncCallback excb = data->excallback;
1340 	GError *error = NULL;
1341 
1342 	e_book_client_remove_contact_by_uid_finish (
1343 		E_BOOK_CLIENT (source_object), result, &error);
1344 
1345 	if (cb != NULL && error == NULL)
1346 		cb (data->book, E_BOOK_ERROR_OK, data->closure);
1347 	if (cb != NULL && error != NULL)
1348 		cb (data->book, error->code, data->closure);
1349 	if (excb != NULL)
1350 		excb (data->book, error, data->closure);
1351 
1352 	if (error != NULL)
1353 		g_error_free (error);
1354 
1355 	g_object_unref (data->book);
1356 	g_slice_free (AsyncData, data);
1357 }
1358 
1359 /**
1360  * e_book_async_remove_contact_by_id:
1361  * @book: an #EBook
1362  * @id: a unique ID string specifying the contact
1363  * @cb: (scope async): a function to call when the operation finishes
1364  * @closure: data to pass to callback function
1365  *
1366  * Removes the contact with id @id from @book.
1367  *
1368  * Returns: %TRUE if successful, %FALSE otherwise
1369  *
1370  * Deprecated: 3.0: Use e_book_remove_contact_by_id_async() instead.
1371  **/
1372 gboolean
e_book_async_remove_contact_by_id(EBook * book,const gchar * id,EBookCallback cb,gpointer closure)1373 e_book_async_remove_contact_by_id (EBook *book,
1374                                    const gchar *id,
1375                                    EBookCallback cb,
1376                                    gpointer closure)
1377 {
1378 	AsyncData *data;
1379 
1380 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1381 	g_return_val_if_fail (id != NULL, FALSE);
1382 
1383 	data = g_slice_new0 (AsyncData);
1384 	data->book = g_object_ref (book);
1385 	data->callback = cb;
1386 	data->closure = closure;
1387 
1388 	e_book_client_remove_contact_by_uid (
1389 		E_BOOK_CLIENT (book->priv->client),
1390 		id, E_BOOK_OPERATION_FLAG_NONE,
1391 		NULL, remove_contact_by_id_reply, data);
1392 
1393 	return TRUE;
1394 }
1395 
1396 /**
1397  * e_book_remove_contact_by_id_async:
1398  * @book: an #EBook
1399  * @id: a unique ID string specifying the contact
1400  * @cb: (scope async): a function to call when the operation finishes
1401  * @closure: data to pass to callback function
1402  *
1403  * Removes the contact with id @id from @book.
1404  *
1405  * Returns: %TRUE if successful, %FALSE otherwise
1406  *
1407  * Since: 2.32
1408  *
1409  * Deprecated: 3.2: Use e_book_client_remove_contact_by_uid() and
1410  *                  e_book_client_remove_contact_by_uid_finish() instead.
1411  **/
1412 gboolean
e_book_remove_contact_by_id_async(EBook * book,const gchar * id,EBookAsyncCallback cb,gpointer closure)1413 e_book_remove_contact_by_id_async (EBook *book,
1414                                    const gchar *id,
1415                                    EBookAsyncCallback cb,
1416                                    gpointer closure)
1417 {
1418 	AsyncData *data;
1419 
1420 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1421 	g_return_val_if_fail (id != NULL, FALSE);
1422 
1423 	data = g_slice_new0 (AsyncData);
1424 	data->book = g_object_ref (book);
1425 	data->excallback = cb;
1426 	data->closure = closure;
1427 
1428 	e_book_client_remove_contact_by_uid (
1429 		E_BOOK_CLIENT (book->priv->client),
1430 		id, E_BOOK_OPERATION_FLAG_NONE,
1431 		NULL, remove_contact_by_id_reply, data);
1432 
1433 	return TRUE;
1434 }
1435 
1436 static void
remove_contacts_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)1437 remove_contacts_reply (GObject *source_object,
1438                        GAsyncResult *result,
1439                        gpointer user_data)
1440 {
1441 	AsyncData *data = user_data;
1442 	EBookCallback cb = data->callback;
1443 	EBookAsyncCallback excb = data->excallback;
1444 	GError *error = NULL;
1445 
1446 	e_book_client_remove_contacts_finish (
1447 		E_BOOK_CLIENT (source_object), result, &error);
1448 
1449 	if (cb != NULL && error == NULL)
1450 		cb (data->book, E_BOOK_ERROR_OK, data->closure);
1451 	if (cb != NULL && error != NULL)
1452 		cb (data->book, error->code, data->closure);
1453 	if (excb != NULL)
1454 		excb (data->book, error, data->closure);
1455 
1456 	if (error != NULL)
1457 		g_error_free (error);
1458 
1459 	g_object_unref (data->book);
1460 	g_slice_free (AsyncData, data);
1461 }
1462 
1463 /**
1464  * e_book_async_remove_contacts:
1465  * @book: an #EBook
1466  * @ids: (element-type utf8): a #GList of const gchar *id's
1467  * @cb: (scope async): a function to call when the operation finishes
1468  * @closure: data to pass to callback function
1469  *
1470  * Removes the contacts with ids from the list @ids from @book.  This is
1471  * always more efficient than calling e_book_remove_contact() if you
1472  * have more than one id to remove, as some backends can implement it
1473  * as a batch request.
1474  *
1475  * Returns: %TRUE if successful, %FALSE otherwise
1476  *
1477  * Deprecated: 3.0: Use e_book_remove_contacts_async() instead.
1478  **/
1479 gboolean
e_book_async_remove_contacts(EBook * book,GList * ids,EBookCallback cb,gpointer closure)1480 e_book_async_remove_contacts (EBook *book,
1481                               GList *ids,
1482                               EBookCallback cb,
1483                               gpointer closure)
1484 {
1485 	AsyncData *data;
1486 	GSList *slist = NULL;
1487 
1488 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1489 
1490 	data = g_slice_new0 (AsyncData);
1491 	data->book = g_object_ref (book);
1492 	data->callback = cb;
1493 	data->closure = closure;
1494 
1495 	/* XXX Never use GSList in a public API. */
1496 	while (ids != NULL) {
1497 		slist = g_slist_prepend (slist, ids->data);
1498 		ids = g_list_next (ids);
1499 	}
1500 	slist = g_slist_reverse (slist);
1501 
1502 	e_book_client_remove_contacts (
1503 		E_BOOK_CLIENT (book->priv->client),
1504 		slist, E_BOOK_OPERATION_FLAG_NONE,
1505 		NULL, remove_contacts_reply, data);
1506 
1507 	g_slist_free (slist);
1508 
1509 	return TRUE;
1510 }
1511 
1512 /**
1513  * e_book_remove_contacts_async:
1514  * @book: an #EBook
1515  * @ids: (element-type utf8): a #GList of const gchar *id's
1516  * @cb: (scope async): a function to call when the operation finishes
1517  * @closure: data to pass to callback function
1518  *
1519  * Removes the contacts with ids from the list @ids from @book.  This is
1520  * always more efficient than calling e_book_remove_contact() if you
1521  * have more than one id to remove, as some backends can implement it
1522  * as a batch request.
1523  *
1524  * Returns: %TRUE if successful, %FALSE otherwise
1525  *
1526  * Since: 2.32
1527  *
1528  * Deprecated: 3.2: Use e_book_client_remove_contacts() and
1529  *                  e_book_client_remove_contacts_finish() instead.
1530  **/
1531 gboolean
e_book_remove_contacts_async(EBook * book,GList * ids,EBookAsyncCallback cb,gpointer closure)1532 e_book_remove_contacts_async (EBook *book,
1533                               GList *ids,
1534                               EBookAsyncCallback cb,
1535                               gpointer closure)
1536 {
1537 	AsyncData *data;
1538 	GSList *slist = NULL;
1539 
1540 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1541 
1542 	data = g_slice_new0 (AsyncData);
1543 	data->book = g_object_ref (book);
1544 	data->excallback = cb;
1545 	data->closure = closure;
1546 
1547 	/* XXX Never use GSList in a public API. */
1548 	while (ids != NULL) {
1549 		slist = g_slist_prepend (slist, ids->data);
1550 		ids = g_list_next (ids);
1551 	}
1552 	slist = g_slist_reverse (slist);
1553 
1554 	e_book_client_remove_contacts (
1555 		E_BOOK_CLIENT (book->priv->client),
1556 		slist, E_BOOK_OPERATION_FLAG_NONE,
1557 		NULL, remove_contacts_reply, data);
1558 
1559 	g_slist_free (slist);
1560 
1561 	return TRUE;
1562 }
1563 
1564 /**
1565  * e_book_get_book_view:
1566  * @book: an #EBook
1567  * @query: an #EBookQuery
1568  * @requested_fields: (nullable) (element-type utf8): a #GList containing
1569  *                    the names of fields to return, or %NULL for all
1570  * @max_results: the maximum number of contacts to show (or 0 for all)
1571  * @book_view: (out): An #EBookView pointer, will be set to the view
1572  * @error: a #GError to set on failure
1573  *
1574  * Query @book with @query, creating an #EBookView in @book_view with the fields
1575  * specified by @requested_fields and limited at @max_results records. On an
1576  * error, @error is set and %FALSE returned.
1577  *
1578  * Returns: %TRUE if successful, %FALSE otherwise
1579  *
1580  * Deprecated: 3.2: Use e_book_client_get_view_sync() instead.
1581  **/
1582 gboolean
e_book_get_book_view(EBook * book,EBookQuery * query,GList * requested_fields,gint max_results,EBookView ** book_view,GError ** error)1583 e_book_get_book_view (EBook *book,
1584                       EBookQuery *query,
1585                       GList *requested_fields,
1586                       gint max_results,
1587                       EBookView **book_view,
1588                       GError **error)
1589 {
1590 	EBookClientView *client_view = NULL;
1591 	gchar *sexp;
1592 	gboolean success;
1593 
1594 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1595 	g_return_val_if_fail (query != NULL, FALSE);
1596 	g_return_val_if_fail (book_view != NULL, FALSE);
1597 
1598 	sexp = e_book_query_to_string (query);
1599 
1600 	success = e_book_client_get_view_sync (
1601 		book->priv->client, sexp, &client_view, NULL, error);
1602 
1603 	g_free (sexp);
1604 
1605 	/* Sanity check. */
1606 	g_return_val_if_fail (
1607 		(success && (client_view != NULL)) ||
1608 		(!success && (client_view == NULL)), FALSE);
1609 
1610 	if (client_view != NULL) {
1611 		*book_view = _e_book_view_new (book, client_view);
1612 		g_object_unref (client_view);
1613 	}
1614 
1615 	return success;
1616 }
1617 
1618 static void
get_book_view_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)1619 get_book_view_reply (GObject *source_object,
1620                      GAsyncResult *result,
1621                      gpointer user_data)
1622 {
1623 	AsyncData *data = user_data;
1624 	EBookBookViewCallback cb = data->callback;
1625 	EBookBookViewAsyncCallback excb = data->excallback;
1626 	EBookClientView *client_view = NULL;
1627 	EBookView *view = NULL;
1628 	GError *error = NULL;
1629 
1630 	e_book_client_get_view_finish (
1631 		E_BOOK_CLIENT (source_object),
1632 		result, &client_view, &error);
1633 
1634 	/* Sanity check. */
1635 	g_return_if_fail (
1636 		((client_view != NULL) && (error == NULL)) ||
1637 		((client_view == NULL) && (error != NULL)));
1638 
1639 	if (client_view != NULL) {
1640 		view = _e_book_view_new (data->book, client_view);
1641 		g_object_unref (client_view);
1642 	}
1643 
1644 	if (cb != NULL && error == NULL)
1645 		cb (data->book, E_BOOK_ERROR_OK, view, data->closure);
1646 	if (cb != NULL && error != NULL)
1647 		cb (data->book, error->code, NULL, data->closure);
1648 	if (excb != NULL)
1649 		excb (data->book, error, view, data->closure);
1650 
1651 	if (error != NULL)
1652 		g_error_free (error);
1653 
1654 	g_object_unref (data->book);
1655 	g_slice_free (AsyncData, data);
1656 }
1657 
1658 /**
1659  * e_book_async_get_book_view:
1660  * @book: an #EBook
1661  * @query: an #EBookQuery
1662  * @requested_fields: (element-type utf8): a #GList containing the names of
1663  *                    fields to return, or NULL for all
1664  * @max_results: the maximum number of contacts to show (or 0 for all)
1665  * @cb: (scope async): a function to call when the operation finishes
1666  * @closure: data to pass to callback function
1667  *
1668  * Query @book with @query, creating an #EBookView with the fields
1669  * specified by @requested_fields and limited at @max_results records.
1670  *
1671  * Returns: %TRUE if successful, %FALSE otherwise
1672  *
1673  * Deprecated: 3.0: Use e_book_get_book_view_async() instead.
1674  **/
1675 gboolean
e_book_async_get_book_view(EBook * book,EBookQuery * query,GList * requested_fields,gint max_results,EBookBookViewCallback cb,gpointer closure)1676 e_book_async_get_book_view (EBook *book,
1677                             EBookQuery *query,
1678                             GList *requested_fields,
1679                             gint max_results,
1680                             EBookBookViewCallback cb,
1681                             gpointer closure)
1682 {
1683 	AsyncData *data;
1684 	gchar *sexp;
1685 
1686 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1687 	g_return_val_if_fail (query != NULL, FALSE);
1688 
1689 	data = g_slice_new0 (AsyncData);
1690 	data->book = g_object_ref (book);
1691 	data->callback = cb;
1692 	data->closure = closure;
1693 
1694 	sexp = e_book_query_to_string (query);
1695 
1696 	e_book_client_get_view (
1697 		book->priv->client, sexp,
1698 		NULL, get_book_view_reply, data);
1699 
1700 	g_free (sexp);
1701 
1702 	return TRUE;
1703 }
1704 
1705 /**
1706  * e_book_get_book_view_async:
1707  * @book: an #EBook
1708  * @query: an #EBookQuery
1709  * @requested_fields: (nullable) (element-type utf8): a #GList containing
1710  *                    the names of fields to return, or %NULL for all
1711  * @max_results: the maximum number of contacts to show (or 0 for all)
1712  * @cb: (scope async): a function to call when the operation finishes
1713  * @closure: data to pass to callback function
1714  *
1715  * Query @book with @query, creating an #EBookView with the fields
1716  * specified by @requested_fields and limited at @max_results records.
1717  *
1718  * Returns: %TRUE if successful, %FALSE otherwise
1719  *
1720  * Since: 2.32
1721  *
1722  * Deprecated: 3.2: Use e_book_client_get_view() and
1723  *                  e_book_client_get_view_finish() instead.
1724  **/
1725 gboolean
e_book_get_book_view_async(EBook * book,EBookQuery * query,GList * requested_fields,gint max_results,EBookBookViewAsyncCallback cb,gpointer closure)1726 e_book_get_book_view_async (EBook *book,
1727                             EBookQuery *query,
1728                             GList *requested_fields,
1729                             gint max_results,
1730                             EBookBookViewAsyncCallback cb,
1731                             gpointer closure)
1732 {
1733 	AsyncData *data;
1734 	gchar *sexp;
1735 
1736 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1737 	g_return_val_if_fail (query != NULL, FALSE);
1738 
1739 	data = g_slice_new0 (AsyncData);
1740 	data->book = g_object_ref (book);
1741 	data->excallback = cb;
1742 	data->closure = closure;
1743 
1744 	sexp = e_book_query_to_string (query);
1745 
1746 	e_book_client_get_view (
1747 		book->priv->client, sexp,
1748 		NULL, get_book_view_reply, data);
1749 
1750 	g_free (sexp);
1751 
1752 	return TRUE;
1753 }
1754 
1755 /**
1756  * e_book_get_contacts:
1757  * @book: an #EBook
1758  * @query: an #EBookQuery
1759  * @contacts: (element-type utf8): a #GList pointer, will be set to the
1760  *            list of contacts
1761  * @error: a #GError to set on failure
1762  *
1763  * Query @book with @query, setting @contacts to the list of contacts which
1764  * matched. On failed, @error will be set and %FALSE returned.
1765  *
1766  * Returns: %TRUE on success, %FALSE otherwise
1767  *
1768  * Deprecated: 3.2: Use e_book_client_get_contacts_sync() instead.
1769  **/
1770 gboolean
e_book_get_contacts(EBook * book,EBookQuery * query,GList ** contacts,GError ** error)1771 e_book_get_contacts (EBook *book,
1772                      EBookQuery *query,
1773                      GList **contacts,
1774                      GError **error)
1775 {
1776 	GSList *slist = NULL;
1777 	gchar *sexp;
1778 	gboolean success;
1779 
1780 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1781 	g_return_val_if_fail (query != NULL, FALSE);
1782 
1783 	if (contacts != NULL)
1784 		*contacts = NULL;
1785 
1786 	sexp = e_book_query_to_string (query);
1787 
1788 	success = e_book_client_get_contacts_sync (
1789 		E_BOOK_CLIENT (book->priv->client),
1790 		sexp, &slist, NULL, error);
1791 
1792 	g_free (sexp);
1793 
1794 	/* XXX Never use GSList in a public API. */
1795 	if (success && contacts != NULL) {
1796 		GList *list = NULL;
1797 		GSList *link;
1798 
1799 		for (link = slist; link != NULL; link = g_slist_next (link)) {
1800 			EContact *contact = E_CONTACT (link->data);
1801 			list = g_list_prepend (list, g_object_ref (contact));
1802 		}
1803 
1804 		*contacts = g_list_reverse (list);
1805 	}
1806 
1807 	g_slist_free_full (slist, (GDestroyNotify) g_object_unref);
1808 
1809 	return success;
1810 }
1811 
1812 static void
get_contacts_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)1813 get_contacts_reply (GObject *source_object,
1814                     GAsyncResult *result,
1815                     gpointer user_data)
1816 {
1817 	AsyncData *data = user_data;
1818 	EBookListAsyncCallback excb = data->excallback;
1819 	EBookListCallback cb = data->callback;
1820 	GSList *slist = NULL;
1821 	GList *list = NULL;
1822 	GError *error = NULL;
1823 
1824 	e_book_client_get_contacts_finish (
1825 		E_BOOK_CLIENT (source_object), result, &slist, &error);
1826 
1827 	/* XXX Never use GSList in a public API. */
1828 	if (error == NULL) {
1829 		GSList *link;
1830 
1831 		for (link = slist; link != NULL; link = g_slist_next (link)) {
1832 			EContact *contact = E_CONTACT (link->data);
1833 			list = g_list_prepend (list, g_object_ref (contact));
1834 		}
1835 
1836 		list = g_list_reverse (list);
1837 	}
1838 
1839 	if (cb != NULL && error == NULL)
1840 		cb (data->book, E_BOOK_ERROR_OK, list, data->closure);
1841 	if (cb != NULL && error != NULL)
1842 		cb (data->book, error->code, list, data->closure);
1843 	if (excb != NULL)
1844 		excb (data->book, error, list, data->closure);
1845 
1846 	g_list_free_full (list, (GDestroyNotify) g_object_unref);
1847 	g_slist_free_full (slist, (GDestroyNotify) g_object_unref);
1848 
1849 	if (error != NULL)
1850 		g_error_free (error);
1851 
1852 	g_object_unref (data->book);
1853 	g_slice_free (AsyncData, data);
1854 }
1855 
1856 /**
1857  * e_book_async_get_contacts:
1858  * @book: an #EBook
1859  * @query: an #EBookQuery
1860  * @cb: (scope async): a function to call when the operation finishes
1861  * @closure: data to pass to callback function
1862  *
1863  * Query @book with @query.
1864  *
1865  * Returns: %FALSE on success, %TRUE otherwise
1866  *
1867  * Deprecated: 3.0: Use e_book_get_contacts_async() instead.
1868  **/
1869 gboolean
e_book_async_get_contacts(EBook * book,EBookQuery * query,EBookListCallback cb,gpointer closure)1870 e_book_async_get_contacts (EBook *book,
1871                            EBookQuery *query,
1872                            EBookListCallback cb,
1873                            gpointer closure)
1874 {
1875 	AsyncData *data;
1876 	gchar *sexp;
1877 
1878 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1879 	g_return_val_if_fail (query != NULL, FALSE);
1880 
1881 	data = g_slice_new0 (AsyncData);
1882 	data->book = g_object_ref (book);
1883 	data->callback = cb;
1884 	data->closure = closure;
1885 
1886 	sexp = e_book_query_to_string (query);
1887 
1888 	e_book_client_get_contacts (
1889 		E_BOOK_CLIENT (book->priv->client),
1890 		sexp, NULL, get_contacts_reply, data);
1891 
1892 	g_free (sexp);
1893 
1894 	return TRUE;
1895 }
1896 
1897 /**
1898  * e_book_get_contacts_async:
1899  * @book: an #EBook
1900  * @query: an #EBookQuery
1901  * @cb: (scope async): a function to call when the operation finishes
1902  * @closure: data to pass to callback function
1903  *
1904  * Query @book with @query.
1905  *
1906  * Returns: %FALSE on success, %TRUE otherwise
1907  *
1908  * Since: 2.32
1909  *
1910  * Deprecated: 3.2: Use e_book_client_get_contacts() and
1911  *                  e_book_client_get_contacts_finish() instead.
1912  **/
1913 gboolean
e_book_get_contacts_async(EBook * book,EBookQuery * query,EBookListAsyncCallback cb,gpointer closure)1914 e_book_get_contacts_async (EBook *book,
1915                            EBookQuery *query,
1916                            EBookListAsyncCallback cb,
1917                            gpointer closure)
1918 {
1919 	AsyncData *data;
1920 	gchar *sexp;
1921 
1922 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1923 	g_return_val_if_fail (query != NULL, FALSE);
1924 
1925 	data = g_slice_new0 (AsyncData);
1926 	data->book = g_object_ref (book);
1927 	data->excallback = cb;
1928 	data->closure = closure;
1929 
1930 	sexp = e_book_query_to_string (query);
1931 
1932 	e_book_client_get_contacts (
1933 		E_BOOK_CLIENT (book->priv->client),
1934 		sexp, NULL, get_contacts_reply, data);
1935 
1936 	g_free (sexp);
1937 
1938 	return TRUE;
1939 }
1940 
1941 /**
1942  * e_book_get_changes: (skip)
1943  * @book: an #EBook
1944  * @changeid:  the change ID
1945  * @changes: (out) (transfer full): return location for a #GList of #EBookChange items
1946  * @error: a #GError to set on failure.
1947  *
1948  * Get the set of changes since the previous call to e_book_get_changes()
1949  * for a given change ID.
1950  *
1951  * Returns: %TRUE on success, %FALSE otherwise
1952  *
1953  * Deprecated: 3.2: This function has been dropped completely.
1954  */
1955 gboolean
e_book_get_changes(EBook * book,const gchar * changeid,GList ** changes,GError ** error)1956 e_book_get_changes (EBook *book,
1957                     const gchar *changeid,
1958                     GList **changes,
1959                     GError **error)
1960 {
1961 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1962 
1963 	g_set_error (
1964 		error, E_BOOK_ERROR,
1965 		E_BOOK_ERROR_NOT_SUPPORTED,
1966 		"Not supported");
1967 
1968 	return FALSE;
1969 }
1970 
1971 /**
1972  * e_book_async_get_changes:
1973  * @book: an #EBook
1974  * @changeid:  the change ID
1975  * @cb: (scope async): function to call when operation finishes
1976  * @closure: data to pass to callback function
1977  *
1978  * Get the set of changes since the previous call to
1979  * e_book_async_get_changes() for a given change ID.
1980  *
1981  * Returns: %TRUE on success, %FALSE otherwise
1982  *
1983  * Deprecated: 3.0: Use e_book_get_changes_async() instead.
1984  */
1985 gboolean
e_book_async_get_changes(EBook * book,const gchar * changeid,EBookListCallback cb,gpointer closure)1986 e_book_async_get_changes (EBook *book,
1987                           const gchar *changeid,
1988                           EBookListCallback cb,
1989                           gpointer closure)
1990 {
1991 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
1992 
1993 	cb (book, E_BOOK_ERROR_NOT_SUPPORTED, NULL, closure);
1994 
1995 	return TRUE;
1996 }
1997 
1998 /**
1999  * e_book_get_changes_async:
2000  * @book: an #EBook
2001  * @changeid:  the change ID
2002  * @cb: (scope async): function to call when operation finishes
2003  * @closure: data to pass to callback function
2004  *
2005  * Get the set of changes since the previous call to
2006  * e_book_async_get_changes() for a given change ID.
2007  *
2008  * Returns: %TRUE on success, %FALSE otherwise
2009  *
2010  * Since: 2.32
2011  *
2012  * Deprecated: 3.2: This function has been dropped completely.
2013  */
2014 gboolean
e_book_get_changes_async(EBook * book,const gchar * changeid,EBookListAsyncCallback cb,gpointer closure)2015 e_book_get_changes_async (EBook *book,
2016                           const gchar *changeid,
2017                           EBookListAsyncCallback cb,
2018                           gpointer closure)
2019 {
2020 	GError *error;
2021 
2022 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2023 
2024 	error = g_error_new (
2025 		E_BOOK_ERROR,
2026 		E_BOOK_ERROR_NOT_SUPPORTED,
2027 		"Not supported");
2028 
2029 	cb (book, error, NULL, closure);
2030 
2031 	g_error_free (error);
2032 
2033 	return TRUE;
2034 }
2035 
2036 /**
2037  * e_book_free_change_list:
2038  * @change_list: (element-type EBookChange): a #GList of #EBookChange items
2039  *
2040  * Free the contents of #change_list, and the list itself.
2041  *
2042  * Deprecated: 3.2: Related function has been dropped completely.
2043  */
2044 void
e_book_free_change_list(GList * change_list)2045 e_book_free_change_list (GList *change_list)
2046 {
2047 	GList *l;
2048 	for (l = change_list; l; l = l->next) {
2049 		EBookChange *change = l->data;
2050 
2051 		g_object_unref (change->contact);
2052 		g_slice_free (EBookChange, change);
2053 	}
2054 
2055 	g_list_free (change_list);
2056 }
2057 
2058 /**
2059  * e_book_cancel:
2060  * @book: an #EBook
2061  * @error: a #GError to set on failure
2062  *
2063  * Used to cancel an already running operation on @book.  This
2064  * function makes a synchronous CORBA to the backend telling it to
2065  * cancel the operation.  If the operation wasn't cancellable (either
2066  * transiently or permanently) or had already comopleted on the server
2067  * side, this function will return E_BOOK_STATUS_COULD_NOT_CANCEL, and
2068  * the operation will continue uncancelled.  If the operation could be
2069  * cancelled, this function will return E_BOOK_ERROR_OK, and the
2070  * blocked e_book function corresponding to current operation will
2071  * return with a status of E_BOOK_STATUS_CANCELLED.
2072  *
2073  * Returns: %TRUE on success, %FALSE otherwise
2074  *
2075  * Deprecated: 3.2: Use e_client_cancel_all() on an #EBookClient object instead.
2076  **/
2077 gboolean
e_book_cancel(EBook * book,GError ** error)2078 e_book_cancel (EBook *book,
2079                GError **error)
2080 {
2081 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2082 
2083 	e_client_cancel_all (E_CLIENT (book->priv->client));
2084 
2085 	return TRUE;
2086 }
2087 
2088 /**
2089  * e_book_cancel_async_op:
2090  * @book: an #EBook
2091  * @error: return location for a #GError, or %NULL
2092  *
2093  * Similar to above e_book_cancel function, only cancels last, still running,
2094  * asynchronous operation.
2095  *
2096  * Returns: %TRUE on success, %FALSE otherwise
2097  *
2098  * Since: 2.24
2099  *
2100  * Deprecated: 3.2: Use e_client_cancel_all() on an #EBookClient object instead.
2101  **/
2102 gboolean
e_book_cancel_async_op(EBook * book,GError ** error)2103 e_book_cancel_async_op (EBook *book,
2104                         GError **error)
2105 {
2106 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2107 
2108 	e_client_cancel_all (E_CLIENT (book->priv->client));
2109 
2110 	return TRUE;
2111 }
2112 
2113 /**
2114  * e_book_open:
2115  * @book: an #EBook
2116  * @only_if_exists: if %TRUE, fail if this book doesn't already exist,
2117  *                  otherwise create it first
2118  * @error: a #GError to set on failure
2119  *
2120  * Opens the addressbook, making it ready for queries and other operations.
2121  *
2122  * Returns: %TRUE if the book was successfully opened, %FALSE otherwise.
2123  *
2124  * Deprecated: 3.2: Use e_client_open_sync() on an #EBookClient object instead.
2125  */
2126 gboolean
e_book_open(EBook * book,gboolean only_if_exists,GError ** error)2127 e_book_open (EBook *book,
2128              gboolean only_if_exists,
2129              GError **error)
2130 {
2131 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2132 
2133 	return e_client_open_sync (
2134 		E_CLIENT (book->priv->client),
2135 		only_if_exists, NULL, error);
2136 }
2137 
2138 static void
open_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)2139 open_reply (GObject *source_object,
2140             GAsyncResult *result,
2141             gpointer user_data)
2142 {
2143 	AsyncData *data = user_data;
2144 	EBookCallback cb = data->callback;
2145 	EBookAsyncCallback excb = data->excallback;
2146 	GError *error = NULL;
2147 
2148 	e_client_open_finish (E_CLIENT (source_object), result, &error);
2149 
2150 	if (cb != NULL && error == NULL)
2151 		cb (data->book, E_BOOK_ERROR_OK, data->closure);
2152 	if (cb != NULL && error != NULL)
2153 		cb (data->book, error->code, data->closure);
2154 	if (excb != NULL)
2155 		excb (data->book, error, data->closure);
2156 
2157 	if (error != NULL)
2158 		g_error_free (error);
2159 
2160 	g_object_unref (data->book);
2161 	g_slice_free (AsyncData, data);
2162 }
2163 
2164 /**
2165  * e_book_async_open:
2166  * @book: an #EBook
2167  * @only_if_exists: if %TRUE, fail if this book doesn't already exist,
2168  *                  otherwise create it first
2169  * @open_response: (scope call) (closure closure): a function to call when
2170  *                 the operation finishes
2171  * @closure: data to pass to callback function
2172  *
2173  * Opens the addressbook, making it ready for queries and other operations.
2174  * This function does not block.
2175  *
2176  * Returns: %TRUE if successful, %FALSE otherwise
2177  *
2178  * Deprecated: 3.0: Use e_book_open_async() instead.
2179  **/
2180 gboolean
e_book_async_open(EBook * book,gboolean only_if_exists,EBookCallback cb,gpointer closure)2181 e_book_async_open (EBook *book,
2182                    gboolean only_if_exists,
2183                    EBookCallback cb,
2184                    gpointer closure)
2185 {
2186 	AsyncData *data;
2187 
2188 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2189 
2190 	data = g_slice_new0 (AsyncData);
2191 	data->book = g_object_ref (book);
2192 	data->callback = cb;
2193 	data->closure = closure;
2194 
2195 	e_client_open (
2196 		E_CLIENT (book->priv->client),
2197 		only_if_exists, NULL, open_reply, data);
2198 
2199 	return TRUE;
2200 }
2201 
2202 /**
2203  * e_book_open_async:
2204  * @book: an #EBook
2205  * @only_if_exists: if %TRUE, fail if this book doesn't already exist,
2206  *                  otherwise create it first
2207  * @open_response: (scope call): a function to call when the operation finishes
2208  * @closure: data to pass to callback function
2209  *
2210  * Opens the addressbook, making it ready for queries and other operations.
2211  * This function does not block.
2212  *
2213  * Returns: %TRUE if successful, %FALSE otherwise
2214  *
2215  * Since: 2.32
2216  *
2217  * Deprecated: 3.2: Use e_client_open() and e_client_open_finish() on an
2218  *                  #EBookClient object instead.
2219  **/
2220 gboolean
e_book_open_async(EBook * book,gboolean only_if_exists,EBookAsyncCallback cb,gpointer closure)2221 e_book_open_async (EBook *book,
2222                    gboolean only_if_exists,
2223                    EBookAsyncCallback cb,
2224                    gpointer closure)
2225 {
2226 	AsyncData *data;
2227 
2228 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2229 
2230 	data = g_slice_new0 (AsyncData);
2231 	data->book = g_object_ref (book);
2232 	data->excallback = cb;
2233 	data->closure = closure;
2234 
2235 	e_client_open (
2236 		E_CLIENT (book->priv->client),
2237 		only_if_exists, NULL, open_reply, data);
2238 
2239 	return TRUE;
2240 }
2241 
2242 /**
2243  * e_book_remove:
2244  * @book: an #EBook
2245  * @error: a #GError to set on failure
2246  *
2247  * Removes the backing data for this #EBook. For example, with the file backend this
2248  * deletes the database file. You cannot get it back!
2249  *
2250  * Returns: %TRUE on success, %FALSE on failure.
2251  *
2252  * Deprecated: 3.2: Use e_client_remove_sync() on an #EBookClient object instead.
2253  */
2254 gboolean
e_book_remove(EBook * book,GError ** error)2255 e_book_remove (EBook *book,
2256                GError **error)
2257 {
2258 	ESource *source;
2259 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2260 
2261 	source = e_book_get_source (book);
2262 
2263 	return e_source_remove_sync (source, NULL, error);
2264 }
2265 
2266 static void
remove_reply(GObject * source_object,GAsyncResult * result,gpointer user_data)2267 remove_reply (GObject *source_object,
2268               GAsyncResult *result,
2269               gpointer user_data)
2270 {
2271 	AsyncData *data = user_data;
2272 	EBookAsyncCallback excb = data->excallback;
2273 	EBookCallback cb = data->callback;
2274 	GError *error = NULL;
2275 
2276 	e_source_remove_finish (E_SOURCE (source_object), result, &error);
2277 
2278 	if (cb != NULL && error == NULL)
2279 		cb (data->book, E_BOOK_ERROR_OK, data->closure);
2280 
2281 	if (cb != NULL && error != NULL)
2282 		cb (data->book, error->code, data->closure);
2283 
2284 	if (excb != NULL)
2285 		excb (data->book, error, data->closure);
2286 
2287 	if (error != NULL)
2288 		g_error_free (error);
2289 
2290 	g_object_unref (data->book);
2291 	g_slice_free (AsyncData, data);
2292 }
2293 
2294 /**
2295  * e_book_async_remove:
2296  * @book: an #EBook
2297  * @cb: (scope async): a function to call when the operation finishes
2298  * @closure: data to pass to callback function
2299  *
2300  * Remove the backing data for this #EBook. For example, with the file backend this
2301  * deletes the database file. You cannot get it back!
2302  *
2303  * Returns: %TRUE if successful, %FALSE otherwise
2304  *
2305  * Deprecated: 3.0: Use e_book_remove_async() instead.
2306  **/
2307 gboolean
e_book_async_remove(EBook * book,EBookCallback cb,gpointer closure)2308 e_book_async_remove (EBook *book,
2309                      EBookCallback cb,
2310                      gpointer closure)
2311 {
2312 	ESource *source;
2313 	AsyncData *data;
2314 
2315 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2316 
2317 	data = g_slice_new0 (AsyncData);
2318 	data->book = g_object_ref (book);
2319 	data->callback = cb;
2320 	data->closure = closure;
2321 
2322 	source = e_book_get_source (book);
2323 
2324 	e_source_remove (source, NULL, remove_reply, data);
2325 
2326 	return TRUE;
2327 }
2328 
2329 /**
2330  * e_book_remove_async:
2331  * @book: an #EBook
2332  * @cb: (scope async): a function to call when the operation finishes
2333  * @closure: data to pass to callback function
2334  *
2335  * Remove the backing data for this #EBook. For example, with the file
2336  * backend this deletes the database file. You cannot get it back!
2337  *
2338  * Returns: %TRUE if successful, %FALSE otherwise
2339  *
2340  * Since: 2.32
2341  *
2342  * Deprecated: 3.2: Use e_client_remove() and e_client_remove_finish() on an
2343  *                  #EBookClient object instead.
2344  **/
2345 gboolean
e_book_remove_async(EBook * book,EBookAsyncCallback cb,gpointer closure)2346 e_book_remove_async (EBook *book,
2347                      EBookAsyncCallback cb,
2348                      gpointer closure)
2349 {
2350 	ESource *source;
2351 	AsyncData *data;
2352 
2353 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2354 
2355 	data = g_slice_new0 (AsyncData);
2356 	data->book = g_object_ref (book);
2357 	data->excallback = cb;
2358 	data->closure = closure;
2359 
2360 	source = e_book_get_source (book);
2361 
2362 	e_source_remove (source, NULL, remove_reply, data);
2363 
2364 	return TRUE;
2365 }
2366 
2367 /**
2368  * e_book_get_source:
2369  * @book: an #EBook
2370  *
2371  * Get the #ESource that this book has loaded.
2372  *
2373  * Returns: (transfer none): The source.
2374  *
2375  * Deprecated: 3.2: Use e_client_get_source() on an #EBookClient object instead.
2376  */
2377 ESource *
e_book_get_source(EBook * book)2378 e_book_get_source (EBook *book)
2379 {
2380 	g_return_val_if_fail (E_IS_BOOK (book), NULL);
2381 
2382 	return book->priv->source;
2383 }
2384 
2385 /**
2386  * e_book_get_static_capabilities:
2387  * @book: an #EBook
2388  * @error: an #GError to set on failure
2389  *
2390  * Get the list of capabilities which the backend for this address book
2391  * supports. This string should not be freed.
2392  *
2393  * Returns: The capabilities list
2394  *
2395  * Deprecated: 3.2: Use e_client_get_capabilities() on an #EBookClient object.
2396  */
2397 const gchar *
e_book_get_static_capabilities(EBook * book,GError ** error)2398 e_book_get_static_capabilities (EBook *book,
2399                                 GError **error)
2400 {
2401 	g_return_val_if_fail (E_IS_BOOK (book), NULL);
2402 
2403 	if (book->priv->cap == NULL) {
2404 		gboolean success;
2405 
2406 		success = e_client_retrieve_capabilities_sync (
2407 			E_CLIENT (book->priv->client),
2408 			&book->priv->cap, NULL, error);
2409 
2410 		/* Sanity check. */
2411 		g_return_val_if_fail (
2412 			(success && (book->priv->cap != NULL)) ||
2413 			(!success && (book->priv->cap == NULL)), NULL);
2414 	}
2415 
2416 	return book->priv->cap;
2417 }
2418 
2419 /**
2420  * e_book_check_static_capability:
2421  * @book: an #EBook
2422  * @cap: A capability string
2423  *
2424  * Check to see if the backend for this address book supports the capability
2425  * @cap.
2426  *
2427  * Returns: %TRUE if the backend supports @cap, %FALSE otherwise.
2428  *
2429  * Deprecated: 3.2: Use e_client_check_capability() on an #EBookClient object instead.
2430  */
2431 gboolean
e_book_check_static_capability(EBook * book,const gchar * cap)2432 e_book_check_static_capability (EBook *book,
2433                                 const gchar *cap)
2434 {
2435 	const gchar *caps;
2436 
2437 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2438 
2439 	caps = e_book_get_static_capabilities (book, NULL);
2440 
2441 	/* XXX this is an inexact test but it works for our use */
2442 	if (caps && strstr (caps, cap))
2443 		return TRUE;
2444 
2445 	return FALSE;
2446 }
2447 
2448 /**
2449  * e_book_is_opened:
2450  * @book: and #EBook
2451  *
2452  * Check if this book has been opened.
2453  *
2454  * Returns: %TRUE if this book has been opened, otherwise %FALSE.
2455  *
2456  * Deprecated: 3.2: Use e_client_is_opened() on an #EBookClient object instead.
2457  */
2458 gboolean
e_book_is_opened(EBook * book)2459 e_book_is_opened (EBook *book)
2460 {
2461 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2462 
2463 	return e_client_is_opened (E_CLIENT (book->priv->client));
2464 }
2465 
2466 /**
2467  * e_book_is_writable:
2468  * @book: an #EBook
2469  *
2470  * Check if this book is writable.
2471  *
2472  * Returns: %TRUE if this book is writable, otherwise %FALSE.
2473  *
2474  * Deprecated: 3.2: Use e_client_is_readonly() on an #EBookClient object instead.
2475  */
2476 gboolean
e_book_is_writable(EBook * book)2477 e_book_is_writable (EBook *book)
2478 {
2479 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2480 
2481 	return !e_client_is_readonly (E_CLIENT (book->priv->client));
2482 }
2483 
2484 /**
2485  * e_book_is_online:
2486  * @book: an #EBook
2487  *
2488  * Check if this book is connected.
2489  *
2490  * Returns: %TRUE if this book is connected, otherwise %FALSE.
2491  *
2492  * Deprecated: 3.2: Use e_client_is_online() on an #EBookClient object instead.
2493  **/
2494 gboolean
e_book_is_online(EBook * book)2495 e_book_is_online (EBook *book)
2496 {
2497 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2498 
2499 	return e_client_is_online (E_CLIENT (book->priv->client));
2500 }
2501 
2502 #define SELF_UID_PATH_ID "org.gnome.evolution-data-server.addressbook"
2503 #define SELF_UID_KEY "self-contact-uid"
2504 
2505 static EContact *
make_me_card(void)2506 make_me_card (void)
2507 {
2508 	GString *vcard;
2509 	const gchar *s;
2510 	EContact *contact;
2511 
2512 	vcard = g_string_new ("BEGIN:VCARD\nVERSION:3.0\n");
2513 
2514 	s = g_get_user_name ();
2515 	if (s)
2516 		g_string_append_printf (vcard, "NICKNAME:%s\n", s);
2517 
2518 	s = g_get_real_name ();
2519 	if (s && strcmp (s, "Unknown") != 0) {
2520 		ENameWestern *western;
2521 
2522 		g_string_append_printf (vcard, "FN:%s\n", s);
2523 
2524 		western = e_name_western_parse (s);
2525 		g_string_append_printf (
2526 			vcard, "N:%s;%s;%s;%s;%s\n",
2527 			western->last ? western->last : "",
2528 			western->first ? western->first : "",
2529 			western->middle ? western->middle : "",
2530 			western->prefix ? western->prefix : "",
2531 			western->suffix ? western->suffix : "");
2532 		e_name_western_free (western);
2533 	}
2534 	g_string_append (vcard, "END:VCARD");
2535 
2536 	contact = e_contact_new_from_vcard (vcard->str);
2537 
2538 	g_string_free (vcard, TRUE);
2539 
2540 	return contact;
2541 }
2542 
2543 /**
2544  * e_book_get_self:
2545  * @registry: an #ESourceRegistry
2546  * @contact: (out): an #EContact pointer to set
2547  * @book: (out): an #EBook pointer to set
2548  * @error: a #GError to set on failure
2549  *
2550  * Get the #EContact referring to the user of the address book
2551  * and set it in @contact and @book.
2552  *
2553  * Returns: %TRUE if successful, otherwise %FALSE.
2554  *
2555  * Deprecated: 3.2: Use e_book_client_get_self() instead.
2556  **/
2557 gboolean
e_book_get_self(ESourceRegistry * registry,EContact ** contact,EBook ** book,GError ** error)2558 e_book_get_self (ESourceRegistry *registry,
2559                  EContact **contact,
2560                  EBook **book,
2561                  GError **error)
2562 {
2563 	ESource *source;
2564 	GError *e = NULL;
2565 	GSettings *settings;
2566 	gboolean status;
2567 	gchar *uid;
2568 
2569 	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
2570 
2571 	source = e_source_registry_ref_builtin_address_book (registry);
2572 	*book = e_book_new (source, &e);
2573 	g_object_unref (source);
2574 
2575 	if (!*book) {
2576 		if (error)
2577 			g_propagate_error (error, e);
2578 		return FALSE;
2579 	}
2580 
2581 	status = e_book_open (*book, FALSE, &e);
2582 	if (status == FALSE) {
2583 		g_object_unref (*book);
2584 		*book = NULL;
2585 		if (error)
2586 			g_propagate_error (error, e);
2587 		return FALSE;
2588 	}
2589 
2590 	settings = g_settings_new (SELF_UID_PATH_ID);
2591 	uid = g_settings_get_string (settings, SELF_UID_KEY);
2592 	g_object_unref (settings);
2593 
2594 	if (uid) {
2595 		gboolean got;
2596 
2597 		/* Don't care about errors because we'll create a
2598 		 * new card on failure. */
2599 		got = e_book_get_contact (*book, uid, contact, NULL);
2600 		g_free (uid);
2601 		if (got)
2602 			return TRUE;
2603 	}
2604 
2605 	*contact = make_me_card ();
2606 	if (!e_book_add_contact (*book, *contact, &e)) {
2607 		/* TODO: return NULL or the contact anyway? */
2608 		g_object_unref (*book);
2609 		*book = NULL;
2610 		g_object_unref (*contact);
2611 		*contact = NULL;
2612 		if (error)
2613 			g_propagate_error (error, e);
2614 		return FALSE;
2615 	}
2616 
2617 	e_book_set_self (*book, *contact, NULL);
2618 
2619 	return TRUE;
2620 }
2621 
2622 /**
2623  * e_book_set_self:
2624  * @book: an #EBook
2625  * @contact: an #EContact
2626  * @error: a #GError to set on failure
2627  *
2628  * Specify that @contact residing in @book is the #EContact that
2629  * refers to the user of the address book.
2630  *
2631  * Returns: %TRUE if successful, %FALSE otherwise.
2632  *
2633  * Deprecated: 3.2: Use e_book_client_set_self() instead.
2634  **/
2635 gboolean
e_book_set_self(EBook * book,EContact * contact,GError ** error)2636 e_book_set_self (EBook *book,
2637                  EContact *contact,
2638                  GError **error)
2639 {
2640 	GSettings *settings;
2641 
2642 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
2643 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
2644 
2645 	settings = g_settings_new (SELF_UID_PATH_ID);
2646 	g_settings_set_string (
2647 		settings, SELF_UID_KEY,
2648 		e_contact_get_const (contact, E_CONTACT_UID));
2649 	g_object_unref (settings);
2650 
2651 	return TRUE;
2652 }
2653 
2654 /**
2655  * e_book_is_self:
2656  * @contact: an #EContact
2657  *
2658  * Check if @contact is the user of the address book.
2659  *
2660  * Returns: %TRUE if @contact is the user, %FALSE otherwise.
2661  *
2662  * Deprecated: 3.2: Use e_book_client_is_self() instead.
2663  **/
2664 gboolean
e_book_is_self(EContact * contact)2665 e_book_is_self (EContact *contact)
2666 {
2667 	GSettings *settings;
2668 	gchar *uid;
2669 	gboolean rv;
2670 
2671 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
2672 
2673 	settings = g_settings_new (SELF_UID_PATH_ID);
2674 	uid = g_settings_get_string (settings, SELF_UID_KEY);
2675 	g_object_unref (settings);
2676 
2677 	rv = (uid && !strcmp (uid, e_contact_get_const (contact, E_CONTACT_UID)));
2678 
2679 	g_free (uid);
2680 
2681 	return rv;
2682 }
2683 
2684 /**
2685  * e_book_new:
2686  * @source: an #ESource
2687  * @error: return location for a #GError, or %NULL
2688  *
2689  * Creates a new #EBook corresponding to the given @source.  There are
2690  * only two operations that are valid on this book at this point:
2691  * e_book_open(), and e_book_remove().
2692  *
2693  * Returns: a new but unopened #EBook.
2694  *
2695  * Deprecated: 3.2: Use e_book_client_new() instead.
2696  */
2697 EBook *
e_book_new(ESource * source,GError ** error)2698 e_book_new (ESource *source,
2699             GError **error)
2700 {
2701 	g_return_val_if_fail (E_IS_SOURCE (source), NULL);
2702 
2703 	return g_initable_new (
2704 		E_TYPE_BOOK, NULL, error,
2705 		"source", source, NULL);
2706 }
2707 
2708