New utility functions for working with the internal rule format.
2000-02-22 NotZed <NotZed@HelixCode.com> * filter-xml.c (filter_clone_optionrule): (filter_clone_optionrule_free): (filter_optionrule_new_from_rule): New utility functions for working with the internal rule format. * filter-arg.[ch]: Added new callbacks for editing a single value, and a new editor which shows all items in a list, and allows you to edit them via the single-edit method. This needs some cleanup for some unused/unusable virtual methods (edit_values, write_html?). * Makefile: Add the druid for build. * filter-druid.c: A 'druid' widget for editing a single filter rule. svn path=/trunk/; revision=1901
This commit is contained in:
@ -1,3 +1,21 @@
|
||||
2000-02-22 NotZed <NotZed@HelixCode.com>
|
||||
|
||||
* filter-xml.c (filter_clone_optionrule):
|
||||
(filter_clone_optionrule_free):
|
||||
(filter_optionrule_new_from_rule): New utility functions for
|
||||
working with the internal rule format.
|
||||
|
||||
* filter-arg.[ch]: Added new callbacks for editing a single value,
|
||||
and a new editor which shows all items in a list, and allows you
|
||||
to edit them via the single-edit method. This needs some cleanup
|
||||
for some unused/unusable virtual methods (edit_values,
|
||||
write_html?).
|
||||
|
||||
* Makefile: Add the druid for build.
|
||||
|
||||
* filter-druid.c: A 'druid' widget for editing a single filter
|
||||
rule.
|
||||
|
||||
2000-02-21 Matt Loper <matt@helixcode.com>
|
||||
|
||||
* .cvsignore: New file.
|
||||
|
||||
@ -1,18 +1,22 @@
|
||||
|
||||
OBJS = filter-arg-types.lo filter-arg.lo filter-xml.lo filter-driver.lo filter-format.lo
|
||||
SRCS = filter-arg-types.c filter-arg.c filter-xml.c filter-driver.c filter-format.c
|
||||
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
|
||||
|
||||
LIBFILTEROBJS = filter-sexp.lo
|
||||
LIBFILTERSRCS = filter-sexp.c
|
||||
|
||||
LIBTOOL=sh ../libtool
|
||||
#CC=insure gcc
|
||||
|
||||
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
|
||||
all: libfilter.la filter-driver filter-druid
|
||||
|
||||
filter-driver: $(OBJS) libfilter.la
|
||||
filter-druid: $(OBJS) filter-druid.lo libfilter.la
|
||||
$(LIBTOOL) --mode link $(CC) $^ -o $@ $(LDFLAGS)
|
||||
|
||||
filter-driver: $(OBJS) filter-driver.lo libfilter.la
|
||||
$(LIBTOOL) --mode link $(CC) $^ -o $@ $(LDFLAGS)
|
||||
|
||||
libfilter.la: $(LIBFILTEROBJS)
|
||||
@ -20,3 +24,6 @@ libfilter.la: $(LIBFILTEROBJS)
|
||||
|
||||
%.lo: %.c
|
||||
$(LIBTOOL) --mode compile $(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
-rm -rf *.o *.lo core .libs
|
||||
|
||||
@ -89,7 +89,51 @@ arg_string_write_text(FilterArg *argin, GString *string)
|
||||
static void
|
||||
arg_string_edit_values(FilterArg *arg)
|
||||
{
|
||||
printf("edit string value!\n");
|
||||
printf("edit string values!\n");
|
||||
}
|
||||
|
||||
/* pop up a dialogue, asking for a new string value */
|
||||
static int
|
||||
arg_string_edit_value(FilterArg *arg, int index)
|
||||
{
|
||||
GnomeDialog *dialogue;
|
||||
GtkHBox *hbox;
|
||||
GtkLabel *label;
|
||||
GtkEntry *entry;
|
||||
char *text = NULL;
|
||||
char *newtext;
|
||||
|
||||
dialogue = (GnomeDialog *)gnome_dialog_new("Edit value", "Ok", "Cancel", 0);
|
||||
|
||||
hbox = (GtkHBox *)gtk_hbox_new(FALSE, 0);
|
||||
label = (GtkLabel *)gtk_label_new("Folder name");
|
||||
gtk_box_pack_start((GtkBox *)hbox, (GtkWidget *)label, FALSE, FALSE, 0);
|
||||
entry = (GtkEntry *)gtk_entry_new();
|
||||
gtk_box_pack_start((GtkBox *)hbox, (GtkWidget *)entry, TRUE, TRUE, 0);
|
||||
if (index>=0) {
|
||||
text = filter_arg_get_value(arg, index);
|
||||
}
|
||||
if (text) {
|
||||
gtk_entry_set_text(entry, text);
|
||||
}
|
||||
gtk_box_pack_start((GtkBox *)dialogue->vbox, (GtkWidget *)hbox, TRUE, TRUE, 0);
|
||||
gtk_widget_show_all((GtkWidget *)hbox);
|
||||
gtk_object_ref((GtkObject *)entry); /* so we can get the text back afterwards */
|
||||
if (gnome_dialog_run_and_close(dialogue) == 0) {
|
||||
GList *node;
|
||||
|
||||
newtext = g_strdup(gtk_entry_get_text(entry));
|
||||
gtk_object_unref((GtkObject *)entry);
|
||||
if (index>=0
|
||||
&& (node = g_list_find(arg->values, text))) {
|
||||
node->data = newtext;
|
||||
} else {
|
||||
arg->values = g_list_append(arg->values, newtext);
|
||||
}
|
||||
g_free(text);
|
||||
return g_list_index(arg->values, newtext);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
@ -161,7 +205,9 @@ filter_arg_string_class_init (FilterArgStringClass *class)
|
||||
class->parent_class.write_html = arg_string_write_html;
|
||||
class->parent_class.write_text = arg_string_write_text;
|
||||
class->parent_class.edit_values = arg_string_edit_values;
|
||||
class->parent_class.edit_value = arg_string_edit_value;
|
||||
class->parent_class.free_value = arg_string_free_value;
|
||||
class->parent_class.get_value_as_string = arg_string_get_value_as_string;
|
||||
|
||||
class->parent_class.values_get_xml = arg_string_values_get_xml;
|
||||
class->parent_class.values_add_xml = arg_string_values_add_xml;
|
||||
@ -267,6 +313,54 @@ arg_address_edit_values(FilterArg *arg)
|
||||
printf("edit it!\n");
|
||||
}
|
||||
|
||||
static int
|
||||
arg_address_edit_value(FilterArg *arg, int index)
|
||||
{
|
||||
GnomeDialog *dialogue;
|
||||
GtkHBox *hbox;
|
||||
GtkLabel *label;
|
||||
GtkEntry *entry;
|
||||
char *text = NULL;
|
||||
char *newtext;
|
||||
struct filter_arg_address *ad;
|
||||
|
||||
dialogue = (GnomeDialog *)gnome_dialog_new("Edit value", "Ok", "Cancel", 0);
|
||||
|
||||
hbox = (GtkHBox *)gtk_hbox_new(FALSE, 0);
|
||||
label = (GtkLabel *)gtk_label_new("Folder name");
|
||||
gtk_box_pack_start((GtkBox *)hbox, (GtkWidget *)label, FALSE, FALSE, 0);
|
||||
entry = (GtkEntry *)gtk_entry_new();
|
||||
gtk_box_pack_start((GtkBox *)hbox, (GtkWidget *)entry, TRUE, TRUE, 0);
|
||||
if (index>=0
|
||||
&& (ad = filter_arg_get_value(arg, index))) {
|
||||
text = ad->email;
|
||||
}
|
||||
if (text) {
|
||||
gtk_entry_set_text(entry, text);
|
||||
}
|
||||
gtk_box_pack_start((GtkBox *)dialogue->vbox, (GtkWidget *)hbox, TRUE, TRUE, 0);
|
||||
gtk_widget_show_all((GtkWidget *)hbox);
|
||||
gtk_object_ref((GtkObject *)entry); /* so we can get the text back afterwards */
|
||||
if (gnome_dialog_run_and_close(dialogue) == 0) {
|
||||
GList *node;
|
||||
|
||||
newtext = g_strdup(gtk_entry_get_text(entry));
|
||||
gtk_object_unref((GtkObject *)entry);
|
||||
if (index>=0
|
||||
&& (node = g_list_find(arg->values, text))) {
|
||||
ad = node->data;
|
||||
ad->email = newtext;
|
||||
} else {
|
||||
ad = g_malloc0(sizeof(*ad));
|
||||
ad->email = newtext;
|
||||
arg->values = g_list_append(arg->values, ad);
|
||||
}
|
||||
g_free(text);
|
||||
return g_list_index(arg->values, ad);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
arg_address_values_get_xml(FilterArg *argin)
|
||||
{
|
||||
@ -319,6 +413,8 @@ arg_address_get_value_as_string(FilterArg *argin, void *data)
|
||||
FilterArgAddress *arg = (FilterArgAddress *)argin;
|
||||
struct filter_arg_address *a = (struct filter_arg_address *)data;
|
||||
|
||||
printf("geting address as string : %s %s\n", a->email, a->name);
|
||||
|
||||
if (a->email == NULL
|
||||
|| a->email[0] == '\0') {
|
||||
if (a->name == NULL
|
||||
@ -348,7 +444,8 @@ filter_arg_address_class_init (FilterArgAddressClass *class)
|
||||
|
||||
class->parent_class.write_html = arg_address_write_html;
|
||||
class->parent_class.write_text = arg_address_write_text;
|
||||
class->parent_class.edit_values = arg_address_edit_values;
|
||||
class->parent_class.edit_values= arg_address_edit_values;
|
||||
class->parent_class.edit_value= arg_address_edit_value;
|
||||
class->parent_class.free_value = arg_address_free_value;
|
||||
|
||||
class->parent_class.values_get_xml = arg_address_values_get_xml;
|
||||
@ -470,7 +567,7 @@ arg_folder_edit_values(FilterArg *argin)
|
||||
dialogue = gnome_dialog_new("Edit addresses",
|
||||
"Ok", "Cancel", NULL);
|
||||
text = gtk_text_new(NULL, NULL);
|
||||
gtk_object_ref(text);
|
||||
gtk_object_ref((GtkObject *)text);
|
||||
|
||||
l = argin->values;
|
||||
while (l) {
|
||||
|
||||
@ -20,6 +20,9 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gnome.h>
|
||||
|
||||
#include "filter-arg.h"
|
||||
|
||||
|
||||
@ -57,6 +60,21 @@ filter_arg_get_type (void)
|
||||
return type;
|
||||
}
|
||||
|
||||
static FilterArg *
|
||||
clone_default(FilterArg *a)
|
||||
{
|
||||
xmlNodePtr values;
|
||||
FilterArg *new = FILTER_ARG ( gtk_type_new (((GtkObject *)a)->klass->type) );
|
||||
|
||||
/* clone values */
|
||||
new->name = g_strdup(a->name);
|
||||
values = filter_arg_values_get_xml(a);
|
||||
filter_arg_values_add_xml(new, values);
|
||||
xmlFreeNodeList(values);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static void
|
||||
write_html_nothing(FilterArg *arg, GtkHTML *html, GtkHTMLStreamHandle *stream)
|
||||
{
|
||||
@ -75,6 +93,12 @@ edit_values_nothing(FilterArg *arg)
|
||||
/* empty */
|
||||
}
|
||||
|
||||
static void *
|
||||
edit_value_nothing(FilterArg *arg, void *v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static void
|
||||
free_value_nothing(FilterArg *arg, void *v)
|
||||
{
|
||||
@ -98,7 +122,9 @@ filter_arg_class_init (FilterArgClass *class)
|
||||
class->write_html = write_html_nothing;
|
||||
class->write_text = write_text_nothing;
|
||||
class->edit_values = edit_values_nothing;
|
||||
class->edit_value = edit_value_nothing;
|
||||
class->free_value = free_value_nothing;
|
||||
class->clone = clone_default;
|
||||
|
||||
signals[CHANGED] =
|
||||
gtk_signal_new ("changed",
|
||||
@ -132,6 +158,12 @@ filter_arg_new (char *name)
|
||||
return a;
|
||||
}
|
||||
|
||||
FilterArg *
|
||||
filter_arg_clone (FilterArg *arg)
|
||||
{
|
||||
return ((FilterArgClass *)(arg->object.klass))->clone(arg);
|
||||
}
|
||||
|
||||
void
|
||||
filter_arg_add(FilterArg *arg, void *v)
|
||||
{
|
||||
@ -157,17 +189,46 @@ filter_arg_write_html(FilterArg *arg, GtkHTML *html, GtkHTMLStreamHandle *stream
|
||||
void
|
||||
filter_arg_write_text(FilterArg *arg, GString *string)
|
||||
{
|
||||
int count, i;
|
||||
|
||||
count = filter_arg_get_count(arg);
|
||||
for (i=0;i<count;i++) {
|
||||
g_string_append(string, filter_arg_get_value_as_string(arg, i));
|
||||
if (i<count-1) {
|
||||
g_string_append(string, ", ");
|
||||
}
|
||||
if (i==count-2 && count>1) {
|
||||
g_string_append(string, "or ");
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
((FilterArgClass *)(arg->object.klass))->write_text(arg, string);
|
||||
#endif
|
||||
}
|
||||
void
|
||||
filter_arg_edit_values(FilterArg *arg)
|
||||
{
|
||||
void filter_arg_edit_values_1(FilterArg *arg);
|
||||
|
||||
g_return_if_fail(arg != NULL);
|
||||
|
||||
|
||||
#if 1
|
||||
filter_arg_edit_values_1(arg);
|
||||
#else
|
||||
|
||||
if (((FilterArgClass *)(arg->object.klass))->edit_values)
|
||||
((FilterArgClass *)(arg->object.klass))->edit_values(arg);
|
||||
else
|
||||
g_warning("No implementation of virtual method edit_values");
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
filter_arg_edit_value(FilterArg *arg, int index)
|
||||
{
|
||||
((FilterArgClass *)(arg->object.klass))->edit_value(arg, index);
|
||||
}
|
||||
|
||||
xmlNodePtr
|
||||
@ -222,3 +283,193 @@ filter_arg_get_value_as_string(FilterArg *arg, int index)
|
||||
}
|
||||
|
||||
|
||||
struct filter_arg_edit {
|
||||
FilterArg *arg;
|
||||
GtkList *list;
|
||||
GList *items;
|
||||
GnomeDialog *dialogue;
|
||||
GtkWidget *add, *remove, *edit;
|
||||
GtkWidget *item_current;
|
||||
};
|
||||
|
||||
static void
|
||||
filter_arg_edit_add(GtkWidget *w, struct filter_arg_edit *edata)
|
||||
{
|
||||
GtkListItem *listitem;
|
||||
GList *items = NULL;
|
||||
int i;
|
||||
|
||||
printf("adding new item\n");
|
||||
|
||||
i = filter_arg_edit_value(edata->arg, -1);
|
||||
if (i>=0) {
|
||||
gtk_list_remove_items_no_unref(edata->list, edata->items);
|
||||
listitem = (GtkListItem *)gtk_list_item_new_with_label(filter_arg_get_value_as_string(edata->arg, i));
|
||||
gtk_object_set_data((GtkObject *)listitem, "arg_i", filter_arg_get_value(edata->arg, i));
|
||||
edata->items = g_list_append(edata->items, listitem);
|
||||
gtk_widget_show((GtkWidget *)listitem);
|
||||
|
||||
/* this api is nonsense */
|
||||
gtk_list_append_items(edata->list, g_list_copy(edata->items));
|
||||
}
|
||||
}
|
||||
|
||||
void dump_list(GList *list)
|
||||
{
|
||||
printf("dumping list:\n");
|
||||
for (;list;list = g_list_next(list)) {
|
||||
printf(" %p %p\n", list, list->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fill_list(struct filter_arg_edit *edata)
|
||||
{
|
||||
GList *items = NULL;
|
||||
int i, count;
|
||||
GtkListItem *listitem;
|
||||
|
||||
gtk_list_remove_items(edata->list, edata->items);
|
||||
g_list_free(edata->items);
|
||||
|
||||
count = filter_arg_get_count(edata->arg);
|
||||
for (i=0;i<count;i++) {
|
||||
char *labeltext;
|
||||
labeltext = filter_arg_get_value_as_string(edata->arg, i);
|
||||
listitem = (GtkListItem *)gtk_list_item_new_with_label(labeltext);
|
||||
gtk_object_set_data((GtkObject *)listitem, "arg_i", filter_arg_get_value(edata->arg, i));
|
||||
items = g_list_append(items, listitem);
|
||||
gtk_widget_show(GTK_WIDGET(listitem));
|
||||
printf("adding item %d\n", i);
|
||||
}
|
||||
|
||||
printf("items re-added\n");
|
||||
|
||||
edata->item_current = NULL;
|
||||
edata->items = items;
|
||||
|
||||
gtk_list_append_items(edata->list, g_list_copy(edata->items));
|
||||
}
|
||||
|
||||
static void
|
||||
filter_arg_edit_edit(GtkWidget *w, struct filter_arg_edit *edata)
|
||||
{
|
||||
char *name;
|
||||
int i;
|
||||
|
||||
/* yurck */
|
||||
if (edata->item_current
|
||||
&& (name = gtk_object_get_data((GtkObject *)edata->item_current, "arg_i"))
|
||||
&& (i = g_list_index(edata->arg->values, name)) >= 0
|
||||
&& (i = filter_arg_edit_value(edata->arg, i)) >= 0) {
|
||||
|
||||
fill_list(edata);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
filter_arg_edit_delete(GtkWidget *w, struct filter_arg_edit *edata)
|
||||
{
|
||||
GtkListItem *listitem;
|
||||
char *name;
|
||||
|
||||
/* yurck */
|
||||
if (edata->item_current
|
||||
&& (name = gtk_object_get_data((GtkObject *)edata->item_current, "arg_i"))) {
|
||||
filter_arg_remove(edata->arg, name);
|
||||
fill_list(edata);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
edit_sensitise(struct filter_arg_edit *edata)
|
||||
{
|
||||
int state = edata->item_current != NULL;
|
||||
gtk_widget_set_sensitive(edata->remove, state);
|
||||
gtk_widget_set_sensitive(edata->edit, state);
|
||||
}
|
||||
|
||||
static void
|
||||
filter_arg_edit_select(GtkWidget *w, GtkListItem *list, struct filter_arg_edit *edata)
|
||||
{
|
||||
edata->item_current = list;
|
||||
edit_sensitise(edata);
|
||||
|
||||
printf ("node = %p\n", g_list_find(edata->items, edata->item_current));
|
||||
}
|
||||
|
||||
static void
|
||||
filter_arg_edit_unselect(GtkWidget *w, GtkListItem *list, struct filter_arg_edit *edata)
|
||||
{
|
||||
edata->item_current = NULL;
|
||||
edit_sensitise(edata);
|
||||
}
|
||||
|
||||
void
|
||||
filter_arg_edit_values_1(FilterArg *arg)
|
||||
{
|
||||
GList *vales;
|
||||
GtkList *list;
|
||||
GtkListItem *listitem;
|
||||
int count, i;
|
||||
GnomeDialog *dialogue;
|
||||
GtkHBox *hbox;
|
||||
GtkVBox *vbox;
|
||||
GtkWidget *button;
|
||||
GtkWidget *scrolled_window, *frame;
|
||||
struct filter_arg_edit edata;
|
||||
|
||||
edata.item_current = NULL;
|
||||
edata.arg = arg;
|
||||
|
||||
dialogue = (GnomeDialog *)gnome_dialog_new("Edit values", "Ok", "Cancel", 0);
|
||||
edata.dialogue = dialogue;
|
||||
|
||||
hbox = (GtkHBox *)gtk_hbox_new(FALSE, 0);
|
||||
|
||||
list = (GtkList *)gtk_list_new();
|
||||
edata.list = list;
|
||||
edata.items = NULL;
|
||||
fill_list(&edata);
|
||||
|
||||
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
|
||||
frame = gtk_frame_new("Option values");
|
||||
|
||||
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), (GtkWidget *)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_widget_set_usize(frame, 200, 300);
|
||||
gtk_box_pack_start((GtkBox *)hbox, frame, TRUE, TRUE, 0);
|
||||
|
||||
/* buttons */
|
||||
vbox = (GtkVBox *)gtk_vbox_new(FALSE, 0);
|
||||
|
||||
button = gtk_button_new_with_label ("Add");
|
||||
gtk_box_pack_start((GtkBox *)vbox, button, FALSE, TRUE, 0);
|
||||
edata.add = button;
|
||||
button = gtk_button_new_with_label ("Remove");
|
||||
gtk_box_pack_start((GtkBox *)vbox, button, FALSE, TRUE, 0);
|
||||
edata.remove = button;
|
||||
button = gtk_button_new_with_label ("Edit");
|
||||
gtk_box_pack_start((GtkBox *)vbox, button, FALSE, TRUE, 0);
|
||||
edata.edit = button;
|
||||
|
||||
gtk_box_pack_start((GtkBox *)hbox, (GtkWidget *)vbox, FALSE, FALSE, 0);
|
||||
|
||||
gtk_signal_connect((GtkObject *)edata.add, "clicked", filter_arg_edit_add, &edata);
|
||||
gtk_signal_connect((GtkObject *)edata.edit, "clicked", filter_arg_edit_edit, &edata);
|
||||
gtk_signal_connect((GtkObject *)edata.remove, "clicked", filter_arg_edit_delete, &edata);
|
||||
gtk_signal_connect((GtkObject *)edata.list, "select_child", filter_arg_edit_select, &edata);
|
||||
gtk_signal_connect((GtkObject *)edata.list, "unselect_child", filter_arg_edit_unselect, &edata);
|
||||
|
||||
gtk_widget_show(GTK_WIDGET(list));
|
||||
gtk_widget_show_all(GTK_WIDGET(hbox));
|
||||
gtk_box_pack_start((GtkBox *)dialogue->vbox, (GtkWidget *)hbox, TRUE, TRUE, 0);
|
||||
|
||||
edit_sensitise(&edata);
|
||||
|
||||
gnome_dialog_run_and_close(dialogue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -44,11 +44,16 @@ struct _FilterArg {
|
||||
struct _FilterArgClass {
|
||||
GtkObjectClass parent_class;
|
||||
|
||||
/* make a copy of yourself */
|
||||
struct _FilterArg * (*clone)(FilterArg *arg);
|
||||
|
||||
/* virtual methods */
|
||||
void (*write_html)(FilterArg *arg, GtkHTML *html, GtkHTMLStreamHandle *stream);
|
||||
void (*write_text)(FilterArg *arg, GString *string);
|
||||
void (*free_value)(FilterArg *arg, void *v);
|
||||
|
||||
void (*edit_values)(FilterArg *arg);
|
||||
int (*edit_value)(FilterArg *arg, int index);
|
||||
|
||||
void (*values_add_xml)(FilterArg *arg, xmlNodePtr node);
|
||||
xmlNodePtr (*values_get_xml)(FilterArg *arg);
|
||||
@ -61,9 +66,11 @@ struct _FilterArgClass {
|
||||
|
||||
guint filter_arg_get_type (void);
|
||||
FilterArg *filter_arg_new (char *name);
|
||||
FilterArg *filter_arg_clone(FilterArg *arg);
|
||||
void filter_arg_value_add(FilterArg *a, void *v);
|
||||
|
||||
void filter_arg_edit_values(FilterArg *arg);
|
||||
int filter_arg_edit_value(FilterArg *arg, int index);
|
||||
|
||||
xmlNodePtr filter_arg_values_get_xml(FilterArg *arg);
|
||||
void filter_arg_values_add_xml(FilterArg *arg, xmlNodePtr node);
|
||||
@ -72,3 +79,4 @@ void *filter_arg_get_value(FilterArg *arg, int index);
|
||||
char *filter_arg_get_value_as_string(FilterArg *arg, int index);
|
||||
|
||||
#endif /* ! _FILTER_ARG_H */
|
||||
|
||||
|
||||
@ -138,6 +138,8 @@ find_optionrule(struct filter_option *option, char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char nooption[] = "<h1>Select option</h1><p>Select an option type from the list above.</p>";
|
||||
|
||||
void
|
||||
html_write_options(GtkHTML *html, struct filter_option *option)
|
||||
{
|
||||
@ -146,13 +148,17 @@ html_write_options(GtkHTML *html, struct filter_option *option)
|
||||
|
||||
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);
|
||||
if (option) {
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
gtk_html_write(html, stream, nooption, strlen(nooption));
|
||||
}
|
||||
gtk_html_end(html, stream, GTK_HTML_STREAM_OK);
|
||||
}
|
||||
|
||||
848
filter/filter-druid.c
Normal file
848
filter/filter-druid.c
Normal file
@ -0,0 +1,848 @@
|
||||
/*
|
||||
* 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 <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gnome.h>
|
||||
#include <gtkhtml/gtkhtml.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gnome-xml/tree.h>
|
||||
#include <gnome-xml/parser.h>
|
||||
|
||||
#include "filter-arg-types.h"
|
||||
#include "filter-xml.h"
|
||||
#include "filter-sexp.h"
|
||||
#include "filter-format.h"
|
||||
|
||||
|
||||
#include "filter-druid.h"
|
||||
|
||||
static void filter_druid_class_init (FilterDruidClass *klass);
|
||||
static void filter_druid_init (FilterDruid *obj);
|
||||
|
||||
#define _PRIVATE(x) (((FilterDruid *)(x))->priv)
|
||||
|
||||
struct _FilterDruidPrivate {
|
||||
GtkWidget *notebook;
|
||||
int page;
|
||||
|
||||
/* page 0 */
|
||||
GtkWidget *list0;
|
||||
GtkWidget *html0;
|
||||
GtkWidget *add0, *remove0, *up0, *down0;
|
||||
GList *items0;
|
||||
GtkFrame *listframe0;
|
||||
|
||||
/* page 1 */
|
||||
GtkWidget *name1;
|
||||
GtkWidget *activate1;
|
||||
GtkHTML *html1;
|
||||
};
|
||||
|
||||
/* forward ref's */
|
||||
static void build_druid(FilterDruid *d);
|
||||
static void update_display(FilterDruid *f, int initial);
|
||||
|
||||
/* globals */
|
||||
static GnomeDialogClass *filter_druid_parent;
|
||||
|
||||
enum SIGNALS {
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
guint
|
||||
filter_druid_get_type (void)
|
||||
{
|
||||
static guint type = 0;
|
||||
|
||||
if (!type) {
|
||||
GtkTypeInfo type_info = {
|
||||
"FilterDruid",
|
||||
sizeof (FilterDruid),
|
||||
sizeof (FilterDruidClass),
|
||||
(GtkClassInitFunc) filter_druid_class_init,
|
||||
(GtkObjectInitFunc) filter_druid_init,
|
||||
(GtkArgSetFunc) NULL,
|
||||
(GtkArgGetFunc) NULL
|
||||
};
|
||||
|
||||
type = gtk_type_unique (gnome_dialog_get_type (), &type_info);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
filter_druid_class_init (FilterDruidClass *klass)
|
||||
{
|
||||
GtkObjectClass *object_class = (GtkObjectClass *) klass;
|
||||
|
||||
filter_druid_parent = gtk_type_class (gnome_dialog_get_type ());
|
||||
|
||||
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
|
||||
}
|
||||
|
||||
static void
|
||||
filter_druid_init (FilterDruid *obj)
|
||||
{
|
||||
struct _FilterDruidPrivate *priv;
|
||||
|
||||
obj->priv = g_malloc0(sizeof(*obj->priv));
|
||||
priv = _PRIVATE(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter_druid_new:
|
||||
*
|
||||
* Create a new FilterDruid object.
|
||||
*
|
||||
* Return value: A new FilterDruid widget.
|
||||
**/
|
||||
FilterDruid *
|
||||
filter_druid_new (void)
|
||||
{
|
||||
FilterDruid *new = FILTER_DRUID ( gtk_type_new (filter_druid_get_type ()));
|
||||
|
||||
build_druid(new);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
extern int filter_find_arg(FilterArg *a, char *name);
|
||||
|
||||
#include "check.xpm"
|
||||
#include "blank.xpm"
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
FILTER_XML_ACTION,
|
||||
};
|
||||
static char *display_pretext[] = {
|
||||
"<b>For messages matching:</b><br><ul>",
|
||||
"<b>Unless:</b><br><ul>",
|
||||
"<b>Perform these actions:</b><br><ul>",
|
||||
};
|
||||
static char *display_posttext[] = {
|
||||
"</ul>",
|
||||
"</ul>",
|
||||
"</ul>",
|
||||
};
|
||||
|
||||
void
|
||||
html_write_options(GtkHTML *html, struct filter_option *option)
|
||||
{
|
||||
GtkHTMLStreamHandle *stream;
|
||||
GList *optionrulel;
|
||||
int i;
|
||||
|
||||
stream = gtk_html_begin(html, "");
|
||||
gtk_html_write(html, stream, "<body bgcolor=white alink=blue>", strlen("<body bgcolor=white alink=blue>"));
|
||||
if (option) {
|
||||
char *t;
|
||||
|
||||
if (option->type == FILTER_XML_SEND) {
|
||||
t = "<p>When a message is <i>sent</i>.</p>";
|
||||
} else {
|
||||
t = "<p>When a message is <i>received</i>.</p>";
|
||||
}
|
||||
gtk_html_write(html, stream, t, strlen(t));
|
||||
|
||||
for (i=0;i<sizeof(display_order)/sizeof(display_order[0]);i++) {
|
||||
int doneheader = FALSE;
|
||||
optionrulel = option->options;
|
||||
while (optionrulel) {
|
||||
struct filter_optionrule *or = optionrulel->data;
|
||||
|
||||
if (or->rule->type == display_order[i]) {
|
||||
if (!doneheader) {
|
||||
gtk_html_write(html, stream, display_pretext[i], strlen(display_pretext[i]));
|
||||
doneheader = TRUE;
|
||||
}
|
||||
|
||||
filter_description_html_write(or->rule->description, or->args, html, stream);
|
||||
gtk_html_write(html, stream, "<br>", strlen("<br>"));
|
||||
}
|
||||
optionrulel = g_list_next(optionrulel);
|
||||
}
|
||||
if (doneheader) {
|
||||
gtk_html_write(html, stream, display_posttext[i], strlen(display_posttext[i]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gtk_html_write(html, stream, nooption, strlen(nooption));
|
||||
}
|
||||
gtk_html_end(html, stream, GTK_HTML_STREAM_OK);
|
||||
}
|
||||
|
||||
GList *
|
||||
fill_rules(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);
|
||||
|
||||
printf("adding rule %s\n", labeltext);
|
||||
|
||||
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);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
GList *
|
||||
fill_options(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);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
GtkWidget *list_global, *html_global;
|
||||
struct filter_option *option_current;
|
||||
|
||||
static void
|
||||
select_rule_child(GtkList *list, GtkWidget *child, FilterDruid *f)
|
||||
{
|
||||
GtkWidget *w;
|
||||
struct filter_rule *fr = gtk_object_get_data(GTK_OBJECT(child), "rule");
|
||||
int state;
|
||||
struct filter_optionrule *rule;
|
||||
struct _FilterDruidPrivate *p = _PRIVATE(f);
|
||||
|
||||
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 = filter_optionrule_new_from_rule(fr);
|
||||
f->option_current->options = g_list_append(f->option_current->options, rule);
|
||||
} else {
|
||||
rule = find_optionrule(f->option_current, fr->name);
|
||||
if (rule) {
|
||||
f->option_current->options = g_list_remove(f->option_current->options, rule);
|
||||
filter_clone_optionrule_free(rule);
|
||||
}
|
||||
}
|
||||
|
||||
update_display(f, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
select_option_child(GtkList *list, GtkWidget *child, FilterDruid *f)
|
||||
{
|
||||
struct filter_option *op;
|
||||
struct filter_option *new;
|
||||
GList *optionsl;
|
||||
struct _FilterDruidPrivate *p = _PRIVATE(f);
|
||||
|
||||
switch (p->page) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
select_rule_child(list, child, f);
|
||||
default:
|
||||
return;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
if (f->option_current) {
|
||||
/* free option_current copy */
|
||||
optionsl = f->option_current->options;
|
||||
while (optionsl) {
|
||||
GList *op = optionsl;
|
||||
optionsl = g_list_next(optionsl);
|
||||
g_free(op->data);
|
||||
}
|
||||
g_list_free(f->option_current->options);
|
||||
g_free(f->option_current);
|
||||
f->option_current = NULL;
|
||||
}
|
||||
|
||||
if (child) {
|
||||
op = gtk_object_get_data(GTK_OBJECT(child), "option");
|
||||
|
||||
/* 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,
|
||||
*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;
|
||||
}
|
||||
|
||||
update_display(f, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
unselect_option_child(GtkList *list, GtkWidget *child, FilterDruid *f)
|
||||
{
|
||||
select_option_child(list, NULL, f);
|
||||
}
|
||||
|
||||
static void
|
||||
arg_link_clicked(GtkHTML *html, const char *url, FilterDruid *f)
|
||||
{
|
||||
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 */
|
||||
update_display(f, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dialogue_clicked(FilterDruid *d, int button, void *data)
|
||||
{
|
||||
GString *s = g_string_new("");
|
||||
struct _FilterDruidPrivate *p = _PRIVATE(d);
|
||||
int initial=0;
|
||||
|
||||
printf("button %d clicked ...\n", button);
|
||||
|
||||
g_string_free(s, TRUE);
|
||||
|
||||
switch(button) {
|
||||
case 1:
|
||||
if (p->page<4) {
|
||||
p->page++;
|
||||
initial =1;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
if (p->page>0) {
|
||||
p->page--;
|
||||
initial = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
update_display(d, initial);
|
||||
}
|
||||
|
||||
static int filter_types[] = { FILTER_XML_MATCH, FILTER_XML_EXCEPT, FILTER_XML_ACTION };
|
||||
static char *filter_titles[] = {
|
||||
"Select rule(s), where messages match",
|
||||
"Select rule(s), where messages do not match",
|
||||
"Select action(s) to apply to messages"
|
||||
|
||||
};
|
||||
static void
|
||||
update_display(FilterDruid *f, int initial)
|
||||
{
|
||||
struct _FilterDruidPrivate *p = _PRIVATE(f);
|
||||
|
||||
printf("rending page %d options\n", p->page);
|
||||
|
||||
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");
|
||||
gtk_signal_handler_block_by_data((GtkObject *)p->list0, f);
|
||||
gtk_list_remove_items((GtkList *)p->list0, p->items0);
|
||||
p->items0 = fill_options(f->options);
|
||||
gtk_list_append_items((GtkList *)p->list0, p->items0);
|
||||
gtk_signal_handler_unblock_by_data((GtkObject *)p->list0, f);
|
||||
gtk_frame_set_label(p->listframe0, "Select rule type");
|
||||
}
|
||||
|
||||
html_write_options((GtkHTML *)p->html0, f->option_current);
|
||||
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);
|
||||
gtk_list_remove_items((GtkList *)p->list0, p->items0);
|
||||
p->items0 = fill_rules(f->rules, f->option_current, filter_types[p->page-1]);
|
||||
gtk_list_append_items((GtkList *)p->list0, p->items0);
|
||||
gtk_signal_handler_unblock_by_data((GtkObject *)p->list0, f);
|
||||
gtk_frame_set_label(p->listframe0, filter_titles[p->page-1]);
|
||||
gtk_notebook_set_page(GTK_NOTEBOOK(p->notebook), 0);
|
||||
}
|
||||
|
||||
html_write_options((GtkHTML *)p->html0, f->option_current);
|
||||
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);
|
||||
if (text == NULL) {
|
||||
/* maybe this could fudge something out of the first
|
||||
bits of the rule */
|
||||
if (f->option_current->type == FILTER_XML_SEND) {
|
||||
text = "Filter messages sent";
|
||||
} else {
|
||||
text = " Filter messages received";
|
||||
}
|
||||
gtk_entry_set_text(GTK_ENTRY(p->name1), text);
|
||||
} else {
|
||||
gtk_entry_set_text(GTK_ENTRY(p->name1), text);
|
||||
g_free(text);
|
||||
}
|
||||
gtk_notebook_set_page(GTK_NOTEBOOK(p->notebook), 1);
|
||||
}
|
||||
|
||||
html_write_options((GtkHTML *)p->html1, f->option_current);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
filter_druid_set_rules(FilterDruid *f, GList *options, GList *rules, struct filter_option *current)
|
||||
{
|
||||
f->options = options;
|
||||
f->rules = rules;
|
||||
f->user = NULL;
|
||||
|
||||
/* FIXME: free this list if it isn't empty ... */
|
||||
f->option_current = current;
|
||||
|
||||
update_display(f, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
build_druid(FilterDruid *d)
|
||||
{
|
||||
GtkWidget *vbox, *frame, *scrolled_window, *list, *html, *hbox, *label, *vbox1;
|
||||
struct _FilterDruidPrivate *p = _PRIVATE(d);
|
||||
|
||||
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);
|
||||
|
||||
p->notebook = gtk_notebook_new();
|
||||
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(p->notebook), FALSE);
|
||||
|
||||
/* page0, initial setup page */
|
||||
vbox = gtk_vbox_new(FALSE, 3);
|
||||
frame = gtk_frame_new("Filters");
|
||||
p->listframe0 = (GtkFrame *)frame;
|
||||
|
||||
list = gtk_list_new();
|
||||
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_widget_set_usize(scrolled_window, 400, 150);
|
||||
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 (click on values to edit)");
|
||||
html = gtk_html_new();
|
||||
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_widget_set_usize(scrolled_window, 400, 150);
|
||||
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_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(html), "link_clicked", arg_link_clicked, d);
|
||||
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(p->notebook), vbox, NULL);
|
||||
|
||||
|
||||
/* page1, used for the final page display */
|
||||
vbox = gtk_vbox_new(FALSE, 3);
|
||||
|
||||
frame = gtk_frame_new("Rule options");
|
||||
vbox1 = gtk_vbox_new(FALSE, 3);
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 3);
|
||||
label = gtk_label_new("Name of rule");
|
||||
p->name1 = gtk_entry_new();
|
||||
gtk_box_pack_start((GtkBox *)hbox, label, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start((GtkBox *)hbox, p->name1, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start((GtkBox *)vbox1, hbox, TRUE, FALSE, 0);
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(frame), vbox1);
|
||||
|
||||
p->activate1 = gtk_check_button_new_with_label("Activate rule?");
|
||||
gtk_box_pack_start((GtkBox *)vbox1, p->activate1, TRUE, FALSE, 0);
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->activate1), TRUE);
|
||||
|
||||
gtk_box_pack_start((GtkBox *)vbox, frame, TRUE, TRUE, 0);
|
||||
|
||||
/* another copy of the filter thingy */
|
||||
frame = gtk_frame_new("Filter Description (click on values to edit)");
|
||||
html = gtk_html_new();
|
||||
p->html1 = (GtkHTML *)html;
|
||||
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_widget_set_usize(scrolled_window, 400, 150);
|
||||
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);
|
||||
|
||||
/* finish off */
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(p->notebook), vbox, NULL);
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(d)->vbox), p->notebook, TRUE, TRUE, 0);
|
||||
}
|
||||
#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;
|
||||
|
||||
gtk_widget_show_all(dialogue);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
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);
|
||||
|
||||
filter_sexp_input_text(f, s->str, strlen(s->str));
|
||||
filter_sexp_parse(f);
|
||||
#endif
|
||||
|
||||
}
|
||||
57
filter/filter-druid.h
Normal file
57
filter/filter-druid.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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_DRUID_H
|
||||
#define _FILTER_DRUID_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "filter-xml.h"
|
||||
|
||||
#define FILTER_DRUID(obj) GTK_CHECK_CAST (obj, filter_druid_get_type (), FilterDruid)
|
||||
#define FILTER_DRUID_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, filter_druid_get_type (), FilterDruidClass)
|
||||
#define IS_FILTER_DRUID(obj) GTK_CHECK_TYPE (obj, filter_druid_get_type ())
|
||||
|
||||
typedef struct _FilterDruid FilterDruid;
|
||||
typedef struct _FilterDruidClass FilterDruidClass;
|
||||
|
||||
struct _FilterDruid {
|
||||
GnomeDialog parent;
|
||||
|
||||
GList *options; /* all options */
|
||||
GList *rules; /* all rules */
|
||||
GList *user; /* current user options */
|
||||
|
||||
struct filter_option *option_current;
|
||||
|
||||
struct _FilterDruidPrivate *priv;
|
||||
};
|
||||
|
||||
struct _FilterDruidClass {
|
||||
GnomeDialogClass parent_class;
|
||||
};
|
||||
|
||||
guint filter_druid_get_type (void);
|
||||
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);
|
||||
|
||||
#endif /* ! _FILTER_DRUID_H */
|
||||
@ -11,18 +11,20 @@
|
||||
#include "filter-arg-types.h"
|
||||
#include "filter-xml.h"
|
||||
|
||||
#define d(x)
|
||||
|
||||
/* FIXME: remove static, this is defined in filter-xml */
|
||||
static int
|
||||
filter_find_rule(struct filter_rule *a, char *name)
|
||||
{
|
||||
printf("finding, is %s = %s?\n", a->name, name);
|
||||
d(printf("finding, is %s = %s?\n", a->name, name));
|
||||
return strcmp(a->name, name);
|
||||
}
|
||||
|
||||
static int
|
||||
filter_find_arg(FilterArg *a, char *name)
|
||||
{
|
||||
printf("finding, is %s = %s?\n", a->name, name);
|
||||
d(printf("finding, is %s = %s?\n", a->name, name));
|
||||
return strcmp(a->name, name);
|
||||
}
|
||||
|
||||
@ -67,11 +69,11 @@ arg_text(FilterArg *arg)
|
||||
|
||||
value = arg->values;
|
||||
|
||||
printf("getting text from arg %s\n", arg->name);
|
||||
d(printf("getting text from arg %s\n", arg->name));
|
||||
|
||||
if (value == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
str = g_string_new("");
|
||||
filter_arg_write_text(arg, str);
|
||||
out = str->str;
|
||||
@ -84,14 +86,14 @@ description_decode_text(struct filter_desc *d, struct description_decode_lambda
|
||||
{
|
||||
GList *list;
|
||||
char *txt;
|
||||
|
||||
|
||||
switch (d->type) {
|
||||
case FILTER_XML_TEXT:
|
||||
case FILTER_XML_DESC:
|
||||
dotext:
|
||||
printf("appending '%s'\n", d->data);
|
||||
d(printf("appending '%s'\n", d->data));
|
||||
/* printf("vartype = %s\n", detokenise(d->vartype)); */
|
||||
printf("varname = %s\n", d->varname);
|
||||
d(printf("varname = %s\n", d->varname));
|
||||
if (d->vartype !=-1 && d->varname
|
||||
&& (list = g_list_find_custom(l->args, d->varname, (GCompareFunc) filter_find_arg))
|
||||
&& (txt = arg_text(list->data))) {
|
||||
@ -112,13 +114,13 @@ filter_description_text(GList *description, GList *args)
|
||||
char *txt;
|
||||
struct description_decode_lambda l;
|
||||
|
||||
printf("\ndecoding ...\n");
|
||||
d(printf("\ndecoding ...\n"));
|
||||
|
||||
l.str = g_string_new("");
|
||||
l.args = args;
|
||||
g_list_foreach(description, (GFunc) description_decode_text, &l);
|
||||
|
||||
printf("string is '%s'\n", l.str->str);
|
||||
d(printf("string is '%s'\n", l.str->str));
|
||||
|
||||
txt = l.str->str;
|
||||
g_string_free(l.str, FALSE);
|
||||
@ -129,7 +131,7 @@ filter_description_text(GList *description, GList *args)
|
||||
static void
|
||||
html_write(GtkHTML *html, GtkHTMLStreamHandle *stream, char *s)
|
||||
{
|
||||
printf("appending html '%s'\n", s);
|
||||
d(printf("appending html '%s'\n", s));
|
||||
gtk_html_write(html, stream, s, strlen(s));
|
||||
}
|
||||
|
||||
@ -145,9 +147,9 @@ description_decode_html(struct filter_desc *d, struct description_decode_lambda
|
||||
case FILTER_XML_TEXT:
|
||||
case FILTER_XML_DESC:
|
||||
dotext:
|
||||
printf("appending '%s'\n", d->data);
|
||||
d(printf("appending '%s'\n", d->data));
|
||||
/*printf("vartype = %s\n", detokenise(d->vartype));*/
|
||||
printf("varname = %s\n", d->varname);
|
||||
d(printf("varname = %s\n", d->varname));
|
||||
free = FALSE;
|
||||
if (d->vartype !=-1 && d->varname) {
|
||||
char *link;
|
||||
@ -190,7 +192,7 @@ filter_description_html_write(GList *description, GList *args, GtkHTML *html, Gt
|
||||
char *txt;
|
||||
struct description_decode_lambda l;
|
||||
|
||||
printf("\ndecoding ...\n");
|
||||
d(printf("\ndecoding ...\n"));
|
||||
|
||||
l.str = NULL;
|
||||
l.args = args;
|
||||
|
||||
@ -388,6 +388,72 @@ filter_write_optionset(xmlDocPtr doc, GList *optionl)
|
||||
return root;
|
||||
}
|
||||
|
||||
/* utility functions */
|
||||
struct filter_optionrule *
|
||||
filter_clone_optionrule(struct filter_optionrule *or)
|
||||
{
|
||||
GList *arg;
|
||||
struct filter_optionrule *rule;
|
||||
|
||||
rule = g_malloc0(sizeof(*rule));
|
||||
|
||||
rule->rule = or->rule;
|
||||
arg = or->args;
|
||||
while (arg) {
|
||||
rule->args = g_list_append(rule->args, filter_arg_clone(FILTER_ARG(arg->data)));
|
||||
arg = g_list_next(arg);
|
||||
}
|
||||
return rule;
|
||||
}
|
||||
|
||||
void
|
||||
filter_clone_optionrule_free(struct filter_optionrule *or)
|
||||
{
|
||||
GList *argl;
|
||||
struct filter_optionrule *rule;
|
||||
|
||||
argl = or->args;
|
||||
while (argl) {
|
||||
gtk_object_unref(GTK_OBJECT(argl->data));
|
||||
argl = g_list_next(argl);
|
||||
}
|
||||
g_list_free(or->args);
|
||||
g_free(or);
|
||||
}
|
||||
|
||||
struct filter_optionrule *
|
||||
filter_optionrule_new_from_rule(struct filter_rule *rule)
|
||||
{
|
||||
struct filter_optionrule *or;
|
||||
GList *descl;
|
||||
|
||||
or = g_malloc0(sizeof(*or));
|
||||
|
||||
or->rule = rule;
|
||||
|
||||
descl = rule->description;
|
||||
while (descl) {
|
||||
struct filter_desc *desc = descl->data;
|
||||
if (desc->varname && desc->vartype != -1) {
|
||||
FilterArg *arg = NULL;
|
||||
switch (desc->vartype) {
|
||||
case FILTER_XML_ADDRESS:
|
||||
arg = filter_arg_address_new(desc->varname);
|
||||
break;
|
||||
case FILTER_XML_FOLDER:
|
||||
arg = filter_arg_folder_new(desc->varname);
|
||||
break;
|
||||
}
|
||||
if (arg) {
|
||||
or->args = g_list_append(or->args, arg);
|
||||
}
|
||||
}
|
||||
descl = g_list_next(descl);
|
||||
}
|
||||
return or;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TESTER
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
@ -59,4 +59,9 @@ xmlNodePtr filter_write_optionset(xmlDocPtr doc, GList *optionl);
|
||||
int filter_find_rule(struct filter_rule *a, char *name);
|
||||
int filter_find_arg(FilterArg *a, char *name);
|
||||
|
||||
/* utility functions */
|
||||
struct filter_optionrule *filter_clone_optionrule(struct filter_optionrule *or);
|
||||
void filter_clone_optionrule_free(struct filter_optionrule *or);
|
||||
struct filter_optionrule *filter_optionrule_new_from_rule(struct filter_rule *rule);
|
||||
|
||||
#endif /* ! _FILTER_XML_H */
|
||||
|
||||
Reference in New Issue
Block a user