Added function GtkFormWidget::add_on_change_op.
Added structs GtkFormWidgetOnChangeOp and GtkFormWidgetOnChangeOpUpdate.
Added enums GtkFormWidgetOnChangeOpType and GtkFormWidgetOnChangeOpUpdateWhen.
Added property "form" to GtkFormWidget.
<!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
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>
<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 ())
8% symbol docs coverage.
-25 symbols documented.
+27 symbols documented.
2 symbols incomplete.
-304 not documented.
+305 not documented.
GTK_FORM
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
GTK_FORM_WIDGET_RADIO
GTK_FORM_WIDGET_RADIO_CLASS
GTK_FORM_WIDGET_RADIO_GET_CLASS
+GtkFormWidgetOnChangeOpType
+GtkFormWidgetOnChangeOpUpdateWhen
GtkFormWidgetRadio
GtkFormWidgetRadioClass
IS_GTK_FORM_WIDGET_RADIO
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
<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>
</para>
+<!-- ##### ARG GtkFormWidget:form ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GtkFormWidget:label ##### -->
+<para>
+
+</para>
+
<!-- ##### ARG GtkFormWidget:widget ##### -->
<para>
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,
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:
if (widget != NULL)
{
+ g_object_set (G_OBJECT (widget), "form", form, NULL);
+
name = xmlGetProp (cur, (const xmlChar *)"name");
if (GTK_IS_BUILDER (priv->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;
#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
typedef struct _GtkFormWidgetPrivate GtkFormWidgetPrivate;
struct _GtkFormWidgetPrivate
{
+ GtkForm *form;
GtkWidget *widget;
gchar *widget_name;
GtkWidget *label;
+
+ GSList *on_change_ops; /* GtkFormOnChangeOp */
};
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",
{
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;
}
/**
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.
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;
}
}
}
+/**
+ * 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,
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;
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;
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
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);
}