diff options
Diffstat (limited to 'mail')
-rw-r--r-- | mail/ChangeLog | 165 | ||||
-rw-r--r-- | mail/e-searching-tokenizer.c | 6 | ||||
-rw-r--r-- | mail/em-account-editor.c | 4 | ||||
-rw-r--r-- | mail/em-filter-folder-element.c | 34 | ||||
-rw-r--r-- | mail/em-filter-folder-element.h | 1 | ||||
-rw-r--r-- | mail/em-folder-view.c | 1 | ||||
-rw-r--r-- | mail/em-format-html-display.c | 189 | ||||
-rw-r--r-- | mail/em-format.c | 15 | ||||
-rw-r--r-- | mail/em-icon-stream.c | 1 | ||||
-rw-r--r-- | mail/em-subscribe-editor.c | 28 | ||||
-rw-r--r-- | mail/em-vfolder-context.c | 9 | ||||
-rw-r--r-- | mail/importers/mail-importer.c | 2 | ||||
-rw-r--r-- | mail/mail-autofilter.c | 3 | ||||
-rw-r--r-- | mail/mail-component.c | 5 | ||||
-rw-r--r-- | mail/mail-config.c | 4 | ||||
-rw-r--r-- | mail/mail-send-recv.c | 6 | ||||
-rw-r--r-- | mail/message-list.c | 13 | ||||
-rw-r--r-- | mail/message-tag-followup.c | 1 | ||||
-rw-r--r-- | mail/searchtypes.xml | 317 | ||||
-rw-r--r-- | mail/vfoldertypes.xml | 253 |
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> |