diff options
-rw-r--r-- | filter/ChangeLog | 31 | ||||
-rw-r--r-- | filter/Makefile.am | 3 | ||||
-rw-r--r-- | filter/filter-driver.c | 205 | ||||
-rw-r--r-- | filter/filter-driver.h | 17 | ||||
-rw-r--r-- | filter/filter-element.c | 80 | ||||
-rw-r--r-- | filter/filter-message-search.c | 20 | ||||
-rw-r--r-- | filter/filter-message-search.h | 2 | ||||
-rw-r--r-- | filter/filter-url.c | 225 | ||||
-rw-r--r-- | filter/filter-url.h | 58 | ||||
-rw-r--r-- | filter/filtertypes.xml | 29 |
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"> |