Support any number of avatars per message
authorRicardo Mones <ricardo@mones.org>
Tue, 11 Feb 2014 00:17:29 +0000 (01:17 +0100)
committerRicardo Mones <ricardo@mones.org>
Tue, 11 Feb 2014 00:19:33 +0000 (01:19 +0100)
Adapt xface/face handling to the new structure

src/common/defs.h
src/headerview.c
src/messageview.c
src/plugins/perl/perl_plugin.c
src/procheader.c
src/procmsg.c
src/procmsg.h
src/proctypes.h
src/summaryview.c
src/textview.c

index 72422ad..2bac991 100644 (file)
 #define DEFAULT_PIXMAP_THEME   "INTERNAL_DEFAULT"
 #define PIXMAP_THEME_DIR               "themes"
 
+#define AVATAR_NONE    0
+#define AVATAR_XFACE   1
+#define AVATAR_FACE    2
+
 #endif /* __DEFS_H__ */
index 965f979..a520e15 100644 (file)
@@ -254,10 +254,9 @@ static gint headerview_show_xface(HeaderView *headerview, MsgInfo *msginfo)
 {
        GtkWidget *hbox = headerview->hbox;
        GtkWidget *image;
+       gchar *xface = procmsg_msginfo_get_avatar(msginfo, AVATAR_XFACE);
 
-       if (!msginfo->extradata || 
-           !msginfo->extradata->xface || 
-           strlen(msginfo->extradata->xface) < 5) {
+       if (!msginfo->extradata || !xface || strlen(xface) < 5) {
                if (headerview->image &&
                    gtk_widget_get_visible(headerview->image)) {
                        gtk_widget_hide(headerview->image);
@@ -271,10 +270,8 @@ static gint headerview_show_xface(HeaderView *headerview, MsgInfo *msginfo)
                gtk_widget_destroy(headerview->image);
                headerview->image = NULL;
        }
-       
 
-       image = xface_get_from_header(msginfo->extradata->xface, &hbox->style->white,
-                               hbox->window);
+       image = xface_get_from_header(xface, &hbox->style->white, hbox->window);
 
        if (image) {
                gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
@@ -293,8 +290,9 @@ static gint headerview_show_face (HeaderView *headerview, MsgInfo *msginfo)
 {
        GtkWidget *hbox = headerview->hbox;
        GtkWidget *image;
+       gchar *face = procmsg_msginfo_get_avatar(msginfo, AVATAR_FACE);
 
-       if (!msginfo->extradata || !msginfo->extradata->face) {
+       if (!msginfo->extradata || !face) {
                if (headerview->image &&
                    gtk_widget_get_visible(headerview->image)) {
                        gtk_widget_hide(headerview->image);
@@ -308,9 +306,8 @@ static gint headerview_show_face (HeaderView *headerview, MsgInfo *msginfo)
                gtk_widget_destroy(headerview->image);
                headerview->image = NULL;
        }
-       
 
-       image = face_get_from_header(msginfo->extradata->face);
+       image = face_get_from_header(face);
 
        if (image) {
                gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
index 895c0e7..930ac66 100644 (file)
@@ -2825,6 +2825,7 @@ static void add_address_cb(GtkAction *action, gpointer data)
        gchar *from;
        GtkWidget *image = NULL;
        GdkPixbuf *picture = NULL;
+       gchar *face;
 
        if (!messageview->msginfo || !messageview->msginfo->from) 
                return;
@@ -2835,18 +2836,18 @@ static void add_address_cb(GtkAction *action, gpointer data)
        extract_address(from);
        
        full_msginfo = procmsg_msginfo_get_full_info(msginfo);
-       if (full_msginfo &&
-           full_msginfo->extradata &&
-           full_msginfo->extradata->face) {
-               image = face_get_from_header(full_msginfo->extradata->face);
-       } 
+       face = procmsg_msginfo_get_avatar(full_msginfo, AVATAR_FACE);
+       if (face) {
+               image = face_get_from_header(face);
+       }
 #if HAVE_LIBCOMPFACE
-       else if (full_msginfo &&
-                full_msginfo->extradata &&
-                full_msginfo->extradata->xface) {
-               image = xface_get_from_header(full_msginfo->extradata->xface,
-                               &(gtk_widget_get_style(messageview->mainwin->summaryview->ctree)->white),
-                               gtk_widget_get_window(messageview->window));
+       else {
+               gchar *xface = procmsg_msginfo_get_avatar(full_msginfo, AVATAR_XFACE);
+               if (xface) {
+                       image = xface_get_from_header(xface,
+                                       &(gtk_widget_get_style(messageview->mainwin->summaryview->ctree)->white),
+                                       gtk_widget_get_window(messageview->window));
+               }
        }
 #endif
        procmsg_msginfo_free(full_msginfo);
index d5729d6..fd69a32 100644 (file)
@@ -559,6 +559,7 @@ static XS(XS_ClawsMail_filter_init)
   gchar buf[BUFFSIZE];
   GSList *walk;
   int ii;
+  gchar *xface;
 
   dXSARGS;
   if(items != 1) {
@@ -590,8 +591,8 @@ static XS(XS_ClawsMail_filter_init)
   case 10:
     msginfo->xref       ? XSRETURN_PV(msginfo->xref)       : XSRETURN_UNDEF;
   case 11:
-    (msginfo->extradata && msginfo->extradata->xface) ?
-      XSRETURN_PV(msginfo->extradata->xface)               : XSRETURN_UNDEF;
+    xface = procmsg_msginfo_get_avatar(msginfo, AVATAR_XFACE);
+    xface               ? XSRETURN_PV(xface)               : XSRETURN_UNDEF;
   case 12:
     (msginfo->extradata && msginfo->extradata->dispositionnotificationto) ?
       XSRETURN_PV(msginfo->extradata->dispositionnotificationto) : XSRETURN_UNDEF;
index 8e82302..2acafb8 100644 (file)
@@ -39,6 +39,7 @@
 #include "codeconv.h"
 #include "prefs_common.h"
 #include "utils.h"
+#include "defs.h"
 
 #define BUFFSIZE       8192
 
@@ -465,6 +466,7 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                             gboolean full, gboolean decrypted)
 {
        MsgInfo *msginfo;
+       MsgInfoAvatar *avatar;
        gchar buf[BUFFSIZE];
        gchar *p, *tmp;
        gchar *hp;
@@ -617,14 +619,18 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                case H_FACE:
                        if (!msginfo->extradata)
                                msginfo->extradata = g_new0(MsgInfoExtraData, 1);
-                       if (msginfo->extradata->face) break;
-                       msginfo->extradata->face = g_strdup(hp);
+                       avatar = g_new0(MsgInfoAvatar, 1);
+                       avatar->avatar_id = AVATAR_FACE;
+                       avatar->avatar_src = g_strdup(hp);
+                       msginfo->extradata->avatars = g_slist_append(msginfo->extradata->avatars, avatar);
                        break;
                case H_X_FACE:
                        if (!msginfo->extradata)
                                msginfo->extradata = g_new0(MsgInfoExtraData, 1);
-                       if (msginfo->extradata->xface) break;
-                       msginfo->extradata->xface = g_strdup(hp);
+                       avatar = g_new0(MsgInfoAvatar, 1);
+                       avatar->avatar_id = AVATAR_XFACE;
+                       avatar->avatar_src = g_strdup(hp);
+                       msginfo->extradata->avatars = g_slist_append(msginfo->extradata->avatars, avatar);
                        break;
                case H_DISPOSITION_NOTIFICATION_TO:
                        if (!msginfo->extradata)
index 0b2ada3..3bb41c9 100644 (file)
@@ -772,6 +772,22 @@ static PrefsAccount *procmsg_get_account_from_file(const gchar *file)
        return mailac;
 }
 
+gchar *procmsg_msginfo_get_avatar(MsgInfo *msginfo, gint type)
+{
+       GSList *mia;
+
+       if (!msginfo || !msginfo->extradata || !msginfo->extradata->avatars)
+               return NULL;
+
+       for (mia = msginfo->extradata->avatars; mia; mia = mia->next) {
+               MsgInfoAvatar *avatar = (MsgInfoAvatar *)mia->data;
+               if (avatar->avatar_id == type)
+                       return avatar->avatar_src;
+       }
+
+       return NULL;
+}
+
 gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo)
 {
        gchar *folder_id;
@@ -1246,6 +1262,28 @@ MsgInfo *procmsg_msginfo_new(void)
        return newmsginfo;
 }
 
+static MsgInfoAvatar *procmsg_msginfoavatar_copy(MsgInfoAvatar *avatar)
+{
+       MsgInfoAvatar *newavatar;
+
+       if (avatar == NULL) return NULL;
+
+       newavatar = g_new0(MsgInfoAvatar, 1);
+       newavatar->avatar_id = avatar->avatar_id;
+       newavatar->avatar_src = g_strdup(avatar->avatar_src);
+
+       return newavatar;
+}
+
+static void procmsg_msginfoavatar_free(MsgInfoAvatar *avatar)
+{
+       if (avatar != NULL) {
+               if (avatar->avatar_src != NULL)
+                       g_free(avatar->avatar_src);
+               g_free(avatar);
+       }
+}
+
 MsgInfo *procmsg_msginfo_copy(MsgInfo *msginfo)
 {
        MsgInfo *newmsginfo;
@@ -1285,8 +1323,10 @@ MsgInfo *procmsg_msginfo_copy(MsgInfo *msginfo)
 
        if (msginfo->extradata) {
                newmsginfo->extradata = g_new0(MsgInfoExtraData, 1);
-               MEMBDUP(extradata->face);
-               MEMBDUP(extradata->xface);
+               if (msginfo->extradata->avatars) {
+                       newmsginfo->extradata->avatars = slist_copy_deep(msginfo->extradata->avatars,
+                                                               (GCopyFunc) procmsg_msginfoavatar_copy);
+               }
                MEMBDUP(extradata->dispositionnotificationto);
                MEMBDUP(extradata->returnreceiptto);
                MEMBDUP(extradata->partial_recv);
@@ -1345,10 +1385,9 @@ MsgInfo *procmsg_msginfo_get_full_info_from_file(MsgInfo *msginfo, const gchar *
                        msginfo->extradata->list_archive= g_strdup(full_msginfo->extradata->list_archive);
                if (!msginfo->extradata->list_owner)
                        msginfo->extradata->list_owner = g_strdup(full_msginfo->extradata->list_owner);
-               if (!msginfo->extradata->xface)
-                       msginfo->extradata->xface = g_strdup(full_msginfo->extradata->xface);
-               if (!msginfo->extradata->face)
-                       msginfo->extradata->face = g_strdup(full_msginfo->extradata->face);
+               if (!msginfo->extradata->avatars)
+                       msginfo->extradata->avatars = slist_copy_deep(full_msginfo->extradata->avatars,
+                                                                       (GCopyFunc) procmsg_msginfoavatar_copy);
                if (!msginfo->extradata->dispositionnotificationto)
                        msginfo->extradata->dispositionnotificationto = 
                                g_strdup(full_msginfo->extradata->dispositionnotificationto);
@@ -1420,10 +1459,14 @@ void procmsg_msginfo_free(MsgInfo *msginfo)
        g_free(msginfo->xref);
 
        if (msginfo->extradata) {
+               if (msginfo->extradata->avatars) {
+                       g_slist_foreach(msginfo->extradata->avatars,
+                                       (GFunc)procmsg_msginfoavatar_free,
+                                       NULL);
+                       g_slist_free(msginfo->extradata->avatars);
+               }
                g_free(msginfo->extradata->returnreceiptto);
                g_free(msginfo->extradata->dispositionnotificationto);
-               g_free(msginfo->extradata->xface);
-               g_free(msginfo->extradata->face);
                g_free(msginfo->extradata->list_post);
                g_free(msginfo->extradata->list_subscribe);
                g_free(msginfo->extradata->list_unsubscribe);
@@ -1480,10 +1523,13 @@ guint procmsg_msginfo_memusage(MsgInfo *msginfo)
        }
        if (msginfo->extradata) {
                memusage += sizeof(MsgInfoExtraData);
-               if (msginfo->extradata->xface)
-                       memusage += strlen(msginfo->extradata->xface);
-               if (msginfo->extradata->face)
-                       memusage += strlen(msginfo->extradata->face);
+               if (msginfo->extradata->avatars) {
+                       for (tmp = msginfo->extradata->avatars; tmp; tmp = tmp->next) {
+                               MsgInfoAvatar *avt = (MsgInfoAvatar *)tmp->data;
+                               memusage += (avt->avatar_src)? strlen(avt->avatar_src): 0;
+                               memusage += sizeof(MsgInfoAvatar) + sizeof(GSList);
+                       }
+               }
                if (msginfo->extradata->dispositionnotificationto)
                        memusage += strlen(msginfo->extradata->dispositionnotificationto);
                if (msginfo->extradata->returnreceiptto)
index 127be1d..14d147e 100644 (file)
@@ -239,8 +239,7 @@ struct _MsgInfo
 
 struct _MsgInfoExtraData
 {
-       gchar *xface;
-       gchar *face;
+       GSList *avatars;
 
        gchar *dispositionnotificationto;
        gchar *returnreceiptto;
@@ -259,6 +258,12 @@ struct _MsgInfoExtraData
        gchar *list_owner;
 };
 
+struct _MsgInfoAvatar
+{
+       gint avatar_id;
+       gchar *avatar_src;
+};
+
 struct _MsgFileInfo
 {
        MsgInfo *msginfo;
@@ -390,4 +395,6 @@ void procmsg_msginfo_clear_tags(MsgInfo *msginfo);
 void procmsg_msginfo_commit_tags(GSList *msglist);
 MsgInfo *procmsg_get_msginfo_from_identifier(const gchar *id);
 gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo);
+
+gchar *procmsg_msginfo_get_avatar(MsgInfo *msginfo, gint type);
 #endif /* __PROCMSG_H__ */
index a95949b..fd080c7 100644 (file)
@@ -43,6 +43,9 @@ typedef struct _MailFilteringData     MailFilteringData;
 struct _MsgInfoExtraData;
 typedef struct _MsgInfoExtraData       MsgInfoExtraData;
 
+struct _MsgInfoAvatar;
+typedef struct _MsgInfoAvatar          MsgInfoAvatar;
+
 typedef GSList MsgInfoList;
 typedef GSList MsgNumberList;
 
index bbfc023..91e6c90 100644 (file)
@@ -4684,6 +4684,7 @@ void summary_add_address(SummaryView *summaryview)
        gchar *from;
        GtkWidget *image = NULL;
        GdkPixbuf *picture = NULL;
+       gchar *face;
 
        msginfo = gtk_cmctree_node_get_row_data(GTK_CMCTREE(summaryview->ctree),
                                              summaryview->selected);
@@ -4695,18 +4696,18 @@ void summary_add_address(SummaryView *summaryview)
        extract_address(from);
        
        full_msginfo = procmsg_msginfo_get_full_info(msginfo);
-       if (full_msginfo &&
-           full_msginfo->extradata &&
-           full_msginfo->extradata->face) {
-               image = face_get_from_header(full_msginfo->extradata->face);
+       face = procmsg_msginfo_get_avatar(full_msginfo, AVATAR_FACE);
+       if (face) {
+               image = face_get_from_header(face);
        } 
 #if HAVE_LIBCOMPFACE
-       else if (full_msginfo &&
-                full_msginfo->extradata &&
-                full_msginfo->extradata->xface) {
-               image = xface_get_from_header(full_msginfo->extradata->xface,
-                               &summaryview->ctree->style->white,
-                               summaryview->mainwin->window->window);  
+       else {
+               gchar *xface = procmsg_msginfo_get_avatar(full_msginfo, AVATAR_XFACE);
+               if (xface) {
+                       image = xface_get_from_header(xface,
+                                       &summaryview->ctree->style->white,
+                                       summaryview->mainwin->window->window);
+               }
        }
 #endif
        procmsg_msginfo_free(full_msginfo);
index 01215be..b7ead66 100644 (file)
@@ -1975,19 +1975,19 @@ static void textview_show_face(TextView *textview)
        GtkTextView *text = GTK_TEXT_VIEW(textview->text);
        MsgInfo *msginfo = textview->messageview->msginfo;
        int x = 0;
+       gchar *face;
        
-       if (prefs_common.display_header_pane
-       ||  !prefs_common.display_xface)
+       if (prefs_common.display_header_pane || !prefs_common.display_xface)
                goto bail;
        
-       if (!msginfo->extradata || !msginfo->extradata->face) {
+       face = procmsg_msginfo_get_avatar(msginfo, AVATAR_FACE);
+       if (!face)
                goto bail;
-       }
 
        if (textview->image) 
                gtk_widget_destroy(textview->image);
        
-       textview->image = face_get_from_header(msginfo->extradata->face);
+       textview->image = face_get_from_header(face);
        cm_return_if_fail(textview->image != NULL);
 
        gtk_widget_show(textview->image);
@@ -2042,20 +2042,21 @@ static void textview_show_xface(TextView *textview)
        GtkTextView *text = GTK_TEXT_VIEW(textview->text);
        int x = 0;
        GdkWindow *window = NULL;
+       gchar *face, *xface;
        
-       if (prefs_common.display_header_pane
-       ||  !prefs_common.display_xface)
+       if (prefs_common.display_header_pane || !prefs_common.display_xface)
                goto bail;
        
-       if (!msginfo || !msginfo->extradata)
+       if (!msginfo || !msginfo->extradata || !msginfo->extradata->avatars)
                goto bail;
 
-       if (msginfo->extradata->face)
+       face = procmsg_msginfo_get_avatar(msginfo, AVATAR_FACE);
+       if (face)
                return;
        
-       if (!msginfo->extradata->xface || strlen(msginfo->extradata->xface) < 5) {
+       xface = procmsg_msginfo_get_avatar(msginfo, AVATAR_XFACE);
+       if (!xface || strlen(xface) < 5)
                goto bail;
-       }
 
        if (textview->image) 
                gtk_widget_destroy(textview->image);
@@ -2063,7 +2064,7 @@ static void textview_show_xface(TextView *textview)
        window = mainwindow_get_mainwindow() ?
                        mainwindow_get_mainwindow()->window->window :
                        textview->text->window;
-       textview->image = xface_get_from_header(msginfo->extradata->xface,
+       textview->image = xface_get_from_header(xface,
                                &textview->text->style->white,
                                window);
        cm_return_if_fail(textview->image != NULL);
@@ -2094,8 +2095,14 @@ static void textview_save_contact_pic(TextView *textview)
        gchar *filename = NULL;
        GError *error = NULL;
        GdkPixbuf *picture = NULL;
+       gchar *face, *xface;
                                
-       if (!msginfo->extradata || (!msginfo->extradata->face && !msginfo->extradata->xface))
+       if (!msginfo->extradata || !msginfo->extradata->avatars)
+               return;
+
+       face = procmsg_msginfo_get_avatar(msginfo, AVATAR_FACE);
+        xface = procmsg_msginfo_get_avatar(msginfo, AVATAR_XFACE);
+       if (!face && !xface)
                return;
 
        if (textview->image) 
@@ -2129,12 +2136,15 @@ static void textview_show_contact_pic(TextView *textview)
        GdkPixbuf *picture = NULL;
        gint w, h;
        GtkAllocation allocation;
+       gchar *face, *xface;
                                
        if (prefs_common.display_header_pane
-       ||  !prefs_common.display_xface)
+               || !prefs_common.display_xface)
                goto bail;
        
-       if (msginfo->extradata && (msginfo->extradata->face || msginfo->extradata->xface))
+       face = procmsg_msginfo_get_avatar(msginfo, AVATAR_FACE);
+       xface = procmsg_msginfo_get_avatar(msginfo, AVATAR_XFACE);
+       if (msginfo->extradata && (face || xface)) /* FIXME extradata not needed */
                return;
 
        if (textview->image) 
@@ -3183,22 +3193,27 @@ static void add_uri_to_addrbook_cb (GtkAction *action, TextView *textview)
        fromname = procheader_get_fromname(fromaddress);
        extract_address(fromaddress);
 
-       if (use_picture && 
-           textview->messageview->msginfo &&
-           textview->messageview->msginfo->extradata &&
-           textview->messageview->msginfo->extradata->face) {
-               image = face_get_from_header(textview->messageview->msginfo->extradata->face);
-       }
+       if (use_picture) {
+               gchar *face = procmsg_msginfo_get_avatar(
+                                       textview->messageview->msginfo,
+                                       AVATAR_FACE);
+               if (face) {
+                       image = face_get_from_header(face);
+               }
 #if HAVE_LIBCOMPFACE 
-       else if (use_picture && 
-                textview->messageview->msginfo &&
-                textview->messageview->msginfo->extradata &&
-                textview->messageview->msginfo->extradata->xface) {
-               image = xface_get_from_header(textview->messageview->msginfo->extradata->xface,
-                               &textview->text->style->white,
-                               mainwindow_get_mainwindow()->window->window);   
-       }
+               else {
+                       gchar *xface = procmsg_msginfo_get_avatar(
+                                               textview->messageview->msginfo,
+                                               AVATAR_XFACE);
+                       if (xface) {
+                               image = xface_get_from_header(xface,
+                                               &textview->text->style->white,
+                                               mainwindow_get_mainwindow()->window->window);
+                       }
+               }
 #endif
+       }
+
        if (image)
                picture = gtk_image_get_pixbuf(GTK_IMAGE(image));