aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filter/ChangeLog8
-rw-r--r--filter/Makefile8
-rw-r--r--filter/filter-druid.c329
-rw-r--r--filter/filter-druid.h23
-rw-r--r--filter/filter-editor.c329
-rw-r--r--filter/filter-editor.h53
-rw-r--r--filter/filter-xml.h2
7 files changed, 502 insertions, 250 deletions
diff --git a/filter/ChangeLog b/filter/ChangeLog
index d7e51cb53d..5b48899b49 100644
--- a/filter/ChangeLog
+++ b/filter/ChangeLog
@@ -1,3 +1,11 @@
+2000-02-24 NotZed <NotZed@HelixCode.com>
+
+ * filter-editor.c: New widget, a dialogue which uses filter-druid
+ to present the various editing views.
+
+ * filter-druid.c: Changed to just being a notebook with no tabs,
+ rather than a full druid (no next/prev/etc buttons).
+
2000-02-22 NotZed <NotZed@HelixCode.com>
* filter-xml.c (filter_clone_optionrule):
diff --git a/filter/Makefile b/filter/Makefile
index 04c6b33405..a462af4413 100644
--- a/filter/Makefile
+++ b/filter/Makefile
@@ -1,6 +1,6 @@
-OBJS = filter-arg-types.lo filter-arg.lo filter-xml.lo filter-format.lo
-SRCS = filter-arg-types.c filter-arg.c filter-xml.c filter-format.c
+OBJS = filter-arg-types.lo filter-arg.lo filter-xml.lo filter-format.lo filter-druid.lo
+SRCS = filter-arg-types.c filter-arg.c filter-xml.c filter-format.c filter-druid.c
LIBFILTEROBJS = filter-sexp.lo
LIBFILTERSRCS = filter-sexp.c
@@ -11,9 +11,9 @@ LIBTOOL=sh ../libtool
CFLAGS = `gnome-config --cflags xml gnome gtk gtkhtml gnomeui` -g -I../camel -I .. -I../libibex
LDFLAGS = `gnome-config --libs xml gnome gtk gtkhtml gnomeui` ../camel/libcamel.la -lpthread
-all: libfilter.la filter-driver filter-druid
+all: libfilter.la filter-editor
-filter-druid: $(OBJS) filter-druid.lo libfilter.la
+filter-editor: $(OBJS) filter-editor.lo libfilter.la
$(LIBTOOL) --mode link $(CC) $^ -o $@ $(LDFLAGS)
filter-driver: $(OBJS) filter-driver.lo libfilter.la
diff --git a/filter/filter-druid.c b/filter/filter-druid.c
index 16efdf8319..0bcb893172 100644
--- a/filter/filter-druid.c
+++ b/filter/filter-druid.c
@@ -44,6 +44,8 @@ struct _FilterDruidPrivate {
GtkWidget *notebook;
int page;
+ char *default_html;
+
/* page 0 */
GtkWidget *list0;
GtkWidget *html0;
@@ -62,9 +64,10 @@ static void build_druid(FilterDruid *d);
static void update_display(FilterDruid *f, int initial);
/* globals */
-static GnomeDialogClass *filter_druid_parent;
+static GtkNotebookClass *filter_druid_parent;
enum SIGNALS {
+ OPTION_SELECTED,
LAST_SIGNAL
};
@@ -86,18 +89,41 @@ filter_druid_get_type (void)
(GtkArgGetFunc) NULL
};
- type = gtk_type_unique (gnome_dialog_get_type (), &type_info);
+ type = gtk_type_unique (gtk_notebook_get_type (), &type_info);
}
return type;
}
static void
+object_finalize(FilterDruid *obj)
+{
+ struct _FilterDruidPrivate *p = _PRIVATE(obj);
+
+ g_free(p->default_html);
+
+ /* FIXME: free lists? */
+
+ GTK_OBJECT_CLASS(filter_druid_parent)->finalize(obj);
+}
+
+static void
filter_druid_class_init (FilterDruidClass *klass)
{
GtkObjectClass *object_class = (GtkObjectClass *) klass;
- filter_druid_parent = gtk_type_class (gnome_dialog_get_type ());
+ filter_druid_parent = gtk_type_class (gtk_notebook_get_type ());
+
+ object_class->finalize = object_finalize;
+
+ signals[OPTION_SELECTED] =
+ gtk_signal_new ("option_selected",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (FilterDruidClass, option_selected),
+ gtk_marshal_NONE__POINTER,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_POINTER);
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
}
@@ -152,8 +178,6 @@ find_optionrule(struct filter_option *option, char *name)
return NULL;
}
-static char nooption[] = "<h2>Select option</h2><p>Select an option type from the list above.</p>"
-"<p>This will set the basic rule options for your new filtering rule.</p>";
static int display_order[] = {
FILTER_XML_MATCH,
FILTER_XML_EXCEPT,
@@ -171,7 +195,7 @@ static char *display_posttext[] = {
};
void
-html_write_options(GtkHTML *html, struct filter_option *option)
+html_write_options(GtkHTML *html, struct filter_option *option, char *def)
{
GtkHTMLStreamHandle *stream;
GList *optionrulel;
@@ -211,7 +235,9 @@ html_write_options(GtkHTML *html, struct filter_option *option)
}
}
} else {
- gtk_html_write(html, stream, nooption, strlen(nooption));
+ if (def == NULL)
+ def = "Select options.";
+ gtk_html_write(html, stream, def, strlen(def));
}
gtk_html_end(html, stream, GTK_HTML_STREAM_OK);
}
@@ -282,9 +308,6 @@ fill_options(GList *options)
return items;
}
-GtkWidget *list_global, *html_global;
-struct filter_option *option_current;
-
static void
select_rule_child(GtkList *list, GtkWidget *child, FilterDruid *f)
{
@@ -337,6 +360,7 @@ select_option_child(GtkList *list, GtkWidget *child, FilterDruid *f)
}
if (f->option_current) {
+ printf("freeing current option\n");
/* free option_current copy */
optionsl = f->option_current->options;
while (optionsl) {
@@ -351,6 +375,8 @@ select_option_child(GtkList *list, GtkWidget *child, FilterDruid *f)
if (child) {
op = gtk_object_get_data(GTK_OBJECT(child), "option");
+
+ printf("option = %p\n", op);
/* clone the option */
new = g_malloc(sizeof(*new));
@@ -366,6 +392,8 @@ select_option_child(GtkList *list, GtkWidget *child, FilterDruid *f)
optionsl = g_list_next(optionsl);
}
f->option_current = new;
+
+ gtk_signal_emit(GTK_OBJECT(f), signals[OPTION_SELECTED], op);
}
update_display(f, 0);
@@ -440,8 +468,6 @@ update_display(FilterDruid *f, int initial)
switch (p->page) {
case 0:
printf("option_current = %p <###################\n", f->option_current);
- gnome_dialog_set_sensitive((GnomeDialog *)f, 0, FALSE);
- gnome_dialog_set_sensitive((GnomeDialog *)f, 1, f->option_current != NULL);
if (initial) {
printf("adding options\n");
@@ -453,15 +479,11 @@ update_display(FilterDruid *f, int initial)
gtk_frame_set_label(p->listframe0, "Select rule type");
}
- html_write_options((GtkHTML *)p->html0, f->option_current);
+ html_write_options((GtkHTML *)p->html0, f->option_current, p->default_html);
break;
case 1:
case 2:
case 3:
- gnome_dialog_set_sensitive((GnomeDialog *)f, 1, TRUE);
- gnome_dialog_set_sensitive((GnomeDialog *)f, 0, TRUE);
- gnome_dialog_set_sensitive((GnomeDialog *)f, 2, FALSE);
-
if (initial) {
printf("adding rules\n");
gtk_signal_handler_block_by_data((GtkObject *)p->list0, f);
@@ -473,13 +495,9 @@ update_display(FilterDruid *f, int initial)
gtk_notebook_set_page(GTK_NOTEBOOK(p->notebook), 0);
}
- html_write_options((GtkHTML *)p->html0, f->option_current);
+ html_write_options((GtkHTML *)p->html0, f->option_current, p->default_html);
break;
case 4:
- gnome_dialog_set_sensitive((GnomeDialog *)f, 1, FALSE);
- gnome_dialog_set_sensitive((GnomeDialog *)f, 0, TRUE);
- gnome_dialog_set_sensitive((GnomeDialog *)f, 2, TRUE);
-
if (initial) {
char *text;
text = filter_description_text(f->option_current->description, NULL);
@@ -489,7 +507,7 @@ update_display(FilterDruid *f, int initial)
if (f->option_current->type == FILTER_XML_SEND) {
text = "Filter messages sent";
} else {
- text = " Filter messages received";
+ text = "Filter messages received";
}
gtk_entry_set_text(GTK_ENTRY(p->name1), text);
} else {
@@ -499,7 +517,7 @@ update_display(FilterDruid *f, int initial)
gtk_notebook_set_page(GTK_NOTEBOOK(p->notebook), 1);
}
- html_write_options((GtkHTML *)p->html1, f->option_current);
+ html_write_options((GtkHTML *)p->html1, f->option_current, p->default_html);
break;
}
@@ -508,12 +526,32 @@ update_display(FilterDruid *f, int initial)
void
filter_druid_set_rules(FilterDruid *f, GList *options, GList *rules, struct filter_option *current)
{
+ struct filter_option *new;
+ GList *optionsl;
+
f->options = options;
f->rules = rules;
f->user = NULL;
- /* FIXME: free this list if it isn't empty ... */
- f->option_current = current;
+ if (current) {
+ /* FIXME: free this list if it isn't empty ... */
+ /* clone the 'current' option */
+ new = g_malloc(sizeof(*new));
+ new->type = current->type;
+ new->description = current->description;
+ new->options = NULL;
+ optionsl = current->options;
+ while (optionsl) {
+ struct filter_optionrule *ornew,
+ *or = optionsl->data;
+ ornew = filter_clone_optionrule(or);
+ new->options = g_list_append(new->options, ornew);
+ optionsl = g_list_next(optionsl);
+ }
+ f->option_current = new;
+ } else {
+ f->option_current = NULL;
+ }
update_display(f, 1);
}
@@ -524,14 +562,16 @@ build_druid(FilterDruid *d)
GtkWidget *vbox, *frame, *scrolled_window, *list, *html, *hbox, *label, *vbox1;
struct _FilterDruidPrivate *p = _PRIVATE(d);
+#if 0
gnome_dialog_append_buttons((GnomeDialog *)d, "Prev", "Next", "Finish", "Cancel", 0);
gnome_dialog_set_close((GnomeDialog *)d, FALSE);
gnome_dialog_set_sensitive((GnomeDialog *)d, 0, FALSE);
gnome_dialog_set_sensitive((GnomeDialog *)d, 1, FALSE);
gnome_dialog_set_sensitive((GnomeDialog *)d, 2, FALSE);
gnome_dialog_set_default((GnomeDialog *)d, 1);
+#endif
- p->notebook = gtk_notebook_new();
+ p->notebook = d;
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(p->notebook), FALSE);
/* page0, initial setup page */
@@ -570,7 +610,7 @@ build_druid(FilterDruid *d)
gtk_signal_connect(GTK_OBJECT(list), "select_child", select_option_child, d);
gtk_signal_connect(GTK_OBJECT(list), "unselect_child", select_option_child, d);
/* gtk_signal_connect(GTK_OBJECT(list), "unselect_child", unselect_option_child, d); */
- gtk_signal_connect(GTK_OBJECT(d), "clicked", dialogue_clicked, d);
+/* gtk_signal_connect(GTK_OBJECT(d), "clicked", dialogue_clicked, d);*/
gtk_signal_connect(GTK_OBJECT(html), "link_clicked", arg_link_clicked, d);
@@ -617,232 +657,33 @@ build_druid(FilterDruid *d)
gtk_signal_connect(GTK_OBJECT(html), "link_clicked", arg_link_clicked, d);
gtk_widget_show_all(p->notebook);
-
- gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(d)->vbox), p->notebook, TRUE, TRUE, 0);
}
-#if 0
-/* crappo */
-static void
-build_first(FilterDruid *d)
+void
+filter_druid_set_page(FilterDruid *f, enum FilterDruidPage page)
{
- GtkWidget *vbox, *frame, *scrolled_window, *list, *html, *hbox;
- struct _FilterDruidPrivate *p = _PRIVATE(d);
-
- gnome_dialog_append_buttons((GnomeDialog *)d, "Prev", "Next", "Finish", "Cancel", 0);
- gnome_dialog_set_close((GnomeDialog *)d, FALSE);
-
- p->notebook = gtk_notebook_new();
- gtk_notebook_set_show_tabs(GTK_NOTEBOOK(p->notebook), FALSE);
-
- /* page0, initial setup page */
- hbox = gtk_hbox_new(FALSE, 0);
-
- vbox = gtk_vbox_new(FALSE, 0);
- frame = gtk_frame_new("Filters");
- list = gtk_list_new();
- scrolled_window = gtk_scrolled_window_new(NULL, NULL);
-
- gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), list);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_container_set_focus_vadjustment
- (GTK_CONTAINER (list),
- gtk_scrolled_window_get_vadjustment
- (GTK_SCROLLED_WINDOW (scrolled_window)));
- gtk_container_add(GTK_CONTAINER(frame), scrolled_window);
- gtk_box_pack_start((GtkBox *)vbox, frame, TRUE, TRUE, 0);
-
- frame = gtk_frame_new("Filter Description");
- html = gtk_html_new();
- scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_container_add(GTK_CONTAINER(scrolled_window), html);
- gtk_container_add(GTK_CONTAINER(frame), scrolled_window);
- gtk_box_pack_start((GtkBox *)vbox, frame, TRUE, TRUE, 0);
-
- p->html0 = html;
- p->list0 = list;
-
- gtk_widget_set_usize(html, 300, 200);
- gtk_widget_set_usize(list, 300, 200);
-
- gtk_box_pack_start((GtkBox *)hbox, vbox, TRUE, TRUE, 0);
-
- /* buttons */
- vbox = gtk_vbox_new(FALSE, 0);
-
- p->add0 = gtk_button_new_with_label ("Add");
- p->remove0 = gtk_button_new_with_label ("Remove");
- p->up0 = gtk_button_new_with_label ("Up");
- p->down0 = gtk_button_new_with_label ("Down");
-
- gtk_box_pack_start((GtkBox *)vbox, p->add0, FALSE, TRUE, 0);
- gtk_box_pack_start((GtkBox *)vbox, p->remove0, FALSE, TRUE, 0);
- gtk_box_pack_start((GtkBox *)vbox, p->up0, FALSE, TRUE, 0);
- gtk_box_pack_start((GtkBox *)vbox, p->down0, FALSE, TRUE, 0);
-
- gtk_box_pack_start((GtkBox *)hbox, vbox, FALSE, FALSE, 0);
-
- gtk_notebook_append_page(GTK_NOTEBOOK(p->notebook), hbox, NULL);
-
- gtk_widget_show_all(p->notebook);
+ struct _FilterDruidPrivate *p = _PRIVATE(f);
+ int initial = p->page != page;
- gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(d)->vbox), p->notebook, TRUE, TRUE, 0);
+ p->page = page;
+ update_display(f, initial);
}
-#endif
-void create_dialogue(void)
-{
- GtkWidget *dialogue,
- *scrolled_window,
- *list,
- *html,
- *frame;
-
- dialogue = gnome_dialog_new("Filter Rules",
- GNOME_STOCK_BUTTON_PREV , GNOME_STOCK_BUTTON_NEXT,
- "Finish", GNOME_STOCK_BUTTON_CANCEL, 0);
- list = gtk_list_new();
- frame = gtk_frame_new("Filter Type");
- scrolled_window = gtk_scrolled_window_new(NULL, NULL);
-
- gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), list);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_container_set_focus_vadjustment
- (GTK_CONTAINER (list),
- gtk_scrolled_window_get_vadjustment
- (GTK_SCROLLED_WINDOW (scrolled_window)));
- gtk_container_add(GTK_CONTAINER(frame), scrolled_window);
- gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialogue)->vbox), frame, TRUE, TRUE, GNOME_PAD);
-
-#if 0
- gtk_signal_connect(GTK_OBJECT(list), "select_child", select_rule_child, NULL);
- gtk_signal_connect(GTK_OBJECT(list), "unselect_child", select_rule_child, NULL);
-#else
- gtk_signal_connect(GTK_OBJECT(list), "select_child", select_option_child, NULL);
- gtk_signal_connect(GTK_OBJECT(list), "unselect_child", select_option_child, NULL);
-#endif
-
- frame = gtk_frame_new("Filter Description");
- html = gtk_html_new();
- scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_container_add(GTK_CONTAINER(scrolled_window), html);
- gtk_container_add(GTK_CONTAINER(frame), scrolled_window);
- gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialogue)->vbox), frame, TRUE, TRUE, GNOME_PAD);
-
- gtk_signal_connect(GTK_OBJECT(html), "link_clicked", arg_link_clicked, NULL);
- gtk_signal_connect(GTK_OBJECT(dialogue), "clicked", dialogue_clicked, NULL);
-
- list_global = list;
- html_global = html;
+void
+filter_druid_set_default_html(FilterDruid *f, const char *html)
+{
+ struct _FilterDruidPrivate *p = _PRIVATE(f);
- gtk_widget_show_all(dialogue);
+ g_free(p->default_html);
+ p->default_html = g_strdup(html);
}
-int main(int argc, char **argv)
+enum FilterDruidPage
+filter_druid_get_page(FilterDruid *f)
{
- FilterSEXP *f;
- FilterSEXPResult *r;
- GList *rules, *options, *options2;
- xmlDocPtr doc, out, optionset, filteroptions;
- GString *s;
-
- gnome_init("Test", "0.0", argc, argv);
- gdk_rgb_init ();
- gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
- gtk_widget_set_default_visual (gdk_rgb_get_visual ());
-
- {
- GtkWidget *d = (GtkWidget *)filter_druid_new();
-
- doc = xmlParseFile("filterdescription.xml");
- rules = filter_load_ruleset(doc);
- options = filter_load_optionset(doc, rules);
- options2 = options;
- out = xmlParseFile("saveoptions.xml");
- options = filter_load_optionset(out, rules);
-
- filter_druid_set_rules((FilterDruid *)d, options2, rules, options->data);
-/* filter_druid_set_rules((FilterDruid *)d, options2, rules, NULL);*/
-
- gtk_widget_show(d);
- gtk_main();
- }
-#if 0
-
- create_dialogue();
-
- doc = xmlParseFile("filterdescription.xml");
- rules = filter_load_ruleset(doc);
- options = filter_load_optionset(doc, rules);
- options2 = options;
- out = xmlParseFile("saveoptions.xml");
- options = filter_load_optionset(out, rules);
-
-#if 0
- option_current = options->data;
- fill_rules(list_global, rules, options->data, FILTER_XML_MATCH);
-#else
- option_current = NULL;
- fill_options(list_global, options2);
-#endif
- gtk_main();
-
- while (options) {
- struct filter_option *fo = options->data;
- GList *optionrulel;
-
- optionrulel = fo->options;
- while (optionrulel) {
- struct filter_optionrule *or = optionrulel->data;
-
- printf("formatting rule: %s\n", or->rule->name);
-
- /*filter_description_text(or->rule->description, or->args);*/
- filter_description_html_write(or->rule->description, or->args, NULL, NULL);
-
- optionrulel = g_list_next(optionrulel);
- }
- options = g_list_next(options);
- }
-
- return 0;
-
- s = g_string_new("");
- g_string_append(s, "");
-
- printf("total rule = '%s'\n", s->str);
-
- f = filter_sexp_new();
- filter_sexp_add_variable(f, 0, "sender", NULL);
- filter_sexp_add_variable(f, 0, "receipient", NULL);
- filter_sexp_add_variable(f, 0, "folder", NULL);
-
- /* simple functions */
- filter_sexp_add_function(f, 0, "header-get", NULL, NULL);
- filter_sexp_add_function(f, 0, "header-contains", NULL, NULL);
- filter_sexp_add_function(f, 0, "copy-to", NULL, NULL);
-
- filter_sexp_add_ifunction(f, 0, "set", NULL, NULL);
-
- /* control functions */
- filter_sexp_add_ifunction(f, 0, "match-all", NULL, NULL);
- filter_sexp_add_ifunction(f, 0, "match", NULL, NULL);
- filter_sexp_add_ifunction(f, 0, "action", NULL, NULL);
- filter_sexp_add_ifunction(f, 0, "except", NULL, NULL);
+ struct _FilterDruidPrivate *p = _PRIVATE(f);
- filter_sexp_input_text(f, s->str, strlen(s->str));
- filter_sexp_parse(f);
-#endif
-
+ return p->page;
}
+
diff --git a/filter/filter-druid.h b/filter/filter-druid.h
index 1b88847041..7927dc70dd 100644
--- a/filter/filter-druid.h
+++ b/filter/filter-druid.h
@@ -32,8 +32,16 @@
typedef struct _FilterDruid FilterDruid;
typedef struct _FilterDruidClass FilterDruidClass;
+enum FilterDruidPage {
+ FILTER_DRUID_SELECT_RULE,
+ FILTER_DRUID_SELECT_MATCH,
+ FILTER_DRUID_SELECT_NOMATCH,
+ FILTER_DRUID_SELECT_ACTION,
+ FILTER_DRUID_SELECT_FINISH
+};
+
struct _FilterDruid {
- GnomeDialog parent;
+ GtkNotebook parent;
GList *options; /* all options */
GList *rules; /* all rules */
@@ -45,7 +53,10 @@ struct _FilterDruid {
};
struct _FilterDruidClass {
- GnomeDialogClass parent_class;
+ GtkNotebookClass parent_class;
+
+ /* signals */
+ void (*option_selected)(FilterDruid *f, struct filter_option *option);
};
guint filter_druid_get_type (void);
@@ -53,5 +64,13 @@ FilterDruid *filter_druid_new (void);
/* Hmm, glists suck, no typesafety */
void filter_druid_set_rules(FilterDruid *f, GList *options, GList *rules, struct filter_option *userrule);
+void filter_druid_set_default_html(FilterDruid *f, const char *text);
+
+/* set the page of display */
+void filter_druid_set_page(FilterDruid *f, enum FilterDruidPage page);
+enum FilterDruidPage filter_druid_get_page(FilterDruid *f);
+
+/* check if the druid is allowed to finish at this point */
+gboolean filter_druid_can_finish(FilterDruid *f);
#endif /* ! _FILTER_DRUID_H */
diff --git a/filter/filter-editor.c b/filter/filter-editor.c
new file mode 100644
index 0000000000..d37769359f
--- /dev/null
+++ b/filter/filter-editor.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2000 Helix Code Inc.
+ *
+ * Authors: Michael Zucchi <notzed@helixcode.com>
+ *
+ * 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 "filter-druid.h"
+#include "filter-editor.h"
+
+
+static void filter_editor_class_init (FilterEditorClass *klass);
+static void filter_editor_init (FilterEditor *obj);
+
+static GnomeDialogClass *filter_editor_parent;
+
+#define _PRIVATE(x) (((FilterEditor *)(x))->priv)
+
+struct _FilterEditorPrivate {
+ FilterDruid *druid;
+
+ GtkWidget *edit, *add, *remove, *up, *down;
+
+ /* for sub-druid */
+ GtkWidget *druid_dialogue;
+ FilterDruid *druid_druid;
+};
+
+enum SIGNALS {
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+guint
+filter_editor_get_type (void)
+{
+ static guint type = 0;
+
+ if (!type) {
+ GtkTypeInfo type_info = {
+ "FilterEditor",
+ sizeof (FilterEditor),
+ sizeof (FilterEditorClass),
+ (GtkClassInitFunc) filter_editor_class_init,
+ (GtkObjectInitFunc) filter_editor_init,
+ (GtkArgSetFunc) NULL,
+ (GtkArgGetFunc) NULL
+ };
+
+ type = gtk_type_unique (gnome_dialog_get_type (), &type_info);
+ }
+
+ return type;
+}
+
+static void
+filter_editor_class_init (FilterEditorClass *klass)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *) klass;
+
+ filter_editor_parent = gtk_type_class (gnome_dialog_get_type ());
+
+ gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+}
+
+static void
+filter_editor_init (FilterEditor *obj)
+{
+ obj->priv = g_malloc0(sizeof(*obj->priv));
+}
+
+
+static void
+sensitise(FilterEditor *e)
+{
+ struct _FilterEditorPrivate *p = _PRIVATE(e);
+
+ gtk_widget_set_sensitive(p->add, TRUE);
+ gtk_widget_set_sensitive(p->edit, e->option_current != NULL);
+ gtk_widget_set_sensitive(p->remove, e->option_current != NULL);
+ gtk_widget_set_sensitive(p->up, g_list_index(e->useroptions, e->option_current)>0);
+ gtk_widget_set_sensitive(p->down, g_list_index(e->useroptions, e->option_current)!=g_list_length(e->useroptions)-1);
+}
+
+static void
+druid_option_selected(FilterDruid *f, struct filter_option *option, FilterEditor *e)
+{
+ printf("option selected: %p\n", option);
+ e->option_current = option;
+ sensitise(e);
+}
+
+static void
+druid_dialogue_clicked(GnomeDialog *d, int button, FilterEditor *e)
+{
+ struct _FilterEditorPrivate *p = _PRIVATE(e);
+ int page = filter_druid_get_page(p->druid_druid);
+
+ switch(button) {
+ case 1:
+ if (page<4) {
+ page++;
+ }
+ break;
+ case 0:
+ if (page>0) {
+ page--;
+ }
+ break;
+ case 2:
+ printf("Finish!\n");
+ if (p->druid_druid->option_current) {
+ /* FIXME: this should be copied? */
+ e->useroptions = g_list_append(e->useroptions, p->druid_druid->option_current);
+ filter_druid_set_rules(p->druid, e->useroptions, e->rules, NULL);
+ }
+ case 3:
+ printf("cancel!\n");
+ gnome_dialog_close(d);
+ return;
+ }
+ filter_druid_set_page(p->druid_druid, page);
+
+ gnome_dialog_set_sensitive(p->druid_dialogue, 0, page>0);
+ gnome_dialog_set_sensitive(p->druid_dialogue, 1, page<4);
+ gnome_dialog_set_sensitive(p->druid_dialogue, 2, page==4); /* FIXME: make this depenedant on when the rules are actually done */
+}
+
+static void
+druid_dialogue_option_selected(FilterDruid *f, struct filter_option *option, FilterEditor *e)
+{
+ struct _FilterEditorPrivate *p = _PRIVATE(e);
+
+ gnome_dialog_set_sensitive(p->druid_dialogue, 1, TRUE);
+}
+
+static void
+add_or_edit(FilterEditor *e, struct filter_option *option)
+{
+ GnomeDialog *dialogue;
+ FilterDruid *druid;
+ struct _FilterEditorPrivate *p = _PRIVATE(e);
+
+ dialogue = gnome_dialog_new(option?"Edit Filter":"Create filter", "Prev", "Next", "Finish", "Cancel", 0);
+
+ p->druid_dialogue = dialogue;
+
+ gnome_dialog_set_close(dialogue, FALSE);
+ gnome_dialog_set_sensitive(dialogue, 0, FALSE);
+ gnome_dialog_set_sensitive(dialogue, 1, FALSE);
+ gnome_dialog_set_sensitive(dialogue, 2, FALSE);
+ gnome_dialog_set_default(dialogue, 1);
+
+ gtk_signal_connect(GTK_OBJECT(dialogue), "clicked", druid_dialogue_clicked, e);
+
+ druid = filter_druid_new();
+
+ p->druid_druid = druid;
+
+ filter_druid_set_default_html(p->druid_druid, "<h2>Create Filtering Rule</h2>"
+ "<p>Select one of the base rules above, then continue "
+ "forwards to customise it.</p>");
+
+ filter_druid_set_rules(druid, e->systemoptions, e->rules, option);
+ gtk_box_pack_start(dialogue->vbox, druid, TRUE, TRUE, 0);
+
+ if (option) {
+ druid_dialogue_clicked(dialogue, 1, e);
+ }
+
+ gtk_signal_connect(druid, "option_selected", druid_dialogue_option_selected, e);
+
+ gtk_widget_show(druid);
+ gtk_widget_show(dialogue);
+}
+
+static void
+add_clicked(GtkWidget *w, FilterEditor *e)
+{
+ printf("add new ...\n");
+
+ add_or_edit(e, NULL);
+}
+
+static void
+edit_clicked(GtkWidget *w, FilterEditor *e)
+{
+ printf("add new ...\n");
+
+ add_or_edit(e, e->option_current);
+}
+
+static void
+remove_clicked(GtkWidget *w, FilterEditor *e)
+{
+ printf("remove current ...\n");
+}
+
+static void
+up_clicked(GtkWidget *w, FilterEditor *e)
+{
+ printf("up ...\n");
+}
+
+static void
+down_clicked(GtkWidget *w, FilterEditor *e)
+{
+ printf("down ...\n");
+}
+
+/* build the contents of the editor */
+static void
+build_editor(FilterEditor *e)
+{
+ struct _FilterEditorPrivate *p = _PRIVATE(e);
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+
+ hbox = gtk_hbox_new(FALSE, 3);
+
+ p->druid = (GtkWidget *)filter_druid_new();
+ gtk_box_pack_start((GtkBox *)hbox, p->druid, TRUE, TRUE, 0);
+
+ vbox = gtk_vbox_new(FALSE, 0);
+
+ p->edit = gtk_button_new_with_label ("Edit");
+ p->add = gtk_button_new_with_label ("Add");
+ p->remove = gtk_button_new_with_label ("Remove");
+ p->up = gtk_button_new_with_label ("Up");
+ p->down = gtk_button_new_with_label ("Down");
+
+ gtk_box_pack_start((GtkBox *)vbox, p->edit, FALSE, TRUE, 0);
+ gtk_box_pack_start((GtkBox *)vbox, p->add, FALSE, TRUE, 3);
+ gtk_box_pack_start((GtkBox *)vbox, p->remove, FALSE, TRUE, 0);
+ gtk_box_pack_start((GtkBox *)vbox, p->up, FALSE, TRUE, 3);
+ gtk_box_pack_start((GtkBox *)vbox, p->down, FALSE, TRUE, 0);
+
+ gtk_box_pack_start((GtkBox *)hbox, vbox, FALSE, FALSE, 0);
+
+ gtk_box_pack_start((GtkBox *)e->parent.vbox, hbox, TRUE, TRUE, 0);
+
+ gtk_signal_connect(p->druid, "option_selected", druid_option_selected, e);
+
+ gtk_signal_connect(p->edit, "clicked", edit_clicked, e);
+ gtk_signal_connect(p->add, "clicked", add_clicked, e);
+ gtk_signal_connect(p->remove, "clicked", remove_clicked, e);
+ gtk_signal_connect(p->up, "clicked", up_clicked, e);
+ gtk_signal_connect(p->down, "clicked", down_clicked, e);
+
+ filter_druid_set_default_html(p->druid, "<h2>Filtering Rules</h2>"
+ "<p>Select one of the rules above to <i>view</i>, and "
+ "<i>edit</i>. Or <i>Add</i> a new rule.</p>");
+
+ gtk_widget_show_all(hbox);
+ sensitise(e);
+}
+
+
+/**
+ * filter_editor_new:
+ *
+ * Create a new FilterEditor object.
+ *
+ * Return value: A new FilterEditor widget.
+ **/
+FilterEditor *
+filter_editor_new (void)
+{
+ FilterEditor *new = FILTER_EDITOR ( gtk_type_new (filter_editor_get_type ()));
+
+ build_editor(new);
+
+ return new;
+}
+
+void
+filter_editor_set_rules(FilterEditor *e, GList *rules, GList *systemoptions, GList *useroptions)
+{
+ struct _FilterEditorPrivate *p = _PRIVATE(e);
+
+ e->rules= rules;
+ e->systemoptions = systemoptions;
+ e->useroptions = useroptions;
+
+ filter_druid_set_rules(p->druid, useroptions, rules, NULL);
+}
+
+int main(int argc, char **argv)
+{
+ GList *rules, *options, *options2;
+ xmlDocPtr doc, out, optionset, filteroptions;
+ GString *s;
+
+ gnome_init("Test", "0.0", argc, argv);
+ gdk_rgb_init ();
+ gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
+ gtk_widget_set_default_visual (gdk_rgb_get_visual ());
+
+ {
+
+ GtkWidget *w = filter_editor_new();
+
+ doc = xmlParseFile("filterdescription.xml");
+ rules = filter_load_ruleset(doc);
+ options = filter_load_optionset(doc, rules);
+ options2 = options;
+ out = xmlParseFile("saveoptions.xml");
+ options = filter_load_optionset(out, rules);
+
+ filter_editor_set_rules(w, rules, options2, options);
+
+ gtk_widget_show(w);
+ gtk_main();
+ }
+}
diff --git a/filter/filter-editor.h b/filter/filter-editor.h
new file mode 100644
index 0000000000..612e9ec166
--- /dev/null
+++ b/filter/filter-editor.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2000 Helix Code Inc.
+ *
+ * Authors: Michael Zucchi <notzed@helixcode.com>
+ *
+ * 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 _FILTER_EDITOR_H
+#define _FILTER_EDITOR_H
+
+#include <gtk/gtk.h>
+#include <gnome.h>
+
+#define FILTER_EDITOR(obj) GTK_CHECK_CAST (obj, filter_editor_get_type (), FilterEditor)
+#define FILTER_EDITOR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, filter_editor_get_type (), FilterEditorClass)
+#define IS_FILTER_EDITOR(obj) GTK_CHECK_TYPE (obj, filter_editor_get_type ())
+
+typedef struct _FilterEditor FilterEditor;
+typedef struct _FilterEditorClass FilterEditorClass;
+
+struct _FilterEditor {
+ GnomeDialog parent;
+
+ struct _FilterEditorPrivate *priv;
+
+ GList *rules;
+ GList *systemoptions;
+ GList *useroptions;
+
+ struct filter_option *option_current;
+};
+
+struct _FilterEditorClass {
+ GnomeDialogClass parent_class;
+};
+
+guint filter_editor_get_type (void);
+FilterEditor *filter_editor_new (void);
+
+#endif /* ! _FILTER_EDITOR_H */
diff --git a/filter/filter-xml.h b/filter/filter-xml.h
index b5d3255560..a2e0cfada0 100644
--- a/filter/filter-xml.h
+++ b/filter/filter-xml.h
@@ -5,6 +5,8 @@
#include <glib.h>
#include <gnome-xml/tree.h>
+#include "filter-arg.h"
+
enum filter_xml_token {
FILTER_XML_TEXT=0,
FILTER_XML_RULE,