From 1565f7ce1cb7ec5b62710dea4a7f2992809530d7 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Sun, 7 Feb 2016 13:56:21 +0100 Subject: [PATCH] Added ZakFormValidatorCompare. --- src/Makefile.am | 2 + src/form.c | 26 ++- src/formvalidator.c | 6 +- src/formvalidator.h | 6 +- src/formvalidatorcompare.c | 292 +++++++++++++++++++++++++++++++++ src/formvalidatorcompare.h | 43 +++++ src/formvalidatorcomparedate.c | 7 +- 7 files changed, 365 insertions(+), 17 deletions(-) create mode 100644 src/formvalidatorcompare.c create mode 100644 src/formvalidatorcompare.h diff --git a/src/Makefile.am b/src/Makefile.am index 7cab596..1947bbc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,6 +20,7 @@ libzakform_la_SOURCES = \ formelementvalidatorregex.c \ formiprovider.c \ formvalidator.c \ + formvalidatorcompare.c \ formvalidatorcomparedate.c libzakform_la_LDFLAGS = -no-undefined @@ -38,6 +39,7 @@ libzakform_include_HEADERS = \ formelementvalidatorregex.h \ formiprovider.h \ formvalidator.h \ + formvalidatorcompare.h \ formvalidatorcomparedate.h libzakform_includedir = $(includedir)/libzakform diff --git a/src/form.c b/src/form.c index 52075c9..2570956 100644 --- a/src/form.c +++ b/src/form.c @@ -269,6 +269,7 @@ zak_form_form_load_from_xml (ZakFormForm *zakform, xmlDoc *xmldoc) gchar *type; guint i; + gint y; FormElementConstructorFunc element_constructor; FormElementXmlParsingFunc element_xml_parsing; @@ -276,6 +277,10 @@ zak_form_form_load_from_xml (ZakFormForm *zakform, xmlDoc *xmldoc) FormValidatorConstructorFunc validator_constructor; FormValidatorXmlParsingFunc validator_xml_parsing; + xmlXPathContextPtr xpcontext; + xmlXPathObjectPtr xpresult; + xmlNodeSetPtr xnodeset; + g_return_val_if_fail (ZAK_FORM_IS_FORM (zakform), FALSE); g_return_val_if_fail (xmldoc != NULL, FALSE); @@ -336,9 +341,20 @@ zak_form_form_load_from_xml (ZakFormForm *zakform, xmlDoc *xmldoc) g_warning (_("Unknown element type «%s»."), type); } } - else if (xmlStrcmp (cur->name, (const xmlChar *)"validator") == 0) + + cur = cur->next; + } + + /* parsing of validators */ + xpcontext = xmlXPathNewContext (xmldoc); + xpcontext->node = xmlDocGetRootElement (xmldoc); + xpresult = xmlXPathEvalExpression ((const xmlChar *)"child::validator", xpcontext); + if (!xmlXPathNodeSetIsEmpty (xpresult->nodesetval)) + { + xnodeset = xpresult->nodesetval; + for (y = 0; y < xnodeset->nodeNr; y++) { - type = xmlGetProp (cur, (const xmlChar *)"type"); + type = xmlGetProp (xnodeset->nodeTab[y], (const xmlChar *)"type"); /* for each module */ for (i = 0; i < priv->ar_modules->len; i++) @@ -358,7 +374,7 @@ zak_form_form_load_from_xml (ZakFormForm *zakform, xmlDoc *xmldoc) { if (validator_xml_parsing != NULL) { - validator_xml_parsing (validator, cur, priv->ar_elements); + validator_xml_parsing (validator, xnodeset->nodeTab[y], priv->ar_elements); } } @@ -371,8 +387,6 @@ zak_form_form_load_from_xml (ZakFormForm *zakform, xmlDoc *xmldoc) g_warning ("Validator «%s» not found.", type); } } - - cur = cur->next; } } else @@ -600,7 +614,7 @@ zak_form_form_is_valid (ZakFormForm *zakform) for (i = 0; i < priv->ar_validators->len; i++) { ZakFormValidator *validator = (ZakFormValidator *)g_ptr_array_index (priv->ar_validators, i); - if (!zak_form_validator_validate (validator, priv->ar_elements)) + if (!zak_form_validator_validate (validator)) { g_ptr_array_add (priv->ar_messages, (gpointer)g_strdup (zak_form_validator_get_message (validator))); ret = FALSE; diff --git a/src/formvalidator.c b/src/formvalidator.c index 719a9a1..56b1d7c 100644 --- a/src/formvalidator.c +++ b/src/formvalidator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Andrea Zagli + * Copyright (C) 2015-2016 Andrea Zagli * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -75,7 +75,7 @@ zak_form_validator_init (ZakFormValidator *zak_form_validator) } gboolean -zak_form_validator_validate (ZakFormValidator *self, GPtrArray *ar_elements) +zak_form_validator_validate (ZakFormValidator *self) { gboolean ret; @@ -84,7 +84,7 @@ zak_form_validator_validate (ZakFormValidator *self, GPtrArray *ar_elements) ret = TRUE; if (ZAK_FORM_VALIDATOR_GET_CLASS (self)->validate != NULL) { - ret = ZAK_FORM_VALIDATOR_GET_CLASS (self)->validate (self, ar_elements); + ret = ZAK_FORM_VALIDATOR_GET_CLASS (self)->validate (self); } return ret; } diff --git a/src/formvalidator.h b/src/formvalidator.h index d94494e..c80677b 100644 --- a/src/formvalidator.h +++ b/src/formvalidator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Andrea Zagli + * Copyright (C) 2015-2016 Andrea Zagli * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,10 +32,10 @@ struct _ZakFormValidatorClass { GObjectClass parent_class; - gboolean (*validate) (ZakFormValidator *self, GPtrArray *ar_elements); + gboolean (*validate) (ZakFormValidator *self); }; -gboolean zak_form_validator_validate (ZakFormValidator *self, GPtrArray *ar_elements); +gboolean zak_form_validator_validate (ZakFormValidator *self); void zak_form_validator_set_message (ZakFormValidator *validator, const gchar *message); diff --git a/src/formvalidatorcompare.c b/src/formvalidatorcompare.c new file mode 100644 index 0000000..02fedf6 --- /dev/null +++ b/src/formvalidatorcompare.c @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2016 Andrea Zagli + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#include + +#include "commons.h" +#include "formvalidator.h" +#include "formvalidatorcompare.h" + +static void zak_form_validator_compare_class_init (ZakFormValidatorCompareClass *class); +static void zak_form_validator_compare_init (ZakFormValidatorCompare *validator); + +static void zak_form_validator_compare_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void zak_form_validator_compare_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void zak_form_validator_compare_dispose (GObject *gobject); +static void zak_form_validator_compare_finalize (GObject *gobject); + +static gboolean zak_form_validator_compare_validate (ZakFormValidator *validator_notempty); + +struct _ZakFormValidatorCompare +{ + ZakFormValidator parent_instance; + + /* Other members, including private data. */ +}; + +#define ZAK_FORM_VALIDATOR_COMPARE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ZAK_FORM_TYPE_VALIDATOR_COMPARE, ZakFormValidatorComparePrivate)) + +enum + { + LESSER, + LESSER_EQUAL, + EQUAL, + NOT_EQUAL, + GREATER, + GREATER_EQUAL + }; + +static gchar *msgs[6]; + +typedef struct _ZakFormValidatorComparePrivate ZakFormValidatorComparePrivate; +struct _ZakFormValidatorComparePrivate + { + guint type; + + ZakFormElement *v1; + ZakFormElement *v2; + }; + +G_DEFINE_TYPE (ZakFormValidatorCompare, zak_form_validator_compare, ZAK_FORM_TYPE_VALIDATOR) + +static void +zak_form_validator_compare_class_init (ZakFormValidatorCompareClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + ZakFormValidatorClass *parent_class = ZAK_FORM_VALIDATOR_CLASS (class); + + object_class->set_property = zak_form_validator_compare_set_property; + object_class->get_property = zak_form_validator_compare_get_property; + object_class->dispose = zak_form_validator_compare_dispose; + object_class->finalize = zak_form_validator_compare_finalize; + + parent_class->validate = zak_form_validator_compare_validate; + + g_type_class_add_private (object_class, sizeof (ZakFormValidatorComparePrivate)); +} + +static void +zak_form_validator_compare_init (ZakFormValidatorCompare *validator) +{ + ZakFormValidatorComparePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_GET_PRIVATE (validator); + + priv->v1 = NULL; + priv->v2 = NULL; + + msgs[0] = _("lesser than"); + msgs[1] = _("lesser or equal to"); + msgs[2] = _("equal to"); + msgs[3] = _("different from"); + msgs[4] = _("greater than"); + msgs[5] = _("greater or equal to"); +} + +/** + * zak_form_validator_compare_new: + * + * Returns: the newly created #ZakFormValidatorCompare object. + */ +ZakFormValidatorCompare +*zak_form_validator_compare_new () +{ + ZakFormValidatorCompare *zak_form_validator_compare; + + zak_form_validator_compare = ZAK_FORM_VALIDATOR_COMPARE (g_object_new (zak_form_validator_compare_get_type (), NULL)); + + return zak_form_validator_compare; +} + +/** + * zak_form_validator_compare_xml_parsing: + * @validator: + * @xnode: + * @ar_elements: + * + */ +gboolean +zak_form_validator_compare_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, GPtrArray *ar_elements) +{ + gchar *prop; + + ZakFormValidatorComparePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_GET_PRIVATE (validator); + + prop = xmlGetProp (xnode, (const xmlChar *)"type_comp"); + if (g_strcmp0 (prop, "lt") == 0) + { + priv->type = LESSER; + } + else if (g_strcmp0 (prop, "let") == 0) + { + priv->type = LESSER_EQUAL; + } + else if (g_strcmp0 (prop, "e") == 0) + { + priv->type = EQUAL; + } + else if (g_strcmp0 (prop, "ne") == 0) + { + priv->type = NOT_EQUAL; + } + else if (g_strcmp0 (prop, "gt") == 0) + { + priv->type = GREATER; + } + else if (g_strcmp0 (prop, "get") == 0) + { + priv->type = GREATER_EQUAL; + } + + prop = xmlGetProp (xnode, (const xmlChar *)"element1"); + priv->v1 = zak_form_get_element_by_id (ar_elements, prop); + + prop = xmlGetProp (xnode, (const xmlChar *)"element2"); + priv->v2 = zak_form_get_element_by_id (ar_elements, prop); + + return TRUE; +} + +/* PRIVATE */ +static void +zak_form_validator_compare_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ZakFormValidatorCompare *validator = (ZakFormValidatorCompare *)object; + ZakFormValidatorComparePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_GET_PRIVATE (validator); + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +zak_form_validator_compare_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ZakFormValidatorCompare *validator = (ZakFormValidatorCompare *)object; + ZakFormValidatorComparePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_GET_PRIVATE (validator); + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +zak_form_validator_compare_dispose (GObject *gobject) +{ + ZakFormValidatorCompare *validator = (ZakFormValidatorCompare *)gobject; + ZakFormValidatorComparePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_GET_PRIVATE (validator); + + + + GObjectClass *parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (gobject)); + parent_class->dispose (gobject); +} + +static void +zak_form_validator_compare_finalize (GObject *gobject) +{ + ZakFormValidatorCompare *validator = (ZakFormValidatorCompare *)gobject; + ZakFormValidatorComparePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_GET_PRIVATE (validator); + + + + GObjectClass *parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (gobject)); + parent_class->finalize (gobject); +} + +static gboolean +zak_form_validator_compare_validate (ZakFormValidator *validator) +{ + gboolean ret; + + gchar *gc1; + gchar *gc2; + + gint comp; + gchar *msg; + + ZakFormValidatorComparePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_GET_PRIVATE (validator); + + if (!ZAK_FORM_IS_ELEMENT (priv->v1) + || !ZAK_FORM_IS_ELEMENT (priv->v2)) + { + ret = TRUE; + } + else + { + gc1 = zak_form_element_get_value (priv->v1); + gc2 = zak_form_element_get_value (priv->v2); + + comp = g_strcmp0 (gc1, gc2); + switch (comp) + { + case -1: + ret = (priv->type == LESSER + || priv->type == LESSER_EQUAL + || priv->type == NOT_EQUAL); + break; + + case 0: + ret = (priv->type == LESSER_EQUAL + || priv->type == EQUAL + || priv->type == GREATER_EQUAL); + break; + + case 1: + ret = (priv->type == GREATER + || priv->type == GREATER_EQUAL + || priv->type == NOT_EQUAL); + break; + }; + + if (!ret) + { + msg = g_strdup_printf (_("«%s» must be %s «%s»"), + zak_form_element_get_long_name (priv->v1), + msgs[priv->type], + zak_form_element_get_long_name (priv->v2)); + zak_form_validator_set_message (validator, msg); + g_free (msg); + } + } + + return ret; +} diff --git a/src/formvalidatorcompare.h b/src/formvalidatorcompare.h new file mode 100644 index 0000000..02139d0 --- /dev/null +++ b/src/formvalidatorcompare.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 Andrea Zagli + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __ZAK_FORM_VALIDATOR_COMPARE_H__ +#define __ZAK_FORM_VALIDATOR_COMPARE_H__ + + +#include + +#include + +#include "formvalidator.h" + + +G_BEGIN_DECLS + + +#define ZAK_FORM_TYPE_VALIDATOR_COMPARE zak_form_validator_compare_get_type () +G_DECLARE_FINAL_TYPE (ZakFormValidatorCompare, zak_form_validator_compare, ZAK_FORM, VALIDATOR_COMPARE, ZakFormValidator) + +ZakFormValidatorCompare *zak_form_validator_compare_new (void); +gboolean zak_form_validator_compare_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, GPtrArray *ar_elements); + + +G_END_DECLS + + +#endif /* __ZAK_FORM_VALIDATOR_COMPARE_H__ */ diff --git a/src/formvalidatorcomparedate.c b/src/formvalidatorcomparedate.c index 8c7be45..5de341e 100644 --- a/src/formvalidatorcomparedate.c +++ b/src/formvalidatorcomparedate.c @@ -43,7 +43,7 @@ static void zak_form_validator_compare_date_get_property (GObject *object, static void zak_form_validator_compare_date_dispose (GObject *gobject); static void zak_form_validator_compare_date_finalize (GObject *gobject); -static gboolean zak_form_validator_compare_date_validate (ZakFormValidator *validator_notempty, const gchar *value); +static gboolean zak_form_validator_compare_date_validate (ZakFormValidator *validator_notempty); struct _ZakFormValidatorCompareDate { @@ -242,8 +242,7 @@ zak_form_validator_compare_date_finalize (GObject *gobject) } static gboolean -zak_form_validator_compare_date_validate (ZakFormValidator *validator, - const gchar *value) +zak_form_validator_compare_date_validate (ZakFormValidator *validator) { gboolean ret; @@ -255,8 +254,6 @@ zak_form_validator_compare_date_validate (ZakFormValidator *validator, ZakFormValidatorCompareDatePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_DATE_GET_PRIVATE (validator); - g_return_val_if_fail (value != NULL, FALSE); - if (!ZAK_FORM_IS_ELEMENT (priv->v1) || !ZAK_FORM_IS_ELEMENT (priv->v2)) { -- 2.49.0