From ca805c536c595f5dd20a09317c291b4d453e78a7 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Sat, 2 Jan 2016 12:06:28 +0100 Subject: [PATCH] Added ZakFormValidatorCompareDate. --- src/Makefile.am | 8 +- src/commons.c | 58 ++++++ src/commons.h | 37 ++++ src/form.c | 34 +++- src/form.h | 2 + src/formvalidatorcomparedate.c | 324 +++++++++++++++++++++++++++++++++ src/formvalidatorcomparedate.h | 43 +++++ 7 files changed, 502 insertions(+), 4 deletions(-) create mode 100644 src/commons.c create mode 100644 src/commons.h create mode 100644 src/formvalidatorcomparedate.c create mode 100644 src/formvalidatorcomparedate.h diff --git a/src/Makefile.am b/src/Makefile.am index 0b9634c..7cab596 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,7 @@ AM_CPPFLAGS = $(ZAKFORM_CFLAGS) \ lib_LTLIBRARIES = libzakform.la libzakform_la_SOURCES = \ + commons.c \ form.c \ formelement.c \ formelementfilter.c \ @@ -18,12 +19,14 @@ libzakform_la_SOURCES = \ formelementvalidatornotempty.c \ formelementvalidatorregex.c \ formiprovider.c \ - formvalidator.c + formvalidator.c \ + formvalidatorcomparedate.c libzakform_la_LDFLAGS = -no-undefined libzakform_include_HEADERS = \ libzakform.h \ + commons.h \ form.h \ formelement.h \ formelementfilter.h \ @@ -34,7 +37,8 @@ libzakform_include_HEADERS = \ formelementvalidatornotempty.h \ formelementvalidatorregex.h \ formiprovider.h \ - formvalidator.h + formvalidator.h \ + formvalidatorcomparedate.h libzakform_includedir = $(includedir)/libzakform diff --git a/src/commons.c b/src/commons.c new file mode 100644 index 0000000..fd49ad0 --- /dev/null +++ b/src/commons.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 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 + +#ifdef G_OS_WIN32 + #include +#endif + +#include "commons.h" + +/** + * zak_form_get_element_by_id: + * @ar_elements: + * @id: + * + * Returns: the #ZakFormElement with @id. + */ +ZakFormElement +*zak_form_get_element_by_id (GPtrArray *ar_elements, const gchar *id) +{ + guint i; + + ZakFormElement *ret; + + ret = NULL; + for (i = 0; i < ar_elements->len; i++) + { + ZakFormElement *element = (ZakFormElement *)g_ptr_array_index (ar_elements, i); + + if (g_strcmp0 (zak_form_element_get_name (element), id) == 0) + { + ret = element; + break; + } + } + + return ret; +} diff --git a/src/commons.h b/src/commons.h new file mode 100644 index 0000000..9312c57 --- /dev/null +++ b/src/commons.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015 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_COMMONS_H_ +#define _ZAK_FORM_COMMONS_H_ + +#include + + +#include "formelement.h" + + +G_BEGIN_DECLS + + +ZakFormElement *zak_form_get_element_by_id (GPtrArray *ar_elements, const gchar *id); + + +G_END_DECLS + + +#endif /* _ZAK_FORM_COMMONS_H_ */ diff --git a/src/form.c b/src/form.c index a8abfdd..52075c9 100644 --- a/src/form.c +++ b/src/form.c @@ -40,7 +40,7 @@ typedef gboolean (* FormElementFilterXmlParsingFunc) (ZakFormElementFilter *, xm typedef ZakFormElementValidator *(* FormElementValidatorConstructorFunc) (void); typedef gboolean (* FormElementValidatorXmlParsingFunc) (ZakFormElementValidator *, xmlNodePtr); typedef ZakFormValidator *(* FormValidatorConstructorFunc) (void); -typedef gboolean (* FormValidatorXmlParsingFunc) (ZakFormValidator *, xmlNodePtr); +typedef gboolean (* FormValidatorXmlParsingFunc) (ZakFormValidator *, xmlNodePtr, GPtrArray *); static void zak_form_form_class_init (ZakFormFormClass *class); static void zak_form_form_init (ZakFormForm *zak_form_form); @@ -65,6 +65,7 @@ typedef struct GPtrArray *ar_modules; GPtrArray *ar_elements; GPtrArray *ar_validators; + GPtrArray *ar_messages; } ZakFormFormPrivate; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ZakFormForm, zak_form_form, G_TYPE_OBJECT) @@ -116,6 +117,7 @@ zak_form_form_init (ZakFormForm *zak_form_form) priv->ar_modules = NULL; priv->ar_elements = g_ptr_array_new (); priv->ar_validators = g_ptr_array_new (); + priv->ar_messages = g_ptr_array_new (); #ifdef G_OS_WIN32 @@ -356,7 +358,7 @@ zak_form_form_load_from_xml (ZakFormForm *zakform, xmlDoc *xmldoc) { if (validator_xml_parsing != NULL) { - validator_xml_parsing (validator, cur); + validator_xml_parsing (validator, cur, priv->ar_elements); } } @@ -579,6 +581,8 @@ zak_form_form_is_valid (ZakFormForm *zakform) ZakFormFormPrivate *priv; + GPtrArray *ar_messages; + priv = zak_form_form_get_instance_private (zakform); ret = TRUE; @@ -592,9 +596,35 @@ zak_form_form_is_valid (ZakFormForm *zakform) } } + g_ptr_array_set_size (priv->ar_messages, 0); + 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)) + { + g_ptr_array_add (priv->ar_messages, (gpointer)g_strdup (zak_form_validator_get_message (validator))); + ret = FALSE; + } + } + return ret; } +/** + * zak_form_form_get_messages: + * @zakform: + * + */ +GPtrArray +*zak_form_form_get_messages (ZakFormForm *zakform) +{ + ZakFormFormPrivate *priv; + + priv = zak_form_form_get_instance_private (zakform); + + return priv->ar_messages; +} + /** * zak_form_form_is_changed: * @zakform: diff --git a/src/form.h b/src/form.h index 38780f1..e97ca2a 100644 --- a/src/form.h +++ b/src/form.h @@ -58,6 +58,8 @@ void zak_form_form_clear (ZakFormForm *zakform); void zak_form_form_set_as_original (ZakFormForm *zakform); gboolean zak_form_form_is_valid (ZakFormForm *zakform); +GPtrArray *zak_form_form_get_messages (ZakFormForm *zakform); + gboolean zak_form_form_is_changed (ZakFormForm *zakform); void zak_form_form_set_editable (ZakFormForm *zakform, gboolean editable); diff --git a/src/formvalidatorcomparedate.c b/src/formvalidatorcomparedate.c new file mode 100644 index 0000000..e4cbd14 --- /dev/null +++ b/src/formvalidatorcomparedate.c @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2015 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 "commons.h" +#include "formvalidator.h" +#include "formvalidatorcomparedate.h" + +static void zak_form_validator_compare_date_class_init (ZakFormValidatorCompareDateClass *class); +static void zak_form_validator_compare_date_init (ZakFormValidatorCompareDate *validator); + +static void zak_form_validator_compare_date_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void zak_form_validator_compare_date_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +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); + +struct _ZakFormValidatorCompareDate +{ + ZakFormValidator parent_instance; + + /* Other members, including private data. */ +}; + +#define ZAK_FORM_VALIDATOR_COMPARE_DATE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ZAK_FORM_TYPE_VALIDATOR_COMPARE_DATE, ZakFormValidatorCompareDatePrivate)) + +enum + { + LESSER, + LESSER_EQUAL, + EQUAL, + NOT_EQUAL, + GREATER, + GREATER_EQUAL + }; + +static gchar *msgs[] = {"lesser than", + "lesser or equal to", + "equal to", + "different from", + "greater than", + "greater or equal to"}; + +typedef struct _ZakFormValidatorCompareDatePrivate ZakFormValidatorCompareDatePrivate; +struct _ZakFormValidatorCompareDatePrivate + { + guint type; + + ZakFormElement *v1; + ZakFormElement *v2; + + gchar *format1; + gchar *format2; + }; + +G_DEFINE_TYPE (ZakFormValidatorCompareDate, zak_form_validator_compare_date, ZAK_FORM_TYPE_VALIDATOR) + +static void +zak_form_validator_compare_date_class_init (ZakFormValidatorCompareDateClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + ZakFormValidatorClass *parent_class = ZAK_FORM_VALIDATOR_CLASS (class); + + object_class->set_property = zak_form_validator_compare_date_set_property; + object_class->get_property = zak_form_validator_compare_date_get_property; + object_class->dispose = zak_form_validator_compare_date_dispose; + object_class->finalize = zak_form_validator_compare_date_finalize; + + parent_class->validate = zak_form_validator_compare_date_validate; + + g_type_class_add_private (object_class, sizeof (ZakFormValidatorCompareDatePrivate)); +} + +static void +zak_form_validator_compare_date_init (ZakFormValidatorCompareDate *validator) +{ + ZakFormValidatorCompareDatePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_DATE_GET_PRIVATE (validator); + + priv->v1 = NULL; + priv->v2 = NULL; +} + +/** + * zak_form_validator_compare_date_new: + * + * Returns: the newly created #ZakFormValidatorCompareDate object. + */ +ZakFormValidatorCompareDate +*zak_form_validator_compare_date_new () +{ + ZakFormValidatorCompareDate *zak_form_validator_compare_date; + + zak_form_validator_compare_date = ZAK_FORM_VALIDATOR_COMPARE_DATE (g_object_new (zak_form_validator_compare_date_get_type (), NULL)); + + return zak_form_validator_compare_date; +} + +/** + * zak_form_validator_compare_date_xml_parsing: + * @validator: + * @xnode: + * @ar_elements: + * + */ +gboolean +zak_form_validator_compare_date_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, GPtrArray *ar_elements) +{ + gchar *prop; + + ZakFormValidatorCompareDatePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_DATE_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); + + prop = xmlGetProp (xnode, (const xmlChar *)"format1"); + priv->format1 = g_strdup (prop); + + prop = xmlGetProp (xnode, (const xmlChar *)"format2"); + priv->format2 = g_strdup (prop); + + return TRUE; +} + +/* PRIVATE */ +static void +zak_form_validator_compare_date_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ZakFormValidatorCompareDate *validator = (ZakFormValidatorCompareDate *)object; + ZakFormValidatorCompareDatePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_DATE_GET_PRIVATE (validator); + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +zak_form_validator_compare_date_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ZakFormValidatorCompareDate *validator = (ZakFormValidatorCompareDate *)object; + ZakFormValidatorCompareDatePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_DATE_GET_PRIVATE (validator); + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +zak_form_validator_compare_date_dispose (GObject *gobject) +{ + ZakFormValidatorCompareDate *validator = (ZakFormValidatorCompareDate *)gobject; + ZakFormValidatorCompareDatePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_DATE_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_date_finalize (GObject *gobject) +{ + ZakFormValidatorCompareDate *validator = (ZakFormValidatorCompareDate *)gobject; + ZakFormValidatorCompareDatePrivate *priv = ZAK_FORM_VALIDATOR_COMPARE_DATE_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_date_validate (ZakFormValidator *validator, + const gchar *value) +{ + gboolean ret; + + GDateTime *gdt1; + GDateTime *gdt2; + + gint comp; + gchar *msg; + + 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)) + { + ret = TRUE; + } + else + { + gdt1 = zak_utils_get_gdatetime_from_string (zak_form_element_get_value (priv->v1), priv->format1); + gdt2 = zak_utils_get_gdatetime_from_string (zak_form_element_get_value (priv->v2), priv->format2); + g_warning ("gdt1 %s; gdt2 %s",g_date_time_format(gdt1,"%d/%m/%Y"),g_date_time_format(gdt2,"%d/%m/%Y")); + if (gdt1 == NULL + || gdt2 == NULL) + { + if (priv->type == LESSER + || priv->type == LESSER_EQUAL) + { + ret = (gdt1 == NULL + && gdt2 != NULL); + } + else if (priv->type == EQUAL) + { + ret = (gdt1 == NULL + && gdt2 == NULL); + } + else if (priv->type == GREATER + || priv->type == GREATER_EQUAL) + { + ret = (gdt1 != NULL + && gdt2 == NULL); + } + } + else + { + comp = g_date_time_compare (gdt1, gdt2); + 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_name (priv->v1), + msgs[priv->type], + zak_form_element_get_name (priv->v2)); + zak_form_validator_set_message (validator, msg); + g_free (msg); + } + } + + return ret; +} diff --git a/src/formvalidatorcomparedate.h b/src/formvalidatorcomparedate.h new file mode 100644 index 0000000..c8940ca --- /dev/null +++ b/src/formvalidatorcomparedate.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 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_DATE_H__ +#define __ZAK_FORM_VALIDATOR_COMPARE_DATE_H__ + + +#include + +#include + +#include "formvalidator.h" + + +G_BEGIN_DECLS + + +#define ZAK_FORM_TYPE_VALIDATOR_COMPARE_DATE zak_form_validator_compare_date_get_type () +G_DECLARE_FINAL_TYPE (ZakFormValidatorCompareDate, zak_form_validator_compare_date, ZAK_FORM, VALIDATOR_COMPARE_DATE, ZakFormValidator) + +ZakFormValidatorCompareDate *zak_form_validator_compare_date_new (void); +gboolean zak_form_validator_compare_date_xml_parsing (ZakFormValidator *validator, xmlNode *xnode, GPtrArray *ar_elements); + + +G_END_DECLS + + +#endif /* __ZAK_FORM_VALIDATOR_COMPARE_DATE_H__ */ -- 2.49.0