aboutsummaryrefslogtreecommitdiffstats
path: root/filter
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2012-08-06 22:10:09 +0800
committerMilan Crha <mcrha@redhat.com>2012-08-06 22:10:09 +0800
commit304a2c1c91bd21b362090a4368fb460bc697d9b0 (patch)
tree5851085a290617813fe15268444d726da9b79ce6 /filter
parent82b67c38f4a54ad10cce86bc541c5608374a20a1 (diff)
downloadgsoc2013-evolution-304a2c1c91bd21b362090a4368fb460bc697d9b0.tar
gsoc2013-evolution-304a2c1c91bd21b362090a4368fb460bc697d9b0.tar.gz
gsoc2013-evolution-304a2c1c91bd21b362090a4368fb460bc697d9b0.tar.bz2
gsoc2013-evolution-304a2c1c91bd21b362090a4368fb460bc697d9b0.tar.lz
gsoc2013-evolution-304a2c1c91bd21b362090a4368fb460bc697d9b0.tar.xz
gsoc2013-evolution-304a2c1c91bd21b362090a4368fb460bc697d9b0.tar.zst
gsoc2013-evolution-304a2c1c91bd21b362090a4368fb460bc697d9b0.zip
Bug #246530 - Rules editor lacks "Label is (not) 'None'"
Diffstat (limited to 'filter')
-rw-r--r--filter/e-filter-option.c85
-rw-r--r--filter/e-filter-option.h7
2 files changed, 76 insertions, 16 deletions
diff --git a/filter/e-filter-option.c b/filter/e-filter-option.c
index 2f6c73454d..dd6d9b8874 100644
--- a/filter/e-filter-option.c
+++ b/filter/e-filter-option.c
@@ -45,6 +45,7 @@ free_option (struct _filter_option *opt)
g_free (opt->title);
g_free (opt->value);
g_free (opt->code);
+ g_free (opt->code_gen_func);
g_free (opt);
}
@@ -101,6 +102,29 @@ filter_option_get_dynamic_options (EFilterOption *option)
}
static void
+filter_option_generate_code (EFilterOption *option,
+ GString *out,
+ EFilterPart *part)
+{
+ GModule *module;
+ void (*code_gen_func) (EFilterElement *element, GString *out, EFilterPart *part);
+
+ if (!option || !option->current || !option->current->code_gen_func)
+ return;
+
+ module = g_module_open (NULL, G_MODULE_BIND_LAZY);
+
+ if (g_module_symbol (module, option->current->code_gen_func, (gpointer) &code_gen_func)) {
+ code_gen_func (E_FILTER_ELEMENT (option), out, part);
+ } else {
+ g_warning ("optionlist dynamic code function '%s' not found",
+ option->current->code_gen_func);
+ }
+
+ g_module_close (module);
+}
+
+static void
filter_option_finalize (GObject *object)
{
EFilterOption *option = E_FILTER_OPTION (object);
@@ -149,7 +173,7 @@ filter_option_xml_create (EFilterElement *element,
n = node->children;
while (n) {
if (!strcmp ((gchar *)n->name, "option")) {
- gchar *tmp, *value, *title = NULL, *code = NULL;
+ gchar *tmp, *value, *title = NULL, *code = NULL, *code_gen_func = NULL;
value = (gchar *)xmlGetProp (n, (xmlChar *)"value");
work = n->children;
@@ -164,21 +188,43 @@ filter_option_xml_create (EFilterElement *element,
xmlFree (tmp);
}
} else if (!strcmp ((gchar *)work->name, "code")) {
- if (!code) {
- if (!(tmp = (gchar *) xmlNodeGetContent (work)))
- tmp = (gchar *)xmlStrdup ((xmlChar *)"");
+ 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);
+ }
- code = g_strdup (tmp);
- xmlFree (tmp);
+ xmlFree (fn);
}
}
work = work->next;
}
- e_filter_option_add (option, value, title, code, FALSE);
+ 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 (
@@ -217,6 +263,7 @@ filter_option_xml_create (EFilterElement *element,
op->value,
op->title,
op->code,
+ op->code_gen_func,
TRUE);
free_option (op);
}
@@ -295,7 +342,7 @@ filter_option_clone (EFilterElement *element)
newop = e_filter_option_add (
clone_option, op->value,
- op->title, op->code, op->is_dynamic);
+ op->title, op->code, op->code_gen_func, op->is_dynamic);
if (option->current == op)
clone_option->current = newop;
}
@@ -335,8 +382,8 @@ filter_option_get_widget (EFilterElement *element)
break;
} else {
e_filter_option_add (
- option, op->value,
- op->title, op->code, FALSE);
+ option, op->value, op->title,
+ op->code, op->code_gen_func, FALSE);
}
}
@@ -346,8 +393,8 @@ filter_option_get_widget (EFilterElement *element)
if (op) {
e_filter_option_add (
- option, op->value,
- op->title, op->code, TRUE);
+ option, op->value, op->title,
+ op->code, op->code_gen_func, TRUE);
free_option (op);
}
}
@@ -360,8 +407,8 @@ filter_option_get_widget (EFilterElement *element)
if (!op->is_dynamic)
e_filter_option_add (
- option, op->value,
- op->title, op->code, FALSE);
+ option, op->value, op->title,
+ op->code, op->code_gen_func, FALSE);
}
if (old_cur)
@@ -402,8 +449,11 @@ filter_option_build_code (EFilterElement *element,
{
EFilterOption *option = E_FILTER_OPTION (element);
- if (option->current && option->current->code)
+ if (option->current && option->current->code_gen_func) {
+ filter_option_generate_code (option, out, part);
+ } else if (option->current && option->current->code) {
e_filter_part_expand_code (part, option->current->code, out);
+ }
}
static void
@@ -464,6 +514,7 @@ e_filter_option_add (EFilterOption *option,
const gchar *value,
const gchar *title,
const gchar *code,
+ const gchar *code_gen_func,
gboolean is_dynamic)
{
struct _filter_option *op;
@@ -471,10 +522,14 @@ e_filter_option_add (EFilterOption *option,
g_return_val_if_fail (E_IS_FILTER_OPTION (option), NULL);
g_return_val_if_fail (find_option (option, value) == NULL, NULL);
+ if (code_gen_func && !*code_gen_func)
+ code_gen_func = NULL;
+
op = g_malloc (sizeof (*op));
op->title = g_strdup (title);
op->value = g_strdup (value);
op->code = g_strdup (code);
+ op->code_gen_func = g_strdup (code_gen_func);
op->is_dynamic = is_dynamic;
option->options = g_list_append (option->options, op);
diff --git a/filter/e-filter-option.h b/filter/e-filter-option.h
index 45d426b761..84b98bd104 100644
--- a/filter/e-filter-option.h
+++ b/filter/e-filter-option.h
@@ -55,8 +55,12 @@ struct _filter_option {
gchar *title; /* button title */
gchar *value; /* value, if it has one */
gchar *code; /* used to string code segments together */
+ gchar *code_gen_func; /* function to generate the code;
+ either @code or @code_gen_func is non-NULL,
+ never both */
- gboolean is_dynamic; /* whether is the option dynamic, FALSE if static */
+ gboolean is_dynamic; /* whether is the option dynamic, FALSE if static;
+ dynamic means "generated by EFilterOption::dynamic_func" */
};
struct _EFilterOption {
@@ -84,6 +88,7 @@ struct _filter_option *
const gchar *name,
const gchar *title,
const gchar *code,
+ const gchar *code_gen_func,
gboolean is_dynamic);
void e_filter_option_remove_all (EFilterOption *option);