aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filter/ChangeLog25
-rw-r--r--filter/Makefile.am2
-rw-r--r--filter/filter-colour.c14
-rw-r--r--filter/filter-datespec.c12
-rw-r--r--filter/filter-element.c18
-rw-r--r--filter/filter-element.h4
-rw-r--r--filter/filter-file.c14
-rw-r--r--filter/filter-filter.c25
-rw-r--r--filter/filter-folder.c9
-rw-r--r--filter/filter-input.c26
-rw-r--r--filter/filter-int.c70
-rw-r--r--filter/filter-int.h9
-rw-r--r--filter/filter-label.c95
-rw-r--r--filter/filter-label.h10
-rw-r--r--filter/filter-option.c12
-rw-r--r--filter/filter-part.c29
-rw-r--r--filter/filter-part.h1
-rw-r--r--filter/filter-rule.c39
-rw-r--r--filter/filter-rule.h2
-rw-r--r--filter/filter-source.c12
-rw-r--r--filter/libfilter-i18n.h36
-rw-r--r--filter/rule-context.c144
-rw-r--r--filter/rule-context.h2
-rw-r--r--filter/vfolder-rule.c25
24 files changed, 496 insertions, 139 deletions
diff --git a/filter/ChangeLog b/filter/ChangeLog
index 84448c091f..dabe4cdccf 100644
--- a/filter/ChangeLog
+++ b/filter/ChangeLog
@@ -1,3 +1,28 @@
+2002-07-10 Not Zed <NotZed@Ximian.com>
+
+ ** fixes for #10781
+
+ * filter-int.c (xml_encode):
+ (xml_decode): Handle encoding/decoding with a type name, in a
+ manner compatible with the score/label elemtns.
+ (filter_int_new_type): New constructor to create a generic 'int'
+ type.
+
+ * filter-score.c: Removed. Now relies on using a filter-int with
+ appropriate settings.
+
+ * filter-label.[ch]: Now inherits from filter-int.
+
+ * rule-context.c (rule_context_revert): New method to revert a
+ filter context back to a user-file's definition.
+ (revert): implementation.
+
+ * filter-rule.h: Added new virtual method _eq and wrapper, and
+ fixed all subclasses to implement it.
+
+ * filter-element.h: Added new virtual method _eq and wrapper.
+ Fixed all subclasses to implement it.
+
2002-07-08 Jeffrey Stedfast <fejj@ximian.com>
* filtertypes.xml: Make the sound type for (play-sound ) a "file"
diff --git a/filter/Makefile.am b/filter/Makefile.am
index 1a3e5d2d74..d832c3b1e0 100644
--- a/filter/Makefile.am
+++ b/filter/Makefile.am
@@ -48,8 +48,6 @@ libfilter_la_SOURCES = \
filter-part.h \
filter-rule.c \
filter-rule.h \
- filter-score.c \
- filter-score.h \
filter-source.h \
filter-source.c \
rule-context.c \
diff --git a/filter/filter-colour.c b/filter/filter-colour.c
index 0836c30932..2a3f68b887 100644
--- a/filter/filter-colour.c
+++ b/filter/filter-colour.c
@@ -30,6 +30,7 @@
#define d(x)
+static int colour_eq(FilterElement *fe, FilterElement *cm);
static void xml_create(FilterElement *fe, xmlNodePtr node);
static xmlNodePtr xml_encode(FilterElement *fe);
static int xml_decode(FilterElement *fe, xmlNodePtr node);
@@ -88,6 +89,7 @@ filter_colour_class_init (FilterColourClass *class)
object_class->finalize = filter_colour_finalise;
/* override methods */
+ filter_element->eq = colour_eq;
filter_element->xml_create = xml_create;
filter_element->xml_encode = xml_encode;
filter_element->xml_decode = xml_decode;
@@ -130,6 +132,18 @@ filter_colour_new(void)
return o;
}
+static int
+colour_eq(FilterElement *fe, FilterElement *cm)
+{
+ FilterColour *fc = (FilterColour *)fe, *cc = (FilterColour *)cm;
+
+ return ((FilterElementClass *)(parent_class))->eq(fe, cm)
+ && fc->r == cc->r
+ && fc->g == cc->g
+ && fc->b == cc->b
+ && fc->a == cc->a;
+}
+
static void xml_create(FilterElement *fe, xmlNodePtr node)
{
/*FilterColour *fc = (FilterColour *)fe;*/
diff --git a/filter/filter-datespec.c b/filter/filter-datespec.c
index fe4e5e3b32..dd8f02614e 100644
--- a/filter/filter-datespec.c
+++ b/filter/filter-datespec.c
@@ -46,6 +46,7 @@
#define d(x)
static gboolean validate (FilterElement *fe);
+static int date_eq(FilterElement *fe, FilterElement *cm);
static void xml_create (FilterElement *fe, xmlNodePtr node);
static xmlNodePtr xml_encode (FilterElement *fe);
static int xml_decode (FilterElement *fe, xmlNodePtr node);
@@ -138,6 +139,7 @@ filter_datespec_class_init (FilterDatespecClass *class)
/* override methods */
filter_element->validate = validate;
+ filter_element->eq = date_eq;
filter_element->xml_create = xml_create;
filter_element->xml_encode = xml_encode;
filter_element->xml_decode = xml_decode;
@@ -201,6 +203,16 @@ validate (FilterElement *fe)
return valid;
}
+static int
+date_eq(FilterElement *fe, FilterElement *cm)
+{
+ FilterDatespec *fd = (FilterDatespec *)fe, *cd = (FilterDatespec *)cm;
+
+ return ((FilterElementClass *)(parent_class))->eq(fe, cm)
+ && (fd->type == cd->type)
+ && (fd->value == cd->value);
+}
+
static void
xml_create (FilterElement *fe, xmlNodePtr node)
{
diff --git a/filter/filter-element.c b/filter/filter-element.c
index cbdab0409f..fa1a6844f9 100644
--- a/filter/filter-element.c
+++ b/filter/filter-element.c
@@ -41,6 +41,7 @@
static gboolean validate (FilterElement *fe);
+static int element_eq(FilterElement *fe, FilterElement *cm);
static void xml_create(FilterElement *fe, xmlNodePtr node);
static FilterElement *clone(FilterElement *fe);
@@ -94,6 +95,7 @@ filter_element_class_init (FilterElementClass *class)
/* override methods */
class->validate = validate;
+ class->eq = element_eq;
class->xml_create = xml_create;
class->clone = clone;
@@ -138,6 +140,13 @@ filter_element_validate (FilterElement *fe)
return ((FilterElementClass *)((GtkObject *)fe)->klass)->validate (fe);
}
+int
+filter_element_eq(FilterElement *fe, FilterElement *cm)
+{
+ return ((GtkObject *)fe)->klass == ((GtkObject *)cm)->klass
+ && ((FilterElementClass *)((GtkObject *)fe)->klass)->eq(fe, cm);
+}
+
/**
* filter_element_xml_create:
* @fe: filter element
@@ -268,7 +277,7 @@ filter_element_new_type_name (const char *type)
} else if (!strcmp (type, "datespec")) {
return (FilterElement *)filter_datespec_new ();
} else if (!strcmp (type, "score")) {
- return (FilterElement *)filter_score_new ();
+ return (FilterElement *)filter_int_new_type("score", -3, 3);
} else if (!strcmp (type, "integer")) {
return (FilterElement *)filter_int_new ();
} else if (!strcmp (type, "regex")) {
@@ -300,6 +309,13 @@ validate (FilterElement *fe)
return TRUE;
}
+static int
+element_eq(FilterElement *fe, FilterElement *cm)
+{
+ return ((fe->name && cm->name && strcmp(fe->name, cm->name) == 0)
+ || (fe->name == NULL && cm->name == NULL));
+}
+
static void
xml_create (FilterElement *fe, xmlNodePtr node)
{
diff --git a/filter/filter-element.h b/filter/filter-element.h
index d5ff5177ce..f6570ef98d 100644
--- a/filter/filter-element.h
+++ b/filter/filter-element.h
@@ -48,7 +48,8 @@ struct _FilterElementClass {
/* virtual methods */
gboolean (*validate)(FilterElement *fe);
-
+ int (*eq)(FilterElement *fe, FilterElement *cm);
+
void (*xml_create)(FilterElement *, xmlNodePtr);
xmlNodePtr (*xml_encode)(FilterElement *);
int (*xml_decode)(FilterElement *, xmlNodePtr);
@@ -71,6 +72,7 @@ void filter_element_set_data (FilterElement *fe, gpointer data);
/* methods */
gboolean filter_element_validate (FilterElement *fe);
+int filter_element_eq (FilterElement *fe, FilterElement *cm);
void filter_element_xml_create (FilterElement *fe, xmlNodePtr node);
diff --git a/filter/filter-file.c b/filter/filter-file.c
index 7a0d1468e6..b34dd0f773 100644
--- a/filter/filter-file.c
+++ b/filter/filter-file.c
@@ -44,6 +44,7 @@
#define d(x)
static gboolean validate (FilterElement *fe);
+static int file_eq(FilterElement *fe, FilterElement *cm);
static void xml_create(FilterElement *fe, xmlNodePtr node);
static xmlNodePtr xml_encode(FilterElement *fe);
static int xml_decode(FilterElement *fe, xmlNodePtr node);
@@ -102,6 +103,7 @@ filter_file_class_init (FilterFileClass *klass)
/* override methods */
filter_element->validate = validate;
+ filter_element->eq = file_eq;
filter_element->xml_create = xml_create;
filter_element->xml_encode = xml_encode;
filter_element->xml_decode = xml_decode;
@@ -197,6 +199,18 @@ validate (FilterElement *fe)
return TRUE;
}
+static int
+file_eq(FilterElement *fe, FilterElement *cm)
+{
+ FilterFile *ff = (FilterFile *)fe, *cf = (FilterFile *)cm;
+
+ return ((FilterElementClass *)(parent_class))->eq(fe, cm)
+ && ((ff->path && cf->path && strcmp(ff->path, cf->path) == 0)
+ || (ff->path == NULL && cf->path == NULL))
+ && ((ff->type && cf->type && strcmp(ff->type, cf->type) == 0)
+ || (ff->type == NULL && cf->type == NULL));
+}
+
static void
xml_create (FilterElement *fe, xmlNodePtr node)
{
diff --git a/filter/filter-filter.c b/filter/filter-filter.c
index 199018da6c..0aae6b9805 100644
--- a/filter/filter-filter.c
+++ b/filter/filter-filter.c
@@ -40,6 +40,7 @@
#define d(x)
static int validate(FilterRule *);
+static int filter_eq(FilterRule *fr, FilterRule *cm);
static xmlNodePtr xml_encode (FilterRule *);
static int xml_decode (FilterRule *, xmlNodePtr, struct _RuleContext *f);
static void rule_copy (FilterRule *dest, FilterRule *src);
@@ -98,6 +99,7 @@ filter_filter_class_init (FilterFilterClass *class)
/* override methods */
filter_rule->validate = validate;
+ filter_rule->eq = filter_eq;
filter_rule->xml_encode = xml_encode;
filter_rule->xml_decode = xml_decode;
/*filter_rule->build_code = build_code;*/
@@ -206,6 +208,29 @@ validate(FilterRule *fr)
return valid;
}
+static int
+list_eq(GList *al, GList *bl)
+{
+ int truth = TRUE;
+
+ while (truth && al && bl) {
+ FilterPart *a = al->data, *b = bl->data;
+
+ truth = filter_part_eq(a, b);
+ al = al->next;
+ bl = bl->next;
+ }
+
+ return truth && al == NULL && bl == NULL;
+}
+
+static int
+filter_eq(FilterRule *fr, FilterRule *cm)
+{
+ return ((FilterRuleClass *)(parent_class))->eq(fr, cm)
+ && list_eq(((FilterFilter *)fr)->actions, ((FilterFilter *)cm)->actions);
+}
+
static xmlNodePtr
xml_encode (FilterRule *fr)
{
diff --git a/filter/filter-folder.c b/filter/filter-folder.c
index 100b4fe253..935e19df0f 100644
--- a/filter/filter-folder.c
+++ b/filter/filter-folder.c
@@ -34,6 +34,7 @@
#define d(x)
static gboolean validate (FilterElement *fe);
+static int folder_eq(FilterElement *fe, FilterElement *cm);
static void xml_create(FilterElement *fe, xmlNodePtr node);
static xmlNodePtr xml_encode(FilterElement *fe);
static int xml_decode(FilterElement *fe, xmlNodePtr node);
@@ -89,6 +90,7 @@ filter_folder_class_init (FilterFolderClass *class)
/* override methods */
filter_element->validate = validate;
+ filter_element->eq = folder_eq;
filter_element->xml_create = xml_create;
filter_element->xml_encode = xml_encode;
filter_element->xml_decode = xml_decode;
@@ -153,6 +155,13 @@ validate (FilterElement *fe)
}
}
+static int
+folder_eq(FilterElement *fe, FilterElement *cm)
+{
+ return ((FilterElementClass *)(parent_class))->eq(fe, cm)
+ && strcmp(((FilterFolder *)fe)->uri, ((FilterFolder *)cm)->uri) == 0;
+}
+
static void
xml_create (FilterElement *fe, xmlNodePtr node)
{
diff --git a/filter/filter-input.c b/filter/filter-input.c
index 8343abbfa8..9be03e66c1 100644
--- a/filter/filter-input.c
+++ b/filter/filter-input.c
@@ -40,6 +40,7 @@
#define d(x)
static gboolean validate (FilterElement *fe);
+static int input_eq(FilterElement *fe, FilterElement *cm);
static void xml_create(FilterElement *fe, xmlNodePtr node);
static xmlNodePtr xml_encode(FilterElement *fe);
static int xml_decode(FilterElement *fe, xmlNodePtr node);
@@ -99,6 +100,7 @@ filter_input_class_init (FilterInputClass *class)
/* override methods */
filter_element->validate = validate;
+ filter_element->eq = input_eq;
filter_element->xml_create = xml_create;
filter_element->xml_encode = xml_encode;
filter_element->xml_decode = xml_decode;
@@ -213,6 +215,30 @@ validate (FilterElement *fe)
return valid;
}
+static int
+list_eq(GList *al, GList *bl)
+{
+ int truth = TRUE;
+
+ while (truth && al && bl) {
+ truth = strcmp((char *)al->data, (char *)bl->data) == 0;
+ al = al->next;
+ bl = bl->next;
+ }
+
+ return truth && al == NULL && bl == NULL;
+}
+
+static int
+input_eq(FilterElement *fe, FilterElement *cm)
+{
+ FilterInput *fi = (FilterInput *)fe, *ci = (FilterInput *)cm;
+
+ return ((FilterElementClass *)(parent_class))->eq(fe, cm)
+ && strcmp(fi->type, ci->type) == 0
+ && list_eq(fi->values, ci->values);
+}
+
static void
xml_create (FilterElement *fe, xmlNodePtr node)
{
diff --git a/filter/filter-int.c b/filter/filter-int.c
index 25d70e43e2..a92b0b1b2b 100644
--- a/filter/filter-int.c
+++ b/filter/filter-int.c
@@ -32,6 +32,7 @@
#define d(x)
+static int int_eq(FilterElement *fe, FilterElement *cm);
static void xml_create (FilterElement *fe, xmlNodePtr node);
static xmlNodePtr xml_encode (FilterElement *fe);
static int xml_decode (FilterElement *fe, xmlNodePtr node);
@@ -90,6 +91,7 @@ filter_int_class_init (FilterIntClass *class)
object_class->finalize = filter_int_finalise;
/* override methods */
+ filter_element->eq = int_eq;
filter_element->xml_create = xml_create;
filter_element->xml_encode = xml_encode;
filter_element->xml_decode = xml_decode;
@@ -105,6 +107,8 @@ filter_int_class_init (FilterIntClass *class)
static void
filter_int_init (FilterInt *o)
{
+ o->min = 0;
+ o->max = G_MAXINT;
o->priv = g_malloc0 (sizeof (*o->priv));
}
@@ -112,8 +116,8 @@ static void
filter_int_finalise(GtkObject *obj)
{
FilterInt *o = (FilterInt *)obj;
-
- o = o;
+
+ g_free(o->type);
((GtkObjectClass *)(parent_class))->finalize(obj);
}
@@ -132,6 +136,29 @@ filter_int_new (void)
return o;
}
+FilterInt *
+filter_int_new_type(const char *type, int min, int max)
+{
+ FilterInt *o = (FilterInt *)gtk_type_new(filter_int_get_type ());
+ o->type = g_strdup(type);
+ o->min = min;
+ o->max = max;
+ return o;
+}
+
+void
+filter_int_set_value(FilterInt *fi, int val)
+{
+ fi->val = val;
+}
+
+static int
+int_eq(FilterElement *fe, FilterElement *cm)
+{
+ return ((FilterElementClass *)(parent_class))->eq(fe, cm)
+ && ((FilterInt *)fe)->val == ((FilterInt *)cm)->val;
+}
+
static void
xml_create (FilterElement *fe, xmlNodePtr node)
{
@@ -144,17 +171,19 @@ xml_encode (FilterElement *fe)
{
xmlNodePtr value;
FilterInt *fs = (FilterInt *)fe;
- char *intval;
+ char intval[32];
+ const char *type;
- d(printf("Encoding integer as xml\n"));
+ type = fs->type?fs->type:"integer";
+
+ d(printf("Encoding %s as xml\n", type));
value = xmlNewNode (NULL, "value");
xmlSetProp (value, "name", fe->name);
- xmlSetProp (value, "type", "integer");
+ xmlSetProp (value, "type", type);
- intval = g_strdup_printf ("%d", fs->val);
- xmlSetProp (value, "integer", intval);
- g_free (intval);
+ sprintf(intval, "%d", fs->val);
+ xmlSetProp (value, type, intval);
return value;
}
@@ -163,7 +192,7 @@ static int
xml_decode (FilterElement *fe, xmlNodePtr node)
{
FilterInt *fs = (FilterInt *)fe;
- char *name;
+ char *name, *type;
char *intval;
d(printf("Decoding integer from xml %p\n", fe));
@@ -172,7 +201,13 @@ xml_decode (FilterElement *fe, xmlNodePtr node)
d(printf ("Name = %s\n", name));
xmlFree (fe->name);
fe->name = name;
- intval = xmlGetProp (node, "integer");
+
+ type = xmlGetProp(node, "type");
+ g_free(fs->type);
+ fs->type = g_strdup(type);
+ xmlFree(type);
+
+ intval = xmlGetProp (node, type?type:"integer");
if (intval) {
fs->val = atoi (intval);
xmlFree (intval);
@@ -197,14 +232,12 @@ get_widget (FilterElement *fe)
GtkObject *adjustment;
FilterInt *fs = (FilterInt *)fe;
- adjustment = gtk_adjustment_new (0.0, 0.0, (gfloat)G_MAXINT,
- 1.0, 1.0, 1.0);
- spin = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 5.0, 0);
+ adjustment = gtk_adjustment_new (0.0, (gfloat)fs->min, (gfloat)fs->max, 1.0, 1.0, 1.0);
+ spin = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), fs->max>fs->min+1000?5.0:1.0, 0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spin), TRUE);
- if (fs->val) {
+ if (fs->val)
gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), (gfloat) fs->val);
- }
gtk_signal_connect (GTK_OBJECT (spin), "changed", spin_changed, fe);
@@ -221,9 +254,6 @@ static void
format_sexp (FilterElement *fe, GString *out)
{
FilterInt *fs = (FilterInt *)fe;
- char *str;
-
- str = g_strdup_printf ("%d", fs->val);
- g_string_append (out, str);
- g_free (str);
+
+ g_string_sprintfa(out, "%d", fs->val);
}
diff --git a/filter/filter-int.h b/filter/filter-int.h
index 7a451f29ff..4ed508cd36 100644
--- a/filter/filter-int.h
+++ b/filter/filter-int.h
@@ -37,8 +37,11 @@ typedef struct _FilterIntClass FilterIntClass;
struct _FilterInt {
FilterElement parent;
struct _FilterIntPrivate *priv;
-
- gint32 val;
+
+ char *type;
+ int val;
+ int min;
+ int max;
};
struct _FilterIntClass {
@@ -51,6 +54,8 @@ struct _FilterIntClass {
guint filter_int_get_type (void);
FilterInt *filter_int_new (void);
+FilterInt *filter_int_new_type(const char *type, int min, int max);
+void filter_int_set_value(FilterInt *fi, int val);
/* methods */
diff --git a/filter/filter-label.c b/filter/filter-label.c
index 0262c3d5f8..fb921eef61 100644
--- a/filter/filter-label.c
+++ b/filter/filter-label.c
@@ -50,11 +50,7 @@
static gboolean validate (FilterElement *fe);
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 *fe, GString *out);
static void filter_label_class_init (FilterLabelClass *klass);
static void filter_label_init (FilterLabel *label);
@@ -86,7 +82,7 @@ filter_label_get_type (void)
(GtkArgGetFunc) NULL
};
- type = gtk_type_unique (filter_element_get_type (), &type_info);
+ type = gtk_type_unique (filter_int_get_type (), &type_info);
}
return type;
@@ -98,18 +94,14 @@ filter_label_class_init (FilterLabelClass *klass)
GtkObjectClass *object_class = (GtkObjectClass *) klass;
FilterElementClass *filter_element = (FilterElementClass *) klass;
- parent_class = gtk_type_class (filter_element_get_type ());
+ parent_class = gtk_type_class (filter_int_get_type ());
object_class->finalize = filter_label_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;
filter_element->get_widget = get_widget;
- filter_element->build_code = build_code;
- filter_element->format_sexp = format_sexp;
/* signals */
@@ -141,20 +133,13 @@ filter_label_new (void)
return (FilterLabel *) gtk_type_new (filter_label_get_type ());
}
-
-void
-filter_label_set_label (FilterLabel *filter, int label)
-{
- filter->label = label;
-}
-
static gboolean
validate (FilterElement *fe)
{
- FilterLabel *label = (FilterLabel *) fe;
+ FilterInt *label = (FilterInt *)fe;
GtkWidget *dialog;
- if (label->label < 0 || label->label > 4) {
+ if (label->val < 0 || label->val > 4) {
dialog = gnome_ok_dialog (_("You must specify a label name"));
gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
@@ -172,65 +157,18 @@ xml_create (FilterElement *fe, xmlNodePtr node)
}
-static xmlNodePtr
-xml_encode (FilterElement *fe)
-{
- FilterLabel *label = (FilterLabel *) fe;
- xmlNodePtr value;
- char *encstr;
-
- d(printf ("Encoding label as xml\n"));
-
- encstr = g_strdup_printf ("%d", label->label);
-
- value = xmlNewNode (NULL, "value");
- xmlSetProp (value, "name", fe->name);
- xmlSetProp (value, "type", "label");
- xmlSetProp (value, "label", encstr);
- g_free (encstr);
-
- return value;
-}
-
-static int
-xml_decode (FilterElement *fe, xmlNodePtr node)
-{
- FilterLabel *label = (FilterLabel *) fe;
- char *name, *str, *type;
-
- type = xmlGetProp (node, "type");
- if (strcmp (type, "label") != 0) {
- xmlFree (type);
- return -1;
- }
-
- xmlFree (type);
-
- d(printf("Decoding label from xml %p\n", fe));
-
- name = xmlGetProp (node, "name");
- xmlFree (fe->name);
- fe->name = name;
-
- str = xmlGetProp (node, "label");
- label->label = atoi (str);
- xmlFree (str);
-
- return 0;
-}
-
static void
label_selected (GtkWidget *item, gpointer user_data)
{
- FilterLabel *label = user_data;
+ FilterInt *label = user_data;
- label->label = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (item), "label"));
+ label->val = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (item), "label"));
}
static GtkWidget *
get_widget (FilterElement *fe)
{
- FilterLabel *label = (FilterLabel *) fe;
+ FilterInt *label = (FilterInt *) fe;
GtkWidget *omenu, *menu, *item;
Bonobo_ConfigDatabase db;
CORBA_Environment ev;
@@ -282,24 +220,7 @@ get_widget (FilterElement *fe)
g_free (path);
gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
- gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), label->label);
+ gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), label->val);
return omenu;
}
-
-static void
-build_code (FilterElement *fe, GString *out, struct _FilterPart *ff)
-{
- return;
-}
-
-static void
-format_sexp (FilterElement *fe, GString *out)
-{
- FilterLabel *label = (FilterLabel *) fe;
- char *str;
-
- str = g_strdup_printf ("%d", label->label);
- g_string_append (out, str);
- g_free (str);
-}
diff --git a/filter/filter-label.h b/filter/filter-label.h
index 384e0864aa..0e78b6d3c1 100644
--- a/filter/filter-label.h
+++ b/filter/filter-label.h
@@ -29,7 +29,7 @@ extern "C" {
#pragma }
#endif /* __cplusplus */
-#include "filter-element.h"
+#include "filter-int.h"
#define FILTER_LABEL(obj) GTK_CHECK_CAST (obj, filter_label_get_type (), FilterLabel)
#define FILTER_LABEL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, filter_label_get_type (), FilterLabelClass)
@@ -39,13 +39,11 @@ typedef struct _FilterLabel FilterLabel;
typedef struct _FilterLabelClass FilterLabelClass;
struct _FilterLabel {
- FilterElement parent;
-
- int label;
+ FilterInt parent;
};
struct _FilterLabelClass {
- FilterElementClass parent_class;
+ FilterIntClass parent_class;
/* virtual methods */
@@ -56,8 +54,6 @@ GtkType filter_label_get_type (void);
FilterLabel *filter_label_new (void);
-void filter_label_set_label (FilterLabel *filter, int label);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/filter/filter-option.c b/filter/filter-option.c
index b0e1abc3d0..4102cd5eaf 100644
--- a/filter/filter-option.c
+++ b/filter/filter-option.c
@@ -34,6 +34,7 @@
#define d(x)
+static int option_eq(FilterElement *fe, FilterElement *cm);
static void xml_create(FilterElement *fe, xmlNodePtr node);
static xmlNodePtr xml_encode(FilterElement *fe);
static int xml_decode(FilterElement *fe, xmlNodePtr node);
@@ -93,6 +94,7 @@ filter_option_class_init (FilterOptionClass *class)
object_class->finalize = filter_option_finalise;
/* override methods */
+ filter_element->eq = option_eq;
filter_element->xml_create = xml_create;
filter_element->xml_encode = xml_encode;
filter_element->xml_decode = xml_decode;
@@ -171,6 +173,16 @@ filter_option_set_current (FilterOption *option, const char *name)
option->current = find_option (option, name);
}
+static int
+option_eq(FilterElement *fe, FilterElement *cm)
+{
+ FilterOption *fo = (FilterOption *)fe, *co = (FilterOption *)cm;
+
+ return ((FilterElementClass *)(parent_class))->eq(fe, cm)
+ && ((fo->current && co->current && strcmp(fo->current->value, co->current->value) == 0)
+ || (fo->current == NULL && co->current == NULL));
+}
+
static void
xml_create (FilterElement *fe, xmlNodePtr node)
{
diff --git a/filter/filter-part.c b/filter/filter-part.c
index e92c42aafb..3f05341c81 100644
--- a/filter/filter-part.c
+++ b/filter/filter-part.c
@@ -153,10 +153,37 @@ filter_part_validate (FilterPart *fp)
}
int
+filter_part_eq(FilterPart *fp, FilterPart *fc)
+{
+ int truth;
+ GList *al, *bl;
+
+ truth = ((fp->name && fc->name && strcmp(fp->name, fc->name) == 0)
+ || (fp->name == NULL && fc->name == NULL))
+ && ((fp->title && fc->title && strcmp(fp->title, fc->title) == 0)
+ || (fp->title == NULL && fc->title == NULL))
+ && ((fp->code && fc->code && strcmp(fp->code, fc->code) == 0)
+ || (fp->code == NULL && fc->code == NULL));
+
+ al = fp->elements;
+ bl = fc->elements;
+ while (truth && al && bl) {
+ FilterElement *a = al->data, *b = bl->data;
+
+ truth = filter_element_eq(a, b);
+
+ al = al->next;
+ bl = bl->next;
+ }
+
+ return truth && al == NULL && bl == NULL;
+}
+
+int
filter_part_xml_create (FilterPart *ff, xmlNodePtr node)
{
xmlNodePtr n;
- char *type, *str, *decstr;
+ char *type, *str;
FilterElement *el;
str = xmlGetProp(node, "name");
diff --git a/filter/filter-part.h b/filter/filter-part.h
index 904be6b191..e47f9a28f2 100644
--- a/filter/filter-part.h
+++ b/filter/filter-part.h
@@ -54,6 +54,7 @@ FilterPart *filter_part_new (void);
/* methods */
gboolean filter_part_validate (FilterPart *fp);
+int filter_part_eq (FilterPart *fp, FilterPart *fc);
int filter_part_xml_create (FilterPart *ff, xmlNodePtr node);
diff --git a/filter/filter-rule.c b/filter/filter-rule.c
index 89e0d76726..4adffeaf3c 100644
--- a/filter/filter-rule.c
+++ b/filter/filter-rule.c
@@ -41,6 +41,7 @@
#define d(x)
static int validate(FilterRule *);
+static int rule_eq(FilterRule *fr, FilterRule *cm);
static xmlNodePtr xml_encode (FilterRule *);
static int xml_decode (FilterRule *, xmlNodePtr, RuleContext *);
static void build_code (FilterRule *, GString * out);
@@ -100,6 +101,7 @@ filter_rule_class_init (FilterRuleClass * class)
/* override methods */
class->validate = validate;
+ class->eq = rule_eq;
class->xml_encode = xml_encode;
class->xml_decode = xml_decode;
class->build_code = build_code;
@@ -231,6 +233,43 @@ validate (FilterRule *fr)
return valid;
}
+int
+filter_rule_eq(FilterRule *fr, FilterRule *cm)
+{
+ g_assert(IS_FILTER_RULE(fr));
+ g_assert(IS_FILTER_RULE(cm));
+
+ return ((GtkObject *)fr)->klass == ((GtkObject *)cm)->klass
+ && ((FilterRuleClass *) ((GtkObject *) fr)->klass)->eq(fr, cm);
+}
+
+static int
+list_eq(GList *al, GList *bl)
+{
+ int truth = TRUE;
+
+ while (truth && al && bl) {
+ FilterPart *a = al->data, *b = bl->data;
+
+ truth = filter_part_eq(a, b);
+ al = al->next;
+ bl = bl->next;
+ }
+
+ return truth && al == NULL && bl == NULL;
+}
+
+static int
+rule_eq(FilterRule *fr, FilterRule *cm)
+{
+ return fr->grouping == cm->grouping
+ && ( (fr->name && cm->name && strcmp(fr->name, cm->name) == 0)
+ || (fr->name == NULL && cm->name == NULL))
+ && ( (fr->source && cm->source && strcmp(fr->source, cm->source) == 0)
+ || (fr->source == NULL && cm->source == NULL) )
+ && list_eq(fr->parts, cm->parts);
+}
+
xmlNodePtr
filter_rule_xml_encode (FilterRule *fr)
{
diff --git a/filter/filter-rule.h b/filter/filter-rule.h
index f0558d0f2b..5e4793c872 100644
--- a/filter/filter-rule.h
+++ b/filter/filter-rule.h
@@ -60,6 +60,7 @@ struct _FilterRuleClass {
/* virtual methods */
int (*validate)(FilterRule *);
+ int (*eq)(FilterRule *fr, FilterRule *cm);
xmlNodePtr (*xml_encode)(FilterRule *);
int (*xml_decode)(FilterRule *, xmlNodePtr, struct _RuleContext *);
@@ -84,6 +85,7 @@ void filter_rule_set_name (FilterRule *fr, const char *name);
void filter_rule_set_source (FilterRule *fr, const char *source);
int filter_rule_validate (FilterRule *fr);
+int filter_rule_eq (FilterRule *fr, FilterRule *cm);
xmlNodePtr filter_rule_xml_encode (FilterRule *fr);
int filter_rule_xml_decode (FilterRule *fr, xmlNodePtr node, struct _RuleContext *f);
diff --git a/filter/filter-source.c b/filter/filter-source.c
index fee37f5ad1..83e20d1bd5 100644
--- a/filter/filter-source.c
+++ b/filter/filter-source.c
@@ -65,6 +65,7 @@ static void filter_source_class_init (FilterSourceClass *);
static void filter_source_init (FilterSource *);
static void filter_source_finalize (GtkObject *);
+static int source_eq(FilterElement *fe, FilterElement *cm);
static void xml_create(FilterElement *fe, xmlNodePtr node);
static xmlNodePtr xml_encode(FilterElement *fe);
static int xml_decode(FilterElement *fe, xmlNodePtr node);
@@ -112,6 +113,7 @@ filter_source_class_init (FilterSourceClass *class)
object_class->finalize = filter_source_finalize;
/* override methods */
+ filter_element->eq = source_eq;
filter_element->xml_create = xml_create;
filter_element->xml_encode = xml_encode;
filter_element->xml_decode = xml_decode;
@@ -164,6 +166,16 @@ filter_source_new (void)
return s;
}
+static int
+source_eq(FilterElement *fe, FilterElement *cm)
+{
+ FilterSource *fs = (FilterSource *)fe, *cs = (FilterSource *)cm;
+
+ return ((FilterElementClass *)parent_class)->eq(fe, cm)
+ && ((fs->priv->current_url && cs->priv->current_url && strcmp(fs->priv->current_url, cs->priv->current_url) == 0)
+ || (fs->priv->current_url == NULL && cs->priv->current_url == NULL));
+}
+
static void
xml_create (FilterElement *fe, xmlNodePtr node)
{
diff --git a/filter/libfilter-i18n.h b/filter/libfilter-i18n.h
index 9d930d930b..982ebae371 100644
--- a/filter/libfilter-i18n.h
+++ b/filter/libfilter-i18n.h
@@ -5,34 +5,18 @@ char *s = N_("Assign Score");
char *s = N_("Attachments");
char *s = N_("Beep");
char *s = N_("Command");
-char *s = N_("contains");
char *s = N_("Copy to Folder");
char *s = N_("Date received");
char *s = N_("Date sent");
char *s = N_("Delete");
char *s = N_("Deleted");
-char *s = N_("does not contain");
-char *s = N_("does not end with");
-char *s = N_("does not exist");
-char *s = N_("does not sound like");
-char *s = N_("does not start with");
char *s = N_("Do Not Exist");
char *s = N_("Draft");
-char *s = N_("ends with");
char *s = N_("Execute Shell Command");
char *s = N_("Exist");
-char *s = N_("exists");
char *s = N_("Expression");
char *s = N_("Follow Up");
char *s = N_("Important");
-char *s = N_("is");
-char *s = N_("is after");
-char *s = N_("is before");
-char *s = N_("is Flagged");
-char *s = N_("is greater than");
-char *s = N_("is less than");
-char *s = N_("is not");
-char *s = N_("is not Flagged");
char *s = N_("Label");
char *s = N_("Mailing list");
char *s = N_("Message Body");
@@ -47,10 +31,26 @@ char *s = N_("Score");
char *s = N_("Sender");
char *s = N_("Set Status");
char *s = N_("Size (kB)");
-char *s = N_("sounds like");
char *s = N_("Source Account");
char *s = N_("Specific header");
-char *s = N_("starts with");
char *s = N_("Status");
char *s = N_("Stop Processing");
char *s = N_("Subject");
+char *s = N_("contains");
+char *s = N_("does not contain");
+char *s = N_("does not end with");
+char *s = N_("does not exist");
+char *s = N_("does not sound like");
+char *s = N_("does not start with");
+char *s = N_("ends with");
+char *s = N_("exists");
+char *s = N_("is Flagged");
+char *s = N_("is after");
+char *s = N_("is before");
+char *s = N_("is greater than");
+char *s = N_("is less than");
+char *s = N_("is not Flagged");
+char *s = N_("is not");
+char *s = N_("is");
+char *s = N_("sounds like");
+char *s = N_("starts with");
diff --git a/filter/rule-context.c b/filter/rule-context.c
index 18939a0041..490c169d05 100644
--- a/filter/rule-context.c
+++ b/filter/rule-context.c
@@ -38,6 +38,7 @@
static int load(RuleContext * f, const char *system, const char *user);
static int save(RuleContext * f, const char *user);
+static int revert(RuleContext *f, const char *user);
static GList *rename_uri(RuleContext *f, const char *olduri, const char *newuri, GCompareFunc cmp);
static GList *delete_uri(RuleContext *f, const char *uri, GCompareFunc cmp);
@@ -97,6 +98,7 @@ rule_context_class_init (RuleContextClass * class)
/* override methods */
class->load = load;
class->save = save;
+ class->revert = revert;
class->rename_uri = rename_uri;
class->delete_uri = delete_uri;
@@ -418,6 +420,148 @@ save (RuleContext *f, const char *user)
return ret;
}
+/**
+ * rule_context_revert:
+ * @f:
+ * @user:
+ *
+ * Reverts a rule context from a user description file. Assumes the
+ * system description file is unchanged from when it was loaded.
+ *
+ * Return value:
+ **/
+int
+rule_context_revert(RuleContext *f, const char *user)
+{
+ g_assert(f);
+
+ d(printf("rule_context: restoring %s %s\n", user));
+
+ return ((RuleContextClass *) ((GtkObject *) f)->klass)->revert(f, user);
+}
+
+struct _revert_data {
+ GHashTable *rules;
+ int rank;
+};
+
+static void
+revert_rule_remove(void *key, FilterRule *frule, RuleContext *f)
+{
+ rule_context_remove_rule(f, frule);
+ gtk_object_unref((GtkObject *)frule);
+}
+
+static void
+revert_source_remove(void *key, struct _revert_data *rest_data, RuleContext *f)
+{
+ g_hash_table_foreach(rest_data->rules, (GHFunc)revert_rule_remove, f);
+ g_hash_table_destroy(rest_data->rules);
+ g_free(rest_data);
+}
+
+static guint source_hashf(const char *a)
+{
+ if (a)
+ return g_str_hash(a);
+ return 0;
+}
+
+static int source_eqf(const char *a, const char *b)
+{
+ return (a && b && strcmp(a, b) == 0)
+ || (a == NULL && b == NULL);
+}
+
+static int
+revert(RuleContext *f, const char *user)
+{
+ xmlNodePtr set, rule;
+ /*struct _part_set_map *part_map;*/
+ struct _rule_set_map *rule_map;
+ struct _revert_data *rest_data;
+ GHashTable *source_hash;
+ xmlDocPtr userdoc;
+ FilterRule *frule;
+
+ rule_context_set_error (f, NULL);
+
+ d(printf("restoring rules %s %s\n", user));
+
+ userdoc = xmlParseFile (user);
+ if (userdoc == NULL)
+ /* clear out anythign we have? */
+ return 0;
+
+ source_hash = g_hash_table_new((GHashFunc)source_hashf, (GCompareFunc)source_eqf);
+
+ /* setup stuff we have now */
+ /* Note that we assume there is only 1 set of rules in a given rule context,
+ although other parts of the code dont assume this */
+ frule = NULL;
+ while ((frule = rule_context_next_rule(f, frule, NULL))) {
+ rest_data = g_hash_table_lookup(source_hash, frule->source);
+ if (rest_data == NULL) {
+ rest_data = g_malloc0(sizeof(*rest_data));
+ rest_data->rules = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert(source_hash, frule->source, rest_data);
+ }
+ g_hash_table_insert(rest_data->rules, frule->name, frule);
+ }
+
+ /* make what we have, match what we load */
+ set = userdoc->root->childs;
+ while (set) {
+ d(printf("set name = %s\n", set->name));
+ rule_map = g_hash_table_lookup (f->rule_set_map, set->name);
+ if (rule_map) {
+ d(printf("loading rules ...\n"));
+ rule = set->childs;
+ while (rule) {
+ d(printf("checking node: %s\n", rule->name));
+ if (!strcmp (rule->name, "rule")) {
+ FilterRule *part = FILTER_RULE(gtk_type_new (rule_map->type));
+
+ if (filter_rule_xml_decode (part, rule, f) == 0) {
+ /* use the revert data to keep track of the right rank of this rule part */
+ rest_data = g_hash_table_lookup(source_hash, part->source);
+ if (rest_data == NULL) {
+ rest_data = g_malloc0(sizeof(*rest_data));
+ rest_data->rules = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert(source_hash, part->source, rest_data);
+ }
+ frule = g_hash_table_lookup(rest_data->rules, part->name);
+ if (frule) {
+ if (f->priv->frozen == 0 && !filter_rule_eq(frule, part))
+ filter_rule_copy(frule, part);
+ gtk_object_unref (GTK_OBJECT (part));
+ rule_context_rank_rule(f, frule, rest_data->rank);
+ g_hash_table_remove(rest_data->rules, frule->name);
+ } else {
+ rule_context_add_rule(f, part);
+ rule_context_rank_rule(f, part, rest_data->rank);
+ }
+ rest_data->rank++;
+ } else {
+ gtk_object_unref (GTK_OBJECT (part));
+ g_warning ("Cannot load filter part");
+ }
+ }
+ rule = rule->next;
+ }
+ }
+ set = set->next;
+ }
+
+ xmlFreeDoc(userdoc);
+
+ /* remove any we still have that weren't in the file */
+ g_hash_table_foreach(source_hash, (GHFunc)revert_source_remove, f);
+ g_hash_table_destroy(source_hash);
+
+ return 0;
+}
+
FilterPart *
rule_context_find_part (RuleContext *f, const char *name)
{
diff --git a/filter/rule-context.h b/filter/rule-context.h
index 56c1bb491e..60d0d6f932 100644
--- a/filter/rule-context.h
+++ b/filter/rule-context.h
@@ -60,6 +60,7 @@ struct _RuleContextClass {
/* virtual methods */
int (*load)(RuleContext *f, const char *system, const char *user);
int (*save)(RuleContext *f, const char *user);
+ int (*revert)(RuleContext *f, const char *user);
GList *(*delete_uri)(RuleContext *f, const char *uri, GCompareFunc cmp);
GList *(*rename_uri)(RuleContext *f, const char *olduri, const char *newuri, GCompareFunc cmp);
@@ -95,6 +96,7 @@ RuleContext *rule_context_new (void);
/* methods */
int rule_context_load(RuleContext *f, const char *system, const char *user);
int rule_context_save(RuleContext *f, const char *user);
+int rule_context_revert(RuleContext *f, const char *user);
void rule_context_add_part(RuleContext *f, FilterPart *new);
FilterPart *rule_context_find_part(RuleContext *f, const char *name);
diff --git a/filter/vfolder-rule.c b/filter/vfolder-rule.c
index 36b381eb06..053561b4eb 100644
--- a/filter/vfolder-rule.c
+++ b/filter/vfolder-rule.c
@@ -39,6 +39,7 @@
#define d(x) x
static gint validate(FilterRule *);
+static int vfolder_eq(FilterRule *fr, FilterRule *cm);
static xmlNodePtr xml_encode(FilterRule *);
static int xml_decode(FilterRule *, xmlNodePtr, struct _RuleContext *f);
static void rule_copy (FilterRule *dest, FilterRule *src);
@@ -93,6 +94,7 @@ vfolder_rule_class_init (VfolderRuleClass *class)
/* override methods */
filter_rule->validate = validate;
+ filter_rule->eq = vfolder_eq;
filter_rule->xml_encode = xml_encode;
filter_rule->xml_decode = xml_decode;
filter_rule->copy = rule_copy;
@@ -222,6 +224,29 @@ validate (FilterRule *fr)
return 1;
}
+static int
+list_eq(GList *al, GList *bl)
+{
+ int truth = TRUE;
+
+ while (truth && al && bl) {
+ char *a = al->data, *b = bl->data;
+
+ truth = strcmp(a, b) == 0;
+ al = al->next;
+ bl = bl->next;
+ }
+
+ return truth && al == NULL && bl == NULL;
+}
+
+static int
+vfolder_eq(FilterRule *fr, FilterRule *cm)
+{
+ return ((FilterRuleClass *)(parent_class))->eq(fr, cm)
+ && list_eq(((VfolderRule *)fr)->sources, ((VfolderRule *)cm)->sources);
+}
+
static xmlNodePtr
xml_encode (FilterRule *fr)
{