From 498e95b4f04e4377a63865bde70361f4be570276 Mon Sep 17 00:00:00 2001 From: Cedric Duval Date: Mon, 26 Sep 2005 15:59:04 +0000 Subject: [PATCH] * statusline_askchoice(): handles localized keybindings for multiple choices * Use of terminal underlining to show keys if available * Fixed screen not refreshed after cancel * xstrndup() --- filter.c | 12 ++++---- ui.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++---- ui.h | 1 + xmalloc.c | 18 ++++++++++++ xmalloc.h | 1 + 5 files changed, 106 insertions(+), 11 deletions(-) diff --git a/filter.c b/filter.c index 41756ad..d2bc6ef 100644 --- a/filter.c +++ b/filter.c @@ -23,6 +23,7 @@ #include "list.h" #include "misc.h" #include "options.h" +#include "ui.h" #include "xmalloc.h" #include @@ -322,13 +323,14 @@ export_database() mvaddstr(5+filter, 2, "->"); if(selected_items()) { - /* TODO gettext: handle translated keypresses? */ - statusline_addstr(_("Export All/Selected/Cancel (A/s/c)?")); - switch( tolower(getch()) ) { - case 's': + switch(statusline_askchoice(_("Export ll, export elected, or ancel?"), S_("keybindings:all/selected/cancel|asc"), 3)) { + case 1: + break; + case 2: enum_mode = ENUM_SELECTED; break; - case 'c': + case 0: + case 3: refresh_screen(); return 1; } diff --git a/ui.c b/ui.c index 901322b..6917f77 100644 --- a/ui.c +++ b/ui.c @@ -15,6 +15,7 @@ #include #include #include "abook.h" +#include #include "ui.h" #include "edit.h" #include "database.h" @@ -231,6 +232,80 @@ statusline_addstr(const char *str) wrefresh(bottom); } +/* Same as statusline_addstr(), but hilight "" sequences if the terminal + * supports it */ +static void +statusline_addhlstr(const char *str) +{ +#if defined(A_BOLD) && defined(A_NORMAL) + const char *p = str, *start = str; + char *tmp; + int pos = 0; + + while(1) { + if(!*p || strchr("<>", *p)) { + if(p - start > 0) { + wattrset(bottom, (*p == '>') ? A_UNDERLINE : A_NORMAL); + tmp = xstrndup(start, p - start); + mvwaddstr(bottom, 1, pos, tmp); + free(tmp); + pos += p - start; + } + if(*p) { + start = p + 1; +#if 0 + /* show tag markers */ + wattrset(bottom, A_DIM); + mvwaddch(bottom, 1, pos++, *p); +#endif + } + } + + if(!*p) { + wattrset(bottom, A_NORMAL); + break; + } + + p++; + } +#else + mvwaddstr(bottom, 1, 0, str); +#endif + + refresh(); + wrefresh(bottom); +} + +int +statusline_askchoice(const char *msg, const char *choices, short dflt) +{ + char *s; + int ch; + + assert((dflt < 0) || (dflt > strlen(choices))); + + if(dflt) { + s = mkstr("%s [%c]", msg, choices[dflt - 1]); + statusline_addhlstr(s); + free(s); + } else + statusline_addhlstr(msg); + + while(1) + { + ch = tolower(getch()); + + if(ch == 7) /* ctrl+G */ + return 0; + + if(dflt && (ch == '\r')) /* default choice */ + return dflt; + + if((s = strchr(choices, ch))) + return (s - choices + 1); + } +} + char * ui_readline(char *prompt, char *s, size_t limit, bool use_completion) { @@ -544,13 +619,11 @@ ui_print_database() if(list_is_empty()) return; - statusline_addstr(_("Print All/Selected/Cancel (a/s/C)?")); - - switch(tolower(getch())) { - case 'a': + switch(statusline_askchoice(_("Print ll, print elected, or ancel?"), S_("keybindings:all/selected/cancel|asc"), 3)) { + case 1: mode = ENUM_ALL; break; - case 's': + case 2: if( !selected_items() ) { statusline_msg(_("No selected items")); return; @@ -558,7 +631,7 @@ ui_print_database() mode = ENUM_SELECTED; break; default: - clear_statusline(); + refresh_screen(); return; } diff --git a/ui.h b/ui.h index db85b59..7e1b8a8 100644 --- a/ui.h +++ b/ui.h @@ -15,6 +15,7 @@ void close_ui(); void headerline(const char *str); void refresh_screen(); int statusline_msg(const char *msg); +int statusline_askchoice(const char *msg, const char *choices, short dflt); char *ask_filename(char *prompt); int statusline_ask_boolean(char *msg, int def); void clear_statusline(); diff --git a/xmalloc.c b/xmalloc.c index ca784be..3a34e1c 100644 --- a/xmalloc.c +++ b/xmalloc.c @@ -149,3 +149,21 @@ xstrdup(const char *s) return (char *)memcpy(new, s, len + 1); } +char * +xstrndup(const char *s, size_t len) +{ + char *new; + size_t n = strlen(s); + + if(n > len) + n = len; + + new = xmalloc_inc(n, 1); + if(new == NULL) + return NULL; + + memcpy(new, s, n); + new[n] = '\0'; + + return new; +} diff --git a/xmalloc.h b/xmalloc.h index 9b0f6de..7351f12 100644 --- a/xmalloc.h +++ b/xmalloc.h @@ -17,6 +17,7 @@ void * xmalloc_inc(size_t, size_t); void * xrealloc(void *, size_t); void * xrealloc_inc(void *, size_t, size_t); char * xstrdup(const char *s); +char * xstrndup(const char *s, size_t); #define xfree(ptr) do { free(ptr); ptr = NULL; } while(0) -- 2.39.2