Description
Experiment to insert a text with suggests based on pre-setted dictionary.
Experiment to insert a text with suggests based on pre-setted dictionary.
#include <gtk/gtk.h> #include <string.h> #include <ctype.h> void change_text (GtkTextBuffer *textbuffer, gpointer user_data); GtkTextBuffer *buffer; GtkWidget *status_bar; GtkWidget *textview; int handler_buffer_id; int handler_backspace; int backspace_pressed = 0; void set_backspace_pressed (void) { backspace_pressed = 1; } int main (int argc, char *argv[]) { GtkWidget *window, *vbox, *hbox; GtkWidget *scrolled_window; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), 320, 240); gtk_window_set_title (GTK_WINDOW (window), "T9 Experiment"); g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (gtk_main_quit), NULL); gtk_widget_show (window); vbox = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox); gtk_container_add (GTK_CONTAINER (window), vbox); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0); gtk_widget_show (scrolled_window); textview = gtk_text_view_new (); gtk_text_view_set_left_margin (GTK_TEXT_VIEW (textview), 3); gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (textview), 2); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (textview), GTK_WRAP_WORD); gtk_widget_modify_font (textview, pango_font_description_from_string ("Monospace 8")); gtk_container_add (GTK_CONTAINER (scrolled_window), textview); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)); handler_buffer_id = g_signal_connect_object (G_OBJECT (buffer), "changed", G_CALLBACK (change_text), NULL, G_CONNECT_SWAPPED); handler_backspace = g_signal_connect_object (G_OBJECT (textview), "backspace", G_CALLBACK (set_backspace_pressed), NULL, G_CONNECT_SWAPPED); gtk_widget_show (textview); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); status_bar = gtk_statusbar_new (); gtk_box_pack_start (GTK_BOX (hbox), status_bar, TRUE, TRUE, 0); gtk_widget_show (status_bar); gtk_statusbar_pop (GTK_STATUSBAR (status_bar), 1); gtk_statusbar_push (GTK_STATUSBAR (status_bar), 1, "Caratteri: 0 - Parole: 0"); gtk_main (); return 0; } char *get_word (GtkTextIter *start, GtkTextIter *end) { char *str; gtk_text_iter_backward_word_start (start); gtk_text_iter_forward_word_end (end); if ( gtk_text_iter_equal (start, end) ) return NULL; return gtk_text_buffer_get_text (buffer, start, end, FALSE); } gboolean is_separator (char c) { static const char *token = " -.,;:#+*][{}^'?!\"£$%&/\\()=|<>\n\t\r"; int lt, j; lt = strlen (token); for ( j = 0; j < lt; j++ ) if ( token[j] == c ) return TRUE; return FALSE; } int gtk_text_buffer_get_word_count (GtkTextBuffer *buffer) { GtkTextIter start, end; char *str; int j, k, ls, cnt; gtk_text_buffer_get_bounds (buffer, &start, &end); str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE); ls = strlen (str); for ( j = (cnt = 1) - 1; j < ls; j++ ) if ( is_separator (str[j]) && !is_separator (j ? str[j - 1] : 'h') ) cnt++; if ( is_separator (str[j - 1]) ) cnt--; g_free (str); return cnt; } char *get_suggest (char *word) { GIOChannel *gic; GError *error = NULL; GString *string; gsize seek; int j, k, w; char *l_str; gic = g_io_channel_new_file ("words.italian.txt", "r", &error); if ( !gic ) { g_error ("%s", error->message); g_error_free (error); return NULL; } w = strlen (word); string = g_string_new (""); while ( G_IO_STATUS_EOF != g_io_channel_read_line_string (gic, string, &seek, &error) ) { k = strlen (string->str); if ( (k - 1) <= w ) continue; for ( j = 0; j < w; j++ ) if ( tolower (word[j]) != tolower (string->str[j]) ) break; if ( j < w ) continue; g_io_channel_close (gic); l_str = g_strndup (string->str + w, string->len - (w + 1)); g_string_free (string, TRUE); return l_str; } return g_strdup_printf (""); } void change_text (GtkTextBuffer *textbuffer, gpointer user_data) { GtkTextMark *mark; GtkTextIter start, end, *select; char *word, *statusbar, *suggest; g_signal_handler_disconnect (buffer, handler_buffer_id); if ( !GTK_IS_TEXT_BUFFER (buffer) ) return; gtk_text_buffer_delete_selection (buffer, TRUE, TRUE); mark = gtk_text_buffer_get_insert (buffer); gtk_text_buffer_get_iter_at_mark (buffer, &start, mark); gtk_text_buffer_get_iter_at_mark (buffer, &end, mark); word = get_word (&start, &end); if ( !word ) return; if ( strlen (word) > 2 && !backspace_pressed) { suggest = get_suggest (word); gtk_text_buffer_insert (buffer, &end, suggest, -1); select = gtk_text_iter_copy (&end); gtk_text_iter_backward_chars (&end, strlen (suggest)); gtk_text_buffer_select_range (buffer, &end, select); g_free (suggest); } g_free (word); statusbar = g_strdup_printf ("Caratteri: %d - Parole: %d", gtk_text_buffer_get_char_count (buffer), gtk_text_buffer_get_word_count (buffer)); gtk_statusbar_pop (GTK_STATUSBAR (status_bar), 1); gtk_statusbar_push (GTK_STATUSBAR (status_bar), 1, statusbar); g_free (statusbar); if ( backspace_pressed ) backspace_pressed = 0; handler_buffer_id = g_signal_connect_object (G_OBJECT (buffer), "changed", G_CALLBACK (change_text), NULL, G_CONNECT_SWAPPED); }