]> saetta.ns0.it Git - libgtkform/commitdiff
Added and managed element "on-change" for GtkFormWidget on xml file definition.
authorAndrea Zagli <azagli@libero.it>
Sat, 24 Jul 2010 16:40:56 +0000 (18:40 +0200)
committerAndrea Zagli <azagli@libero.it>
Sat, 24 Jul 2010 16:40:56 +0000 (18:40 +0200)
Added function GtkFormWidget::add_on_change_op.
Added structs GtkFormWidgetOnChangeOp and GtkFormWidgetOnChangeOpUpdate.
Added enums GtkFormWidgetOnChangeOpType and GtkFormWidgetOnChangeOpUpdateWhen.
Added property "form" to GtkFormWidget.

data/gtkform.dtd
docs/reference/libgtkform-decl-list.txt
docs/reference/libgtkform-decl.txt
docs/reference/libgtkform-undocumented.txt
docs/reference/libgtkform-unused.txt
docs/reference/libgtkform.args
docs/reference/tmpl/widget.sgml
src/form.c
src/widget.c
src/widget.h
src/widgetcombobox.c

index c84d85968f6eade772908928b17961fc4beae1c4..c0e1c82288bcb33203da97f363b0218c15ec2a7a 100644 (file)
@@ -4,7 +4,7 @@
 
 <!ELEMENT table (#PCDATA)>
 
-<!ELEMENT widget (column-field?, sql?, return-value?, field?)>
+<!ELEMENT widget (column-field?, sql?, return-value?, on-change*, field?)>
 
 <!ATTLIST widget
        type  (checkbox | combobox | entry | label | radio | spin | textview)  #REQUIRED
 
 <!ELEMENT return-value (#PCDATA)>
 
+<!ELEMENT on-change (widget-name?, sql, when?)>
+
+<!ATTLIST on-change
+       what (update) #REQUIRED
+       when (before | after | both) #IMPLIED
+>
+
+<!ELEMENT widget-name (#PCDATA)>
+
 <!ELEMENT field (to-load?, to-save?, obligatory?, default?, is-key?, auto-increment?, datetime-type?, display-format?)>
 
 <!ATTLIST field
index ac8676bc874169ea1537e55e192ba4ad715706fb..a307ffdcff8ec280cc33f37c38d170f69002a6da 100644 (file)
@@ -81,6 +81,9 @@ gtk_form_widget_get_value_stringify
 gtk_form_widget_set_value_stringify
 gtk_form_widget_set_editable
 gtk_form_widget_set_visible
+GtkFormWidgetOnChangeOpType
+GtkFormWidgetOnChangeOpUpdateWhen
+gtk_form_widget_add_on_change_op
 </SECTION>
 
 <SECTION>
index a3438a0a65b6e0985088817efdbfc26eccd511a6..7751923e1442a96644b500f27c87591c389bce0d 100644 (file)
@@ -345,6 +345,27 @@ GtkFormWidget *fwidget, gboolean editable
 <RETURNS>void </RETURNS>
 GtkFormWidget *fwidget, gboolean visible 
 </FUNCTION>
+<ENUM>
+<NAME>GtkFormWidgetOnChangeOpType</NAME>
+typedef enum
+{
+       GTK_FORM_WIDGET_ON_CHANGE_OP_UPDATE
+} GtkFormWidgetOnChangeOpType;
+</ENUM>
+<ENUM>
+<NAME>GtkFormWidgetOnChangeOpUpdateWhen</NAME>
+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;
+</ENUM>
+<FUNCTION>
+<NAME>gtk_form_widget_add_on_change_op</NAME>
+<RETURNS>void </RETURNS>
+GtkFormWidget *fwidget, GtkFormWidgetOnChangeOp *op 
+</FUNCTION>
 <MACRO>
 <NAME>TYPE_GTK_FORM_FIELD_TEXT</NAME>
 #define TYPE_GTK_FORM_FIELD_TEXT                 (gtk_form_field_text_get_type ())
index 61c36d7875960605d9b62a0636c16f18f796a898..a2b03d3b3190e1b1277dcf0f34a07b25035c4d8d 100644 (file)
@@ -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
index 65b2d4ed52c3b69f3c3d303750a02ed401ec8b08..3cb8dad475507458dc0c9ba04f73b26d3fd572cf 100644 (file)
@@ -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
index 3859680af6aa0c1b103cae549787da9f25ce1cb8..671dc7b92b59561bb628c535eb1459efb541ab84 100644 (file)
 <DEFAULT>""</DEFAULT>
 </ARG>
 
+<ARG>
+<NAME>GtkFormWidget::form</NAME>
+<TYPE>GtkForm*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>GtkForm</NICK>
+<BLURB>The GtkForm.</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GtkFormWidget::label</NAME>
+<TYPE>GtkWidget*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>GtkLabel</NICK>
+<BLURB>The GtkLabel.</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
 <ARG>
 <NAME>GtkFormWidget::widget</NAME>
 <TYPE>GtkWidget*</TYPE>
index 71fa31eb0c6ee493c1d3bf0efe8ffe4d6065930f..7357bec7e0a22775ce4c894af0ed403ca2437239 100644 (file)
@@ -73,6 +73,16 @@ FormWidget
 </para>
 
 
+<!-- ##### ARG GtkFormWidget:form ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkFormWidget:label ##### -->
+<para>
+
+</para>
+
 <!-- ##### ARG GtkFormWidget:widget ##### -->
 <para>
 
index 855d799dcad1aa407176948381703dfae7bf58ae..c3fed8eefa1a26fabbae8a8d98d50007039d8d53 100644 (file)
@@ -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;
index 92fb30c73fb9d47824297ba2f0e4e0e42e910da6..a2a80672154cd1c304f9c3b31055452cef51dafa 100644 (file)
 
 #include <gtk/gtk.h>
 
+#include <sql-parser/gda-sql-parser.h>
+
+#include <libgdaex.h>
+
+#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, &params, 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;
index d24b959fc76d4a4e0b140abb01086a2385c0c1fc..052284dfcbc6988223d08963dab7106a26951e9f 100644 (file)
@@ -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
 
index ae1b2e95b61218610289d0145702f297598cdff1..0e52d582e9edc6f9495dc768357f2ba0e53b6c57 100644 (file)
@@ -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);
 }