[anjal] Messave view shows contact's photo
- From: Srinivasa Ragavan <sragavan src gnome org>
- To: svn-commits-list gnome org
- Subject: [anjal] Messave view shows contact's photo
- Date: Fri, 17 Jul 2009 09:13:37 +0000 (UTC)
commit 65950f99e541993daf3fe0b452d6abafd4e09872
Author: Srinivasa Ragavan <sragavan novell com>
Date: Fri Jul 17 13:37:29 2009 +0530
Messave view shows contact's photo
src/mail-conv-view.c | 6 +-
src/mail-message-view.c | 1 +
src/mail-utils.c | 232 +++++++++++++++++++++++++++++++++++++++++++++++
src/mail-utils.h | 3 +
4 files changed, 239 insertions(+), 3 deletions(-)
---
diff --git a/src/mail-conv-view.c b/src/mail-conv-view.c
index 4cb2db2..847e4c7 100644
--- a/src/mail-conv-view.c
+++ b/src/mail-conv-view.c
@@ -63,9 +63,9 @@ mail_conv_view_init (MailConvView *shell)
static void
mail_conv_view_finalize (GObject *object)
{
-MailConvView *shell = (MailConvView *)object;
-MailConvViewPrivate *priv = shell->priv;
-
+ MailConvView *shell = (MailConvView *)object;
+ MailConvViewPrivate *priv = shell->priv;
+
g_free (priv);
G_OBJECT_CLASS (mail_conv_view_parent_class)->finalize (object);
diff --git a/src/mail-message-view.c b/src/mail-message-view.c
index a3c0ba2..168639f 100644
--- a/src/mail-message-view.c
+++ b/src/mail-message-view.c
@@ -1195,6 +1195,7 @@ mail_message_view_set_message (MailMessageView *mmview, CamelFolder *folder, con
mmview->main_header = gtk_hbox_new (FALSE, 12);
tmp = gtk_image_new_from_icon_name ("stock_person", GTK_ICON_SIZE_DIALOG);
gtk_widget_show(tmp);
+ mail_util_fill_photo (tmp, camel_message_info_from(info));
gtk_box_pack_start ((GtkBox *)GTK_BOX (mmview->main_header), tmp, FALSE, FALSE, 3);
mmview->priv->table_headers = (GtkWidget *)table;
diff --git a/src/mail-utils.c b/src/mail-utils.c
index ebcdb1b..cd2a7e7 100644
--- a/src/mail-utils.c
+++ b/src/mail-utils.c
@@ -20,7 +20,13 @@
*
*/
+#include <glib/gi18n.h>
#include <mail-utils.h>
+#include <libebook/e-book.h>
+#include <libedataserver/e-flag.h>
+#include <camel/camel-operation.h>
+#include <camel/camel-internet-address.h>
+#include <mail/mail-mt.h>
static GtkIconTheme *theme = NULL;
@@ -56,3 +62,229 @@ mail_utils_get_icon_path (const char *icon, int icon_size)
return file;
}
+static EBook *default_book = NULL;
+GStaticMutex booklock = G_STATIC_MUTEX_INIT;
+static GHashTable *contact_pixbuf_cache = NULL;
+
+struct TryOpenEBookStruct {
+ GError **error;
+ EFlag *flag;
+ gboolean result;
+};
+
+static void
+try_open_e_book_cb (EBook *book, EBookStatus status, gpointer closure)
+{
+ struct TryOpenEBookStruct *data = (struct TryOpenEBookStruct *)closure;
+
+ if (!data)
+ return;
+
+ data->result = status == E_BOOK_ERROR_OK;
+
+ if (!data->result) {
+ g_clear_error (data->error);
+ g_set_error (data->error, E_BOOK_ERROR, status, "EBookStatus returned %d", status);
+ }
+
+ e_flag_set (data->flag);
+}
+
+/**
+ * try_open_e_book:
+ * Tries to open address book asynchronously, but acts as synchronous.
+ * The advantage is it checks periodically whether the camel_operation
+ * has been canceled or not, and if so, then stops immediately, with
+ * result FALSE. Otherwise returns same as e_book_open
+ **/
+static gboolean
+try_open_e_book (EBook *book, gboolean only_if_exists, GError **error)
+{
+ struct TryOpenEBookStruct data;
+ gboolean canceled = FALSE;
+ EFlag *flag = e_flag_new ();
+
+ data.error = error;
+ data.flag = flag;
+ data.result = FALSE;
+
+ if (e_book_async_open (book, only_if_exists, try_open_e_book_cb, &data) != FALSE) {
+ e_flag_free (flag);
+ g_clear_error (error);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_OTHER_ERROR, "Failed to call e_book_async_open.");
+ return FALSE;
+ }
+
+ while (canceled = camel_operation_cancel_check (NULL), !canceled && !e_flag_is_set (flag)) {
+ GTimeVal wait;
+
+ g_get_current_time (&wait);
+ g_time_val_add (&wait, 250000); /* waits 250ms */
+
+ e_flag_timed_wait (flag, &wait);
+ }
+
+ if (canceled) {
+ g_clear_error (error);
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CANCELLED, "Operation has been canceled.");
+ e_book_cancel_async_op (book, NULL);
+ /* it had been canceled, the above callback may not be called, thus setting flag here */
+ e_flag_set (flag);
+ }
+
+ e_flag_wait (flag);
+ e_flag_free (flag);
+
+ return data.result && (!error || !*error);
+}
+
+static EContact *
+mu_get_contact (const char *addr)
+{
+ GError *error = NULL;
+ GList *contacts = NULL;
+ EContact *contact;
+ EBookQuery *query;
+
+ if (!default_book) {
+ default_book = e_book_new_default_addressbook (&error);
+ contact_pixbuf_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
+ if (!try_open_e_book (default_book, TRUE, &error)) {
+ default_book = NULL;
+ g_message ("Unable to open addressbook: %s\n", error->message);
+ return NULL;
+ }
+ }
+
+ query = e_book_query_field_test(E_CONTACT_EMAIL, E_BOOK_QUERY_IS, addr);
+
+ if (!e_book_get_contacts(default_book, query, &contacts, &error)) {
+ g_message ("Unable to get contacts: %s\n", error->message);
+ return NULL;
+ }
+
+ if (contacts) {
+ contact = contacts->data;
+ g_object_ref(contact);
+ g_list_foreach (contacts, (GFunc)g_object_unref, NULL);
+ g_list_free (contacts);
+ } else {
+ printf("Unable to get contact for %s\n", addr);
+ }
+
+ return contact;
+}
+
+struct _mail_contact_msg {
+ MailMsg base;
+
+ GtkWidget *widget;
+ char *address;
+ EContact *contact;
+ GdkPixbuf *pixbuf;
+};
+
+static gchar *
+mu_contact_desc (struct _mail_contact_msg *m)
+{
+ return g_strdup(_("Rendering image"));
+}
+
+static void
+mu_contact_exec (struct _mail_contact_msg *m)
+{
+ g_static_mutex_lock (&booklock);
+ if (!contact_pixbuf_cache || !g_hash_table_lookup_extended (contact_pixbuf_cache, m->address, NULL, (gpointer)&m->pixbuf)) {
+ m->contact = mu_get_contact (m->address);
+
+ if (m->contact) {
+ EContactPhoto *photo;
+
+ photo = e_contact_get (m->contact, E_CONTACT_PHOTO);
+ if (!photo)
+ photo = e_contact_get (m->contact, E_CONTACT_LOGO);
+ if (photo && photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
+ GdkPixbufLoader *loader = gdk_pixbuf_loader_new_with_mime_type ("image/png", NULL);
+ GdkPixbuf *pbuf;
+
+ gdk_pixbuf_loader_set_size (loader, 72, 72);
+ gdk_pixbuf_loader_write (loader, photo->data.inlined.data, photo->data.inlined.length, NULL);
+ gdk_pixbuf_loader_close (loader, NULL);
+ e_contact_photo_free (photo);
+
+ pbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ m->pixbuf = pbuf;
+
+ g_object_ref (pbuf);
+ g_hash_table_insert (contact_pixbuf_cache, g_strdup(m->address), pbuf);
+
+ m->address = NULL; /* Saved one free/alloc cycle */
+
+ g_object_unref (loader);
+ } else if (photo && photo->type == E_CONTACT_PHOTO_TYPE_URI) {
+ /* Handle URI */
+ }
+ } else
+ g_hash_table_insert (contact_pixbuf_cache, g_strdup(m->address), NULL);
+ }
+ g_static_mutex_unlock (&booklock);
+
+}
+
+static void
+mu_contact_done (struct _mail_contact_msg *m)
+{
+ if (m->pixbuf) {
+ gtk_image_set_from_pixbuf((GtkImage *)m->widget, m->pixbuf);
+ }
+}
+
+static void
+mu_contact_free (struct _mail_contact_msg *m)
+{
+ if (m->contact)
+ g_object_unref (m->contact);
+ g_free (m->address);
+}
+
+static MailMsgInfo mail_contact_info = {
+ sizeof (struct _mail_contact_msg),
+ (MailMsgDescFunc) mu_contact_desc,
+ (MailMsgExecFunc) mu_contact_exec,
+ (MailMsgDoneFunc) mu_contact_done,
+ (MailMsgFreeFunc) mu_contact_free
+};
+
+
+int
+mail_util_fill_photo (GtkWidget *widget, const char *address)
+{
+ struct _mail_contact_msg *m;
+ gint id;
+ CamelInternetAddress *cia;
+ const char *email;
+
+ cia = camel_internet_address_new();
+ camel_address_decode((CamelAddress *) cia, (const gchar *) address);
+
+ m = mail_msg_new (&mail_contact_info);
+
+ m->widget = widget;
+ camel_internet_address_get(cia, 0, NULL, &email);
+ m->address = g_strdup(email);
+ camel_object_unref(cia);
+ id = m->base.seq;
+ mail_msg_unordered_push (m);
+
+ return id;
+}
+
+void
+mail_util_clear_photo_cache ()
+{
+ g_static_mutex_lock (&booklock);
+ g_hash_table_remove_all (contact_pixbuf_cache);
+ g_static_mutex_unlock (&booklock);
+
+}
diff --git a/src/mail-utils.h b/src/mail-utils.h
index 1e703e2..b572651 100644
--- a/src/mail-utils.h
+++ b/src/mail-utils.h
@@ -27,4 +27,7 @@
GdkPixbuf * mail_utils_get_icon (const char *icon, int icon_size);
char * mail_utils_get_icon_path (const char *icon, int icon_size);
+void mail_util_clear_photo_cache (void);
+int mail_util_fill_photo (GtkWidget *widget, const char *address);
+
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]