diff options
-rw-r--r-- | contrib/anastasis_gtk_challenge_code.glade | 1 | ||||
-rw-r--r-- | src/anastasis/anastasis-gtk_autocomplete.c | 100 | ||||
-rw-r--r-- | src/anastasis/anastasis-gtk_handle-challenge-code.c | 25 |
3 files changed, 101 insertions, 25 deletions
diff --git a/contrib/anastasis_gtk_challenge_code.glade b/contrib/anastasis_gtk_challenge_code.glade index 8b4113e..176660e 100644 --- a/contrib/anastasis_gtk_challenge_code.glade +++ b/contrib/anastasis_gtk_challenge_code.glade @@ -235,6 +235,7 @@ Author: Christian Grothoff <property name="primary-icon-stock">gtk-dialog-authentication</property> <property name="placeholder-text" translatable="no">A-</property> <signal name="changed" handler="anastasis_gtk_c_code_dialog_answer_entry_changed_cb" swapped="no"/> + <signal name="insert-text" handler="anastasis_gtk_pin_autocomplete_insert_text" swapped="no"/> </object> <packing> <property name="expand">False</property> diff --git a/src/anastasis/anastasis-gtk_autocomplete.c b/src/anastasis/anastasis-gtk_autocomplete.c index 1e3da34..c941d25 100644 --- a/src/anastasis/anastasis-gtk_autocomplete.c +++ b/src/anastasis/anastasis-gtk_autocomplete.c @@ -50,12 +50,41 @@ lookup_autocomplete (GtkEditable *editable) } json_array_foreach (ra, index, a) { - const char *widget_name = json_string_value (json_object_get (a, - "widget")); - if (editable == - GTK_EDITABLE (GCG_get_main_window_object (ai[i].widget_name))) - return json_string_value (json_object_get (a, - "autocomplete")); + const char *autocomplete = NULL; + const char *widget_name = NULL; + const char *type = NULL; + char *data_name; + bool match; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("widget", + &widget_name)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("autocomplete", + &autocomplete)), + GNUNET_JSON_spec_string ("type", + &type), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (a, + spec, + NULL, NULL)) + { + GNUNET_break (0); + continue; + } + if ( (NULL == autocomplete) || + (NULL == widget_name) ) + continue; + data_name = AG_expand_name (widget_name, + type); + match = (editable == + GTK_EDITABLE (GCG_get_main_window_object (data_name))); + GNUNET_free (data_name); + if (match) + return autocomplete; } GNUNET_break (0); return NULL; @@ -115,10 +144,10 @@ anastasis_gtk_autocomplete_insert_text (GtkEditable *editable, void *user_data) { const char *ac; - (void) user_data; gint pos; char *replacement; + (void) user_data; ac = lookup_autocomplete (editable); if (NULL == ac) return; @@ -141,3 +170,60 @@ anastasis_gtk_autocomplete_insert_text (GtkEditable *editable, GNUNET_free (replacement); } } + + +/** + * Function called from an auto-completed PIN widget upon text insertion. + * + * @param editable the widget + * @param new_text inserted text + * @param new_text_length number of bytes in @a new_text + * @param position insertion position + * @param user_data unused + */ +void +anastasis_gtk_pin_autocomplete_insert_text (GtkEditable *editable, + const char *new_text, + int new_text_length, + gpointer position, + void *user_data) +{ + /* Use \? to break up trigraphs */ + const char *acn = "????\?-??\?-???\?-??\?"; + const char *aca = "A-????\?-??\?-???\?-??\?"; + const char *ac; + gint pos; + char *replacement; + gchar *pfx; + + (void) user_data; + pfx = gtk_editable_get_chars (editable, + 0, + 2); + if (0 == strncasecmp (pfx, + "A-", + 2)) + ac = aca; + else + ac = acn; + g_free (pfx); + + pos = gtk_editable_get_position (editable); + if (strlen (ac) <= pos + new_text_length) + return; + if (ac[pos+new_text_length] != '?') + { + g_signal_stop_emission_by_name (editable, + "insert-text"); + GNUNET_asprintf (&replacement, + "%.*s%c", + new_text_length, + new_text, + ac[pos+new_text_length]); + gtk_editable_insert_text (editable, + replacement, + -1, + position); + GNUNET_free (replacement); + } +} diff --git a/src/anastasis/anastasis-gtk_handle-challenge-code.c b/src/anastasis/anastasis-gtk_handle-challenge-code.c index 7a993da..4f42023 100644 --- a/src/anastasis/anastasis-gtk_handle-challenge-code.c +++ b/src/anastasis/anastasis-gtk_handle-challenge-code.c @@ -49,6 +49,7 @@ anastasis_gtk_c_code_dialog_response_cb (GtkDialog *dialog, json_t *args; unsigned long long pin; char dummy; + char s[16]; if (GTK_RESPONSE_OK != response_id) { @@ -65,20 +66,15 @@ anastasis_gtk_c_code_dialog_response_cb (GtkDialog *dialog, q = GTK_ENTRY (gtk_builder_get_object (builder, "anastasis_gtk_c_code_entry")); qs = gtk_entry_get_text (q); - if ( (NULL != qs) && - (0 == strncasecmp ("a-", qs, 2)) ) - qs += 2; /* skip "A-" prefix if present */ - if (1 != sscanf (qs, - "%llu%c", - &pin, - &dummy)) + if (! ANASTASIS_scan_pin (qs, + &pin)) { GNUNET_break (0); return; } args = GNUNET_JSON_PACK ( GNUNET_JSON_pack_uint64 ("pin", - pin)); + (uint64_t) pin)); gtk_widget_destroy (GTK_WIDGET (dialog)); g_object_unref (G_OBJECT (builder)); AG_freeze (); @@ -98,21 +94,14 @@ anastasis_gtk_c_code_dialog_answer_entry_changed_cb (GtkEntry *entry, GtkBuilder *builder = GTK_BUILDER (user_data); GtkEntry *a; const char *as; - unsigned int pin; - char dummy; + unsigned long long pin; bool ok; a = GTK_ENTRY (gtk_builder_get_object (builder, "anastasis_gtk_c_code_entry")); as = gtk_entry_get_text (a); - if ( (NULL != as) && - (0 == strncasecmp ("a-", as, 2)) ) - as += 2; /* skip "A-" prefix if present */ - ok = ( (NULL != as) && - (1 == sscanf (as, - "%u%c", - &pin, - &dummy)) ); + ok = ANASTASIS_scan_pin (as, + &pin); gtk_widget_set_sensitive ( GTK_WIDGET (gtk_builder_get_object (builder, "anastasis_gtk_c_code_dialog_btn_ok")), |