From aa6c56b5d0e6f7b3c2a6e1bddb24719896014d01 Mon Sep 17 00:00:00 2001 From: Ricardo Mones Date: Tue, 11 Feb 2014 01:17:29 +0100 Subject: [PATCH] Support any number of avatars per message Adapt xface/face handling to the new structure --- src/common/defs.h | 4 ++ src/headerview.c | 15 +++---- src/messageview.c | 23 ++++++----- src/plugins/perl/perl_plugin.c | 5 ++- src/procheader.c | 14 +++++-- src/procmsg.c | 70 ++++++++++++++++++++++++++------ src/procmsg.h | 11 ++++- src/proctypes.h | 3 ++ src/summaryview.c | 21 +++++----- src/textview.c | 73 ++++++++++++++++++++-------------- 10 files changed, 160 insertions(+), 79 deletions(-) diff --git a/src/common/defs.h b/src/common/defs.h index 72422adf9..2bac991e3 100644 --- a/src/common/defs.h +++ b/src/common/defs.h @@ -170,4 +170,8 @@ #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__ */ diff --git a/src/headerview.c b/src/headerview.c index 965f979df..a520e1563 100644 --- a/src/headerview.c +++ b/src/headerview.c @@ -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); diff --git a/src/messageview.c b/src/messageview.c index 895c0e768..930ac66d4 100644 --- a/src/messageview.c +++ b/src/messageview.c @@ -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); diff --git a/src/plugins/perl/perl_plugin.c b/src/plugins/perl/perl_plugin.c index d5729d67d..fd69a32d5 100644 --- a/src/plugins/perl/perl_plugin.c +++ b/src/plugins/perl/perl_plugin.c @@ -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; diff --git a/src/procheader.c b/src/procheader.c index 8e82302c4..2acafb8ed 100644 --- a/src/procheader.c +++ b/src/procheader.c @@ -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) diff --git a/src/procmsg.c b/src/procmsg.c index 0b2ada3c1..3bb41c9e0 100644 --- a/src/procmsg.c +++ b/src/procmsg.c @@ -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) diff --git a/src/procmsg.h b/src/procmsg.h index 127be1d43..14d147ed0 100644 --- a/src/procmsg.h +++ b/src/procmsg.h @@ -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__ */ diff --git a/src/proctypes.h b/src/proctypes.h index a95949bef..fd080c722 100644 --- a/src/proctypes.h +++ b/src/proctypes.h @@ -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; diff --git a/src/summaryview.c b/src/summaryview.c index bbfc0230c..91e6c905d 100644 --- a/src/summaryview.c +++ b/src/summaryview.c @@ -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); diff --git a/src/textview.c b/src/textview.c index 01215be59..b7ead66ed 100644 --- a/src/textview.c +++ b/src/textview.c @@ -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)); -- 2.25.1