From 9ddabfee03542411d02851a1b1f144707ce32b82 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Mon, 31 Jul 2000 15:03:23 +0000 Subject: Set value of a simple type to a new string. 2000-07-31 Not Zed * filter-input.c (filter_input_set_value): Set value of a simple type to a new string. * filter-option.c (filter_option_set_current): New function to set the current value of an option. * filter-rule.c (filter_rule_find_list): New function to find a rule in a list, by name. (filter_rule_set_name): Let you set the name of a rule. * rule-context.c (rule_context_find_rule): Find a rule by name. (rule_context_create_part): Helper to find and clone a part by name. * filter-folder.c (button_clicked): Fix warning. * filter.glade: Add new widgets for vfolder rule editor. * vfolder-context.c (vfolder_context_init): Changed to use vfolder rule as the rule type. * vfolder-rule.c: New class to encode extra information required for vfolder rules. svn path=/trunk/; revision=4421 --- filter/ChangeLog | 26 ++++ filter/Makefile.am | 4 +- filter/filter-filter.c | 2 +- filter/filter-folder.c | 2 +- filter/filter-input.c | 14 ++ filter/filter-option.c | 7 + filter/filter-option.h | 1 + filter/filter-rule.c | 18 +++ filter/filter-rule.h | 3 + filter/filter.glade | 160 +++++++++++++++++++++ filter/rule-context.c | 17 ++- filter/rule-context.h | 5 +- filter/vfolder-context.c | 3 +- filter/vfolder-rule.c | 354 +++++++++++++++++++++++++++++++++++++++++++++++ filter/vfolder-rule.h | 59 ++++++++ 15 files changed, 668 insertions(+), 7 deletions(-) create mode 100644 filter/vfolder-rule.c create mode 100644 filter/vfolder-rule.h diff --git a/filter/ChangeLog b/filter/ChangeLog index c2008adab9..70ef7fe69d 100644 --- a/filter/ChangeLog +++ b/filter/ChangeLog @@ -1,3 +1,29 @@ +2000-07-31 Not Zed + + * filter-input.c (filter_input_set_value): Set value of a simple + type to a new string. + + * filter-option.c (filter_option_set_current): New function to set + the current value of an option. + + * filter-rule.c (filter_rule_find_list): New function to find a + rule in a list, by name. + (filter_rule_set_name): Let you set the name of a rule. + + * rule-context.c (rule_context_find_rule): Find a rule by name. + (rule_context_create_part): Helper to find and clone a part by + name. + + * filter-folder.c (button_clicked): Fix warning. + + * filter.glade: Add new widgets for vfolder rule editor. + + * vfolder-context.c (vfolder_context_init): Changed to use vfolder + rule as the rule type. + + * vfolder-rule.c: New class to encode extra information required + for vfolder rules. + 2000-07-30 Not Zed ** Almost a total rewrite of every file, except for filter-driver diff --git a/filter/Makefile.am b/filter/Makefile.am index f6b31dcfc8..e8195559ee 100644 --- a/filter/Makefile.am +++ b/filter/Makefile.am @@ -55,7 +55,9 @@ libfilter_la_SOURCES = \ vfolder-context.c \ vfolder-context.h \ vfolder-editor.c \ - vfolder-editor.h + vfolder-editor.h \ + vfolder-rule.c \ + vfolder-rule.h EXTRA_DIST = blank.xpm check.xpm \ filtertypes.xml vfoldertypes.xml diff --git a/filter/filter-filter.c b/filter/filter-filter.c index 9e902dbbd8..db974ef029 100644 --- a/filter/filter-filter.c +++ b/filter/filter-filter.c @@ -25,7 +25,7 @@ #include "filter-filter.h" #include "filter-context.h" -#define d(x) x +#define d(x) static xmlNodePtr xml_encode(FilterRule *); static int xml_decode(FilterRule *, xmlNodePtr, struct _RuleContext *f); diff --git a/filter/filter-folder.c b/filter/filter-folder.c index fa3fe913ae..b5be1be8a9 100644 --- a/filter/filter-folder.c +++ b/filter/filter-folder.c @@ -196,7 +196,7 @@ static void button_clicked(GtkButton *button, FilterFolder *ff) str = uri; ff->name = g_strdup(str); - gtk_label_set_text(GTK_BIN(button)->child, ff->name); + gtk_label_set_text((GtkLabel *)GTK_BIN(button)->child, ff->name); } else { g_free(uri); } diff --git a/filter/filter-input.c b/filter/filter-input.c index eca5afd2ff..f422a091b1 100644 --- a/filter/filter-input.c +++ b/filter/filter-input.c @@ -135,6 +135,20 @@ FilterInput *filter_input_new_type_name (const char *type) return o; } +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_list_free(fi->values); + + fi->values = g_list_append(NULL, g_strdup(value)); +} + static void xml_create(FilterElement *fe, xmlNodePtr node) { /* parent implementation */ diff --git a/filter/filter-option.c b/filter/filter-option.c index 31be216f25..bbf1a8ef90 100644 --- a/filter/filter-option.c +++ b/filter/filter-option.c @@ -146,6 +146,13 @@ find_option(FilterOption *fo, const char *name) return NULL; } +void filter_option_set_current(FilterOption *option, const char *name) +{ + g_assert(IS_FILTER_OPTION(option)); + + option->current = find_option(option, name); +} + static void xml_create(FilterElement *fe, xmlNodePtr node) { FilterOption *fo = (FilterOption *)fe; diff --git a/filter/filter-option.h b/filter/filter-option.h index 1645b333a1..1bbec79d84 100644 --- a/filter/filter-option.h +++ b/filter/filter-option.h @@ -58,6 +58,7 @@ guint filter_option_get_type (void); FilterOption *filter_option_new (void); /* methods */ +void filter_option_set_current(FilterOption *option, const char *name); #endif /* ! _FILTER_OPTION_H */ diff --git a/filter/filter-rule.c b/filter/filter-rule.c index 9e1da43164..9c47af6daf 100644 --- a/filter/filter-rule.c +++ b/filter/filter-rule.c @@ -133,6 +133,12 @@ filter_rule_new(void) return o; } +void filter_rule_set_name (FilterRule *fr, const char *name) +{ + g_free(fr->name); + fr->name = g_strdup(name); +} + xmlNodePtr filter_rule_xml_encode (FilterRule *fr) { return ((FilterRuleClass *)((GtkObject *)fr)->klass)->xml_encode(fr); @@ -523,3 +529,15 @@ FilterRule *filter_rule_next_list (GList *l, FilterRule *last) return node->data; return NULL; } + +FilterRule *filter_rule_find_list (GList *l, const char *name) +{ + while (l) { + FilterRule *rule = l->data; + if (!strcmp(rule->name, name)) + return rule; + l = g_list_next(l); + } + return NULL; +} + diff --git a/filter/filter-rule.h b/filter/filter-rule.h index ca5b1ddfb7..396af19e59 100644 --- a/filter/filter-rule.h +++ b/filter/filter-rule.h @@ -67,6 +67,8 @@ guint filter_rule_get_type (void); FilterRule *filter_rule_new (void); /* methods */ +void filter_rule_set_name (FilterRule *fr, const char *name); + xmlNodePtr filter_rule_xml_encode (FilterRule *fr); int filter_rule_xml_decode (FilterRule *fr, xmlNodePtr node, struct _RuleContext *f); @@ -83,6 +85,7 @@ void filter_rule_build_action(FilterRule *fr, GString *out); /* static functions */ FilterRule *filter_rule_next_list (GList *l, FilterRule *last); +FilterRule *filter_rule_find_list (GList *l, const char *name); #endif /* ! _FILTER_RULE_H */ diff --git a/filter/filter.glade b/filter/filter.glade index 7592bc30fd..ff40068aa7 100644 --- a/filter/filter.glade +++ b/filter/filter.glade @@ -380,4 +380,164 @@ Outgoing + + GnomeDialog + vfolder_source + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + False + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox3 + False + 8 + + 4 + True + True + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area3 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + button16 + True + True + GNOME_STOCK_BUTTON_OK + + + + GtkButton + button17 + True + True + GNOME_STOCK_BUTTON_APPLY + + + + GtkButton + button18 + True + True + GNOME_STOCK_BUTTON_CANCEL + + + + + GtkFrame + vfolder_source_frame + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkHBox + hbox3 + False + 0 + + + GtkScrolledWindow + scrolledwindow3 + 256 + 125 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + GtkViewport + viewport3 + GTK_SHADOW_IN + + + GtkList + source_list + GTK_SELECTION_SINGLE + + + + + + GtkVBox + vbox3 + False + 0 + + 0 + False + False + + + + GtkVButtonBox + vbuttonbox3 + GTK_BUTTONBOX_DEFAULT_STYLE + 0 + 85 + 27 + 6 + 0 + + 0 + False + False + + + + GtkButton + source_add + True + True + + + + + GtkButton + source_remove + True + True + + + + + + + + + diff --git a/filter/rule-context.c b/filter/rule-context.c index e6a18d078a..5335882932 100644 --- a/filter/rule-context.c +++ b/filter/rule-context.c @@ -306,12 +306,22 @@ static int save(RuleContext *f, const char *user) return 0; } -FilterPart *rule_context_find_part(RuleContext *f, char *name) +FilterPart *rule_context_find_part(RuleContext *f, const char *name) { d(printf("find part : ")); return filter_part_find_list(f->parts, name); } +FilterPart *rule_context_create_part(RuleContext *f, const char *name) +{ + FilterPart *part; + + part = rule_context_find_part(f, name); + if (part) + part = filter_part_clone(part); + return part; +} + FilterPart *rule_context_next_part(RuleContext *f, FilterPart *last) { return filter_part_next_list(f->parts, last); @@ -322,6 +332,11 @@ FilterRule *rule_context_next_rule(RuleContext *f, FilterRule *last) return filter_rule_next_list(f->rules, last); } +FilterRule *rule_context_find_rule(RuleContext *f, const char *name) +{ + return filter_rule_find_list(f->rules, name); +} + void rule_context_add_part(RuleContext *f, FilterPart *part) { f->parts = g_list_append(f->parts, part); diff --git a/filter/rule-context.h b/filter/rule-context.h index f2b59cd3c0..6a442d504b 100644 --- a/filter/rule-context.h +++ b/filter/rule-context.h @@ -89,11 +89,12 @@ int rule_context_load(RuleContext *f, const char *system, const char *user); int rule_context_save(RuleContext *f, const char *user); void rule_context_add_part(RuleContext *f, FilterPart *new); -FilterPart *rule_context_find_part(RuleContext *f, char *name); -/*FilterPart *rule_context_create_part(RuleContext *f, char *name);*/ +FilterPart *rule_context_find_part(RuleContext *f, const char *name); +FilterPart *rule_context_create_part(RuleContext *f, const char *name); FilterPart *rule_context_next_part(RuleContext *f, FilterPart *last); FilterRule *rule_context_next_rule(RuleContext *f, FilterRule *last); +FilterRule *rule_context_find_rule(RuleContext *f, const char *name); void rule_context_add_rule(RuleContext *f, FilterRule *new); void rule_context_remove_rule(RuleContext *f, FilterRule *rule); diff --git a/filter/vfolder-context.c b/filter/vfolder-context.c index 0202c71847..41453ea310 100644 --- a/filter/vfolder-context.c +++ b/filter/vfolder-context.c @@ -22,6 +22,7 @@ #include #include "vfolder-context.h" +#include "vfolder-rule.h" static void vfolder_context_class_init (VfolderContextClass *class); static void vfolder_context_init (VfolderContext *gspaper); @@ -86,7 +87,7 @@ vfolder_context_init (VfolderContext *o) rule_context_add_part_set((RuleContext *)o, "partset", filter_part_get_type(), rule_context_add_part, rule_context_next_part); - rule_context_add_rule_set((RuleContext *)o, "ruleset", filter_rule_get_type(), + rule_context_add_rule_set((RuleContext *)o, "ruleset", vfolder_rule_get_type(), rule_context_add_rule, rule_context_next_rule); } diff --git a/filter/vfolder-rule.c b/filter/vfolder-rule.c new file mode 100644 index 0000000000..d6da471b07 --- /dev/null +++ b/filter/vfolder-rule.c @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2000 Helix Code Inc. + * + * Authors: Not Zed + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include "vfolder-context.h" +#include "vfolder-rule.h" +#include "shell/evolution-shell-client.h" + +#define d(x) x + +static xmlNodePtr xml_encode(FilterRule *); +static int xml_decode(FilterRule *, xmlNodePtr, struct _RuleContext *f); +/*static void build_code(FilterRule *, GString *out);*/ +static GtkWidget *get_widget(FilterRule *fr, struct _RuleContext *f); + +extern EvolutionShellClient *global_shell_client; + +static void vfolder_rule_class_init (VfolderRuleClass *class); +static void vfolder_rule_init (VfolderRule *gspaper); +static void vfolder_rule_finalise (GtkObject *obj); + +#define _PRIVATE(x) (((VfolderRule *)(x))->priv) + +struct _VfolderRulePrivate { +}; + +static FilterRuleClass *parent_class; + +guint +vfolder_rule_get_type (void) +{ + static guint type = 0; + + if (!type) { + GtkTypeInfo type_info = { + "VfolderRule", + sizeof(VfolderRule), + sizeof(VfolderRuleClass), + (GtkClassInitFunc)vfolder_rule_class_init, + (GtkObjectInitFunc)vfolder_rule_init, + (GtkArgSetFunc)NULL, + (GtkArgGetFunc)NULL + }; + + type = gtk_type_unique(filter_rule_get_type (), &type_info); + } + + return type; +} + +static void +vfolder_rule_class_init (VfolderRuleClass *class) +{ + GtkObjectClass *object_class; + FilterRuleClass *filter_rule = (FilterRuleClass *)class; + + object_class = (GtkObjectClass *)class; + parent_class = gtk_type_class(filter_rule_get_type ()); + + object_class->finalize = vfolder_rule_finalise; + + /* override methods */ + filter_rule->xml_encode = xml_encode; + filter_rule->xml_decode = xml_decode; + /*filter_rule->build_code = build_code;*/ + filter_rule->get_widget = get_widget; +} + +static void +vfolder_rule_init (VfolderRule *o) +{ + o->priv = g_malloc0(sizeof(*o->priv)); +} + +static void +vfolder_rule_finalise(GtkObject *obj) +{ + VfolderRule *o = (VfolderRule *)obj; + o = o; + ((GtkObjectClass *)(parent_class))->finalize(obj); +} + +/** + * vfolder_rule_new: + * + * Create a new VfolderRule object. + * + * Return value: A new #VfolderRule object. + **/ +VfolderRule * +vfolder_rule_new(void) +{ + VfolderRule *o = (VfolderRule *)gtk_type_new(vfolder_rule_get_type ()); + return o; +} + +void vfolder_rule_add_source (VfolderRule *vr, const char *uri) +{ + g_assert(IS_VFOLDER_RULE(vr)); + + vr->sources = g_list_append(vr->sources, g_strdup(uri)); +} + +const char *vfolder_rule_find_source (VfolderRule *vr, const char *uri) +{ + GList *l; + + g_assert(IS_VFOLDER_RULE(vr)); + + /* only does a simple string or address comparison, should + probably do a decoded url comparison */ + l = vr->sources; + while (l) { + if (l->data == uri || !strcmp(l->data, uri)) + return l->data; + l = g_list_next(l); + } + return NULL; +} + +void vfolder_rule_remove_source (VfolderRule *vr, const char *uri) +{ + char *found; + + g_assert(IS_VFOLDER_RULE(vr)); + + found = (char *)vfolder_rule_find_source(vr, uri); + if (found) { + vr->sources = g_list_remove(vr->sources, found); + g_free(found); + } +} + +const char *vfolder_rule_next_source (VfolderRule *vr, const char *last) +{ + GList *node; + + if (last == NULL) { + node = vr->sources; + } else { + node = g_list_find(vr->sources, (char *)last); + if (node == NULL) + node = vr->sources; + else + node = g_list_next(node); + } + if (node) + return (const char *)node->data; + return NULL; +} + +static xmlNodePtr xml_encode(FilterRule *fr) +{ + xmlNodePtr node, set, work; + GList *l; + VfolderRule *vr = (VfolderRule *)fr; + + node = ((FilterRuleClass *)(parent_class))->xml_encode(fr); + g_assert(node != NULL); + set = xmlNewNode(NULL, "sources"); + xmlAddChild(node, set); + l = vr->sources; + while (l) { + work = xmlNewNode(NULL, "folder"); + xmlSetProp(work, "uri", l->data); + xmlAddChild(set, work); + l = g_list_next(l); + } + return node; +} + +static int xml_decode(FilterRule *fr, xmlNodePtr node, struct _RuleContext *f) +{ + xmlNodePtr set, work; + int result; + VfolderRule *vr = (VfolderRule *)fr; + char *uri; + + result = ((FilterRuleClass *)(parent_class))->xml_decode(fr, node, f); + if (result != 0) + return result; + + set = node->childs; + while (set) { + if (!strcmp(set->name, "sources")) { + work = set->childs; + while (work) { + if (!strcmp(work->name, "folder")) { + uri = xmlGetProp(work, "uri"); + if (uri) + vr->sources = g_list_append(vr->sources, uri); + } + work = work->next; + } + } + set = set->next; + } + return 0; +} + +enum { + BUTTON_ADD, + BUTTON_REMOVE, + BUTTON_LAST, +}; + +struct _source_data { + RuleContext *f; + VfolderRule *vr; + const char *current; + GtkList *list; + GtkButton *buttons[BUTTON_LAST]; +}; + +static void source_add(GtkWidget *widget, struct _source_data *data); +static void source_remove(GtkWidget *widget, struct _source_data *data); + +static struct { + char *name; + GtkSignalFunc func; +} edit_buttons[] = { + { "source_add", source_add }, + { "source_remove", source_remove }, +}; + +static void +set_sensitive(struct _source_data *data) +{ + gtk_widget_set_sensitive((GtkWidget *)data->buttons[BUTTON_ADD], TRUE); + gtk_widget_set_sensitive((GtkWidget *)data->buttons[BUTTON_REMOVE], data->current != NULL); +} + +static void +select_source(GtkWidget *w, GtkWidget *child, struct _source_data *data) +{ + data->current = gtk_object_get_data((GtkObject *)child, "source"); + set_sensitive(data); +} + +static void source_add(GtkWidget *widget, struct _source_data *data) +{ + const char *allowed_types[] = { "mail", NULL }; + char *def, *uri; + GtkListItem *item; + GList *l; + + def = ""; + evolution_shell_client_user_select_folder (global_shell_client, + _("Select Folder"), + def, allowed_types, NULL, &uri); + + if (uri != NULL && uri[0] != '\0') { + data->vr->sources = g_list_append(data->vr->sources, uri); + + l = NULL; + item = (GtkListItem *)gtk_list_item_new_with_label(uri); + gtk_object_set_data((GtkObject *)item, "source", uri); + gtk_widget_show((GtkWidget *)item); + l = g_list_append(NULL, item); + gtk_list_append_items(data->list, l); + gtk_list_select_child(data->list, (GtkWidget *)item); + data->current = uri; + } else { + g_free(uri); + } + set_sensitive(data); +} + +static void source_remove(GtkWidget *widget, struct _source_data *data) +{ + const char *source; + int index = 0; + GList *l; + GtkListItem *item; + + source = NULL; + while ((source = vfolder_rule_next_source(data->vr, source))) { + if (data->current == source) { + vfolder_rule_remove_source(data->vr, source); + item = g_list_nth_data(data->list->children, index); + l = g_list_append(NULL, item); + gtk_list_remove_items(data->list, l); + g_list_free(l); + data->current = NULL; + break; + } + index++; + } + set_sensitive(data); +} + +static GtkWidget *get_widget(FilterRule *fr, struct _RuleContext *f) +{ + GtkWidget *widget, *frame, *w; + GladeXML *gui; + const char *source; + VfolderRule *vr = (VfolderRule *)fr; + struct _source_data *data; + int i; + GList *l; + + widget = ((FilterRuleClass *)(parent_class))->get_widget(fr, f); + + data = g_malloc0(sizeof(*data)); + data->f = f; + data->vr = vr; + + gui = glade_xml_new(FILTER_GLADEDIR "/filter.glade", "vfolder_source_frame"); + frame = glade_xml_get_widget (gui, "vfolder_source_frame"); + + gtk_object_set_data_full((GtkObject *)frame, "data", data, g_free); + + for (i=0;ibuttons[i] = (GtkButton *)w = glade_xml_get_widget (gui, edit_buttons[i].name); + gtk_signal_connect((GtkObject *)w, "clicked", edit_buttons[i].func, data); + } + + w = glade_xml_get_widget (gui, "source_list"); + data->list = (GtkList *)w; + l = NULL; + source = NULL; + while ((source = vfolder_rule_next_source(vr, source))) { + GtkListItem *item = (GtkListItem *)gtk_list_item_new_with_label(source); + gtk_object_set_data((GtkObject *)item, "source", (void *)source); + gtk_widget_show((GtkWidget *)item); + l = g_list_append(l, item); + } + gtk_list_append_items(data->list, l); + gtk_signal_connect((GtkObject *)w, "select_child", select_source, data); + set_sensitive(data); + + gtk_box_pack_start(GTK_BOX(widget), frame, TRUE, TRUE, 3); + return widget; +} diff --git a/filter/vfolder-rule.h b/filter/vfolder-rule.h new file mode 100644 index 0000000000..c3fa130c84 --- /dev/null +++ b/filter/vfolder-rule.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2000 Helix Code Inc. + * + * Authors: Not Zed + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _VFOLDER_RULE_H +#define _VFOLDER_RULE_H + +#include +#include "filter-rule.h" + +#define VFOLDER_RULE(obj) GTK_CHECK_CAST (obj, vfolder_rule_get_type (), VfolderRule) +#define VFOLDER_RULE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, vfolder_rule_get_type (), VfolderRuleClass) +#define IS_VFOLDER_RULE(obj) GTK_CHECK_TYPE (obj, vfolder_rule_get_type ()) + +typedef struct _VfolderRule VfolderRule; +typedef struct _VfolderRuleClass VfolderRuleClass; + +struct _VfolderRule { + FilterRule parent; + struct _VfolderRulePrivate *priv; + + GList *sources; /* uri's of the source folders */ +}; + +struct _VfolderRuleClass { + FilterRuleClass parent_class; + + /* virtual methods */ + + /* signals */ +}; + +guint vfolder_rule_get_type (void); +VfolderRule *vfolder_rule_new (void); + +/* methods */ +void vfolder_rule_add_source (VfolderRule *vr, const char *uri); +void vfolder_rule_remove_source (VfolderRule *vr, const char *uri); +const char *vfolder_rule_find_source (VfolderRule *vr, const char *uri); +const char *vfolder_rule_next_source (VfolderRule *vr, const char *last); + +#endif /* ! _VFOLDER_RULE_H */ + -- cgit v1.2.3