From 5070972da664ebdbef31f3d26bf0a77665f15df1 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Wed, 13 May 2020 20:34:19 +0200 Subject: [PATCH] Added ZakFormElementValidatorIsNumber (implemented as regex). --- src/Makefile.am | 2 + src/formelementvalidatorisnumber.c | 345 +++++++++++++++++++++++++++++ src/formelementvalidatorisnumber.h | 51 +++++ 3 files changed, 398 insertions(+) create mode 100644 src/formelementvalidatorisnumber.c create mode 100644 src/formelementvalidatorisnumber.h diff --git a/src/Makefile.am b/src/Makefile.am index 7f121d8..50fdaf1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,6 +25,7 @@ libzakform_la_SOURCES = \ formelementfiltertrim.c \ formelementvalidator.c \ formelementvalidatordate.c \ + formelementvalidatorisnumber.c \ formelementvalidatornotempty.c \ formelementvalidatornumber.c \ formelementvalidatorregex.c \ @@ -49,6 +50,7 @@ gir_include = \ formelementfiltertrim.h \ formelementvalidator.h \ formelementvalidatordate.h \ + formelementvalidatorisnumber.h \ formelementvalidatornotempty.h \ formelementvalidatornumber.h \ formelementvalidatorregex.h \ diff --git a/src/formelementvalidatorisnumber.c b/src/formelementvalidatorisnumber.c new file mode 100644 index 0000000..c2e6f00 --- /dev/null +++ b/src/formelementvalidatorisnumber.c @@ -0,0 +1,345 @@ +/* + * Copyright (C) 2020 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 "formelementvalidator.h" +#include "formelementvalidatorisnumber.h" +#include "formelementvalidatorregex.h" + +static void zak_form_element_validator_is_number_class_init (ZakFormElementValidatorIsNumberClass *class); +static void zak_form_element_validator_is_number_init (ZakFormElementValidatorIsNumber *zak_form_element); + +static void zak_form_element_validator_is_number_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void zak_form_element_validator_is_number_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void zak_form_element_validator_is_number_dispose (GObject *gobject); +static void zak_form_element_validator_is_number_finalize (GObject *gobject); + +static gboolean zak_form_element_validator_is_number_xml_parsing (ZakFormElementValidator *validator, xmlNode *xnode); +static gboolean zak_form_element_validator_is_number_validate (ZakFormElementValidator *validator_is_number, const gchar *value); + +struct _ZakFormElementValidatorIsNumber +{ + ZakFormElementValidator parent_instance; + + /* Other members, including private data. */ +}; + +#define ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ZAK_FORM_TYPE_ELEMENT_VALIDATOR_IS_NUMBER, ZakFormElementValidatorIsNumberPrivate)) + +typedef struct _ZakFormElementValidatorIsNumberPrivate ZakFormElementValidatorIsNumberPrivate; +struct _ZakFormElementValidatorIsNumberPrivate + { + gchar decimals_separator; + gchar thousands_separator; + gboolean plusminus; + }; + +G_DEFINE_TYPE (ZakFormElementValidatorIsNumber, zak_form_element_validator_is_number, ZAK_FORM_TYPE_ELEMENT_VALIDATOR) + +static void +zak_form_element_validator_is_number_class_init (ZakFormElementValidatorIsNumberClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + ZakFormElementValidatorClass *parent_class = ZAK_FORM_ELEMENT_VALIDATOR_CLASS (class); + + object_class->set_property = zak_form_element_validator_is_number_set_property; + object_class->get_property = zak_form_element_validator_is_number_get_property; + object_class->dispose = zak_form_element_validator_is_number_dispose; + object_class->finalize = zak_form_element_validator_is_number_finalize; + + parent_class->xml_parsing = zak_form_element_validator_is_number_xml_parsing; + parent_class->validate = zak_form_element_validator_is_number_validate; + + g_type_class_add_private (object_class, sizeof (ZakFormElementValidatorIsNumberPrivate)); +} + +static void +zak_form_element_validator_is_number_init (ZakFormElementValidatorIsNumber *zak_form_element) +{ + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (zak_form_element); + + priv->decimals_separator = ','; + priv->thousands_separator = '.'; + priv->plusminus = TRUE; +} + +/** + * zak_form_element_validator_is_number_new: + * + * Returns: the newly created #ZakFormElementValidatorIsNumber object. + */ +ZakFormElementValidatorIsNumber +*zak_form_element_validator_is_number_new () +{ + ZakFormElementValidatorIsNumber *zak_form_element_validator_is_number; + + zak_form_element_validator_is_number = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER (g_object_new (zak_form_element_validator_is_number_get_type (), NULL)); + + return zak_form_element_validator_is_number; +} + +/** + * zak_form_element_validator_is_number_set_decimals_separator: + * @validator: + * @decimals_separator: + * + */ +void +zak_form_element_validator_is_number_set_decimals_separator (ZakFormElementValidatorIsNumber *validator, gchar decimals_separator) +{ + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER (validator)); + + priv->decimals_separator = decimals_separator; +} + +/** + * zak_form_element_validator_is_number_get_decimals_separator: + * @validator: + * + * Returns: the char for decimals separator. + */ +gchar +zak_form_element_validator_is_number_get_decimals_separator (ZakFormElementValidatorIsNumber *validator) +{ + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER (validator)); + + return priv->decimals_separator; +} + +/** + * zak_form_element_validator_is_number_set_thousands_separator: + * @validator: + * @thousands_separator: + * + */ +void +zak_form_element_validator_is_number_set_thousands_separator (ZakFormElementValidatorIsNumber *validator, gchar thousands_separator) +{ + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER (validator)); + + priv->thousands_separator = thousands_separator; +} + +/** + * zak_form_element_validator_is_number_get_thousands_separator: + * @validator: + * + * Returns: the char for thousands separator. + */ +gchar +zak_form_element_validator_is_number_get_thousands_separator (ZakFormElementValidatorIsNumber *validator) +{ + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER (validator)); + + return priv->thousands_separator; +} + +/** + * zak_form_element_validator_is_number_set_plusminus: + * @validator: + * @plusminus: + * + */ +void +zak_form_element_validator_is_number_set_plusminus (ZakFormElementValidatorIsNumber *validator, gboolean plusminus) +{ + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER (validator)); + + priv->plusminus = plusminus; +} + +/** + * zak_form_element_validator_is_number_get_plusminus: + * @validator: + * + * Returns: if plus/minus chars are accepted at the start of the number. + */ +gboolean +zak_form_element_validator_is_number_get_plusminus (ZakFormElementValidatorIsNumber *validator) +{ + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER (validator)); + + return priv->plusminus; +} + +/** + * zak_form_element_validator_is_number_xml_parsing: + * @validator: + * @xnode: + * + */ +static gboolean +zak_form_element_validator_is_number_xml_parsing (ZakFormElementValidator *validator, xmlNode *xnode) +{ + gchar *prop; + + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER (validator)); + + prop = (gchar *)xmlGetProp (xnode, (const xmlChar *)"thousands_separator"); + if (prop != NULL) + { + zak_form_element_validator_is_number_set_thousands_separator (ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER (validator), prop[0]); + } + g_free (prop); + + prop = (gchar *)xmlGetProp (xnode, (const xmlChar *)"decimals_separator"); + if (prop != NULL) + { + zak_form_element_validator_is_number_set_decimals_separator (ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER (validator), prop[0]); + } + g_free (prop); + + prop = (gchar *)xmlGetProp (xnode, (const xmlChar *)"plusminus"); + if (prop != NULL) + { + zak_form_element_validator_is_number_set_plusminus (ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER (validator), + xmlStrEqual (prop, (const xmlChar *)"TRUE")); + } + g_free (prop); + + return TRUE; +} + +/* PRIVATE */ +static void +zak_form_element_validator_is_number_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ZakFormElementValidatorIsNumber *zak_form_element = (ZakFormElementValidatorIsNumber *)object; + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (zak_form_element); + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +zak_form_element_validator_is_number_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ZakFormElementValidatorIsNumber *zak_form_element = (ZakFormElementValidatorIsNumber *)object; + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (zak_form_element); + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +zak_form_element_validator_is_number_dispose (GObject *gobject) +{ + ZakFormElementValidatorIsNumber *zak_form_element = (ZakFormElementValidatorIsNumber *)gobject; + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (zak_form_element); + + + + GObjectClass *parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (gobject)); + parent_class->dispose (gobject); +} + +static void +zak_form_element_validator_is_number_finalize (GObject *gobject) +{ + ZakFormElementValidatorIsNumber *zak_form_element = (ZakFormElementValidatorIsNumber *)gobject; + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (zak_form_element); + + GObjectClass *parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (gobject)); + parent_class->finalize (gobject); +} + +static gboolean +zak_form_element_validator_is_number_validate (ZakFormElementValidator *validator_is_number, + const gchar *value) +{ + gchar *_value; + + GString *regex; + + gchar *tesc; + gchar *desc; + + ZakFormElementValidatorRegex *validator; + + ZakFormElementValidatorIsNumberPrivate *priv = ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_GET_PRIVATE (validator_is_number); + + g_return_val_if_fail (value != NULL, FALSE); + + _value = g_strstrip (g_strdup (value)); + validator = zak_form_element_validator_regex_new (); + + regex = g_string_new ("^"); + + if (priv->plusminus) + { + g_string_append (regex, "[+-]?"); + } + + if (priv->thousands_separator == '.') + { + tesc = g_strdup ("\\."); + } + else + { + tesc = g_strdup_printf ("%c", priv->thousands_separator); + } + + if (priv->decimals_separator == '.') + { + desc = g_strdup ("\\."); + } + else + { + desc = g_strdup_printf ("%c", priv->decimals_separator); + } + + g_string_append_printf (regex, + "\\d{1,3}(%s\\d{3})*(%s\\d+)?$|^[+-]?\\d+(%s\\d+)?$", + tesc, + desc, + desc); + + zak_form_element_validator_regex_set_regex (validator, regex->str); + + g_string_free (regex, TRUE); + + return zak_form_element_validator_validate (ZAK_FORM_ELEMENT_VALIDATOR (validator), _value); +} diff --git a/src/formelementvalidatorisnumber.h b/src/formelementvalidatorisnumber.h new file mode 100644 index 0000000..b061e33 --- /dev/null +++ b/src/formelementvalidatorisnumber.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 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_ELEMENT_VALIDATOR_IS_NUMBER_H__ +#define __ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_H__ + + +#include + +#include + +#include "commons.h" +#include "formelementvalidator.h" + + +G_BEGIN_DECLS + + +#define ZAK_FORM_TYPE_ELEMENT_VALIDATOR_IS_NUMBER zak_form_element_validator_is_number_get_type () +G_DECLARE_FINAL_TYPE (ZakFormElementValidatorIsNumber, zak_form_element_validator_is_number, ZAK_FORM, ELEMENT_VALIDATOR_IS_NUMBER, ZakFormElementValidator) + +ZakFormElementValidatorIsNumber *zak_form_element_validator_is_number_new (void); + +void zak_form_element_validator_is_number_set_decimals_separator (ZakFormElementValidatorIsNumber *validator, gchar decimals_separator); +gchar zak_form_element_validator_is_number_get_decimals_separator (ZakFormElementValidatorIsNumber *validator); + +void zak_form_element_validator_is_number_set_thousands_separator (ZakFormElementValidatorIsNumber *validator, gchar thousands_separator); +gchar zak_form_element_validator_is_number_get_thousands_separator (ZakFormElementValidatorIsNumber *validator); + +void zak_form_element_validator_is_number_set_plusminus (ZakFormElementValidatorIsNumber *validator, gboolean plusminus); +gboolean zak_form_element_validator_is_number_get_plusminus (ZakFormElementValidatorIsNumber *validator); + +G_END_DECLS + + +#endif /* __ZAK_FORM_ELEMENT_VALIDATOR_IS_NUMBER_H__ */ -- 2.49.0