aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filter/ChangeLog31
-rw-r--r--filter/Makefile.am3
-rw-r--r--filter/filter-driver.c205
-rw-r--r--filter/filter-driver.h17
-rw-r--r--filter/filter-element.c80
-rw-r--r--filter/filter-message-search.c20
-rw-r--r--filter/filter-message-search.h2
-rw-r--r--filter/filter-url.c225
-rw-r--r--filter/filter-url.h58
-rw-r--r--filter/filtertypes.xml29
10 files changed, 539 insertions, 131 deletions
diff --git a/filter/ChangeLog b/filter/ChangeLog
index 0ee8b900cb..44834ea3f8 100644
--- a/filter/ChangeLog
+++ b/filter/ChangeLog
@@ -1,3 +1,34 @@
+2000-10-20 Jeffrey Stedfast <fejj@helixcode.com>
+
+ * Makefile.am: Added filter-url.[c,h].
+
+ * filter-message-search.c (get_source): New callback to get the
+ source url of the message being filtered.
+ (filter_message_search): Now takes a source argument.
+
+ * filter-element.c (filter_element_new_type_name): Added code to
+ handle URL types.
+
+ * filter-url.[c,h]: New filter object to handle URLs (ie in the
+ case of filtering on source url). FIXME: find a way to populate
+ the source combo box (including mail-config.h breaks the build in
+ the addressbook - how does including mail-tools.h not break the
+ build???)
+
+ * filtertypes.xml: Added the source filter type and added the
+ move-to action.
+
+ * filter-driver.c (do_move): New callback, a "Copy" action should
+ just copy the message to another location while a Move should both
+ copy the message to a new location and delete it from the source
+ location.
+ (do_delete): Set the deleted flag on the message info.
+ (filter_driver_filter_message): Now returns void as we don't care
+ if it was copied or not in the caller functions. Also check the
+ CamelMessageInfo being passed in - if the message has been marked
+ as deleted prior to being filtered, then return immediately as we
+ don't want to apply filter actions to deleted messages.
+
2000-10-19 Jeffrey Stedfast <fejj@helixcode.com>
* filter-driver.c (filter_driver_filter_folder): Start fetching at
diff --git a/filter/Makefile.am b/filter/Makefile.am
index 3a5dfe8e24..bf17f89614 100644
--- a/filter/Makefile.am
+++ b/filter/Makefile.am
@@ -52,6 +52,8 @@ libfilter_la_SOURCES = \
filter-rule.h \
filter-score.c \
filter-score.h \
+ filter-url.c \
+ filter-url.h \
rule-context.c \
rule-context.h \
score-context.c \
@@ -73,4 +75,3 @@ EXTRA_DIST = filtertypes.xml vfoldertypes.xml \
# basic rules.
filterdir = $(datadir)/evolution
filter_DATA = filtertypes.xml vfoldertypes.xml
-
diff --git a/filter/filter-driver.c b/filter/filter-driver.c
index f4863605a2..d1f132e428 100644
--- a/filter/filter-driver.c
+++ b/filter/filter-driver.c
@@ -86,6 +86,7 @@ static int close_folders (FilterDriver *d);
static ESExpResult *do_delete (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
static ESExpResult *mark_forward (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
static ESExpResult *do_copy (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
+static ESExpResult *do_move (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
static ESExpResult *do_stop (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
static ESExpResult *do_colour (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
static ESExpResult *do_score (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
@@ -99,7 +100,8 @@ static struct {
} symbols[] = {
{ "delete", (ESExpFunc *) do_delete, 0 },
{ "forward-to", (ESExpFunc *) mark_forward, 0 },
- { "copy-to", (ESExpFunc *) do_copy, 0 },
+ { "copy-to", (ESExpFunc *) do_copy, 0 },
+ { "move-to", (ESExpFunc *) do_move, 0 },
{ "stop", (ESExpFunc *) do_stop, 0 },
{ "set-colour", (ESExpFunc *) do_colour, 0 },
{ "set-score", (ESExpFunc *) do_score, 0 }
@@ -229,38 +231,40 @@ filter_driver_new (FilterContext *context, FilterGetFolderFunc get_folder, void
void
-filter_driver_set_status_func(FilterDriver *d, FDStatusFunc *func, void *data)
+filter_driver_set_status_func (FilterDriver *d, FDStatusFunc *func, void *data)
{
struct _FilterDriverPrivate *p = _PRIVATE (d);
-
+
p->statusfunc = func;
p->statusdata = data;
}
void
-filter_driver_set_default_folder(FilterDriver *d, CamelFolder *def)
+filter_driver_set_default_folder (FilterDriver *d, CamelFolder *def)
{
struct _FilterDriverPrivate *p = _PRIVATE (d);
-
+
if (p->defaultfolder)
- camel_object_unref((CamelObject *)p->defaultfolder);
+ camel_object_unref (CAMEL_OBJECT (p->defaultfolder));
+
p->defaultfolder = def;
+
if (p->defaultfolder)
- camel_object_ref((CamelObject *)p->defaultfolder);
+ camel_object_ref (CAMEL_OBJECT (p->defaultfolder));
}
static void
-report_status(FilterDriver *driver, enum filter_status_t status, const char *desc, ...)
+report_status (FilterDriver *driver, enum filter_status_t status, const char *desc, ...)
{
struct _FilterDriverPrivate *p = _PRIVATE (driver);
va_list ap;
char *str;
-
+
if (p->statusfunc) {
- va_start(ap, desc);
- str = g_strdup_vprintf(desc, ap);
- p->statusfunc(driver, status, str, p->message, p->statusdata);
- g_free(str);
+ va_start (ap, desc);
+ str = g_strdup_vprintf (desc, ap);
+ p->statusfunc (driver, status, str, p->message, p->statusdata);
+ g_free (str);
}
}
@@ -288,8 +292,9 @@ do_delete (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver
d(fprintf (stderr, "doing delete\n"));
p->deleted = TRUE;
- report_status(driver, FILTER_STATUS_ACTION, "Delete");
-
+ p->info->flags = p->info->flags | CAMEL_MESSAGE_DELETED;
+ report_status (driver, FILTER_STATUS_ACTION, "Delete");
+
return NULL;
}
@@ -300,7 +305,7 @@ mark_forward (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriv
d(fprintf (stderr, "marking message for forwarding\n"));
/* FIXME: do stuff here */
- report_status(driver, FILTER_STATUS_ACTION, "Forward");
+ report_status (driver, FILTER_STATUS_ACTION, "Forward");
return NULL;
}
@@ -315,7 +320,7 @@ do_copy (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d
p->copied = TRUE;
for (i = 0; i < argc; i++) {
if (argv[i]->type == ESEXP_RES_STRING) {
- /* open folders we intent to copy to */
+ /* open folders we intent to copy to */
char *folder = argv[i]->value.string;
CamelFolder *outbox;
@@ -325,7 +330,37 @@ do_copy (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d
mail_tool_camel_lock_up ();
camel_folder_append_message (outbox, p->message, p->info, p->ex);
- report_status(driver, FILTER_STATUS_ACTION, "Copy to folder %s", outbox->full_name);
+ report_status (driver, FILTER_STATUS_ACTION, "Copy to folder %s", outbox->full_name);
+ mail_tool_camel_lock_down ();
+ }
+ }
+
+ return NULL;
+}
+
+static ESExpResult *
+do_move (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *driver)
+{
+ struct _FilterDriverPrivate *p = _PRIVATE (driver);
+ int i;
+
+ d(fprintf (stderr, "moving message...\n"));
+ p->copied = TRUE;
+ p->deleted = TRUE; /* a 'move' is a copy & delete */
+ p->info->flags = p->info->flags | CAMEL_MESSAGE_DELETED;
+ for (i = 0; i < argc; i++) {
+ if (argv[i]->type == ESEXP_RES_STRING) {
+ /* open folders we intent to move to */
+ char *folder = argv[i]->value.string;
+ CamelFolder *outbox;
+
+ outbox = open_folder (driver, folder);
+ if (!outbox)
+ continue;
+
+ mail_tool_camel_lock_up ();
+ camel_folder_append_message (outbox, p->message, p->info, p->ex);
+ report_status (driver, FILTER_STATUS_ACTION, "Move to folder %s", outbox->full_name);
mail_tool_camel_lock_down ();
}
}
@@ -338,7 +373,7 @@ do_stop (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d
{
struct _FilterDriverPrivate *p = _PRIVATE (driver);
- report_status(driver, FILTER_STATUS_ACTION, "Stopped processing");
+ report_status (driver, FILTER_STATUS_ACTION, "Stopped processing");
d(fprintf (stderr, "terminating message processing\n"));
p->terminated = TRUE;
@@ -353,7 +388,7 @@ do_colour (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver
d(fprintf (stderr, "setting colour tag\n"));
if (argc > 0 && argv[0]->type == ESEXP_RES_STRING) {
camel_tag_set (&p->info->user_tags, "colour", argv[0]->value.string);
- report_status(driver, FILTER_STATUS_ACTION, "Set colour to %s", argv[0]->value.string);
+ report_status (driver, FILTER_STATUS_ACTION, "Set colour to %s", argv[0]->value.string);
}
return NULL;
@@ -370,7 +405,7 @@ do_score (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *
value = g_strdup_printf ("%d", argv[0]->value.number);
camel_tag_set (&p->info->user_tags, "score", value);
- report_status(driver, FILTER_STATUS_ACTION, "Set score to %d", argv[0]->value.number);
+ report_status (driver, FILTER_STATUS_ACTION, "Set score to %d", argv[0]->value.number);
g_free (value);
}
@@ -439,28 +474,29 @@ free_key (gpointer key, gpointer value, gpointer user_data)
void
-filter_driver_status_log(FilterDriver *driver, enum filter_status_t status, const char *desc, CamelMimeMessage *msg, void *data)
+filter_driver_status_log (FilterDriver *driver, enum filter_status_t status,
+ const char *desc, CamelMimeMessage *msg, void *data)
{
FILE *out = data;
-
+
switch(status) {
case FILTER_STATUS_END: {
/* write log header */
time_t t;
char date[50];
- time(&t);
- strftime(date, 49, "%a, %d %b %Y %H:%M:%S", localtime(&t));
- fprintf(out, " - Applied filter \"%s\" to message from %s - \"%s\" at %s\n",
- desc, msg?camel_mime_message_get_from(msg):"unknown",
- msg?camel_mime_message_get_subject(msg):"", date);
+ time (&t);
+ strftime (date, 49, "%a, %d %b %Y %H:%M:%S", localtime (&t));
+ fprintf (out, " - Applied filter \"%s\" to message from %s - \"%s\" at %s\n",
+ desc, msg ? camel_mime_message_get_from (msg) : "unknown",
+ msg ? camel_mime_message_get_subject (msg) : "", date);
break;
}
case FILTER_STATUS_START:
- fprintf(out, "\n");
+ fprintf (out, "\n");
break;
case FILTER_STATUS_ACTION:
- fprintf(out, "Action: %s\n", desc);
+ fprintf (out, "Action: %s\n", desc);
break;
default:
/* nothing else is loggable */
@@ -471,61 +507,61 @@ filter_driver_status_log(FilterDriver *driver, enum filter_status_t status, cons
/* will filter only an mbox - is more efficient as it doesn't need to open the folder through camel directly */
void
-filter_driver_filter_mbox(FilterDriver *driver, const char *mbox, const char *source, CamelException *ex)
+filter_driver_filter_mbox (FilterDriver *driver, const char *mbox, const char *source, CamelException *ex)
{
- CamelMimeParser *mp =NULL;
+ CamelMimeParser *mp = NULL;
int fd = -1;
int i = 0;
struct stat st;
-
- fd = open(mbox, O_RDONLY);
+
+ fd = open (mbox, O_RDONLY);
if (fd == -1) {
- camel_exception_set(ex, CAMEL_EXCEPTION_SYSTEM, "Unable to open spool folder");
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, "Unable to open spool folder");
goto fail;
}
/* to get the filesize */
- fstat(fd, &st);
-
- mp = camel_mime_parser_new();
- camel_mime_parser_scan_from(mp, TRUE);
- if (camel_mime_parser_init_with_fd(mp, fd) == -1) {
- camel_exception_set(ex, CAMEL_EXCEPTION_SYSTEM, "Unable to process spool folder");
+ fstat (fd, &st);
+
+ mp = camel_mime_parser_new ();
+ camel_mime_parser_scan_from (mp, TRUE);
+ if (camel_mime_parser_init_with_fd (mp, fd) == -1) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, "Unable to process spool folder");
goto fail;
}
fd = -1;
- while (camel_mime_parser_step(mp, 0, 0) == HSCAN_FROM) {
+ while (camel_mime_parser_step (mp, 0, 0) == HSCAN_FROM) {
CamelMimeMessage *msg;
int pc;
-
- pc = camel_mime_parser_tell(mp) * 100 / st.st_size;
- report_status(driver, FILTER_STATUS_START, "Getting message %d (%d%% of file)", i, pc);
-
- msg = camel_mime_message_new();
- if (camel_mime_part_construct_from_parser((CamelMimePart *)msg, mp) == -1) {
- report_status(driver, FILTER_STATUS_END, "Failed message %d", i);
- camel_exception_set(ex, CAMEL_EXCEPTION_SYSTEM, "Cannot open message");
- camel_object_unref((CamelObject *)msg);
+
+ pc = camel_mime_parser_tell (mp) * 100 / st.st_size;
+ report_status (driver, FILTER_STATUS_START, "Getting message %d (%d%% of file)", i, pc);
+
+ msg = camel_mime_message_new ();
+ if (camel_mime_part_construct_from_parser (CAMEL_MIME_PART (msg), mp) == -1) {
+ report_status (driver, FILTER_STATUS_END, "Failed message %d", i);
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, "Cannot open message");
+ camel_object_unref (CAMEL_OBJECT (msg));
goto fail;
}
-
- filter_driver_filter_message(driver, msg, NULL, source, ex);
- camel_object_unref((CamelObject *)msg);
- if (camel_exception_is_set(ex)) {
- report_status(driver, FILTER_STATUS_END, "Failed message %d", i);
+
+ filter_driver_filter_message (driver, msg, NULL, source, ex);
+ camel_object_unref (CAMEL_OBJECT (msg));
+ if (camel_exception_is_set (ex)) {
+ report_status (driver, FILTER_STATUS_END, "Failed message %d", i);
goto fail;
}
-
- report_status(driver, FILTER_STATUS_END, "Finished message %d", i);
+
+ report_status (driver, FILTER_STATUS_END, "Finished message %d", i);
i++;
-
+
/* skip over the FROM_END state */
- camel_mime_parser_step(mp, 0, 0);
+ camel_mime_parser_step (mp, 0, 0);
}
fail:
if (fd != -1)
- close(fd);
+ close (fd);
if (mp)
- camel_object_unref((CamelObject *)mp);
+ camel_object_unref (CAMEL_OBJECT (mp));
}
/* will filter a folder */
@@ -574,7 +610,7 @@ filter_driver_filter_folder (FilterDriver *driver, CamelFolder *folder, const ch
camel_folder_free_uids (folder, uids);
}
-gboolean
+void
filter_driver_filter_message (FilterDriver *driver, CamelMimeMessage *message, CamelMessageInfo *info,
const char *source, CamelException *ex)
{
@@ -583,18 +619,21 @@ filter_driver_filter_message (FilterDriver *driver, CamelMimeMessage *message, C
GString *fsearch, *faction;
FilterFilter *rule;
int freeinfo = FALSE;
-
+
if (info == NULL) {
- struct _header_raw *h = CAMEL_MIME_PART(message)->headers;
-
- info = g_malloc0(sizeof(*info));
+ struct _header_raw *h = CAMEL_MIME_PART (message)->headers;
+
+ info = g_new0 (CamelMessageInfo, 1);
freeinfo = TRUE;
- info->subject = camel_folder_summary_format_string(h, "subject");
- info->from = camel_folder_summary_format_address(h, "from");
- info->to = camel_folder_summary_format_address(h, "to");
- info->cc = camel_folder_summary_format_address(h, "cc");
+ info->subject = camel_folder_summary_format_string (h, "subject");
+ info->from = camel_folder_summary_format_address (h, "from");
+ info->to = camel_folder_summary_format_address (h, "to");
+ info->cc = camel_folder_summary_format_address (h, "cc");
+ } else {
+ if (info->flags & CAMEL_MESSAGE_DELETED)
+ return;
}
-
+
p->ex = ex;
p->terminated = FALSE;
p->deleted = FALSE;
@@ -618,7 +657,7 @@ filter_driver_filter_message (FilterDriver *driver, CamelMimeMessage *message, C
d(fprintf (stderr, "applying rule %s\n action %s\n", fsearch->str, faction->str));
mail_tool_camel_lock_up ();
- matched = filter_message_search (p->message, p->info, fsearch->str, p->ex);
+ matched = filter_message_search (p->message, p->info, source, fsearch->str, p->ex);
mail_tool_camel_lock_down ();
if (matched) {
@@ -640,21 +679,19 @@ filter_driver_filter_message (FilterDriver *driver, CamelMimeMessage *message, C
if (!p->deleted && !p->copied && p->defaultfolder) {
/* copy it to the default inbox */
- report_status(driver, FILTER_STATUS_ACTION, "Copy to default folder");
+ report_status (driver, FILTER_STATUS_ACTION, "Copy to default folder");
mail_tool_camel_lock_up ();
camel_folder_append_message (p->defaultfolder, p->message, p->info, p->ex);
mail_tool_camel_lock_down ();
}
-
+
if (freeinfo) {
- camel_flag_list_free(&info->user_flags);
- camel_tag_list_free(&info->user_tags);
- g_free(info->subject);
- g_free(info->from);
- g_free(info->to);
- g_free(info->cc);
- g_free(info);
+ camel_flag_list_free (&info->user_flags);
+ camel_tag_list_free (&info->user_tags);
+ g_free (info->subject);
+ g_free (info->from);
+ g_free (info->to);
+ g_free (info->cc);
+ g_free (info);
}
-
- return p->copied;
}
diff --git a/filter/filter-driver.h b/filter/filter-driver.h
index 90a6db6a7b..1da1fc37ff 100644
--- a/filter/filter-driver.h
+++ b/filter/filter-driver.h
@@ -63,20 +63,21 @@ guint filter_driver_get_type (void);
FilterDriver *filter_driver_new (FilterContext *ctx, FilterGetFolderFunc fetcher, void *data);
/* modifiers */
-void filter_driver_set_status_func(FilterDriver *d, FDStatusFunc *func, void *data);
-void filter_driver_set_default_folder(FilterDriver *d, CamelFolder *def);
+void filter_driver_set_status_func (FilterDriver *d, FDStatusFunc *func, void *data);
+void filter_driver_set_default_folder (FilterDriver *d, CamelFolder *def);
/*void filter_driver_set_global(FilterDriver *, const char *name, const char *value);*/
/* filter a message - returns TRUE if the message was filtered into some location other than inbox */
-gboolean filter_driver_filter_message (FilterDriver *driver, CamelMimeMessage *message, CamelMessageInfo *info,
- const char *source, CamelException *ex);
-void filter_driver_filter_mbox (FilterDriver *driver, const char *mbox, const char *source, CamelException *ex);
-void filter_driver_filter_folder (FilterDriver *driver, CamelFolder *folder, const char *source,
- GPtrArray *uids, gboolean remove, CamelException *ex);
+void filter_driver_filter_message (FilterDriver *driver, CamelMimeMessage *message, CamelMessageInfo *info,
+ const char *source, CamelException *ex);
+void filter_driver_filter_mbox (FilterDriver *driver, const char *mbox, const char *source, CamelException *ex);
+void filter_driver_filter_folder (FilterDriver *driver, CamelFolder *folder, const char *source,
+ GPtrArray *uids, gboolean remove, CamelException *ex);
/* convenience function to log the status, data should be the FILE * of the logfile */
-void filter_driver_status_log(FilterDriver *driver, enum filter_status_t status, const char *desc, CamelMimeMessage *msg, void *data);
+void filter_driver_status_log (FilterDriver *driver, enum filter_status_t status,
+ const char *desc, CamelMimeMessage *msg, void *data);
#if 0
/* generate the search query/action string for a filter option */
diff --git a/filter/filter-element.c b/filter/filter-element.c
index 58e68350a4..40a9357598 100644
--- a/filter/filter-element.c
+++ b/filter/filter-element.c
@@ -28,6 +28,7 @@
#include "filter-colour.h"
#include "filter-datespec.h"
#include "filter-score.h"
+#include "filter-url.h"
#include "filter-folder.h"
static void xml_create(FilterElement *fe, xmlNodePtr node);
@@ -77,7 +78,7 @@ filter_element_class_init (FilterElementClass *class)
GtkObjectClass *object_class;
object_class = (GtkObjectClass *)class;
- parent_class = gtk_type_class(gtk_object_get_type ());
+ parent_class = gtk_type_class (gtk_object_get_type ());
object_class->finalize = filter_element_finalise;
@@ -87,17 +88,17 @@ filter_element_class_init (FilterElementClass *class)
/* signals */
- gtk_object_class_add_signals(object_class, signals, LAST_SIGNAL);
+ gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
}
static void
filter_element_init (FilterElement *o)
{
- o->priv = g_malloc0(sizeof(*o->priv));
+ o->priv = g_malloc0 (sizeof (*o->priv));
}
static void
-filter_element_finalise(GtkObject *obj)
+filter_element_finalise (GtkObject *obj)
{
FilterElement *o = (FilterElement *)obj;
@@ -114,7 +115,7 @@ filter_element_finalise(GtkObject *obj)
* Return value: A new #FilterElement object.
**/
FilterElement *
-filter_element_new(void)
+filter_element_new (void)
{
FilterElement *o = (FilterElement *)gtk_type_new(filter_element_get_type ());
return o;
@@ -122,106 +123,114 @@ filter_element_new(void)
/**
* filter_element_xml_create:
- * @fe:
- * @node:
+ * @fe: filter element
+ * @node: xml node
*
* Create a new filter element based on an xml definition of
* that element.
**/
-void filter_element_xml_create (FilterElement *fe, xmlNodePtr node)
+void
+filter_element_xml_create (FilterElement *fe, xmlNodePtr node)
{
return ((FilterElementClass *)((GtkObject *)fe)->klass)->xml_create(fe, node);
}
/**
* filter_element_xml_encode:
- * @fe:
+ * @fe: filter element
*
* Encode the values of a filter element into xml format.
*
* Return value:
**/
-xmlNodePtr filter_element_xml_encode (FilterElement *fe)
+xmlNodePtr
+filter_element_xml_encode (FilterElement *fe)
{
return ((FilterElementClass *)((GtkObject *)fe)->klass)->xml_encode(fe);
}
/**
* filter_element_xml_decode:
- * @fe:
- * @node:
+ * @fe: filter element
+ * @node: xml node
*
* Decode the values of a fitler element from xml format.
*
* Return value:
**/
-int filter_element_xml_decode (FilterElement *fe, xmlNodePtr node)
+int
+filter_element_xml_decode (FilterElement *fe, xmlNodePtr node)
{
return ((FilterElementClass *)((GtkObject *)fe)->klass)->xml_decode(fe, node);
}
/**
* filter_element_clone:
- * @fe:
+ * @fe: filter element
*
* Clones the FilterElement @fe.
*
* Return value:
**/
-FilterElement *filter_element_clone (FilterElement *fe)
+FilterElement *
+filter_element_clone (FilterElement *fe)
{
return ((FilterElementClass *)((GtkObject *)fe)->klass)->clone(fe);
}
/**
* filter_element_get_widget:
- * @fe:
- * @node:
+ * @fe: filter element
+ * @node: xml node
*
* Create a widget to represent this element.
*
* Return value:
**/
-GtkWidget *filter_element_get_widget (FilterElement *fe)
+GtkWidget *
+filter_element_get_widget (FilterElement *fe)
{
return ((FilterElementClass *)((GtkObject *)fe)->klass)->get_widget(fe);
}
/**
* filter_element_build_code:
- * @fe:
- * @out:
+ * @fe: filter element
+ * @out: output buffer
* @ff:
*
* Add the code representing this element to the output string @out.
**/
-void filter_element_build_code (FilterElement *fe, GString *out, struct _FilterPart *ff)
+void
+filter_element_build_code (FilterElement *fe, GString *out, struct _FilterPart *ff)
{
return ((FilterElementClass *)((GtkObject *)fe)->klass)->build_code(fe, out, ff);
}
/**
* filter_element_format_sexp:
- * @fe:
- * @out:
+ * @fe: filter element
+ * @out: output buffer
*
* Format the value(s) of this element in a method suitable for the context of
* sexp where it is used. Usually as space separated, double-quoted strings.
**/
-void filter_element_format_sexp (FilterElement *fe, GString *out)
+void
+filter_element_format_sexp (FilterElement *fe, GString *out)
{
return ((FilterElementClass *)((GtkObject *)fe)->klass)->format_sexp(fe, out);
}
/**
* filter_element_new_type_name:
- * @type:
+ * @type: filter element type
*
* Create a new filter element based on its type name.
*
* Return value:
**/
-FilterElement *filter_element_new_type_name (const char *type)
+FilterElement *
+filter_element_new_type_name (const char *type)
{
if (type == NULL)
return NULL;
@@ -243,6 +252,8 @@ FilterElement *filter_element_new_type_name (const char *type)
return (FilterElement *)filter_datespec_new ();
} else if (!strcmp (type, "score")) {
return (FilterElement *)filter_score_new ();
+ } else if (!strcmp (type, "url")) {
+ return (FilterElement *)filter_url_new ();
} else {
g_warning("Unknown filter type '%s'", type);
return 0;
@@ -250,20 +261,23 @@ FilterElement *filter_element_new_type_name (const char *type)
}
/* default implementations */
-static void xml_create(FilterElement *fe, xmlNodePtr node)
+static void
+xml_create (FilterElement *fe, xmlNodePtr node)
{
- fe->name = xmlGetProp(node, "name");
+ fe->name = xmlGetProp (node, "name");
}
-static FilterElement *clone(FilterElement *fe)
+static FilterElement *
+clone (FilterElement *fe)
{
xmlNodePtr node;
FilterElement *new;
- new = (FilterElement *)gtk_type_new( ((GtkObject *)fe)->klass->type );
- node = filter_element_xml_encode(fe);
- filter_element_xml_decode(new, node);
- xmlFreeNodeList(node);
+ new = (FilterElement *)gtk_type_new (GTK_OBJECT (fe)->klass->type);
+ node = filter_element_xml_encode (fe);
+ filter_element_xml_decode (new, node);
+ xmlFreeNodeList (node);
+
return new;
}
diff --git a/filter/filter-message-search.c b/filter/filter-message-search.c
index 4f351b0829..8b90e273e6 100644
--- a/filter/filter-message-search.c
+++ b/filter/filter-message-search.c
@@ -27,6 +27,7 @@
typedef struct {
CamelMimeMessage *message;
CamelMessageInfo *info;
+ const char *source;
CamelException *ex;
} FilterMessageSearch;
@@ -40,6 +41,7 @@ static ESExpResult *get_sent_date (struct _ESExp *f, int argc, struct _ESExpResu
static ESExpResult *get_received_date (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms);
static ESExpResult *get_current_date (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms);
static ESExpResult *get_score (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms);
+static ESExpResult *get_source (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms);
/* builtin functions */
static struct {
@@ -56,7 +58,8 @@ static struct {
{ "get-sent-date", (ESExpFunc *) get_sent_date, 0 },
{ "get-received-date", (ESExpFunc *) get_received_date, 0 },
{ "get-current-date", (ESExpFunc *) get_current_date, 0 },
- { "get-score", (ESExpFunc *) get_score, 0 }
+ { "get-score", (ESExpFunc *) get_score, 0 },
+ { "get-source", (ESExpFunc *) get_source, 0 },
};
static ESExpResult *
@@ -337,8 +340,20 @@ get_score (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessage
return r;
}
+static ESExpResult *
+get_source (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms)
+{
+ ESExpResult *r;
+
+ r = e_sexp_result_new (ESEXP_RES_STRING);
+ r->value.string = g_strdup (fms->source);
+
+ return r;
+}
+
gboolean
-filter_message_search (CamelMimeMessage *message, CamelMessageInfo *info, const char *expression, CamelException *ex)
+filter_message_search (CamelMimeMessage *message, CamelMessageInfo *info,
+ const char *source, const char *expression, CamelException *ex)
{
FilterMessageSearch *fms;
ESExp *sexp;
@@ -349,6 +364,7 @@ filter_message_search (CamelMimeMessage *message, CamelMessageInfo *info, const
fms = g_new (FilterMessageSearch, 1);
fms->message = message;
fms->info = info;
+ fms->source = source;
fms->ex = ex;
sexp = e_sexp_new ();
diff --git a/filter/filter-message-search.h b/filter/filter-message-search.h
index ce9cc57c52..453e888e54 100644
--- a/filter/filter-message-search.h
+++ b/filter/filter-message-search.h
@@ -34,7 +34,7 @@ extern "C" {
#include <camel-folder-summary.h>
gboolean filter_message_search (CamelMimeMessage *message, CamelMessageInfo *info,
- const char *expression, CamelException *ex);
+ const char *source, const char *expression, CamelException *ex);
#ifdef __cplusplus
}
diff --git a/filter/filter-url.c b/filter/filter-url.c
new file mode 100644
index 0000000000..f84470d934
--- /dev/null
+++ b/filter/filter-url.c
@@ -0,0 +1,225 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@helixcode.com>
+ *
+ * Copyright 2000 Helix Code, Inc. (www.helixcode.com)
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#include <gtk/gtk.h>
+#include <gnome.h>
+#include <gnome-xml/xmlmemory.h>
+
+#include "e-util/e-sexp.h"
+#include "filter-url.h"
+/*#include "mail/mail-config.h"*/
+
+#define d(x)
+
+static void xml_create (FilterElement *fe, xmlNodePtr node);
+static xmlNodePtr xml_encode (FilterElement *fe);
+static int xml_decode (FilterElement *fe, xmlNodePtr node);
+static GtkWidget *get_widget (FilterElement *fe);
+static void build_code (FilterElement *fe, GString *out, struct _FilterPart *ff);
+static void format_sexp (FilterElement *, GString *);
+
+static void filter_url_class_init (FilterUrlClass *class);
+static void filter_url_init (FilterUrl *gspaper);
+static void filter_url_finalise (GtkObject *obj);
+
+#define _PRIVATE(x) (((FilterUrl *)(x))->priv)
+
+struct _FilterUrlPrivate {
+};
+
+static FilterElementClass *parent_class;
+
+enum {
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+guint
+filter_url_get_type (void)
+{
+ static guint type = 0;
+
+ if (!type) {
+ GtkTypeInfo type_info = {
+ "FilterUrl",
+ sizeof (FilterUrl),
+ sizeof (FilterUrlClass),
+ (GtkClassInitFunc) filter_url_class_init,
+ (GtkObjectInitFunc) filter_url_init,
+ (GtkArgSetFunc) NULL,
+ (GtkArgGetFunc) NULL
+ };
+
+ type = gtk_type_unique (filter_element_get_type (), &type_info);
+ }
+
+ return type;
+}
+
+static void
+filter_url_class_init (FilterUrlClass *class)
+{
+ GtkObjectClass *object_class;
+ FilterElementClass *filter_element = (FilterElementClass *)class;
+
+ object_class = (GtkObjectClass *) class;
+ parent_class = gtk_type_class (filter_element_get_type ());
+
+ object_class->finalize = filter_url_finalise;
+
+ /* override methods */
+ filter_element->xml_create = xml_create;
+ filter_element->xml_encode = xml_encode;
+ filter_element->xml_decode = xml_decode;
+ filter_element->get_widget = get_widget;
+ filter_element->build_code = build_code;
+ filter_element->format_sexp = format_sexp;
+
+ /* signals */
+
+ gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+}
+
+static void
+filter_url_init (FilterUrl *o)
+{
+ o->priv = g_malloc0 (sizeof (*o->priv));
+}
+
+static void
+filter_url_finalise (GtkObject *obj)
+{
+ FilterUrl *o = (FilterUrl *)obj;
+
+ o = o;
+
+ ((GtkObjectClass *)(parent_class))->finalize (obj);
+}
+
+/**
+ * filter_url_new:
+ *
+ * Create a new FilterUrl object.
+ *
+ * Return value: A new #FilterUrl object.
+ **/
+FilterUrl *
+filter_url_new (void)
+{
+ FilterUrl *o = (FilterUrl *) gtk_type_new (filter_url_get_type ());
+
+ return o;
+}
+
+static void
+xml_create (FilterElement *fe, xmlNodePtr node)
+{
+ /*FilterUrl *fu = (FilterUrl *)fe;*/
+
+ /* parent implementation */
+ ((FilterElementClass *)(parent_class))->xml_create (fe, node);
+}
+
+static xmlNodePtr
+xml_encode (FilterElement *fe)
+{
+ xmlNodePtr value;
+ FilterUrl *fu = (FilterUrl *)fe;
+
+ d(printf ("Encoding url as xml\n"));
+ value = xmlNewNode (NULL, "value");
+ xmlSetProp (value, "name", fe->name);
+ xmlSetProp (value, "type", "url");
+
+ xmlSetProp (value, "url", fu->url);
+
+ return value;
+}
+
+static gchar *
+get_value (xmlNodePtr node, char *name)
+{
+ gchar *value;
+
+ value = xmlGetProp (node, name);
+
+ return value;
+}
+
+
+static int
+xml_decode (FilterElement *fe, xmlNodePtr node)
+{
+ FilterUrl *fu = (FilterUrl *)fe;
+
+ fe->name = xmlGetProp (node, "name");
+ fu->url = get_value (node, "url");
+
+ return 0;
+}
+
+static void
+set_url (GtkWidget *entry, FilterUrl *fu)
+{
+ fu->url = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+}
+
+static GtkWidget *
+get_widget (FilterElement *fe)
+{
+ GtkWidget *combo;
+ GList *sources;
+ GSList *s;
+
+ combo = gtk_combo_new ();
+ /*s = mail_config_get_sources ();
+ sources = NULL;
+ while (s) {
+ MailConfigService *service = s->data;
+ sources = g_list_append (sources, service->url);
+ s = s->next;
+ }
+ gtk_combo_set_popdown_strings (GTK_COMBO (combo), sources);
+ g_list_free (sources);
+ */
+
+ gtk_widget_show (combo);
+ gtk_signal_connect (GTK_OBJECT (GTK_EDITABLE (GTK_COMBO (combo)->entry)), "changed", set_url, fe);
+
+ return combo;
+}
+
+static void
+build_code (FilterElement *fe, GString *out, struct _FilterPart *ff)
+{
+ return;
+}
+
+static void
+format_sexp (FilterElement *fe, GString *out)
+{
+ FilterUrl *fu = (FilterUrl *)fe;
+
+ e_sexp_encode_string (out, fu->url);
+}
diff --git a/filter/filter-url.h b/filter/filter-url.h
new file mode 100644
index 0000000000..be27efa6e5
--- /dev/null
+++ b/filter/filter-url.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@helixcode.com>
+ *
+ * Copyright 2000 Helix Code, Inc. (www.helixcode.com)
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef _FILTER_URL_H
+#define _FILTER_URL_H
+
+#include <gtk/gtk.h>
+#include "filter-element.h"
+
+#define FILTER_URL(obj) GTK_CHECK_CAST (obj, filter_url_get_type (), FilterUrl)
+#define FILTER_URL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, filter_url_get_type (), FilterUrlClass)
+#define IS_FILTER_URL(obj) GTK_CHECK_TYPE (obj, filter_url_get_type ())
+
+typedef struct _FilterUrl FilterUrl;
+typedef struct _FilterUrlClass FilterUrlClass;
+
+struct _FilterUrl {
+ FilterElement parent;
+ struct _FilterUrlPrivate *priv;
+
+ gchar *url;
+};
+
+struct _FilterUrlClass {
+ FilterElementClass parent_class;
+
+ /* virtual methods */
+
+ /* signals */
+};
+
+guint filter_url_get_type (void);
+FilterUrl *filter_url_new (void);
+
+/* methods */
+
+#endif /* ! _FILTER_URL_H */
+
diff --git a/filter/filtertypes.xml b/filter/filtertypes.xml
index 43a6043124..1b869bd577 100644
--- a/filter/filtertypes.xml
+++ b/filter/filtertypes.xml
@@ -197,6 +197,26 @@
</input>
</part>
+ <part name="source">
+ <title>Source</title>
+ <input type="optionlist" name="url-type">
+ <option value="is">
+ <title>is</title>
+ <code>
+ (match-all (= (get-source) ${source}))
+ </code>
+ </option>
+ <option value="is-not">
+ <title>is not</title>
+ <code>
+ (match-all (not (= (get-source) ${source})))
+ </code>
+ </option>
+ </input>
+ <input type="url" name="source">
+ </input>
+ </part>
+
</partset>
@@ -206,8 +226,13 @@
<code>(copy-to ${folder})</code>
<input type="folder" name="folder"/>
</part>
+ <part name="move-to-folder">
+ <title>Move to Folder</title>
+ <code>(move-to ${folder})</code>
+ <input type="folder" name="folder"/>
+ </part>
<part name="forward-to">
- <title>Forward to address</title>
+ <title>Forward to Address</title>
<code>(forward-to ${address})</code>
<input type="address" name="address"/>
</part>
@@ -216,7 +241,7 @@
<code>(delete)</code>
</part>
<part name="stop">
- <title>Stop processing</title>
+ <title>Stop Processing</title>
<code>(stop)</code>
</part>
<part name="colour">