aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils.c
diff options
context:
space:
mode:
authorLars Henriksen <LarsHenriksen@get2net.dk>2018-02-14 20:28:01 +0100
committerLukas Fleischer <lfleischer@calcurse.org>2018-06-03 11:28:46 +0200
commit500b0c080e53c40dc46bbc05e94575b32fa72499 (patch)
tree8e19970656ce2200b117c6eb3ea609f4ef57dbb7 /src/utils.c
parent7078556f9d055cb46339d436add2a03cc8abbc71 (diff)
downloadcalcurse-500b0c080e53c40dc46bbc05e94575b32fa72499.tar.gz
calcurse-500b0c080e53c40dc46bbc05e94575b32fa72499.zip
Support UTF-8 encoded characters in user choices
Translations (in po-files) of texts that are used for alternative choices (e.g. [dwmy]), may use UTF-8 encoded Unicode characters (e.g. [éãüå]). Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
Diffstat (limited to 'src/utils.c')
-rw-r--r--src/utils.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/utils.c b/src/utils.c
index 495b8fc..bb90e36 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -192,7 +192,7 @@ void status_mesg(const char *msg1, const char *msg2)
/*
* Prompts the user to make a choice between named alternatives.
*
- * The available choices are described by a string of the form
+ * The available choices are described (in po-files) by a string of the form
* "[ynp]". The first and last char are ignored (they are only here to
* make the translators' life easier), and every other char indicates
* a key the user is allowed to press.
@@ -203,25 +203,36 @@ void status_mesg(const char *msg1, const char *msg2)
int status_ask_choice(const char *message, const char choice[],
int nb_choice)
{
- /* "[4/2/f/t/w/.../Z] " */
- char avail_choice[2 * nb_choice + 3];
- int i, ch;
+ /* Turn "[42w...Z]" into * "[4/2/w/.../Z]". */
+ char avail_choice[nb_choice * UTF8_MAXLEN + nb_choice + 1];
+ int ichoice[nb_choice];
+ int i, j, k, n, ch;
avail_choice[0] = '[';
- for (i = 1; i <= nb_choice; i++) {
- avail_choice[i * 2 - 1] = choice[i];
- avail_choice[i * 2] = '/';
+ for (n = 0, i = 1, j = 1; n < nb_choice; n++, i += k) {
+ for (k = 0; k < UTF8_LENGTH(choice[i]); k++) {
+ avail_choice[j] = choice[i + k];
+ j++;
+ }
+ avail_choice[j] = '/';
+ j++;
}
- avail_choice[nb_choice * 2] = ']';
- avail_choice[nb_choice * 2 + 1] = '\0';
+ avail_choice[j - 1] = ']';
+ avail_choice[j] = '\0';
status_mesg(message, avail_choice);
+ /* Convert the character choices to internal integer codes. */
+ for (n = 0, i = 1; n < nb_choice; n++, i += j) {
+ j = UTF8_LENGTH(choice[i]);
+ ichoice[n] = utf8_decode(choice + i) + (j > 1 ? KEY_MAX : 0);
+ }
+
for (;;) {
ch = keys_wgetch(win[KEY].p);
- for (i = 1; i <= nb_choice; i++)
- if (ch == choice[i])
- return i;
+ for (i = 0; i < nb_choice; i++)
+ if (ch == ichoice[i])
+ return i + 1;
if (ch == ESCAPE)
return (-1);
if (resize) {