diff options
Diffstat (limited to 'modules/contact-photos')
-rw-r--r-- | modules/contact-photos/Makefile.am | 30 | ||||
-rw-r--r-- | modules/contact-photos/e-contact-photo-source.c | 432 | ||||
-rw-r--r-- | modules/contact-photos/e-contact-photo-source.h | 73 | ||||
-rw-r--r-- | modules/contact-photos/e-photo-cache-contact-loader.c | 252 | ||||
-rw-r--r-- | modules/contact-photos/e-photo-cache-contact-loader.h | 66 | ||||
-rw-r--r-- | modules/contact-photos/evolution-contact-photos.c | 40 |
6 files changed, 893 insertions, 0 deletions
diff --git a/modules/contact-photos/Makefile.am b/modules/contact-photos/Makefile.am new file mode 100644 index 0000000000..83b934471f --- /dev/null +++ b/modules/contact-photos/Makefile.am @@ -0,0 +1,30 @@ +module_LTLIBRARIES = module-contact-photos.la + +module_contact_photos_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_srcdir) \ + -DG_LOG_DOMAIN=\"evolution-contact-photos\" \ + $(EVOLUTION_DATA_SERVER_CFLAGS) \ + $(GNOME_PLATFORM_CFLAGS) \ + $(GTKHTML_CFLAGS) \ + $(NULL) + +module_contact_photos_la_SOURCES = \ + evolution-contact-photos.c \ + e-contact-photo-source.c \ + e-contact-photo-source.h \ + e-photo-cache-contact-loader.c \ + e-photo-cache-contact-loader.h \ + $(NULL) + +module_contact_photos_la_LIBADD = \ + $(top_builddir)/e-util/libeutil.la \ + $(EVOLUTION_DATA_SERVER_LIBS) \ + $(GNOME_PLATFORM_LIBS) \ + $(GTKHTML_LIBS) \ + $(NULL) + +module_contact_photos_la_LDFLAGS = \ + -module -avoid-version $(NO_UNDEFINED) + +-include $(top_srcdir)/git.mk diff --git a/modules/contact-photos/e-contact-photo-source.c b/modules/contact-photos/e-contact-photo-source.c new file mode 100644 index 0000000000..b290a2168f --- /dev/null +++ b/modules/contact-photos/e-contact-photo-source.c @@ -0,0 +1,432 @@ +/* + * e-contact-photo-source.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + */ + +#include "e-contact-photo-source.h" + +#define E_CONTACT_PHOTO_SOURCE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CONTACT_PHOTO_SOURCE, EContactPhotoSourcePrivate)) + +typedef struct _AsyncContext AsyncContext; + +struct _EContactPhotoSourcePrivate { + EClientCache *client_cache; + ESource *source; +}; + +struct _AsyncContext { + gchar *query_string; + GInputStream *stream; + gint priority; +}; + +enum { + PROP_0, + PROP_CLIENT_CACHE, + PROP_SOURCE +}; + +/* Forward Declarations */ +static void e_contact_photo_source_interface_init + (EPhotoSourceInterface *interface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED ( + EContactPhotoSource, + e_contact_photo_source, + G_TYPE_OBJECT, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC ( + E_TYPE_PHOTO_SOURCE, + e_contact_photo_source_interface_init)) + +static void +async_context_free (AsyncContext *async_context) +{ + g_free (async_context->query_string); + g_clear_object (&async_context->stream); + + g_slice_free (AsyncContext, async_context); +} + +static EContactPhoto * +contact_photo_source_extract_photo (EContact *contact, + gint *out_priority) +{ + EContactPhoto *photo; + + photo = e_contact_get (contact, E_CONTACT_PHOTO); + *out_priority = G_PRIORITY_HIGH; + + if (photo == NULL) { + photo = e_contact_get (contact, E_CONTACT_LOGO); + *out_priority = G_PRIORITY_LOW; + } + + return photo; +} + +static void +contact_photo_source_get_photo_thread (GSimpleAsyncResult *simple, + GObject *source_object, + GCancellable *cancellable) +{ + EContactPhotoSource *photo_source; + AsyncContext *async_context; + EClientCache *client_cache; + ESourceRegistry *registry; + EClient *client = NULL; + ESource *source; + GSList *slist = NULL; + GSList *slink; + GError *error = NULL; + + photo_source = E_CONTACT_PHOTO_SOURCE (source_object); + async_context = g_simple_async_result_get_op_res_gpointer (simple); + + client_cache = e_contact_photo_source_ref_client_cache (photo_source); + source = e_contact_photo_source_ref_source (photo_source); + registry = e_client_cache_ref_registry (client_cache); + + /* Return no result if the source is disabled. */ + if (!e_source_registry_check_enabled (registry, source)) + goto exit; + + client = e_client_cache_get_client_sync ( + client_cache, source, + E_SOURCE_EXTENSION_ADDRESS_BOOK, + cancellable, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + if (error != NULL) { + g_simple_async_result_take_error (simple, error); + goto exit; + } + + e_book_client_get_contacts_sync ( + E_BOOK_CLIENT (client), + async_context->query_string, + &slist, cancellable, &error); + + if (error != NULL) { + g_warn_if_fail (slist == NULL); + g_simple_async_result_take_error (simple, error); + goto exit; + } + + /* See if any of the contacts have a photo. */ + for (slink = slist; slink != NULL; slink = g_slist_next (slink)) { + EContact *contact = E_CONTACT (slink->data); + GInputStream *stream = NULL; + EContactPhoto *photo; + + photo = contact_photo_source_extract_photo ( + contact, &async_context->priority); + + if (photo == NULL) + continue; + + /* Stream takes ownership of the inlined data. */ + if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED) { + stream = g_memory_input_stream_new_from_data ( + photo->data.inlined.data, + photo->data.inlined.length, + (GDestroyNotify) g_free); + photo->data.inlined.data = NULL; + photo->data.inlined.length = 0; + + } else { + GFileInputStream *file_stream; + GFile *file; + + file = g_file_new_for_uri (photo->data.uri); + + /* Disregard errors and proceed as + * though the contact has no photo. */ + + /* XXX Return type should have been GInputStream. */ + file_stream = g_file_read (file, cancellable, NULL); + if (file_stream != NULL) + stream = G_INPUT_STREAM (file_stream); + + g_object_unref (file); + } + + e_contact_photo_free (photo); + + /* Stop on the first input stream. */ + if (stream != NULL) { + async_context->stream = g_object_ref (stream); + g_object_unref (stream); + break; + } + } + + g_slist_free_full (slist, (GDestroyNotify) g_object_unref); + +exit: + g_clear_object (&client_cache); + g_clear_object (®istry); + g_clear_object (&client); + g_clear_object (&source); +} + +static void +contact_photo_source_set_client_cache (EContactPhotoSource *photo_source, + EClientCache *client_cache) +{ + g_return_if_fail (E_IS_CLIENT_CACHE (client_cache)); + g_return_if_fail (photo_source->priv->client_cache == NULL); + + photo_source->priv->client_cache = g_object_ref (client_cache); +} + +static void +contact_photo_source_set_source (EContactPhotoSource *photo_source, + ESource *source) +{ + g_return_if_fail (E_IS_SOURCE (source)); + g_return_if_fail (photo_source->priv->source == NULL); + + photo_source->priv->source = g_object_ref (source); +} + +static void +contact_photo_source_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CLIENT_CACHE: + contact_photo_source_set_client_cache ( + E_CONTACT_PHOTO_SOURCE (object), + g_value_get_object (value)); + return; + + case PROP_SOURCE: + contact_photo_source_set_source ( + E_CONTACT_PHOTO_SOURCE (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +contact_photo_source_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CLIENT_CACHE: + g_value_take_object ( + value, + e_contact_photo_source_ref_client_cache ( + E_CONTACT_PHOTO_SOURCE (object))); + return; + + case PROP_SOURCE: + g_value_take_object ( + value, + e_contact_photo_source_ref_source ( + E_CONTACT_PHOTO_SOURCE (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +contact_photo_source_dispose (GObject *object) +{ + EContactPhotoSourcePrivate *priv; + + priv = E_CONTACT_PHOTO_SOURCE_GET_PRIVATE (object); + + g_clear_object (&priv->client_cache); + g_clear_object (&priv->source); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_contact_photo_source_parent_class)->dispose (object); +} + +static void +contact_photo_source_get_photo (EPhotoSource *photo_source, + const gchar *email_address, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + AsyncContext *async_context; + EBookQuery *book_query; + + book_query = e_book_query_field_test ( + E_CONTACT_EMAIL, E_BOOK_QUERY_IS, email_address); + + async_context = g_slice_new0 (AsyncContext); + async_context->query_string = e_book_query_to_string (book_query); + + e_book_query_unref (book_query); + + simple = g_simple_async_result_new ( + G_OBJECT (photo_source), callback, + user_data, contact_photo_source_get_photo); + + g_simple_async_result_set_check_cancellable (simple, cancellable); + + g_simple_async_result_set_op_res_gpointer ( + simple, async_context, (GDestroyNotify) async_context_free); + + g_simple_async_result_run_in_thread ( + simple, contact_photo_source_get_photo_thread, + G_PRIORITY_DEFAULT, cancellable); + + g_object_unref (simple); +} + +static gboolean +contact_photo_source_get_photo_finish (EPhotoSource *photo_source, + GAsyncResult *result, + GInputStream **out_stream, + gint *out_priority, + GError **error) +{ + GSimpleAsyncResult *simple; + AsyncContext *async_context; + + g_return_val_if_fail ( + g_simple_async_result_is_valid ( + result, G_OBJECT (photo_source), + contact_photo_source_get_photo), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + async_context = g_simple_async_result_get_op_res_gpointer (simple); + + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + + if (async_context->stream != NULL) { + *out_stream = g_object_ref (async_context->stream); + if (out_priority != NULL) + *out_priority = async_context->priority; + } else { + *out_stream = NULL; + } + + return TRUE; +} + +static void +e_contact_photo_source_class_init (EContactPhotoSourceClass *class) +{ + GObjectClass *object_class; + + g_type_class_add_private (class, sizeof (EContactPhotoSourcePrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = contact_photo_source_set_property; + object_class->get_property = contact_photo_source_get_property; + object_class->dispose = contact_photo_source_dispose; + + g_object_class_install_property ( + object_class, + PROP_CLIENT_CACHE, + g_param_spec_object ( + "client-cache", + "Client Cache", + "Cache of shared EClient instances", + E_TYPE_CLIENT_CACHE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property ( + object_class, + PROP_SOURCE, + g_param_spec_object ( + "source", + "Source", + "An address book source", + E_TYPE_SOURCE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +e_contact_photo_source_class_finalize (EContactPhotoSourceClass *class) +{ +} + +static void +e_contact_photo_source_interface_init (EPhotoSourceInterface *interface) +{ + interface->get_photo = contact_photo_source_get_photo; + interface->get_photo_finish = contact_photo_source_get_photo_finish; +} + +static void +e_contact_photo_source_init (EContactPhotoSource *photo_source) +{ + photo_source->priv = E_CONTACT_PHOTO_SOURCE_GET_PRIVATE (photo_source); +} + +void +e_contact_photo_source_type_register (GTypeModule *type_module) +{ + /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration + * function, so we have to wrap it with a public function in + * order to register types from a separate compilation unit. */ + e_contact_photo_source_register_type (type_module); +} + +EPhotoSource * +e_contact_photo_source_new (EClientCache *client_cache, + ESource *source) +{ + g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL); + g_return_val_if_fail (E_IS_SOURCE (source), NULL); + + return g_object_new ( + E_TYPE_CONTACT_PHOTO_SOURCE, + "client-cache", client_cache, + "source", source, + NULL); +} + +EClientCache * +e_contact_photo_source_ref_client_cache (EContactPhotoSource *photo_source) +{ + g_return_val_if_fail (E_IS_CONTACT_PHOTO_SOURCE (photo_source), NULL); + + return g_object_ref (photo_source->priv->client_cache); +} + +ESource * +e_contact_photo_source_ref_source (EContactPhotoSource *photo_source) +{ + g_return_val_if_fail (E_IS_CONTACT_PHOTO_SOURCE (photo_source), NULL); + + return g_object_ref (photo_source->priv->source); +} + diff --git a/modules/contact-photos/e-contact-photo-source.h b/modules/contact-photos/e-contact-photo-source.h new file mode 100644 index 0000000000..2720c18acc --- /dev/null +++ b/modules/contact-photos/e-contact-photo-source.h @@ -0,0 +1,73 @@ +/* + * e-contact-photo-source.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 E_CONTACT_PHOTO_SOURCE_H +#define E_CONTACT_PHOTO_SOURCE_H + +#include <e-util/e-util.h> + +/* Standard GObject macros */ +#define E_TYPE_CONTACT_PHOTO_SOURCE \ + (e_contact_photo_source_get_type ()) +#define E_CONTACT_PHOTO_SOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CONTACT_PHOTO_SOURCE, EContactPhotoSource)) +#define E_CONTACT_PHOTO_SOURCE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_CONTACT_PHOTO_SOURCE, EContactPhotoSourceClass)) +#define E_IS_CONTACT_PHOTO_SOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CONTACT_PHOTO_SOURCE)) +#define E_IS_CONTACT_PHOTO_SOURCE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CONTACT_PHOTO_SOURCE)) +#define E_CONTACT_PHOTO_SOURCE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CONTACT_PHOTO_SOURCE, EContactPhotoSourceClass)) + +G_BEGIN_DECLS + +typedef struct _EContactPhotoSource EContactPhotoSource; +typedef struct _EContactPhotoSourceClass EContactPhotoSourceClass; +typedef struct _EContactPhotoSourcePrivate EContactPhotoSourcePrivate; + +struct _EContactPhotoSource { + GObject parent; + EContactPhotoSourcePrivate *priv; +}; + +struct _EContactPhotoSourceClass { + GObjectClass parent_class; +}; + +GType e_contact_photo_source_get_type + (void) G_GNUC_CONST; +void e_contact_photo_source_type_register + (GTypeModule *type_module); +EPhotoSource * e_contact_photo_source_new + (EClientCache *client_cache, + ESource *source); +EClientCache * e_contact_photo_source_ref_client_cache + (EContactPhotoSource *photo_source); +ESource * e_contact_photo_source_ref_source + (EContactPhotoSource *photo_source); + +G_END_DECLS + +#endif /* E_CONTACT_PHOTO_SOURCE_H */ + diff --git a/modules/contact-photos/e-photo-cache-contact-loader.c b/modules/contact-photos/e-photo-cache-contact-loader.c new file mode 100644 index 0000000000..122c6b1b5c --- /dev/null +++ b/modules/contact-photos/e-photo-cache-contact-loader.c @@ -0,0 +1,252 @@ +/* + * e-photo-cache-contact-loader.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + */ + +#include "e-photo-cache-contact-loader.h" + +#include "e-contact-photo-source.h" + +#define E_PHOTO_CACHE_CONTACT_LOADER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_PHOTO_CACHE_CONTACT_LOADER, EPhotoCacheContactLoaderPrivate)) + +struct _EPhotoCacheContactLoaderPrivate { + ESourceRegistry *registry; + gulong source_added_handler_id; + gulong source_removed_handler_id; + + /* ESource -> EPhotoSource */ + GHashTable *photo_sources; +}; + +G_DEFINE_DYNAMIC_TYPE ( + EPhotoCacheContactLoader, + e_photo_cache_contact_loader, + E_TYPE_EXTENSION) + +static EPhotoCache * +photo_cache_contact_loader_get_photo_cache (EPhotoCacheContactLoader *loader) +{ + EExtensible *extensible; + + extensible = e_extension_get_extensible (E_EXTENSION (loader)); + + return E_PHOTO_CACHE (extensible); +} + +static void +photo_cache_contact_loader_add_source (EPhotoCacheContactLoader *loader, + ESource *source) +{ + EPhotoCache *photo_cache; + EPhotoSource *photo_source; + EClientCache *client_cache; + + photo_cache = photo_cache_contact_loader_get_photo_cache (loader); + client_cache = e_photo_cache_ref_client_cache (photo_cache); + + photo_source = e_contact_photo_source_new (client_cache, source); + g_hash_table_insert ( + loader->priv->photo_sources, + g_object_ref (source), + g_object_ref (photo_source)); + e_photo_cache_add_photo_source (photo_cache, photo_source); + g_object_unref (photo_source); + + g_object_unref (client_cache); +} + +static void +photo_cache_contact_loader_remove_source (EPhotoCacheContactLoader *loader, + ESource *source) +{ + EPhotoCache *photo_cache; + EPhotoSource *photo_source; + GHashTable *hash_table; + + photo_cache = photo_cache_contact_loader_get_photo_cache (loader); + + hash_table = loader->priv->photo_sources; + photo_source = g_hash_table_lookup (hash_table, source); + if (photo_source != NULL) { + e_photo_cache_remove_photo_source (photo_cache, photo_source); + g_hash_table_remove (hash_table, source); + } +} + +static void +photo_cache_contact_loader_source_added_cb (ESourceRegistry *registry, + ESource *source, + EPhotoCacheContactLoader *loader) +{ + const gchar *extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK; + + if (e_source_has_extension (source, extension_name)) + photo_cache_contact_loader_add_source (loader, source); +} + +static void +photo_cache_contact_loader_source_removed_cb (ESourceRegistry *registry, + ESource *source, + EPhotoCacheContactLoader *loader) +{ + const gchar *extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK; + + if (e_source_has_extension (source, extension_name)) + photo_cache_contact_loader_remove_source (loader, source); +} + +static void +photo_cache_contact_loader_dispose (GObject *object) +{ + EPhotoCacheContactLoaderPrivate *priv; + + priv = E_PHOTO_CACHE_CONTACT_LOADER_GET_PRIVATE (object); + + if (priv->source_added_handler_id > 0) { + g_signal_handler_disconnect ( + priv->registry, + priv->source_added_handler_id); + priv->source_added_handler_id = 0; + } + + if (priv->source_removed_handler_id > 0) { + g_signal_handler_disconnect ( + priv->registry, + priv->source_removed_handler_id); + priv->source_removed_handler_id = 0; + } + + g_clear_object (&priv->registry); + + g_hash_table_remove_all (priv->photo_sources); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_photo_cache_contact_loader_parent_class)-> + dispose (object); +} + +static void +photo_cache_contact_loader_finalize (GObject *object) +{ + EPhotoCacheContactLoaderPrivate *priv; + + priv = E_PHOTO_CACHE_CONTACT_LOADER_GET_PRIVATE (object); + + g_hash_table_destroy (priv->photo_sources); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (e_photo_cache_contact_loader_parent_class)-> + finalize (object); +} + +static void +photo_cache_contact_loader_constructed (GObject *object) +{ + EPhotoCacheContactLoader *loader; + EPhotoCache *photo_cache; + EClientCache *client_cache; + ESourceRegistry *registry; + GList *list, *link; + const gchar *extension_name; + gulong handler_id; + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_photo_cache_contact_loader_parent_class)-> + constructed (object); + + loader = E_PHOTO_CACHE_CONTACT_LOADER (object); + photo_cache = photo_cache_contact_loader_get_photo_cache (loader); + + client_cache = e_photo_cache_ref_client_cache (photo_cache); + registry = e_client_cache_ref_registry (client_cache); + + extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK; + list = e_source_registry_list_sources (registry, extension_name); + + for (link = list; link != NULL; link = g_list_next (link)) { + ESource *source = E_SOURCE (link->data); + photo_cache_contact_loader_add_source (loader, source); + } + + g_list_free_full (list, (GDestroyNotify) g_object_unref); + + loader->priv->registry = g_object_ref (registry); + + handler_id = g_signal_connect ( + registry, "source-added", + G_CALLBACK (photo_cache_contact_loader_source_added_cb), + loader); + loader->priv->source_added_handler_id = handler_id; + + handler_id = g_signal_connect ( + registry, "source-removed", + G_CALLBACK (photo_cache_contact_loader_source_removed_cb), + loader); + loader->priv->source_removed_handler_id = handler_id; + + g_object_unref (client_cache); + g_object_unref (registry); +} + +static void +e_photo_cache_contact_loader_class_init (EPhotoCacheContactLoaderClass *class) +{ + GObjectClass *object_class; + EExtensionClass *extension_class; + + g_type_class_add_private ( + class, sizeof (EPhotoCacheContactLoaderPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->dispose = photo_cache_contact_loader_dispose; + object_class->finalize = photo_cache_contact_loader_finalize; + object_class->constructed = photo_cache_contact_loader_constructed; + + extension_class = E_EXTENSION_CLASS (class); + extension_class->extensible_type = E_TYPE_PHOTO_CACHE; +} + +static void +e_photo_cache_contact_loader_class_finalize (EPhotoCacheContactLoaderClass *class) +{ +} + +static void +e_photo_cache_contact_loader_init (EPhotoCacheContactLoader *loader) +{ + GHashTable *photo_sources; + + photo_sources = g_hash_table_new_full ( + (GHashFunc) e_source_hash, + (GEqualFunc) e_source_equal, + (GDestroyNotify) g_object_unref, + (GDestroyNotify) g_object_unref); + + loader->priv = E_PHOTO_CACHE_CONTACT_LOADER_GET_PRIVATE (loader); + loader->priv->photo_sources = photo_sources; +} + +void +e_photo_cache_contact_loader_type_register (GTypeModule *type_module) +{ + /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration + * function, so we have to wrap it with a public function in + * order to register types from a separate compilation unit. */ + e_photo_cache_contact_loader_register_type (type_module); +} + diff --git a/modules/contact-photos/e-photo-cache-contact-loader.h b/modules/contact-photos/e-photo-cache-contact-loader.h new file mode 100644 index 0000000000..3289723fcc --- /dev/null +++ b/modules/contact-photos/e-photo-cache-contact-loader.h @@ -0,0 +1,66 @@ +/* + * e-photo-cache-contact-loader.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 E_PHOTO_CACHE_CONTACT_LOADER_H +#define E_PHOTO_CACHE_CONTACT_LOADER_H + +#include <e-util/e-util.h> + +/* Standard GObject macros */ +#define E_TYPE_PHOTO_CACHE_CONTACT_LOADER \ + (e_photo_cache_contact_loader_get_type ()) +#define E_PHOTO_CACHE_CONTACT_LOADER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_PHOTO_CACHE_CONTACT_LOADER, EPhotoCacheContactLoader)) +#define E_PHOTO_CACHE_CONTACT_LOADER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_PHOTO_CACHE_CONTACT_LOADER, EPhotoCacheContactLoaderClass)) +#define E_IS_PHOTO_CACHE_CONTACT_LOADER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_PHOTO_CACHE_CONTACT_LOADER)) +#define E_IS_PHOTO_CACHE_CONTACT_LOADER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_PHOTO_CACHE_CONTACT_LOADER)) +#define E_PHOTO_CACHE_CONTACT_LOADER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_PHOTO_CACHE_CONTACT_LOADER, EPhotoCacheContactLoaderClass)) + +G_BEGIN_DECLS + +typedef struct _EPhotoCacheContactLoader EPhotoCacheContactLoader; +typedef struct _EPhotoCacheContactLoaderClass EPhotoCacheContactLoaderClass; +typedef struct _EPhotoCacheContactLoaderPrivate EPhotoCacheContactLoaderPrivate; + +struct _EPhotoCacheContactLoader { + EExtension parent; + EPhotoCacheContactLoaderPrivate *priv; +}; + +struct _EPhotoCacheContactLoaderClass { + EExtensionClass parent_class; +}; + +GType e_photo_cache_contact_loader_get_type + (void) G_GNUC_CONST; +void e_photo_cache_contact_loader_type_register + (GTypeModule *type_module); + +G_END_DECLS + +#endif /* E_PHOTO_CACHE_CONTACT_LOADER_H */ + diff --git a/modules/contact-photos/evolution-contact-photos.c b/modules/contact-photos/evolution-contact-photos.c new file mode 100644 index 0000000000..2ab6f04c40 --- /dev/null +++ b/modules/contact-photos/evolution-contact-photos.c @@ -0,0 +1,40 @@ +/* + * evolution-module-contact-photos.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + */ + +#include <gmodule.h> +#include <glib-object.h> + +#include "e-contact-photo-source.h" +#include "e-photo-cache-contact-loader.h" + +/* Module Entry Points */ +void e_module_load (GTypeModule *type_module); +void e_module_unload (GTypeModule *type_module); + +G_MODULE_EXPORT void +e_module_load (GTypeModule *type_module) +{ + e_contact_photo_source_type_register (type_module); + e_photo_cache_contact_loader_type_register (type_module); +} + +G_MODULE_EXPORT void +e_module_unload (GTypeModule *type_module) +{ +} + |