Nico Golde:
[apps/madmutt.git] / curs_lib.c
index 0f38f05..d62d651 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 1996-2002 Michael R. Elkins <me@mutt.org>
+ * Copyright (C) 2004 g10 Code GmbH
  * 
  *     This program is free software; you can redistribute it and/or modify
  *     it under the terms of the GNU General Public License as published by
  *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  */ 
 
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include "mutt.h"
 #include "mutt_menu.h"
 #include "mutt_curses.h"
@@ -57,6 +62,20 @@ void mutt_refresh (void)
   refresh ();
 }
 
+/* Make sure that the next refresh does a full refresh.  This could be
+   optmized by not doing it at all if DISPLAY is set as this might
+   indicate that a GUI based pinentry was used.  Having an option to
+   customize this is of course the Mutt way.  */
+void mutt_need_hard_redraw (void)
+{
+  if (!getenv ("DISPLAY"))
+  {
+    keypad (stdscr, TRUE);
+    clearok (stdscr, TRUE);
+    set_option (OPTNEEDREDRAW);
+  }
+}
+
 event_t mutt_getch (void)
 {
   int ch;
@@ -139,6 +158,19 @@ void mutt_clear_error (void)
     CLEARLINE (LINES-1);
 }
 
+static void fix_end_of_file (const char *data)
+{
+  FILE *fp;
+  int c;
+  
+  if ((fp = safe_fopen (data, "a+")) == NULL)
+    return;
+  fseek (fp,-1,SEEK_END);
+  if ((c = fgetc(fp)) != '\n')
+    fputc ('\n', fp);
+  safe_fclose (&fp);
+}
+
 void mutt_edit_file (const char *editor, const char *data)
 {
   char cmd[LONG_STRING];
@@ -147,6 +179,7 @@ void mutt_edit_file (const char *editor, const char *data)
   mutt_expand_file_fmt (cmd, sizeof (cmd), editor, data);
   if (mutt_system (cmd) == -1)
     mutt_error (_("Error running \"%s\"!"), cmd);
+  fix_end_of_file (data);
   keypad (stdscr, TRUE);
   clearok (stdscr, TRUE);
 }
@@ -170,7 +203,7 @@ int mutt_yesorno (const char *msg, int def)
   answer[1] = 0;
   
   reyes_ok = (expr = nl_langinfo (YESEXPR)) && expr[0] == '^' &&
-            !regcomp (&reyes, expr, REG_NOSUB|REG_EXTENDED);
+             !regcomp (&reyes, expr, REG_NOSUB|REG_EXTENDED);
   reno_ok = (expr = nl_langinfo (NOEXPR)) && expr[0] == '^' &&
             !regcomp (&reno, expr, REG_NOSUB|REG_EXTENDED);
 #endif
