Nico Golde:
[apps/madmutt.git] / curs_lib.c
index 1eb0911..fcf17b6 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);
 }
@@ -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),
+  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),
+  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))
   {
@@ -651,14 +688,30 @@ void mutt_format_s_tree (char *dest,
 
 void mutt_paddstr (int n, const char *s)
 {
+  wchar_t wc;
+  int w;
+  size_t k;
   size_t len = mutt_strlen (s);
+  mbstate_t mbstate;
 
-  for (; len && *s; s += 1, len -= 1)
+  memset (&mbstate, 0, sizeof (mbstate));
+  for (; len && (k = mbrtowc (&wc, s, len, &mbstate)); s += k, len -= k)
   {
-    if (1 > n)
-      break;
-    addnstr ((char *)s, 1);
-    n -= 1;
+    if (k == (size_t)(-1) || k == (size_t)(-2))
+    {
+      k = (k == (size_t)(-1)) ? 1 : len;
+      wc = replacement_char ();
+    }
+    if (!IsWPrint (wc))
+      wc = '?';
+    w = wcwidth (wc);
+    if (w >= 0)
+    {
+      if (w > n)
+        break;
+      addnstr ((char *)s, 1);
+      n -= w;
+    }
   }
   while (n-- > 0)
     addch (' ');
@@ -667,10 +720,30 @@ void mutt_paddstr (int n, const char *s)
 /*
  * mutt_strwidth is like mutt_strlen except that it returns the width
  * refering to the number of characters cells.
- * AK: since we remove all that multibyte-character-stuff, it is equal to mutt_strlen
  */
 
 int mutt_strwidth (const char *s)
 {
-  return mutt_strlen(s);
+  wchar_t wc;
+  int w;
+  size_t k, n;
+  mbstate_t mbstate;
+
+  if (!s) return 0;
+
+  n = mutt_strlen (s);
+
+  memset (&mbstate, 0, sizeof (mbstate));
+  for (w=0; n && (k = mbrtowc (&wc, s, n, &mbstate)); s += k, n -= k)
+  {
+    if (k == (size_t)(-1) || k == (size_t)(-2))
+    {
+      k = (k == (size_t)(-1)) ? 1 : n;
+      wc = replacement_char ();
+    }
+    if (!IsWPrint (wc))
+      wc = '?';
+    w += wcwidth (wc);
+  }
+  return w;
 }