gtk - GtkEntry change text on user input -
in gui want modify text user inserts in gtkentry. eg if user enters 'john doe', gui should see not nicely formatted name , changes 'john doe'.
i connect handler "changed" signal described in eg gtkentry text change signal. problem occurs if change entry in signal handler, "changed" signal emitted again , again until kingdom comes.
i prevent doing string comparison, , change text in gtkentrybuffer if text "namified" version unequal text inside entry. feel programmer should able change the text inside entry without changed handler called on , on again.
the changed signal handler is:
void nameify_entry ( gtkeditable* editable, gpointer data ) { gchar* nameified; const gchar *entry_text; entry_text = gtk_entry_get_text( gtk_entry(editable) ); nameified = nameify(entry_text); /*is possible change buffer without using string comparison, without "change" signal being emitted on , on again?*/ if ( g_strcmp0(entry_text, nameified) != 0 ){ gtkentrybuffer* buf = gtk_entry_get_buffer(gtk_entry(editable) ); gtk_entry_buffer_set_text( buf, nameified, -1 ); } g_free(nameified); } and nameify function is:
/*removes characters should not belong name*/ gchar* nameify ( const char* cstr ) { const char* c; gchar* ret_val; gstring* s = g_string_new(""); gboolean uppercase_next = true; g_debug( "string = %s", cstr); ( c = cstr; *c != '0'; c = g_utf8_next_char(c) ) { gunichar cp = g_utf8_get_char(c); if ( cp == 0 ) break; if ( g_unichar_isalpha( cp ) ){ if ( uppercase_next ){ g_string_append_unichar( s, g_unichar_toupper(cp) ); uppercase_next = false; } else{ g_string_append_unichar(s,g_unichar_tolower(cp)); } } if ( cp == '-' ){ g_string_append_unichar( s, cp); uppercase_next = true; } if ( cp == ' '){ g_string_append_unichar( s, cp); uppercase_next = true; } } ret_val = s->str; g_string_free(s, false); return ret_val; } any welcome.
it's not handy connect 'changed' signal, more appropriate connect 'insert-text' signal. better have default 'insert-text' handler update entry. use g_signal_connect_after on 'insert-text' signal update text in entry prevents changed signal run infinitely. should done 'delete-text' signal, because if user deletes capital letter, capital should removed , second should capitalized.
so on creation run:
g_signal_connect_after( entry, "insert-text", g_callback(name_insert_after), null ); g_signal_connect_after( entry, "delete-text", g_callback(name_delete_after), null ); then can have these signal handlers:
void name_insert_after (gtkeditable* edit, gchar* new_text, gint new_length, gpointer position, gpointer data) { /*prevent compiler warnings unused variables*/ (void) new_text; (void) new_length; (void) position; (void) data; const gchar* content = gtk_entry_get_text( gtk_entry(edit) ); gchar* modified = nameify( content); gtk_entry_set_text(gtk_entry(edit),modified); g_free(modified); } void name_delete_after (gtkeditable* edit, gint start_pos, gint end_pos, gpointer data) { /*no op cast prevent compiler warnings*/ (void) start_pos; (void) end_pos; (void) data; /*get text , modify entry*/ int cursor_pos = gtk_editable_get_position(edit); const gchar* content = gtk_entry_get_text( gtk_entry(edit) ); gchar* modified = nameify( content); gtk_entry_set_text(gtk_entry(edit),modified); gtk_editable_set_position(edit, cursor_pos); g_free(modified); } and these can used nameify function in original post. might provide function pointer @ data instead of 'null' use 1 handler different functions able modify string in entry.
Comments
Post a Comment