[Commits] [SCM] claws branch, master, updated. 3.9.3-29-gb079a3a
mones at claws-mail.org
mones at claws-mail.org
Fri Feb 21 19:59:51 CET 2014
The branch master of project "claws" (Claws Mail) has been updated
via b079a3a27273d2441202ab9ac80a94645afc6017 (commit)
via daea250f36c7346e018cdc8a759f10ff0c9834f5 (commit)
via a3ec21768c199ad01785f8ec177cf60470824759 (commit)
from 37df4f1b3240328a17c03108319ad315447e7fb7 (commit)
- Log -----------------------------------------------------------------
commit b079a3a27273d2441202ab9ac80a94645afc6017
Author: Ricardo Mones <ricardo at mones.org>
Date: Sun Feb 16 19:21:54 2014 +0100
Use new internal plugin for rendering avatars
Updates and simplifies rendering logic in header pane,
message view and text view and when adding pictures to
address book.
diff --git a/src/headerview.c b/src/headerview.c
index 2d7074b..7880d25 100644
--- a/src/headerview.c
+++ b/src/headerview.c
@@ -31,10 +31,6 @@
#include <string.h>
#include <time.h>
-#if HAVE_LIBCOMPFACE
-# include <compface.h>
-#endif
-
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "headerview.h"
@@ -45,13 +41,10 @@
#include "base64.h"
#include "headers.h"
#include "addrindex.h"
+#include "hooks.h"
+#include "avatars.h"
-#if HAVE_LIBCOMPFACE
-static gint headerview_show_xface (HeaderView *headerview,
- MsgInfo *msginfo);
-#endif
-
-static gint headerview_show_face (HeaderView *headerview,
+static gint headerview_show_avatar (HeaderView *headerview,
MsgInfo *msginfo);
static gint headerview_show_contact_pic (HeaderView *headerview,
MsgInfo *msginfo);
@@ -221,91 +214,50 @@ void headerview_show(HeaderView *headerview, MsgInfo *msginfo)
gtk_widget_show(headerview->tags_body_label);
g_free(tags);
}
- if (!headerview_show_face(headerview, msginfo))
- return;
-
-#if HAVE_LIBCOMPFACE
- if (!headerview_show_xface(headerview, msginfo))
+ if (!headerview_show_avatar(headerview, msginfo))
return;
-#endif
if (!headerview_show_contact_pic(headerview, msginfo))
return;
}
-#if HAVE_LIBCOMPFACE
-static gint headerview_show_xface(HeaderView *headerview, MsgInfo *msginfo)
+static gint headerview_show_avatar (HeaderView *headerview, MsgInfo *msginfo)
{
+ AvatarRender *avatarr = avatars_avatarrender_new(msginfo);
GtkWidget *hbox = headerview->hbox;
GtkWidget *image;
- gchar *xface = procmsg_msginfo_get_avatar(msginfo, AVATAR_XFACE);
- if (!msginfo->extradata || !xface || strlen(xface) < 5) {
- if (headerview->image &&
- gtk_widget_get_visible(headerview->image)) {
+ hooks_invoke(AVATAR_IMAGE_RENDER_HOOKLIST, avatarr);
+
+ if (!avatarr->image) {
+ if (headerview->image
+ && gtk_widget_get_visible(headerview->image)) {
gtk_widget_hide(headerview->image);
gtk_widget_queue_resize(hbox);
}
+ avatars_avatarrender_free(avatarr);
return -1;
}
- if (!gtk_widget_get_visible(headerview->hbox)) return -1;
-
- if (headerview->image) {
- gtk_widget_destroy(headerview->image);
- headerview->image = NULL;
- }
-
- image = xface_get_from_header(xface);
-
- if (image) {
- gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
- gtk_widget_show(image);
- }
-
- headerview->image = image;
- if (image) {
- headerview_save_contact_pic(headerview, msginfo);
- }
- return 0;
-}
-#endif
-
-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 || !face) {
- if (headerview->image &&
- gtk_widget_get_visible(headerview->image)) {
- gtk_widget_hide(headerview->image);
- gtk_widget_queue_resize(hbox);
- }
+ if (!gtk_widget_get_visible(hbox)) {
+ avatars_avatarrender_free(avatarr);
return -1;
}
- if (!gtk_widget_get_visible(headerview->hbox)) return -1;
if (headerview->image) {
gtk_widget_destroy(headerview->image);
headerview->image = NULL;
}
- image = face_get_from_header(face);
+ gtk_box_pack_start(GTK_BOX(hbox), avatarr->image, FALSE, FALSE, 0);
+ gtk_widget_show(avatarr->image);
- if (image) {
- gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
- gtk_widget_show(image);
- }
+ headerview->image = avatarr->image;
+ avatarr->image = NULL; /* avoid destroying */
+ avatars_avatarrender_free(avatarr);
- headerview->image = image;
- if (image == NULL)
- return -1;
- else {
- headerview_save_contact_pic(headerview, msginfo);
- return 0;
- }
+ headerview_save_contact_pic(headerview, msginfo);
+ return 0;
}
static void headerview_save_contact_pic (HeaderView *headerview, MsgInfo *msginfo)
diff --git a/src/messageview.c b/src/messageview.c
index 1f1f094..bfab482 100644
--- a/src/messageview.c
+++ b/src/messageview.c
@@ -67,6 +67,7 @@
#include "version.h"
#include "statusbar.h"
#include "folder_item_prefs.h"
+#include "avatars.h"
#ifndef USE_NEW_ADDRBOOK
#include "addressbook.h"
#else
@@ -2823,9 +2824,8 @@ static void add_address_cb(GtkAction *action, gpointer data)
MessageView *messageview = (MessageView *)data;
MsgInfo *msginfo, *full_msginfo;
gchar *from;
- GtkWidget *image = NULL;
GdkPixbuf *picture = NULL;
- gchar *face;
+ AvatarRender *avatarr;
if (!messageview->msginfo || !messageview->msginfo->from)
return;
@@ -2836,21 +2836,14 @@ static void add_address_cb(GtkAction *action, gpointer data)
extract_address(from);
full_msginfo = procmsg_msginfo_get_full_info(msginfo);
- face = procmsg_msginfo_get_avatar(full_msginfo, AVATAR_FACE);
- if (face) {
- image = face_get_from_header(face);
- }
-#if HAVE_LIBCOMPFACE
- else {
- gchar *xface = procmsg_msginfo_get_avatar(full_msginfo, AVATAR_XFACE);
- if (xface) {
- image = xface_get_from_header(xface);
- }
- }
-#endif
+
+ avatarr = avatars_avatarrender_new(full_msginfo);
+ hooks_invoke(AVATAR_IMAGE_RENDER_HOOKLIST, avatarr);
+
procmsg_msginfo_free(full_msginfo);
- if (image)
- picture = gtk_image_get_pixbuf(GTK_IMAGE(image));
+
+ if (avatarr->image != NULL)
+ picture = gtk_image_get_pixbuf(GTK_IMAGE(avatarr->image));
#ifndef USE_NEW_ADDRBOOK
addressbook_add_contact(msginfo->fromname, from, NULL, picture);
@@ -2859,8 +2852,7 @@ static void add_address_cb(GtkAction *action, gpointer data)
debug_print( "addressbook_add_contact - added\n" );
}
#endif
- if (image)
- gtk_widget_destroy(image);
+ avatars_avatarrender_free(avatarr);
}
static void create_filter_cb(GtkAction *gaction, gpointer data)
diff --git a/src/summaryview.c b/src/summaryview.c
index 3bd2ac0..8da3900 100644
--- a/src/summaryview.c
+++ b/src/summaryview.c
@@ -81,6 +81,7 @@
#include "edittags.h"
#include "manual.h"
#include "manage_window.h"
+#include "avatars.h"
#define SUMMARY_COL_MARK_WIDTH 10
#define SUMMARY_COL_STATUS_WIDTH 13
@@ -4682,9 +4683,8 @@ void summary_add_address(SummaryView *summaryview)
{
MsgInfo *msginfo, *full_msginfo;
gchar *from;
- GtkWidget *image = NULL;
GdkPixbuf *picture = NULL;
- gchar *face;
+ AvatarRender *avatarr;
msginfo = gtk_cmctree_node_get_row_data(GTK_CMCTREE(summaryview->ctree),
summaryview->selected);
@@ -4696,21 +4696,14 @@ void summary_add_address(SummaryView *summaryview)
extract_address(from);
full_msginfo = procmsg_msginfo_get_full_info(msginfo);
- face = procmsg_msginfo_get_avatar(full_msginfo, AVATAR_FACE);
- if (face) {
- image = face_get_from_header(face);
- }
-#if HAVE_LIBCOMPFACE
- else {
- gchar *xface = procmsg_msginfo_get_avatar(full_msginfo, AVATAR_XFACE);
- if (xface) {
- image = xface_get_from_header(xface);
- }
- }
-#endif
+
+ avatarr = avatars_avatarrender_new(full_msginfo);
+ hooks_invoke(AVATAR_IMAGE_RENDER_HOOKLIST, avatarr);
+
procmsg_msginfo_free(full_msginfo);
- if (image)
- picture = gtk_image_get_pixbuf(GTK_IMAGE(image));
+
+ if (avatarr->image)
+ picture = gtk_image_get_pixbuf(GTK_IMAGE(avatarr->image));
#ifndef USE_NEW_ADDRBOOK
addressbook_add_contact(msginfo->fromname, from, NULL, picture);
@@ -4719,8 +4712,7 @@ void summary_add_address(SummaryView *summaryview)
debug_print( "addressbook_add_contact - added\n" );
}
#endif
- if (image)
- gtk_widget_destroy(image);
+ avatars_avatarrender_free(avatarr);
}
void summary_select_all(SummaryView *summaryview)
diff --git a/src/textview.c b/src/textview.c
index 5575bfd..5106d45 100644
--- a/src/textview.c
+++ b/src/textview.c
@@ -37,9 +37,6 @@
#if HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
-#if HAVE_LIBCOMPFACE
-# include <compface.h>
-#endif
#include "main.h"
#include "summaryview.h"
@@ -72,6 +69,7 @@
#include "tags.h"
#include "manage_window.h"
#include "folder_item_prefs.h"
+#include "avatars.h"
static GdkColor quote_colors[3] = {
{(gulong)0, (gushort)0, (gushort)0, (gushort)0},
@@ -1965,26 +1963,31 @@ static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
return sorted_headers;
}
-static void textview_show_face(TextView *textview)
+static void textview_show_avatar(TextView *textview)
{
GtkAllocation allocation;
GtkTextView *text = GTK_TEXT_VIEW(textview->text);
MsgInfo *msginfo = textview->messageview->msginfo;
int x = 0;
- gchar *face;
+ AvatarRender *avatarr;
if (prefs_common.display_header_pane || !prefs_common.display_xface)
goto bail;
- face = procmsg_msginfo_get_avatar(msginfo, AVATAR_FACE);
- if (!face)
+ avatarr = avatars_avatarrender_new(msginfo);
+ hooks_invoke(AVATAR_IMAGE_RENDER_HOOKLIST, avatarr);
+
+ if (!avatarr->image) {
+ avatars_avatarrender_free(avatarr);
goto bail;
+ }
if (textview->image)
gtk_widget_destroy(textview->image);
- textview->image = face_get_from_header(face);
- cm_return_if_fail(textview->image != NULL);
+ textview->image = avatarr->image;
+ avatarr->image = NULL; /* avoid destroying */
+ avatars_avatarrender_free(avatarr);
gtk_widget_show(textview->image);
@@ -1995,7 +1998,6 @@ static void textview_show_face(TextView *textview)
GTK_TEXT_WINDOW_TEXT, x, 5);
gtk_widget_show_all(textview->text);
-
return;
bail:
@@ -2030,58 +2032,6 @@ void textview_show_icon(TextView *textview, const gchar *stock_id)
return;
}
-#if HAVE_LIBCOMPFACE
-static void textview_show_xface(TextView *textview)
-{
- GtkAllocation allocation;
- MsgInfo *msginfo = textview->messageview->msginfo;
- 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)
- goto bail;
-
- if (!msginfo || !msginfo->extradata || !msginfo->extradata->avatars)
- goto bail;
-
- face = procmsg_msginfo_get_avatar(msginfo, AVATAR_FACE);
- if (face)
- return;
-
- xface = procmsg_msginfo_get_avatar(msginfo, AVATAR_XFACE);
- if (!xface || strlen(xface) < 5)
- goto bail;
-
- if (textview->image)
- gtk_widget_destroy(textview->image);
-
- window = mainwindow_get_mainwindow() ?
- mainwindow_get_mainwindow()->window->window :
- textview->text->window;
- textview->image = xface_get_from_header(xface);
- cm_return_if_fail(textview->image != NULL);
-
- gtk_widget_show(textview->image);
-
- gtk_widget_get_allocation(textview->text, &allocation);
- x = allocation.width - WIDTH -5;
-
- gtk_text_view_add_child_in_window(text, textview->image,
- GTK_TEXT_WINDOW_TEXT, x, 5);
-
- gtk_widget_show_all(textview->text);
-
- return;
-bail:
- if (textview->image)
- gtk_widget_destroy(textview->image);
- textview->image = NULL;
-
-}
-#endif
-
static void textview_save_contact_pic(TextView *textview)
{
#ifndef USE_NEW_ADDRBOOK
@@ -2089,14 +2039,8 @@ 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->avatars)
- return;
- face = procmsg_msginfo_get_avatar(msginfo, AVATAR_FACE);
- xface = procmsg_msginfo_get_avatar(msginfo, AVATAR_XFACE);
- if (!face && !xface)
+ if (!msginfo->extradata || !msginfo->extradata->avatars)
return;
if (textview->image)
@@ -2130,15 +2074,12 @@ 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)
goto bail;
- 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 */
+ if (msginfo->extradata && msginfo->extradata->avatars)
return;
if (textview->image)
@@ -2345,10 +2286,8 @@ static void textview_show_header(TextView *textview, GPtrArray *headers)
"header", NULL);
}
- textview_show_face(textview);
-#if HAVE_LIBCOMPFACE
- textview_show_xface(textview);
-#endif
+ textview_show_avatar(textview);
+
textview_save_contact_pic(textview);
textview_show_contact_pic(textview);
}
@@ -3170,7 +3109,7 @@ static void add_uri_to_addrbook_cb (GtkAction *action, TextView *textview)
gchar *fromname, *fromaddress;
ClickableText *uri = g_object_get_data(G_OBJECT(textview->mail_popup_menu),
"menu_button");
- GtkWidget *image = NULL;
+ AvatarRender *avatarr = NULL;
GdkPixbuf *picture = NULL;
gboolean use_picture = FALSE;
@@ -3188,26 +3127,16 @@ static void add_uri_to_addrbook_cb (GtkAction *action, TextView *textview)
extract_address(fromaddress);
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 {
- gchar *xface = procmsg_msginfo_get_avatar(
- textview->messageview->msginfo,
- AVATAR_XFACE);
- if (xface) {
- image = xface_get_from_header(xface);
- }
- }
-#endif
+ avatarr = avatars_avatarrender_new(textview->messageview->msginfo);
+ hooks_invoke(AVATAR_IMAGE_RENDER_HOOKLIST, avatarr);
}
- if (image)
- picture = gtk_image_get_pixbuf(GTK_IMAGE(image));
+ if (avatarr && avatarr->image) {
+ picture = gtk_image_get_pixbuf(GTK_IMAGE(avatarr->image));
+ }
+ if (avatarr) {
+ avatars_avatarrender_free(avatarr);
+ }
#ifndef USE_NEW_ADDRBOOK
addressbook_add_contact( fromname, fromaddress, NULL, picture);
commit daea250f36c7346e018cdc8a759f10ff0c9834f5
Author: Ricardo Mones <ricardo at mones.org>
Date: Sat Feb 15 20:40:43 2014 +0100
New hooklist for rendering avatars and some utils
• Create and destroy hooklist parameter structs
• Initialization function to install default handler
diff --git a/src/Makefile.am b/src/Makefile.am
index e5bd012..375d561 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -130,6 +130,7 @@ claws_mail_SOURCES = \
advsearch.c \
alertpanel.c \
autofaces.c \
+ avatars.c \
codeconv.c \
compose.c \
crash.c \
@@ -244,6 +245,7 @@ claws_mailinclude_HEADERS = \
advsearch.h \
alertpanel.h \
autofaces.h \
+ avatars.h \
codeconv.h \
compose.h \
crash.h \
diff --git a/src/avatars.c b/src/avatars.c
new file mode 100644
index 0000000..51acba4
--- /dev/null
+++ b/src/avatars.c
@@ -0,0 +1,110 @@
+/*
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2014 Ricardo Mones and the Claws Mail team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#include "claws-features.h"
+#endif
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "defs.h"
+#include "hooks.h"
+#include "gtkutils.h"
+#include "procmsg.h"
+#include "prefs_common.h"
+#include "avatars.h"
+
+static guint avatar_render_hook_id = -1;
+
+AvatarRender *avatars_avatarrender_new(MsgInfo *msginfo)
+{
+ AvatarRender *ar = g_new0(AvatarRender, 1);
+ ar->full_msginfo = msginfo;
+ ar->image = NULL;
+
+ return ar;
+}
+
+void avatars_avatarrender_free(AvatarRender *avrender)
+{
+ if (avrender == NULL)
+ return;
+
+ if (avrender->image != NULL) {
+ gtk_widget_destroy(avrender->image);
+ }
+ g_free(avrender);
+}
+
+gboolean avatars_internal_rendering_hook(gpointer source, gpointer data)
+{
+ AvatarRender *avatarr = (AvatarRender *)source;
+ gchar *aface;
+
+ if (!(prefs_common.enable_avatars | AVATARS_ENABLE_RENDER)) {
+ debug_print("Internal rendering of avatars is disabled");
+ return FALSE;
+ }
+
+ if (avatarr == NULL) {
+ g_warning("Internal rendering invoked with NULL argument");
+ return FALSE;
+ }
+
+ if (avatarr->image != NULL) {
+ g_warning("Memory leak: image widget not destroyed");
+ }
+
+ aface = procmsg_msginfo_get_avatar(avatarr->full_msginfo, AVATAR_FACE);
+ if (aface) {
+ avatarr->image = face_get_from_header(aface);
+ }
+#if HAVE_LIBCOMPFACE
+ else {
+ aface = procmsg_msginfo_get_avatar(avatarr->full_msginfo, AVATAR_XFACE);
+ if (aface) {
+ avatarr->image = xface_get_from_header(aface);
+ }
+ }
+#endif
+ return FALSE;
+}
+
+void avatars_init(void)
+{
+ if (avatar_render_hook_id != -1) {
+ g_warning(_("Internal avatars rendering already initialized"));
+ return;
+ }
+ avatar_render_hook_id = hooks_register_hook(AVATAR_IMAGE_RENDER_HOOKLIST, avatars_internal_rendering_hook, NULL);
+ if (avatar_render_hook_id == -1) {
+ g_warning(_("Failed to register avatars internal rendering hook"));
+ }
+}
+
+void avatars_done(void)
+{
+ if (avatar_render_hook_id != -1) {
+ hooks_unregister_hook(AVATAR_IMAGE_RENDER_HOOKLIST, avatar_render_hook_id);
+ avatar_render_hook_id = -1;
+ }
+}
+
diff --git a/src/avatars.h b/src/avatars.h
new file mode 100644
index 0000000..d6f304a
--- /dev/null
+++ b/src/avatars.h
@@ -0,0 +1,47 @@
+/*
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2014 Ricardo Mones and the Claws Mail team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __AVATARS_H__
+#define __AVATARS_H__
+
+#include <glib.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#include "proctypes.h"
+
+#define AVATAR_IMAGE_RENDER_HOOKLIST "avatar_image_render"
+
+typedef struct _AvatarRender AvatarRender;
+
+struct _AvatarRender
+{
+ MsgInfo *full_msginfo;
+ GtkWidget *image;
+};
+
+AvatarRender *avatars_avatarrender_new (MsgInfo *msginfo);
+void avatars_avatarrender_free (AvatarRender *avrender);
+
+gboolean avatars_internal_rendering_hook (gpointer source,
+ gpointer data);
+
+void avatars_init (void);
+void avatars_done (void);
+
+#endif
diff --git a/src/main.c b/src/main.c
index c7d3eac..70f8da4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -126,6 +126,7 @@
#include "menu.h"
#include "quicksearch.h"
#include "advsearch.h"
+#include "avatars.h"
#ifdef HAVE_LIBETPAN
#include "imap-thread.h"
@@ -1403,6 +1404,7 @@ int main(int argc, char *argv[])
claws_register_idle_function(claws_gtk_idle);
+ avatars_init();
prefs_toolbar_init();
num_folder_class = g_list_length(folder_get_list());
@@ -1655,6 +1657,7 @@ static void exit_claws(MainWindow *mainwin)
matcher_done();
prefs_toolbar_done();
+ avatars_done();
#ifndef USE_NEW_ADDRBOOK
addressbook_destroy();
commit a3ec21768c199ad01785f8ec177cf60470824759
Author: Ricardo Mones <ricardo at mones.org>
Date: Wed Feb 12 23:56:32 2014 +0100
New hooklist to collect avatar data from headers
Also:
• Refactorize X-Face/Face capture as an internal plugin.
• Add hidden preference ‘enable_avatars’ to control the internal
capture/render process, and which allows disabling it by external
plugins for example.
diff --git a/manual/advanced.xml b/manual/advanced.xml
index dfcd319..5d4cb67 100644
--- a/manual/advanced.xml
+++ b/manual/advanced.xml
@@ -630,6 +630,22 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><literal>enable_avatars</literal></term>
+ <listitem>
+ <para>
+ Enables capture and/or rendering of internal avatars (Face and
+ also X-Face headers if built with compface support).
+ '0' disables both, '1' enables capture only, '2' enables rendering
+ only and '3' enables both.
+ </para>
+ <para>
+ Note that external plugins already providing these features may
+ disable partially or completely this to speed up process, regardless
+ of the configured value.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><literal>enable_dotted_lines</literal></term>
<listitem>
<para>
diff --git a/src/prefs_common.c b/src/prefs_common.c
index e2c676b..93fcce6 100644
--- a/src/prefs_common.c
+++ b/src/prefs_common.c
@@ -1177,6 +1177,7 @@ static PrefParam param[] = {
NULL, NULL, NULL},
{"address_search_wildcard", "TRUE", &prefs_common.address_search_wildcard, P_BOOL,
NULL, NULL, NULL},
+ {"enable_avatars", "3", &prefs_common.enable_avatars, P_INT, NULL, NULL, NULL},
{NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
};
diff --git a/src/prefs_common.h b/src/prefs_common.h
index cc89e33..37ccfe6 100644
--- a/src/prefs_common.h
+++ b/src/prefs_common.h
@@ -102,6 +102,14 @@ typedef enum
SHOW_BOTH
} SummaryFromShow;
+typedef enum
+{
+ AVATARS_DISABLE = 0,
+ AVATARS_ENABLE_CAPTURE = 1,
+ AVATARS_ENABLE_RENDER = 2,
+ AVATARS_ENABLE_BOTH = 3
+} EnableAvatars;
+
struct _PrefsCommon
{
/* Receive */
@@ -522,6 +530,8 @@ struct _PrefsCommon
gboolean folder_search_wildcard;
gboolean address_search_wildcard;
+
+ guint enable_avatars;
};
extern PrefsCommon prefs_common;
diff --git a/src/procheader.c b/src/procheader.c
index 2acafb8..4b7ff05 100644
--- a/src/procheader.c
+++ b/src/procheader.c
@@ -38,6 +38,7 @@
#include "procmsg.h"
#include "codeconv.h"
#include "prefs_common.h"
+#include "hooks.h"
#include "utils.h"
#include "defs.h"
@@ -462,17 +463,37 @@ MsgInfo *procheader_parse_stream(FILE *fp, MsgFlags flags, gboolean full,
return parse_stream(fp, FALSE, flags, full, decrypted);
}
+static gboolean avatar_from_some_face(gpointer source, gpointer userdata)
+{
+ AvatarCaptureData *acd = (AvatarCaptureData *)source;
+
+ if (*(acd->content) == '\0') /* won't be null, but may be empty */
+ return FALSE;
+
+ if (!strcmp(acd->header, hentry_full[H_FACE].name)) {
+ debug_print("avatar_from_some_face: found 'Face' header\n");
+ procmsg_msginfo_add_avatar(acd->msginfo, AVATAR_FACE, acd->content);
+ }
+#if HAVE_LIBCOMPFACE
+ else if (!strcmp(acd->header, hentry_full[H_X_FACE].name)) {
+ debug_print("avatar_from_some_face: found 'X-Face' header\n");
+ procmsg_msginfo_add_avatar(acd->msginfo, AVATAR_XFACE, acd->content);
+ }
+#endif
+ return FALSE;
+}
+
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;
HeaderEntry *hentry;
gint hnum;
void *orig_data = data;
+ guint hook_id = -1;
get_one_field_func get_one_field =
isstring ? (get_one_field_func)string_get_one_field
@@ -510,6 +531,10 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
msginfo->inreplyto = NULL;
+ if (prefs_common.enable_avatars | AVATARS_ENABLE_CAPTURE) {
+ hook_id = hooks_register_hook(AVATAR_HEADER_UPDATE_HOOKLIST, avatar_from_some_face, NULL);
+ }
+
while ((hnum = get_one_field(buf, sizeof(buf), data, hentry))
!= -1) {
hp = buf + strlen(hentry[hnum].name);
@@ -616,22 +641,6 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_NEW|MSG_UNREAD);
break;
#endif
- case H_FACE:
- if (!msginfo->extradata)
- msginfo->extradata = g_new0(MsgInfoExtraData, 1);
- 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);
- 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)
msginfo->extradata = g_new0(MsgInfoExtraData, 1);
@@ -740,12 +749,28 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
default:
break;
}
+ /* to avoid performance penalty hooklist is invoked only for
+ headers known to be able to generate avatars */
+ if (hnum == H_FROM || hnum == H_X_FACE || hnum == H_FACE) {
+ AvatarCaptureData *acd = g_new0(AvatarCaptureData, 1);
+ /* no extra memory is wasted, hooks are expected to
+ take care of copying members when needed */
+ acd->msginfo = msginfo;
+ acd->header = hentry_full[hnum].name;
+ acd->content = hp;
+ hooks_invoke(AVATAR_HEADER_UPDATE_HOOKLIST, (gpointer)acd);
+ g_free(acd);
+ }
}
if (!msginfo->inreplyto && msginfo->references)
msginfo->inreplyto =
g_strdup((gchar *)msginfo->references->data);
+ if (hook_id != -1) {
+ hooks_unregister_hook(AVATAR_HEADER_UPDATE_HOOKLIST, hook_id);
+ }
+
return msginfo;
}
diff --git a/src/procheader.h b/src/procheader.h
index adbc82a..b8e48fc 100644
--- a/src/procheader.h
+++ b/src/procheader.h
@@ -26,6 +26,8 @@
#include "proctypes.h"
+#define AVATAR_HEADER_UPDATE_HOOKLIST "avatar_header_update"
+
struct _HeaderEntry
{
gchar *name;
diff --git a/src/procmsg.c b/src/procmsg.c
index 3bb41c9..767fe64 100644
--- a/src/procmsg.c
+++ b/src/procmsg.c
@@ -788,6 +788,20 @@ gchar *procmsg_msginfo_get_avatar(MsgInfo *msginfo, gint type)
return NULL;
}
+void procmsg_msginfo_add_avatar(MsgInfo *msginfo, gint type, const gchar *data)
+{
+ MsgInfoAvatar *av;
+
+ if (!msginfo->extradata)
+ msginfo->extradata = g_new0(MsgInfoExtraData, 1);
+
+ av = g_new0(MsgInfoAvatar, 1);
+ av->avatar_id = type;
+ av->avatar_src = g_strdup(data);
+
+ msginfo->extradata->avatars = g_slist_append(msginfo->extradata->avatars, av);
+}
+
gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo)
{
gchar *folder_id;
diff --git a/src/procmsg.h b/src/procmsg.h
index 14d147e..52b04c0 100644
--- a/src/procmsg.h
+++ b/src/procmsg.h
@@ -285,6 +285,13 @@ struct _MailFilteringData
PrefsAccount *account;
};
+struct _AvatarCaptureData
+{
+ MsgInfo *msginfo;
+ const gchar *header;
+ const gchar *content;
+};
+
GSList *procmsg_read_cache (FolderItem *item,
gboolean scan_file);
void procmsg_msg_list_free (MsgInfoList *mlist);
@@ -397,4 +404,5 @@ 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);
+void procmsg_msginfo_add_avatar(MsgInfo *msginfo, gint type, const gchar *data);
#endif /* __PROCMSG_H__ */
diff --git a/src/proctypes.h b/src/proctypes.h
index fd080c7..ef6ec58 100644
--- a/src/proctypes.h
+++ b/src/proctypes.h
@@ -40,6 +40,9 @@ typedef struct _MsgInfoUpdate MsgInfoUpdate;
struct _MailFilteringData;
typedef struct _MailFilteringData MailFilteringData;
+struct _AvatarCaptureData;
+typedef struct _AvatarCaptureData AvatarCaptureData;
+
struct _MsgInfoExtraData;
typedef struct _MsgInfoExtraData MsgInfoExtraData;
-----------------------------------------------------------------------
Summary of changes:
manual/advanced.xml | 16 ++++++
src/Makefile.am | 2 +
src/avatars.c | 110 ++++++++++++++++++++++++++++++++++++++
src/{wizard.h => avatars.h} | 29 +++++++---
src/headerview.c | 90 ++++++++-----------------------
src/main.c | 3 ++
src/messageview.c | 28 ++++------
src/prefs_common.c | 1 +
src/prefs_common.h | 10 ++++
src/procheader.c | 59 +++++++++++++++------
src/procheader.h | 2 +
src/procmsg.c | 14 +++++
src/procmsg.h | 8 +++
src/proctypes.h | 3 ++
src/summaryview.c | 28 ++++------
src/textview.c | 123 +++++++++----------------------------------
16 files changed, 300 insertions(+), 226 deletions(-)
create mode 100644 src/avatars.c
copy src/{wizard.h => avatars.h} (58%)
hooks/post-receive
--
Claws Mail
More information about the Commits
mailing list