From 0cc82d1f8161af1a34f547680070312506a13c2d Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Mon, 24 Oct 2011 16:59:13 +0200 Subject: [PATCH] Implemented interface GdaExQueryEditorIWidget on GtkFormDecoder. --- .gitignore | 1 + libgtkformui/gtkformdecoder.c | 38 ++- libgtkformui/test/Makefile.am | 5 +- libgtkformui/test/query_editor.c | 457 +++++++++++++++++++++++++++++++ 4 files changed, 497 insertions(+), 4 deletions(-) create mode 100644 libgtkformui/test/query_editor.c diff --git a/.gitignore b/.gitignore index eaf70b6..faedc98 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ test/test test/from_xml test/from_xml_with_db libgtkformui/test/decoder +libgtkformui/test/query_editor POTFILES mkinstalldirs stamp-it diff --git a/libgtkformui/gtkformdecoder.c b/libgtkformui/gtkformdecoder.c index d856f4c..6de3a2d 100644 --- a/libgtkformui/gtkformdecoder.c +++ b/libgtkformui/gtkformdecoder.c @@ -45,6 +45,8 @@ enum static void gtk_form_decoder_class_init (GtkFormDecoderClass *klass); static void gtk_form_decoder_init (GtkFormDecoder *decoder); +static void gtk_form_decoder_gdaex_query_editor_iwidget_interface_init (GdaExQueryEditorIWidgetIface *iface); + static void gtk_form_decoder_decode (GtkFormDecoder *decoder); static void gtk_form_decoder_size_request (GtkWidget *widget, @@ -87,6 +89,10 @@ static gboolean gtk_form_decoder_match_func (GtkEntryCompletion *completion, GtkTreeIter *iter, gpointer user_data); +static const gchar *gtk_form_decoder_get_value (GdaExQueryEditorIWidget *iwidget); +static const gchar *gtk_form_decoder_get_value_sql (GdaExQueryEditorIWidget *iwidget); +static void gtk_form_decoder_set_value (GdaExQueryEditorIWidget *iwidget, const gchar *value); + static GtkWidgetClass *parent_class = NULL; @@ -113,7 +119,9 @@ struct _GtkFormDecoderPrivate gulong completion_focus_out_handler_id; }; -G_DEFINE_TYPE (GtkFormDecoder, gtk_form_decoder, GTK_TYPE_BIN) +G_DEFINE_TYPE_WITH_CODE (GtkFormDecoder, gtk_form_decoder, GTK_TYPE_BIN, + G_IMPLEMENT_INTERFACE (GDAEX_QUERY_EDITOR_TYPE_IWIDGET, + gtk_form_decoder_gdaex_query_editor_iwidget_interface_init)); static void gtk_form_decoder_class_init (GtkFormDecoderClass *klass) @@ -301,6 +309,14 @@ gtk_form_decoder_init (GtkFormDecoder *decoder) priv->completion_focus_out_handler_id = 0; } +static void +gtk_form_decoder_gdaex_query_editor_iwidget_interface_init (GdaExQueryEditorIWidgetIface *iface) +{ + iface->get_value = gtk_form_decoder_get_value; + iface->get_value_sql = gtk_form_decoder_get_value_sql; + iface->set_value = gtk_form_decoder_set_value; +} + /** * gtk_form_decoder_new: * @@ -1027,3 +1043,23 @@ gtk_form_decoder_match_func (GtkEntryCompletion *completion, return ret; } + +static const gchar +*gtk_form_decoder_get_value (GdaExQueryEditorIWidget *iwidget) +{ + return (const gchar *)gtk_form_decoder_get_decoded (GTK_FORM_DECODER (iwidget)); +} + +static const gchar +*gtk_form_decoder_get_value_sql (GdaExQueryEditorIWidget *iwidget) +{ + return (const gchar *)gtk_form_decoder_get_key (GTK_FORM_DECODER (iwidget)); +} + +static void +gtk_form_decoder_set_value (GdaExQueryEditorIWidget *iwidget, + const gchar *value) +{ + gtk_form_decoder_set_key (GTK_FORM_DECODER (iwidget), value); +} + diff --git a/libgtkformui/test/Makefile.am b/libgtkformui/test/Makefile.am index 40afd35..7bd7f11 100644 --- a/libgtkformui/test/Makefile.am +++ b/libgtkformui/test/Makefile.am @@ -7,9 +7,8 @@ AM_CPPFLAGS = $(GTKFORM_CFLAGS) \ -I$(top_srcdir) \ -DGUIDIR="\"@abs_builddir@\"" -noinst_PROGRAMS = decoder - -decoder_SOURCES = decoder.c +noinst_PROGRAMS = decoder \ + query_editor LDADD = $(top_builddir)/libgtkform/libgtkform.la \ $(top_builddir)/libgtkformui/libgtkformui.la diff --git a/libgtkformui/test/query_editor.c b/libgtkformui/test/query_editor.c new file mode 100644 index 0000000..d160d09 --- /dev/null +++ b/libgtkformui/test/query_editor.c @@ -0,0 +1,457 @@ +/* + * Copyright (C) 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include + +GtkWidget *w; + +GtkWidget *fdec_city; + +static gboolean +on_btn_fdec_city_clean_clicked (gpointer instance, gint arg1, gpointer user_data) +{ + return FALSE; +} + +static gboolean +on_btn_fdec_city_new_clicked (gpointer instance, gpointer user_data) +{ + g_debug ("New clicked."); + return FALSE; +} + +static gboolean +on_btn_fdec_city_open_clicked (gpointer instance, gpointer user_data) +{ + g_debug ("Open clicked."); + return FALSE; +} + +static gboolean +on_btn_fdec_city_browse_clicked (gpointer instance, gpointer user_data) +{ + gtk_form_decoder_set_key (GTK_FORM_DECODER (fdec_city), "1"); + return FALSE; +} + +static void +on_btn_clean_clicked (GtkButton *button, + gpointer user_data) +{ + gdaex_query_editor_clean_choices ((GdaExQueryEditor *)user_data); +} + +static void +on_btn_save_xml_clicked (GtkButton *button, + gpointer user_data) +{ + xmlDoc *doc; + xmlNode *node; + GtkWidget *dialog; + + doc = xmlNewDoc ("1.0"); + node = gdaex_query_editor_get_sql_as_xml ((GdaExQueryEditor *)user_data); + xmlDocSetRootElement (doc, node); + + dialog = gtk_file_chooser_dialog_new ("Save xml to...", + GTK_WINDOW (w), + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, + NULL); + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) + { + gchar *filename; + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + xmlSaveFormatFile (filename, doc, 2); + g_free (filename); + } + gtk_widget_destroy (dialog); +} + +static void +on_btn_load_xml_clicked (GtkButton *button, + gpointer user_data) +{ + GtkWidget *dialog; + xmlDoc *doc; + xmlNode *node; + + dialog = gtk_file_chooser_dialog_new ("Load xml from...", + GTK_WINDOW (w), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) + { + gchar *filename; + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + doc = xmlParseFile (filename); + if (doc != NULL) + { + node = xmlDocGetRootElement (doc); + if (node != NULL) + { + gdaex_query_editor_load_choices_from_xml ((GdaExQueryEditor *)user_data, node, TRUE); + } + } + g_free (filename); + } + gtk_widget_destroy (dialog); +} + +static void +on_btn_get_sql_clicked (GtkButton *button, + gpointer user_data) +{ + xmlDoc *doc; + xmlNode *node; + xmlChar *buf; + + gchar *sql; + + gint size; + + /* SQL */ + sql = (gchar *)gdaex_query_editor_get_sql ((GdaExQueryEditor *)user_data); + sql = g_strjoinv ("%%", g_strsplit (sql, "%", -1)); + GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (w), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + sql); + gtk_window_set_title (GTK_WINDOW (dialog), "Sql"); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + /* SQL SELECT */ + sql = (gchar *)gdaex_query_editor_get_sql_select ((GdaExQueryEditor *)user_data); + sql = g_strjoinv ("%%", g_strsplit (sql, "%", -1)); + dialog = gtk_message_dialog_new (GTK_WINDOW (w), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + sql); + gtk_window_set_title (GTK_WINDOW (dialog), "Sql Select"); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + g_free (sql); + + /* SQL FROM */ + sql = (gchar *)gdaex_query_editor_get_sql_from ((GdaExQueryEditor *)user_data); + sql = g_strjoinv ("%%", g_strsplit (sql, "%", -1)); + dialog = gtk_message_dialog_new (GTK_WINDOW (w), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + sql); + gtk_window_set_title (GTK_WINDOW (dialog), "Sql From"); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + g_free (sql); + + /* SQL WHERE */ + sql = (gchar *)gdaex_query_editor_get_sql_where ((GdaExQueryEditor *)user_data); + sql = g_strjoinv ("%%", g_strsplit (sql, "%", -1)); + dialog = gtk_message_dialog_new (GTK_WINDOW (w), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + sql); + gtk_window_set_title (GTK_WINDOW (dialog), "Sql Where"); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + g_free (sql); + + /* SQL ORDER */ + sql = (gchar *)gdaex_query_editor_get_sql_order ((GdaExQueryEditor *)user_data); + sql = g_strjoinv ("%%", g_strsplit (sql, "%", -1)); + dialog = gtk_message_dialog_new (GTK_WINDOW (w), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + sql); + gtk_window_set_title (GTK_WINDOW (dialog), "Sql Order By"); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + g_free (sql); + + /* XML */ + doc = xmlNewDoc ("1.0"); + node = gdaex_query_editor_get_sql_as_xml ((GdaExQueryEditor *)user_data); + xmlDocSetRootElement (doc, node); + xmlDocDumpMemory (doc, &buf, &size); + buf = g_strjoinv ("%%", g_strsplit (buf, "%", -1)); + + dialog = gtk_message_dialog_new (GTK_WINDOW (w), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + buf); + gtk_window_set_title (GTK_WINDOW (dialog), "Xml"); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + +int +main (int argc, char *argv[]) +{ + GError *error; + + GOptionContext *context; + + GdaEx *gdaex; + GdaExQueryEditor *qe; + + GdaExQueryEditorField *field; + + GtkWidget *vbox; + GtkWidget *widget_qe; + GtkWidget *hbtnbox; + GtkWidget *btn_clean; + GtkWidget *btn_get_sql; + GtkWidget *btn_save_xml; + GtkWidget *btn_load_xml; + GtkWidget *btn_ok; + + gtk_init (&argc, &argv); + + gdaex = gdaex_new_from_string ("SQLite://DB_DIR=" GUIDIR ";DB_NAME=database.db"); + if (gdaex == NULL) + { + g_error ("Error on GdaEx initialization."); + return 0; + } + + error = NULL; + context = g_option_context_new ("tests"); + g_option_context_add_group (context, gdaex_get_option_group (gdaex)); + g_option_context_parse (context, &argc, &argv, &error); + if (error != NULL) + { + g_warning ("Error on command line parsing: %s", error->message); + } + + qe = gdaex_query_editor_new (gdaex); + + gdaex_query_editor_add_table (qe, "clients", "Clients"); + + field = g_new0 (GdaExQueryEditorField, 1); + field->name = g_strdup ("id"); + field->name_visible = g_strdup ("ID"); + field->type = GDAEX_QE_FIELD_TYPE_INTEGER; + field->for_show = TRUE; + field->always_showed = TRUE; + field->for_where = TRUE; + field->available_where_type = GDAEX_QE_WHERE_TYPE_EQUAL; + gdaex_query_editor_table_add_field (qe, "clients", *field); + g_free (field); + + field = g_new0 (GdaExQueryEditorField, 1); + field->name = g_strdup ("name"); + field->name_visible = g_strdup ("Name"); + field->description = g_strdup ("The client's name"); + field->type = GDAEX_QE_FIELD_TYPE_TEXT; + field->for_show = TRUE; + field->for_where = TRUE; + field->for_order = TRUE; + field->available_where_type = GDAEX_QE_WHERE_TYPE_STARTS + | GDAEX_QE_WHERE_TYPE_CONTAINS + | GDAEX_QE_WHERE_TYPE_ENDS + | GDAEX_QE_WHERE_TYPE_ISTARTS + | GDAEX_QE_WHERE_TYPE_ICONTAINS + | GDAEX_QE_WHERE_TYPE_IENDS; + gdaex_query_editor_table_add_field (qe, "clients", *field); + g_free (field); + + field = g_new0 (GdaExQueryEditorField, 1); + field->name = g_strdup ("surname"); + field->name_visible = g_strdup ("Surname"); + field->description = g_strdup ("The client's surname"); + field->type = GDAEX_QE_FIELD_TYPE_TEXT; + field->for_show = TRUE; + field->for_where = TRUE; + field->for_order = TRUE; + field->available_where_type = GDAEX_QE_WHERE_TYPE_STRING + | GDAEX_QE_WHERE_TYPE_IS_NULL; + gdaex_query_editor_table_add_field (qe, "clients", *field); + g_free (field); + + field = g_new0 (GdaExQueryEditorField, 1); + field->name = g_strdup ("brithday"); + field->name_visible = g_strdup ("Birthday"); + field->description = g_strdup ("The client's birthday"); + field->type = GDAEX_QE_FIELD_TYPE_DATE; + field->for_show = TRUE; + field->for_where = TRUE; + field->for_order = TRUE; + field->available_where_type = GDAEX_QE_WHERE_TYPE_DATETIME + | GDAEX_QE_WHERE_TYPE_IS_NULL; + gdaex_query_editor_table_add_field (qe, "clients", *field); + g_free (field); + + field = g_new0 (GdaExQueryEditorField, 1); + field->name = g_strdup ("age"); + field->name_visible = g_strdup ("Age"); + field->description = g_strdup ("The client's age"); + field->alias = g_strdup ("client_age"); + field->type = GDAEX_QE_FIELD_TYPE_INTEGER; + field->for_show = TRUE; + field->for_where = TRUE; + field->for_order = TRUE; + field->available_where_type = GDAEX_QE_WHERE_TYPE_NUMBER; + gdaex_query_editor_table_add_field (qe, "clients", *field); + g_free (field); + + field = g_new0 (GdaExQueryEditorField, 1); + field->name = g_strdup ("datetime"); + field->name_visible = g_strdup ("DateTime"); + field->description = g_strdup ("???"); + field->type = GDAEX_QE_FIELD_TYPE_DATETIME; + field->for_show = TRUE; + field->for_where = TRUE; + field->for_order = TRUE; + field->available_where_type = GDAEX_QE_WHERE_TYPE_DATETIME + | GDAEX_QE_WHERE_TYPE_IS_NULL; + gdaex_query_editor_table_add_field (qe, "clients", *field); + g_free (field); + + fdec_city = gtk_form_decoder_new (); + g_object_set (G_OBJECT (fdec_city), + "gdaex", gdaex, + "sql", "SELECT name" + " FROM customers" + " WHERE id = ##key0::gint", + "show-btn-clean", TRUE, + "show-btn-new", TRUE, + "show-btn-open", TRUE, + NULL); + + g_signal_connect (G_OBJECT (fdec_city), "btn_clean_clicked", + G_CALLBACK (on_btn_fdec_city_clean_clicked), NULL); + g_signal_connect (G_OBJECT (fdec_city), "btn_new_clicked", + G_CALLBACK (on_btn_fdec_city_new_clicked), NULL); + g_signal_connect (G_OBJECT (fdec_city), "btn_open_clicked", + G_CALLBACK (on_btn_fdec_city_open_clicked), NULL); + g_signal_connect (G_OBJECT (fdec_city), "btn_browse_clicked", + G_CALLBACK (on_btn_fdec_city_browse_clicked), NULL); + + field = g_new0 (GdaExQueryEditorField, 1); + field->name = g_strdup ("id_cities"); + field->name_visible = g_strdup ("City"); + field->description = g_strdup ("The client's city"); + field->type = GDAEX_QE_FIELD_TYPE_INTEGER; + field->for_show = TRUE; + field->for_where = TRUE; + field->for_order = TRUE; + field->iwidget_from = GDAEX_QUERY_EDITOR_IWIDGET (fdec_city); + field->iwidget_to = NULL; + field->decode_table2 = g_strdup ("cities"); + field->decode_join_type = GDAEX_QE_JOIN_TYPE_LEFT; + /*field->decode_fields1 = g_slist_append (field->decode_fields1, "id_cities"); + field->decode_fields2 = g_slist_append (field->decode_fields2, "id");*/ + field->decode_field2 = g_strdup ("id"); + field->decode_field_to_show = g_strdup ("name"); + field->decode_field_alias = g_strdup ("city_name"); + field->available_where_type = GDAEX_QE_WHERE_TYPE_EQUAL; + gdaex_query_editor_table_add_field (qe, "clients", *field); + g_free (field); + + gdaex_query_editor_add_table (qe, "orders", "Orders"); + + field = g_new0 (GdaExQueryEditorField, 1); + field->name = g_strdup ("id"); + field->type = GDAEX_QE_FIELD_TYPE_INTEGER; + gdaex_query_editor_table_add_field (qe, "orders", *field); + g_free (field); + + field = g_new0 (GdaExQueryEditorField, 1); + field->name = g_strdup ("id_clients"); + field->type = GDAEX_QE_FIELD_TYPE_INTEGER; + gdaex_query_editor_table_add_field (qe, "orders", *field); + g_free (field); + + gdaex_query_editor_add_relation (qe, + "clients", "orders", + GDAEX_QE_JOIN_TYPE_LEFT, + "id", "id_clients", + NULL); + + field = g_new0 (GdaExQueryEditorField, 1); + field->name = g_strdup ("amount"); + field->name_visible = g_strdup ("Amount"); + field->type = GDAEX_QE_FIELD_TYPE_DOUBLE; + field->for_show = TRUE; + field->for_where = TRUE; + field->for_order = TRUE; + field->available_where_type = GDAEX_QE_WHERE_TYPE_NUMBER; + gdaex_query_editor_table_add_field (qe, "orders", *field); + g_free (field); + + w = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size (GTK_WINDOW (w), 610, 400); + gtk_window_set_modal (GTK_WINDOW (w), TRUE); + gtk_window_set_position (GTK_WINDOW (w), GTK_WIN_POS_CENTER); + g_signal_connect (G_OBJECT (w), "delete-event", + gtk_main_quit, NULL); + + vbox = gtk_vbox_new (FALSE, 5); + gtk_container_add (GTK_CONTAINER (w), vbox); + + widget_qe = gdaex_query_editor_get_widget (qe); + gtk_box_pack_start (GTK_BOX (vbox), widget_qe, TRUE, TRUE, 5); + + hbtnbox = gtk_hbutton_box_new (); + gtk_button_box_set_layout (GTK_BUTTON_BOX (hbtnbox), GTK_BUTTONBOX_END); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbtnbox), 5); + gtk_box_pack_start (GTK_BOX (vbox), hbtnbox, FALSE, FALSE, 5); + + btn_clean = gtk_button_new_from_stock ("gtk-clear"); + gtk_box_pack_start (GTK_BOX (hbtnbox), btn_clean, TRUE, TRUE, 5); + g_signal_connect (G_OBJECT (btn_clean), "clicked", + G_CALLBACK (on_btn_clean_clicked), qe); + + btn_get_sql = gtk_button_new_with_mnemonic ("Get _Sql"); + gtk_box_pack_start (GTK_BOX (hbtnbox), btn_get_sql, TRUE, TRUE, 5); + g_signal_connect (G_OBJECT (btn_get_sql), "clicked", + G_CALLBACK (on_btn_get_sql_clicked), qe); + + btn_save_xml = gtk_button_new_from_stock ("gtk-save"); + gtk_box_pack_start (GTK_BOX (hbtnbox), btn_save_xml, TRUE, TRUE, 5); + g_signal_connect (G_OBJECT (btn_save_xml), "clicked", + G_CALLBACK (on_btn_save_xml_clicked), qe); + + btn_load_xml = gtk_button_new_from_stock ("gtk-open"); + gtk_box_pack_start (GTK_BOX (hbtnbox), btn_load_xml, TRUE, TRUE, 5); + g_signal_connect (G_OBJECT (btn_load_xml), "clicked", + G_CALLBACK (on_btn_load_xml_clicked), qe); + + btn_ok = gtk_button_new_from_stock ("gtk-close"); + gtk_box_pack_start (GTK_BOX (hbtnbox), btn_ok, TRUE, TRUE, 5); + g_signal_connect (G_OBJECT (btn_ok), "clicked", + gtk_main_quit, NULL); + + gtk_widget_show_all (w); + + gtk_main (); + + return 0; +} -- 2.49.0