aboutsummaryrefslogtreecommitdiffstats
path: root/filter/rule-context.c
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2002-07-15 09:46:17 +0800
committerMichael Zucci <zucchi@src.gnome.org>2002-07-15 09:46:17 +0800
commit68ec840bca073bc8e8ea2f58ad36078df9c619c1 (patch)
tree64083ad8df8983d37c2658c51e1c961e4671f160 /filter/rule-context.c
parente785008af08bdc913ce2711dcd7998efb51f694b (diff)
downloadgsoc2013-evolution-68ec840bca073bc8e8ea2f58ad36078df9c619c1.tar
gsoc2013-evolution-68ec840bca073bc8e8ea2f58ad36078df9c619c1.tar.gz
gsoc2013-evolution-68ec840bca073bc8e8ea2f58ad36078df9c619c1.tar.bz2
gsoc2013-evolution-68ec840bca073bc8e8ea2f58ad36078df9c619c1.tar.lz
gsoc2013-evolution-68ec840bca073bc8e8ea2f58ad36078df9c619c1.tar.xz
gsoc2013-evolution-68ec840bca073bc8e8ea2f58ad36078df9c619c1.tar.zst
gsoc2013-evolution-68ec840bca073bc8e8ea2f58ad36078df9c619c1.zip
** fixes for #10781
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. svn path=/trunk/; revision=17448
Diffstat (limited to 'filter/rule-context.c')
-rw-r--r--filter/rule-context.c144
1 files changed, 144 insertions, 0 deletions
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)
{