diff options
Diffstat (limited to 'src/anastasis/anastasis-gtk_autocomplete.c')
-rw-r--r-- | src/anastasis/anastasis-gtk_autocomplete.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/anastasis/anastasis-gtk_autocomplete.c b/src/anastasis/anastasis-gtk_autocomplete.c new file mode 100644 index 0000000..1e3da34 --- /dev/null +++ b/src/anastasis/anastasis-gtk_autocomplete.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | This file is part of anastasis-gtk. | ||
3 | Copyright (C) 2021 Anastasis SARL | ||
4 | |||
5 | Anastasis is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | Anastasis is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with Anastasis; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file src/anastasis/anastasis-gtk_autocomplete.c | ||
22 | * @brief Autocomplete logic for GtkEntry widgets | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include <gnunet/platform.h> | ||
26 | #include <gnunet/gnunet_util_lib.h> | ||
27 | #include "anastasis-gtk_attributes.h" | ||
28 | #include "anastasis-gtk_dispatch.h" | ||
29 | #include "anastasis-gtk_helper.h" | ||
30 | #include <jansson.h> | ||
31 | |||
32 | |||
33 | /** | ||
34 | * Lookup autocompletion string for @a editable widget. | ||
35 | * | ||
36 | * @param editable widget to lookup | ||
37 | * @return NULL if not found | ||
38 | */ | ||
39 | static const char * | ||
40 | lookup_autocomplete (GtkEditable *editable) | ||
41 | { | ||
42 | json_t *a; | ||
43 | size_t index; | ||
44 | json_t *ra = json_object_get (AG_redux_state, | ||
45 | "required_attributes"); | ||
46 | if (NULL == ra) | ||
47 | { | ||
48 | GNUNET_break (0); | ||
49 | return NULL; | ||
50 | } | ||
51 | json_array_foreach (ra, index, a) | ||
52 | { | ||
53 | const char *widget_name = json_string_value (json_object_get (a, | ||
54 | "widget")); | ||
55 | if (editable == | ||
56 | GTK_EDITABLE (GCG_get_main_window_object (ai[i].widget_name))) | ||
57 | return json_string_value (json_object_get (a, | ||
58 | "autocomplete")); | ||
59 | } | ||
60 | GNUNET_break (0); | ||
61 | return NULL; | ||
62 | } | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Function called from an auto-completed entry widget up on upon text | ||
67 | * deletion. | ||
68 | * | ||
69 | * @param editable the widget | ||
70 | * @param start_pos starting position | ||
71 | * @param end_pos end position | ||
72 | * @param user_data unused | ||
73 | */ | ||
74 | void | ||
75 | anastasis_gtk_autocomplete_delete_text (GtkEditable *editable, | ||
76 | int start_pos, | ||
77 | int end_pos, | ||
78 | void *user_data) | ||
79 | { | ||
80 | const char *ac; | ||
81 | (void) user_data; | ||
82 | |||
83 | ac = lookup_autocomplete (editable); | ||
84 | if (NULL == ac) | ||
85 | return; | ||
86 | if (0 == start_pos) | ||
87 | return; | ||
88 | #if CONFUSING_UX_DESIRED | ||
89 | if (ac[start_pos] != '?') | ||
90 | { | ||
91 | g_signal_stop_emission_by_name (editable, | ||
92 | "delete-text"); | ||
93 | gtk_editable_delete_text (editable, | ||
94 | start_pos - 1, | ||
95 | end_pos); | ||
96 | } | ||
97 | #endif | ||
98 | } | ||
99 | |||
100 | |||
101 | /** | ||
102 | * Function called from an auto-completed widget upon text insertion. | ||
103 | * | ||
104 | * @param editable the widget | ||
105 | * @param new_text inserted text | ||
106 | * @param new_text_length number of bytes in @a new_text | ||
107 | * @param position insertion position | ||
108 | * @param user_data unused | ||
109 | */ | ||
110 | void | ||
111 | anastasis_gtk_autocomplete_insert_text (GtkEditable *editable, | ||
112 | const char *new_text, | ||
113 | int new_text_length, | ||
114 | gpointer position, | ||
115 | void *user_data) | ||
116 | { | ||
117 | const char *ac; | ||
118 | (void) user_data; | ||
119 | gint pos; | ||
120 | char *replacement; | ||
121 | |||
122 | ac = lookup_autocomplete (editable); | ||
123 | if (NULL == ac) | ||
124 | return; | ||
125 | pos = gtk_editable_get_position (editable); | ||
126 | if (strlen (ac) <= pos + new_text_length) | ||
127 | return; | ||
128 | if (ac[pos+new_text_length] != '?') | ||
129 | { | ||
130 | g_signal_stop_emission_by_name (editable, | ||
131 | "insert-text"); | ||
132 | GNUNET_asprintf (&replacement, | ||
133 | "%.*s%c", | ||
134 | new_text_length, | ||
135 | new_text, | ||
136 | ac[pos+new_text_length]); | ||
137 | gtk_editable_insert_text (editable, | ||
138 | replacement, | ||
139 | -1, | ||
140 | position); | ||
141 | GNUNET_free (replacement); | ||
142 | } | ||
143 | } | ||