aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@src.gnome.org>2009-01-12 12:12:01 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2009-01-12 12:12:01 +0800
commitc7d3c9f95609123035ebaa267f9d2e6ecfa8c2e8 (patch)
tree246bdb714e24e1b0c9a8ce4a3e45a46b230316de /mail
parentf8b33bc4ebe9dd8043674141b5fe4660efaa99e8 (diff)
downloadgsoc2013-evolution-c7d3c9f95609123035ebaa267f9d2e6ecfa8c2e8.tar.gz
gsoc2013-evolution-c7d3c9f95609123035ebaa267f9d2e6ecfa8c2e8.tar.zst
gsoc2013-evolution-c7d3c9f95609123035ebaa267f9d2e6ecfa8c2e8.zip
Merge revisions 36866:37046 from trunk.
svn path=/branches/kill-bonobo/; revision=37050
Diffstat (limited to 'mail')
-rw-r--r--mail/ChangeLog165
-rw-r--r--mail/e-searching-tokenizer.c6
-rw-r--r--mail/em-account-editor.c4
-rw-r--r--mail/em-filter-folder-element.c34
-rw-r--r--mail/em-filter-folder-element.h1
-rw-r--r--mail/em-folder-view.c1
-rw-r--r--mail/em-format-html-display.c189
-rw-r--r--mail/em-format.c15
-rw-r--r--mail/em-icon-stream.c1
-rw-r--r--mail/em-subscribe-editor.c28
-rw-r--r--mail/em-vfolder-context.c9
-rw-r--r--mail/importers/mail-importer.c2
-rw-r--r--mail/mail-autofilter.c3
-rw-r--r--mail/mail-component.c5
-rw-r--r--mail/mail-config.c4
-rw-r--r--mail/mail-send-recv.c6
-rw-r--r--mail/message-list.c13
-rw-r--r--mail/message-tag-followup.c1
-rw-r--r--mail/searchtypes.xml317
-rw-r--r--mail/vfoldertypes.xml253
20 files changed, 1021 insertions, 36 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 98aeccdef7..915369221f 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,168 @@
+2009-01-11 Matthew Barnes <mbarnes@redhat.com>
+
+ * em-config.c:
+ * em-menu.c:
+ Remove unneeded #include <libgnome/gnome-url.h>
+
+ * em-folder-view.c (emfv_format_link_clicked):
+ * em-popup.c (emp_uri_popup_link_open):
+ Call e_show_uri() instead of gnome_url_show().
+
+2009-10-10 Matthew Barnes <mbarnes@redhat.com>
+
+ * em-folder-view.c:
+ * importers/mail-importer.c:
+ Remove unneeded #include <libgnome/gnome-util.h>.
+
+2009-01-10 Matthew Barnes <mbarnes@redhat.com>
+
+ * mail-autofilter.c:
+ Remove unneeded #include <libgnomeui/gnome-app.h>.
+ Remove unneeded #include <libgnomeui/gnome-app-helper.h>.
+
+2009-01-10 Matthew Barnes <mbarnes@redhat.com>
+
+ ** Fixes bug #567280
+
+ * message-tag-followup.c:
+ Remove unneeded #include <libgnomeui/gnome-pixmap.h>.
+
+2009-01-10 Matthew Barnes <mbarnes@redhat.com>
+
+ ** Fixes part of bug #567285
+
+ * mail-autofilter.c:
+ Remove unneeded #include <libgnomeui/gnome-popup-menu.h>.
+
+2009-01-09 Takao Fujiwara <takao.fujiwara@sun.com>
+
+ Reviewed by Matthew Barnes <mbarnes@redhat.com>
+
+ * Fix for bug #566011
+
+ * mail-component.c (mail_component_class_init):
+ Include <glib/gi18n-lib.h> instead of <glib/gi18n.h> and
+ add bindtextdomain().
+
+2009-01-08 Milan Crha <mcrha@redhat.com>
+
+ ** Fix for bug #565376
+
+ * vfoldertypes.xml:
+ * searchtypes.xml: Merge some search types together.
+ * em-vfolder-context.c: (vfolder_new_element): More elements.
+ * em-filter-folder-element.h: (struct _EMFilterFolderElement):
+ * em-filter-folder-element.c: (xml_encode), (xml_decode),
+ (folder_selected), (get_widget), (format_sexp):
+ Support storing folder uri in a camel's way.
+
+ * em-format-html-display.c: (efhd_use_component):
+ Compiler warning fix.
+
+2008-12-29 Matthew Barnes <mbarnes@redhat.com>
+
+ ** Fixes bug #565857
+
+ * e-searching-tokenizer.c (searcher_next_token):
+ The HTMLTokenizer now expects a newly-allocated string from its
+ next_token() method, so duplicate the returned string. This fixes
+ a memory leak whereby previously, some implementations of next_token()
+ did return a newly-allocated string, some did not. Those that did
+ leaked those strings.
+
+2008-12-22 Sankar P <psankar@novell.com>
+
+ ** Part of fix for bug #559153
+
+ * em-migrate.c (update_progress_in_main_thread), (migrate_folders),
+ (count_folders), (migrate_folders_to_db_thread), (migrate_to_db),
+ (em_migrate):
+ Migration Improvements
+
+2008-12-22 Norman Wang <zhichao.wang@sun.com>
+
+ ** Fix for bug #558337
+
+ * mail/em-subscribe-editor.c: Create a wrapper class MailMsgListNode of
+ _zsubscribe_msg message. The MailMsgListNode class is the subclass of
+ EDListNode class. So the _zsubscribe_msg can be added into the EDList.
+
+2008-12-16 Milan Crha <mcrha@redhat.com>
+
+ ** Part of fix for bug #552583
+
+ * mail-config.c: (mail_config_get_account_by_source_url),
+ (mail_config_get_account_by_transport_url): Do not leak.
+
+2008-12-15 Milan Crha <mcrha@redhat.com>
+
+ ** Fix for bug #564007
+
+ * em-format.c: (emf_inlinepgp_encrypted): Guess the decrypted
+ part mime type if not known from the decryptor, thus show the
+ content really inline, if possible.
+
+2008-12-15 Milan Crha <mcrha@redhat.com>
+
+ ** Part of fix for bug #563669
+
+ * em-account-editor.c: (emae_option_checkspin):
+ Use zero GtkSpinButton's PageSize, as Gtk+ requires.
+
+2008-12-15 Srinivasa Ragavan <sragavan@novell.com>
+
+ * em-format-html-display.c: Fix a impllicit warning
+
+2008-12-15 Srinivasa Ragavan <sragavan@novell.com>
+
+ ** Fix for bug #552583
+
+ * mail-config.c: (mail_config_get_account_by_transport_url): Free the
+ right url.
+
+2008-12-15 Srinivasa Ragavan <sragavan@novell.com>
+
+ ** Fix for #546637
+
+ * message-list.c: (message_list_finalise), (regen_list_exec),
+ (regen_list_done): Don't loose uids.
+
+2008-12-15 Srinivasa Ragavan <sragavan@novell.com>
+
+
+ * em-format-html-display.c: (efhd_bonobo_unknown),
+ (efhd_find_handler), (efhd_bonobo_object),
+ (efhd_check_server_prop), (efhd_use_component),
+ (efhd_format_attachment): Restore the code for BONOBO components need
+ by the vcard inline viewer.
+
+2008-12-15 Srinivasa Ragavan <sragavan@novell.com>
+
+ * em-account-editor.c: (emae_option_checkspin):
+ * em-folder-tree.c: (emft_popup_uvfolder), (emft_popup): Add the
+ unread vfolder hack.
+
+2008-12-15 Lucian Langa <lucilanga@gnome.org>
+
+ ** Fixes bug #564519
+
+ * mail-send-recv.c: (build_dialog):
+ Count also deleted unsent messages when displaying SMTP server
+
+2008-12-13 Matthew Barnes <mbarnes@redhat.com>
+
+ ** Fixes bug #564351 (patch by Tal Benavidor)
+
+ * em-icon-stream.c:
+ Fix single-header include issue for GdkPixbuf.
+
+2008-12-10 Milan Crha <mcrha@redhat.com>
+
+ ** Part of fix for bug #552357
+
+ * e-searching-tokenizer.c: (e_searching_tokenizer_begin):
+ Function prototype changed.
+
2008-12-10 Milan Crha <mcrha@redhat.com>
** Part of fix for bug #563870
diff --git a/mail/e-searching-tokenizer.c b/mail/e-searching-tokenizer.c
index 044c3840b7..172a126c92 100644
--- a/mail/e-searching-tokenizer.c
+++ b/mail/e-searching-tokenizer.c
@@ -45,7 +45,7 @@ enum {
static guint signals[LAST_SIGNAL] = { 0, };
-static void e_searching_tokenizer_begin (HTMLTokenizer *, char *);
+static void e_searching_tokenizer_begin (HTMLTokenizer *, const char *);
static void e_searching_tokenizer_end (HTMLTokenizer *);
static char *e_searching_tokenizer_peek_token (HTMLTokenizer *);
static char *e_searching_tokenizer_next_token (HTMLTokenizer *);
@@ -811,7 +811,7 @@ searcher_next_token(struct _searcher *s)
s->current = token = (struct _token *)e_dlist_remhead(&s->output);
- return token?token->tok:NULL;
+ return token ? g_strdup (token->tok) : NULL;
}
static char *
@@ -1070,7 +1070,7 @@ static char *get_token(HTMLTokenizer *t)
}
static void
-e_searching_tokenizer_begin (HTMLTokenizer *t, char *content_type)
+e_searching_tokenizer_begin (HTMLTokenizer *t, const char *content_type)
{
ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (t);
struct _ESearchingTokenizerPrivate *p = st->priv;
diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c
index a29f408231..3174deaed9 100644
--- a/mail/em-account-editor.c
+++ b/mail/em-account-editor.c
@@ -2018,9 +2018,9 @@ emae_option_checkspin(EMAccountEditorService *service, CamelURL *url, const char
hbox = gtk_hbox_new(FALSE, 0);
check = g_object_new(gtk_check_button_get_type(), "label", pre, "use_underline", TRUE, "active", enable, NULL);
- spin = gtk_spin_button_new((GtkAdjustment *)gtk_adjustment_new(def, min, max, 1, 1, 1), 1, 0);
+ spin = gtk_spin_button_new((GtkAdjustment *)gtk_adjustment_new(def, min, max, 1, 1, 0), 1, 0);
if (post)
- label = gtk_label_new(post);
+ label = gtk_label_new_with_mnemonic(post);
gtk_box_pack_start((GtkBox *)hbox, check, FALSE, TRUE, 0);
gtk_box_pack_start((GtkBox *)hbox, spin, FALSE, TRUE, 0);
if (label)
diff --git a/mail/em-filter-folder-element.c b/mail/em-filter-folder-element.c
index 3f49796650..b4b098b4b6 100644
--- a/mail/em-filter-folder-element.c
+++ b/mail/em-filter-folder-element.c
@@ -181,7 +181,10 @@ xml_encode(FilterElement *fe)
value = xmlNewNode(NULL, (unsigned const char *)"value");
xmlSetProp(value, (unsigned const char *)"name", (unsigned char *)fe->name);
- xmlSetProp(value, (unsigned const char *)"type", (unsigned const char *)"folder");
+ if (ff->store_camel_uri)
+ xmlSetProp(value, (unsigned const char *)"type", (unsigned const char *)"folder-curi");
+ else
+ xmlSetProp(value, (unsigned const char *)"type", (unsigned const char *)"folder");
work = xmlNewChild(value, NULL, (unsigned const char *)"folder", NULL);
xmlSetProp(work, (unsigned const char *)"uri", (unsigned const char *)ff->uri);
@@ -194,12 +197,21 @@ xml_decode(FilterElement *fe, xmlNodePtr node)
{
EMFilterFolderElement *ff = (EMFilterFolderElement *)fe;
xmlNodePtr n;
+ xmlChar *type;
d(printf("Decoding folder from xml %p\n", fe));
xmlFree(fe->name);
fe->name = (char *)xmlGetProp(node, (unsigned const char *)"name");
+ type = xmlGetProp (node, (unsigned const char *)"type");
+ if (type) {
+ ff->store_camel_uri = g_str_equal ((const char *)type, "folder-curi");
+ xmlFree (type);
+ } else {
+ ff->store_camel_uri = FALSE;
+ }
+
n = node->children;
while(n) {
if (!strcmp((char *)n->name, "folder")) {
@@ -224,7 +236,11 @@ folder_selected(EMFolderSelectionButton *button, EMFilterFolderElement *ff)
uri = em_folder_selection_button_get_selection(button);
g_free(ff->uri);
- ff->uri = uri!=NULL?em_uri_from_camel(uri):NULL;
+
+ if (ff->store_camel_uri)
+ ff->uri = g_strdup (uri);
+ else
+ ff->uri = uri != NULL ? em_uri_from_camel (uri) : NULL;
gdk_window_raise(GTK_WIDGET(gtk_widget_get_ancestor(GTK_WIDGET(button), GTK_TYPE_WINDOW))->window);
}
@@ -237,11 +253,16 @@ get_widget(FilterElement *fe)
GtkWidget *button;
char *uri;
- uri = em_uri_to_camel(ff->uri);
+ if (ff->store_camel_uri)
+ uri = ff->uri;
+ else
+ uri = em_uri_to_camel (ff->uri);
model = e_mail_shell_module_get_folder_tree_model (mail_shell_module);
button = em_folder_selection_button_new (model, _("Select Folder"), NULL);
em_folder_selection_button_set_selection(EM_FOLDER_SELECTION_BUTTON(button), uri);
- g_free(uri);
+
+ if (!ff->store_camel_uri)
+ g_free(uri);
gtk_widget_show(button);
g_signal_connect(button, "selected", G_CALLBACK(folder_selected), ff);
@@ -266,8 +287,9 @@ format_sexp(FilterElement *fe, GString *out)
static void
emff_copy_value(FilterElement *de, FilterElement *se)
{
- if (EM_IS_FILTER_FOLDER_ELEMENT(se))
+ if (EM_IS_FILTER_FOLDER_ELEMENT(se)) {
+ ((EMFilterFolderElement *)de)->store_camel_uri = ((EMFilterFolderElement *)se)->store_camel_uri;
em_filter_folder_element_set_value((EMFilterFolderElement *)de, ((EMFilterFolderElement *)se)->uri);
- else
+ } else
parent_class->copy_value(de, se);
}
diff --git a/mail/em-filter-folder-element.h b/mail/em-filter-folder-element.h
index 27c6ea81d4..8f9a2d8b4e 100644
--- a/mail/em-filter-folder-element.h
+++ b/mail/em-filter-folder-element.h
@@ -40,6 +40,7 @@ struct _EMFilterFolderElement {
FilterElement parent_object;
char *uri;
+ gboolean store_camel_uri; /* true if uri should contain camel uri, otherwise contains evolution's uri with an Account ID */
};
struct _EMFilterFolderElementClass {
diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c
index 68b682c14c..6cf21f3a94 100644
--- a/mail/em-folder-view.c
+++ b/mail/em-folder-view.c
@@ -30,7 +30,6 @@
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gdk/gdkkeysyms.h>
-#include <libgnome/gnome-util.h>
#ifdef G_OS_WIN32
/* Work around 'DATADIR' and 'interface' lossage in <windows.h> */
diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c
index 20f86ca562..b87767654a 100644
--- a/mail/em-format-html-display.c
+++ b/mail/em-format-html-display.c
@@ -49,6 +49,7 @@
#include <bonobo/bonobo-control-frame.h>
#include <bonobo/bonobo-stream-memory.h>
#include <bonobo/bonobo-widget.h>
+#include <bonobo-activation/bonobo-activation-mime.h>
#include <camel/camel-stream.h>
#include <camel/camel-stream-filter.h>
@@ -187,6 +188,8 @@ static void efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart
static void efhd_complete(EMFormat *);
gboolean efhd_mnemonic_show_bar (GtkWidget *widget, gboolean focus, GtkWidget *efhd);
+static gboolean efhd_bonobo_object(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject);
+static gboolean efhd_use_component(const char *mime_type);
static void efhd_builtin_init(EMFormatHTMLDisplayClass *efhc);
enum {
@@ -1304,10 +1307,37 @@ efhd_builtin_init(EMFormatHTMLDisplayClass *efhc)
}
/* ********************************************************************** */
-
+static void
+efhd_bonobo_unknown(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
+{
+ char *classid;
+
+ classid = g_strdup_printf("bonobo-unknown:///em-format-html-display/%s", emf->part_id->str);
+ em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_bonobo_object);
+ camel_stream_printf(stream, "<object classid=\"%s\" type=\"%s\"></object><br>\n", classid, info->mime_type);
+ g_free(classid);
+}
+
+ /* ********************************************************************** */
static const EMFormatHandler *efhd_find_handler(EMFormat *emf, const char *mime_type)
{
- return ((EMFormatClass *)efhd_parent)->find_handler(emf, mime_type);
+ const EMFormatHandler *handle;
+
+ if ( (handle = ((EMFormatClass *)efhd_parent)->find_handler(emf, mime_type)) == NULL
+ && efhd_use_component(mime_type)
+ && (handle = g_hash_table_lookup(efhd_bonobo_handlers, mime_type)) == NULL) {
+
+ EMFormatHandler *h = g_malloc0(sizeof(*h));
+
+ h->mime_type = g_strdup(mime_type);
+ h->handler = efhd_bonobo_unknown;
+ h->flags = EM_FORMAT_HANDLER_INLINE_DISPOSITION;
+ g_hash_table_insert(efhd_bonobo_handlers, h->mime_type, h);
+
+ handle = h;
+ }
+
+ return handle;
}
static void efhd_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *src)
@@ -1957,6 +1987,155 @@ efhd_attachment_frame(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri)
}
}
+static gboolean
+efhd_bonobo_object(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject)
+{
+ CamelDataWrapper *wrapper;
+ Bonobo_ServerInfo *component;
+ GtkWidget *embedded;
+ Bonobo_PersistStream persist;
+ CORBA_Environment ev;
+ CamelStreamMem *cstream;
+ BonoboStream *bstream;
+ BonoboControlFrame *control_frame;
+ Bonobo_PropertyBag prop_bag;
+
+ component = bonobo_activation_get_default_component_for_mime_type (eb->type);
+ if (component == NULL)
+ return FALSE;
+
+ embedded = bonobo_widget_new_control(component->iid, NULL);
+ CORBA_free(component);
+ if (embedded == NULL)
+ return FALSE;
+
+ CORBA_exception_init(&ev);
+
+ control_frame = bonobo_widget_get_control_frame((BonoboWidget *)embedded);
+ prop_bag = bonobo_control_frame_get_control_property_bag(control_frame, NULL);
+ if (prop_bag != CORBA_OBJECT_NIL) {
+ /*
+ * Now we can take care of business. Currently, the only control
+ * that needs something passed to it through a property bag is
+ * the iTip control, and it needs only the From email address,
+ * but perhaps in the future we can generalize this section of code
+ * to pass a bunch of useful things to all embedded controls.
+ */
+ const CamelInternetAddress *from;
+ char *from_address;
+
+ from = camel_mime_message_get_from((CamelMimeMessage *)((EMFormat *)efh)->message);
+ from_address = camel_address_encode((CamelAddress *)from);
+ bonobo_property_bag_client_set_value_string(prop_bag, "from_address", from_address, &ev);
+ g_free(from_address);
+
+ Bonobo_Unknown_unref(prop_bag, &ev);
+ }
+
+ persist = (Bonobo_PersistStream)Bonobo_Unknown_queryInterface(bonobo_widget_get_objref((BonoboWidget *)embedded),
+ "IDL:Bonobo/PersistStream:1.0", &ev);
+ if (persist == CORBA_OBJECT_NIL) {
+ g_object_ref_sink(embedded);
+ CORBA_exception_free(&ev);
+ return FALSE;
+ }
+
+ /* Write the data to a CamelStreamMem... */
+ cstream = (CamelStreamMem *)camel_stream_mem_new();
+ wrapper = camel_medium_get_content_object((CamelMedium *)pobject->part);
+ if (FALSE && !g_ascii_strncasecmp (eb->type, "text/", 5)) {
+ /* do charset conversion, etc */
+ d(printf("performing charset conversion for %s component\n", eb->type));
+ em_format_format_text((EMFormat *)efh, (CamelStream *)cstream, wrapper);
+ } else {
+ camel_data_wrapper_decode_to_stream (wrapper, (CamelStream *) cstream);
+ }
+
+ /* ...convert the CamelStreamMem to a BonoboStreamMem... */
+ bstream = bonobo_stream_mem_create((char *)cstream->buffer->data, cstream->buffer->len, TRUE, FALSE);
+ camel_object_unref(cstream);
+
+ /* ...and hydrate the PersistStream from the BonoboStream. */
+ Bonobo_PersistStream_load(persist,
+ bonobo_object_corba_objref(BONOBO_OBJECT (bstream)),
+ eb->type, &ev);
+ bonobo_object_unref(BONOBO_OBJECT (bstream));
+ Bonobo_Unknown_unref(persist, &ev);
+ CORBA_Object_release(persist, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_object_ref_sink(embedded);
+ CORBA_exception_free(&ev);
+ return FALSE;
+ }
+ CORBA_exception_free(&ev);
+
+ gtk_widget_show(embedded);
+ gtk_container_add(GTK_CONTAINER (eb), embedded);
+
+ return TRUE;
+}
+
+static gboolean
+efhd_check_server_prop(Bonobo_ServerInfo *component, const char *propname, const char *value)
+{
+ CORBA_sequence_CORBA_string stringv;
+ Bonobo_ActivationProperty *prop;
+ int i;
+
+ prop = bonobo_server_info_prop_find(component, propname);
+ if (!prop || prop->v._d != Bonobo_ACTIVATION_P_STRINGV)
+ return FALSE;
+
+ stringv = prop->v._u.value_stringv;
+ for (i = 0; i < stringv._length; i++) {
+ if (!g_ascii_strcasecmp(value, stringv._buffer[i]))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+efhd_use_component(const char *mime_type)
+{
+ GList *components, *iter;
+ Bonobo_ServerInfo *component = NULL;
+
+ /* should this cache it? */
+
+ if (g_ascii_strcasecmp(mime_type, "text/x-vcard") != 0
+ && g_ascii_strcasecmp(mime_type, "text/calendar") != 0) {
+ const char **mime_types;
+ int i;
+
+ mime_types = mail_config_get_allowable_mime_types();
+ for (i = 0; mime_types[i]; i++) {
+ if (!g_ascii_strcasecmp(mime_types[i], mime_type))
+ goto type_ok;
+ }
+ return FALSE;
+ }
+type_ok:
+ components = bonobo_activation_get_all_components_for_mime_type (mime_type);
+ for (iter = components; iter; iter = iter->next) {
+ Bonobo_ServerInfo *comp = iter->data;
+
+ comp = iter->data;
+ if (efhd_check_server_prop(comp, "repo_ids", "IDL:Bonobo/PersistStream:1.0")
+ && efhd_check_server_prop(comp, "bonobo:supported_mime_types", mime_type)) {
+ component = comp;
+ break;
+ }
+ }
+
+ /* FIXME: How should I free the Bonobo_ServerInfo's ? */
+ g_list_foreach (components, (GFunc)CORBA_free, NULL);
+ g_list_free (components);
+
+ return component != NULL;
+}
+
static void
attachment_bar_arrow_clicked(GtkWidget *w, EMFormatHTMLDisplay *efhd)
{
@@ -2330,6 +2509,12 @@ efhd_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part,
if (handle) {
if (info->shown)
handle->handler(emf, stream, part, handle);
+ } else if (efhd_use_component(mime_type)) {
+ g_free(classid); /* messy */
+
+ classid = g_strdup_printf("bonobo-unknown:///em-format-html-display/%s", emf->part_id->str);
+ em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_bonobo_object);
+ camel_stream_printf(stream, "<object classid=\"%s\" type=\"%s\"></object><br>>\n", classid, mime_type);
}
g_free(classid);
diff --git a/mail/em-format.c b/mail/em-format.c
index 9b05b1ef6e..4af272a3ff 100644
--- a/mail/em-format.c
+++ b/mail/em-format.c
@@ -1653,6 +1653,8 @@ emf_inlinepgp_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *ipart
CamelCipherValidity *valid;
CamelException *ex;
CamelMimePart *opart;
+ CamelDataWrapper *dw;
+ char *mime_type;
cipher = camel_gpg_context_new(emf->session);
ex = camel_exception_new();
@@ -1671,6 +1673,19 @@ emf_inlinepgp_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *ipart
return;
}
+ dw = camel_medium_get_content_object ((CamelMedium *)opart);
+ mime_type = camel_data_wrapper_get_mime_type (dw);
+
+ /* this ensures to show the 'opart' as inlined, if possible */
+ if (mime_type && g_ascii_strcasecmp (mime_type, "application/octet-stream") == 0) {
+ const char *snoop = em_utils_snoop_type (opart);
+
+ if (snoop)
+ camel_data_wrapper_set_mime_type (dw, snoop);
+ }
+
+ g_free (mime_type);
+
/* Pass it off to the real formatter */
em_format_format_secure(emf, stream, opart, valid);
diff --git a/mail/em-icon-stream.c b/mail/em-icon-stream.c
index 673559440f..2e1a7ae2f6 100644
--- a/mail/em-icon-stream.c
+++ b/mail/em-icon-stream.c
@@ -29,7 +29,6 @@
#include <string.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gdk-pixbuf/gdk-pixbuf-loader.h>
#include <gtk/gtk.h>
#include "em-icon-stream.h"
#include "e-util/e-icon-factory.h"
diff --git a/mail/em-subscribe-editor.c b/mail/em-subscribe-editor.c
index 548029e0ba..8146b66bb6 100644
--- a/mail/em-subscribe-editor.c
+++ b/mail/em-subscribe-editor.c
@@ -111,6 +111,12 @@ struct _EMSubscribeNode {
GtkTreePath *path;
};
+typedef struct _MailMsgListNode MailMsgListNode;
+struct _MailMsgListNode {
+ EDListNode node;
+ MailMsg *msg;
+};
+
static void sub_editor_busy(EMSubscribeEditor *se, int dir);
static int sub_queue_fill_level(EMSubscribe *sub, EMSubscribeNode *node);
static void sub_selection_changed(GtkTreeSelection *selection, EMSubscribe *sub);
@@ -185,6 +191,7 @@ sub_folder_done (struct _zsubscribe_msg *m)
GtkTreeModel *model;
EMSubscribeNode *node;
gboolean subscribed, issub;
+ MailMsgListNode *msgListNode;
m->sub->subscribe_id = -1;
if (m->sub->cancel)
@@ -209,10 +216,13 @@ sub_folder_done (struct _zsubscribe_msg *m)
}
/* queue any further ones, or if out, update the ui */
- next = (struct _zsubscribe_msg *)e_dlist_remhead(&m->sub->subscribe);
- if (next) {
+ msgListNode = (MailMsgListNode *) e_dlist_remhead(&m->sub->subscribe);
+ if (msgListNode) {
+ next = (struct _zsubscribe_msg *) msgListNode->msg;
+ /* Free the memory of the MailMsgListNode which won't be used anymore. */
+ g_free(msgListNode);
next->sub->subscribe_id = next->base.seq;
- mail_msg_unordered_push (next);
+ mail_msg_unordered_push (next);
} else {
/* should it go off the model instead? */
sub_selection_changed(gtk_tree_view_get_selection(m->sub->tree), m->sub);
@@ -239,6 +249,7 @@ static int
sub_subscribe_folder (EMSubscribe *sub, EMSubscribeNode *node, int state, const char *spath)
{
struct _zsubscribe_msg *m;
+ MailMsgListNode *msgListNode;
int id;
m = mail_msg_new (&sub_subscribe_folder_info);
@@ -254,8 +265,10 @@ sub_subscribe_folder (EMSubscribe *sub, EMSubscribeNode *node, int state, const
d(printf("running subscribe folder '%s'\n", spath));
mail_msg_unordered_push (m);
} else {
+ msgListNode = g_malloc0(sizeof(MailMsgListNode));
+ msgListNode->msg = (MailMsg *) m;
d(printf("queueing subscribe folder '%s'\n", spath));
- e_dlist_addtail(&sub->subscribe, (EDListNode *)m);
+ e_dlist_addtail(&sub->subscribe, (EDListNode *)msgListNode);
}
return id;
@@ -541,6 +554,7 @@ static void
sub_destroy(GtkWidget *w, EMSubscribe *sub)
{
struct _zsubscribe_msg *m;
+ MailMsgListNode *msgListNode;
d(printf("subscribe closed\n"));
sub->cancel = TRUE;
@@ -551,8 +565,12 @@ sub_destroy(GtkWidget *w, EMSubscribe *sub)
if (sub->subscribe_id != -1)
mail_msg_cancel(sub->subscribe_id);
- while ( (m = (struct _zsubscribe_msg *)e_dlist_remhead(&sub->subscribe)) )
+ while ( (msgListNode = (MailMsgListNode *)e_dlist_remhead(&sub->subscribe))) {
+ m = (struct _zsubscribe_msg *) msgListNode->msg;
+ /* Free the memory of MailMsgListNode which won't be used anymore. */
+ g_free(msgListNode);
mail_msg_unref(m);
+ }
sub_unref(sub);
}
diff --git a/mail/em-vfolder-context.c b/mail/em-vfolder-context.c
index eebf12e960..88c97b0a0f 100644
--- a/mail/em-vfolder-context.c
+++ b/mail/em-vfolder-context.c
@@ -33,6 +33,8 @@
#include "filter/filter-option.h"
#include "filter/filter-int.h"
+#include "em-filter-folder-element.h"
+
static FilterElement *vfolder_new_element(RuleContext *rc, const char *type);
static RuleContextClass *parent_class = NULL;
@@ -108,6 +110,13 @@ vfolder_new_element(RuleContext *rc, const char *type)
return (FilterElement *) filter_option_new();
} else if (!strcmp(type, "score")) {
return (FilterElement *) filter_int_new_type("score", -3, 3);
+ } else if (!strcmp(type, "folder-curi")) {
+ EMFilterFolderElement *ff = em_filter_folder_element_new ();
+ if (ff)
+ ff->store_camel_uri = TRUE;
+ return (FilterElement *) ff;
+ } else if (!strcmp(type, "folder")) {
+ return (FilterElement *) em_filter_folder_element_new();
} else {
return parent_class->new_element(rc, type);
}
diff --git a/mail/importers/mail-importer.c b/mail/importers/mail-importer.c
index 45dac0e11c..fde63dfdae 100644
--- a/mail/importers/mail-importer.c
+++ b/mail/importers/mail-importer.c
@@ -25,6 +25,7 @@
#include <config.h>
#endif
+#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/types.h>
@@ -36,7 +37,6 @@
#include <glib/gstdio.h>
#include <gmodule.h>
-#include <libgnome/gnome-util.h>
#include <glib/gi18n.h>
#include <camel/camel-folder.h>
#include <camel/camel-store.h>
diff --git a/mail/mail-autofilter.c b/mail/mail-autofilter.c
index 9ad44a6599..f73c44be42 100644
--- a/mail/mail-autofilter.c
+++ b/mail/mail-autofilter.c
@@ -29,9 +29,6 @@
#include <glib.h>
#include <glib/gi18n.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-app-helper.h>
-#include <libgnomeui/gnome-popup-menu.h>
#include "mail-vfolder.h"
#include "mail-autofilter.h"
diff --git a/mail/mail-component.c b/mail/mail-component.c
index 9013556388..c2ccb69729 100644
--- a/mail/mail-component.c
+++ b/mail/mail-component.c
@@ -80,7 +80,7 @@
#include <table/e-tree.h>
#include <table/e-tree-memory.h>
-#include <glib/gi18n.h>
+#include <glib/gi18n-lib.h>
#include <camel/camel-file-utils.h>
#include <camel/camel-vtrash-folder.h>
@@ -1239,6 +1239,9 @@ mail_component_class_init (MailComponentClass *class)
POA_GNOME_Evolution_MailComponent__epv *mepv = &class->epv;
GObjectClass *object_class = G_OBJECT_CLASS (class);
+ bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+
parent_class = g_type_class_peek_parent (class);
object_class->dispose = impl_dispose;
diff --git a/mail/mail-config.c b/mail/mail-config.c
index 8333b02e09..29e74cfe00 100644
--- a/mail/mail-config.c
+++ b/mail/mail-config.c
@@ -859,6 +859,7 @@ mail_config_get_account_by_source_url (const char *source_url)
}
g_object_unref (iter);
+ camel_url_free (url);
return account;
}
@@ -898,10 +899,11 @@ mail_config_get_account_by_transport_url (const char *transport_url)
if (!mail_config_account_url_equal (url, account_url))
account = NULL; /* not a match */
- camel_url_free (url);
+ camel_url_free (account_url);
}
g_object_unref (iter);
+ camel_url_free (url);
return account;
}
diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c
index 70b69f0c97..1a8fb02017 100644
--- a/mail/mail-send-recv.c
+++ b/mail/mail-send-recv.c
@@ -424,7 +424,8 @@ build_dialog (GtkWindow *parent,
g_object_unref (iter);
/* Check to see if we have to send any mails --- if we don't, don't display the SMTP row in the table */
- if (outbox && destination && camel_folder_get_message_count (outbox) == 0)
+ if (outbox && destination
+ && (camel_folder_get_message_count(outbox) - camel_folder_get_deleted_message_count(outbox)) == 0)
num_sources--;
table = gtk_table_new (num_sources, 4, FALSE);
@@ -552,7 +553,8 @@ build_dialog (GtkWindow *parent,
e_event_emit ((EEvent *)em_event_peek (), "mail.sendreceive", (EEventTarget *) target);
/* Skip displaying the SMTP row if we've got no outbox, destination or unsent mails */
- if (outbox && destination && camel_folder_get_message_count (outbox) != 0) {
+ if (outbox && destination
+ && (camel_folder_get_message_count(outbox) - camel_folder_get_deleted_message_count(outbox)) != 0) {
info = g_hash_table_lookup (data->active, SEND_URI_KEY);
if (info == NULL) {
info = g_malloc0 (sizeof (*info));
diff --git a/mail/message-list.c b/mail/message-list.c
index 993c387cd7..b52ec71b82 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -2358,6 +2358,11 @@ message_list_finalise (GObject *object)
g_hash_table_destroy (message_list->normalised_hash);
+ if (message_list->ensure_uid) {
+ g_free (message_list->ensure_uid);
+ message_list->ensure_uid = NULL;
+ }
+
if (message_list->thread_tree)
camel_folder_thread_messages_unref(message_list->thread_tree);
@@ -4030,13 +4035,11 @@ regen_list_exec (struct _regen_list_msg *m)
uids = camel_folder_get_uids (m->folder);
} else {
searchuids = uids = camel_folder_search_by_expression (m->folder, expr, &m->base.ex);
-
/* If m->changes is not NULL, then it means we are called from folder_changed event,
thus we will keep the selected message to be sure it doesn't disappear because
it no longer belong to our search filter. */
- if (uids && m->ml->search && ((m->changes && m->ml->cursor_uid) || m->ml->ensure_uid)) {
+ if (uids && ((m->changes && m->ml->cursor_uid) || m->ml->ensure_uid)) {
const char *looking_for = m->ml->cursor_uid;
-
/* ensure_uid has precedence of cursor_uid */
if (m->ml->ensure_uid)
looking_for = m->ml->ensure_uid;
@@ -4190,10 +4193,6 @@ regen_list_done (struct _regen_list_msg *m)
if (m->ml->priv->destroyed)
return;
- if (m->ml->ensure_uid) {
- g_free (m->ml->ensure_uid);
- m->ml->ensure_uid = NULL;
- }
if (!m->complete)
return;
diff --git a/mail/message-tag-followup.c b/mail/message-tag-followup.c
index 3818c6ecf0..93f037eb82 100644
--- a/mail/message-tag-followup.c
+++ b/mail/message-tag-followup.c
@@ -33,7 +33,6 @@
#include <gconf/gconf.h>
#include <gconf/gconf-client.h>
-#include <libgnomeui/gnome-pixmap.h>
#include <glib/gi18n.h>
#include "e-util/e-util-private.h"
diff --git a/mail/searchtypes.xml b/mail/searchtypes.xml
index ded2e2eabd..83941d875c 100644
--- a/mail/searchtypes.xml
+++ b/mail/searchtypes.xml
@@ -115,6 +115,223 @@
<input type="address" name="recipient"/>
</part>
+ <part name="cc">
+ <title>CC</title>
+ <input type="optionlist" name="recipient-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>
+ (match-all (header-contains "Cc" ${recipient}))
+ </code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>
+ (match-all (not (header-contains "Cc" ${recipient})))
+ </code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>
+ (match-all (header-matches "Cc" ${recipient}))
+ </code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>
+ (match-all (not (header-matches "Cc" ${recipient})))
+ </code>
+ </option>
+ <option value="starts with">
+ <title>starts with</title>
+ <code>
+ (match-all (header-starts-with "Cc" ${recipient}))
+ </code>
+ </option>
+ <option value="not starts with">
+ <title>does not start with</title>
+ <code>
+ (match-all (not (header-starts-with "Cc" ${recipient})))
+ </code>
+ </option>
+ <option value="ends with">
+ <title>ends with</title>
+ <code>
+ (match-all (header-ends-with "Cc" ${recipient}))
+ </code>
+ </option>
+ <option value="not ends with">
+ <title>does not end with</title>
+ <code>
+ (match-all (not (header-ends-with "Cc" ${recipient})))
+ </code>
+ </option>
+ <option value="matches soundex">
+ <title>sounds like</title>
+ <code>
+ (match-all (header-soundex "Cc" ${recipient}))
+ </code>
+ </option>
+ <option value="not match soundex">
+ <title>does not sound like</title>
+ <code>
+ (match-all (not (header-soundex "Cc" ${recipient})))
+ </code>
+ </option>
+ </input>
+ <input type="address" name="recipient"/>
+ </part>
+
+ <part name="bcc">
+ <title>BCC</title>
+ <input type="optionlist" name="recipient-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>
+ (match-all (header-contains "Bcc" ${recipient}))
+ </code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>
+ (match-all (not (header-contains "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>
+ (match-all (header-matches "Bcc" ${recipient}))
+ </code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>
+ (match-all (not (header-matches "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="starts with">
+ <title>starts with</title>
+ <code>
+ (match-all (header-starts-with "Bcc" ${recipient}))
+ </code>
+ </option>
+ <option value="not starts with">
+ <title>does not start with</title>
+ <code>
+ (match-all (not (header-starts-with "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="ends with">
+ <title>ends with</title>
+ <code>
+ (match-all (header-ends-with "Bcc" ${recipient}))
+ </code>
+ </option>
+ <option value="not ends with">
+ <title>does not end with</title>
+ <code>
+ (match-all (not (header-ends-with "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="matches soundex">
+ <title>sounds like</title>
+ <code>
+ (match-all (header-soundex "Bcc" ${recipient}))
+ </code>
+ </option>
+ <option value="not match soundex">
+ <title>does not sound like</title>
+ <code>
+ (match-all (not (header-soundex "Bcc" ${recipient})))
+ </code>
+ </option>
+ </input>
+ <input type="address" name="recipient"/>
+ </part>
+
+ <part name="senderto">
+ <title>Sender or Recipients</title>
+ <input type="optionlist" name="recipient-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>
+ (match-all (or (header-contains "From" ${recipient})
+ (header-contains "To" ${recipient})
+ (header-contains "Cc" ${recipient})
+ (header-contains "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>
+ (match-all (not (or
+ (header-contains "From" ${recipient})
+ (header-contains "To" ${recipient})
+ (header-contains "Cc" ${recipient})
+ (header-contains "Bcc" ${recipient}))))
+ </code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>
+ (match-all (or (header-matches "From" ${recipient})
+ (header-matches "To" ${recipient})
+ (header-matches "Cc" ${recipient})
+ (header-matches "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>
+ (match-all (not (or
+ (header-matches "From" ${recipient})
+ (header-matches "To" ${recipient})
+ (header-matches "Cc" ${recipient})
+ (header-matches "Bcc" ${recipient}))))
+ </code>
+ </option>
+ <option value="starts with">
+ <title>starts with</title>
+ <code>
+ (match-all (or (header-starts-with "From" ${recipient})
+ (header-starts-with "To" ${recipient})
+ (header-starts-with "Cc" ${recipient})
+ (header-starts-with "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="not starts with">
+ <title>does not start with</title>
+ <code>
+ (match-all (not (or
+ (header-starts-with "From" ${recipient})
+ (header-starts-with "To" ${recipient})
+ (header-starts-with "Cc" ${recipient})
+ (header-starts-with "Bcc" ${recipient}))))
+ </code>
+ </option>
+ <option value="ends with">
+ <title>ends with</title>
+ <code>
+ (match-all (or (header-ends-with "From" ${recipient})
+ (header-ends-with "To" ${recipient})
+ (header-ends-with "Cc" ${recipient})
+ (header-ends-with "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="not ends with">
+ <title>does not end with</title>
+ <code>
+ (match-all (not (or
+ (header-ends-with "From" ${recipient})
+ (header-ends-with "To" ${recipient})
+ (header-ends-with "Cc" ${recipient})
+ (header-ends-with "Bcc" ${recipient}))))
+ </code>
+ </option>
+ </input>
+ <input type="address" name="recipient"/>
+ </part>
+
<part name="subject">
<title>Subject</title>
<input type="optionlist" name="subject-type">
@@ -169,6 +386,87 @@
</input>
<input type="string" name="subject"/>
</part>
+
+ <part name="header">
+ <title>Specific header</title>
+ <input type="string" name="header-field"/>
+ <input type="optionlist" name="header-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>
+ (match-all (header-contains ${header-field} ${word}))
+ </code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>
+ (match-all (not (header-contains ${header-field} ${word})))
+ </code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>
+ (match-all (header-matches ${header-field} ${word}))
+ </code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>
+ (match-all (not (header-matches ${header-field} ${word})))
+ </code>
+ </option>
+ <option value="starts with">
+ <title>starts with</title>
+ <code>
+ (match-all (header-starts-with ${header-field} ${word}))
+ </code>
+ </option>
+ <option value="not starts with">
+ <title>does not start with</title>
+ <code>
+ (match-all (not (header-starts-with ${header-field} ${word})))
+ </code>
+ </option>
+ <option value="ends with">
+ <title>ends with</title>
+ <code>
+ (match-all (header-ends-with ${header-field} ${word}))
+ </code>
+ </option>
+ <option value="not ends with">
+ <title>does not end with</title>
+ <code>
+ (match-all (not (header-ends-with ${header-field} ${word})))
+ </code>
+ </option>
+ <option value="exists">
+ <title>exists</title>
+ <code>
+ (match-all (header-exists ${header-field}))
+ </code>
+ </option>
+ <option value="not exists">
+ <title>does not exist</title>
+ <code>
+ (match-all (not (header-exists ${header-field})))
+ </code>
+ </option>
+ <option value="matches soundex">
+ <title>sounds like</title>
+ <code>
+ (match-all (header-soundex ${header-field} ${word}))
+ </code>
+ </option>
+ <option value="not match soundex">
+ <title>does not sound like</title>
+ <code>
+ (match-all (not (header-soundex ${header-field} ${word})))
+ </code>
+ </option>
+ </input>
+ <input type="string" name="word"/>
+ </part>
+
<part name="body">
<title>Message Body</title>
<input type="optionlist" name="body-type">
@@ -437,6 +735,25 @@
<input type="string" name="mlist"/>
</part>
+ <part name="regex">
+ <title>Regex Match</title>
+ <input type="optionlist" name="match-type">
+ <option value="header">
+ <title>Message Header</title>
+ <code>
+ (match-all (header-full-regex ${expression}))
+ </code>
+ </option>
+ <option value="body">
+ <title>Message Body</title>
+ <code>
+ (match-all (body-regex ${expression}))
+ </code>
+ </option>
+ </input>
+ <input type="regex" name="expression"/>
+ </part>
+
<part name="all">
<title>Match All</title>
<code>
diff --git a/mail/vfoldertypes.xml b/mail/vfoldertypes.xml
index b87af3280a..11ed7cc0af 100644
--- a/mail/vfoldertypes.xml
+++ b/mail/vfoldertypes.xml
@@ -115,6 +115,140 @@
<input type="address" name="recipient"/>
</part>
+ <part name="cc">
+ <title>CC</title>
+ <input type="optionlist" name="recipient-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>
+ (match-all (header-contains "Cc" ${recipient}))
+ </code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>
+ (match-all (not (header-contains "Cc" ${recipient})))
+ </code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>
+ (match-all (header-matches "Cc" ${recipient}))
+ </code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>
+ (match-all (not (header-matches "Cc" ${recipient})))
+ </code>
+ </option>
+ <option value="starts with">
+ <title>starts with</title>
+ <code>
+ (match-all (header-starts-with "Cc" ${recipient}))
+ </code>
+ </option>
+ <option value="not starts with">
+ <title>does not start with</title>
+ <code>
+ (match-all (not (header-starts-with "Cc" ${recipient})))
+ </code>
+ </option>
+ <option value="ends with">
+ <title>ends with</title>
+ <code>
+ (match-all (header-ends-with "Cc" ${recipient}))
+ </code>
+ </option>
+ <option value="not ends with">
+ <title>does not end with</title>
+ <code>
+ (match-all (not (header-ends-with "Cc" ${recipient})))
+ </code>
+ </option>
+ <option value="matches soundex">
+ <title>sounds like</title>
+ <code>
+ (match-all (header-soundex "Cc" ${recipient}))
+ </code>
+ </option>
+ <option value="not match soundex">
+ <title>does not sound like</title>
+ <code>
+ (match-all (not (header-soundex "Cc" ${recipient})))
+ </code>
+ </option>
+ </input>
+ <input type="address" name="recipient"/>
+ </part>
+
+ <part name="bcc">
+ <title>BCC</title>
+ <input type="optionlist" name="recipient-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>
+ (match-all (header-contains "Bcc" ${recipient}))
+ </code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>
+ (match-all (not (header-contains "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>
+ (match-all (header-matches "Bcc" ${recipient}))
+ </code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>
+ (match-all (not (header-matches "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="starts with">
+ <title>starts with</title>
+ <code>
+ (match-all (header-starts-with "Bcc" ${recipient}))
+ </code>
+ </option>
+ <option value="not starts with">
+ <title>does not start with</title>
+ <code>
+ (match-all (not (header-starts-with "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="ends with">
+ <title>ends with</title>
+ <code>
+ (match-all (header-ends-with "Bcc" ${recipient}))
+ </code>
+ </option>
+ <option value="not ends with">
+ <title>does not end with</title>
+ <code>
+ (match-all (not (header-ends-with "Bcc" ${recipient})))
+ </code>
+ </option>
+ <option value="matches soundex">
+ <title>sounds like</title>
+ <code>
+ (match-all (header-soundex "Bcc" ${recipient}))
+ </code>
+ </option>
+ <option value="not match soundex">
+ <title>does not sound like</title>
+ <code>
+ (match-all (not (header-soundex "Bcc" ${recipient})))
+ </code>
+ </option>
+ </input>
+ <input type="address" name="recipient"/>
+ </part>
+
<part name="senderto">
<title>Sender or Recipients</title>
<input type="optionlist" name="recipient-type">
@@ -252,6 +386,87 @@
</input>
<input type="string" name="subject"/>
</part>
+
+ <part name="header">
+ <title>Specific header</title>
+ <input type="string" name="header-field"/>
+ <input type="optionlist" name="header-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>
+ (match-all (header-contains ${header-field} ${word}))
+ </code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>
+ (match-all (not (header-contains ${header-field} ${word})))
+ </code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>
+ (match-all (header-matches ${header-field} ${word}))
+ </code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>
+ (match-all (not (header-matches ${header-field} ${word})))
+ </code>
+ </option>
+ <option value="starts with">
+ <title>starts with</title>
+ <code>
+ (match-all (header-starts-with ${header-field} ${word}))
+ </code>
+ </option>
+ <option value="not starts with">
+ <title>does not start with</title>
+ <code>
+ (match-all (not (header-starts-with ${header-field} ${word})))
+ </code>
+ </option>
+ <option value="ends with">
+ <title>ends with</title>
+ <code>
+ (match-all (header-ends-with ${header-field} ${word}))
+ </code>
+ </option>
+ <option value="not ends with">
+ <title>does not end with</title>
+ <code>
+ (match-all (not (header-ends-with ${header-field} ${word})))
+ </code>
+ </option>
+ <option value="exists">
+ <title>exists</title>
+ <code>
+ (match-all (header-exists ${header-field}))
+ </code>
+ </option>
+ <option value="not exists">
+ <title>does not exist</title>
+ <code>
+ (match-all (not (header-exists ${header-field})))
+ </code>
+ </option>
+ <option value="matches soundex">
+ <title>sounds like</title>
+ <code>
+ (match-all (header-soundex ${header-field} ${word}))
+ </code>
+ </option>
+ <option value="not match soundex">
+ <title>does not sound like</title>
+ <code>
+ (match-all (not (header-soundex ${header-field} ${word})))
+ </code>
+ </option>
+ </input>
+ <input type="string" name="word"/>
+ </part>
+
<part name="body">
<title>Message Body</title>
<input type="optionlist" name="body-type">
@@ -523,6 +738,44 @@
<input type="string" name="mlist"/>
</part>
+ <part name="regex">
+ <title>Regex Match</title>
+ <input type="optionlist" name="match-type">
+ <option value="header">
+ <title>Message Header</title>
+ <code>
+ (match-all (header-full-regex ${expression}))
+ </code>
+ </option>
+ <option value="body">
+ <title>Message Body</title>
+ <code>
+ (match-all (body-regex ${expression}))
+ </code>
+ </option>
+ </input>
+ <input type="regex" name="expression"/>
+ </part>
+
+ <part name="location">
+ <title>Message Location</title>
+ <input type="optionlist" name="msglocation-type">
+ <option value="is">
+ <title>is</title>
+ <code>
+ (match-all (message-location ${folder}))
+ </code>
+ </option>
+ <option value="is-not">
+ <title>is not</title>
+ <code>
+ (match-all (not (message-location ${folder})))
+ </code>
+ </option>
+ </input>
+ <input type="folder-curi" name="folder"/>
+ </part>
+
<part name="all">
<title>Match All</title>
<code>