diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2012-12-10 21:09:59 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2012-12-13 03:33:43 +0800 |
commit | d09d8de870b6697c8a8b262e7e077b871a69b315 (patch) | |
tree | 3b718882e7a0bb0a996daf2967a033d91714c9b5 /filter | |
parent | b61331ed03ac1c7a9b8614e25510040b9c60ae02 (diff) | |
download | gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.gz gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.bz2 gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.lz gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.xz gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.tar.zst gsoc2013-evolution-d09d8de870b6697c8a8b262e7e077b871a69b315.zip |
Consolidate base utility libraries into libeutil.
Evolution consists of entirely too many small utility libraries, which
increases linking and loading time, places a burden on higher layers of
the application (e.g. modules) which has to remember to link to all the
small in-tree utility libraries, and makes it difficult to generate API
documentation for these utility libraries in one Gtk-Doc module.
Merge the following utility libraries under the umbrella of libeutil,
and enforce a single-include policy on libeutil so we can reorganize
the files as desired without disrupting its pseudo-public API.
libemail-utils/libemail-utils.la
libevolution-utils/libevolution-utils.la
filter/libfilter.la
widgets/e-timezone-dialog/libetimezonedialog.la
widgets/menus/libmenus.la
widgets/misc/libemiscwidgets.la
widgets/table/libetable.la
widgets/text/libetext.la
This also merges libedataserverui from the Evolution-Data-Server module,
since Evolution is its only consumer nowadays, and I'd like to make some
improvements to those APIs without concern for backward-compatibility.
And finally, start a Gtk-Doc module for libeutil. It's going to be a
project just getting all the symbols _listed_ much less _documented_.
But the skeletal structure is in place and I'm off to a good start.
Diffstat (limited to 'filter')
-rw-r--r-- | filter/Makefile.am | 76 | ||||
-rw-r--r-- | filter/e-filter-code.c | 102 | ||||
-rw-r--r-- | filter/e-filter-code.h | 68 | ||||
-rw-r--r-- | filter/e-filter-color.c | 163 | ||||
-rw-r--r-- | filter/e-filter-color.h | 70 | ||||
-rw-r--r-- | filter/e-filter-datespec.c | 515 | ||||
-rw-r--r-- | filter/e-filter-datespec.h | 87 | ||||
-rw-r--r-- | filter/e-filter-element.c | 446 | ||||
-rw-r--r-- | filter/e-filter-element.h | 120 | ||||
-rw-r--r-- | filter/e-filter-file.c | 262 | ||||
-rw-r--r-- | filter/e-filter-file.h | 74 | ||||
-rw-r--r-- | filter/e-filter-input.c | 305 | ||||
-rw-r--r-- | filter/e-filter-input.h | 74 | ||||
-rw-r--r-- | filter/e-filter-int.c | 230 | ||||
-rw-r--r-- | filter/e-filter-int.h | 77 | ||||
-rw-r--r-- | filter/e-filter-option.c | 566 | ||||
-rw-r--r-- | filter/e-filter-option.h | 97 | ||||
-rw-r--r-- | filter/e-filter-part.c | 513 | ||||
-rw-r--r-- | filter/e-filter-part.h | 107 | ||||
-rw-r--r-- | filter/e-filter-rule.c | 1242 | ||||
-rw-r--r-- | filter/e-filter-rule.h | 159 | ||||
-rw-r--r-- | filter/e-rule-context.c | 1027 | ||||
-rw-r--r-- | filter/e-rule-context.h | 214 | ||||
-rw-r--r-- | filter/e-rule-editor.c | 920 | ||||
-rw-r--r-- | filter/e-rule-editor.h | 121 | ||||
-rw-r--r-- | filter/filter.error.xml | 34 | ||||
-rw-r--r-- | filter/filter.ui | 591 |
27 files changed, 0 insertions, 8260 deletions
diff --git a/filter/Makefile.am b/filter/Makefile.am deleted file mode 100644 index 0c2db0a8f0..0000000000 --- a/filter/Makefile.am +++ /dev/null @@ -1,76 +0,0 @@ -ui_DATA = filter.ui - -privsolib_LTLIBRARIES = libfilter.la - -libfilter_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I $(top_srcdir) \ - -I $(top_srcdir)/e-util \ - -DEVOLUTION_UIDIR=\"$(uidir)\" \ - -DG_LOG_DOMAIN=\"filter\" \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) - -filterincludedir = $(privincludedir)/filter - -filterinclude_HEADERS = \ - e-filter-code.h \ - e-filter-color.h \ - e-filter-datespec.h \ - e-filter-element.h \ - e-filter-file.h \ - e-filter-input.h \ - e-filter-int.h \ - e-filter-option.h \ - e-filter-part.h \ - e-filter-rule.h \ - e-rule-context.h \ - e-rule-editor.h - -libfilter_la_SOURCES = \ - e-filter-code.c \ - e-filter-code.h \ - e-filter-color.c \ - e-filter-color.h \ - e-filter-datespec.c \ - e-filter-datespec.h \ - e-filter-element.c \ - e-filter-element.h \ - e-filter-file.c \ - e-filter-file.h \ - e-filter-input.c \ - e-filter-input.h \ - e-filter-int.c \ - e-filter-int.h \ - e-filter-option.c \ - e-filter-option.h \ - e-filter-part.c \ - e-filter-part.h \ - e-filter-rule.c \ - e-filter-rule.h \ - e-rule-context.c \ - e-rule-context.h \ - e-rule-editor.c \ - e-rule-editor.h - -libfilter_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) - -libfilter_la_LIBADD = \ - $(top_builddir)/libevolution-utils/libevolution-utils.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(REGEX_LIBS) - -EXTRA_DIST = \ - $(ui_DATA) \ - filter.error.xml - -# basic rules. -error_DATA = filter.error -errordir = $(privdatadir)/errors -@EVO_PLUGIN_RULE@ - -BUILT_SOURCES = $(error_DATA) -CLEANFILES = $(BUILT_SOURCES) - --include $(top_srcdir)/git.mk diff --git a/filter/e-filter-code.c b/filter/e-filter-code.c deleted file mode 100644 index 0352703638..0000000000 --- a/filter/e-filter-code.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-filter-code.h" -#include "e-filter-part.h" - -G_DEFINE_TYPE ( - EFilterCode, - e_filter_code, - E_TYPE_FILTER_INPUT) - -/* here, the string IS the code */ -static void -filter_code_build_code (EFilterElement *element, - GString *out, - EFilterPart *part) -{ - GList *l; - EFilterInput *fi = (EFilterInput *) element; - gboolean is_rawcode = fi->type && g_str_equal (fi->type, "rawcode"); - - if (!is_rawcode) - g_string_append (out, "(match-all "); - - l = fi->values; - while (l) { - g_string_append (out, (gchar *) l->data); - l = g_list_next (l); - } - - if (!is_rawcode) - g_string_append (out, ")"); -} - -/* and we have no value */ -static void -filter_code_format_sexp (EFilterElement *element, - GString *out) -{ -} - -static void -e_filter_code_class_init (EFilterCodeClass *class) -{ - EFilterElementClass *filter_element_class; - - filter_element_class = E_FILTER_ELEMENT_CLASS (class); - filter_element_class->build_code = filter_code_build_code; - filter_element_class->format_sexp = filter_code_format_sexp; -} - -static void -e_filter_code_init (EFilterCode *code) -{ - EFilterInput *input = E_FILTER_INPUT (code); - - input->type = (gchar *) xmlStrdup ((xmlChar *) "code"); -} - -/** - * filter_code_new: - * - * Create a new EFilterCode object. - * - * Return value: A new #EFilterCode object. - **/ -EFilterCode * -e_filter_code_new (gboolean raw_code) -{ - EFilterCode *fc = g_object_new (E_TYPE_FILTER_CODE, NULL, NULL); - - if (fc && raw_code) { - xmlFree (((EFilterInput *) fc)->type); - ((EFilterInput *) fc)->type = (gchar *) xmlStrdup ((xmlChar *)"rawcode"); - } - - return fc; -} diff --git a/filter/e-filter-code.h b/filter/e-filter-code.h deleted file mode 100644 index 6a903a5dcb..0000000000 --- a/filter/e-filter-code.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILTER_CODE_H -#define E_FILTER_CODE_H - -#include "e-filter-input.h" - -/* Standard GObject macros */ -#define E_TYPE_FILTER_CODE \ - (e_filter_code_get_type ()) -#define E_FILTER_CODE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILTER_CODE, EFilterCode)) -#define E_FILTER_CODE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILTER_CODE, EFilterCodeClass)) -#define E_IS_FILTER_CODE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILTER_CODE)) -#define E_IS_FILTER_CODE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FILTER_CODE)) -#define E_FILTER_CODE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILTER_CODE, EFilterCodeClass)) - -G_BEGIN_DECLS - -typedef struct _EFilterCode EFilterCode; -typedef struct _EFilterCodeClass EFilterCodeClass; -typedef struct _EFilterCodePrivate EFilterCodePrivate; - -struct _EFilterCode { - EFilterInput parent; - EFilterCodePrivate *priv; -}; - -struct _EFilterCodeClass { - EFilterInputClass parent_class; -}; - -GType e_filter_code_get_type (void); -EFilterCode * e_filter_code_new (gboolean raw_code); - -G_END_DECLS - -#endif /* E_FILTER_CODE_H */ diff --git a/filter/e-filter-color.c b/filter/e-filter-color.c deleted file mode 100644 index 213530fbb2..0000000000 --- a/filter/e-filter-color.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> - -#include "e-filter-color.h" - -G_DEFINE_TYPE ( - EFilterColor, - e_filter_color, - E_TYPE_FILTER_ELEMENT) - -static void -set_color (GtkColorButton *color_button, - EFilterColor *fc) -{ - gtk_color_button_get_color (color_button, &fc->color); -} - -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 xmlNodePtr -filter_color_xml_encode (EFilterElement *element) -{ - EFilterColor *fc = E_FILTER_COLOR (element); - xmlNodePtr value; - gchar spec[16]; - - g_snprintf ( - spec, sizeof (spec), "#%04x%04x%04x", - fc->color.red, fc->color.green, fc->color.blue); - - value = xmlNewNode (NULL, (xmlChar *)"value"); - xmlSetProp (value, (xmlChar *)"type", (xmlChar *)"colour"); - xmlSetProp (value, (xmlChar *)"name", (xmlChar *) element->name); - xmlSetProp (value, (xmlChar *)"spec", (xmlChar *) spec); - - return value; -} - -static gint -filter_color_xml_decode (EFilterElement *element, - xmlNodePtr node) -{ - EFilterColor *fc = E_FILTER_COLOR (element); - xmlChar *prop; - - xmlFree (element->name); - element->name = (gchar *) xmlGetProp (node, (xmlChar *)"name"); - - prop = xmlGetProp (node, (xmlChar *)"spec"); - if (prop != NULL) { - gdk_color_parse ((gchar *) prop, &fc->color); - xmlFree (prop); - } else { - /* try reading the old RGB properties */ - prop = xmlGetProp (node, (xmlChar *)"red"); - sscanf ((gchar *) prop, "%" G_GINT16_MODIFIER "x", &fc->color.red); - xmlFree (prop); - prop = xmlGetProp (node, (xmlChar *)"green"); - sscanf ((gchar *) prop, "%" G_GINT16_MODIFIER "x", &fc->color.green); - xmlFree (prop); - prop = xmlGetProp (node, (xmlChar *)"blue"); - sscanf ((gchar *) prop, "%" G_GINT16_MODIFIER "x", &fc->color.blue); - xmlFree (prop); - } - - return 0; -} - -static GtkWidget * -filter_color_get_widget (EFilterElement *element) -{ - EFilterColor *fc = E_FILTER_COLOR (element); - GtkWidget *color_button; - - color_button = gtk_color_button_new_with_color (&fc->color); - gtk_widget_show (color_button); - - g_signal_connect ( - color_button, "color_set", - G_CALLBACK (set_color), element); - - return color_button; -} - -static void -filter_color_format_sexp (EFilterElement *element, - GString *out) -{ - EFilterColor *fc = E_FILTER_COLOR (element); - gchar spec[16]; - - g_snprintf ( - spec, sizeof (spec), "#%04x%04x%04x", - fc->color.red, fc->color.green, fc->color.blue); - camel_sexp_encode_string (out, spec); -} - -static void -e_filter_color_class_init (EFilterColorClass *class) -{ - EFilterElementClass *filter_element_class; - - filter_element_class = E_FILTER_ELEMENT_CLASS (class); - filter_element_class->eq = filter_color_eq; - filter_element_class->xml_encode = filter_color_xml_encode; - filter_element_class->xml_decode = filter_color_xml_decode; - filter_element_class->get_widget = filter_color_get_widget; - filter_element_class->format_sexp = filter_color_format_sexp; -} - -static void -e_filter_color_init (EFilterColor *filter) -{ -} - -/** - * filter_color_new: - * - * Create a new EFilterColor object. - * - * Return value: A new #EFilterColor object. - **/ -EFilterColor * -e_filter_color_new (void) -{ - return g_object_new (E_TYPE_FILTER_COLOR, NULL); -} diff --git a/filter/e-filter-color.h b/filter/e-filter-color.h deleted file mode 100644 index cf75bc13ce..0000000000 --- a/filter/e-filter-color.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILTER_COLOR_H -#define E_FILTER_COLOR_H - -#include "e-filter-element.h" - -/* Standard GObject macros */ -#define E_TYPE_FILTER_COLOR \ - (e_filter_color_get_type ()) -#define E_FILTER_COLOR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILTER_COLOR, EFilterColor)) -#define E_FILTER_COLOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILTER_COLOR, EFilterColorClass)) -#define E_IS_FILTER_COLOR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILTER_COLOR)) -#define E_IS_FILTER_COLOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FILTER_COLOR)) -#define E_FILTER_COLOR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILTER_COLOR, EFilterColorClass)) - -G_BEGIN_DECLS - -typedef struct _EFilterColor EFilterColor; -typedef struct _EFilterColorClass EFilterColorClass; -typedef struct _EFilterColorPrivate EFilterColorPrivate; - -struct _EFilterColor { - EFilterElement parent; - EFilterColorPrivate *priv; - - GdkColor color; -}; - -struct _EFilterColorClass { - EFilterElementClass parent_class; -}; - -GType e_filter_color_get_type (void); -EFilterColor * e_filter_color_new (void); - -G_END_DECLS - -#endif /* E_FILTER_COLOR_H */ diff --git a/filter/e-filter-datespec.c b/filter/e-filter-datespec.c deleted file mode 100644 index 8cf01d664f..0000000000 --- a/filter/e-filter-datespec.c +++ /dev/null @@ -1,515 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <stdlib.h> -#include <time.h> -#include <math.h> - -#include <gtk/gtk.h> -#include <glib/gi18n.h> - -#include "libevolution-utils/e-alert.h" -#include "libevolution-utils/evolution-util.h" - -#include "e-filter-datespec.h" -#include "e-filter-part.h" - -#ifdef G_OS_WIN32 -#ifdef localtime_r -#undef localtime_r -#endif -#define localtime_r(tp,tmp) memcpy(tmp,localtime(tp),sizeof(struct tm)) -#endif - -#define E_FILTER_DATESPEC_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_FILTER_DATESPEC, EFilterDatespecPrivate)) - -#define d(x) - -typedef struct { - guint32 seconds; - const gchar *past_singular; - const gchar *past_plural; - const gchar *future_singular; - const gchar *future_plural; - gfloat max; -} timespan; - -#if 0 - -/* Don't delete this code, since it is needed so that xgettext can extract the translations. - * Please, keep these strings in sync with the strings in the timespans array */ - - ngettext ("1 second ago", "%d seconds ago", 1); - ngettext ("1 second in the future", "%d seconds in the future", 1); - ngettext ("1 minute ago", "%d minutes ago", 1); - ngettext ("1 minute in the future", "%d minutes in the future", 1); - ngettext ("1 hour ago", "%d hours ago", 1); - ngettext ("1 hour in the future", "%d hours in the future", 1); - ngettext ("1 day ago", "%d days ago", 1); - ngettext ("1 day in the future", "%d days in the future", 1); - ngettext ("1 week ago", "%d weeks ago", 1); - ngettext ("1 week in the future", "%d weeks in the future", 1) - ngettext ("1 month ago", "%d months ago", 1); - ngettext ("1 month in the future", "%d months in the future", 1); - ngettext ("1 year ago", "%d years ago", 1); - ngettext ("1 year in the future", "%d years in the future", 1); - -#endif - -static const timespan timespans[] = { - { 1, "1 second ago", "%d seconds ago", "1 second in the future", "%d seconds in the future", 59.0 }, - { 60, "1 minute ago", "%d minutes ago", "1 minute in the future", "%d minutes in the future", 59.0 }, - { 3600, "1 hour ago", "%d hours ago", "1 hour in the future", "%d hours in the future", 23.0 }, - { 86400, "1 day ago", "%d days ago", "1 day in the future", "%d days in the future", 31.0 }, - { 604800, "1 week ago", "%d weeks ago", "1 week in the future", "%d weeks in the future", 52.0 }, - { 2419200, "1 month ago", "%d months ago", "1 month in the future", "%d months in the future", 12.0 }, - { 31557600, "1 year ago", "%d years ago", "1 year in the future", "%d years in the future", 1000.0 }, -}; - -#define DAY_INDEX 3 - -struct _EFilterDatespecPrivate { - GtkWidget *label_button; - GtkWidget *notebook_type, *combobox_type, *calendar_specify, *spin_relative, *combobox_relative, *combobox_past_future; - EFilterDatespecType type; - gint span; -}; - -G_DEFINE_TYPE ( - EFilterDatespec, - e_filter_datespec, - E_TYPE_FILTER_ELEMENT) - -static gint -get_best_span (time_t val) -{ - gint i; - - for (i = G_N_ELEMENTS (timespans) - 1; i >= 0; i--) { - if (val % timespans[i].seconds == 0) - return i; - } - - return 0; -} - -/* sets button label */ -static void -set_button (EFilterDatespec *fds) -{ - gchar buf[128]; - gchar *label = buf; - - switch (fds->type) { - case FDST_UNKNOWN: - label = _("<click here to select a date>"); - break; - case FDST_NOW: - label = _("now"); - break; - case FDST_SPECIFIED: { - struct tm tm; - - localtime_r (&fds->value, &tm); - /* strftime for date filter display, only needs to show a day date (i.e. no time) */ - strftime (buf, sizeof (buf), _("%d-%b-%Y"), &tm); - break; } - case FDST_X_AGO: - if (fds->value == 0) - label = _("now"); - else { - gint span, count; - - span = get_best_span (fds->value); - count = fds->value / timespans[span].seconds; - sprintf (buf, ngettext (timespans[span].past_singular, timespans[span].past_plural, count), count); - } - break; - case FDST_X_FUTURE: - if (fds->value == 0) - label = _("now"); - else { - gint span, count; - - span = get_best_span (fds->value); - count = fds->value / timespans[span].seconds; - sprintf (buf, ngettext (timespans[span].future_singular, timespans[span].future_plural, count), count); - } - break; - } - - gtk_label_set_text ((GtkLabel *) fds->priv->label_button, label); -} - -static void -get_values (EFilterDatespec *fds) -{ - EFilterDatespecPrivate *p = E_FILTER_DATESPEC_GET_PRIVATE (fds); - - switch (fds->priv->type) { - case FDST_SPECIFIED: { - guint year, month, day; - struct tm tm; - - gtk_calendar_get_date ((GtkCalendar *) p->calendar_specify, &year, &month, &day); - memset (&tm, 0, sizeof (tm)); - tm.tm_mday = day; - tm.tm_year = year - 1900; - tm.tm_mon = month; - fds->value = mktime (&tm); - /* what about timezone? */ - break; } - case FDST_X_FUTURE: - case FDST_X_AGO: { - gint val; - - val = gtk_spin_button_get_value_as_int ((GtkSpinButton *) p->spin_relative); - fds->value = timespans[p->span].seconds * val; - break; } - case FDST_NOW: - default: - break; - } - - fds->type = p->type; -} - -static void -set_values (EFilterDatespec *fds) -{ - gint note_type; - - EFilterDatespecPrivate *p = E_FILTER_DATESPEC_GET_PRIVATE (fds); - - p->type = fds->type == FDST_UNKNOWN ? FDST_NOW : fds->type; - - note_type = p->type==FDST_X_FUTURE ? FDST_X_AGO : p->type; /* FUTURE and AGO use the same notebook pages/etc. */ - - switch (p->type) { - case FDST_NOW: - case FDST_UNKNOWN: - /* noop */ - break; - case FDST_SPECIFIED: - { - struct tm tm; - - localtime_r (&fds->value, &tm); - gtk_calendar_select_month ((GtkCalendar *) p->calendar_specify, tm.tm_mon, tm.tm_year + 1900); - gtk_calendar_select_day ((GtkCalendar *) p->calendar_specify, tm.tm_mday); - break; - } - case FDST_X_AGO: - p->span = get_best_span (fds->value); - gtk_spin_button_set_value ((GtkSpinButton *) p->spin_relative, fds->value / timespans[p->span].seconds); - gtk_combo_box_set_active (GTK_COMBO_BOX (p->combobox_relative), p->span); - gtk_combo_box_set_active (GTK_COMBO_BOX (p->combobox_past_future), 0); - break; - case FDST_X_FUTURE: - p->span = get_best_span (fds->value); - gtk_spin_button_set_value ((GtkSpinButton *) p->spin_relative, fds->value / timespans[p->span].seconds); - gtk_combo_box_set_active (GTK_COMBO_BOX (p->combobox_relative), p->span); - gtk_combo_box_set_active (GTK_COMBO_BOX (p->combobox_past_future), 1); - break; - } - - gtk_notebook_set_current_page ((GtkNotebook *) p->notebook_type, note_type); - gtk_combo_box_set_active (GTK_COMBO_BOX (p->combobox_type), note_type); -} - -static void -set_combobox_type (GtkComboBox *combobox, - EFilterDatespec *fds) -{ - fds->priv->type = gtk_combo_box_get_active (combobox); - gtk_notebook_set_current_page ((GtkNotebook *) fds->priv->notebook_type, fds->priv->type); -} - -static void -set_combobox_relative (GtkComboBox *combobox, - EFilterDatespec *fds) -{ - fds->priv->span = gtk_combo_box_get_active (combobox); -} - -static void -set_combobox_past_future (GtkComboBox *combobox, - EFilterDatespec *fds) -{ - if (gtk_combo_box_get_active (combobox) == 0) - fds->type = fds->priv->type = FDST_X_AGO; - else - fds->type = fds->priv->type = FDST_X_FUTURE; -} - -static void -button_clicked (GtkButton *button, - EFilterDatespec *fds) -{ - EFilterDatespecPrivate *p = E_FILTER_DATESPEC_GET_PRIVATE (fds); - GtkWidget *content_area; - GtkWidget *toplevel; - GtkDialog *dialog; - GtkBuilder *builder; - - /* XXX I think we're leaking the GtkBuilder. */ - builder = gtk_builder_new (); - e_load_ui_builder_definition (builder, "filter.ui"); - - toplevel = e_builder_get_widget (builder, "filter_datespec"); - - dialog = (GtkDialog *) gtk_dialog_new (); - gtk_window_set_title ( - GTK_WINDOW (dialog), - _("Select a time to compare against")); - gtk_dialog_add_buttons ( - dialog, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); - - p->notebook_type = e_builder_get_widget (builder, "notebook_type"); - p->combobox_type = e_builder_get_widget (builder, "combobox_type"); - p->calendar_specify = e_builder_get_widget (builder, "calendar_specify"); - p->spin_relative = e_builder_get_widget (builder, "spin_relative"); - p->combobox_relative = e_builder_get_widget (builder, "combobox_relative"); - p->combobox_past_future = e_builder_get_widget (builder, "combobox_past_future"); - - set_values (fds); - - g_signal_connect ( - p->combobox_type, "changed", - G_CALLBACK (set_combobox_type), fds); - g_signal_connect ( - p->combobox_relative, "changed", - G_CALLBACK (set_combobox_relative), fds); - g_signal_connect ( - p->combobox_past_future, "changed", - G_CALLBACK (set_combobox_past_future), fds); - - content_area = gtk_dialog_get_content_area (dialog); - gtk_box_pack_start (GTK_BOX (content_area), toplevel, TRUE, TRUE, 3); - - if (gtk_dialog_run (dialog) == GTK_RESPONSE_OK) { - get_values (fds); - set_button (fds); - } - - gtk_widget_destroy ((GtkWidget *) dialog); -} - -static gboolean -filter_datespec_validate (EFilterElement *element, - EAlert **alert) -{ - EFilterDatespec *fds = E_FILTER_DATESPEC (element); - gboolean valid; - - g_warn_if_fail (alert == NULL || *alert == NULL); - - valid = fds->type != FDST_UNKNOWN; - if (!valid) { - if (alert) - *alert = e_alert_new ("filter:no-date", NULL); - } - - return valid; -} - -static gint -filter_datespec_eq (EFilterElement *element_a, - EFilterElement *element_b) -{ - EFilterDatespec *datespec_a = E_FILTER_DATESPEC (element_a); - EFilterDatespec *datespec_b = E_FILTER_DATESPEC (element_b); - - /* Chain up to parent's eq() method. */ - if (!E_FILTER_ELEMENT_CLASS (e_filter_datespec_parent_class)-> - eq (element_a, element_b)) - return FALSE; - - return (datespec_a->type == datespec_b->type) && - (datespec_a->value == datespec_b->value); -} - -static xmlNodePtr -filter_datespec_xml_encode (EFilterElement *element) -{ - xmlNodePtr value, work; - EFilterDatespec *fds = E_FILTER_DATESPEC (element); - gchar str[32]; - - d (printf ("Encoding datespec as xml\n")); - - value = xmlNewNode (NULL, (xmlChar *)"value"); - xmlSetProp (value, (xmlChar *)"name", (xmlChar *) element->name); - xmlSetProp (value, (xmlChar *)"type", (xmlChar *)"datespec"); - - work = xmlNewChild (value, NULL, (xmlChar *)"datespec", NULL); - sprintf (str, "%d", fds->type); - xmlSetProp (work, (xmlChar *)"type", (xmlChar *) str); - sprintf (str, "%d", (gint) fds->value); - xmlSetProp (work, (xmlChar *)"value", (xmlChar *) str); - - return value; -} - -static gint -filter_datespec_xml_decode (EFilterElement *element, - xmlNodePtr node) -{ - EFilterDatespec *fds = E_FILTER_DATESPEC (element); - xmlNodePtr n; - xmlChar *val; - - d (printf ("Decoding datespec from xml %p\n", element)); - - xmlFree (element->name); - element->name = (gchar *) xmlGetProp (node, (xmlChar *)"name"); - - n = node->children; - while (n) { - if (!strcmp ((gchar *) n->name, "datespec")) { - val = xmlGetProp (n, (xmlChar *)"type"); - fds->type = atoi ((gchar *) val); - xmlFree (val); - val = xmlGetProp (n, (xmlChar *)"value"); - fds->value = atoi ((gchar *) val); - xmlFree (val); - break; - } - n = n->next; - } - - return 0; -} - -static GtkWidget * -filter_datespec_get_widget (EFilterElement *element) -{ - EFilterDatespec *fds = E_FILTER_DATESPEC (element); - GtkWidget *button; - - fds->priv->label_button = gtk_label_new (""); - gtk_misc_set_alignment (GTK_MISC (fds->priv->label_button), 0.5, 0.5); - set_button (fds); - - button = gtk_button_new (); - gtk_container_add (GTK_CONTAINER (button), fds->priv->label_button); - g_signal_connect ( - button, "clicked", - G_CALLBACK (button_clicked), fds); - - gtk_widget_show (button); - gtk_widget_show (fds->priv->label_button); - - return button; -} - -static void -filter_datespec_format_sexp (EFilterElement *element, - GString *out) -{ - EFilterDatespec *fds = E_FILTER_DATESPEC (element); - - switch (fds->type) { - case FDST_UNKNOWN: - g_warning ("user hasn't selected a datespec yet!"); - /* fall through */ - case FDST_NOW: - g_string_append (out, "(get-current-date)"); - break; - case FDST_SPECIFIED: - g_string_append_printf (out, "%d", (gint) fds->value); - break; - case FDST_X_AGO: - switch (get_best_span (fds->value)) { - case 5: /* months */ - g_string_append_printf (out, "(get-relative-months (- 0 %d))", (gint) (fds->value / timespans[5].seconds)); - break; - case 6: /* years */ - g_string_append_printf (out, "(get-relative-months (- 0 %d))", (gint) (12 * fds->value / timespans[6].seconds)); - break; - default: - g_string_append_printf (out, "(- (get-current-date) %d)", (gint) fds->value); - break; - } - break; - case FDST_X_FUTURE: - switch (get_best_span (fds->value)) { - case 5: /* months */ - g_string_append_printf (out, "(get-relative-months %d)", (gint) (fds->value / timespans[5].seconds)); - break; - case 6: /* years */ - g_string_append_printf (out, "(get-relative-months %d)", (gint) (12 * fds->value / timespans[6].seconds)); - break; - default: - g_string_append_printf (out, "(+ (get-current-date) %d)", (gint) fds->value); - break; - } - break; - } -} - -static void -e_filter_datespec_class_init (EFilterDatespecClass *class) -{ - EFilterElementClass *filter_element_class; - - g_type_class_add_private (class, sizeof (EFilterDatespecPrivate)); - - filter_element_class = E_FILTER_ELEMENT_CLASS (class); - filter_element_class->validate = filter_datespec_validate; - filter_element_class->eq = filter_datespec_eq; - filter_element_class->xml_encode = filter_datespec_xml_encode; - filter_element_class->xml_decode = filter_datespec_xml_decode; - filter_element_class->get_widget = filter_datespec_get_widget; - filter_element_class->format_sexp = filter_datespec_format_sexp; -} - -static void -e_filter_datespec_init (EFilterDatespec *datespec) -{ - datespec->priv = E_FILTER_DATESPEC_GET_PRIVATE (datespec); - datespec->type = FDST_UNKNOWN; -} - -/** - * filter_datespec_new: - * - * Create a new EFilterDatespec object. - * - * Return value: A new #EFilterDatespec object. - **/ -EFilterDatespec * -e_filter_datespec_new (void) -{ - return g_object_new (E_TYPE_FILTER_DATESPEC, NULL); -} diff --git a/filter/e-filter-datespec.h b/filter/e-filter-datespec.h deleted file mode 100644 index aed978a09a..0000000000 --- a/filter/e-filter-datespec.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILTER_DATESPEC_H -#define E_FILTER_DATESPEC_H - -#include <time.h> -#include "e-filter-element.h" - -/* Standard GObject types */ -#define E_TYPE_FILTER_DATESPEC \ - (e_filter_datespec_get_type ()) -#define E_FILTER_DATESPEC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILTER_DATESPEC, EFilterDatespec)) -#define E_FILTER_DATESPEC_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILTER_DATESPEC, EFilterDatespecClass)) -#define E_IS_FILTER_DATESPEC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILTER_DATESPEC)) -#define E_IS_FILTER_DATESPEC_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FILTER_DATESPEC)) -#define E_FILTER_DATESPEC_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILTER_DATESPEC, EFilterDatespecClass)) - -G_BEGIN_DECLS - -typedef struct _EFilterDatespec EFilterDatespec; -typedef struct _EFilterDatespecClass EFilterDatespecClass; -typedef struct _EFilterDatespecPrivate EFilterDatespecPrivate; - -typedef enum { - FDST_UNKNOWN = -1, - FDST_NOW, - FDST_SPECIFIED, - FDST_X_AGO, - FDST_X_FUTURE -} EFilterDatespecType; - -struct _EFilterDatespec { - EFilterElement parent; - EFilterDatespecPrivate *priv; - - EFilterDatespecType type; - - /* either a timespan, an absolute time, or 0 - * depending on type -- the above mapping to - * (X_FUTURE, X_AGO, SPECIFIED, NOW) - */ - - time_t value; -}; - -struct _EFilterDatespecClass { - EFilterElementClass parent_class; -}; - -GType e_filter_datespec_get_type (void); -EFilterDatespec * - e_filter_datespec_new (void); - -G_END_DECLS - -#endif /* E_FILTER_DATESPEC_H */ diff --git a/filter/e-filter-element.c b/filter/e-filter-element.c deleted file mode 100644 index e00651ec03..0000000000 --- a/filter/e-filter-element.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <stdlib.h> - -#include "e-filter-element.h" -#include "e-filter-part.h" - -struct _element_type { - gchar *name; - - EFilterElementFunc create; - gpointer data; -}; - -G_DEFINE_TYPE ( - EFilterElement, - e_filter_element, - G_TYPE_OBJECT) - -static gboolean -filter_element_validate (EFilterElement *element, - EAlert **alert) -{ - return TRUE; -} - -static gint -filter_element_eq (EFilterElement *element_a, - EFilterElement *element_b) -{ - return (g_strcmp0 (element_a->name, element_b->name) == 0); -} - -static void -filter_element_xml_create (EFilterElement *element, - xmlNodePtr node) -{ - element->name = (gchar *) xmlGetProp (node, (xmlChar *) "name"); -} - -static EFilterElement * -filter_element_clone (EFilterElement *element) -{ - EFilterElement *clone; - xmlNodePtr node; - - clone = g_object_new (G_OBJECT_TYPE (element), NULL); - - node = e_filter_element_xml_encode (element); - e_filter_element_xml_decode (clone, node); - xmlFreeNodeList (node); - - return clone; -} - -/* This is somewhat hackish, implement all the base cases in here */ -#include "e-filter-input.h" -#include "e-filter-option.h" -#include "e-filter-code.h" -#include "e-filter-color.h" -#include "e-filter-datespec.h" -#include "e-filter-int.h" -#include "e-filter-file.h" - -static void -filter_element_copy_value (EFilterElement *dst_element, - EFilterElement *src_element) -{ - if (E_IS_FILTER_INPUT (src_element)) { - EFilterInput *src_input; - - src_input = E_FILTER_INPUT (src_element); - - if (E_IS_FILTER_INPUT (dst_element)) { - EFilterInput *dst_input; - - dst_input = E_FILTER_INPUT (dst_element); - - if (src_input->values) - e_filter_input_set_value ( - dst_input, - src_input->values->data); - - } else if (E_IS_FILTER_INT (dst_element)) { - EFilterInt *dst_int; - - dst_int = E_FILTER_INT (dst_element); - - dst_int->val = atoi (src_input->values->data); - } - - } else if (E_IS_FILTER_COLOR (src_element)) { - EFilterColor *src_color; - - src_color = E_FILTER_COLOR (src_element); - - if (E_IS_FILTER_COLOR (dst_element)) { - EFilterColor *dst_color; - - dst_color = E_FILTER_COLOR (dst_element); - - dst_color->color = src_color->color; - } - - } else if (E_IS_FILTER_DATESPEC (src_element)) { - EFilterDatespec *src_datespec; - - src_datespec = E_FILTER_DATESPEC (src_element); - - if (E_IS_FILTER_DATESPEC (dst_element)) { - EFilterDatespec *dst_datespec; - - dst_datespec = E_FILTER_DATESPEC (dst_element); - - dst_datespec->type = src_datespec->type; - dst_datespec->value = src_datespec->value; - } - - } else if (E_IS_FILTER_INT (src_element)) { - EFilterInt *src_int; - - src_int = E_FILTER_INT (src_element); - - if (E_IS_FILTER_INT (dst_element)) { - EFilterInt *dst_int; - - dst_int = E_FILTER_INT (dst_element); - - dst_int->val = src_int->val; - - } else if (E_IS_FILTER_INPUT (dst_element)) { - EFilterInput *dst_input; - gchar *values; - - dst_input = E_FILTER_INPUT (dst_element); - - values = g_strdup_printf ("%d", src_int->val); - e_filter_input_set_value (dst_input, values); - g_free (values); - } - - } else if (E_IS_FILTER_OPTION (src_element)) { - EFilterOption *src_option; - - src_option = E_FILTER_OPTION (src_element); - - if (E_IS_FILTER_OPTION (dst_element)) { - EFilterOption *dst_option; - - dst_option = E_FILTER_OPTION (dst_element); - - if (src_option->current) - e_filter_option_set_current ( - dst_option, - src_option->current->value); - } - } -} - -static void -filter_element_finalize (GObject *object) -{ - EFilterElement *element = E_FILTER_ELEMENT (object); - - xmlFree (element->name); - - /* Chain up to parent's finalize () method. */ - G_OBJECT_CLASS (e_filter_element_parent_class)->finalize (object); -} - -static void -e_filter_element_class_init (EFilterElementClass *class) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = filter_element_finalize; - - class->validate = filter_element_validate; - class->eq = filter_element_eq; - class->xml_create = filter_element_xml_create; - class->clone = filter_element_clone; - class->copy_value = filter_element_copy_value; -} - -static void -e_filter_element_init (EFilterElement *element) -{ -} - -/** - * filter_element_new: - * - * Create a new EFilterElement object. - * - * Return value: A new #EFilterElement object. - **/ -EFilterElement * -e_filter_element_new (void) -{ - return g_object_new (E_TYPE_FILTER_ELEMENT, NULL); -} - -gboolean -e_filter_element_validate (EFilterElement *element, - EAlert **alert) -{ - EFilterElementClass *class; - - g_return_val_if_fail (E_IS_FILTER_ELEMENT (element), FALSE); - - class = E_FILTER_ELEMENT_GET_CLASS (element); - g_return_val_if_fail (class->validate != NULL, FALSE); - - return class->validate (element, alert); -} - -gint -e_filter_element_eq (EFilterElement *element_a, - EFilterElement *element_b) -{ - EFilterElementClass *class; - - g_return_val_if_fail (E_IS_FILTER_ELEMENT (element_a), FALSE); - g_return_val_if_fail (E_IS_FILTER_ELEMENT (element_b), FALSE); - - /* The elements must be the same type. */ - if (G_OBJECT_TYPE (element_a) != G_OBJECT_TYPE (element_b)) - return FALSE; - - class = E_FILTER_ELEMENT_GET_CLASS (element_a); - g_return_val_if_fail (class->eq != NULL, FALSE); - - return class->eq (element_a, element_b); -} - -/** - * filter_element_xml_create: - * @fe: filter element - * @node: xml node - * - * Create a new filter element based on an xml definition of - * that element. - **/ -void -e_filter_element_xml_create (EFilterElement *element, - xmlNodePtr node) -{ - EFilterElementClass *class; - - g_return_if_fail (E_IS_FILTER_ELEMENT (element)); - g_return_if_fail (node != NULL); - - class = E_FILTER_ELEMENT_GET_CLASS (element); - g_return_if_fail (class->xml_create != NULL); - - class->xml_create (element, node); -} - -/** - * filter_element_xml_encode: - * @fe: filter element - * - * Encode the values of a filter element into xml format. - * - * Return value: - **/ -xmlNodePtr -e_filter_element_xml_encode (EFilterElement *element) -{ - EFilterElementClass *class; - - g_return_val_if_fail (E_IS_FILTER_ELEMENT (element), NULL); - - class = E_FILTER_ELEMENT_GET_CLASS (element); - g_return_val_if_fail (class->xml_encode != NULL, NULL); - - return class->xml_encode (element); -} - -/** - * filter_element_xml_decode: - * @fe: filter element - * @node: xml node - * - * Decode the values of a fitler element from xml format. - * - * Return value: - **/ -gint -e_filter_element_xml_decode (EFilterElement *element, - xmlNodePtr node) -{ - EFilterElementClass *class; - - g_return_val_if_fail (E_IS_FILTER_ELEMENT (element), FALSE); - g_return_val_if_fail (node != NULL, FALSE); - - class = E_FILTER_ELEMENT_GET_CLASS (element); - g_return_val_if_fail (class->xml_decode != NULL, FALSE); - - return class->xml_decode (element, node); -} - -/** - * filter_element_clone: - * @fe: filter element - * - * Clones the EFilterElement @fe. - * - * Return value: - **/ -EFilterElement * -e_filter_element_clone (EFilterElement *element) -{ - EFilterElementClass *class; - - g_return_val_if_fail (E_IS_FILTER_ELEMENT (element), NULL); - - class = E_FILTER_ELEMENT_GET_CLASS (element); - g_return_val_if_fail (class->clone != NULL, NULL); - - return class->clone (element); -} - -/** - * filter_element_get_widget: - * @fe: filter element - * @node: xml node - * - * Create a widget to represent this element. - * - * Return value: - **/ -GtkWidget * -e_filter_element_get_widget (EFilterElement *element) -{ - EFilterElementClass *class; - - g_return_val_if_fail (E_IS_FILTER_ELEMENT (element), NULL); - - class = E_FILTER_ELEMENT_GET_CLASS (element); - g_return_val_if_fail (class->get_widget != NULL, NULL); - - return class->get_widget (element); -} - -/** - * filter_element_build_code: - * @fe: filter element - * @out: output buffer - * @ff: - * - * Add the code representing this element to the output string @out. - **/ -void -e_filter_element_build_code (EFilterElement *element, - GString *out, - EFilterPart *part) -{ - EFilterElementClass *class; - - g_return_if_fail (E_IS_FILTER_ELEMENT (element)); - g_return_if_fail (out != NULL); - g_return_if_fail (E_IS_FILTER_PART (part)); - - class = E_FILTER_ELEMENT_GET_CLASS (element); - - /* This method is optional. */ - if (class->build_code != NULL) - class->build_code (element, out, part); -} - -/** - * filter_element_format_sexp: - * @fe: filter element - * @out: output buffer - * - * Format the value(s) of this element in a method suitable for the context of - * sexp where it is used. Usually as space separated, double-quoted strings. - **/ -void -e_filter_element_format_sexp (EFilterElement *element, - GString *out) -{ - EFilterElementClass *class; - - g_return_if_fail (E_IS_FILTER_ELEMENT (element)); - g_return_if_fail (out != NULL); - - class = E_FILTER_ELEMENT_GET_CLASS (element); - g_return_if_fail (class->format_sexp != NULL); - - class->format_sexp (element, out); -} - -void -e_filter_element_set_data (EFilterElement *element, - gpointer data) -{ - g_return_if_fail (E_IS_FILTER_ELEMENT (element)); - - element->data = data; -} - -/* only copies the value, not the name/type */ -void -e_filter_element_copy_value (EFilterElement *dst_element, - EFilterElement *src_element) -{ - EFilterElementClass *class; - - g_return_if_fail (E_IS_FILTER_ELEMENT (dst_element)); - g_return_if_fail (E_IS_FILTER_ELEMENT (src_element)); - - class = E_FILTER_ELEMENT_GET_CLASS (dst_element); - g_return_if_fail (class->copy_value != NULL); - - class->copy_value (dst_element, src_element); -} diff --git a/filter/e-filter-element.h b/filter/e-filter-element.h deleted file mode 100644 index 694efa2de6..0000000000 --- a/filter/e-filter-element.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILTER_ELEMENT_H -#define E_FILTER_ELEMENT_H - -#include <gtk/gtk.h> -#include <camel/camel.h> -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> -#include <libevolution-utils/e-alert.h> - -#define E_TYPE_FILTER_ELEMENT \ - (e_filter_element_get_type ()) -#define E_FILTER_ELEMENT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILTER_ELEMENT, EFilterElement)) -#define E_FILTER_ELEMENT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILTER_ELEMENT, EFilterElementClass)) -#define E_IS_FILTER_ELEMENT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILTER_ELEMENT)) -#define E_IS_FILTER_ELEMENT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FILTER_ELEMENT)) -#define E_FILTER_ELEMENT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILTER_ELEMENT, EFilterElementClass)) - -G_BEGIN_DECLS - -struct _EFilterPart; - -typedef struct _EFilterElement EFilterElement; -typedef struct _EFilterElementClass EFilterElementClass; -typedef struct _EFilterElementPrivate EFilterElementPrivate; - -typedef EFilterElement * (*EFilterElementFunc) (gpointer data); - -struct _EFilterElement { - GObject parent; - EFilterElementPrivate *priv; - - gchar *name; - gpointer data; -}; - -struct _EFilterElementClass { - GObjectClass parent_class; - - gboolean (*validate) (EFilterElement *element, - EAlert **alert); - gint (*eq) (EFilterElement *element_a, - EFilterElement *element_b); - - void (*xml_create) (EFilterElement *element, - xmlNodePtr node); - xmlNodePtr (*xml_encode) (EFilterElement *element); - gint (*xml_decode) (EFilterElement *element, - xmlNodePtr node); - - EFilterElement *(*clone) (EFilterElement *element); - void (*copy_value) (EFilterElement *dst_element, - EFilterElement *src_element); - - GtkWidget * (*get_widget) (EFilterElement *element); - void (*build_code) (EFilterElement *element, - GString *out, - struct _EFilterPart *part); - void (*format_sexp) (EFilterElement *element, - GString *out); -}; - -GType e_filter_element_get_type (void); -EFilterElement *e_filter_element_new (void); -void e_filter_element_set_data (EFilterElement *element, - gpointer data); -gboolean e_filter_element_validate (EFilterElement *element, - EAlert **alert); -gint e_filter_element_eq (EFilterElement *element_a, - EFilterElement *element_b); -void e_filter_element_xml_create (EFilterElement *element, - xmlNodePtr node); -xmlNodePtr e_filter_element_xml_encode (EFilterElement *element); -gint e_filter_element_xml_decode (EFilterElement *element, - xmlNodePtr node); -EFilterElement *e_filter_element_clone (EFilterElement *element); -void e_filter_element_copy_value (EFilterElement *dst_element, - EFilterElement *src_element); -GtkWidget * e_filter_element_get_widget (EFilterElement *element); -void e_filter_element_build_code (EFilterElement *element, - GString *out, - struct _EFilterPart *part); -void e_filter_element_format_sexp (EFilterElement *element, - GString *out); - -G_END_DECLS - -#endif /* E_FILTER_ELEMENT_H */ diff --git a/filter/e-filter-file.c b/filter/e-filter-file.c deleted file mode 100644 index 4be1a10fda..0000000000 --- a/filter/e-filter-file.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <sys/types.h> - -#include <gtk/gtk.h> -#include <glib/gi18n.h> -#include <glib/gstdio.h> - -#include "libevolution-utils/e-alert.h" - -#include "e-filter-file.h" -#include "e-filter-part.h" - -G_DEFINE_TYPE ( - EFilterFile, - e_filter_file, - E_TYPE_FILTER_ELEMENT) - -static void -filter_file_filename_changed (GtkFileChooser *file_chooser, - EFilterElement *element) -{ - EFilterFile *file = E_FILTER_FILE (element); - const gchar *path; - - path = gtk_file_chooser_get_filename (file_chooser); - - g_free (file->path); - file->path = g_strdup (path); -} - -static void -filter_file_finalize (GObject *object) -{ - EFilterFile *file = E_FILTER_FILE (object); - - xmlFree (file->type); - g_free (file->path); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_filter_file_parent_class)->finalize (object); -} - -static gboolean -filter_file_validate (EFilterElement *element, - EAlert **alert) -{ - EFilterFile *file = E_FILTER_FILE (element); - - g_warn_if_fail (alert == NULL || *alert == NULL); - - if (!file->path) { - if (alert) - *alert = e_alert_new ("filter:no-file", NULL); - return FALSE; - } - - /* FIXME: do more to validate command-lines? */ - - if (g_strcmp0 (file->type, "file") == 0) { - if (!g_file_test (file->path, G_FILE_TEST_IS_REGULAR)) { - if (alert) - *alert = e_alert_new ("filter:bad-file", - file->path, NULL); - return FALSE; - } - } else if (g_strcmp0 (file->type, "command") == 0) { - /* Only requirements so far is that the - * command can't be an empty string. */ - return (file->path[0] != '\0'); - } - - return TRUE; -} - -static gint -filter_file_eq (EFilterElement *element_a, - EFilterElement *element_b) -{ - EFilterFile *file_a = E_FILTER_FILE (element_a); - EFilterFile *file_b = E_FILTER_FILE (element_b); - - /* Chain up to parent's eq() method. */ - if (!E_FILTER_ELEMENT_CLASS (e_filter_file_parent_class)-> - eq (element_a, element_b)) - return FALSE; - - if (g_strcmp0 (file_a->path, file_b->path) != 0) - return FALSE; - - if (g_strcmp0 (file_a->type, file_b->type) != 0) - return FALSE; - - return TRUE; -} - -static xmlNodePtr -filter_file_xml_encode (EFilterElement *element) -{ - EFilterFile *file = E_FILTER_FILE (element); - xmlNodePtr cur, value; - const gchar *type; - - type = file->type ? file->type : "file"; - - value = xmlNewNode (NULL, (xmlChar *)"value"); - xmlSetProp (value, (xmlChar *) "name", (xmlChar *) element->name); - xmlSetProp (value, (xmlChar *) "type", (xmlChar *) type); - - cur = xmlNewChild (value, NULL, (xmlChar *) type, NULL); - xmlNodeSetContent (cur, (xmlChar *) file->path); - - return value; -} - -static gint -filter_file_xml_decode (EFilterElement *element, - xmlNodePtr node) -{ - EFilterFile *file = E_FILTER_FILE (element); - gchar *name, *str, *type; - xmlNodePtr child; - - name = (gchar *) xmlGetProp (node, (xmlChar *) "name"); - type = (gchar *) xmlGetProp (node, (xmlChar *) "type"); - - xmlFree (element->name); - element->name = name; - - xmlFree (file->type); - file->type = type; - - g_free (file->path); - file->path = NULL; - - child = node->children; - while (child != NULL) { - if (!strcmp ((gchar *) child->name, type)) { - str = (gchar *) xmlNodeGetContent (child); - file->path = g_strdup (str ? str : ""); - xmlFree (str); - - break; - } else if (child->type == XML_ELEMENT_NODE) { - g_warning ( - "Unknown node type '%s' encountered " - "decoding a %s\n", child->name, type); - } - - child = child->next; - } - - return 0; -} - -static GtkWidget * -filter_file_get_widget (EFilterElement *element) -{ - EFilterFile *file = E_FILTER_FILE (element); - GtkWidget *widget; - - widget = gtk_file_chooser_button_new ( - _("Choose a File"), GTK_FILE_CHOOSER_ACTION_OPEN); - gtk_file_chooser_set_filename ( - GTK_FILE_CHOOSER (widget), file->path); - g_signal_connect ( - widget, "selection-changed", - G_CALLBACK (filter_file_filename_changed), element); - - return widget; -} - -static void -filter_file_format_sexp (EFilterElement *element, - GString *out) -{ - EFilterFile *file = E_FILTER_FILE (element); - - camel_sexp_encode_string (out, file->path); -} - -static void -e_filter_file_class_init (EFilterFileClass *class) -{ - GObjectClass *object_class; - EFilterElementClass *filter_element_class; - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = filter_file_finalize; - - filter_element_class = E_FILTER_ELEMENT_CLASS (class); - filter_element_class->validate = filter_file_validate; - filter_element_class->eq = filter_file_eq; - filter_element_class->xml_encode = filter_file_xml_encode; - filter_element_class->xml_decode = filter_file_xml_decode; - filter_element_class->get_widget = filter_file_get_widget; - filter_element_class->format_sexp = filter_file_format_sexp; -} - -static void -e_filter_file_init (EFilterFile *filter) -{ -} - -/** - * filter_file_new: - * - * Create a new EFilterFile object. - * - * Return value: A new #EFilterFile object. - **/ -EFilterFile * -e_filter_file_new (void) -{ - return g_object_new (E_TYPE_FILTER_FILE, NULL); -} - -EFilterFile * -e_filter_file_new_type_name (const gchar *type) -{ - EFilterFile *file; - - file = e_filter_file_new (); - file->type = (gchar *) xmlStrdup ((xmlChar *) type); - - return file; -} - -void -e_filter_file_set_path (EFilterFile *file, - const gchar *path) -{ - g_return_if_fail (E_IS_FILTER_FILE (file)); - - g_free (file->path); - file->path = g_strdup (path); -} diff --git a/filter/e-filter-file.h b/filter/e-filter-file.h deleted file mode 100644 index 6f7946e8e7..0000000000 --- a/filter/e-filter-file.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILTER_FILE_H -#define E_FILTER_FILE_H - -#include "e-filter-element.h" - -/* Standard GObject macros */ -#define E_TYPE_FILTER_FILE \ - (e_filter_file_get_type ()) -#define E_FILTER_FILE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILTER_FILE, EFilterFile)) -#define E_FILTER_FILE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILTER_FILE, EFilterFileClass)) -#define E_IS_FILTER_FILE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILTER_FILE)) -#define E_IS_FILTER_FILE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FILTER_FILE)) -#define E_FILTER_FILE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILTER_FILE, EFilterFileClass)) - -G_BEGIN_DECLS - -typedef struct _EFilterFile EFilterFile; -typedef struct _EFilterFileClass EFilterFileClass; -typedef struct _EFilterFilePrivate EFilterFilePrivate; - -struct _EFilterFile { - EFilterElement parent; - EFilterFilePrivate *priv; - - gchar *type; - gchar *path; -}; - -struct _EFilterFileClass { - EFilterElementClass parent_class; -}; - -GType e_filter_file_get_type (void); -EFilterFile * e_filter_file_new (void); -EFilterFile * e_filter_file_new_type_name (const gchar *type); -void e_filter_file_set_path (EFilterFile *file, - const gchar *path); - -G_END_DECLS - -#endif /* E_FILTER_FILE_H */ diff --git a/filter/e-filter-input.c b/filter/e-filter-input.c deleted file mode 100644 index b13f910048..0000000000 --- a/filter/e-filter-input.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <sys/types.h> -#include <regex.h> - -#include <gtk/gtk.h> -#include <glib/gi18n.h> - -#include "libevolution-utils/e-alert.h" - -#include "e-filter-input.h" - -G_DEFINE_TYPE ( - EFilterInput, - e_filter_input, - E_TYPE_FILTER_ELEMENT) - -static void -filter_input_entry_changed (GtkEntry *entry, - EFilterElement *element) -{ - EFilterInput *input = E_FILTER_INPUT (element); - const gchar *text; - - g_list_foreach (input->values, (GFunc) g_free, NULL); - g_list_free (input->values); - - text = gtk_entry_get_text (entry); - input->values = g_list_append (NULL, g_strdup (text)); -} - -static void -filter_input_finalize (GObject *object) -{ - EFilterInput *input = E_FILTER_INPUT (object); - - xmlFree (input->type); - - g_list_foreach (input->values, (GFunc) g_free, NULL); - g_list_free (input->values); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_filter_input_parent_class)->finalize (object); -} - -static gboolean -filter_input_validate (EFilterElement *element, - EAlert **alert) -{ - EFilterInput *input = E_FILTER_INPUT (element); - gboolean valid = TRUE; - - g_warn_if_fail (alert == NULL || *alert == NULL); - - if (input->values && !strcmp (input->type, "regex")) { - const gchar *pattern; - regex_t regexpat; - gint regerr; - - pattern = input->values->data; - - regerr = regcomp ( - ®expat, pattern, - REG_EXTENDED | REG_NEWLINE | REG_ICASE); - if (regerr != 0) { - if (alert) { - gsize reglen; - gchar *regmsg; - - /* regerror gets called twice to get the full error string - * length to do proper posix error reporting */ - reglen = regerror (regerr, ®expat, 0, 0); - regmsg = g_malloc0 (reglen + 1); - regerror (regerr, ®expat, regmsg, reglen); - - *alert = e_alert_new ("filter:bad-regexp", - pattern, regmsg, NULL); - g_free (regmsg); - } - - valid = FALSE; - } - - regfree (®expat); - } - - return valid; -} - -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 xmlNodePtr -filter_input_xml_encode (EFilterElement *element) -{ - EFilterInput *input = E_FILTER_INPUT (element); - xmlNodePtr value; - GList *link; - const gchar *type; - - type = input->type ? input->type : "string"; - - value = xmlNewNode (NULL, (xmlChar *) "value"); - xmlSetProp (value, (xmlChar *) "name", (xmlChar *) element->name); - xmlSetProp (value, (xmlChar *) "type", (xmlChar *) type); - - for (link = input->values; link != NULL; link = g_list_next (link)) { - xmlChar *str = link->data; - xmlNodePtr cur; - - cur = xmlNewChild (value, NULL, (xmlChar *) type, NULL); - - str = xmlEncodeEntitiesReentrant (NULL, str); - xmlNodeSetContent (cur, str); - xmlFree (str); - } - - return value; -} - -static gint -filter_input_xml_decode (EFilterElement *element, - xmlNodePtr node) -{ - EFilterInput *input = (EFilterInput *) element; - gchar *name, *str, *type; - xmlNodePtr child; - - g_list_foreach (input->values, (GFunc) g_free, NULL); - g_list_free (input->values); - input->values = NULL; - - name = (gchar *) xmlGetProp (node, (xmlChar *) "name"); - type = (gchar *) xmlGetProp (node, (xmlChar *) "type"); - - xmlFree (element->name); - element->name = name; - - xmlFree (input->type); - input->type = type; - - child = node->children; - while (child != NULL) { - if (!strcmp ((gchar *) child->name, type)) { - if (!(str = (gchar *) xmlNodeGetContent (child))) - str = (gchar *) xmlStrdup ((xmlChar *)""); - - input->values = g_list_append (input->values, g_strdup (str)); - xmlFree (str); - } else if (child->type == XML_ELEMENT_NODE) { - g_warning ( - "Unknown node type '%s' encountered " - "decoding a %s\n", child->name, type); - } - child = child->next; - } - - return 0; -} - -static GtkWidget * -filter_input_get_widget (EFilterElement *element) -{ - EFilterInput *input = E_FILTER_INPUT (element); - GtkWidget *entry; - - entry = gtk_entry_new (); - if (input->values && input->values->data) - gtk_entry_set_text ( - GTK_ENTRY (entry), input->values->data); - - g_signal_connect ( - entry, "changed", - G_CALLBACK (filter_input_entry_changed), element); - - return entry; -} - -static void -filter_input_format_sexp (EFilterElement *element, - GString *out) -{ - EFilterInput *input = E_FILTER_INPUT (element); - GList *link; - - for (link = input->values; link != NULL; link = g_list_next (link)) - camel_sexp_encode_string (out, link->data); -} - -static void -e_filter_input_class_init (EFilterInputClass *class) -{ - GObjectClass *object_class; - EFilterElementClass *filter_element_class; - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = filter_input_finalize; - - filter_element_class = E_FILTER_ELEMENT_CLASS (class); - filter_element_class->validate = filter_input_validate; - filter_element_class->eq = filter_input_eq; - filter_element_class->xml_encode = filter_input_xml_encode; - filter_element_class->xml_decode = filter_input_xml_decode; - filter_element_class->get_widget = filter_input_get_widget; - filter_element_class->format_sexp = filter_input_format_sexp; -} - -static void -e_filter_input_init (EFilterInput *input) -{ - input->values = g_list_prepend (NULL, g_strdup ("")); -} - -/** - * filter_input_new: - * - * Create a new EFilterInput object. - * - * Return value: A new #EFilterInput object. - **/ -EFilterInput * -e_filter_input_new (void) -{ - return g_object_new (E_TYPE_FILTER_INPUT, NULL); -} - -EFilterInput * -e_filter_input_new_type_name (const gchar *type) -{ - EFilterInput *input; - - input = e_filter_input_new (); - input->type = (gchar *) xmlStrdup ((xmlChar *) type); - - return input; -} - -void -e_filter_input_set_value (EFilterInput *input, - const gchar *value) -{ - g_return_if_fail (E_IS_FILTER_INPUT (input)); - - g_list_foreach (input->values, (GFunc) g_free, NULL); - g_list_free (input->values); - - input->values = g_list_append (NULL, g_strdup (value)); -} diff --git a/filter/e-filter-input.h b/filter/e-filter-input.h deleted file mode 100644 index 07239c92cb..0000000000 --- a/filter/e-filter-input.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILTER_INPUT_H -#define E_FILTER_INPUT_H - -#include "e-filter-element.h" - -/* Standard GObject macros */ -#define E_TYPE_FILTER_INPUT \ - (e_filter_input_get_type ()) -#define E_FILTER_INPUT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILTER_INPUT, EFilterInput)) -#define E_FILTER_INPUT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILTER_INPUT, EFilterInputClass)) -#define E_IS_FILTER_INPUT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILTER_INPUT)) -#define E_IS_FILTER_INPUT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FILTER_INPUT)) -#define E_FILTER_INPUT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILTER_INPUT, EFilterInputClass)) - -G_BEGIN_DECLS - -typedef struct _EFilterInput EFilterInput; -typedef struct _EFilterInputClass EFilterInputClass; -typedef struct _EFilterInputPrivate EFilterInputPrivate; - -struct _EFilterInput { - EFilterElement parent; - EFilterInputPrivate *priv; - - gchar *type; /* name of type */ - GList *values; /* strings */ -}; - -struct _EFilterInputClass { - EFilterElementClass parent_class; -}; - -GType e_filter_input_get_type (void); -EFilterInput * e_filter_input_new (void); -EFilterInput * e_filter_input_new_type_name (const gchar *type); -void e_filter_input_set_value (EFilterInput *input, - const gchar *value); - -G_END_DECLS - -#endif /* E_FILTER_INPUT_H */ diff --git a/filter/e-filter-int.c b/filter/e-filter-int.c deleted file mode 100644 index ba4eacde2e..0000000000 --- a/filter/e-filter-int.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <gtk/gtk.h> - -#include "e-filter-int.h" - -G_DEFINE_TYPE ( - EFilterInt, - e_filter_int, - E_TYPE_FILTER_ELEMENT) - -static void -filter_int_spin_changed (GtkSpinButton *spin_button, - EFilterElement *element) -{ - EFilterInt *filter_int = E_FILTER_INT (element); - - filter_int->val = gtk_spin_button_get_value_as_int (spin_button); -} - -static void -filter_int_finalize (GObject *object) -{ - EFilterInt *filter_int = E_FILTER_INT (object); - - g_free (filter_int->type); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_filter_int_parent_class)->finalize (object); -} - -static gint -filter_int_eq (EFilterElement *element_a, - EFilterElement *element_b) -{ - EFilterInt *filter_int_a = E_FILTER_INT (element_a); - EFilterInt *filter_int_b = E_FILTER_INT (element_b); - - /* Chain up to parent's eq() method. */ - if (!E_FILTER_ELEMENT_CLASS (e_filter_int_parent_class)-> - eq (element_a, element_b)) - return FALSE; - - return (filter_int_a->val == filter_int_b->val); -} - -static EFilterElement * -filter_int_clone (EFilterElement *element) -{ - EFilterInt *filter_int = E_FILTER_INT (element); - EFilterInt *clone; - - clone = (EFilterInt *) e_filter_int_new_type ( - filter_int->type, filter_int->min, filter_int->max); - clone->val = filter_int->val; - - E_FILTER_ELEMENT (clone)->name = g_strdup (element->name); - - return E_FILTER_ELEMENT (clone); -} - -static xmlNodePtr -filter_int_xml_encode (EFilterElement *element) -{ - EFilterInt *filter_int = E_FILTER_INT (element); - xmlNodePtr value; - gchar intval[32]; - const gchar *type; - - type = filter_int->type ? filter_int->type : "integer"; - - value = xmlNewNode (NULL, (xmlChar *)"value"); - xmlSetProp (value, (xmlChar *) "name", (xmlChar *) element->name); - xmlSetProp (value, (xmlChar *) "type", (xmlChar *) type); - - sprintf (intval, "%d", filter_int->val); - xmlSetProp (value, (xmlChar *) type, (xmlChar *) intval); - - return value; -} - -static gint -filter_int_xml_decode (EFilterElement *element, - xmlNodePtr node) -{ - EFilterInt *filter_int = E_FILTER_INT (element); - gchar *name, *type; - gchar *intval; - - name = (gchar *) xmlGetProp (node, (xmlChar *)"name"); - xmlFree (element->name); - element->name = name; - - type = (gchar *) xmlGetProp (node, (xmlChar *)"type"); - g_free (filter_int->type); - filter_int->type = g_strdup (type); - xmlFree (type); - - intval = (gchar *) xmlGetProp ( - node, (xmlChar *) (filter_int->type ? - filter_int->type : "integer")); - if (intval) { - filter_int->val = atoi (intval); - xmlFree (intval); - } else { - filter_int->val = 0; - } - - return 0; -} - -static GtkWidget * -filter_int_get_widget (EFilterElement *element) -{ - EFilterInt *filter_int = E_FILTER_INT (element); - GtkWidget *widget; - GtkAdjustment *adjustment; - - adjustment = GTK_ADJUSTMENT (gtk_adjustment_new ( - 0.0, (gfloat) filter_int->min, - (gfloat) filter_int->max, 1.0, 1.0, 0)); - widget = gtk_spin_button_new ( - adjustment, - filter_int->max > filter_int->min + 1000 ? 5.0 : 1.0, 0); - gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (widget), TRUE); - - if (filter_int->val) - gtk_spin_button_set_value ( - GTK_SPIN_BUTTON (widget), (gfloat) filter_int->val); - - g_signal_connect ( - widget, "value-changed", - G_CALLBACK (filter_int_spin_changed), element); - - return widget; -} - -static void -filter_int_format_sexp (EFilterElement *element, - GString *out) -{ - EFilterInt *filter_int = E_FILTER_INT (element); - - if (filter_int->val < 0) - /* See #364731 #457523 C6*/ - g_string_append_printf (out, "(- 0 %d)", (filter_int->val * -1)); - else - g_string_append_printf (out, "%d", filter_int->val); -} - -static void -e_filter_int_class_init (EFilterIntClass *class) -{ - GObjectClass *object_class; - EFilterElementClass *filter_element_class; - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = filter_int_finalize; - - filter_element_class = E_FILTER_ELEMENT_CLASS (class); - filter_element_class->eq = filter_int_eq; - filter_element_class->clone = filter_int_clone; - filter_element_class->xml_encode = filter_int_xml_encode; - filter_element_class->xml_decode = filter_int_xml_decode; - filter_element_class->get_widget = filter_int_get_widget; - filter_element_class->format_sexp = filter_int_format_sexp; -} - -static void -e_filter_int_init (EFilterInt *filter_int) -{ - filter_int->min = 0; - filter_int->max = G_MAXINT; -} - -EFilterElement * -e_filter_int_new (void) -{ - return g_object_new (E_TYPE_FILTER_INT, NULL); -} - -EFilterElement * -e_filter_int_new_type (const gchar *type, - gint min, - gint max) -{ - EFilterInt *filter_int; - - filter_int = g_object_new (E_TYPE_FILTER_INT, NULL); - - filter_int->type = g_strdup (type); - filter_int->min = min; - filter_int->max = max; - - return E_FILTER_ELEMENT (filter_int); -} - -void -e_filter_int_set_value (EFilterInt *filter_int, - gint value) -{ - g_return_if_fail (E_IS_FILTER_INT (filter_int)); - - filter_int->val = value; -} diff --git a/filter/e-filter-int.h b/filter/e-filter-int.h deleted file mode 100644 index be0aa4e65a..0000000000 --- a/filter/e-filter-int.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILTER_INT_H -#define E_FILTER_INT_H - -#include "e-filter-element.h" - -/* Standard GObject macros */ -#define E_TYPE_FILTER_INT \ - (e_filter_int_get_type ()) -#define E_FILTER_INT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILTER_INT, EFilterInt)) -#define E_FILTER_INT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILTER_INT, EFilterIntClass)) -#define E_IS_FILTER_INT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILTER_INT)) -#define E_IS_FILTER_INT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FILTER_INT)) -#define E_FILTER_INT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILTER_INT, EFilterIntClass)) - -G_BEGIN_DECLS - -typedef struct _EFilterInt EFilterInt; -typedef struct _EFilterIntClass EFilterIntClass; -typedef struct _EFilterIntPrivate EFilterIntPrivate; - -struct _EFilterInt { - EFilterElement parent; - EFilterIntPrivate *priv; - - gchar *type; - gint val; - gint min; - gint max; -}; - -struct _EFilterIntClass { - EFilterElementClass parent_class; -}; - -GType e_filter_int_get_type (void); -EFilterElement *e_filter_int_new (void); -EFilterElement *e_filter_int_new_type (const gchar *type, - gint min, - gint max); -void e_filter_int_set_value (EFilterInt *f_int, - gint value); - -G_END_DECLS - -#endif /* E_FILTER_INT_H */ diff --git a/filter/e-filter-option.c b/filter/e-filter-option.c deleted file mode 100644 index 630ab31916..0000000000 --- a/filter/e-filter-option.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <gtk/gtk.h> -#include <glib/gi18n.h> -#include <gmodule.h> - -#include "e-filter-option.h" -#include "e-filter-part.h" - -G_DEFINE_TYPE ( - EFilterOption, - e_filter_option, - E_TYPE_FILTER_ELEMENT) - -static void -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); -} - -static struct _filter_option * -find_option (EFilterOption *option, - const gchar *name) -{ - GList *link; - - for (link = option->options; link != NULL; link = g_list_next (link)) { - struct _filter_option *opt = link->data; - - if (strcmp (name, opt->value) == 0) - return opt; - } - - return NULL; -} - -static void -filter_option_combobox_changed (GtkComboBox *combo_box, - EFilterElement *element) -{ - EFilterOption *option = E_FILTER_OPTION (element); - gint active; - - active = gtk_combo_box_get_active (combo_box); - option->current = g_list_nth_data (option->options, active); -} - -static GSList * -filter_option_get_dynamic_options (EFilterOption *option) -{ - GModule *module; - GSList *(*get_func)(void); - GSList *res = NULL; - - if (!option || !option->dynamic_func) - return res; - - module = g_module_open (NULL, G_MODULE_BIND_LAZY); - - if (g_module_symbol (module, option->dynamic_func, (gpointer) &get_func)) { - res = get_func (); - } else { - g_warning ( - "optionlist dynamic fill function '%s' not found", - option->dynamic_func); - } - - g_module_close (module); - - return res; -} - -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); - - g_list_foreach (option->options, (GFunc) free_option, NULL); - g_list_free (option->options); - - g_free (option->dynamic_func); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_filter_option_parent_class)->finalize (object); -} - -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; - } -} - -static xmlNodePtr -filter_option_xml_encode (EFilterElement *element) -{ - EFilterOption *option = E_FILTER_OPTION (element); - xmlNodePtr value; - - value = xmlNewNode (NULL, (xmlChar *) "value"); - xmlSetProp (value, (xmlChar *) "name", (xmlChar *) element->name); - xmlSetProp (value, (xmlChar *) "type", (xmlChar *) option->type); - if (option->current) - xmlSetProp (value, (xmlChar *) "value", (xmlChar *) option->current->value); - - return value; -} - -static gint -filter_option_xml_decode (EFilterElement *element, - xmlNodePtr node) -{ - EFilterOption *option = E_FILTER_OPTION (element); - gchar *value; - - xmlFree (element->name); - element->name = (gchar *) xmlGetProp (node, (xmlChar *)"name"); - - value = (gchar *) xmlGetProp (node, (xmlChar *)"value"); - if (value) { - option->current = find_option (option, value); - xmlFree (value); - } else { - option->current = NULL; - } - - return 0; -} - -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 GtkWidget * -filter_option_get_widget (EFilterElement *element) -{ - EFilterOption *option = E_FILTER_OPTION (element); - GtkWidget *combobox; - GList *l; - struct _filter_option *op; - gint index = 0, current = 0; - - if (option->dynamic_func) { - /* it is dynamically filled, thus remove all dynamics - * and put there the fresh ones */ - GSList *items, *i; - GList *old_ops; - struct _filter_option *old_cur; - - old_ops = option->options; - old_cur = option->current; - - /* start with an empty list */ - option->current = NULL; - option->options = NULL; - - for (l = option->options; l; l = l->next) { - op = l->data; - - if (op->is_dynamic) { - break; - } else { - e_filter_option_add ( - option, op->value, op->title, - op->code, op->code_gen_func, FALSE); - } - } - - 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); - - /* maybe some static left after those dynamic, add them too */ - for (; l; l = l->next) { - op = l->data; - - if (!op->is_dynamic) - e_filter_option_add ( - option, op->value, op->title, - op->code, op->code_gen_func, FALSE); - } - - if (old_cur) - e_filter_option_set_current (option, old_cur->value); - - /* free old list */ - g_list_foreach (old_ops, (GFunc) free_option, NULL); - g_list_free (old_ops); - } - - combobox = gtk_combo_box_text_new (); - l = option->options; - while (l) { - op = l->data; - gtk_combo_box_text_append_text ( - GTK_COMBO_BOX_TEXT (combobox), _(op->title)); - - if (op == option->current) - current = index; - - l = g_list_next (l); - index++; - } - - g_signal_connect ( - combobox, "changed", - G_CALLBACK (filter_option_combobox_changed), element); - - gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), current); - - return combobox; -} - -static void -filter_option_build_code (EFilterElement *element, - GString *out, - EFilterPart *part) -{ - EFilterOption *option = E_FILTER_OPTION (element); - - 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 -filter_option_format_sexp (EFilterElement *element, - GString *out) -{ - EFilterOption *option = E_FILTER_OPTION (element); - - if (option->current) - camel_sexp_encode_string (out, option->current->value); -} - -static void -e_filter_option_class_init (EFilterOptionClass *class) -{ - GObjectClass *object_class; - EFilterElementClass *filter_element_class; - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = filter_option_finalize; - - filter_element_class = E_FILTER_ELEMENT_CLASS (class); - filter_element_class->eq = filter_option_eq; - filter_element_class->xml_create = filter_option_xml_create; - filter_element_class->xml_encode = filter_option_xml_encode; - filter_element_class->xml_decode = filter_option_xml_decode; - filter_element_class->clone = filter_option_clone; - filter_element_class->get_widget = filter_option_get_widget; - filter_element_class->build_code = filter_option_build_code; - filter_element_class->format_sexp = filter_option_format_sexp; -} - -static void -e_filter_option_init (EFilterOption *option) -{ - option->type = "option"; - option->dynamic_func = NULL; -} - -EFilterElement * -e_filter_option_new (void) -{ - return g_object_new (E_TYPE_FILTER_OPTION, NULL); -} - -void -e_filter_option_set_current (EFilterOption *option, - const gchar *name) -{ - g_return_if_fail (E_IS_FILTER_OPTION (option)); - - option->current = find_option (option, name); -} - -/* used by implementers to add additional options */ -struct _filter_option * -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; - - 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); - - if (option->current == NULL) - option->current = op; - - return op; -} - -const gchar * -e_filter_option_get_current (EFilterOption *option) -{ - g_return_val_if_fail (E_IS_FILTER_OPTION (option), NULL); - - if (option->current == NULL) - return NULL; - - return option->current->value; -} - -void -e_filter_option_remove_all (EFilterOption *option) -{ - g_return_if_fail (E_IS_FILTER_OPTION (option)); - - g_list_foreach (option->options, (GFunc) free_option, NULL); - g_list_free (option->options); - - option->options = NULL; - option->current = NULL; -} diff --git a/filter/e-filter-option.h b/filter/e-filter-option.h deleted file mode 100644 index f241f09250..0000000000 --- a/filter/e-filter-option.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILTER_OPTION_H -#define E_FILTER_OPTION_H - -#include "e-filter-element.h" - -/* Standard GObject macros */ -#define E_TYPE_FILTER_OPTION \ - (e_filter_option_get_type ()) -#define E_FILTER_OPTION(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILTER_OPTION, EFilterOption)) -#define E_FILTER_OPTION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILTER_OPTION, EFilterOptionClass)) -#define E_IS_FILTER_OPTION(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILTER_OPTION)) -#define E_IS_FILTER_OPTION_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FILTER_OPTION)) -#define E_FILTER_OPTION_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILTER_OPTION, EFilterOptionClass)) - -G_BEGIN_DECLS - -typedef struct _EFilterOption EFilterOption; -typedef struct _EFilterOptionClass EFilterOptionClass; -typedef struct _EFilterOptionPrivate EFilterOptionPrivate; - -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; - * dynamic means "generated by EFilterOption::dynamic_func" */ -}; - -struct _EFilterOption { - EFilterElement parent; - EFilterOptionPrivate *priv; - - const gchar *type; /* static memory, type name written to xml */ - - GList *options; - struct _filter_option *current; - gchar *dynamic_func; /* name of the dynamic fill func, called in get_widget */ -}; - -struct _EFilterOptionClass { - EFilterElementClass parent_class; -}; - -GType e_filter_option_get_type (void); -EFilterElement *e_filter_option_new (void); -void e_filter_option_set_current (EFilterOption *option, - const gchar *name); -const gchar * e_filter_option_get_current (EFilterOption *option); -struct _filter_option * - e_filter_option_add (EFilterOption *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); - -G_END_DECLS - -#endif /* E_FILTER_OPTION_H */ diff --git a/filter/e-filter-part.c b/filter/e-filter-part.c deleted file mode 100644 index c9e14e30c6..0000000000 --- a/filter/e-filter-part.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jepartrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#include <gtk/gtk.h> -#include <glib/gi18n.h> - -#include "e-filter-file.h" -#include "e-filter-part.h" -#include "e-rule-context.h" - -G_DEFINE_TYPE ( - EFilterPart, - e_filter_part, - G_TYPE_OBJECT) - -static void -filter_part_finalize (GObject *object) -{ - EFilterPart *part = E_FILTER_PART (object); - - g_list_foreach (part->elements, (GFunc) g_object_unref, NULL); - g_list_free (part->elements); - - g_free (part->name); - g_free (part->title); - g_free (part->code); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_filter_part_parent_class)->finalize (object); -} - -static void -e_filter_part_class_init (EFilterPartClass *class) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = filter_part_finalize; -} - -static void -e_filter_part_init (EFilterPart *part) -{ -} - -/** - * e_filter_part_new: - * - * Create a new EFilterPart object. - * - * Return value: A new #EFilterPart object. - **/ -EFilterPart * -e_filter_part_new (void) -{ - return g_object_new (E_TYPE_FILTER_PART, NULL); -} - -gboolean -e_filter_part_validate (EFilterPart *part, - EAlert **alert) -{ - GList *link; - - g_return_val_if_fail (E_IS_FILTER_PART (part), FALSE); - - /* The part is valid if all of its elements are valid. */ - for (link = part->elements; link != NULL; link = g_list_next (link)) { - EFilterElement *element = link->data; - - if (!e_filter_element_validate (element, alert)) - return FALSE; - } - - return TRUE; -} - -gint -e_filter_part_eq (EFilterPart *part_a, - EFilterPart *part_b) -{ - GList *link_a, *link_b; - - g_return_val_if_fail (E_IS_FILTER_PART (part_a), FALSE); - g_return_val_if_fail (E_IS_FILTER_PART (part_b), FALSE); - - if (g_strcmp0 (part_a->name, part_b->name) != 0) - return FALSE; - - if (g_strcmp0 (part_a->title, part_b->title) != 0) - return FALSE; - - if (g_strcmp0 (part_a->code, part_b->code) != 0) - return FALSE; - - link_a = part_a->elements; - link_b = part_b->elements; - - while (link_a != NULL && link_b != NULL) { - EFilterElement *element_a = link_a->data; - EFilterElement *element_b = link_b->data; - - if (!e_filter_element_eq (element_a, element_b)) - 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; -} - -gint -e_filter_part_xml_create (EFilterPart *part, - xmlNodePtr node, - ERuleContext *context) -{ - xmlNodePtr n; - gchar *type, *str; - EFilterElement *el; - - g_return_val_if_fail (E_IS_FILTER_PART (part), FALSE); - g_return_val_if_fail (node != NULL, FALSE); - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), FALSE); - - str = (gchar *) xmlGetProp (node, (xmlChar *)"name"); - part->name = g_strdup (str); - if (str) - xmlFree (str); - - n = node->children; - while (n) { - if (!strcmp ((gchar *) n->name, "input")) { - type = (gchar *) xmlGetProp (n, (xmlChar *)"type"); - if (type != NULL - && (el = e_rule_context_new_element (context, type)) != NULL) { - e_filter_element_xml_create (el, n); - xmlFree (type); - part->elements = g_list_append (part->elements, el); - } else { - g_warning ("Invalid xml format, missing/unknown input type"); - } - } else if (!strcmp ((gchar *) n->name, "title") || - !strcmp ((gchar *) n->name, "_title")) { - if (!part->title) { - str = (gchar *) xmlNodeGetContent (n); - part->title = g_strdup (str); - if (str) - xmlFree (str); - } - } else if (!strcmp ((gchar *) n->name, "code")) { - if (!part->code) { - str = (gchar *) xmlNodeGetContent (n); - part->code = g_strdup (str); - if (str) - xmlFree (str); - } - } else if (n->type == XML_ELEMENT_NODE) { - g_warning ("Unknown part element in xml: %s\n", n->name); - } - n = n->next; - } - - return 0; -} - -xmlNodePtr -e_filter_part_xml_encode (EFilterPart *part) -{ - xmlNodePtr node; - GList *link; - - g_return_val_if_fail (E_IS_FILTER_PART (part), NULL); - - node = xmlNewNode (NULL, (xmlChar *)"part"); - xmlSetProp (node, (xmlChar *)"name", (xmlChar *) part->name); - - for (link = part->elements; link != NULL; link = g_list_next (link)) { - EFilterElement *element = link->data; - xmlNodePtr value; - - value = e_filter_element_xml_encode (element); - xmlAddChild (node, value); - } - - return node; -} - -gint -e_filter_part_xml_decode (EFilterPart *part, - xmlNodePtr node) -{ - xmlNodePtr child; - - g_return_val_if_fail (E_IS_FILTER_PART (part), -1); - g_return_val_if_fail (node != NULL, -1); - - for (child = node->children; child != NULL; child = child->next) { - EFilterElement *element; - xmlChar *name; - - if (strcmp ((gchar *) child->name, "value") != 0) - continue; - - name = xmlGetProp (child, (xmlChar *) "name"); - element = e_filter_part_find_element (part, (gchar *) name); - xmlFree (name); - - if (element != NULL) - e_filter_element_xml_decode (element, child); - } - - return 0; -} - -EFilterPart * -e_filter_part_clone (EFilterPart *part) -{ - EFilterPart *clone; - GList *link; - - g_return_val_if_fail (E_IS_FILTER_PART (part), NULL); - - clone = g_object_new (G_OBJECT_TYPE (part), NULL, NULL); - clone->name = g_strdup (part->name); - clone->title = g_strdup (part->title); - clone->code = g_strdup (part->code); - - for (link = part->elements; link != NULL; link = g_list_next (link)) { - EFilterElement *element = link->data; - EFilterElement *clone_element; - - clone_element = e_filter_element_clone (element); - clone->elements = g_list_append (clone->elements, clone_element); - } - - return clone; -} - -/* only copies values of matching parts in the right order */ -void -e_filter_part_copy_values (EFilterPart *dst_part, - EFilterPart *src_part) -{ - GList *dst_link, *src_link; - - g_return_if_fail (E_IS_FILTER_PART (dst_part)); - g_return_if_fail (E_IS_FILTER_PART (src_part)); - - /* NOTE: we go backwards, it just works better that way */ - - /* for each source type, search the dest type for - * a matching type in the same order */ - src_link = g_list_last (src_part->elements); - dst_link = g_list_last (dst_part->elements); - - while (src_link != NULL && dst_link != NULL) { - EFilterElement *src_element = src_link->data; - GList *link = dst_link; - - while (link != NULL) { - EFilterElement *dst_element = link->data; - GType dst_type = G_OBJECT_TYPE (dst_element); - GType src_type = G_OBJECT_TYPE (src_element); - - if (dst_type == src_type) { - e_filter_element_copy_value ( - dst_element, src_element); - dst_link = g_list_previous (link); - break; - } - - link = g_list_previous (link); - } - - src_link = g_list_previous (src_link); - } -} - -EFilterElement * -e_filter_part_find_element (EFilterPart *part, - const gchar *name) -{ - GList *link; - - g_return_val_if_fail (E_IS_FILTER_PART (part), NULL); - - if (name == NULL) - return NULL; - - for (link = part->elements; link != NULL; link = g_list_next (link)) { - EFilterElement *element = link->data; - - if (g_strcmp0 (element->name, name) == 0) - return element; - } - - return NULL; -} - -GtkWidget * -e_filter_part_get_widget (EFilterPart *part) -{ - GtkWidget *hbox; - GList *link; - - g_return_val_if_fail (E_IS_FILTER_PART (part), NULL); - - hbox = gtk_hbox_new (FALSE, 3); - - for (link = part->elements; link != NULL; link = g_list_next (link)) { - EFilterElement *element = link->data; - GtkWidget *widget; - - widget = e_filter_element_get_widget (element); - if (widget != NULL) - gtk_box_pack_start ( - GTK_BOX (hbox), widget, - E_IS_FILTER_FILE (element), - E_IS_FILTER_FILE (element), 3); - } - - gtk_widget_show_all (hbox); - - return hbox; -} - -/** - * e_filter_part_build_code: - * @part: - * @out: - * - * Outputs the code of a part. - **/ -void -e_filter_part_build_code (EFilterPart *part, - GString *out) -{ - GList *link; - - g_return_if_fail (E_IS_FILTER_PART (part)); - g_return_if_fail (out != NULL); - - if (part->code != NULL) - e_filter_part_expand_code (part, part->code, out); - - for (link = part->elements; link != NULL; link = g_list_next (link)) { - EFilterElement *element = link->data; - e_filter_element_build_code (element, out, part); - } -} - -/** - * e_filter_part_build_code_list: - * @l: - * @out: - * - * Construct a list of the filter parts code into - * a single string. - **/ -void -e_filter_part_build_code_list (GList *list, - GString *out) -{ - GList *link; - - g_return_if_fail (out != NULL); - - for (link = list; link != NULL; link = g_list_next (link)) { - EFilterPart *part = link->data; - - e_filter_part_build_code (part, out); - g_string_append (out, "\n "); - } -} - -/** - * e_filter_part_find_list: - * @l: - * @name: - * - * Find a filter part stored in a list. - * - * Return value: - **/ -EFilterPart * -e_filter_part_find_list (GList *list, - const gchar *name) -{ - GList *link; - - g_return_val_if_fail (name != NULL, NULL); - - for (link = list; link != NULL; link = g_list_next (link)) { - EFilterPart *part = link->data; - - if (g_strcmp0 (part->name, name) == 0) - return part; - } - - return NULL; -} - -/** - * e_filter_part_next_list: - * @l: - * @last: The last item retrieved, or NULL to start - * from the beginning of the list. - * - * Iterate through a filter part list. - * - * Return value: The next value in the list, or NULL if the - * list is expired. - **/ -EFilterPart * -e_filter_part_next_list (GList *list, - EFilterPart *last) -{ - GList *link = list; - - if (last != NULL) { - link = g_list_find (list, last); - if (link == NULL) - link = list; - else - link = link->next; - } - - return (link != NULL) ? link->data : NULL; -} - -/** - * e_filter_part_expand_code: - * @part: - * @str: - * @out: - * - * Expands the variables in string @str based on the values of the part. - **/ -void -e_filter_part_expand_code (EFilterPart *part, - const gchar *source, - GString *out) -{ - const gchar *newstart, *start, *end; - gchar *name = g_alloca (32); - gint len, namelen = 32; - - g_return_if_fail (E_IS_FILTER_PART (part)); - g_return_if_fail (source != NULL); - g_return_if_fail (out != NULL); - - start = source; - - while (start && (newstart = strstr (start, "${")) - && (end = strstr (newstart + 2, "}"))) { - EFilterElement *element; - - len = end - newstart - 2; - if (len + 1 > namelen) { - namelen = (len + 1) * 2; - name = g_alloca (namelen); - } - memcpy (name, newstart + 2, len); - name[len] = 0; - - element = e_filter_part_find_element (part, name); - if (element != NULL) { - g_string_append_printf (out, "%.*s", (gint)(newstart - start), start); - e_filter_element_format_sexp (element, out); -#if 0 - } else if ((val = g_hash_table_lookup (part->globals, name))) { - g_string_append_printf (out, "%.*s", newstart - start, start); - camel_sexp_encode_string (out, val); -#endif - } else { - g_string_append_printf (out, "%.*s", (gint)(end - start + 1), start); - } - start = end + 1; - } - - g_string_append (out, start); -} diff --git a/filter/e-filter-part.h b/filter/e-filter-part.h deleted file mode 100644 index da377f3b75..0000000000 --- a/filter/e-filter-part.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILTER_PART_H -#define E_FILTER_PART_H - -#include <gtk/gtk.h> -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> -#include "libevolution-utils/e-alert.h" -#include "e-filter-element.h" - -/* Standard GObject macros */ -#define E_TYPE_FILTER_PART \ - (e_filter_part_get_type ()) -#define E_FILTER_PART(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILTER_PART, EFilterPart)) -#define E_FILTER_PART_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILTER_PART, EFilterPartClass)) -#define E_IS_FILTER_PART(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILTER_PART)) -#define E_IS_FILTER_PART_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FILTER_PART)) -#define E_FILTER_PART_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILTER_PART, EFilterPartClass)) - -G_BEGIN_DECLS - -struct _ERuleContext; - -typedef struct _EFilterPart EFilterPart; -typedef struct _EFilterPartClass EFilterPartClass; -typedef struct _EFilterPartPrivate EFilterPartPrivate; - -struct _EFilterPart { - GObject parent; - EFilterPartPrivate *priv; - - gchar *name; - gchar *title; - gchar *code; - GList *elements; -}; - -struct _EFilterPartClass { - GObjectClass parent_class; -}; - -GType e_filter_part_get_type (void); -EFilterPart * e_filter_part_new (void); -gboolean e_filter_part_validate (EFilterPart *part, - EAlert **alert); -gint e_filter_part_eq (EFilterPart *part_a, - EFilterPart *part_b); -gint e_filter_part_xml_create (EFilterPart *part, - xmlNodePtr node, - struct _ERuleContext *rc); -xmlNodePtr e_filter_part_xml_encode (EFilterPart *fe); -gint e_filter_part_xml_decode (EFilterPart *fe, - xmlNodePtr node); -EFilterPart * e_filter_part_clone (EFilterPart *part); -void e_filter_part_copy_values (EFilterPart *dst_part, - EFilterPart *src_part); -EFilterElement *e_filter_part_find_element (EFilterPart *part, - const gchar *name); -GtkWidget * e_filter_part_get_widget (EFilterPart *part); -void e_filter_part_build_code (EFilterPart *part, - GString *out); -void e_filter_part_expand_code (EFilterPart *part, - const gchar *str, - GString *out); - -void e_filter_part_build_code_list (GList *list, - GString *out); -EFilterPart * e_filter_part_find_list (GList *list, - const gchar *name); -EFilterPart * e_filter_part_next_list (GList *list, - EFilterPart *last); - -G_END_DECLS - -#endif /* E_FILTER_PART_H */ diff --git a/filter/e-filter-rule.c b/filter/e-filter-rule.c deleted file mode 100644 index 548fe4cc87..0000000000 --- a/filter/e-filter-rule.c +++ /dev/null @@ -1,1242 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <gtk/gtk.h> -#include <glib/gi18n.h> - -#include "libevolution-utils/e-alert-dialog.h" - -#include "e-filter-rule.h" -#include "e-rule-context.h" - -#define E_FILTER_RULE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_FILTER_RULE, EFilterRulePrivate)) - -typedef struct _FilterPartData FilterPartData; -typedef struct _FilterRuleData FilterRuleData; - -struct _EFilterRulePrivate { - gint frozen; -}; - -struct _FilterPartData { - EFilterRule *rule; - ERuleContext *context; - EFilterPart *part; - GtkWidget *partwidget; - GtkWidget *container; -}; - -struct _FilterRuleData { - EFilterRule *rule; - ERuleContext *context; - GtkWidget *parts; -}; - -enum { - CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -G_DEFINE_TYPE ( - EFilterRule, - e_filter_rule, - G_TYPE_OBJECT) - -static void -filter_rule_grouping_changed_cb (GtkComboBox *combo_box, - EFilterRule *rule) -{ - rule->grouping = gtk_combo_box_get_active (combo_box); -} - -static void -filter_rule_threading_changed_cb (GtkComboBox *combo_box, - EFilterRule *rule) -{ - rule->threading = gtk_combo_box_get_active (combo_box); -} - -static void -part_combobox_changed (GtkComboBox *combobox, - FilterPartData *data) -{ - EFilterPart *part = NULL; - EFilterPart *newpart; - gint index, i; - - index = gtk_combo_box_get_active (combobox); - for (i = 0, part = e_rule_context_next_part (data->context, part); - part && i < index; - i++, part = e_rule_context_next_part (data->context, part)) { - /* traverse until reached index */ - } - - g_return_if_fail (part != NULL); - g_return_if_fail (i == index); - - /* dont update if we haven't changed */ - if (!strcmp (part->title, data->part->title)) - return; - - /* here we do a widget shuffle, throw away the old widget/rulepart, - * and create another */ - if (data->partwidget) - gtk_container_remove (GTK_CONTAINER (data->container), data->partwidget); - - newpart = e_filter_part_clone (part); - e_filter_part_copy_values (newpart, data->part); - e_filter_rule_replace_part (data->rule, data->part, newpart); - g_object_unref (data->part); - data->part = newpart; - data->partwidget = e_filter_part_get_widget (newpart); - if (data->partwidget) - gtk_box_pack_start ( - GTK_BOX (data->container), - data->partwidget, TRUE, TRUE, 0); -} - -static GtkWidget * -get_rule_part_widget (ERuleContext *context, - EFilterPart *newpart, - EFilterRule *rule) -{ - EFilterPart *part = NULL; - GtkWidget *combobox; - GtkWidget *hbox; - GtkWidget *p; - gint index = 0, current = 0; - FilterPartData *data; - - data = g_malloc0 (sizeof (*data)); - data->rule = rule; - data->context = context; - data->part = newpart; - - hbox = gtk_hbox_new (FALSE, 0); - /* only set to automatically clean up the memory */ - g_object_set_data_full ((GObject *) hbox, "data", data, g_free); - - p = e_filter_part_get_widget (newpart); - - data->partwidget = p; - data->container = hbox; - - combobox = gtk_combo_box_text_new (); - - /* sigh, this is a little ugly */ - while ((part = e_rule_context_next_part (context, part))) { - gtk_combo_box_text_append_text ( - GTK_COMBO_BOX_TEXT (combobox), _(part->title)); - - if (!strcmp (newpart->title, part->title)) - current = index; - - index++; - } - - gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), current); - g_signal_connect ( - combobox, "changed", - G_CALLBACK (part_combobox_changed), data); - gtk_widget_show (combobox); - - gtk_box_pack_start (GTK_BOX (hbox), combobox, FALSE, FALSE, 0); - if (p) - gtk_box_pack_start (GTK_BOX (hbox), p, TRUE, TRUE, 0); - - gtk_widget_show_all (hbox); - - return hbox; -} - -static void -less_parts (GtkWidget *button, - FilterRuleData *data) -{ - EFilterPart *part; - GtkWidget *rule; - FilterPartData *part_data; - - if (g_list_length (data->rule->parts) < 1) - return; - - rule = g_object_get_data ((GObject *) button, "rule"); - part_data = g_object_get_data ((GObject *) rule, "data"); - - g_return_if_fail (part_data != NULL); - - part = part_data->part; - - /* remove the part from the list */ - e_filter_rule_remove_part (data->rule, part); - g_object_unref (part); - - /* and from the display */ - gtk_container_remove (GTK_CONTAINER (data->parts), rule); - gtk_container_remove (GTK_CONTAINER (data->parts), button); -} - -static void -attach_rule (GtkWidget *rule, - FilterRuleData *data, - EFilterPart *part, - gint row) -{ - GtkWidget *remove; - - gtk_table_attach ( - GTK_TABLE (data->parts), rule, 0, 1, row, row + 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - - remove = gtk_button_new_from_stock (GTK_STOCK_REMOVE); - g_object_set_data ((GObject *) remove, "rule", rule); - g_signal_connect ( - remove, "clicked", - G_CALLBACK (less_parts), data); - gtk_table_attach ( - GTK_TABLE (data->parts), remove, 1, 2, row, row + 1, - 0, 0, 0, 0); - - gtk_widget_show (remove); -} - -static void -do_grab_focus_cb (GtkWidget *widget, - gpointer data) -{ - gboolean *done = (gboolean *) data; - - if (*done || !widget) - return; - - if (gtk_widget_get_can_focus (widget) || GTK_IS_COMBO_BOX (widget)) { - *done = TRUE; - gtk_widget_grab_focus (widget); - } else if (GTK_IS_CONTAINER (widget)) { - gtk_container_foreach (GTK_CONTAINER (widget), do_grab_focus_cb, done); - } -} - -static void -more_parts (GtkWidget *button, - FilterRuleData *data) -{ - EFilterPart *new; - - /* first make sure that the last part is ok */ - if (data->rule->parts) { - EFilterPart *part; - GList *l; - EAlert *alert = NULL; - - l = g_list_last (data->rule->parts); - part = l->data; - if (!e_filter_part_validate (part, &alert)) { - GtkWidget *toplevel; - toplevel = gtk_widget_get_toplevel (button); - e_alert_run_dialog (GTK_WINDOW (toplevel), alert); - return; - } - } - - /* create a new rule entry, use the first type of rule */ - new = e_rule_context_next_part (data->context, NULL); - if (new) { - GtkWidget *w; - guint rows; - - new = e_filter_part_clone (new); - e_filter_rule_add_part (data->rule, new); - w = get_rule_part_widget (data->context, new, data->rule); - - g_object_get (data->parts, "n-rows", &rows, NULL); - gtk_table_resize (GTK_TABLE (data->parts), rows + 1, 2); - attach_rule (w, data, new, rows); - - if (GTK_IS_CONTAINER (w)) { - gboolean done = FALSE; - - gtk_container_foreach (GTK_CONTAINER (w), do_grab_focus_cb, &done); - } else - gtk_widget_grab_focus (w); - - /* also scroll down to see new part */ - w = (GtkWidget *) g_object_get_data (G_OBJECT (button), "scrolled-window"); - if (w) { - GtkAdjustment *adjustment; - - adjustment = gtk_scrolled_window_get_vadjustment ( - GTK_SCROLLED_WINDOW (w)); - if (adjustment) { - gdouble upper; - - upper = gtk_adjustment_get_upper (adjustment); - gtk_adjustment_set_value (adjustment, upper); - } - - } - } -} - -static void -name_changed (GtkEntry *entry, - EFilterRule *rule) -{ - g_free (rule->name); - rule->name = g_strdup (gtk_entry_get_text (entry)); -} - -GtkWidget * -e_filter_rule_get_widget (EFilterRule *rule, - ERuleContext *context) -{ - EFilterRuleClass *class; - - g_return_val_if_fail (E_IS_FILTER_RULE (rule), NULL); - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), NULL); - - class = E_FILTER_RULE_GET_CLASS (rule); - g_return_val_if_fail (class->get_widget != NULL, NULL); - - return class->get_widget (rule, context); -} - -static void -filter_rule_load_set (xmlNodePtr node, - EFilterRule *rule, - ERuleContext *context) -{ - xmlNodePtr work; - gchar *rulename; - EFilterPart *part; - - work = node->children; - while (work) { - if (!strcmp ((gchar *) work->name, "part")) { - rulename = (gchar *) xmlGetProp (work, (xmlChar *)"name"); - part = e_rule_context_find_part (context, rulename); - if (part) { - part = e_filter_part_clone (part); - e_filter_part_xml_decode (part, work); - e_filter_rule_add_part (rule, part); - } else { - g_warning ("cannot find rule part '%s'\n", rulename); - } - xmlFree (rulename); - } else if (work->type == XML_ELEMENT_NODE) { - g_warning ("Unknown xml node in part: %s", work->name); - } - work = work->next; - } -} - -static void -filter_rule_finalize (GObject *object) -{ - EFilterRule *rule = E_FILTER_RULE (object); - - g_free (rule->name); - g_free (rule->source); - - g_list_foreach (rule->parts, (GFunc) g_object_unref, NULL); - g_list_free (rule->parts); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_filter_rule_parent_class)->finalize (object); -} - -static gint -filter_rule_validate (EFilterRule *rule, - EAlert **alert) -{ - gint valid = TRUE; - GList *parts; - - g_warn_if_fail (alert == NULL || *alert == NULL); - if (!rule->name || !*rule->name) { - if (alert) - *alert = e_alert_new ("filter:no-name", NULL); - - return FALSE; - } - - /* validate rule parts */ - parts = rule->parts; - valid = parts != NULL; - while (parts && valid) { - valid = e_filter_part_validate ((EFilterPart *) parts->data, alert); - parts = parts->next; - } - - return valid; -} - -static gint -filter_rule_eq (EFilterRule *rule_a, - EFilterRule *rule_b) -{ - GList *link_a; - GList *link_b; - - if (rule_a->enabled != rule_b->enabled) - return FALSE; - - if (rule_a->grouping != rule_b->grouping) - return FALSE; - - if (rule_a->threading != rule_b->threading) - return FALSE; - - if (g_strcmp0 (rule_a->name, rule_b->name) != 0) - return FALSE; - - if (g_strcmp0 (rule_a->source, rule_b->source) != 0) - return FALSE; - - link_a = rule_a->parts; - link_b = rule_b->parts; - - while (link_a != NULL && link_b != NULL) { - EFilterPart *part_a = link_a->data; - EFilterPart *part_b = link_b->data; - - if (!e_filter_part_eq (part_a, part_b)) - 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 xmlNodePtr -filter_rule_xml_encode (EFilterRule *rule) -{ - xmlNodePtr node, set, work; - GList *l; - - node = xmlNewNode (NULL, (xmlChar *)"rule"); - - xmlSetProp ( - node, (xmlChar *)"enabled", - (xmlChar *)(rule->enabled ? "true" : "false")); - - switch (rule->grouping) { - case E_FILTER_GROUP_ALL: - xmlSetProp (node, (xmlChar *)"grouping", (xmlChar *)"all"); - break; - case E_FILTER_GROUP_ANY: - xmlSetProp (node, (xmlChar *)"grouping", (xmlChar *)"any"); - break; - } - - switch (rule->threading) { - case E_FILTER_THREAD_NONE: - break; - case E_FILTER_THREAD_ALL: - xmlSetProp (node, (xmlChar *)"threading", (xmlChar *)"all"); - break; - case E_FILTER_THREAD_REPLIES: - xmlSetProp (node, (xmlChar *)"threading", (xmlChar *)"replies"); - break; - case E_FILTER_THREAD_REPLIES_PARENTS: - xmlSetProp (node, (xmlChar *)"threading", (xmlChar *)"replies_parents"); - break; - case E_FILTER_THREAD_SINGLE: - xmlSetProp (node, (xmlChar *)"threading", (xmlChar *)"single"); - break; - } - - if (rule->source) { - xmlSetProp (node, (xmlChar *)"source", (xmlChar *) rule->source); - } else { - /* set to the default filter type */ - xmlSetProp (node, (xmlChar *)"source", (xmlChar *)"incoming"); - } - - if (rule->name) { - gchar *escaped = g_markup_escape_text (rule->name, -1); - - work = xmlNewNode (NULL, (xmlChar *)"title"); - xmlNodeSetContent (work, (xmlChar *) escaped); - xmlAddChild (node, work); - - g_free (escaped); - } - - set = xmlNewNode (NULL, (xmlChar *)"partset"); - xmlAddChild (node, set); - l = rule->parts; - while (l) { - work = e_filter_part_xml_encode ((EFilterPart *) l->data); - xmlAddChild (set, work); - l = l->next; - } - - return node; -} - -static gint -filter_rule_xml_decode (EFilterRule *rule, - xmlNodePtr node, - ERuleContext *context) -{ - xmlNodePtr work; - gchar *grouping; - gchar *source; - - g_free (rule->name); - rule->name = NULL; - - grouping = (gchar *) xmlGetProp (node, (xmlChar *)"enabled"); - if (!grouping) - rule->enabled = TRUE; - else { - rule->enabled = strcmp (grouping, "false") != 0; - xmlFree (grouping); - } - - grouping = (gchar *) xmlGetProp (node, (xmlChar *)"grouping"); - if (!strcmp (grouping, "any")) - rule->grouping = E_FILTER_GROUP_ANY; - else - rule->grouping = E_FILTER_GROUP_ALL; - xmlFree (grouping); - - rule->threading = E_FILTER_THREAD_NONE; - if (context->flags & E_RULE_CONTEXT_THREADING - && (grouping = (gchar *) xmlGetProp (node, (xmlChar *)"threading"))) { - if (!strcmp (grouping, "all")) - rule->threading = E_FILTER_THREAD_ALL; - else if (!strcmp (grouping, "replies")) - rule->threading = E_FILTER_THREAD_REPLIES; - else if (!strcmp (grouping, "replies_parents")) - rule->threading = E_FILTER_THREAD_REPLIES_PARENTS; - else if (!strcmp (grouping, "single")) - rule->threading = E_FILTER_THREAD_SINGLE; - xmlFree (grouping); - } - - g_free (rule->source); - source = (gchar *) xmlGetProp (node, (xmlChar *)"source"); - if (source) { - rule->source = g_strdup (source); - xmlFree (source); - } else { - /* default filter type */ - rule->source = g_strdup ("incoming"); - } - - work = node->children; - while (work) { - if (!strcmp ((gchar *) work->name, "partset")) { - filter_rule_load_set (work, rule, context); - } else if (!strcmp ((gchar *) work->name, "title") || - !strcmp ((gchar *) work->name, "_title")) { - - if (!rule->name) { - gchar *str, *decstr = NULL; - - str = (gchar *) xmlNodeGetContent (work); - if (str) { - decstr = g_strdup (_(str)); - xmlFree (str); - } - rule->name = decstr; - } - } - work = work->next; - } - - return 0; -} - -static void -filter_rule_build_code (EFilterRule *rule, - GString *out) -{ - switch (rule->threading) { - case E_FILTER_THREAD_NONE: - break; - case E_FILTER_THREAD_ALL: - g_string_append (out, " (match-threads \"all\" "); - break; - case E_FILTER_THREAD_REPLIES: - g_string_append (out, " (match-threads \"replies\" "); - break; - case E_FILTER_THREAD_REPLIES_PARENTS: - g_string_append (out, " (match-threads \"replies_parents\" "); - break; - case E_FILTER_THREAD_SINGLE: - g_string_append (out, " (match-threads \"single\" "); - break; - } - - switch (rule->grouping) { - case E_FILTER_GROUP_ALL: - g_string_append (out, " (and\n "); - break; - case E_FILTER_GROUP_ANY: - g_string_append (out, " (or\n "); - break; - default: - g_warning ("Invalid grouping"); - } - - e_filter_part_build_code_list (rule->parts, out); - g_string_append (out, ")\n"); - - if (rule->threading != E_FILTER_THREAD_NONE) - g_string_append (out, ")\n"); -} - -static void -filter_rule_copy (EFilterRule *dest, - EFilterRule *src) -{ - GList *node; - - dest->enabled = src->enabled; - - g_free (dest->name); - dest->name = g_strdup (src->name); - - g_free (dest->source); - dest->source = g_strdup (src->source); - - dest->grouping = src->grouping; - dest->threading = src->threading; - - if (dest->parts) { - g_list_foreach (dest->parts, (GFunc) g_object_unref, NULL); - g_list_free (dest->parts); - dest->parts = NULL; - } - - node = src->parts; - while (node) { - EFilterPart *part; - - part = e_filter_part_clone (node->data); - dest->parts = g_list_append (dest->parts, part); - node = node->next; - } -} - -static void -ensure_scrolled_width_cb (GtkAdjustment *adj, - GParamSpec *param_spec, - GtkScrolledWindow *scrolled_window) -{ - gtk_scrolled_window_set_min_content_width ( - scrolled_window, - gtk_adjustment_get_upper (adj)); -} - -static void -ensure_scrolled_height_cb (GtkAdjustment *adj, - GParamSpec *param_spec, - GtkScrolledWindow *scrolled_window) -{ - GtkWidget *toplevel; - GdkScreen *screen; - gint toplevel_height, scw_height, require_scw_height = 0, max_height; - - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (scrolled_window)); - if (!toplevel || !gtk_widget_is_toplevel (toplevel)) - return; - - scw_height = gtk_widget_get_allocated_height (GTK_WIDGET (scrolled_window)); - - gtk_widget_get_preferred_height_for_width (gtk_bin_get_child (GTK_BIN (scrolled_window)), - gtk_widget_get_allocated_width (GTK_WIDGET (scrolled_window)), - &require_scw_height, NULL); - - if (scw_height >= require_scw_height) { - if (require_scw_height > 0) - gtk_scrolled_window_set_min_content_height (scrolled_window, require_scw_height); - return; - } - - if (!GTK_IS_WINDOW (toplevel) || - !gtk_widget_get_window (toplevel)) - return; - - screen = gtk_window_get_screen (GTK_WINDOW (toplevel)); - if (screen) { - gint monitor; - GdkRectangle workarea; - - monitor = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (toplevel)); - if (monitor < 0) - monitor = 0; - - gdk_screen_get_monitor_workarea (screen, monitor, &workarea); - - /* can enlarge up to 4 / 5 monitor's work area height */ - max_height = workarea.height * 4 / 5; - } else { - return; - } - - toplevel_height = gtk_widget_get_allocated_height (toplevel); - if (toplevel_height + require_scw_height - scw_height > max_height) - return; - - gtk_scrolled_window_set_min_content_height (scrolled_window, require_scw_height); -} - -static GtkWidget * -filter_rule_get_widget (EFilterRule *rule, - ERuleContext *context) -{ - GtkGrid *hgrid, *vgrid, *inframe; - GtkWidget *parts, *add, *label, *name, *w; - GtkWidget *combobox; - GtkWidget *scrolledwindow; - GtkAdjustment *hadj, *vadj; - GList *l; - gchar *text; - EFilterPart *part; - FilterRuleData *data; - gint rows, i; - - /* this stuff should probably be a table, but the - * rule parts need to be a vbox */ - vgrid = GTK_GRID (gtk_grid_new ()); - gtk_grid_set_row_spacing (vgrid, 6); - gtk_orientable_set_orientation (GTK_ORIENTABLE (vgrid), GTK_ORIENTATION_VERTICAL); - - label = gtk_label_new_with_mnemonic (_("R_ule name:")); - name = gtk_entry_new (); - gtk_widget_set_hexpand (name, TRUE); - gtk_widget_set_halign (name, GTK_ALIGN_FILL); - gtk_label_set_mnemonic_widget ((GtkLabel *) label, name); - - if (!rule->name) { - rule->name = g_strdup (_("Untitled")); - gtk_entry_set_text (GTK_ENTRY (name), rule->name); - /* FIXME: do we want the following code in the future? */ - /*gtk_editable_select_region (GTK_EDITABLE (name), 0, -1);*/ - } else { - gtk_entry_set_text (GTK_ENTRY (name), rule->name); - } - - g_signal_connect ( - name, "realize", - G_CALLBACK (gtk_widget_grab_focus), name); - - hgrid = GTK_GRID (gtk_grid_new ()); - gtk_grid_set_column_spacing (hgrid, 12); - - gtk_grid_attach (hgrid, label, 0, 0, 1, 1); - gtk_grid_attach_next_to (hgrid, name, label, GTK_POS_RIGHT, 1, 1); - - gtk_container_add (GTK_CONTAINER (vgrid), GTK_WIDGET (hgrid)); - - g_signal_connect ( - name, "changed", - G_CALLBACK (name_changed), rule); - - hgrid = GTK_GRID (gtk_grid_new ()); - gtk_grid_set_column_spacing (hgrid, 12); - gtk_container_add (GTK_CONTAINER (vgrid), GTK_WIDGET (hgrid)); - - /* this is the parts table, it should probably be inside a scrolling list */ - rows = g_list_length (rule->parts); - parts = gtk_table_new (rows, 2, FALSE); - - /* data for the parts part of the display */ - data = g_malloc0 (sizeof (*data)); - data->context = context; - data->rule = rule; - data->parts = parts; - - /* only set to automatically clean up the memory */ - g_object_set_data_full ((GObject *) vgrid, "data", data, g_free); - - if (context->flags & E_RULE_CONTEXT_GROUPING) { - const gchar *thread_types[] = { - N_("all the following conditions"), - N_("any of the following conditions") - }; - - hgrid = GTK_GRID (gtk_grid_new ()); - gtk_grid_set_column_spacing (hgrid, 12); - - label = gtk_label_new_with_mnemonic (_("_Find items which match:")); - combobox = gtk_combo_box_text_new (); - - for (i = 0; i < 2; i++) { - gtk_combo_box_text_append_text ( - GTK_COMBO_BOX_TEXT (combobox), - _(thread_types[i])); - } - - gtk_label_set_mnemonic_widget ((GtkLabel *) label, combobox); - gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), rule->grouping); - - gtk_grid_attach (hgrid, label, 0, 0, 1, 1); - gtk_grid_attach_next_to (hgrid, combobox, label, GTK_POS_RIGHT, 1, 1); - - g_signal_connect ( - combobox, "changed", - G_CALLBACK (filter_rule_grouping_changed_cb), rule); - - gtk_container_add (GTK_CONTAINER (vgrid), GTK_WIDGET (hgrid)); - } else { - text = g_strdup_printf ( - "<b>%s</b>", - _("Find items that meet the following conditions")); - label = gtk_label_new (text); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - gtk_container_add (GTK_CONTAINER (vgrid), label); - g_free (text); - } - - hgrid = GTK_GRID (gtk_grid_new ()); - gtk_grid_set_column_spacing (hgrid, 12); - - if (context->flags & E_RULE_CONTEXT_THREADING) { - const gchar *thread_types[] = { - /* Translators: "None" for not including threads; - * part of "Include threads: None" */ - N_("None"), - N_("All related"), - N_("Replies"), - N_("Replies and parents"), - N_("No reply or parent") - }; - - label = gtk_label_new_with_mnemonic (_("I_nclude threads:")); - combobox = gtk_combo_box_text_new (); - - for (i = 0; i < 5; i++) { - gtk_combo_box_text_append_text ( - GTK_COMBO_BOX_TEXT (combobox), - _(thread_types[i])); - } - - gtk_label_set_mnemonic_widget ((GtkLabel *) label, combobox); - gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), rule->threading); - - gtk_grid_attach (hgrid, label, 0, 0, 1, 1); - gtk_grid_attach_next_to (hgrid, combobox, label, GTK_POS_RIGHT, 1, 1); - - g_signal_connect ( - combobox, "changed", - G_CALLBACK (filter_rule_threading_changed_cb), rule); - } - - gtk_container_add (GTK_CONTAINER (vgrid), GTK_WIDGET (hgrid)); - - hgrid = GTK_GRID (gtk_grid_new ()); - gtk_grid_set_column_spacing (hgrid, 3); - gtk_widget_set_vexpand (GTK_WIDGET (hgrid), TRUE); - gtk_widget_set_valign (GTK_WIDGET (hgrid), GTK_ALIGN_FILL); - - gtk_container_add (GTK_CONTAINER (vgrid), GTK_WIDGET (hgrid)); - - label = gtk_label_new (""); - gtk_grid_attach (hgrid, label, 0, 0, 1, 1); - - inframe = GTK_GRID (gtk_grid_new ()); - gtk_grid_set_row_spacing (inframe, 6); - gtk_orientable_set_orientation (GTK_ORIENTABLE (inframe), GTK_ORIENTATION_VERTICAL); - gtk_widget_set_hexpand (GTK_WIDGET (inframe), TRUE); - gtk_widget_set_halign (GTK_WIDGET (inframe), GTK_ALIGN_FILL); - gtk_widget_set_vexpand (GTK_WIDGET (inframe), TRUE); - gtk_widget_set_valign (GTK_WIDGET (inframe), GTK_ALIGN_FILL); - gtk_grid_attach_next_to (hgrid, GTK_WIDGET (inframe), label, GTK_POS_RIGHT, 1, 1); - - l = rule->parts; - i = 0; - while (l) { - part = l->data; - w = get_rule_part_widget (context, part, rule); - attach_rule (w, data, part, i++); - l = g_list_next (l); - } - - hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1.0, 1.0, 1.0, 1.0)); - vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1.0, 1.0, 1.0, 1.0)); - scrolledwindow = gtk_scrolled_window_new (hadj, vadj); - - g_signal_connect ( - hadj, "notify::upper", - G_CALLBACK (ensure_scrolled_width_cb), scrolledwindow); - g_signal_connect ( - vadj, "notify::upper", - G_CALLBACK (ensure_scrolled_height_cb), scrolledwindow); - - gtk_scrolled_window_set_policy ( - GTK_SCROLLED_WINDOW (scrolledwindow), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - - gtk_scrolled_window_add_with_viewport ( - GTK_SCROLLED_WINDOW (scrolledwindow), parts); - - gtk_widget_set_vexpand (scrolledwindow, TRUE); - gtk_widget_set_valign (scrolledwindow, GTK_ALIGN_FILL); - gtk_widget_set_hexpand (scrolledwindow, TRUE); - gtk_widget_set_halign (scrolledwindow, GTK_ALIGN_FILL); - gtk_container_add (GTK_CONTAINER (inframe), scrolledwindow); - - hgrid = GTK_GRID (gtk_grid_new ()); - gtk_grid_set_column_spacing (hgrid, 3); - - add = gtk_button_new_with_mnemonic (_("A_dd Condition")); - gtk_button_set_image ( - GTK_BUTTON (add), gtk_image_new_from_stock ( - GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON)); - g_signal_connect ( - add, "clicked", - G_CALLBACK (more_parts), data); - gtk_grid_attach (hgrid, add, 0, 0, 1, 1); - - gtk_container_add (GTK_CONTAINER (inframe), GTK_WIDGET (hgrid)); - - gtk_widget_show_all (GTK_WIDGET (vgrid)); - - g_object_set_data (G_OBJECT (add), "scrolled-window", scrolledwindow); - - return GTK_WIDGET (vgrid); -} - -static void -e_filter_rule_class_init (EFilterRuleClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (EFilterRulePrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = filter_rule_finalize; - - class->validate = filter_rule_validate; - class->eq = filter_rule_eq; - class->xml_encode = filter_rule_xml_encode; - class->xml_decode = filter_rule_xml_decode; - class->build_code = filter_rule_build_code; - class->copy = filter_rule_copy; - class->get_widget = filter_rule_get_widget; - - signals[CHANGED] = g_signal_new ( - "changed", - E_TYPE_FILTER_RULE, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EFilterRuleClass, changed), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -e_filter_rule_init (EFilterRule *rule) -{ - rule->priv = E_FILTER_RULE_GET_PRIVATE (rule); - rule->enabled = TRUE; -} - -/** - * filter_rule_new: - * - * Create a new EFilterRule object. - * - * Return value: A new #EFilterRule object. - **/ -EFilterRule * -e_filter_rule_new (void) -{ - return g_object_new (E_TYPE_FILTER_RULE, NULL); -} - -EFilterRule * -e_filter_rule_clone (EFilterRule *rule) -{ - EFilterRule *clone; - - g_return_val_if_fail (E_IS_FILTER_RULE (rule), NULL); - - clone = g_object_new (G_OBJECT_TYPE (rule), NULL); - e_filter_rule_copy (clone, rule); - - return clone; -} - -void -e_filter_rule_set_name (EFilterRule *rule, - const gchar *name) -{ - g_return_if_fail (E_IS_FILTER_RULE (rule)); - - if (g_strcmp0 (rule->name, name) == 0) - return; - - g_free (rule->name); - rule->name = g_strdup (name); - - e_filter_rule_emit_changed (rule); -} - -void -e_filter_rule_set_source (EFilterRule *rule, - const gchar *source) -{ - g_return_if_fail (E_IS_FILTER_RULE (rule)); - - if (g_strcmp0 (rule->source, source) == 0) - return; - - g_free (rule->source); - rule->source = g_strdup (source); - - e_filter_rule_emit_changed (rule); -} - -gint -e_filter_rule_validate (EFilterRule *rule, - EAlert **alert) -{ - EFilterRuleClass *class; - - g_return_val_if_fail (E_IS_FILTER_RULE (rule), FALSE); - - class = E_FILTER_RULE_GET_CLASS (rule); - g_return_val_if_fail (class->validate != NULL, FALSE); - - return class->validate (rule, alert); -} - -gint -e_filter_rule_eq (EFilterRule *rule_a, - EFilterRule *rule_b) -{ - EFilterRuleClass *class; - - g_return_val_if_fail (E_IS_FILTER_RULE (rule_a), FALSE); - g_return_val_if_fail (E_IS_FILTER_RULE (rule_b), FALSE); - - class = E_FILTER_RULE_GET_CLASS (rule_a); - g_return_val_if_fail (class->eq != NULL, FALSE); - - if (G_OBJECT_TYPE (rule_a) != G_OBJECT_TYPE (rule_b)) - return FALSE; - - return class->eq (rule_a, rule_b); -} - -xmlNodePtr -e_filter_rule_xml_encode (EFilterRule *rule) -{ - EFilterRuleClass *class; - - g_return_val_if_fail (E_IS_FILTER_RULE (rule), NULL); - - class = E_FILTER_RULE_GET_CLASS (rule); - g_return_val_if_fail (class->xml_encode != NULL, NULL); - - return class->xml_encode (rule); -} - -gint -e_filter_rule_xml_decode (EFilterRule *rule, - xmlNodePtr node, - ERuleContext *context) -{ - EFilterRuleClass *class; - gint result; - - g_return_val_if_fail (E_IS_FILTER_RULE (rule), FALSE); - g_return_val_if_fail (node != NULL, FALSE); - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), FALSE); - - class = E_FILTER_RULE_GET_CLASS (rule); - g_return_val_if_fail (class->xml_decode != NULL, FALSE); - - rule->priv->frozen++; - result = class->xml_decode (rule, node, context); - rule->priv->frozen--; - - e_filter_rule_emit_changed (rule); - - return result; -} - -void -e_filter_rule_copy (EFilterRule *dst_rule, - EFilterRule *src_rule) -{ - EFilterRuleClass *class; - - g_return_if_fail (E_IS_FILTER_RULE (dst_rule)); - g_return_if_fail (E_IS_FILTER_RULE (src_rule)); - - class = E_FILTER_RULE_GET_CLASS (dst_rule); - g_return_if_fail (class->copy != NULL); - - class->copy (dst_rule, src_rule); - - e_filter_rule_emit_changed (dst_rule); -} - -void -e_filter_rule_add_part (EFilterRule *rule, - EFilterPart *part) -{ - g_return_if_fail (E_IS_FILTER_RULE (rule)); - g_return_if_fail (E_IS_FILTER_PART (part)); - - rule->parts = g_list_append (rule->parts, part); - - e_filter_rule_emit_changed (rule); -} - -void -e_filter_rule_remove_part (EFilterRule *rule, - EFilterPart *part) -{ - g_return_if_fail (E_IS_FILTER_RULE (rule)); - g_return_if_fail (E_IS_FILTER_PART (part)); - - rule->parts = g_list_remove (rule->parts, part); - - e_filter_rule_emit_changed (rule); -} - -void -e_filter_rule_replace_part (EFilterRule *rule, - EFilterPart *old_part, - EFilterPart *new_part) -{ - GList *link; - - g_return_if_fail (E_IS_FILTER_RULE (rule)); - g_return_if_fail (E_IS_FILTER_PART (old_part)); - g_return_if_fail (E_IS_FILTER_PART (new_part)); - - link = g_list_find (rule->parts, old_part); - if (link != NULL) - link->data = new_part; - else - rule->parts = g_list_append (rule->parts, new_part); - - e_filter_rule_emit_changed (rule); -} - -void -e_filter_rule_build_code (EFilterRule *rule, - GString *out) -{ - EFilterRuleClass *class; - - g_return_if_fail (E_IS_FILTER_RULE (rule)); - g_return_if_fail (out != NULL); - - class = E_FILTER_RULE_GET_CLASS (rule); - g_return_if_fail (class->build_code != NULL); - - class->build_code (rule, out); -} - -void -e_filter_rule_emit_changed (EFilterRule *rule) -{ - g_return_if_fail (E_IS_FILTER_RULE (rule)); - - if (rule->priv->frozen == 0) - g_signal_emit (rule, signals[CHANGED], 0); -} - -EFilterRule * -e_filter_rule_next_list (GList *list, - EFilterRule *last, - const gchar *source) -{ - GList *link = list; - - if (last != NULL) { - link = g_list_find (link, last); - if (link == NULL) - link = list; - else - link = g_list_next (link); - } - - if (source != NULL) { - while (link != NULL) { - EFilterRule *rule = link->data; - - if (g_strcmp0 (rule->source, source) == 0) - break; - - link = g_list_next (link); - } - } - - return (link != NULL) ? link->data : NULL; -} - -EFilterRule * -e_filter_rule_find_list (GList *list, - const gchar *name, - const gchar *source) -{ - GList *link; - - g_return_val_if_fail (name != NULL, FALSE); - - for (link = list; link != NULL; link = g_list_next (link)) { - EFilterRule *rule = link->data; - - if (strcmp (rule->name, name) == 0) - if (source == NULL || (rule->source != NULL && - strcmp (rule->source, source) == 0)) - return rule; - } - - return NULL; -} - -#ifdef FOR_TRANSLATIONS_ONLY - -static gchar *list[] = { - N_("Incoming"), N_("Outgoing") -}; -#endif diff --git a/filter/e-filter-rule.h b/filter/e-filter-rule.h deleted file mode 100644 index 29ba21c451..0000000000 --- a/filter/e-filter-rule.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_FILTER_RULE_H -#define E_FILTER_RULE_H - -#include "e-filter-part.h" - -/* Standard GObject macros */ -#define E_TYPE_FILTER_RULE \ - (e_filter_rule_get_type ()) -#define E_FILTER_RULE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_FILTER_RULE, EFilterRule)) -#define E_FILTER_RULE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_FILTER_RULE, EFilterRuleClass)) -#define E_IS_FILTER_RULE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_FILTER_RULE)) -#define E_IS_FILTER_RULE_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_FILTER_RULE)) -#define E_FILTER_RULE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_FILTER_RULE, EFilterRuleClass)) - -G_BEGIN_DECLS - -struct _RuleContext; - -typedef struct _EFilterRule EFilterRule; -typedef struct _EFilterRuleClass EFilterRuleClass; -typedef struct _EFilterRulePrivate EFilterRulePrivate; - -enum _filter_grouping_t { - E_FILTER_GROUP_ALL, /* all rules must match */ - E_FILTER_GROUP_ANY /* any rule must match */ -}; - -/* threading, if the context supports it */ -enum _filter_threading_t { - E_FILTER_THREAD_NONE, /* don't add any thread matching */ - E_FILTER_THREAD_ALL, /* add all possible threads */ - E_FILTER_THREAD_REPLIES, /* add only replies */ - E_FILTER_THREAD_REPLIES_PARENTS, /* replies plus parents */ - E_FILTER_THREAD_SINGLE /* messages with no replies or parents */ -}; - -#define E_FILTER_SOURCE_INCOMING "incoming" /* performed on incoming email */ -#define E_FILTER_SOURCE_DEMAND "demand" /* performed on the selected folder - * when the user asks for it */ -#define E_FILTER_SOURCE_OUTGOING "outgoing"/* performed on outgoing mail */ -#define E_FILTER_SOURCE_JUNKTEST "junktest"/* check incoming mail for junk */ - -struct _EFilterRule { - GObject parent_object; - EFilterRulePrivate *priv; - - gchar *name; - gchar *source; - - enum _filter_grouping_t grouping; - enum _filter_threading_t threading; - - guint system:1; /* this is a system rule, cannot be edited/deleted */ - GList *parts; - - gboolean enabled; -}; - -struct _EFilterRuleClass { - GObjectClass parent_class; - - /* virtual methods */ - gint (*validate) (EFilterRule *rule, - EAlert **alert); - gint (*eq) (EFilterRule *rule_a, - EFilterRule *rule_b); - - xmlNodePtr (*xml_encode) (EFilterRule *rule); - gint (*xml_decode) (EFilterRule *rule, - xmlNodePtr node, - struct _ERuleContext *context); - - void (*build_code) (EFilterRule *rule, - GString *out); - - void (*copy) (EFilterRule *dst_rule, - EFilterRule *src_rule); - - GtkWidget * (*get_widget) (EFilterRule *rule, - struct _ERuleContext *context); - - /* signals */ - void (*changed) (EFilterRule *rule); -}; - -GType e_filter_rule_get_type (void); -EFilterRule * e_filter_rule_new (void); -EFilterRule * e_filter_rule_clone (EFilterRule *rule); -void e_filter_rule_set_name (EFilterRule *rule, - const gchar *name); -void e_filter_rule_set_source (EFilterRule *rule, - const gchar *source); -gint e_filter_rule_validate (EFilterRule *rule, - EAlert **alert); -gint e_filter_rule_eq (EFilterRule *rule_a, - EFilterRule *rule_b); -xmlNodePtr e_filter_rule_xml_encode (EFilterRule *rule); -gint e_filter_rule_xml_decode (EFilterRule *rule, - xmlNodePtr node, - struct _ERuleContext *context); -void e_filter_rule_copy (EFilterRule *dst_rule, - EFilterRule *src_rule); -void e_filter_rule_add_part (EFilterRule *rule, - EFilterPart *part); -void e_filter_rule_remove_part (EFilterRule *rule, - EFilterPart *part); -void e_filter_rule_replace_part (EFilterRule *rule, - EFilterPart *old_part, - EFilterPart *new_part); -GtkWidget * e_filter_rule_get_widget (EFilterRule *rule, - struct _ERuleContext *context); -void e_filter_rule_build_code (EFilterRule *rule, - GString *out); -void e_filter_rule_emit_changed (EFilterRule *rule); - -/* static functions */ -EFilterRule * e_filter_rule_next_list (GList *list, - EFilterRule *last, - const gchar *source); -EFilterRule * e_filter_rule_find_list (GList *list, - const gchar *name, - const gchar *source); - -G_END_DECLS - -#endif /* E_FILTER_RULE_H */ diff --git a/filter/e-rule-context.c b/filter/e-rule-context.c deleted file mode 100644 index 714c37f1c9..0000000000 --- a/filter/e-rule-context.c +++ /dev/null @@ -1,1027 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> - -#include <glib/gstdio.h> - -#include <gtk/gtk.h> - -#include <glib/gi18n.h> - -#include <libedataserver/libedataserver.h> - -#include "libevolution-utils/e-alert-dialog.h" -#include "libevolution-utils/e-xml-utils.h" - -#include "e-filter-code.h" -#include "e-filter-color.h" -#include "e-filter-datespec.h" -#include "e-filter-file.h" -#include "e-filter-input.h" -#include "e-filter-int.h" -#include "e-filter-option.h" -#include "e-filter-rule.h" -#include "e-rule-context.h" - -#define E_RULE_CONTEXT_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_RULE_CONTEXT, ERuleContextPrivate)) - -struct _ERuleContextPrivate { - gint frozen; -}; - -enum { - RULE_ADDED, - RULE_REMOVED, - CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -struct _revert_data { - GHashTable *rules; - gint rank; -}; - -G_DEFINE_TYPE ( - ERuleContext, - e_rule_context, - G_TYPE_OBJECT) - -static void -rule_context_set_error (ERuleContext *context, - gchar *error) -{ - g_free (context->error); - context->error = error; -} - -static void -new_rule_response (GtkWidget *dialog, - gint button, - ERuleContext *context) -{ - if (button == GTK_RESPONSE_OK) { - EFilterRule *rule = g_object_get_data ((GObject *) dialog, "rule"); - gchar *user = g_object_get_data ((GObject *) dialog, "path"); - EAlert *alert = NULL; - - if (!e_filter_rule_validate (rule, &alert)) { - e_alert_run_dialog (GTK_WINDOW (dialog), alert); - g_object_unref (alert); - return; - } - - if (e_rule_context_find_rule (context, rule->name, rule->source)) { - e_alert_run_dialog_for_args ((GtkWindow *) dialog, - "filter:bad-name-notunique", - rule->name, NULL); - - return; - } - - g_object_ref (rule); - e_rule_context_add_rule (context, rule); - if (user) - e_rule_context_save (context, user); - } - - gtk_widget_destroy (dialog); -} - -static void -revert_rule_remove (gpointer key, - EFilterRule *rule, - ERuleContext *context) -{ - e_rule_context_remove_rule (context, rule); - g_object_unref (rule); -} - -static void -revert_source_remove (gpointer key, - struct _revert_data *rest_data, - ERuleContext *context) -{ - g_hash_table_foreach ( - rest_data->rules, (GHFunc) revert_rule_remove, context); - g_hash_table_destroy (rest_data->rules); - g_free (rest_data); -} - -static guint -source_hashf (const gchar *a) -{ - return (a != NULL) ? g_str_hash (a) : 0; -} - -static gint -source_eqf (const gchar *a, - const gchar *b) -{ - return (g_strcmp0 (a, b) == 0); -} - -static void -free_part_set (struct _part_set_map *map) -{ - g_free (map->name); - g_free (map); -} - -static void -free_rule_set (struct _rule_set_map *map) -{ - g_free (map->name); - g_free (map); -} - -static void -rule_context_finalize (GObject *obj) -{ - ERuleContext *context =(ERuleContext *) obj; - - g_list_foreach (context->rule_set_list, (GFunc) free_rule_set, NULL); - g_list_free (context->rule_set_list); - g_hash_table_destroy (context->rule_set_map); - - g_list_foreach (context->part_set_list, (GFunc) free_part_set, NULL); - g_list_free (context->part_set_list); - g_hash_table_destroy (context->part_set_map); - - g_free (context->error); - - g_list_foreach (context->parts, (GFunc) g_object_unref, NULL); - g_list_free (context->parts); - - g_list_foreach (context->rules, (GFunc) g_object_unref, NULL); - g_list_free (context->rules); - - G_OBJECT_CLASS (e_rule_context_parent_class)->finalize (obj); -} - -static gint -rule_context_load (ERuleContext *context, - const gchar *system, - const gchar *user) -{ - xmlNodePtr set, rule, root; - xmlDocPtr systemdoc, userdoc; - struct _part_set_map *part_map; - struct _rule_set_map *rule_map; - - rule_context_set_error (context, NULL); - - systemdoc = e_xml_parse_file (system); - if (systemdoc == NULL) { - gchar * err_msg; - - err_msg = g_strdup_printf ( - "Unable to load system rules '%s': %s", - system, g_strerror (errno)); - g_warning ("%s: %s", G_STRFUNC, err_msg); - rule_context_set_error (context, err_msg); - /* no need to free err_msg here */ - return -1; - } - - root = xmlDocGetRootElement (systemdoc); - if (root == NULL || strcmp ((gchar *) root->name, "filterdescription")) { - gchar * err_msg; - - err_msg = g_strdup_printf ( - "Unable to load system rules '%s': " - "Invalid format", system); - g_warning ("%s: %s", G_STRFUNC, err_msg); - rule_context_set_error (context, err_msg); - /* no need to free err_msg here */ - xmlFreeDoc (systemdoc); - return -1; - } - /* doesn't matter if this doens't exist */ - userdoc = NULL; - if (g_file_test (user, G_FILE_TEST_IS_REGULAR)) - userdoc = e_xml_parse_file (user); - - /* now parse structure */ - /* get rule parts */ - set = root->children; - while (set) { - part_map = g_hash_table_lookup (context->part_set_map, set->name); - if (part_map) { - rule = set->children; - while (rule) { - if (!strcmp ((gchar *) rule->name, "part")) { - EFilterPart *part = - E_FILTER_PART (g_object_new ( - part_map->type, NULL, NULL)); - - if (e_filter_part_xml_create (part, rule, context) == 0) { - part_map->append (context, part); - } else { - g_object_unref (part); - g_warning ("Cannot load filter part"); - } - } - rule = rule->next; - } - } else if ((rule_map = g_hash_table_lookup ( - context->rule_set_map, set->name))) { - rule = set->children; - while (rule) { - if (!strcmp ((gchar *) rule->name, "rule")) { - EFilterRule *part = - E_FILTER_RULE (g_object_new ( - rule_map->type, NULL, NULL)); - - if (e_filter_rule_xml_decode (part, rule, context) == 0) { - part->system = TRUE; - rule_map->append (context, part); - } else { - g_object_unref (part); - g_warning ("Cannot load filter part"); - } - } - rule = rule->next; - } - } - set = set->next; - } - - /* now load actual rules */ - if (userdoc) { - root = xmlDocGetRootElement (userdoc); - set = root ? root->children : NULL; - while (set) { - rule_map = g_hash_table_lookup (context->rule_set_map, set->name); - if (rule_map) { - rule = set->children; - while (rule) { - if (!strcmp ((gchar *) rule->name, "rule")) { - EFilterRule *part = - E_FILTER_RULE (g_object_new ( - rule_map->type, NULL, NULL)); - - if (e_filter_rule_xml_decode (part, rule, context) == 0) { - rule_map->append (context, part); - } else { - g_object_unref (part); - g_warning ("Cannot load filter part"); - } - } - rule = rule->next; - } - } - set = set->next; - } - } - - xmlFreeDoc (userdoc); - xmlFreeDoc (systemdoc); - - return 0; -} - -static gint -rule_context_save (ERuleContext *context, - const gchar *user) -{ - xmlDocPtr doc; - xmlNodePtr root, rules, work; - GList *l; - EFilterRule *rule; - struct _rule_set_map *map; - gint ret; - - doc = xmlNewDoc ((xmlChar *)"1.0"); - /* FIXME: set character encoding to UTF-8? */ - root = xmlNewDocNode (doc, NULL, (xmlChar *)"filteroptions", NULL); - xmlDocSetRootElement (doc, root); - l = context->rule_set_list; - while (l) { - map = l->data; - rules = xmlNewDocNode (doc, NULL, (xmlChar *) map->name, NULL); - xmlAddChild (root, rules); - rule = NULL; - while ((rule = map->next (context, rule, NULL))) { - if (!rule->system) { - work = e_filter_rule_xml_encode (rule); - xmlAddChild (rules, work); - } - } - l = g_list_next (l); - } - - ret = e_xml_save_file (user, doc); - - xmlFreeDoc (doc); - - return ret; -} - -static gint -rule_context_revert (ERuleContext *context, - const gchar *user) -{ - xmlNodePtr set, rule; - /*struct _part_set_map *part_map;*/ - struct _rule_set_map *rule_map; - struct _revert_data *rest_data; - GHashTable *source_hash; - xmlDocPtr userdoc; - EFilterRule *frule; - - rule_context_set_error (context, NULL); - - userdoc = e_xml_parse_file (user); - if (userdoc == NULL) - /* clear out anythign we have? */ - return 0; - - source_hash = g_hash_table_new ( - (GHashFunc) source_hashf, - (GCompareFunc) source_eqf); - - /* setup stuff we have now */ - /* Note that we assume there is only 1 set of rules in a given rule context, - * although other parts of the code dont assume this */ - frule = NULL; - while ((frule = e_rule_context_next_rule (context, frule, NULL))) { - rest_data = g_hash_table_lookup (source_hash, frule->source); - if (rest_data == NULL) { - rest_data = g_malloc0 (sizeof (*rest_data)); - rest_data->rules = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_insert (source_hash, frule->source, rest_data); - } - g_hash_table_insert (rest_data->rules, frule->name, frule); - } - - /* make what we have, match what we load */ - set = xmlDocGetRootElement (userdoc); - set = set ? set->children : NULL; - while (set) { - rule_map = g_hash_table_lookup (context->rule_set_map, set->name); - if (rule_map) { - rule = set->children; - while (rule) { - if (!strcmp ((gchar *) rule->name, "rule")) { - EFilterRule *part = - E_FILTER_RULE (g_object_new ( - rule_map->type, NULL, NULL)); - - if (e_filter_rule_xml_decode (part, rule, context) == 0) { - /* Use the revert data to keep - * track of the right rank of - * this rule part. */ - rest_data = g_hash_table_lookup (source_hash, part->source); - if (rest_data == NULL) { - rest_data = g_malloc0 (sizeof (*rest_data)); - rest_data->rules = g_hash_table_new ( - g_str_hash, - g_str_equal); - g_hash_table_insert ( - source_hash, - part->source, - rest_data); - } - frule = g_hash_table_lookup ( - rest_data->rules, - part->name); - if (frule) { - if (context->priv->frozen == 0 && - !e_filter_rule_eq (frule, part)) - e_filter_rule_copy (frule, part); - - g_object_unref (part); - e_rule_context_rank_rule ( - context, frule, - frule->source, - rest_data->rank); - g_hash_table_remove (rest_data->rules, frule->name); - } else { - e_rule_context_add_rule (context, part); - e_rule_context_rank_rule ( - context, - part, - part->source, - rest_data->rank); - } - rest_data->rank++; - } else { - g_object_unref (part); - g_warning ("Cannot load filter part"); - } - } - rule = rule->next; - } - } - set = set->next; - } - - xmlFreeDoc (userdoc); - - /* remove any we still have that weren't in the file */ - g_hash_table_foreach (source_hash, (GHFunc) revert_source_remove, context); - g_hash_table_destroy (source_hash); - - return 0; -} - -static EFilterElement * -rule_context_new_element (ERuleContext *context, - const gchar *type) -{ - if (!strcmp (type, "string")) { - return (EFilterElement *) e_filter_input_new (); - } else if (!strcmp (type, "address")) { - /* FIXME: temporary ... need real address type */ - return (EFilterElement *) e_filter_input_new_type_name (type); - } else if (!strcmp (type, "code")) { - return (EFilterElement *) e_filter_code_new (FALSE); - } else if (!strcmp (type, "rawcode")) { - return (EFilterElement *) e_filter_code_new (TRUE); - } else if (!strcmp (type, "colour")) { - return (EFilterElement *) e_filter_color_new (); - } else if (!strcmp (type, "optionlist")) { - return (EFilterElement *) e_filter_option_new (); - } else if (!strcmp (type, "datespec")) { - return (EFilterElement *) e_filter_datespec_new (); - } else if (!strcmp (type, "command")) { - return (EFilterElement *) e_filter_file_new_type_name (type); - } else if (!strcmp (type, "file")) { - return (EFilterElement *) e_filter_file_new_type_name (type); - } else if (!strcmp (type, "integer")) { - return (EFilterElement *) e_filter_int_new (); - } else if (!strcmp (type, "regex")) { - return (EFilterElement *) e_filter_input_new_type_name (type); - } else if (!strcmp (type, "completedpercent")) { - return (EFilterElement *) e_filter_int_new_type ( - "completedpercent", 0,100); - } else { - g_warning ("Unknown filter type '%s'", type); - return NULL; - } -} - -static void -e_rule_context_class_init (ERuleContextClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ERuleContextPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = rule_context_finalize; - - class->load = rule_context_load; - class->save = rule_context_save; - class->revert = rule_context_revert; - class->new_element = rule_context_new_element; - - signals[RULE_ADDED] = g_signal_new ( - "rule-added", - E_TYPE_RULE_CONTEXT, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ERuleContextClass, rule_added), - NULL, - NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - signals[RULE_REMOVED] = g_signal_new ( - "rule-removed", - E_TYPE_RULE_CONTEXT, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ERuleContextClass, rule_removed), - NULL, - NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - signals[CHANGED] = g_signal_new ( - "changed", - E_TYPE_RULE_CONTEXT, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ERuleContextClass, changed), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -e_rule_context_init (ERuleContext *context) -{ - context->priv = E_RULE_CONTEXT_GET_PRIVATE (context); - - context->part_set_map = g_hash_table_new (g_str_hash, g_str_equal); - context->rule_set_map = g_hash_table_new (g_str_hash, g_str_equal); - - context->flags = E_RULE_CONTEXT_GROUPING; -} - -/** - * e_rule_context_new: - * - * Create a new ERuleContext object. - * - * Return value: A new #ERuleContext object. - **/ -ERuleContext * -e_rule_context_new (void) -{ - return g_object_new (E_TYPE_RULE_CONTEXT, NULL); -} - -void -e_rule_context_add_part_set (ERuleContext *context, - const gchar *setname, - GType part_type, - ERuleContextPartFunc append, - ERuleContextNextPartFunc next) -{ - struct _part_set_map *map; - - g_return_if_fail (E_IS_RULE_CONTEXT (context)); - g_return_if_fail (setname != NULL); - g_return_if_fail (append != NULL); - g_return_if_fail (next != NULL); - - map = g_hash_table_lookup (context->part_set_map, setname); - if (map != NULL) { - g_hash_table_remove (context->part_set_map, setname); - context->part_set_list = g_list_remove (context->part_set_list, map); - free_part_set (map); - map = NULL; - } - - map = g_malloc0 (sizeof (*map)); - map->type = part_type; - map->append = append; - map->next = next; - map->name = g_strdup (setname); - g_hash_table_insert (context->part_set_map, map->name, map); - context->part_set_list = g_list_append (context->part_set_list, map); -} - -void -e_rule_context_add_rule_set (ERuleContext *context, - const gchar *setname, - GType rule_type, - ERuleContextRuleFunc append, - ERuleContextNextRuleFunc next) -{ - struct _rule_set_map *map; - - g_return_if_fail (E_IS_RULE_CONTEXT (context)); - g_return_if_fail (setname != NULL); - g_return_if_fail (append != NULL); - g_return_if_fail (next != NULL); - - map = g_hash_table_lookup (context->rule_set_map, setname); - if (map != NULL) { - g_hash_table_remove (context->rule_set_map, setname); - context->rule_set_list = g_list_remove (context->rule_set_list, map); - free_rule_set (map); - map = NULL; - } - - map = g_malloc0 (sizeof (*map)); - map->type = rule_type; - map->append = append; - map->next = next; - map->name = g_strdup (setname); - g_hash_table_insert (context->rule_set_map, map->name, map); - context->rule_set_list = g_list_append (context->rule_set_list, map); -} - -/** - * e_rule_context_load: - * @f: - * @system: - * @user: - * - * Load a rule context from a system and user description file. - * - * Return value: - **/ -gint -e_rule_context_load (ERuleContext *context, - const gchar *system, - const gchar *user) -{ - ERuleContextClass *class; - gint result; - - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), -1); - g_return_val_if_fail (system != NULL, -1); - g_return_val_if_fail (user != NULL, -1); - - class = E_RULE_CONTEXT_GET_CLASS (context); - g_return_val_if_fail (class->load != NULL, -1); - - context->priv->frozen++; - result = class->load (context, system, user); - context->priv->frozen--; - - return result; -} - -/** - * e_rule_context_save: - * @f: - * @user: - * - * Save a rule context to disk. - * - * Return value: - **/ -gint -e_rule_context_save (ERuleContext *context, - const gchar *user) -{ - ERuleContextClass *class; - - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), -1); - g_return_val_if_fail (user != NULL, -1); - - class = E_RULE_CONTEXT_GET_CLASS (context); - g_return_val_if_fail (class->save != NULL, -1); - - return class->save (context, user); -} - -/** - * e_rule_context_revert: - * @f: - * @user: - * - * Reverts a rule context from a user description file. Assumes the - * system description file is unchanged from when it was loaded. - * - * Return value: - **/ -gint -e_rule_context_revert (ERuleContext *context, - const gchar *user) -{ - ERuleContextClass *class; - - g_return_val_if_fail (E_RULE_CONTEXT (context), 0); - g_return_val_if_fail (user != NULL, 0); - - class = E_RULE_CONTEXT_GET_CLASS (context); - g_return_val_if_fail (class->revert != NULL, 0); - - return class->revert (context, user); -} - -EFilterPart * -e_rule_context_find_part (ERuleContext *context, - const gchar *name) -{ - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), NULL); - g_return_val_if_fail (name != NULL, NULL); - - return e_filter_part_find_list (context->parts, name); -} - -EFilterPart * -e_rule_context_create_part (ERuleContext *context, - const gchar *name) -{ - EFilterPart *part; - - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), NULL); - g_return_val_if_fail (name != NULL, NULL); - - part = e_rule_context_find_part (context, name); - - if (part == NULL) - return NULL; - - return e_filter_part_clone (part); -} - -EFilterPart * -e_rule_context_next_part (ERuleContext *context, - EFilterPart *last) -{ - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), NULL); - - return e_filter_part_next_list (context->parts, last); -} - -EFilterRule * -e_rule_context_next_rule (ERuleContext *context, - EFilterRule *last, - const gchar *source) -{ - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), NULL); - - return e_filter_rule_next_list (context->rules, last, source); -} - -EFilterRule * -e_rule_context_find_rule (ERuleContext *context, - const gchar *name, - const gchar *source) -{ - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), NULL); - g_return_val_if_fail (name != NULL, NULL); - - return e_filter_rule_find_list (context->rules, name, source); -} - -void -e_rule_context_add_part (ERuleContext *context, - EFilterPart *part) -{ - g_return_if_fail (E_IS_RULE_CONTEXT (context)); - g_return_if_fail (E_IS_FILTER_PART (part)); - - context->parts = g_list_append (context->parts, part); -} - -void -e_rule_context_add_rule (ERuleContext *context, - EFilterRule *rule) -{ - g_return_if_fail (E_IS_RULE_CONTEXT (context)); - g_return_if_fail (E_IS_FILTER_RULE (rule)); - - context->rules = g_list_append (context->rules, rule); - - if (context->priv->frozen == 0) { - g_signal_emit (context, signals[RULE_ADDED], 0, rule); - g_signal_emit (context, signals[CHANGED], 0); - } -} - -/* Add a rule, with a gui, asking for confirmation first, - * and optionally save to path. */ -void -e_rule_context_add_rule_gui (ERuleContext *context, - EFilterRule *rule, - const gchar *title, - const gchar *path) -{ - GtkDialog *dialog; - GtkWidget *widget; - GtkWidget *content_area; - - g_return_if_fail (E_IS_RULE_CONTEXT (context)); - g_return_if_fail (E_IS_FILTER_RULE (rule)); - - widget = e_filter_rule_get_widget (rule, context); - gtk_widget_show (widget); - - dialog =(GtkDialog *) gtk_dialog_new (); - gtk_dialog_add_buttons ( - dialog, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); - - gtk_window_set_title ((GtkWindow *) dialog, title); - gtk_window_set_default_size ((GtkWindow *) dialog, 600, 400); - gtk_window_set_resizable ((GtkWindow *) dialog, TRUE); - - content_area = gtk_dialog_get_content_area (dialog); - gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0); - - g_object_set_data_full ((GObject *) dialog, "rule", rule, g_object_unref); - if (path) - g_object_set_data_full ((GObject *) dialog, "path", g_strdup (path), g_free); - - g_signal_connect ( - dialog, "response", - G_CALLBACK (new_rule_response), context); - - g_object_ref (context); - - g_object_set_data_full ((GObject *) dialog, "context", context, g_object_unref); - - gtk_widget_show ((GtkWidget *) dialog); -} - -void -e_rule_context_remove_rule (ERuleContext *context, - EFilterRule *rule) -{ - g_return_if_fail (E_IS_RULE_CONTEXT (context)); - g_return_if_fail (E_IS_FILTER_RULE (rule)); - - context->rules = g_list_remove (context->rules, rule); - - if (context->priv->frozen == 0) { - g_signal_emit (context, signals[RULE_REMOVED], 0, rule); - g_signal_emit (context, signals[CHANGED], 0); - } -} - -void -e_rule_context_rank_rule (ERuleContext *context, - EFilterRule *rule, - const gchar *source, - gint rank) -{ - GList *node; - gint i = 0, index = 0; - - g_return_if_fail (E_IS_RULE_CONTEXT (context)); - g_return_if_fail (E_IS_FILTER_RULE (rule)); - - if (e_rule_context_get_rank_rule (context, rule, source) == rank) - return; - - context->rules = g_list_remove (context->rules, rule); - node = context->rules; - while (node) { - EFilterRule *r = node->data; - - if (i == rank) { - context->rules = g_list_insert (context->rules, rule, index); - if (context->priv->frozen == 0) - g_signal_emit (context, signals[CHANGED], 0); - - return; - } - - index++; - if (source == NULL || (r->source && strcmp (r->source, source) == 0)) - i++; - - node = node->next; - } - - context->rules = g_list_append (context->rules, rule); - if (context->priv->frozen == 0) - g_signal_emit (context, signals[CHANGED], 0); -} - -gint -e_rule_context_get_rank_rule (ERuleContext *context, - EFilterRule *rule, - const gchar *source) -{ - GList *node; - gint i = 0; - - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), -1); - g_return_val_if_fail (E_IS_FILTER_RULE (rule), -1); - - node = context->rules; - while (node) { - EFilterRule *r = node->data; - - if (r == rule) - return i; - - if (source == NULL || (r->source && strcmp (r->source, source) == 0)) - i++; - - node = node->next; - } - - return -1; -} - -EFilterRule * -e_rule_context_find_rank_rule (ERuleContext *context, - gint rank, - const gchar *source) -{ - GList *node; - gint i = 0; - - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), NULL); - - node = context->rules; - while (node) { - EFilterRule *r = node->data; - - if (source == NULL || (r->source && strcmp (r->source, source) == 0)) { - if (rank == i) - return r; - i++; - } - - node = node->next; - } - - return NULL; -} - -GList * -e_rule_context_rename_uri (ERuleContext *context, - const gchar *old_uri, - const gchar *new_uri, - GCompareFunc compare) -{ - ERuleContextClass *class; - - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), NULL); - g_return_val_if_fail (old_uri != NULL, NULL); - g_return_val_if_fail (new_uri != NULL, NULL); - g_return_val_if_fail (compare != NULL, NULL); - - class = E_RULE_CONTEXT_GET_CLASS (context); - - /* This method is optional. */ - if (class->rename_uri == NULL) - return NULL; - - return class->rename_uri (context, old_uri, new_uri, compare); -} - -GList * -e_rule_context_delete_uri (ERuleContext *context, - const gchar *uri, - GCompareFunc compare) -{ - ERuleContextClass *class; - - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), NULL); - g_return_val_if_fail (uri != NULL, NULL); - g_return_val_if_fail (compare != NULL, NULL); - - class = E_RULE_CONTEXT_GET_CLASS (context); - - /* This method is optional. */ - if (class->delete_uri == NULL) - return NULL; - - return class->delete_uri (context, uri, compare); -} - -void -e_rule_context_free_uri_list (ERuleContext *context, - GList *uris) -{ - g_return_if_fail (E_IS_RULE_CONTEXT (context)); - - /* TODO: should be virtual */ - - g_list_foreach (uris, (GFunc) g_free, NULL); - g_list_free (uris); -} - -/** - * e_rule_context_new_element: - * @context: - * @name: - * - * create a new filter element based on name. - * - * Return value: - **/ -EFilterElement * -e_rule_context_new_element (ERuleContext *context, - const gchar *name) -{ - ERuleContextClass *class; - - g_return_val_if_fail (E_IS_RULE_CONTEXT (context), NULL); - g_return_val_if_fail (name != NULL, NULL); - - class = E_RULE_CONTEXT_GET_CLASS (context); - g_return_val_if_fail (class->new_element != NULL, NULL); - - return class->new_element (context, name); -} diff --git a/filter/e-rule-context.h b/filter/e-rule-context.h deleted file mode 100644 index a2a2d2df97..0000000000 --- a/filter/e-rule-context.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_RULE_CONTEXT_H -#define E_RULE_CONTEXT_H - -#include <libxml/parser.h> - -#include "e-filter-part.h" -#include "e-filter-rule.h" - -/* Standard GObject macros */ -#define E_TYPE_RULE_CONTEXT \ - (e_rule_context_get_type ()) -#define E_RULE_CONTEXT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_RULE_CONTEXT, ERuleContext)) -#define E_RULE_CONTEXT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_RULE_CONTEXT, ERuleContextClass)) -#define E_IS_RULE_CONTEXT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_RULE_CONTEXT)) -#define E_IS_RULE_CONTEXT_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_RULE_CONTEXT)) -#define E_RULE_CONTEXT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_RULE_CONTEXT, ERuleContextClass)) - -G_BEGIN_DECLS - -typedef struct _ERuleContext ERuleContext; -typedef struct _ERuleContextClass ERuleContextClass; -typedef struct _ERuleContextPrivate ERuleContextPrivate; - -/* backend capabilities, this is a hack since we don't support nested rules */ -enum { - E_RULE_CONTEXT_GROUPING = 1 << 0, - E_RULE_CONTEXT_THREADING = 1 << 1 -}; - -typedef void (*ERuleContextRegisterFunc) (ERuleContext *context, - EFilterRule *rule, - gpointer user_data); -typedef void (*ERuleContextPartFunc) (ERuleContext *context, - EFilterPart *part); -typedef void (*ERuleContextRuleFunc) (ERuleContext *context, - EFilterRule *part); -typedef EFilterPart * - (*ERuleContextNextPartFunc) (ERuleContext *context, - EFilterPart *part); -typedef EFilterRule * - (*ERuleContextNextRuleFunc) (ERuleContext *context, - EFilterRule *rule, - const gchar *source); - -struct _ERuleContext { - GObject parent; - ERuleContextPrivate *priv; - - gchar *error; /* string version of error */ - - guint32 flags; /* capability flags */ - - GList *parts; - GList *rules; - - GHashTable *part_set_map; /* map set types to part types */ - GList *part_set_list; - GHashTable *rule_set_map; /* map set types to rule types */ - GList *rule_set_list; -}; - -struct _ERuleContextClass { - GObjectClass parent_class; - - /* methods */ - gint (*load) (ERuleContext *context, - const gchar *system, - const gchar *user); - gint (*save) (ERuleContext *context, - const gchar *user); - gint (*revert) (ERuleContext *context, - const gchar *user); - - GList * (*delete_uri) (ERuleContext *context, - const gchar *uri, - GCompareFunc compare_func); - GList * (*rename_uri) (ERuleContext *context, - const gchar *old_uri, - const gchar *new_uri, - GCompareFunc compare_func); - - EFilterElement *(*new_element) (ERuleContext *context, - const gchar *name); - - /* signals */ - void (*rule_added) (ERuleContext *context, - EFilterRule *rule); - void (*rule_removed) (ERuleContext *context, - EFilterRule *rule); - void (*changed) (ERuleContext *context); -}; - -struct _part_set_map { - gchar *name; - GType type; - ERuleContextPartFunc append; - ERuleContextNextPartFunc next; -}; - -struct _rule_set_map { - gchar *name; - GType type; - ERuleContextRuleFunc append; - ERuleContextNextRuleFunc next; -}; - -GType e_rule_context_get_type (void); -ERuleContext * e_rule_context_new (void); - -gint e_rule_context_load (ERuleContext *context, - const gchar *system, - const gchar *user); -gint e_rule_context_save (ERuleContext *context, - const gchar *user); -gint e_rule_context_revert (ERuleContext *context, - const gchar *user); - -void e_rule_context_add_part (ERuleContext *context, - EFilterPart *part); -EFilterPart * e_rule_context_find_part (ERuleContext *context, - const gchar *name); -EFilterPart * e_rule_context_create_part (ERuleContext *context, - const gchar *name); -EFilterPart * e_rule_context_next_part (ERuleContext *context, - EFilterPart *last); - -EFilterRule * e_rule_context_next_rule (ERuleContext *context, - EFilterRule *last, - const gchar *source); -EFilterRule * e_rule_context_find_rule (ERuleContext *context, - const gchar *name, - const gchar *source); -EFilterRule * e_rule_context_find_rank_rule (ERuleContext *context, - gint rank, - const gchar *source); -void e_rule_context_add_rule (ERuleContext *context, - EFilterRule *rule); -void e_rule_context_add_rule_gui (ERuleContext *context, - EFilterRule *rule, - const gchar *title, - const gchar *path); -void e_rule_context_remove_rule (ERuleContext *context, - EFilterRule *rule); - -void e_rule_context_rank_rule (ERuleContext *context, - EFilterRule *rule, - const gchar *source, - gint rank); -gint e_rule_context_get_rank_rule (ERuleContext *context, - EFilterRule *rule, - const gchar *source); - -void e_rule_context_add_part_set (ERuleContext *context, - const gchar *setname, - GType part_type, - ERuleContextPartFunc append, - ERuleContextNextPartFunc next); -void e_rule_context_add_rule_set (ERuleContext *context, - const gchar *setname, - GType rule_type, - ERuleContextRuleFunc append, - ERuleContextNextRuleFunc next); - -EFilterElement *e_rule_context_new_element (ERuleContext *context, - const gchar *name); - -GList * e_rule_context_delete_uri (ERuleContext *context, - const gchar *uri, - GCompareFunc compare); -GList * e_rule_context_rename_uri (ERuleContext *context, - const gchar *old_uri, - const gchar *new_uri, - GCompareFunc compare); - -void e_rule_context_free_uri_list (ERuleContext *context, - GList *uris); - -G_END_DECLS - -#endif /* E_RULE_CONTEXT_H */ diff --git a/filter/e-rule-editor.c b/filter/e-rule-editor.c deleted file mode 100644 index d3a92b3693..0000000000 --- a/filter/e-rule-editor.c +++ /dev/null @@ -1,920 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -/* for getenv only, remove when getenv need removed */ -#include <stdlib.h> -#include <string.h> - -#include <glib/gi18n.h> - -#include "libevolution-utils/e-alert-dialog.h" -#include "libevolution-utils/evolution-util.h" - -#include "e-rule-editor.h" - -#define E_RULE_EDITOR_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_RULE_EDITOR, ERuleEditorPrivate)) - -static gint enable_undo = 0; - -enum { - BUTTON_ADD, - BUTTON_EDIT, - BUTTON_DELETE, - BUTTON_TOP, - BUTTON_UP, - BUTTON_DOWN, - BUTTON_BOTTOM, - BUTTON_LAST -}; - -struct _ERuleEditorPrivate { - GtkButton *buttons[BUTTON_LAST]; -}; - -G_DEFINE_TYPE ( - ERuleEditor, - e_rule_editor, - GTK_TYPE_DIALOG) - -static void -rule_editor_add_undo (ERuleEditor *editor, - gint type, - EFilterRule *rule, - gint rank, - gint newrank) -{ - ERuleEditorUndo *undo; - - if (!editor->undo_active && enable_undo) { - undo = g_malloc0 (sizeof (*undo)); - undo->rule = rule; - undo->type = type; - undo->rank = rank; - undo->newrank = newrank; - - undo->next = editor->undo_log; - editor->undo_log = undo; - } else { - g_object_unref (rule); - } -} - -static void -rule_editor_play_undo (ERuleEditor *editor) -{ - ERuleEditorUndo *undo, *next; - EFilterRule *rule; - - editor->undo_active = TRUE; - undo = editor->undo_log; - editor->undo_log = NULL; - while (undo) { - next = undo->next; - switch (undo->type) { - case E_RULE_EDITOR_LOG_EDIT: - rule = e_rule_context_find_rank_rule (editor->context, undo->rank, undo->rule->source); - if (rule) { - e_filter_rule_copy (rule, undo->rule); - } else { - g_warning ("Could not find the right rule to undo against?"); - } - break; - case E_RULE_EDITOR_LOG_ADD: - rule = e_rule_context_find_rank_rule (editor->context, undo->rank, undo->rule->source); - if (rule) - e_rule_context_remove_rule (editor->context, rule); - break; - case E_RULE_EDITOR_LOG_REMOVE: - g_object_ref (undo->rule); - e_rule_context_add_rule (editor->context, undo->rule); - e_rule_context_rank_rule (editor->context, undo->rule, editor->source, undo->rank); - break; - case E_RULE_EDITOR_LOG_RANK: - rule = e_rule_context_find_rank_rule (editor->context, undo->newrank, undo->rule->source); - if (rule) - e_rule_context_rank_rule (editor->context, rule, editor->source, undo->rank); - break; - } - - g_object_unref (undo->rule); - g_free (undo); - undo = next; - } - editor->undo_active = FALSE; -} - -static void -dialog_rule_changed (EFilterRule *fr, - GtkWidget *dialog) -{ - g_return_if_fail (dialog != NULL); - - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, fr && fr->parts); -} - -static void -add_editor_response (GtkWidget *dialog, - gint button, - ERuleEditor *editor) -{ - GtkTreeSelection *selection; - GtkTreePath *path; - GtkTreeIter iter; - - if (button == GTK_RESPONSE_OK) { - EAlert *alert = NULL; - if (!e_filter_rule_validate (editor->edit, &alert)) { - e_alert_run_dialog (GTK_WINDOW (dialog), alert); - g_object_unref (alert); - return; - } - - if (e_rule_context_find_rule (editor->context, editor->edit->name, editor->edit->source)) { - e_alert_run_dialog_for_args ( - GTK_WINDOW (dialog), - "filter:bad-name-notunique", - editor->edit->name, NULL); - return; - } - - g_object_ref (editor->edit); - - gtk_list_store_append (editor->model, &iter); - gtk_list_store_set ( - editor->model, &iter, - 0, editor->edit->name, - 1, editor->edit, - 2, editor->edit->enabled, -1); - selection = gtk_tree_view_get_selection (editor->list); - gtk_tree_selection_select_iter (selection, &iter); - - /* scroll to the newly added row */ - path = gtk_tree_model_get_path ( - GTK_TREE_MODEL (editor->model), &iter); - gtk_tree_view_scroll_to_cell ( - editor->list, path, NULL, TRUE, 1.0, 0.0); - gtk_tree_path_free (path); - - editor->current = editor->edit; - e_rule_context_add_rule (editor->context, editor->current); - - g_object_ref (editor->current); - rule_editor_add_undo ( - editor, - E_RULE_EDITOR_LOG_ADD, - editor->current, - e_rule_context_get_rank_rule ( - editor->context, - editor->current, - editor->current->source), - 0); - } - - gtk_widget_destroy (dialog); -} - -static void -editor_destroy (ERuleEditor *editor, - GObject *deadbeef) -{ - if (editor->edit) { - g_object_unref (editor->edit); - editor->edit = NULL; - } - - editor->dialog = NULL; - - gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE); - e_rule_editor_set_sensitive (editor); -} - -static gboolean -update_selected_rule (ERuleEditor *editor) -{ - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - - selection = gtk_tree_view_get_selection (editor->list); - if (selection && gtk_tree_selection_get_selected (selection, &model, &iter)) { - gtk_tree_model_get (GTK_TREE_MODEL (editor->model), &iter, 1, &editor->current, -1); - return TRUE; - } - - return FALSE; -} - -static void -cursor_changed (GtkTreeView *treeview, - ERuleEditor *editor) -{ - if (update_selected_rule (editor)) { - g_return_if_fail (editor->current); - - e_rule_editor_set_sensitive (editor); - } -} - -static void -editor_response (GtkWidget *dialog, - gint button, - ERuleEditor *editor) -{ - if (button == GTK_RESPONSE_CANCEL) { - if (enable_undo) - rule_editor_play_undo (editor); - else { - ERuleEditorUndo *undo, *next; - - undo = editor->undo_log; - editor->undo_log = NULL; - while (undo) { - next = undo->next; - g_object_unref (undo->rule); - g_free (undo); - undo = next; - } - } - } -} - -static void -rule_add (GtkWidget *widget, - ERuleEditor *editor) -{ - GtkWidget *rules; - GtkWidget *content_area; - - if (editor->edit != NULL) - return; - - editor->edit = e_rule_editor_create_rule (editor); - e_filter_rule_set_source (editor->edit, editor->source); - rules = e_filter_rule_get_widget (editor->edit, editor->context); - - editor->dialog = gtk_dialog_new (); - gtk_dialog_add_buttons ( - GTK_DIALOG (editor->dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); - - gtk_window_set_title ((GtkWindow *) editor->dialog, _("Add Rule")); - gtk_window_set_default_size (GTK_WINDOW (editor->dialog), 650, 400); - gtk_window_set_resizable (GTK_WINDOW (editor->dialog), TRUE); - gtk_window_set_transient_for ((GtkWindow *) editor->dialog, (GtkWindow *) editor); - gtk_container_set_border_width ((GtkContainer *) editor->dialog, 6); - - content_area = gtk_dialog_get_content_area (GTK_DIALOG (editor->dialog)); - gtk_box_pack_start (GTK_BOX (content_area), rules, TRUE, TRUE, 3); - - g_signal_connect ( - editor->dialog, "response", - G_CALLBACK (add_editor_response), editor); - g_object_weak_ref ((GObject *) editor->dialog, (GWeakNotify) editor_destroy, editor); - - g_signal_connect ( - editor->edit, "changed", - G_CALLBACK (dialog_rule_changed), editor->dialog); - dialog_rule_changed (editor->edit, editor->dialog); - - gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE); - - gtk_widget_show (editor->dialog); -} - -static void -edit_editor_response (GtkWidget *dialog, - gint button, - ERuleEditor *editor) -{ - EFilterRule *rule; - GtkTreePath *path; - GtkTreeIter iter; - gint pos; - - if (button == GTK_RESPONSE_OK) { - EAlert *alert = NULL; - if (!e_filter_rule_validate (editor->edit, &alert)) { - e_alert_run_dialog (GTK_WINDOW (dialog), alert); - g_object_unref (alert); - return; - } - - rule = e_rule_context_find_rule ( - editor->context, - editor->edit->name, - editor->edit->source); - - if (rule != NULL && rule != editor->current) { - e_alert_run_dialog_for_args ( - GTK_WINDOW (dialog), - "filter:bad-name-notunique", - rule->name, NULL); - return; - } - - pos = e_rule_context_get_rank_rule ( - editor->context, - editor->current, - editor->source); - - if (pos != -1) { - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, pos); - gtk_tree_model_get_iter ( - GTK_TREE_MODEL (editor->model), &iter, path); - gtk_tree_path_free (path); - - gtk_list_store_set ( - editor->model, &iter, - 0, editor->edit->name, -1); - - rule_editor_add_undo ( - editor, E_RULE_EDITOR_LOG_EDIT, - e_filter_rule_clone (editor->current), - pos, 0); - - /* replace the old rule with the new rule */ - e_filter_rule_copy (editor->current, editor->edit); - } - } - - gtk_widget_destroy (dialog); -} - -static void -rule_edit (GtkWidget *widget, - ERuleEditor *editor) -{ - GtkWidget *rules; - GtkWidget *content_area; - - update_selected_rule (editor); - - if (editor->current == NULL || editor->edit != NULL) - return; - - editor->edit = e_filter_rule_clone (editor->current); - - rules = e_filter_rule_get_widget (editor->edit, editor->context); - - editor->dialog = gtk_dialog_new (); - gtk_dialog_add_buttons ( - (GtkDialog *) editor->dialog, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); - - gtk_window_set_title ((GtkWindow *) editor->dialog, _("Edit Rule")); - gtk_window_set_default_size (GTK_WINDOW (editor->dialog), 650, 400); - gtk_window_set_resizable (GTK_WINDOW (editor->dialog), TRUE); - gtk_window_set_transient_for (GTK_WINDOW (editor->dialog), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (editor)))); - gtk_container_set_border_width ((GtkContainer *) editor->dialog, 6); - - content_area = gtk_dialog_get_content_area (GTK_DIALOG (editor->dialog)); - gtk_box_pack_start (GTK_BOX (content_area), rules, TRUE, TRUE, 3); - - g_signal_connect ( - editor->dialog, "response", - G_CALLBACK (edit_editor_response), editor); - g_object_weak_ref ((GObject *) editor->dialog, (GWeakNotify) editor_destroy, editor); - - g_signal_connect ( - editor->edit, "changed", - G_CALLBACK (dialog_rule_changed), editor->dialog); - dialog_rule_changed (editor->edit, editor->dialog); - - gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE); - - gtk_widget_show (editor->dialog); -} - -static void -rule_delete (GtkWidget *widget, - ERuleEditor *editor) -{ - GtkTreeSelection *selection; - GtkTreePath *path; - GtkTreeIter iter; - gint pos, len; - - update_selected_rule (editor); - - pos = e_rule_context_get_rank_rule (editor->context, editor->current, editor->source); - if (pos != -1) { - EFilterRule *delete_rule = editor->current; - - editor->current = NULL; - - e_rule_context_remove_rule (editor->context, delete_rule); - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, pos); - gtk_tree_model_get_iter (GTK_TREE_MODEL (editor->model), &iter, path); - gtk_list_store_remove (editor->model, &iter); - gtk_tree_path_free (path); - - rule_editor_add_undo ( - editor, - E_RULE_EDITOR_LOG_REMOVE, - delete_rule, - e_rule_context_get_rank_rule ( - editor->context, - delete_rule, - delete_rule->source), - 0); -#if 0 - g_object_unref (delete_rule); -#endif - - /* now select the next rule */ - len = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (editor->model), NULL); - pos = pos >= len ? len - 1 : pos; - - if (pos >= 0) { - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, pos); - gtk_tree_model_get_iter (GTK_TREE_MODEL (editor->model), &iter, path); - gtk_tree_path_free (path); - - /* select the new row */ - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (editor->list)); - gtk_tree_selection_select_iter (selection, &iter); - - /* scroll to the selected row */ - path = gtk_tree_model_get_path ((GtkTreeModel *) editor->model, &iter); - gtk_tree_view_scroll_to_cell (editor->list, path, NULL, FALSE, 0.0, 0.0); - gtk_tree_path_free (path); - - /* update our selection state */ - cursor_changed (editor->list, editor); - return; - } - } - - e_rule_editor_set_sensitive (editor); -} - -static void -rule_move (ERuleEditor *editor, - gint from, - gint to) -{ - GtkTreeSelection *selection; - GtkTreePath *path; - GtkTreeIter iter; - EFilterRule *rule; - - rule_editor_add_undo ( - editor, E_RULE_EDITOR_LOG_RANK, - g_object_ref (editor->current), - e_rule_context_get_rank_rule (editor->context, - editor->current, editor->source), to); - - e_rule_context_rank_rule ( - editor->context, editor->current, editor->source, to); - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, from); - gtk_tree_model_get_iter (GTK_TREE_MODEL (editor->model), &iter, path); - gtk_tree_path_free (path); - - gtk_tree_model_get (GTK_TREE_MODEL (editor->model), &iter, 1, &rule, -1); - g_return_if_fail (rule != NULL); - - /* remove and then re-insert the row at the new location */ - gtk_list_store_remove (editor->model, &iter); - gtk_list_store_insert (editor->model, &iter, to); - - /* set the data on the row */ - gtk_list_store_set (editor->model, &iter, 0, rule->name, 1, rule, 2, rule->enabled, -1); - - /* select the row */ - selection = gtk_tree_view_get_selection (editor->list); - gtk_tree_selection_select_iter (selection, &iter); - - /* scroll to the selected row */ - path = gtk_tree_model_get_path ((GtkTreeModel *) editor->model, &iter); - gtk_tree_view_scroll_to_cell (editor->list, path, NULL, FALSE, 0.0, 0.0); - gtk_tree_path_free (path); - - e_rule_editor_set_sensitive (editor); -} - -static void -rule_top (GtkWidget *widget, - ERuleEditor *editor) -{ - gint pos; - - update_selected_rule (editor); - - pos = e_rule_context_get_rank_rule ( - editor->context, editor->current, editor->source); - if (pos > 0) - rule_move (editor, pos, 0); -} - -static void -rule_up (GtkWidget *widget, - ERuleEditor *editor) -{ - gint pos; - - update_selected_rule (editor); - - pos = e_rule_context_get_rank_rule ( - editor->context, editor->current, editor->source); - if (pos > 0) - rule_move (editor, pos, pos - 1); -} - -static void -rule_down (GtkWidget *widget, - ERuleEditor *editor) -{ - gint pos; - - update_selected_rule (editor); - - pos = e_rule_context_get_rank_rule ( - editor->context, editor->current, editor->source); - if (pos >= 0) - rule_move (editor, pos, pos + 1); -} - -static void -rule_bottom (GtkWidget *widget, - ERuleEditor *editor) -{ - gint pos; - gint count = 0; - EFilterRule *rule = NULL; - - update_selected_rule (editor); - - pos = e_rule_context_get_rank_rule ( - editor->context, editor->current, editor->source); - /* There's probably a better/faster way to get the count of the list here */ - while ((rule = e_rule_context_next_rule (editor->context, rule, editor->source))) - count++; - count--; - if (pos >= 0) - rule_move (editor, pos, count); -} - -static struct { - const gchar *name; - GCallback func; -} edit_buttons[] = { - { "rule_add", G_CALLBACK (rule_add) }, - { "rule_edit", G_CALLBACK (rule_edit) }, - { "rule_delete", G_CALLBACK (rule_delete) }, - { "rule_top", G_CALLBACK (rule_top) }, - { "rule_up", G_CALLBACK (rule_up) }, - { "rule_down", G_CALLBACK (rule_down) }, - { "rule_bottom", G_CALLBACK (rule_bottom) }, -}; - -static void -rule_editor_finalize (GObject *object) -{ - ERuleEditor *editor = E_RULE_EDITOR (object); - ERuleEditorUndo *undo, *next; - - g_object_unref (editor->context); - - undo = editor->undo_log; - while (undo) { - next = undo->next; - g_object_unref (undo->rule); - g_free (undo); - undo = next; - } - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_rule_editor_parent_class)->finalize (object); -} - -static void -rule_editor_dispose (GObject *object) -{ - ERuleEditor *editor = E_RULE_EDITOR (object); - - if (editor->dialog != NULL) { - gtk_widget_destroy (GTK_WIDGET (editor->dialog)); - editor->dialog = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_rule_editor_parent_class)->dispose (object); -} - -static void -rule_editor_set_source (ERuleEditor *editor, - const gchar *source) -{ - EFilterRule *rule = NULL; - GtkTreeIter iter; - - gtk_list_store_clear (editor->model); - - while ((rule = e_rule_context_next_rule (editor->context, rule, source)) != NULL) { - gtk_list_store_append (editor->model, &iter); - gtk_list_store_set ( - editor->model, &iter, - 0, rule->name, 1, rule, 2, rule->enabled, -1); - } - - g_free (editor->source); - editor->source = g_strdup (source); - editor->current = NULL; - e_rule_editor_set_sensitive (editor); -} - -static void -rule_editor_set_sensitive (ERuleEditor *editor) -{ - EFilterRule *rule = NULL; - gint index = -1, count = 0; - - while ((rule = e_rule_context_next_rule (editor->context, rule, editor->source))) { - if (rule == editor->current) - index = count; - count++; - } - - count--; - - gtk_widget_set_sensitive (GTK_WIDGET (editor->priv->buttons[BUTTON_EDIT]), index != -1); - gtk_widget_set_sensitive (GTK_WIDGET (editor->priv->buttons[BUTTON_DELETE]), index != -1); - gtk_widget_set_sensitive (GTK_WIDGET (editor->priv->buttons[BUTTON_TOP]), index > 0); - gtk_widget_set_sensitive (GTK_WIDGET (editor->priv->buttons[BUTTON_UP]), index > 0); - gtk_widget_set_sensitive (GTK_WIDGET (editor->priv->buttons[BUTTON_DOWN]), index >= 0 && index < count); - gtk_widget_set_sensitive (GTK_WIDGET (editor->priv->buttons[BUTTON_BOTTOM]), index >= 0 && index < count); -} - -static EFilterRule * -rule_editor_create_rule (ERuleEditor *editor) -{ - EFilterRule *rule; - EFilterPart *part; - - /* create a rule with 1 part in it */ - rule = e_filter_rule_new (); - part = e_rule_context_next_part (editor->context, NULL); - e_filter_rule_add_part (rule, e_filter_part_clone (part)); - - return rule; -} - -static void -e_rule_editor_class_init (ERuleEditorClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ERuleEditorPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = rule_editor_finalize; - object_class->dispose = rule_editor_dispose; - - class->set_source = rule_editor_set_source; - class->set_sensitive = rule_editor_set_sensitive; - class->create_rule = rule_editor_create_rule; - - /* TODO: Remove when it works (or never will) */ - enable_undo = getenv ("EVOLUTION_RULE_UNDO") != NULL; -} - -static void -e_rule_editor_init (ERuleEditor *editor) -{ - editor->priv = E_RULE_EDITOR_GET_PRIVATE (editor); -} - -/** - * rule_editor_new: - * - * Create a new ERuleEditor object. - * - * Return value: A new #ERuleEditor object. - **/ -ERuleEditor * -e_rule_editor_new (ERuleContext *context, - const gchar *source, - const gchar *label) -{ - ERuleEditor *editor = (ERuleEditor *) g_object_new (E_TYPE_RULE_EDITOR, NULL); - GtkBuilder *builder; - - builder = gtk_builder_new (); - e_load_ui_builder_definition (builder, "filter.ui"); - e_rule_editor_construct (editor, context, builder, source, label); - gtk_widget_hide (e_builder_get_widget (builder, "label17")); - gtk_widget_hide (e_builder_get_widget (builder, "filter_source_combobox")); - g_object_unref (builder); - - return editor; -} - -void -e_rule_editor_set_sensitive (ERuleEditor *editor) -{ - ERuleEditorClass *class; - - g_return_if_fail (E_IS_RULE_EDITOR (editor)); - - class = E_RULE_EDITOR_GET_CLASS (editor); - g_return_if_fail (class->set_sensitive != NULL); - - class->set_sensitive (editor); -} - -void -e_rule_editor_set_source (ERuleEditor *editor, - const gchar *source) -{ - ERuleEditorClass *class; - - g_return_if_fail (E_IS_RULE_EDITOR (editor)); - - class = E_RULE_EDITOR_GET_CLASS (editor); - g_return_if_fail (class->set_source != NULL); - - class->set_source (editor, source); -} - -EFilterRule * -e_rule_editor_create_rule (ERuleEditor *editor) -{ - ERuleEditorClass *class; - - g_return_val_if_fail (E_IS_RULE_EDITOR (editor), NULL); - - class = E_RULE_EDITOR_GET_CLASS (editor); - g_return_val_if_fail (class->create_rule != NULL, NULL); - - return class->create_rule (editor); -} - -static void -double_click (GtkTreeView *treeview, - GtkTreePath *path, - GtkTreeViewColumn *column, - ERuleEditor *editor) -{ - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - - selection = gtk_tree_view_get_selection (editor->list); - if (gtk_tree_selection_get_selected (selection, &model, &iter)) - gtk_tree_model_get (GTK_TREE_MODEL (editor->model), &iter, 1, &editor->current, -1); - - if (editor->current) - rule_edit ((GtkWidget *) treeview, editor); -} - -static void -rule_able_toggled (GtkCellRendererToggle *renderer, - gchar *path_string, - gpointer user_data) -{ - GtkWidget *table = user_data; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - - path = gtk_tree_path_new_from_string (path_string); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (table)); - - if (gtk_tree_model_get_iter (model, &iter, path)) { - EFilterRule *rule = NULL; - - gtk_tree_model_get (model, &iter, 1, &rule, -1); - - if (rule) { - rule->enabled = !rule->enabled; - gtk_list_store_set (GTK_LIST_STORE (model), &iter, 2, rule->enabled, -1); - } - } - - gtk_tree_path_free (path); -} - -void -e_rule_editor_construct (ERuleEditor *editor, - ERuleContext *context, - GtkBuilder *builder, - const gchar *source, - const gchar *label) -{ - GtkWidget *widget; - GtkWidget *action_area; - GtkWidget *content_area; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - GtkTreeSelection *selection; - GObject *object; - GList *list; - gint i; - - g_return_if_fail (E_IS_RULE_EDITOR (editor)); - g_return_if_fail (E_IS_RULE_CONTEXT (context)); - g_return_if_fail (GTK_IS_BUILDER (builder)); - - editor->context = g_object_ref (context); - - action_area = gtk_dialog_get_action_area (GTK_DIALOG (editor)); - content_area = gtk_dialog_get_content_area (GTK_DIALOG (editor)); - - gtk_window_set_resizable ((GtkWindow *) editor, TRUE); - gtk_window_set_default_size ((GtkWindow *) editor, 350, 400); - gtk_widget_realize ((GtkWidget *) editor); - gtk_container_set_border_width (GTK_CONTAINER (action_area), 12); - - widget = e_builder_get_widget (builder, "rule_editor"); - gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0); - - for (i = 0; i < BUTTON_LAST; i++) { - widget = e_builder_get_widget (builder, edit_buttons[i].name); - editor->priv->buttons[i] = GTK_BUTTON (widget); - g_signal_connect ( - widget, "clicked", - G_CALLBACK (edit_buttons[i].func), editor); - } - - object = gtk_builder_get_object (builder, "rule_tree_view"); - editor->list = GTK_TREE_VIEW (object); - - column = gtk_tree_view_get_column (GTK_TREE_VIEW (object), 0); - g_return_if_fail (column != NULL); - - gtk_tree_view_column_set_visible (column, FALSE); - list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column)); - g_return_if_fail (list != NULL); - - renderer = GTK_CELL_RENDERER (list->data); - g_warn_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (renderer)); - - g_signal_connect ( - renderer, "toggled", - G_CALLBACK (rule_able_toggled), editor->list); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - object = gtk_builder_get_object (builder, "rule_list_store"); - editor->model = GTK_LIST_STORE (object); - - g_signal_connect ( - editor->list, "cursor-changed", - G_CALLBACK (cursor_changed), editor); - g_signal_connect ( - editor->list, "row-activated", - G_CALLBACK (double_click), editor); - - widget = e_builder_get_widget (builder, "rule_label"); - gtk_label_set_label (GTK_LABEL (widget), label); - gtk_label_set_mnemonic_widget ( - GTK_LABEL (widget), GTK_WIDGET (editor->list)); - - g_signal_connect ( - editor, "response", - G_CALLBACK (editor_response), editor); - rule_editor_set_source (editor, source); - - gtk_dialog_add_buttons ( - GTK_DIALOG (editor), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); -} diff --git a/filter/e-rule-editor.h b/filter/e-rule-editor.h deleted file mode 100644 index 2b1a4f2bf7..0000000000 --- a/filter/e-rule-editor.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Not Zed <notzed@lostzed.mmc.com.au> - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_RULE_EDITOR_H -#define E_RULE_EDITOR_H - -#include <gtk/gtk.h> - -#include "e-rule-context.h" -#include "e-filter-rule.h" - -/* Standard GObject macros */ -#define E_TYPE_RULE_EDITOR \ - (e_rule_editor_get_type ()) -#define E_RULE_EDITOR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_RULE_EDITOR, ERuleEditor)) -#define E_RULE_EDITOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_RULE_EDITOR, ERuleEditorClass)) -#define E_IS_RULE_EDITOR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_RULE_EDITOR)) -#define E_IS_RULE_EDITOR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_RULE_EDITOR)) -#define E_RULE_EDITOR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_RULE_EDITOR, ERuleEditorClass)) - -G_BEGIN_DECLS - -typedef struct _ERuleEditor ERuleEditor; -typedef struct _ERuleEditorClass ERuleEditorClass; -typedef struct _ERuleEditorPrivate ERuleEditorPrivate; - -typedef struct _ERuleEditorUndo ERuleEditorUndo; - -struct _ERuleEditor { - GtkDialog parent; - - GtkListStore *model; - GtkTreeView *list; - - ERuleContext *context; - EFilterRule *current; - EFilterRule *edit; /* for editing/adding rules, so we only do 1 at a time */ - - GtkWidget *dialog; - - gchar *source; - - ERuleEditorUndo *undo_log; /* cancel/undo log */ - guint undo_active:1; /* we're performing undo */ - - ERuleEditorPrivate *priv; -}; - -struct _ERuleEditorClass { - GtkDialogClass parent_class; - - void (*set_sensitive) (ERuleEditor *editor); - void (*set_source) (ERuleEditor *editor, - const gchar *source); - - EFilterRule * (*create_rule) (ERuleEditor *editor); -}; - -enum { - E_RULE_EDITOR_LOG_EDIT, - E_RULE_EDITOR_LOG_ADD, - E_RULE_EDITOR_LOG_REMOVE, - E_RULE_EDITOR_LOG_RANK -}; - -struct _ERuleEditorUndo { - ERuleEditorUndo *next; - - guint type; - EFilterRule *rule; - gint rank; - gint newrank; -}; - -GType e_rule_editor_get_type (void); -ERuleEditor * e_rule_editor_new (ERuleContext *context, - const gchar *source, - const gchar *label); -void e_rule_editor_construct (ERuleEditor *editor, - ERuleContext *context, - GtkBuilder *builder, - const gchar *source, - const gchar *label); -void e_rule_editor_set_source (ERuleEditor *editor, - const gchar *source); -void e_rule_editor_set_sensitive (ERuleEditor *editor); -EFilterRule * e_rule_editor_create_rule (ERuleEditor *editor); - -G_END_DECLS - -#endif /* E_RULE_EDITOR_H */ diff --git a/filter/filter.error.xml b/filter/filter.error.xml deleted file mode 100644 index 62b75193d2..0000000000 --- a/filter/filter.error.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<error-list domain="filter"> - - <error id="no-date" type="error"> - <_primary>Missing date.</_primary> - <_secondary>You must choose a date.</_secondary> - </error> - - <error id="no-file" type="error"> - <_primary>Missing filename.</_primary> - <_secondary>You must specify a filename.</_secondary> - </error> - - <error id="bad-file" type="error"> - <_primary>File "{0}" does not exist or is not a regular file.</_primary> - <_secondary>You must specify a filename.</_secondary> - </error> - - <error id="bad-regexp" type="error"> - <_primary>Bad regular expression "{0}".</_primary> - <_secondary>Could not compile regular expression "{1}".</_secondary> - </error> - - <error id="no-name" type="error"> - <_primary>Missing name.</_primary> - <_secondary>You must name this filter.</_secondary> - </error> - - <error id="bad-name-notunique" type="error"> - <_primary>Name "{0}" already used.</_primary> - <_secondary>Please choose another name.</_secondary> - </error> - -</error-list> diff --git a/filter/filter.ui b/filter/filter.ui deleted file mode 100644 index d91292736d..0000000000 --- a/filter/filter.ui +++ /dev/null @@ -1,591 +0,0 @@ -<?xml version="1.0"?> -<interface> - <requires lib="gtk+" version="2.16"/> - <!-- interface-naming-policy toplevel-contextual --> - <object class="GtkAdjustment" id="adjustment1"> - <property name="value">1</property> - <property name="upper">1000</property> - <property name="step_increment">1</property> - <property name="page_increment">10</property> - </object> - <object class="GtkListStore" id="model1"> - <columns> - <!-- column-name gchararray --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">Incoming</col> - </row> - </data> - </object> - <object class="GtkListStore" id="model2"> - <columns> - <!-- column-name gchararray --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">the current time</col> - </row> - <row> - <col id="0" translatable="yes">the time you specify</col> - </row> - <row> - <col id="0" translatable="yes">a time relative to the current time</col> - </row> - </data> - </object> - <object class="GtkListStore" id="model3"> - <columns> - <!-- column-name gchararray --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">seconds</col> - </row> - <row> - <col id="0" translatable="yes">minutes</col> - </row> - <row> - <col id="0" translatable="yes">hours</col> - </row> - <row> - <col id="0" translatable="yes">days</col> - </row> - <row> - <col id="0" translatable="yes">weeks</col> - </row> - <row> - <col id="0" translatable="yes">months</col> - </row> - <row> - <col id="0" translatable="yes">years</col> - </row> - </data> - </object> - <object class="GtkListStore" id="model4"> - <columns> - <!-- column-name gchararray --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">ago</col> - </row> - <row> - <col id="0" translatable="yes">in the future</col> - </row> - </data> - </object> - <object class="GtkListStore" id="rule_list_store"> - <columns> - <!-- column-name column1 --> - <column type="gchararray"/> - <!-- column-name column2 --> - <column type="gpointer"/> - <!-- column-name column3 --> - <column type="gboolean"/> - </columns> - </object> - <object class="GtkVBox" id="rule_editor"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="label17"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Show filters for mail:</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="filter_source_combobox"> - <property name="visible">True</property> - <property name="model">model1</property> - <child> - <object class="GtkCellRendererText" id="renderer1"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="rule_frame"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="rule_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Filter Rules</property> - <property name="use_underline">True</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox10"> - <property name="visible">True</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="label16"> - <property name="visible">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox4"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkScrolledWindow" id="rule_scrolled_window"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> - <property name="shadow_type">in</property> - <child> - <object class="GtkTreeView" id="rule_tree_view"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="model">rule_list_store</property> - <property name="headers_visible">False</property> - <child> - <object class="GtkTreeViewColumn" id="column_enabled"> - <!--<property name="visible">False</property>--> - <property name="title">Enabled</property> - <child> - <object class="GtkCellRendererToggle" id="cell_renderer_enabled"/> - <attributes> - <attribute name="active">2</attribute> - </attributes> - </child> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="column_rule_name"> - <property name="title">Rule Name</property> - <child> - <object class="GtkCellRendererText" id="cell_renderer_rule_name"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox5"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkVButtonBox" id="vbuttonbox4"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkButton" id="rule_add"> - <property name="label">gtk-add</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="rule_edit"> - <property name="label" translatable="yes">_Edit</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="rule_delete"> - <property name="label">gtk-remove</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkButton" id="rule_top"> - <property name="label">gtk-goto-top</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> - </packing> - </child> - <child> - <object class="GtkButton" id="rule_up"> - <property name="label">gtk-go-up</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">4</property> - </packing> - </child> - <child> - <object class="GtkButton" id="rule_down"> - <property name="label">gtk-go-down</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">5</property> - </packing> - </child> - <child> - <object class="GtkButton" id="rule_bottom"> - <property name="label">gtk-goto-bottom</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">6</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="padding">3</property> - <property name="position">2</property> - </packing> - </child> - </object> - <object class="GtkVBox" id="filter_datespec"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkHBox" id="hbox5"> - <property name="visible">True</property> - <property name="border_width">4</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="label4"> - <property name="visible">True</property> - <property name="label" translatable="yes">Compare against</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="combobox_type"> - <property name="visible">True</property> - <property name="model">model2</property> - <child> - <object class="GtkCellRendererText" id="renderer2"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHSeparator" id="hseparator1"> - <property name="visible">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="padding">1</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkNotebook" id="notebook_type"> - <property name="visible">True</property> - <property name="show_tabs">False</property> - <property name="show_border">False</property> - <child> - <object class="GtkVBox" id="vbox9"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkLabel" id="label5"> - <property name="visible">True</property> - <property name="label" translatable="yes">The message's date will be compared against -the current time when filtering occurs.</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="tab_fill">False</property> - </packing> - </child> - <child type="tab"> - <object class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">label1</property> - <property name="justify">center</property> - </object> - <packing> - <property name="tab_fill">False</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox7"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkLabel" id="label6"> - <property name="visible">True</property> - <property name="label" translatable="yes">The message's date will be compared against -12:00am of the date specified.</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkCalendar" id="calendar_specify"> - <property name="visible">True</property> - <property name="can_focus">True</property> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - <child type="tab"> - <object class="GtkLabel" id="label2"> - <property name="visible">True</property> - <property name="label" translatable="yes">label2</property> - <property name="justify">center</property> - </object> - <packing> - <property name="position">1</property> - <property name="tab_fill">False</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox8"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkLabel" id="label7"> - <property name="visible">True</property> - <property name="ypad">15</property> - <property name="label" translatable="yes">The message's date will be compared against -a time relative to when filtering occurs.</property> - <property name="justify">center</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment1"> - <property name="visible">True</property> - <property name="top_padding">5</property> - <property name="left_padding">58</property> - <child> - <object class="GtkHBox" id="hbox6"> - <property name="visible">True</property> - <property name="homogeneous">True</property> - <child> - <object class="GtkSpinButton" id="spin_relative"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="adjustment">adjustment1</property> - <property name="climb_rate">1</property> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="combobox_relative"> - <property name="visible">True</property> - <property name="model">model3</property> - <property name="active">0</property> - <child> - <object class="GtkCellRendererText" id="renderer3"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="combobox_past_future"> - <property name="visible">True</property> - <property name="model">model4</property> - <property name="active">0</property> - <child> - <object class="GtkCellRendererText" id="renderer4"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="padding">2</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">2</property> - </packing> - </child> - <child type="tab"> - <object class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="label" translatable="yes">label3</property> - <property name="justify">center</property> - </object> - <packing> - <property name="position">2</property> - <property name="tab_fill">False</property> - </packing> - </child> - </object> - <packing> - <property name="position">2</property> - </packing> - </child> - </object> -</interface> |