@@ -204,21 +237,21 @@ int mutt_yesorno (const char *msg, int def)
 #ifdef HAVE_LANGINFO_YESEXPR
     answer[0] = ch.ch;
     if (reyes_ok ? 
-       (regexec (& reyes, answer, 0, 0, 0) == 0) :
+        (regexec (& reyes, answer, 0, 0, 0) == 0) :
 #else
     if (
 #endif
-       (tolower (ch.ch) == 'y'))
+        (tolower (ch.ch) == 'y'))
     {
       def = M_YES;
       break;
     }
     else if (
 #ifdef HAVE_LANGINFO_YESEXPR
-            reno_ok ?
-            (regexec (& reno, answer, 0, 0, 0) == 0) :
+             reno_ok ?
+             (regexec (& reno, answer, 0, 0, 0) == 0) :
 #endif
-            (tolower (ch.ch) == 'n'))
+             (tolower (ch.ch) == 'n'))
     {
       def = M_NO;
       break;
@@ -263,6 +296,7 @@ void mutt_query_exit (void)
 
 void mutt_curses_error (const char *fmt, ...)
 {
+  char TmpErrorbuf[STRING];
   va_list ap;
 
   va_start (ap, fmt);
@@ -270,8 +304,9 @@ void mutt_curses_error (const char *fmt, ...)
   va_end (ap);
   
   dprint (1, (debugfile, "%s\n", Errorbuf));
-  mutt_format_string (Errorbuf, sizeof (Errorbuf),
-                     0, COLS-2, 0, 0, Errorbuf, sizeof (Errorbuf), 0);
+  mutt_format_string (TmpErrorbuf, sizeof (TmpErrorbuf),
+                      0, COLS-2, 0, 0, Errorbuf, sizeof (Errorbuf), 0);
+  snprintf(Errorbuf,sizeof(Errorbuf),"%s",TmpErrorbuf); /* overkill */
 
   if (!option (OPTKEEPQUIET))
   {
@@ -288,14 +323,16 @@ void mutt_curses_error (const char *fmt, ...)
 
 void mutt_curses_message (const char *fmt, ...)
 {
+  char TmpErrorbuf[STRING];
   va_list ap;
 
   va_start (ap, fmt);
   vsnprintf (Errorbuf, sizeof (Errorbuf), fmt, ap);
   va_end (ap);
 
-  mutt_format_string (Errorbuf, sizeof (Errorbuf),
-                     0, COLS-2, 0, 0, Errorbuf, sizeof (Errorbuf), 0);
+  mutt_format_string (TmpErrorbuf, sizeof (TmpErrorbuf),
+                      0, COLS-2, 0, 0, Errorbuf, sizeof (Errorbuf), 0);
+  snprintf(Errorbuf,sizeof(Errorbuf),"%s",TmpErrorbuf); /* overkill */
 
   if (!option (OPTKEEPQUIET))
   {
@@ -376,9 +413,9 @@ int mutt_any_key_to_continue (const char *s)
 }
 
 int mutt_do_pager (const char *banner,
-                  const char *tempfile,
-                  int do_color,
-                  pager_t *info)
+                   const char *tempfile,
+                   int do_color,
+                   pager_t *info)
 {
   int rc;
   
@@ -425,17 +462,17 @@ int _mutt_enter_fname (const char *prompt, char *buf, size_t blen, int *redraw,
     mutt_refresh ();
     buf[0] = 0;
     _mutt_select_file (buf, blen, M_SEL_FOLDER | (multiple ? M_SEL_MULTI : 0), 
-                      files, numfiles);
+                       files, numfiles);
     *redraw = REDRAW_FULL;
   }
   else
   {
     char *pc = safe_malloc (mutt_strlen (prompt) + 3);
 
-    sprintf (pc, "%s: ", prompt);      /* __SPRINTF_CHECKED__ */
+    sprintf (pc, "%s: ", prompt);        /* __SPRINTF_CHECKED__ */
     mutt_ungetch (ch.op ? 0 : ch.ch, ch.op ? ch.op : 0);
     if (_mutt_get_field (pc, buf, blen, (buffy ? M_EFILE : M_FILE) | M_CLEAR, multiple, files, numfiles)
-       != 0)
+        != 0)
       buf[0] = 0;
     MAYBE_REDRAW (*redraw);
     FREE (&pc);
@@ -479,8 +516,8 @@ void mutt_curs_set (int cursor)
     SavedCursor = cursor;
   
   if (curs_set (cursor) == ERR) {
-    if (cursor == 1)   /* cnorm */
-      curs_set (2);    /* cvvis */
+    if (cursor == 1)        /* cnorm */
+      curs_set (2);        /* cvvis */
   }
 }
 #endif
@@ -507,14 +544,14 @@ int mutt_multi_choice (char *prompt, char *letters)
       p = strchr (letters, ch.ch);
       if (p)
       {
-       choice = p - letters + 1;
-       break;
+        choice = p - letters + 1;
+        break;
       }
       else if (ch.ch <= '9' && ch.ch > '0')
       {
-       choice = ch.ch - '0';
-       if (choice <= mutt_strlen (letters))
-         break;
+        choice = ch.ch - '0';
+        if (choice <= mutt_strlen (letters))
+          break;
       }
     }
     BEEP ();
@@ -551,29 +588,47 @@ int mutt_addwch (wchar_t wc)
  */
 
 void mutt_format_string (char *dest, size_t destlen,
-                        int min_width, int max_width,
-                        int right_justify, char m_pad_char,
-                        const char *s, size_t n,
-                        int arboreal)
+                         int min_width, int max_width,
+                         int right_justify, char m_pad_char,
+                         const char *s, size_t n,
+                         int arboreal)
 {
   char *p;
+  wchar_t wc;
   int w;
   size_t k, k2;
   char scratch[MB_LEN_MAX];
+  mbstate_t mbstate1, mbstate2;
 
+  memset(&mbstate1, 0, sizeof (mbstate1));
+  memset(&mbstate2, 0, sizeof (mbstate2));
   --destlen;
   p = dest;
-  for (; n; s+=1, n-=1)
+  for (; n && (k = mbrtowc (&wc, s, n, &mbstate1)); s += k, n -= k)
   {
-    w = 1;
-    k2 = 1;
-    if (w > max_width)
+    if (k == (size_t)(-1) || k == (size_t)(-2))
+    {
+      k = (k == (size_t)(-1)) ? 1 : n;
+      wc = replacement_char ();
+    }
+    if (arboreal && wc < M_TREE_MAX)
+      w = 1; /* hack */
+    else
+    {
+      if (!IsWPrint (wc))
+       wc = '?';
+      w = wcwidth (wc);
+    }
+    if (w >= 0)
+    {
+      if (w > max_width || (k2 = wcrtomb (scratch, wc, &mbstate2)) > destlen)
         break;
-    min_width -= w;
-    max_width -= w;
-    strncpy (p, s, k2);
-    p += k2;            
-    destlen -= k2;
+      min_width -= w;
+      max_width -= w;
+      strncpy (p, scratch, k2);
+      p += k2;            
+      destlen -= k2;
+    }
   }
   w = (int)destlen < min_width ? destlen : min_width;
   if (w <= 0)
@@ -603,10 +658,10 @@ void mutt_format_string (char *dest, size_t destlen,
  */
 
 static void mutt_format_s_x (char *dest,
-                            size_t destlen,
-                            const char *prefix,
-                            const char *s,
-                            int arboreal)
+                             size_t destlen,
+                             const char *prefix,
+                             const char *s,
+                             int arboreal)
 {
   int right_justify = 1;
   char *p;
@@ -625,21 +680,21 @@ static void mutt_format_s_x (char *dest,
   }
 
   mutt_format_string (dest, destlen, min_width, max_width,
-                     right_justify, ' ', s, mutt_strlen (s), arboreal);
+                      right_justify, ' ', s, mutt_strlen (s), arboreal);
 }
 
 void mutt_format_s (char *dest,
-                   size_t destlen,
-                   const char *prefix,
-                   const char *s)
+                    size_t destlen,
+                    const char *prefix,
+                    const char *s)
 {
   mutt_format_s_x (dest, destlen, prefix, s, 0);
 }
 
 void mutt_format_s_tree (char *dest,
-                        size_t destlen,
-                        const char *prefix,
-                        const char *s)
+                         size_t destlen,
+                         const char *prefix,
+                         const char *s)
 {
   mutt_format_s_x (dest, destlen, prefix, s, 1);
 }
@@ -671,8 +726,8 @@ void mutt_paddstr (int n, const char *s)
     if (w >= 0)
     {
       if (w > n)
-       break;
-      addnstr ((char *)s, k);
+        break;
+      addnstr ((char *)s, 1);
       n -= w;
     }
   }