From e9486cbe60bcad6d666f424f2d2d804d109131ec Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Thu, 20 Oct 2011 15:12:19 +0200 Subject: [PATCH] Managed only valid values in GtkFormDecoder's autocompletion. refs #41 --- libgtkformui/gtkformdecoder.c | 116 +++++++++++++++++++++++++++++++++- libgtkformui/gtkformdecoder.h | 3 +- libgtkformui/test/decoder.c | 3 +- 3 files changed, 117 insertions(+), 5 deletions(-) diff --git a/libgtkformui/gtkformdecoder.c b/libgtkformui/gtkformdecoder.c index 2c99663..0c3ffef 100644 --- a/libgtkformui/gtkformdecoder.c +++ b/libgtkformui/gtkformdecoder.c @@ -75,6 +75,9 @@ static gboolean gtk_form_decoder_on_completion_match_selected (GtkEntryCompletio GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data); +static gboolean gtk_form_decoder_on_decoded_focus_out_event (GtkWidget *widget, + GdkEvent *event, + gpointer user_data); static GtkWidgetClass *parent_class = NULL; @@ -96,6 +99,8 @@ struct _GtkFormDecoderPrivate GdaDataModel *completion_dm; guint completion_text_column; guint completion_key_column; + gboolean completion_only_valid_values; + gulong completion_focus_out_handler_id; }; G_DEFINE_TYPE (GtkFormDecoder, gtk_form_decoder, GTK_TYPE_BIN) @@ -240,8 +245,13 @@ gtk_form_decoder_init (GtkFormDecoder *decoder) priv->lbl_key = gtk_label_new (""); gtk_box_pack_start (GTK_BOX (priv->hbox), priv->lbl_key, FALSE, FALSE, 0); - //gtk_widget_set_no_show_all (priv->lbl_key, TRUE); - gtk_widget_show (priv->lbl_key); + gtk_widget_set_no_show_all (priv->lbl_key, TRUE); + + priv->completion_dm = NULL; + priv->completion_key_column = 0; + priv->completion_text_column = 0; + priv->completion_only_valid_values = FALSE; + priv->completion_focus_out_handler_id = 0; } /** @@ -474,7 +484,8 @@ gtk_form_decoder_set_completion (GtkFormDecoder *decoder, const gchar *sql, GdaDataModel *data_model, guint key_column, - guint text_column) + guint text_column, + gboolean only_valid_values) { gchar *_sql; @@ -490,9 +501,12 @@ gtk_form_decoder_set_completion (GtkFormDecoder *decoder, priv->completion_dm = NULL; priv->completion_text_column = 0; priv->completion_key_column = 0; + priv->completion_only_valid_values = FALSE; gtk_entry_set_completion (GTK_ENTRY (priv->txt_decoded), NULL); gtk_editable_set_editable (GTK_EDITABLE (priv->txt_decoded), FALSE); + + g_signal_handler_disconnect (G_OBJECT (priv->txt_decoded), priv->completion_focus_out_handler_id); return; } @@ -550,6 +564,11 @@ gtk_form_decoder_set_completion (GtkFormDecoder *decoder, gtk_entry_completion_set_text_column (completion, priv->completion_text_column); gtk_editable_set_editable (GTK_EDITABLE (priv->txt_decoded), TRUE); + + priv->completion_only_valid_values = only_valid_values; + + priv->completion_focus_out_handler_id = g_signal_connect (G_OBJECT (priv->txt_decoded), "focus-out-event", + G_CALLBACK (gtk_form_decoder_on_decoded_focus_out_event), (gpointer)decoder); } /* CALLBACKS */ @@ -755,3 +774,94 @@ gtk_form_decoder_on_completion_match_selected (GtkEntryCompletion *widget, return TRUE; } + +static gboolean +gtk_form_decoder_on_decoded_focus_out_event (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + GtkEntryCompletion *completion; + GtkTreeModel *model; + GtkTreeIter iter; + GValue *key; + GValue *value; + + gchar *decoded; + gchar *decoded_casefold; + + gboolean found; + + GtkWidget *dialog; + + GtkFormDecoder *decoder = (GtkFormDecoder *)user_data; + GtkFormDecoderPrivate *priv = GTK_FORM_DECODER_GET_PRIVATE (decoder); + + found = FALSE; + + /* check if inserted value exists in GtkTreeModel */ + completion = gtk_entry_get_completion (GTK_ENTRY (priv->txt_decoded)); + if (completion != NULL) + { + model = gtk_entry_completion_get_model (GTK_ENTRY_COMPLETION (completion)); + if (model != NULL && gtk_tree_model_get_iter_first (model, &iter)) + { + decoded = (gchar *)gtk_entry_get_text (GTK_ENTRY (priv->txt_decoded)); + if (decoded == NULL) + { + gtk_form_decoder_set_key (decoder, "0"); + return FALSE; + } + decoded = g_strdup (decoded); + g_strstrip (decoded); + if (g_strcmp0 (decoded, "") == 0) + { + gtk_form_decoder_set_key (decoder, "0"); + return FALSE; + } + + decoded_casefold = g_utf8_casefold (decoded, -1); + g_free (decoded); + do + { + key = g_new0 (GValue, 1); + value = g_new0 (GValue, 1); + gtk_tree_model_get_value (model, &iter, + priv->completion_key_column, key); + gtk_tree_model_get_value (model, &iter, + priv->completion_text_column, value); + if (g_strcmp0 (decoded_casefold, g_utf8_casefold (gda_value_stringify (value), -1)) == 0) + { + gtk_form_decoder_set_key (decoder, gda_value_stringify (key)); + found = TRUE; + g_value_unset (key); + g_value_unset (value); + break; + } + g_value_unset (key); + g_value_unset (value); + } while (gtk_tree_model_iter_next (model, &iter)); + + if (!found) + { + if (priv->completion_only_valid_values) + { + gtk_form_decoder_set_key (decoder, "0"); + /* TODO message dialog */ + dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (decoder))), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + _("Only valid values are allowed.")); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + } + else + { + gtk_label_set_text (GTK_LABEL (priv->lbl_key), "0"); + } + } + } + } + + return FALSE; +} diff --git a/libgtkformui/gtkformdecoder.h b/libgtkformui/gtkformdecoder.h index 95a6aff..7e5eb52 100644 --- a/libgtkformui/gtkformdecoder.h +++ b/libgtkformui/gtkformdecoder.h @@ -75,7 +75,8 @@ void gtk_form_decoder_set_completion (GtkFormDecoder *decoder, const gchar *sql, GdaDataModel *data_model, guint key_column, - guint text_column); + guint text_column, + gboolean only_valid_values); G_END_DECLS diff --git a/libgtkformui/test/decoder.c b/libgtkformui/test/decoder.c index a0e0566..189d0b0 100644 --- a/libgtkformui/test/decoder.c +++ b/libgtkformui/test/decoder.c @@ -82,7 +82,8 @@ main (int argc, char **argv) gtk_form_decoder_set_completion (GTK_FORM_DECODER (decoder), "SELECT id, name FROM customers", - NULL, 0, 1); + NULL, 0, 1, + TRUE); g_signal_connect (G_OBJECT (decoder), "btn_clean_clicked", G_CALLBACK (on_btn_clean_clicked), NULL); -- 2.49.0