/* * 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 * * * Authors: * Not Zed * Jeffrey Stedfast * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include "e-filter-element.h" #include "e-filter-part.h" typedef EFilterElement * (*EFilterElementFunc) (gpointer data); 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); }