From a8070efbcb6ae653c8e31004f14a4baf9da38e0d Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Mon, 4 Apr 2011 18:20:47 +0200 Subject: [PATCH] Added and implemented min-value and max-values field's properties. For now only for GtkFormFieldDateTime. --- data/gtkform.dtd | 4 +- src/field.c | 77 +++++++++++++++++++---- src/field.h | 3 + src/fielddatetime.c | 149 ++++++++++++++++++++++++++++++++++++++++++-- src/fielddatetime.h | 4 +- src/form.c | 45 ++++++++----- test/database.db | Bin 2048 -> 2048 bytes test/test_db.xml | 3 + 8 files changed, 251 insertions(+), 34 deletions(-) diff --git a/data/gtkform.dtd b/data/gtkform.dtd index 93f10d9..cc91902 100644 --- a/data/gtkform.dtd +++ b/data/gtkform.dtd @@ -31,7 +31,7 @@ - + + + diff --git a/src/field.c b/src/field.c index ddc4ad5..1b72ca8 100644 --- a/src/field.c +++ b/src/field.c @@ -29,8 +29,10 @@ enum PROP_OBLIGATORY, PROP_AUTO_INCREMENT, PROP_DATAMODEL, + PROP_TRIM, PROP_WIDGET, - PROP_TRIM + PROP_MIN_VALUE, + PROP_MAX_VALUE }; static void gtk_form_field_class_init (GtkFormFieldClass *klass); @@ -58,6 +60,8 @@ struct _GtkFormFieldPrivate gboolean obligatory; gboolean auto_increment; gboolean trim; + gchar *min_value; + gchar *max_value; GdaDataModel *dm; @@ -98,35 +102,35 @@ gtk_form_field_class_init (GtkFormFieldClass *klass) "Whether load the field or not", "Whether the field should be included or not on sql SELECT", TRUE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (object_class, PROP_TO_SAVE, g_param_spec_boolean ("to-save", "Whether save the field or not", "Whether the field should be included or not on sql INSERT INTO and UPDATE", TRUE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (object_class, PROP_OBLIGATORY, g_param_spec_boolean ("obligatory", "Obligatory", "Whether the field could be empty", FALSE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (object_class, PROP_AUTO_INCREMENT, g_param_spec_boolean ("auto-increment", "Auto increment", "Whether the field auto increments (works only on numeric fields)", FALSE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (object_class, PROP_TRIM, g_param_spec_boolean ("trim", "Trim stringify value", "Whether to trim the field's stringify value", FALSE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (object_class, PROP_WIDGET, g_param_spec_object ("form-widget", @@ -135,6 +139,20 @@ gtk_form_field_class_init (GtkFormFieldClass *klass) TYPE_GTK_FORM_WIDGET, G_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_MIN_VALUE, + g_param_spec_string ("min-value", + "Minimun value", + "The minimun value allowed for this field.", + "", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (object_class, PROP_MAX_VALUE, + g_param_spec_string ("max-value", + "Maximun value", + "The macimun value allowed for this field.", + "", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_type_class_add_private (object_class, sizeof (GtkFormFieldPrivate)); } @@ -398,6 +416,25 @@ gtk_form_field_is_empty (GtkFormField *field) return ret; } +/** + * gtk_form_field_is_valid: + * @field: a #GtkFormField object. + * + * Returns: TRUE if the field is valid. + */ +gboolean +gtk_form_field_is_valid (GtkFormField *field) +{ + gboolean ret = TRUE; + + if (IS_GTK_FORM_FIELD (field) && GTK_FORM_FIELD_GET_CLASS (field)->is_valid != NULL) + { + ret = GTK_FORM_FIELD_GET_CLASS (field)->is_valid (field); + } + + return ret; +} + /** * gtk_form_field_is_changed: * @field: a #GtkFormField object. @@ -543,19 +580,27 @@ gtk_form_field_set_property (GObject *object, priv->dm = g_value_get_pointer (value); break; + case PROP_TRIM: + priv->trim = g_value_get_boolean (value); + break; + case PROP_WIDGET: priv->widget = g_value_get_object (value); g_object_set (G_OBJECT (priv->widget), "field", field, NULL); break; - case PROP_TRIM: - priv->trim = g_value_get_boolean (value); + case PROP_MIN_VALUE: + priv->min_value = g_strstrip (g_value_dup_string (value)); + break; + + case PROP_MAX_VALUE: + priv->max_value = g_strstrip (g_value_dup_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; - } + } } static void @@ -598,16 +643,24 @@ gtk_form_field_get_property (GObject *object, g_value_set_pointer (value, priv->dm); break; + case PROP_TRIM: + g_value_set_boolean (value, priv->trim); + break; + case PROP_WIDGET: g_value_set_object (value, priv->widget); break; - case PROP_TRIM: - g_value_set_boolean (value, priv->trim); + case PROP_MIN_VALUE: + g_value_set_string (value, g_strdup (priv->min_value)); + break; + + case PROP_MAX_VALUE: + g_value_set_string (value, g_strdup (priv->max_value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; - } + } } diff --git a/src/field.h b/src/field.h index 680a174..92b8d36 100644 --- a/src/field.h +++ b/src/field.h @@ -57,6 +57,7 @@ struct _GtkFormFieldClass gboolean (*clear) (GtkFormField *field); gboolean (*is_empty) (GtkFormField *field); gboolean (*is_changed) (GtkFormField *field); + gboolean (*is_valid) (GtkFormField *field); void (*set_as_origin) (GtkFormField *field); gboolean (*set_from_datamodel) (GtkFormField *field, GdaDataModel *dm, gint row); gboolean (*set_from_hashtable) (GtkFormField *field, GHashTable *hashtable); @@ -87,6 +88,8 @@ gboolean gtk_form_field_is_auto_increment (GtkFormField *field); gboolean gtk_form_field_is_empty (GtkFormField *field); +gboolean gtk_form_field_is_valid (GtkFormField *field); + gboolean gtk_form_field_is_changed (GtkFormField *field); void gtk_form_field_set_as_origin (GtkFormField *field); diff --git a/src/fielddatetime.c b/src/fielddatetime.c index 504a823..62a7e52 100644 --- a/src/fielddatetime.c +++ b/src/fielddatetime.c @@ -57,7 +57,7 @@ static gchar *gtk_form_field_datetime_str_replace (const gchar *string, const gchar *origin, const gchar *replace); -static gboolean gtk_form_field_datetime_is_valid (GtkFormFieldDateTime *field); +static gboolean gtk_form_field_datetime_is_valid_datetime (GtkFormFieldDateTime *field); #define GTK_FORM_FIELD_DATETIME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_GTK_FORM_FIELD_DATETIME, GtkFormFieldDateTimePrivate)) @@ -91,6 +91,7 @@ gtk_form_field_datetime_class_init (GtkFormFieldDateTimeClass *klass) field_class->clear = gtk_form_field_datetime_clear; field_class->is_empty = gtk_form_field_datetime_is_empty; field_class->is_changed = gtk_form_field_datetime_is_changed; + field_class->is_valid = gtk_form_field_datetime_is_valid; field_class->set_as_origin = gtk_form_field_datetime_set_as_origin; field_class->set_from_datamodel = gtk_form_field_datetime_set_from_datamodel; field_class->set_from_hashtable = gtk_form_field_datetime_set_from_hashtable; @@ -324,7 +325,7 @@ gtk_form_field_datetime_is_empty (GtkFormField *field) g_return_val_if_fail (IS_GTK_FORM_FIELD_DATETIME (field), TRUE); - return !gtk_form_field_datetime_is_valid (GTK_FORM_FIELD_DATETIME (field)); + return !gtk_form_field_datetime_is_valid_datetime (GTK_FORM_FIELD_DATETIME (field)); } /** @@ -369,6 +370,136 @@ gtk_form_field_datetime_is_changed (GtkFormField *field) return ret; } +/** + * gtk_form_field_datetime_is_valid: + * @field: a #GtkFormField object. + * + */ +gboolean +gtk_form_field_datetime_is_valid (GtkFormField *field) +{ + gboolean ret; + + GtkFormFieldDateTimePrivate *priv; + + struct tm *tm_value; + + gchar *min_value; + struct tm *tm_min_value; + gchar *max_value; + struct tm *tm_max_value; + + g_return_val_if_fail (IS_GTK_FORM_FIELD_DATETIME (field), FALSE); + + ret = TRUE; + + priv = GTK_FORM_FIELD_DATETIME_GET_PRIVATE (GTK_FORM_FIELD_DATETIME (field)); + + tm_value = gtk_form_field_datetime_get_tm_from_str (gtk_form_field_datetime_get_value_stringify (field), priv->display_format); + + if (tm_value != NULL) + { + min_value = NULL; + max_value = NULL; + + g_object_get (G_OBJECT (field), + "min-value", &min_value, + "max-value", &max_value, + NULL); + + if (min_value != NULL + && g_strcmp0 (min_value, "") != 0) + { + if (g_strcasecmp (min_value, "now") == 0) + { + time_t tt; + tt = time (NULL); + + tm_min_value = g_memdup (localtime (&tt), sizeof (struct tm)); + + if (priv->type == GTK_FORM_FIELD_DATETIME_TYPE_DATE) + { + tm_min_value->tm_hour = 0; + tm_min_value->tm_min = 0; + tm_min_value->tm_sec = 0; + } + else if (priv->type == GTK_FORM_FIELD_DATETIME_TYPE_TIME) + { + tm_min_value->tm_year = 0; + tm_min_value->tm_mon = 0; + tm_min_value->tm_mday = 0; + } + } + else + { + tm_min_value = gtk_form_field_datetime_get_tm_from_str (min_value, + gtk_form_field_datetime_get_str_format (GTK_FORM_FIELD_DATETIME (field))); + } + + if (tm_min_value != NULL) + { + time_t tt_min_value; + time_t tt_value; + + tt_min_value = mktime (tm_min_value); + tt_value = mktime (tm_value); + + ret = (difftime (tt_min_value, tt_value) <= 0); + + g_free (tm_min_value); + } + } + + if (ret + && max_value != NULL + && g_strcmp0 (max_value, "") != 0) + { + if (g_strcasecmp (max_value, "now") == 0) + { + time_t tt; + tt = time (NULL); + + tm_max_value = g_memdup (localtime (&tt), sizeof (struct tm)); + + if (priv->type == GTK_FORM_FIELD_DATETIME_TYPE_DATE) + { + tm_max_value->tm_hour = 0; + tm_max_value->tm_min = 0; + tm_max_value->tm_sec = 0; + } + else if (priv->type == GTK_FORM_FIELD_DATETIME_TYPE_TIME) + { + tm_max_value->tm_year = 0; + tm_max_value->tm_mon = 0; + tm_max_value->tm_mday = 0; + } + } + else + { + tm_max_value = gtk_form_field_datetime_get_tm_from_str (max_value, + gtk_form_field_datetime_get_str_format (GTK_FORM_FIELD_DATETIME (field))); + } + + if (tm_max_value != NULL) + { + time_t tt_max_value; + time_t tt_value; + + tt_max_value = mktime (tm_max_value); + tt_value = mktime (tm_value); + + ret = (difftime (tt_max_value, tt_value) >= 0); + + g_free (tm_max_value); + } + } + + g_free (tm_value); + } + + return ret; +} + /** * gtk_form_field_datetime_set_as_origin: * @field: a #GtkFormField object. @@ -659,6 +790,12 @@ struct tm mktime (ret); } + /* mktime set tm_hour = 1 if tm_hour == 0 */ + if (g_strrstr (delimiters, "%H") == NULL) + { + ret->tm_hour = 0; + } + return ret; } @@ -769,13 +906,13 @@ gtk_form_field_datetime_set_property (GObject *object, break; case PROP_DISPLAY_FORMAT: - priv->display_format = g_strdup (g_value_get_string (value)); + priv->display_format = g_strstrip (g_value_dup_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; - } + } } static void @@ -805,7 +942,7 @@ gtk_form_field_datetime_get_property (GObject *object, default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; - } + } } static gboolean @@ -895,7 +1032,7 @@ static gchar } static gboolean -gtk_form_field_datetime_is_valid (GtkFormFieldDateTime *field) +gtk_form_field_datetime_is_valid_datetime (GtkFormFieldDateTime *field) { gboolean ret; diff --git a/src/fielddatetime.h b/src/fielddatetime.h index 6acfeac..4faee2c 100644 --- a/src/fielddatetime.h +++ b/src/fielddatetime.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Andrea Zagli + * Copyright (C) 2005-2011 Andrea Zagli * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -71,6 +71,8 @@ gboolean gtk_form_field_datetime_is_empty (GtkFormField *field); gboolean gtk_form_field_datetime_is_changed (GtkFormField *field); void gtk_form_field_datetime_set_as_origin (GtkFormField *field); +gboolean gtk_form_field_datetime_is_valid (GtkFormField *field); + gboolean gtk_form_field_datetime_set_from_datamodel (GtkFormField *field, GdaDataModel *dm, gint row); gboolean gtk_form_field_datetime_set_from_hashtable (GtkFormField *field, GHashTable *hashtable); gboolean gtk_form_field_datetime_set_value (GtkFormField *field, GValue *gvalue); diff --git a/src/form.c b/src/form.c index 368d5cc..cc6fe04 100644 --- a/src/form.c +++ b/src/form.c @@ -80,7 +80,8 @@ static void gtk_form_get_property (GObject *object, GParamSpec *pspec); static void gtk_form_show_check_error_dialog (GtkFormWidget *fwidget, - GtkWidget *parent_window); + GtkWidget *parent_window, + const gchar *message); #define GTK_FORM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_GTK_FORM, GtkFormPrivate)) @@ -237,7 +238,7 @@ gtkform_log_handler (const gchar *log_domain, if (g_output_stream_write (G_OUTPUT_STREAM (priv->log_file), msg, strlen (msg), NULL, &error) < 0) { - g_warning ("Error on writing on log file: %s", + g_warning (_("Error on writing on log file: %s"), error != NULL && error->message != NULL ? error->message : "no details."); } } @@ -271,7 +272,7 @@ gtkform_post_parse_options (GOptionContext *context, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &my_error); if (priv->log_file == NULL) { - g_warning ("Error on opening log file: %s.", + g_warning (_("Error on opening log file: %s."), my_error != NULL && my_error->message != NULL ? my_error->message : "no details."); } else @@ -758,8 +759,16 @@ gtk_form_load_from_xml (GtkForm *form, xmlDoc *xmldoc, GtkBuilder *gtkbuilder) else if (xmlStrcmp (node_field->name, (const xmlChar *)"trim") == 0) { g_object_set (G_OBJECT (field), - "trim", gtk_form_field_boolean_str_to_boolean (prop), - NULL); + "trim", gtk_form_field_boolean_str_to_boolean (prop), + NULL); + } + else if (xmlStrcmp (node_field->name, (const xmlChar *)"min-value") == 0) + { + g_object_set (G_OBJECT (field), "min-value", prop, NULL); + } + else if (xmlStrcmp (node_field->name, (const xmlChar *)"max-value") == 0) + { + g_object_set (G_OBJECT (field), "max-value", prop, NULL); } node_field = node_field->next; @@ -1361,6 +1370,8 @@ gtk_form_check (GtkForm *form, gboolean with_key, GtkFormWidget **form_widget, gboolean ret; gboolean to_save; gboolean obl; + gboolean is_empty; + gboolean is_valid; g_return_val_if_fail (IS_GTK_FORM (form), FALSE); @@ -1384,7 +1395,10 @@ gtk_form_check (GtkForm *form, gboolean with_key, GtkFormWidget **form_widget, "obligatory", &obl, NULL); - if (to_save && obl && gtk_form_field_is_empty (field)) + is_empty = gtk_form_field_is_empty (field); + is_valid = gtk_form_field_is_valid (field); + if (to_save + && ((obl && is_empty) || !is_valid)) { ret = FALSE; @@ -1398,7 +1412,8 @@ gtk_form_check (GtkForm *form, gboolean with_key, GtkFormWidget **form_widget, if (show_error_dialog) { - gtk_form_show_check_error_dialog (fwidget, parent_window); + gtk_form_show_check_error_dialog (fwidget, parent_window, + obl && is_empty ? _(" is obligatory") : _(" isn't valid")); } if (set_focus) @@ -1424,7 +1439,7 @@ gtk_form_check (GtkForm *form, gboolean with_key, GtkFormWidget **form_widget, if (!ret && key_form_widget != NULL && show_error_dialog) { - gtk_form_show_check_error_dialog (key_form_widget, parent_window); + gtk_form_show_check_error_dialog (key_form_widget, parent_window, _(" is obligatory")); } if (!ret && key_form_widget != NULL && set_focus) @@ -1471,7 +1486,7 @@ gtk_form_is_changed (GtkForm *form) { if (priv->debug > 0) { - g_message ("Field «%s» is changed.", gtk_form_field_get_field_name (field)); + g_debug (_("Field «%s» is changed."), gtk_form_field_get_field_name (field)); } break; } @@ -2343,7 +2358,9 @@ gtk_form_get_property (GObject *object, } static void -gtk_form_show_check_error_dialog (GtkFormWidget *fwidget, GtkWidget *parent_window) +gtk_form_show_check_error_dialog (GtkFormWidget *fwidget, + GtkWidget *parent_window, + const gchar *message) { GtkWidget *dialog; GtkWidget *label; @@ -2386,10 +2403,10 @@ gtk_form_show_check_error_dialog (GtkFormWidget *fwidget, GtkWidget *parent_wind } dialog = gtk_message_dialog_new (GTK_WINDOW (parent_window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_OK, - _("The field «%s» is obligatory."), label_text); + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + g_strdup_printf (_("The field «%s»%s"), label_text, message)); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } diff --git a/test/database.db b/test/database.db index 128b578fc52b4c12fe934caa5bbd64043cbcec39..3e5486bb09557dd64dbea3faa8619987de8e2cad 100644 GIT binary patch delta 126 zcmZn=Xb_kn&1g4K#+lJ>W5N<v2Y^OL;MjIxUCoD2{KZ%RrE12cnXi9%+vo}QkOfuW(U0SHb0%2ve7rplt=w)-$<| MU5X1y!3_2c08D%vaR2}S delta 131 zcmZn=Xb_kn&8R$4#+gxhW5N<<0XC+u3`}2{PczSCc4Ss(F4 + t + now + date %d/%m/%Y -- 2.49.0