diff options
-rw-r--r-- | filter/ChangeLog | 18 | ||||
-rw-r--r-- | filter/filter-element.c | 16 | ||||
-rw-r--r-- | filter/filter-element.h | 5 | ||||
-rw-r--r-- | filter/filter-input.c | 72 | ||||
-rw-r--r-- | filter/filter-option.c | 7 | ||||
-rw-r--r-- | filter/filter-part.c | 19 | ||||
-rw-r--r-- | filter/filter-part.h | 2 | ||||
-rw-r--r-- | filter/filter-rule.c | 11 | ||||
-rw-r--r-- | filter/filtertypes.xml | 4 |
9 files changed, 139 insertions, 15 deletions
diff --git a/filter/ChangeLog b/filter/ChangeLog index a43dce3f0d..bfa9886c53 100644 --- a/filter/ChangeLog +++ b/filter/ChangeLog @@ -1,5 +1,23 @@ 2000-10-30 Jeffrey Stedfast <fejj@helixcode.com> + * filter-option.c (option_activate): If a regex option is + selected, change the FilterElement data to TRUE else set to FALSE. + + * filter-rule.c (more_parts): Validate the previously entered + FilterPart before allowing the user to add a new FilterPart. + + * filter-part.c (filter_part_validate): New convenience function + to validate an entire FilterPart expression. + + * filter-input.c (validate): Validate the entry text if it + contains a regular expression. + + * filter-element.[c,h]: New virtual function to validate the + contents of the FilterElement (useful for regex and sexp). + (filter_element_validate): You get the idea... + +2000-10-30 Jeffrey Stedfast <fejj@helixcode.com> + * filter-input.c: * filter-option.c: * filter-part.c: Pure formatting changes, no actual code diff --git a/filter/filter-element.c b/filter/filter-element.c index 21df744fe5..ad6e133a6a 100644 --- a/filter/filter-element.c +++ b/filter/filter-element.c @@ -31,6 +31,7 @@ #include "filter-folder.h" #include "filter-url.h" +static gboolean validate (FilterElement *fe, gpointer data); static void xml_create(FilterElement *fe, xmlNodePtr node); static FilterElement *clone(FilterElement *fe); @@ -83,6 +84,7 @@ filter_element_class_init (FilterElementClass *class) object_class->finalize = filter_element_finalise; /* override methods */ + class->validate = validate; class->xml_create = xml_create; class->clone = clone; @@ -121,6 +123,12 @@ filter_element_new (void) return o; } +gboolean +filter_element_validate (FilterElement *fe, gpointer data) +{ + return ((FilterElementClass *)((GtkObject *)fe)->klass)->validate (fe, data); +} + /** * filter_element_xml_create: * @fe: filter element @@ -261,6 +269,12 @@ filter_element_new_type_name (const char *type) } /* default implementations */ +static gboolean +validate (FilterElement *fe, gpointer data) +{ + return TRUE; +} + static void xml_create (FilterElement *fe, xmlNodePtr node) { @@ -280,5 +294,3 @@ clone (FilterElement *fe) return new; } - - diff --git a/filter/filter-element.h b/filter/filter-element.h index 8fe82402ee..ce5290c3cb 100644 --- a/filter/filter-element.h +++ b/filter/filter-element.h @@ -36,6 +36,7 @@ struct _FilterElement { struct _FilterElementPrivate *priv; char *name; + gpointer data; }; struct _FilterPart; @@ -44,6 +45,8 @@ struct _FilterElementClass { GtkObjectClass parent_class; /* virtual methods */ + gboolean (*validate)(FilterElement *fe, gpointer data); + void (*xml_create)(FilterElement *, xmlNodePtr); xmlNodePtr (*xml_encode)(FilterElement *); int (*xml_decode)(FilterElement *, xmlNodePtr); @@ -63,6 +66,8 @@ FilterElement *filter_element_new (void); FilterElement *filter_element_new_type_name (const char *type); /* methods */ +gboolean filter_element_validate (FilterElement *fe, gpointer data); + void filter_element_xml_create (FilterElement *fe, xmlNodePtr node); xmlNodePtr filter_element_xml_encode (FilterElement *fe); diff --git a/filter/filter-input.c b/filter/filter-input.c index 2ef4327c33..fcee83a9eb 100644 --- a/filter/filter-input.c +++ b/filter/filter-input.c @@ -20,6 +20,7 @@ #include <gtk/gtk.h> #include <gnome.h> +#include <regex.h> #include <gal/widgets/e-unicode.h> @@ -28,6 +29,7 @@ #define d(x) +static gboolean validate (FilterElement *fe, gpointer data); static void xml_create(FilterElement *fe, xmlNodePtr node); static xmlNodePtr xml_encode(FilterElement *fe); static int xml_decode(FilterElement *fe, xmlNodePtr node); @@ -86,6 +88,7 @@ filter_input_class_init (FilterInputClass *class) object_class->finalize = filter_input_finalise; /* override methods */ + filter_element->validate = validate; filter_element->xml_create = xml_create; filter_element->xml_encode = xml_encode; filter_element->xml_decode = xml_decode; @@ -101,16 +104,16 @@ filter_input_class_init (FilterInputClass *class) static void filter_input_init (FilterInput *o) { - o->priv = g_malloc0(sizeof(*o->priv)); + o->priv = g_malloc0 (sizeof (*o->priv)); } static void -filter_input_finalise(GtkObject *obj) +filter_input_finalise (GtkObject *obj) { FilterInput *o = (FilterInput *)obj; - + o = o; - + ((GtkObjectClass *)(parent_class))->finalize(obj); } @@ -131,8 +134,8 @@ filter_input_new (void) FilterInput * filter_input_new_type_name (const char *type) { - FilterInput *o = filter_input_new(); - o->type = g_strdup(type); + FilterInput *o = filter_input_new (); + o->type = g_strdup (type); d(printf("new type %s = %p\n", type, o)); return o; @@ -142,15 +145,62 @@ void filter_input_set_value (FilterInput *fi, const char *value) { GList *l; - + l = fi->values; while (l) { - g_free(l->data); - l = g_list_next(l); + g_free (l->data); + l = g_list_next (l); } - g_list_free(fi->values); + g_list_free (fi->values); + + fi->values = g_list_append (NULL, g_strdup (value)); +} - fi->values = g_list_append(NULL, g_strdup(value)); +static gboolean +validate (FilterElement *fe, gpointer data) +{ + FilterInput *fi = (FilterInput *)fe; + gboolean is_regex = FALSE; + gboolean valid = TRUE; + + if (data) + is_regex = GPOINTER_TO_INT (data); + + if (is_regex) { + regex_t regexpat; /* regex patern */ + gint regerr; + char *text; + + text = fi->values->data; + + regerr = regcomp (®expat, text, REG_EXTENDED | REG_NEWLINE | REG_ICASE); + if (regerr) { + GtkWidget *dialog; + gchar *regmsg, *errmsg; + size_t reglen; + + /* regerror gets called twice to get the full error string + length to do proper posix error reporting */ + reglen = regerror (regerr, ®expat, 0, 0); + regmsg = g_malloc0 (reglen + 1); + regerror (regerr, ®expat, regmsg, reglen); + + errmsg = g_strdup_printf (_("Error in regular expression '%s':\n%s"), + text, regmsg); + g_free (regmsg); + + dialog = gnome_ok_dialog (errmsg); + + gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); + + g_free (errmsg); + valid = FALSE; + } + + regfree (®expat); + } + + return valid; } static void diff --git a/filter/filter-option.c b/filter/filter-option.c index 10ac977a1d..bdac9288d3 100644 --- a/filter/filter-option.c +++ b/filter/filter-option.c @@ -234,8 +234,15 @@ xml_decode (FilterElement *fe, xmlNodePtr node) static void option_activate (GtkMenuItem *item, FilterOption *fo) { + FilterElement *fe = (FilterElement *) fo; + gboolean is_regex; + fo->current = gtk_object_get_data (GTK_OBJECT (item), "option"); d(printf ("option changed to %s\n", fo->current->title)); + + /* FIXME: there's probably a better way to do this */ + is_regex = !(!strstr (fo->current->title, "regex")); + fe->data = GINT_TO_POINTER (is_regex); } static GtkWidget * diff --git a/filter/filter-part.c b/filter/filter-part.c index a467a0c3c0..f32ed517c7 100644 --- a/filter/filter-part.c +++ b/filter/filter-part.c @@ -113,6 +113,25 @@ filter_part_new (void) return o; } +gboolean +filter_part_validate (FilterPart *fp) +{ + gboolean correct = TRUE; + FilterElement *last = NULL; + GList *l; + + l = fp->elements; + while (l && correct) { + FilterElement *fe = l->data; + + correct = filter_element_validate (fe, last ? last->data : NULL); + + last = fe; + l = l->next; + } + + return correct; +} int filter_part_xml_create (FilterPart *ff, xmlNodePtr node) diff --git a/filter/filter-part.h b/filter/filter-part.h index 2995046b20..bc9424486b 100644 --- a/filter/filter-part.h +++ b/filter/filter-part.h @@ -53,6 +53,8 @@ guint filter_part_get_type (void); FilterPart *filter_part_new (void); /* methods */ +gboolean filter_part_validate (FilterPart *fp); + int filter_part_xml_create (FilterPart *ff, xmlNodePtr node); xmlNodePtr filter_part_xml_encode (FilterPart *fe); diff --git a/filter/filter-rule.c b/filter/filter-rule.c index 51e474aa72..a33373af5e 100644 --- a/filter/filter-rule.c +++ b/filter/filter-rule.c @@ -458,6 +458,17 @@ more_parts (GtkWidget *button, struct _rule_data *data) FilterPart *new; GtkWidget *w; + /* first make sure that the last part is ok */ + if (data->fr->parts) { + FilterPart *part; + GList *l; + + l = g_list_last (data->fr->parts); + part = l->data; + if (!filter_part_validate (part)) + return; + } + /* create a new rule entry, use the first type of rule */ new = rule_context_next_part (data->f, NULL); if (new) { diff --git a/filter/filtertypes.xml b/filter/filtertypes.xml index 925593e402..07846d731c 100644 --- a/filter/filtertypes.xml +++ b/filter/filtertypes.xml @@ -52,13 +52,13 @@ (match-all (not (header-ends-with "From" ${sender}))) </code> </option> - <option value="matches regex" type="regex"> + <option value="matches regex"> <title>matches regex</title> <code> (match-all (header-regex "From" ${sender})) </code> </option> - <option value="not match regex" type="regex"> + <option value="not match regex"> <title>does not match regex</title> <code> (match-all (not (header-regex "From" ${sender}))) |