static EFilterElement * filter_option_clone (EFilterElement *element) { EFilterOption *option = E_FILTER_OPTION (element); EFilterOption *clone_option; EFilterElement *clone; GList *link; /* Chain up to parent's clone() method. */ clone = E_FILTER_ELEMENT_CLASS (e_filter_option_parent_class)-> clone (element); clone_option = E_FILTER_OPTION (clone); for (link = option->options; link != NULL; link = g_list_next (link)) { struct _filter_option *op = link->data; struct _filter_option *newop; newop = e_filter_option_add ( clone_option, op->value, op->title, op->code, op->code_gen_func, op->is_dynamic); if (option->current == op) clone_option->current = newop; } clone_option->dynamic_func = g_strdup (option->dynamic_func); return clone; }
static gint filter_input_eq (EFilterElement *element_a, EFilterElement *element_b) { EFilterInput *input_a = E_FILTER_INPUT (element_a); EFilterInput *input_b = E_FILTER_INPUT (element_b); GList *link_a; GList *link_b; /* Chain up to parent's eq() method. */ if (!E_FILTER_ELEMENT_CLASS (e_filter_input_parent_class)-> eq (element_a, element_b)) return FALSE; if (g_strcmp0 (input_a->type, input_b->type) != 0) return FALSE; link_a = input_a->values; link_b = input_b->values; while (link_a != NULL && link_b != NULL) { if (g_strcmp0 (link_a->data, link_b->data) != 0) return FALSE; link_a = g_list_next (link_a); link_b = g_list_next (link_b); } if (link_a != NULL || link_b != NULL) return FALSE; return TRUE; }
static gint filter_color_eq (EFilterElement *element_a, EFilterElement *element_b) { EFilterColor *color_a = E_FILTER_COLOR (element_a); EFilterColor *color_b = E_FILTER_COLOR (element_b); return E_FILTER_ELEMENT_CLASS (e_filter_color_parent_class)-> eq (element_a, element_b) && gdk_color_equal (&color_a->color, &color_b->color); }
static gint filter_option_eq (EFilterElement *element_a, EFilterElement *element_b) { EFilterOption *option_a = E_FILTER_OPTION (element_a); EFilterOption *option_b = E_FILTER_OPTION (element_b); /* Chain up to parent's eq() method. */ if (!E_FILTER_ELEMENT_CLASS (e_filter_option_parent_class)-> eq (element_a, element_b)) return FALSE; if (option_a->current == NULL && option_b->current == NULL) return TRUE; if (option_a->current == NULL || option_b->current == NULL) return FALSE; return (g_strcmp0 (option_a->current->value, option_b->current->value) == 0); }
static void filter_option_xml_create (EFilterElement *element, xmlNodePtr node) { EFilterOption *option = E_FILTER_OPTION (element); xmlNodePtr n, work; /* Chain up to parent's xml_create() method. */ E_FILTER_ELEMENT_CLASS (e_filter_option_parent_class)-> xml_create (element, node); n = node->children; while (n) { if (!strcmp ((gchar *) n->name, "option")) { gchar *tmp, *value, *title = NULL, *code = NULL, *code_gen_func = NULL; value = (gchar *) xmlGetProp (n, (xmlChar *)"value"); work = n->children; while (work) { if (!strcmp ((gchar *) work->name, "title") || !strcmp ((gchar *) work->name, "_title")) { if (!title) { if (!(tmp = (gchar *) xmlNodeGetContent (work))) tmp = (gchar *) xmlStrdup ((xmlChar *)""); title = g_strdup (tmp); xmlFree (tmp); } } else if (!strcmp ((gchar *) work->name, "code")) { if (code || code_gen_func) { g_warning ( "Element 'code' defined twice in '%s'", element->name); } else { xmlChar *fn; /* if element 'code' has attribute 'func', then * the content of the element is ignored and only * the 'func' is used to generate actual rule code; * The function prototype is: * void code_gen_func (EFilterElement *element, GString *out, EFilterPart *part); * where @element is the one on which was called, * @out is GString where to add the code, and * @part is part which contains @element and other options of it. */ fn = xmlGetProp (work, (xmlChar *)"func"); if (fn && *fn) { code_gen_func = g_strdup ((const gchar *) fn); } else { if (!(tmp = (gchar *) xmlNodeGetContent (work))) tmp = (gchar *) xmlStrdup ((xmlChar *)""); code = g_strdup (tmp); xmlFree (tmp); } xmlFree (fn); } } work = work->next; } e_filter_option_add (option, value, title, code, code_gen_func, FALSE); xmlFree (value); g_free (title); g_free (code); g_free (code_gen_func); } else if (g_str_equal ((gchar *) n->name, "dynamic")) { if (option->dynamic_func) { g_warning ( "Only one 'dynamic' node is " "acceptable in the optionlist '%s'", element->name); } else { /* Expecting only one <dynamic func="cb" /> * in the option list, * The 'cb' should be of this prototype: * GSList *cb (void); * returning GSList of struct _filter_option, * all newly allocated, because it'll be * freed with g_free and g_slist_free. * 'is_dynamic' member is ignored here. */ xmlChar *fn; fn = xmlGetProp (n, (xmlChar *)"func"); if (fn && *fn) { GSList *items, *i; struct _filter_option *op; option->dynamic_func = g_strdup ((const gchar *) fn); /* Get options now, to have them * available when reading saved * rules. */ items = filter_option_get_dynamic_options (option); for (i = items; i; i = i->next) { op = i->data; if (op) { e_filter_option_add ( option, op->value, op->title, op->code, op->code_gen_func, TRUE); free_option (op); } } g_slist_free (items); } else { g_warning ( "Missing 'func' attribute within " "'%s' node in optionlist '%s'", n->name, element->name); } xmlFree (fn); } } else if (n->type == XML_ELEMENT_NODE) { g_warning ("Unknown xml node within optionlist: %s\n", n->name); } n = n->next; } }