aboutsummaryrefslogtreecommitdiffstats
path: root/filter/filter-driver.c
diff options
context:
space:
mode:
authorNotZed <NotZed@HelixCode.com>2000-02-19 09:55:48 +0800
committerMichael Zucci <zucchi@src.gnome.org>2000-02-19 09:55:48 +0800
commitac051f19eea6551b5e8075e30cd00b4f25c9b1cb (patch)
treea3e0fdb76cd22b3932e772385109677c3c4d56fe /filter/filter-driver.c
parente72c45d304fb6e538aad8ceb9ce07b1d8c59156f (diff)
downloadgsoc2013-evolution-ac051f19eea6551b5e8075e30cd00b4f25c9b1cb.tar
gsoc2013-evolution-ac051f19eea6551b5e8075e30cd00b4f25c9b1cb.tar.gz
gsoc2013-evolution-ac051f19eea6551b5e8075e30cd00b4f25c9b1cb.tar.bz2
gsoc2013-evolution-ac051f19eea6551b5e8075e30cd00b4f25c9b1cb.tar.lz
gsoc2013-evolution-ac051f19eea6551b5e8075e30cd00b4f25c9b1cb.tar.xz
gsoc2013-evolution-ac051f19eea6551b5e8075e30cd00b4f25c9b1cb.tar.zst
gsoc2013-evolution-ac051f19eea6551b5e8075e30cd00b4f25c9b1cb.zip
Now have loader/save, basic gui elements (which i want
to change), and uh, other stuff i forget right now. 2000-02-18 NotZed <NotZed@HelixCode.com> * Uh, more changes, lots, its still work in progress. svn path=/trunk/; revision=1851
Diffstat (limited to 'filter/filter-driver.c')
-rw-r--r--filter/filter-driver.c386
1 files changed, 338 insertions, 48 deletions
diff --git a/filter/filter-driver.c b/filter/filter-driver.c
index 6df07e76b8..b51e3f0705 100644
--- a/filter/filter-driver.c
+++ b/filter/filter-driver.c
@@ -10,19 +10,23 @@
#include "filter-arg-types.h"
#include "filter-xml.h"
#include "filter-sexp.h"
+#include "filter-format.h"
extern int filter_find_arg(FilterArg *a, char *name);
+#include "check.xpm"
+#include "blank.xpm"
+
/*
splices ${cc} lines into a single string
*/
int
-expand_variables(GString *out, char *source, GList *args, int index)
+expand_variables(GString *out, char *source, GList *args, GHashTable *globals)
{
GList *argl;
FilterArg *arg;
char *name= alloca(32);
- char *start, *end, *newstart, *tmp;
+ char *start, *end, *newstart, *tmp, *val;
int namelen=32;
int len=0;
int ok = 0;
@@ -37,13 +41,31 @@ expand_variables(GString *out, char *source, GList *args, int index)
}
memcpy(name, newstart+2, len);
name[len] = 0;
- argl = g_list_find_custom(args, name, filter_find_arg);
+ argl = g_list_find_custom(args, name, (GCompareFunc) filter_find_arg);
if (argl) {
+ int i, count;
+
+ tmp = g_strdup_printf("%.*s", newstart-start, start);
+ printf("appending: %s\n", tmp);
+ g_string_append(out, tmp);
+ g_free(tmp);
+
arg = argl->data;
- tmp = g_strdup_printf("%.*s%s", newstart-start, start, filter_arg_get_value_as_string(arg, index));
+ count = filter_arg_get_count(arg);
+ for (i=0;i<count;i++) {
+ printf("appending '%s'\n", filter_arg_get_value_as_string(arg, i));
+ g_string_append(out, " \"");
+ g_string_append(out, filter_arg_get_value_as_string(arg, i));
+ g_string_append(out, "\"");
+ }
+ } else if ( (val = g_hash_table_lookup(globals, name)) ) {
+ tmp = g_strdup_printf("%.*s", newstart-start, start);
printf("appending: %s\n", tmp);
g_string_append(out, tmp);
g_free(tmp);
+ g_string_append(out, " \"");
+ g_string_append(out, val);
+ g_string_append(out, "\"");
} else {
ok = 1;
tmp = g_strdup_printf("%.*s", end-start+1, start);
@@ -66,54 +88,23 @@ expand_filter_option(GString *s, struct filter_option *op)
{
GList *optionl;
FilterArg *arg;
+ GHashTable *globals;
+
+ globals = g_hash_table_new(g_str_hash, g_str_equal);
+
+ g_hash_table_insert(globals, "self-email", "mzucchi@dehaa.sa.gov.au");
g_string_append(s, "(and ");
optionl = op->options;
while (optionl) {
struct filter_optionrule *or = optionl->data;
- if (or->rule->type == FILTER_XML_MATCH) {
- GList *argl;
- int max=1, count;
- int i;
-
- /* find out how many values we have in each arg (rule
- is repeated that many times for each arg) */
- argl = or->args;
- while (argl) {
- arg = argl->data;
- count = filter_arg_get_count(arg);
- if (count>=max && max>1) {
- g_warning("Rule '%s' has too many multi-valued values, ignored", or->rule->name);
- goto next_rule;
- }
- if (count>max) {
- max = count;
- }
- argl = g_list_next(argl);
- }
- g_string_append(s, "(or ");
- for (i=0;i<max;i++) {
- expand_variables(s, or->rule->code, or->args, i);
- }
- g_string_append(s, ") ");
- }
- next_rule:
- optionl = g_list_next(optionl);
- }
-#if 0
- optionl = op->options;
- while (optionl) {
- struct filter_optionrule *or = optionl->data;
- if (or->rule->type == FILTER_XML_EXCEPT) {
- g_string_append(s, " (except \"");
- g_string_append(s, or->rule->name);
- g_string_append(s, "\" ");
- g_string_append(s, or->rule->code);
- g_string_append(s, " ) ");
+ if (or->rule->type == FILTER_XML_MATCH
+ || or->rule->type == FILTER_XML_EXCEPT) {
+ expand_variables(s, or->rule->code, or->args, globals);
}
optionl = g_list_next(optionl);
}
-#endif
+
g_string_append(s, ")");
#if 0
optionl = op->options;
@@ -130,21 +121,320 @@ expand_filter_option(GString *s, struct filter_option *op)
printf("combined rule '%s'\n", s->str);
}
+struct filter_optionrule *
+find_optionrule(struct filter_option *option, char *name)
+{
+ GList *optionrulel;
+ struct filter_optionrule *or;
+
+ optionrulel = option->options;
+ while (optionrulel) {
+ or = optionrulel->data;
+ if (!strcmp(or->rule->name, name)) {
+ return or;
+ }
+ optionrulel = g_list_next(optionrulel);
+ }
+ return NULL;
+}
+
+void
+html_write_options(GtkHTML *html, struct filter_option *option)
+{
+ GtkHTMLStreamHandle *stream;
+ GList *optionrulel;
+
+ stream = gtk_html_begin(html, "");
+ gtk_html_write(html, stream, "<body bgcolor=white alink=blue>", strlen("<body bgcolor=white alink=blue>"));
+ optionrulel = option->options;
+ while (optionrulel) {
+ struct filter_optionrule *or = optionrulel->data;
+
+ filter_description_html_write(or->rule->description, or->args, html, stream);
+ gtk_html_write(html, stream, "<br>", strlen("<br>"));
+ optionrulel = g_list_next(optionrulel);
+ }
+ gtk_html_end(html, stream, GTK_HTML_STREAM_OK);
+}
+
+void
+fill_rules(GtkWidget *list, GList *rules, struct filter_option *option, int type)
+{
+ GList *optionl, *rulel;
+ GtkWidget *listitem, *hbox, *checkbox, *label;
+ GList *items = NULL;
+
+ rulel = rules;
+ while (rulel) {
+ struct filter_rule *fr = rulel->data;
+ char *labeltext;
+
+ if (fr->type == type) {
+ int state;
+
+ state = find_optionrule(option, fr->name) != NULL;
+
+ labeltext = filter_description_text(fr->description, NULL);
+
+ hbox = gtk_hbox_new(FALSE, 3);
+ checkbox = gnome_pixmap_new_from_xpm_d(state?check_xpm:blank_xpm);
+ gtk_box_pack_start(GTK_BOX(hbox), checkbox, FALSE, FALSE, 0);
+ label = gtk_label_new(labeltext);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
+ listitem = gtk_list_item_new();
+ gtk_container_add(GTK_CONTAINER(listitem), hbox);
+ gtk_widget_show_all(listitem);
+
+ gtk_object_set_data(GTK_OBJECT(listitem), "checkbox", checkbox);
+ gtk_object_set_data(GTK_OBJECT(listitem), "checkstate", (void *)state);
+ gtk_object_set_data(GTK_OBJECT(listitem), "rule", fr);
+
+ items = g_list_append(items, listitem);
+ }
+ rulel = g_list_next(rulel);
+ }
+ gtk_list_append_items(GTK_LIST(list), items);
+}
+
+void
+fill_options(GtkWidget *list, GList *options)
+{
+ GList *optionl, *rulel, *optionrulel;
+ GtkWidget *listitem, *hbox, *checkbox, *label;
+ GList *items = NULL;
+
+ optionl = options;
+ while (optionl) {
+ struct filter_option *op = optionl->data;
+ char *labeltext;
+
+ labeltext = filter_description_text(op->description, NULL);
+ listitem = gtk_list_item_new_with_label(labeltext);
+ g_free(labeltext);
+ gtk_widget_show_all(listitem);
+
+ gtk_object_set_data(GTK_OBJECT(listitem), "option", op);
+
+ items = g_list_append(items, listitem);
+ optionl = g_list_next(optionl);
+ }
+ gtk_list_append_items(GTK_LIST(list), items);
+}
+
+GtkWidget *list_global, *html_global;
+struct filter_option *option_current;
+
+static void
+select_rule_child(GtkList *list, GtkWidget *child, void *data)
+{
+ GtkWidget *w;
+ struct filter_rule *fr = gtk_object_get_data(GTK_OBJECT(child), "rule");
+ int state;
+ struct filter_optionrule *rule;
+
+ w = gtk_object_get_data(GTK_OBJECT(child), "checkbox");
+ state = !(int) gtk_object_get_data(GTK_OBJECT(child), "checkstate");
+
+ gnome_pixmap_load_xpm_d(GNOME_PIXMAP(w), state?check_xpm:blank_xpm);
+ gtk_object_set_data(GTK_OBJECT(child), "checkstate", (void *)state);
+
+ if (state) {
+ printf("adding rule %p\n", fr);
+ rule = g_malloc0(sizeof(*rule));
+ rule->rule = fr;
+ option_current->options = g_list_prepend(option_current->options, rule);
+ } else {
+ /* FIXME: free optionrule */
+ rule = find_optionrule(option_current, fr->name);
+ if (rule)
+ option_current->options = g_list_remove(option_current->options, rule);
+ }
+
+ {
+ GString *s = g_string_new("");
+ expand_filter_option(s, option_current);
+ printf("Rules: %s\n", s->str);
+ g_string_free(s, TRUE);
+ }
+
+ html_write_options(html_global, option_current);
+}
+
+static void
+select_option_child(GtkList *list, GtkWidget *child, void *data)
+{
+ struct filter_option *op = gtk_object_get_data(GTK_OBJECT(child), "option");
+ struct filter_option *new;
+ GList *optionsl;
+
+ if (option_current) {
+ /* free option_current copy */
+ optionsl = option_current->options;
+ while (optionsl) {
+ GList *op = optionsl;
+ optionsl = g_list_next(optionsl);
+ g_free(op->data);
+ }
+ g_list_free(option_current->options);
+ g_free(option_current);
+ option_current = NULL;
+ }
+
+ /* clone the option */
+ new = g_malloc(sizeof(*new));
+ new->type = op->type;
+ new->description = op->description;
+ new->options = NULL;
+ optionsl = op->options;
+ while (optionsl) {
+ struct filter_optionrule *ornew = g_malloc(sizeof(*ornew)),
+ *or = optionsl->data;
+ ornew->rule = or->rule;
+ /* FIXME: must copy args too *sigh* */
+ ornew->args = or->args;
+ new->options = g_list_append(new->options, ornew);
+ optionsl = g_list_next(optionsl);
+ }
+ option_current = new;
+
+ html_write_options(GTK_HTML(html_global), option_current);
+}
+
+static void
+arg_link_clicked(GtkHTML *html, const char *url, void *data)
+{
+ printf("url clicked: %s\n", url);
+ if (!strncmp(url, "arg:", 4)) {
+ FilterArg *arg;
+ void *dummy;
+
+ if (sscanf(url+4, "%p %p", &dummy, &arg)==2
+ && arg) {
+ printf("arg = %p\n", arg);
+ filter_arg_edit_values(arg);
+ /* should have a changed signal which propagates the rewrite */
+ html_write_options(GTK_HTML(html_global), option_current);
+ }
+ }
+}
+
+static void
+dialogue_clicked(GtkWidget *w, int button, void *data)
+{
+ GString *s = g_string_new("");
+
+ printf("button %d clicked ...\n");
+
+ if (option_current)
+ expand_filter_option(s, option_current);
+
+ g_string_free(s, TRUE);
+}
+
+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;
+
+ gtk_widget_show_all(dialogue);
+}
+
int main(int argc, char **argv)
{
FilterSEXP *f;
FilterSEXPResult *r;
- GList *rules, *options;
+ 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 ());
+
+ create_dialogue();
doc = xmlParseFile("filterdescription.xml");
- rules = load_ruleset(doc);
- options = load_optionset(doc, rules);
+ rules = filter_load_ruleset(doc);
+ options = filter_load_optionset(doc, rules);
+ options2 = options;
out = xmlParseFile("saveoptions.xml");
- options = load_optionset(out, rules);
+ 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("");
expand_filter_option(s, options->data);