tFix column output of drugs available - vaccinewars - be a doctor and try to vaccinate the world
 (HTM) git clone git://src.adamsgaard.dk/vaccinewars
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 4de78172baa253ad9297d26834c41ff628204bc1
 (DIR) parent d789fa510de3ce5bd2103cdb5e496e5ce6f2d0ba
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Wed,  9 Dec 2020 19:08:18 -0800
       
       Fix column output of drugs available
       
       Previously columns did not line up properly
       in some translations due to the length in bytes
       being used rather than the length in characters
       (see #54). Also, some translations (e.g. es)
       have very long names for some drugs, so long that
       sometimes not all the drugs available can be
       shown on the screen. Truncate drug names if
       necessary to make everything fit.
       
       Diffstat:
         M po/de.po                            |       4 ++--
         M po/dopewars.pot                     |       2 +-
         M po/es.po                            |       4 ++--
         M po/es_ES.po                         |       4 ++--
         M po/fr.po                            |       4 ++--
         M po/fr_CA.po                         |       4 ++--
         M po/nn.po                            |       4 ++--
         M po/pl.po                            |       4 ++--
         M po/pt_BR.po                         |       4 ++--
         M src/curses_client/curses_client.c   |      46 ++++++++++++++++++-------------
       
       10 files changed, 44 insertions(+), 36 deletions(-)
       ---
 (DIR) diff --git a/po/de.po b/po/de.po
       t@@ -1904,8 +1904,8 @@ msgstr "Hey Kleiner, die %tde Preise von hier:"
        #. List of individual drug names for selection (%tde="Opium" etc.
        #. by default)
        #: src/curses_client/curses_client.c:2287
       -msgid "%c. %tde%s %8P"
       -msgstr "%c. %tde%s %8P"
       +msgid "%/Drug Select/%c. %tde"
       +msgstr "%c. %tde"
        
        #: src/curses_client/curses_client.c:2332
        msgid "Cannot install SIGWINCH interrupt handler!"
 (DIR) diff --git a/po/dopewars.pot b/po/dopewars.pot
       t@@ -1810,7 +1810,7 @@ msgstr ""
        #. List of individual drug names for selection (%tde="Opium" etc.
        #. by default)
        #: src/curses_client/curses_client.c:2287
       -msgid "%c. %tde%s %8P"
       +msgid "%/Drug Select/%c. %tde"
        msgstr ""
        
        #: src/curses_client/curses_client.c:2332
 (DIR) diff --git a/po/es.po b/po/es.po
       t@@ -1950,8 +1950,8 @@ msgstr "Eh, oiga. Los precios de las %tde aquí son:"
        #. List of individual drug names for selection (%tde="Opium" etc.
        #. by default)
        #: src/curses_client/curses_client.c:2287
       -msgid "%c. %tde%s %8P"
       -msgstr "%c. %tde%s %8P"
       +msgid "%/Drug Select/%c. %tde"
       +msgstr "%c. %tde"
        
        #: src/curses_client/curses_client.c:2332
        msgid "Cannot install SIGWINCH interrupt handler!"
 (DIR) diff --git a/po/es_ES.po b/po/es_ES.po
       t@@ -1952,8 +1952,8 @@ msgstr "Eh, tío. Los precios de las %tde aquí son:"
        #. List of individual drug names for selection (%tde="Opium" etc.
        #. by default)
        #: src/curses_client/curses_client.c:2287
       -msgid "%c. %tde%s %8P"
       -msgstr "%c. %tde%s %8P"
       +msgid "%/Drug Select/%c. %tde"
       +msgstr "%c. %tde"
        
        #: src/curses_client/curses_client.c:2332
        msgid "Cannot install SIGWINCH interrupt handler!"
 (DIR) diff --git a/po/fr.po b/po/fr.po
       t@@ -1890,8 +1890,8 @@ msgstr "He man, les prix du %tde sont la:"
        #. List of individual drug names for selection (%tde="Opium" etc.
        #. by default)
        #: src/curses_client/curses_client.c:2287
       -msgid "%c. %tde%s %8P"
       -msgstr "%c. %tde%s %8P"
       +msgid "%/Drug Select/%c. %tde"
       +msgstr "%c. %tde"
        
        #: src/curses_client/curses_client.c:2332
        msgid "Cannot install SIGWINCH interrupt handler!"
 (DIR) diff --git a/po/fr_CA.po b/po/fr_CA.po
       t@@ -1933,8 +1933,8 @@ msgstr "Heille man, les prix du %tde sont la:"
        #. List of individual drug names for selection (%tde="Opium" etc.
        #. by default)
        #: src/curses_client/curses_client.c:2287
       -msgid "%c. %tde%s %8P"
       -msgstr "%c. %tde%s %8P"
       +msgid "%/Drug Select/%c. %tde"
       +msgstr "%c. %tde"
        
        #: src/curses_client/curses_client.c:2332
        msgid "Cannot install SIGWINCH interrupt handler!"
 (DIR) diff --git a/po/nn.po b/po/nn.po
       t@@ -1921,8 +1921,8 @@ msgstr "Hei du. Her kostar %tbe:"
        #. List of individual drug names for selection (%tde="Opium" etc.
        #. by default)
        #: src/curses_client/curses_client.c:2287
       -msgid "%c. %tde%s %8P"
       -msgstr "%c. %tde%s %8P"
       +msgid "%/Drug Select/%c. %tde"
       +msgstr "%c. %tde"
        
        #: src/curses_client/curses_client.c:2332
        msgid "Cannot install SIGWINCH interrupt handler!"
 (DIR) diff --git a/po/pl.po b/po/pl.po
       t@@ -1879,8 +1879,8 @@ msgstr "Hej cieciu, oto %tde jakie są w obiegu:"
        #. List of individual drug names for selection (%tde="Opium" etc.
        #. by default)
        #: src/curses_client/curses_client.c:2287
       -msgid "%c. %tde%s %8P"
       -msgstr ""
       +msgid "%/Drug Select/%c. %tde"
       +msgstr "%c. %tde"
        
        #: src/curses_client/curses_client.c:2332
        msgid "Cannot install SIGWINCH interrupt handler!"
 (DIR) diff --git a/po/pt_BR.po b/po/pt_BR.po
       t@@ -1888,8 +1888,8 @@ msgstr "Ei carinha, os preços de %tde aqui estão:"
        #. List of individual drug names for selection (%tde="Opium" etc.
        #. by default)
        #: src/curses_client/curses_client.c:2287
       -msgid "%c. %tde%s %8P"
       -msgstr ""
       +msgid "%/Drug Select/%c. %tde"
       +msgstr "%c. %tde"
        
        #: src/curses_client/curses_client.c:2332
        msgid "Cannot install SIGWINCH interrupt handler!"
 (DIR) diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_client.c
       t@@ -259,6 +259,25 @@ static void g_string_pad(GString *text, int len)
          memset(text->str + curlen, ' ', len);
        }
        
       +/* Make the string the given number of characters, either by adding spaces
       +   to the end, or by truncating it */
       +static void g_string_pad_or_truncate_to_charlen(GString *text, int len)
       +{
       +  int curlen = strcharlen(text->str);
       +  if (len < 0) {
       +    return;
       +  }
       +  if (curlen < len) {
       +    g_string_pad(text, len - curlen);
       +  } else if (curlen > len) {
       +    if (LocaleIsUTF8) {
       +      /* Convert from number of characters to bytes */
       +      len = g_utf8_offset_to_pointer(text->str, len) - text->str;
       +    }
       +    g_string_truncate(text, len);
       +  }
       +}
       +
        /*
         * Displays a string, horizontally centred on the given row
         */
       t@@ -751,7 +770,7 @@ void display_select_list(GSList *names)
        
          for (listpt = names, numlist = 0; listpt;
               listpt = g_slist_next(listpt), numlist++) {
       -    maxlen = MAX(maxlen, strlen(listpt->data));
       +    maxlen = MAX(maxlen, strcharlen(listpt->data));
          }
        
          maxlen += 3;
       t@@ -2276,20 +2295,6 @@ char *nice_input(char *prompt, int sy, int sx, gboolean digitsonly,
          return ReturnString;
        }
        
       -/* Return a blank string long enough to pad `name` out to `pad_len`.
       -   This works with characters, not bytes, if in a UTF-8 locale */
       -static char *pad_name(const char *name, guint pad_len)
       -{
       -  /* 40 character blank string (must be longer than max value of pad_len) */
       -  static char *pad = "                                        ";
       -  int slen = strcharlen(name);
       -  if (slen > pad_len || slen > 40) {
       -    return "";
       -  } else {
       -    return pad + 40 - pad_len + slen;
       -  }
       -}
       -
        static void DisplayDrugsHere(Player *Play)
        {
          int NumDrugsHere, i, c;
       t@@ -2312,12 +2317,15 @@ static void DisplayDrugsHere(Player *Play)
          for (c = 0, i = GetNextDrugIndex(-1, Play);
               c < NumDrugsHere && i != -1;
               c++, i = GetNextDrugIndex(i, Play)) {
       +    char *price = FormatPrice(Play->Drugs[i].Price);
       +    GString *str = g_string_new(NULL);
            /* List of individual drug names for selection (%tde="Opium" etc.
               by default) */
       -    text = dpg_strdup_printf( _("%c. %tde%s %8P"), 'A' + c,
       -                             Drug[i].Name, pad_name(Drug[i].Name, 10),
       -                             Play->Drugs[i].Price);
       -    names = g_slist_append(names, text);
       +    dpg_string_printf(str, _("%/Drug Select/%c. %tde"), 'A' + c, Drug[i].Name);
       +    g_string_pad_or_truncate_to_charlen(str, 22 - strcharlen(price));
       +    g_string_append(str, price);
       +    g_free(price);
       +    names = g_slist_append(names, g_string_free(str, FALSE));
          }
          display_select_list(names);
          attrset(PromptAttr);