From 5ac7dbc499b186ef3a87b64953cbfb481be4f791 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Wed, 29 Jul 2009 17:48:34 +0200 Subject: [PATCH] Implemented loading form's definition from xml file (missing key and default value). --- .gitignore | 1 + data/gtkform.dtd | 6 +- src/fieldboolean.c | 89 ++++++++++-------- src/fieldboolean.h | 2 + src/form.c | 167 ++++++++++++++++++++++++++++++++- src/form.h | 4 +- src/widgetcombobox.c | 12 ++- test/Makefile.am | 5 +- test/from_xml.c | 219 +++++++++++++++++++++++++++++++++++++++++++ test/test.xml | 47 ++++++++++ 10 files changed, 502 insertions(+), 50 deletions(-) create mode 100644 test/from_xml.c create mode 100644 test/test.xml diff --git a/.gitignore b/.gitignore index eed6425..c10f0d4 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,6 @@ src/.libs/ src/libgtkform.la test/.libs/ test/test +test/from_xml *.bak *.stamp diff --git a/data/gtkform.dtd b/data/gtkform.dtd index 5a4c83e..cd38f83 100644 --- a/data/gtkform.dtd +++ b/data/gtkform.dtd @@ -1,8 +1,10 @@ - + + + - + default_value)); @@ -184,7 +191,7 @@ gtk_form_field_boolean_clear (GtkFormField *field) /** * gtk_form_field_boolean_is_empty: - * @field: + * @field: a #GtkFormField object. * */ gboolean @@ -197,7 +204,7 @@ gtk_form_field_boolean_is_empty (GtkFormField *field) /** * gtk_form_field_boolean_set_from_datamodel: - * @field: + * @field: a #GtkFormField object. * @dm: * @row: * @@ -219,6 +226,42 @@ gtk_form_field_boolean_set_from_datamodel (GtkFormField *field, GdaDataModel *dm return ret; } +/** + * gtk_form_field_boolean_str_to_boolean: + * @value: + * + * Utility function to convert a string to its #gboolean equivalent. + * + * Returns: the #gboolean equivalent from @value. + */ +gboolean +gtk_form_field_boolean_str_to_boolean (const gchar *value) +{ + gchar *str_value; + gboolean bool_value = FALSE; + + str_value = g_strstrip (g_strdup (value)); + + if (strcmp (str_value, "0") == 0 + || strcasecmp (str_value, "f") == 0 + || strcasecmp (str_value, "false") == 0 + || strcasecmp (str_value, "n") == 0 + || strcasecmp (str_value, "no") == 0) + { + bool_value = FALSE; + } + else if (strcmp (str_value, "1") == 0 + || strcasecmp (str_value, "t") == 0 + || strcasecmp (str_value, "true") == 0 + || strcasecmp (str_value, "y") == 0 + || strcasecmp (str_value, "yes") == 0) + { + bool_value = TRUE; + } + + return bool_value; +} + /* PRIVATE */ static void gtk_form_field_boolean_set_property (GObject *object, @@ -278,31 +321,3 @@ gtk_form_field_boolean_set_value_stringify (GtkFormField *field, const gchar *va return ret; } - -static gboolean -check_value (const gchar *value) -{ - gchar *str_value; - gboolean bool_value = FALSE; - - str_value = g_strstrip (g_strdup (value)); - - if (strcmp (str_value, "0") == 0 - || strcasecmp (str_value, "f") == 0 - || strcasecmp (str_value, "false") == 0 - || strcasecmp (str_value, "n") == 0 - || strcasecmp (str_value, "no") == 0) - { - bool_value = FALSE; - } - else if (strcmp (str_value, "1") == 0 - || strcasecmp (str_value, "t") == 0 - || strcasecmp (str_value, "true") == 0 - || strcasecmp (str_value, "y") == 0 - || strcasecmp (str_value, "yes") == 0) - { - bool_value = TRUE; - } - - return bool_value; -} diff --git a/src/fieldboolean.h b/src/fieldboolean.h index f47f8fc..a3dfe58 100644 --- a/src/fieldboolean.h +++ b/src/fieldboolean.h @@ -62,6 +62,8 @@ gboolean gtk_form_field_boolean_is_empty (GtkFormField *field); gboolean gtk_form_field_boolean_set_from_datamodel (GtkFormField *field, GdaDataModel *dm, gint row); +gboolean gtk_form_field_boolean_str_to_boolean (const gchar *value); + G_END_DECLS diff --git a/src/form.c b/src/form.c index ae7bcb6..d24dc7e 100644 --- a/src/form.c +++ b/src/form.c @@ -24,6 +24,20 @@ #include "form.h" +#include "fieldboolean.h" +#include "fielddatetime.h" +#include "fieldinteger.h" +#include "fieldfloat.h" +#include "fieldtext.h" +#include "widget.h" +#include "widgetcheck.h" +#include "widgetcombobox.h" +#include "widgetentry.h" +#include "widgetlabel.h" +#include "widgetspin.h" +#include "widgettextview.h" + + enum { PROP_0, @@ -104,23 +118,167 @@ GtkForm /** * gtk_form_new_from_xml: * @xmldoc: + * @gtkbuilder: * * Returns: the newly created #GtkForm object from an #xmlDoc that contains the * xml definition of the form. */ GtkForm -*gtk_form_new_from_xml (xmlDoc *xmldoc) +*gtk_form_new_from_xml (xmlDoc *xmldoc, GtkBuilder *gtkbuilder) { GtkForm *form; xmlNode *cur; + GtkBuilder *new_gtkbuilder; form = NULL; + if (GTK_IS_BUILDER (gtkbuilder)) + { + new_gtkbuilder = gtkbuilder; + } + else + { + new_gtkbuilder = NULL; + } + cur = xmlDocGetRootElement (xmldoc); if (cur != NULL) { - if (xmlStrcmp (cur->name, "gtkform") == 0) + if (xmlStrcmp (cur->name, (const xmlChar *)"gtkform") == 0) { + gchar *type; + gchar *name; + + GtkFormWidget *widget; + xmlNode *node_widget; + + GtkFormField *field; + xmlNode *node_field; + + form = gtk_form_new (); + + /* TO DO + * search gtkguilder-file node + */ + + cur = cur->children; + while (cur) + { + if (xmlStrcmp (cur->name, (const xmlChar *)"table") == 0) + { + gtk_form_set_table (form, (gchar *)xmlNodeGetContent (cur)); + } + else if (xmlStrcmp (cur->name, (const xmlChar *)"widget") == 0) + { + type = xmlGetProp (cur, (const xmlChar *)"type"); + if (strcmp (type, "checkbox") == 0) + { + widget = gtk_form_widget_check_new (); + } + else if (strcmp (type, "combobox") == 0) + { + widget = gtk_form_widget_combo_box_new (); + } + else if (strcmp (type, "entry") == 0) + { + widget = gtk_form_widget_entry_new (); + } + else if (strcmp (type, "label") == 0) + { + widget = gtk_form_widget_label_new (); + } + else if (strcmp (type, "spin") == 0) + { + widget = gtk_form_widget_spin_new (); + } + else if (strcmp (type, "textview") == 0) + { + widget = gtk_form_widget_textview_new (); + } + + if (widget != NULL) + { + name = xmlGetProp (cur, (const xmlChar *)"name"); + + gtk_form_widget_set_from_gtkbuilder (widget, new_gtkbuilder, name); + + node_widget = cur->children; + while (node_widget != NULL) + { + if (xmlStrcmp (node_widget->name, (const xmlChar *)"column-field") == 0 + && IS_GTK_FORM_WIDGET_COMBO_BOX (widget)) + { + g_object_set (G_OBJECT (widget), "column-field", + strtol ((gchar *)xmlNodeGetContent (node_widget), NULL, 10), NULL); + } + else if (xmlStrcmp (node_widget->name, (const xmlChar *)"field") == 0) + { + type = xmlGetProp (node_widget, (const xmlChar *)"type"); + if (strcmp (type, "boolean") == 0) + { + field = gtk_form_field_boolean_new (); + } + else if (strcmp (type, "datetime") == 0) + { + field = gtk_form_field_datetime_new (); + } + else if (strcmp (type, "float") == 0) + { + field = gtk_form_field_float_new (); + } + else if (strcmp (type, "integer") == 0) + { + field = gtk_form_field_integer_new (); + } + else if (strcmp (type, "text") == 0) + { + field = gtk_form_field_text_new (); + } + + if (field != NULL) + { + gchar *prop; + + gtk_form_add_field (form, field); + + name = xmlGetProp (node_widget, (const xmlChar *)"name"); + g_object_set (G_OBJECT (field), + "field", name, + "form-widget", widget, + NULL); + + node_field = node_widget->children; + while (node_field != NULL) + { + if (xmlStrcmp (node_field->name, (const xmlChar *)"obligatory") == 0) + { + prop = (gchar *)xmlNodeGetContent (node_field); + g_object_set (G_OBJECT (field), + "obligatory", gtk_form_field_boolean_str_to_boolean (prop), + NULL); + } + else if (xmlStrcmp (node_field->name, (const xmlChar *)"default-value") == 0) + { + /*g_object_set (G_OBJECT (field), + "default-value", name, + NULL);*/ + } + else if (xmlStrcmp (node_field->name, (const xmlChar *)"is-key") == 0) + { + } + + node_field = node_field->next; + } + } + } + + node_widget = node_widget->next; + } + } + } + + cur = cur->next; + } } else { @@ -135,12 +293,13 @@ GtkForm /** * gtk_form_new_from_file: * @filename: + * @gtkbuilder: * * Returns: the newly created #GtkForm object from a file that contains the * xml denifition of the form. */ GtkForm -*gtk_form_new_from_file (const gchar *filename) +*gtk_form_new_from_file (const gchar *filename, GtkBuilder *gtkbuilder) { GtkForm *form; xmlDoc *xdoc; @@ -152,7 +311,7 @@ GtkForm xdoc = xmlParseFile (filename); if (xdoc != NULL) { - form = gtk_form_new_from_xml (xdoc); + form = gtk_form_new_from_xml (xdoc, gtkbuilder); } return form; diff --git a/src/form.h b/src/form.h index f10860c..456574d 100644 --- a/src/form.h +++ b/src/form.h @@ -56,8 +56,8 @@ GType gtk_form_get_type (void) G_GNUC_CONST; GtkForm *gtk_form_new (void); -GtkForm *gtk_form_new_from_xml (xmlDoc *xmldoc); -GtkForm *gtk_form_new_from_file (const gchar *filename); +GtkForm *gtk_form_new_from_xml (xmlDoc *xmldoc, GtkBuilder *gtkbuilder); +GtkForm *gtk_form_new_from_file (const gchar *filename, GtkBuilder *gtkbuilder); const gchar *gtk_form_get_table (GtkForm *form); void gtk_form_set_table (GtkForm *form, const gchar *table); diff --git a/src/widgetcombobox.c b/src/widgetcombobox.c index a7d5731..e9bd7f4 100644 --- a/src/widgetcombobox.c +++ b/src/widgetcombobox.c @@ -92,13 +92,16 @@ GtkFormWidget /** * gtk_form_widget_combo_box_get_value_stringify: - * @widget: + * @fwidget: a #GtkFormWidget object. * */ const gchar *gtk_form_widget_combo_box_get_value_stringify (GtkFormWidget *fwidget) { const gchar *ret = ""; + + g_return_val_if_fail (IS_GTK_FORM_WIDGET_COMBO_BOX (fwidget), NULL); + GtkWidget *w = gtk_form_widget_get_widget (fwidget); GtkFormWidgetComboBoxPrivate *priv = GTK_FORM_WIDGET_COMBO_BOX_GET_PRIVATE (fwidget); @@ -127,17 +130,20 @@ const gchar /** * gtk_form_widget_combo_box_set_value_stringify: - * @fwidget: + * @fwidget: a #GtkFormWidget object. * @value: * */ gboolean -gtk_form_widget_combo_box_set_value_stringify (GtkFormWidget *fwidget, const gchar *value) +gtk_form_widget_combo_box_set_value_stringify (GtkFormWidget *fwidget, + const gchar *value) { gboolean ret = FALSE; GtkWidget *w; GtkTreeModel *tmodel; + g_return_val_if_fail (IS_GTK_FORM_WIDGET_COMBO_BOX (fwidget), FALSE); + GtkFormWidgetComboBoxPrivate *priv = GTK_FORM_WIDGET_COMBO_BOX_GET_PRIVATE (fwidget); g_object_get (G_OBJECT (fwidget), diff --git a/test/Makefile.am b/test/Makefile.am index a653687..4537996 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -5,8 +5,9 @@ AM_CPPFLAGS = $(GTKFORM_CFLAGS) \ -I$(top_srcdir)/src \ -DGUIDIR="\"@abs_builddir@\"" -noinst_PROGRAMS = test +noinst_PROGRAMS = test \ + from_xml test_SOURCES = main.c -test_LDADD = $(top_builddir)/src/libgtkform.la +LDADD = $(top_builddir)/src/libgtkform.la diff --git a/test/from_xml.c b/test/from_xml.c new file mode 100644 index 0000000..74cca12 --- /dev/null +++ b/test/from_xml.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2005-2009 Andrea Zagli + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include + +#include + +#include "form.h" +#include "field.h" +#include "fieldboolean.h" +#include "fielddatetime.h" +#include "fieldinteger.h" +#include "fieldfloat.h" +#include "fieldtext.h" +#include "widget.h" +#include "widgetcheck.h" +#include "widgetcombobox.h" +#include "widgetentry.h" +#include "widgetlabel.h" +#include "widgetspin.h" +#include "widgettextview.h" + +GtkForm *form; + +GtkWidget *w; +GtkWidget *txtvSql; +GtkWidget *tbtnEditable; +GtkWidget *tbtnSensitive; + +void +on_btnClear_clicked (GtkButton *button, + gpointer user_data) +{ + gtk_form_clear (form); +} + +void +on_btnCheck_clicked (GtkButton *button, + gpointer user_data) +{ + if (!gtk_form_check (form)) + { + GtkWidget *diag = gtk_message_dialog_new (GTK_WINDOW (w), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "Some obligatory field is empty."); + gtk_dialog_run (GTK_DIALOG (diag)); + gtk_widget_destroy (diag); + } +} + +void +on_tbtnEditable_toggled (GtkToggleButton *button, + gpointer user_data) +{ + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tbtnEditable))) + { + gtk_button_set_label (GTK_BUTTON (tbtnEditable), "Not Editable"); + gtk_form_set_editable (form, FALSE); + } + else + { + gtk_button_set_label (GTK_BUTTON (tbtnEditable), "Editable"); + gtk_form_set_editable (form, TRUE); + } +} + +void +on_tbtnSensitive_toggled (GtkToggleButton *button, + gpointer user_data) +{ + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tbtnSensitive))) + { + gtk_button_set_label (GTK_BUTTON (tbtnSensitive), "Not Sensitive"); + gtk_form_set_sensitive (form, FALSE); + } + else + { + gtk_button_set_label (GTK_BUTTON (tbtnSensitive), "Sensitive"); + gtk_form_set_sensitive (form, TRUE); + } +} + +void +on_btnSqlSelect_clicked (GtkButton *button, + gpointer user_data) +{ + GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (txtvSql)); + gchar *sql = gtk_form_get_sql (form, GTK_FORM_SQL_SELECT); + + gtk_text_buffer_set_text (buf, sql, strlen (sql)); +} + +void +on_btnSqlUpdate_clicked (GtkButton *button, + gpointer user_data) +{ + GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (txtvSql)); + gchar *sql = gtk_form_get_sql (form, GTK_FORM_SQL_UPDATE); + + gtk_text_buffer_set_text (buf, sql, strlen (sql)); +} + +void +on_btnSqlInsert_clicked (GtkButton *button, + gpointer user_data) +{ + GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (txtvSql)); + gchar *sql = gtk_form_get_sql (form, GTK_FORM_SQL_INSERT); + + gtk_text_buffer_set_text (buf, sql, strlen (sql)); +} + +void +on_btnSqlDelete_clicked (GtkButton *button, + gpointer user_data) +{ + GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (txtvSql)); + gchar *sql = gtk_form_get_sql (form, GTK_FORM_SQL_DELETE); + + gtk_text_buffer_set_text (buf, sql, strlen (sql)); +} + +void +create_cb_nation (GtkWidget *w) +{ + GtkCellRenderer *renderer; + GtkListStore *store; + GtkTreeIter iter; + gint id = 0; + + store = gtk_list_store_new (2, + G_TYPE_INT, + G_TYPE_STRING); + gtk_combo_box_set_model (GTK_COMBO_BOX (w), GTK_TREE_MODEL (store)); + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (w), renderer, FALSE); + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (w), renderer, + "text", 1); + + id++; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, id, + 1, "China", + -1); + id++; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, id, + 1, "Germany", + -1); + id++; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, id, + 1, "India", + -1); + id++; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, id, + 1, "Italy", + -1); + id++; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, id, + 1, "USA", + -1); +} + +int +main (int argc, char **argv) +{ + GtkBuilder *gtkbuilder; + + gtk_init (&argc, &argv); + + gtkbuilder = gtk_builder_new (); + + gtk_builder_add_from_file (gtkbuilder, GUIDIR "/test.gui", NULL); + + w = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "wMain")); + + tbtnEditable = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "tbtnEditable")); + tbtnSensitive = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "tbtnSensitive")); + + form = gtk_form_new_from_file (GUIDIR "/test.xml", gtkbuilder); + if (form == NULL) return 0; + + create_cb_nation (GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "cbNation"))); + + txtvSql = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "txtvSql")); + + gtk_builder_connect_signals (gtkbuilder, NULL); + + gtk_widget_show_all (w); + + gtk_main (); + + return 0; +} diff --git a/test/test.xml b/test/test.xml new file mode 100644 index 0000000..21f7a9f --- /dev/null +++ b/test/test.xml @@ -0,0 +1,47 @@ + + + names
+ + + + + + + + + + + + + + TRUE + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + +
-- 2.49.0