From: Andrea Zagli Date: Sat, 24 Jul 2010 16:40:56 +0000 (+0200) Subject: Added and managed element "on-change" for GtkFormWidget on xml file definition. X-Git-Tag: 0.1.4~7 X-Git-Url: https://saetta.ns0.it/gitweb?a=commitdiff_plain;h=3c249db55cfdf3724be4bdcd1ad32bb6482e1af2;p=libgtkform Added and managed element "on-change" for GtkFormWidget on xml file definition. Added function GtkFormWidget::add_on_change_op. Added structs GtkFormWidgetOnChangeOp and GtkFormWidgetOnChangeOpUpdate. Added enums GtkFormWidgetOnChangeOpType and GtkFormWidgetOnChangeOpUpdateWhen. Added property "form" to GtkFormWidget. --- diff --git a/data/gtkform.dtd b/data/gtkform.dtd index c84d859..c0e1c82 100644 --- a/data/gtkform.dtd +++ b/data/gtkform.dtd @@ -4,7 +4,7 @@ - + + + + + + +
diff --git a/docs/reference/libgtkform-decl.txt b/docs/reference/libgtkform-decl.txt index a3438a0..7751923 100644 --- a/docs/reference/libgtkform-decl.txt +++ b/docs/reference/libgtkform-decl.txt @@ -345,6 +345,27 @@ GtkFormWidget *fwidget, gboolean editable void GtkFormWidget *fwidget, gboolean visible + +GtkFormWidgetOnChangeOpType +typedef enum +{ + GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE +} GtkFormWidgetOnChangeOpType; + + +GtkFormWidgetOnChangeOpUpdateWhen +typedef enum +{ + GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_BEFORE, + GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_AFTER, + GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_BOTH +} GtkFormWidgetOnChangeOpUpdateWhen; + + +gtk_form_widget_add_on_change_op +void +GtkFormWidget *fwidget, GtkFormWidgetOnChangeOp *op + TYPE_GTK_FORM_FIELD_TEXT #define TYPE_GTK_FORM_FIELD_TEXT (gtk_form_field_text_get_type ()) diff --git a/docs/reference/libgtkform-undocumented.txt b/docs/reference/libgtkform-undocumented.txt index 61c36d7..a2b03d3 100644 --- a/docs/reference/libgtkform-undocumented.txt +++ b/docs/reference/libgtkform-undocumented.txt @@ -1,7 +1,7 @@ 8% symbol docs coverage. -25 symbols documented. +27 symbols documented. 2 symbols incomplete. -304 not documented. +305 not documented. GTK_FORM @@ -232,6 +232,7 @@ gtk_form_set_sensitive gtk_form_set_sensitive_by_name gtk_form_set_table gtk_form_set_visible_by_name +gtk_form_widget_add_on_change_op gtk_form_widget_check_get_type gtk_form_widget_check_get_value_stringify gtk_form_widget_check_new diff --git a/docs/reference/libgtkform-unused.txt b/docs/reference/libgtkform-unused.txt index 65b2d4e..3cb8dad 100644 --- a/docs/reference/libgtkform-unused.txt +++ b/docs/reference/libgtkform-unused.txt @@ -1,6 +1,8 @@ GTK_FORM_WIDGET_RADIO GTK_FORM_WIDGET_RADIO_CLASS GTK_FORM_WIDGET_RADIO_GET_CLASS +GtkFormWidgetOnChangeOpType +GtkFormWidgetOnChangeOpUpdateWhen GtkFormWidgetRadio GtkFormWidgetRadioClass IS_GTK_FORM_WIDGET_RADIO @@ -57,6 +59,7 @@ gtk_form_set_key gtk_form_set_sensitive_by_name gtk_form_set_table gtk_form_set_visible_by_name +gtk_form_widget_add_on_change_op gtk_form_widget_combo_box_fill_from_datamodel gtk_form_widget_combo_box_fill_from_sql gtk_form_widget_get_label diff --git a/docs/reference/libgtkform.args b/docs/reference/libgtkform.args index 3859680..671dc7b 100644 --- a/docs/reference/libgtkform.args +++ b/docs/reference/libgtkform.args @@ -168,6 +168,26 @@ "" + +GtkFormWidget::form +GtkForm* + +rw +GtkForm +The GtkForm. + + + + +GtkFormWidget::label +GtkWidget* + +rw +GtkLabel +The GtkLabel. + + + GtkFormWidget::widget GtkWidget* diff --git a/docs/reference/tmpl/widget.sgml b/docs/reference/tmpl/widget.sgml index 71fa31e..7357bec 100644 --- a/docs/reference/tmpl/widget.sgml +++ b/docs/reference/tmpl/widget.sgml @@ -73,6 +73,16 @@ FormWidget + + + + + + + + + + diff --git a/src/form.c b/src/form.c index 855d799..c3fed8e 100644 --- a/src/form.c +++ b/src/form.c @@ -57,6 +57,8 @@ enum static void gtk_form_class_init (GtkFormClass *class); static void gtk_form_init (GtkForm *form); +static void parse_widget_on_change (GtkForm *form, xmlNodePtr xnode, GtkFormWidget *fwidget); + static void gtk_form_set_property (GObject *object, guint property_id, const GValue *value, @@ -200,6 +202,69 @@ GtkForm return form; } +static void +parse_widget_on_change (GtkForm *form, xmlNodePtr xnode, GtkFormWidget *fwidget) +{ + gchar *what; + gchar *widget_name; + gchar *sql; + + xmlNodePtr child; + + what = (gchar *)xmlGetProp (xnode, (const xmlChar *)"what"); + + g_return_if_fail (what != NULL); + + if (g_strcmp0 (what, "update") == 0) + { + child = xnode->children; + while (child != NULL) + { + if (xmlStrcmp (child->name, (const xmlChar *)"widget-name") == 0) + { + widget_name = (gchar *)xmlNodeGetContent (child); + } + else if (xmlStrcmp (child->name, (const xmlChar *)"sql") == 0) + { + sql = (gchar *)xmlNodeGetContent (child); + } + + child = child->next; + } + + if (sql != NULL && g_strcmp0 (g_strstrip (sql), "") != 0) + { + GtkFormWidgetOnChangeOpUpdate *op = (GtkFormWidgetOnChangeOpUpdate *)g_malloc0 (sizeof (GtkFormWidgetOnChangeOpUpdate)); + op->op.type = GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE; + if (widget_name != NULL && g_strcmp0 (g_strstrip (widget_name), "") != 0) + { + op->form_widget_name = g_strdup (widget_name); + } + op->sql = g_strdup (sql); + + gchar *when = (gchar *)xmlGetProp (xnode, (const xmlChar *)"when"); + if (when == NULL) + { + op->when = GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_BOTH; + } + else if (g_strcmp0 (when, "before") == 0) + { + op->when = GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_BEFORE; + } + else if (g_strcmp0 (when, "after") == 0) + { + op->when = GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_AFTER; + } + else + { + op->when = GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_BOTH; + } + + gtk_form_widget_add_on_change_op (fwidget, (GtkFormWidgetOnChangeOp *)op); + } + } +} + /** * gtk_form_load_from_xml: * @form: @@ -329,6 +394,8 @@ gtk_form_load_from_xml (GtkForm *form, xmlDoc *xmldoc, GtkBuilder *gtkbuilder) if (widget != NULL) { + g_object_set (G_OBJECT (widget), "form", form, NULL); + name = xmlGetProp (cur, (const xmlChar *)"name"); if (GTK_IS_BUILDER (priv->gtkbuilder)) @@ -380,6 +447,10 @@ gtk_form_load_from_xml (GtkForm *form, xmlDoc *xmldoc, GtkBuilder *gtkbuilder) g_object_set (G_OBJECT (widget), "return-value", xmlNodeGetContent (node_widget), NULL); } + else if (xmlStrcmp (node_widget->name, (const xmlChar *)"on-change") == 0) + { + parse_widget_on_change (form, node_widget, widget); + } else if (xmlStrcmp (node_widget->name, (const xmlChar *)"field") == 0) { field = NULL; diff --git a/src/widget.c b/src/widget.c index 92fb30c..a2a8067 100644 --- a/src/widget.c +++ b/src/widget.c @@ -24,11 +24,17 @@ #include +#include + +#include + +#include "form.h" #include "widget.h" enum { PROP_0, + PROP_FORM, PROP_WIDGET, PROP_NAME, PROP_LABEL @@ -51,10 +57,13 @@ static void gtk_form_widget_get_property (GObject *object, typedef struct _GtkFormWidgetPrivate GtkFormWidgetPrivate; struct _GtkFormWidgetPrivate { + GtkForm *form; GtkWidget *widget; gchar *widget_name; GtkWidget *label; + + GSList *on_change_ops; /* GtkFormOnChangeOp */ }; @@ -72,6 +81,13 @@ gtk_form_widget_class_init (GtkFormWidgetClass *klass) object_class->set_property = gtk_form_widget_set_property; object_class->get_property = gtk_form_widget_get_property; + g_object_class_install_property (object_class, PROP_FORM, + g_param_spec_object ("form", + "GtkForm", + "The GtkForm", + TYPE_GTK_FORM, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_WIDGET, g_param_spec_object ("widget", "GtkWidget", @@ -101,9 +117,11 @@ gtk_form_widget_init (GtkFormWidget *gtk_form_widget) { GtkFormWidgetPrivate *priv = GTK_FORM_WIDGET_GET_PRIVATE (gtk_form_widget); + priv->form = NULL; priv->widget = NULL; priv->widget_name = NULL; priv->label = NULL; + priv->on_change_ops = NULL; } /** @@ -253,6 +271,93 @@ gchar return ret; } +static void +execute_on_change_op (GtkFormWidget *fwidget, GtkFormWidgetOnChangeOpUpdate *op) +{ + GtkFormWidgetPrivate *priv; + GdaEx *gdaex; + + GObject *res; + GdaConnection *gdacon; + GdaSqlParser *parser; + GdaStatement *stmt; + GdaSet *params; + GSList *hs; + GdaHolder *h; + GValue *gval; + GError *error; + + g_return_if_fail (IS_GTK_FORM_WIDGET (fwidget)); + + priv = GTK_FORM_WIDGET_GET_PRIVATE (fwidget); + + gdaex = NULL; + + g_object_get (G_OBJECT (priv->form), "gdaex", &gdaex, NULL); + if (IS_GDAEX (gdaex)) + { + gdacon = (GdaConnection *)gdaex_get_gdaconnection (gdaex); + parser = gda_connection_create_parser (gdacon); + if (parser == NULL) + { + parser = gda_sql_parser_new (); + } + + error == NULL; + stmt = gda_sql_parser_parse_string (parser, op->sql, NULL, &error); + if (stmt == NULL) + { + g_warning (_("Error on parsing sql string: %s\n%s"), op->sql, + (error != NULL && error->message != NULL ? error->message : "no details")); + } + else + { + gda_statement_get_parameters (stmt, ¶ms, NULL); + if (params != NULL) + { + hs = params->holders; + while (hs != NULL) + { + h = (GdaHolder *)hs->data; + + if (GDA_IS_HOLDER (h)) + { + gval = gda_value_new_from_string (gtk_form_widget_get_value_stringify (gtk_form_get_form_widget_from_name (priv->form, gda_holder_get_id (h))), gda_holder_get_g_type (h)); + + error = NULL; + if (!gda_holder_set_value (h, gval, &error)) + { + g_warning (_("Error on setting holder's value: %s"), + (error != NULL && error->message != NULL ? error->message : "no details")); + } + } + hs = g_slist_next (hs); + } + } + + error = NULL; + res = gda_connection_statement_execute (gdacon, stmt, params, + GDA_STATEMENT_MODEL_RANDOM_ACCESS, + NULL, &error); + + if (res == NULL) + { + g_warning (_("Error on executing GtkFormWidgetOnChangeOp: %s"), + (error != NULL && error->message != NULL ? error->message : "no details")); + } + else if (GDA_IS_DATA_MODEL (res) && gda_data_model_get_n_rows ((GdaDataModel *)res) == 1) + { + gtk_form_widget_set_value_stringify (gtk_form_get_form_widget_from_name (priv->form, op->form_widget_name), + gdaex_data_model_get_value_stringify_at ((GdaDataModel *)res, 0, 0)); + } + } + } + else + { + g_warning (_("No GdaEx object inside GtkFormWidget.")); + } +} + /** * gtk_form_widget_set_value_stringify: * @fwidget: a #GtkFormWidget object. @@ -263,12 +368,64 @@ gboolean gtk_form_widget_set_value_stringify (GtkFormWidget *fwidget, const gchar *value) { gboolean ret; + GSList *ops; + GtkFormWidgetOnChangeOp *op; + + GtkFormWidgetPrivate *priv; + + g_return_val_if_fail (IS_GTK_FORM_WIDGET (fwidget), FALSE); + + priv = GTK_FORM_WIDGET_GET_PRIVATE (fwidget); - if (IS_GTK_FORM_WIDGET (fwidget) && GTK_FORM_WIDGET_GET_CLASS (fwidget)->set_value_stringify != NULL) + ops = priv->on_change_ops; + while (ops != NULL) + { + op = (GtkFormWidgetOnChangeOp *)ops->data; + switch (op->type) + { + case GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE: + { + GtkFormWidgetOnChangeOpUpdate *op_update = (GtkFormWidgetOnChangeOpUpdate *)op; + if (IS_GTK_FORM (priv->form) + && (op_update->when == GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_BEFORE + || op_update->when == GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_BOTH)) + { + execute_on_change_op (fwidget, op_update); + } + } + break; + } + + ops = g_slist_next (ops); + } + + if (GTK_FORM_WIDGET_GET_CLASS (fwidget)->set_value_stringify != NULL) { ret = GTK_FORM_WIDGET_GET_CLASS (fwidget)->set_value_stringify (fwidget, value); } + ops = priv->on_change_ops; + while (ops != NULL) + { + op = (GtkFormWidgetOnChangeOp *)ops->data; + switch (op->type) + { + case GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE: + { + GtkFormWidgetOnChangeOpUpdate *op_update = (GtkFormWidgetOnChangeOpUpdate *)op; + if (IS_GTK_FORM (priv->form) + && (op_update->when == GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_AFTER + || op_update->when == GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_BOTH)) + { + execute_on_change_op (fwidget, op_update); + } + } + break; + } + + ops = g_slist_next (ops); + } + return ret; } @@ -320,6 +477,30 @@ gtk_form_widget_set_visible (GtkFormWidget *fwidget, gboolean visible) } } +/** + * gtk_form_widget_add_on_change_op: + * @fwidget: + * @op: + * + */ +void +gtk_form_widget_add_on_change_op (GtkFormWidget *fwidget, GtkFormWidgetOnChangeOp *op) +{ + GtkFormWidgetPrivate *priv; + + g_return_if_fail (IS_GTK_FORM_WIDGET (fwidget)); + g_return_if_fail (op != NULL); + + priv = GTK_FORM_WIDGET_GET_PRIVATE (fwidget); + + switch (op->type) + { + case GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE: + priv->on_change_ops = g_slist_append (priv->on_change_ops, g_memdup (op, sizeof (GtkFormWidgetOnChangeOpUpdate))); + break; + } +} + /* PRIVATE */ static void gtk_form_widget_set_property (GObject *object, @@ -333,6 +514,10 @@ gtk_form_widget_set_property (GObject *object, switch (property_id) { + case PROP_FORM: + priv->form = g_value_get_object (value); + break; + case PROP_WIDGET: priv->widget = g_value_get_object (value); break; @@ -363,6 +548,10 @@ gtk_form_widget_get_property (GObject *object, switch (property_id) { + case PROP_FORM: + g_value_set_object (value, priv->form); + break; + case PROP_WIDGET: g_value_set_object (value, priv->widget); break; diff --git a/src/widget.h b/src/widget.h index d24b959..052284d 100644 --- a/src/widget.h +++ b/src/widget.h @@ -76,6 +76,33 @@ void gtk_form_widget_set_editable (GtkFormWidget *fwidget, gboolean editable); void gtk_form_widget_set_visible (GtkFormWidget *fwidget, gboolean visible); +typedef enum +{ + GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE +} GtkFormWidgetOnChangeOpType; + +typedef struct +{ + GtkFormWidgetOnChangeOpType type; +} GtkFormWidgetOnChangeOp; + +typedef enum +{ + GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_BEFORE, + GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_AFTER, + GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE_BOTH +} GtkFormWidgetOnChangeOpUpdateWhen; + +typedef struct +{ + GtkFormWidgetOnChangeOp op; + gchar *form_widget_name; + gchar *sql; + GtkFormWidgetOnChangeOpUpdateWhen when; +} GtkFormWidgetOnChangeOpUpdate; + +void gtk_form_widget_add_on_change_op (GtkFormWidget *fwidget, GtkFormWidgetOnChangeOp *op); + G_END_DECLS diff --git a/src/widgetcombobox.c b/src/widgetcombobox.c index ae1b2e9..0e52d58 100644 --- a/src/widgetcombobox.c +++ b/src/widgetcombobox.c @@ -267,11 +267,25 @@ gtk_form_widget_combo_box_fill_from_datamodel (GtkFormWidget *fwidget, GdaDataMo void gtk_form_widget_combo_box_fill_from_sql (GtkFormWidget *fwidget, GdaEx *gdaex, const gchar *sql, gboolean with_empty_entry) { + GdaEx *real_gdaex; GdaDataModel *dm; - g_return_if_fail (IS_GDAEX (gdaex)); + real_gdaex = NULL; - dm = gdaex_query (gdaex, sql); + if (IS_GDAEX (gdaex)) + { + real_gdaex = gdaex; + } + else + { + g_object_get (G_OBJECT (fwidget), + "gdaex", &real_gdaex, + NULL); + } + + g_return_if_fail (real_gdaex != NULL); + + dm = gdaex_query (real_gdaex, sql); gtk_form_widget_combo_box_fill_from_datamodel (fwidget, dm, with_empty_entry); }