Rocco Rutte:
[apps/madmutt.git] / buffy.c
diff --git a/buffy.c b/buffy.c
index 208eaac..c955ab9 100644 (file)
--- a/buffy.c
+++ b/buffy.c
@@ -24,6 +24,7 @@
 #include "buffy.h"
 #include "mailbox.h"
 #include "mx.h"
+#include "sidebar.h"
 
 #include "mutt_curses.h"
 
 
 #include <stdio.h>
 
-static time_t BuffyTime = 0;   /* last time we started checking for mail */
-time_t BuffyDoneTime = 0;      /* last time we knew for sure how much mail there was. */
-static short BuffyCount = 0;   /* how many boxes with new mail */
-static short BuffyNotify = 0;  /* # of unnotified new boxes */
+static time_t BuffyTime = 0;            /* last time we started checking for mail */
+#ifdef USE_IMAP
+static time_t ImapBuffyTime = 0;        /* last time we started checking for mail */
+#endif
+static short BuffyCount = 0;            /* how many boxes with new mail */
+static short BuffyNotify = 0;           /* # of unnotified new boxes */
 
 #ifdef BUFFY_SIZE
 
@@ -258,6 +261,11 @@ int mutt_parse_mailboxes (BUFFER *path, BUFFER *s, unsigned long data, BUFFER *e
 #define STAT_CHECK (sb.st_mtime > sb.st_atime || (tmp->newly_created && sb.st_ctime == sb.st_mtime && sb.st_ctime == sb.st_atime))
 #endif /* BUFFY_SIZE */
 
+/* values for force:
+ * 0    don't force any checks + update sidebar
+ * 1    force all checks + update sidebar
+ * 2    force all checks + _don't_ update sidebar
+ */
 int mutt_buffy_check (int force)
 {
   BUFFY *tmp;
@@ -266,22 +274,35 @@ int mutt_buffy_check (int force)
   DIR *dirp;
   char path[_POSIX_PATH_MAX];
   struct stat contex_sb;
-  time_t t;
+  time_t now, last1;
   CONTEXT *ctx;
 #ifdef USE_IMAP
+  time_t last2;
   /* update postponed count as well, on force */
-  if (force)
+  if (force != 0)
     mutt_update_num_postponed ();
 #endif
 
   /* fastest return if there are no mailboxes */
   if (!Incoming)
     return 0;
-  t = time (NULL);
-  if (!force && (t - BuffyTime < BuffyTimeout))
+  now = time (NULL);
+  if (force == 0 && (now - BuffyTime < BuffyTimeout)
+#ifdef USE_IMAP
+      && (now - ImapBuffyTime < ImapBuffyTimeout))
+#else
+      )
+#endif
     return BuffyCount;
-  BuffyTime = t;
+
+  last1 = BuffyTime;
+  if (force != 0 || now - BuffyTime >= BuffyTimeout)
+    BuffyTime = now;
+#ifdef USE_IMAP
+  last2 = ImapBuffyTime;
+  if (force != 0 || now - ImapBuffyTime >= ImapBuffyTimeout)
+    ImapBuffyTime = now;
+#endif
   BuffyCount = 0;
   BuffyNotify = 0;
 
@@ -303,10 +324,6 @@ int mutt_buffy_check (int force)
   
   for (tmp = Incoming; tmp; tmp = tmp->next)
   {
-       if ( tmp->new == 1 )
-               tmp->has_new = 1;
-    tmp->new = 0;
-
 #ifdef USE_IMAP
     if (mx_is_imap (tmp->path))
       tmp->magic = M_IMAP;
@@ -323,7 +340,7 @@ int mutt_buffy_check (int force)
     else
 #endif
     if (stat (tmp->path, &sb) != 0 || sb.st_size == 0 ||
-       (!tmp->magic && (tmp->magic = mx_get_magic (tmp->path)) <= 0))
+       (!tmp->magic && (tmp->magic = mx_get_magic (tmp->path)) <= 0))
     {
       /* if the mailbox still doesn't exist, set the newly created flag to
        * be ready for when it does. */
@@ -338,163 +355,177 @@ int mutt_buffy_check (int force)
     /* check to see if the folder is the currently selected folder
      * before polling */
     if (!Context || !Context->path ||
-        (
-          (0
+         (
+           (0
 #ifdef USE_IMAP
-           || tmp->magic == M_IMAP
+            || tmp->magic == M_IMAP
 #endif
 #ifdef USE_POP
-           || tmp->magic == M_POP
+            || tmp->magic == M_POP
 #endif
 #ifdef USE_NNTP
-           || tmp->magic == M_NNTP
+            || tmp->magic == M_NNTP
 #endif
-          ) ? mutt_strcmp (tmp->path, Context->path) :
-              (sb.st_dev != contex_sb.st_dev || sb.st_ino != contex_sb.st_ino)
-        )
+           ) ? mutt_strcmp (tmp->path, Context->path) :
+               (sb.st_dev != contex_sb.st_dev || sb.st_ino != contex_sb.st_ino)
+         )
        )
     {
       switch (tmp->magic)
       {
       case M_MBOX:
       case M_MMDF:
-
-    {
-       if (STAT_CHECK || tmp->msgcount == 0)
-       {
-         BUFFY b = *tmp;
-         int msgcount = 0;
-         int msg_unread = 0;
-         BuffyCount++;
-         /* parse the mailbox, to see how much mail there is */
-         ctx = mx_open_mailbox( tmp->path, M_READONLY | M_QUIET | M_NOSORT,
-           NULL);
-         if(ctx)
-         {
-             msgcount = ctx->msgcount;
-             msg_unread = ctx->unread;
-             mx_close_mailbox(ctx, 0);
-         }
-         *tmp = b;
-         tmp->msgcount = msgcount;
-         tmp->msg_unread = msg_unread;
-         if(STAT_CHECK)
-             tmp->has_new = tmp->new = 1;
-       }
+        /* only check on force or $mail_check reached */
+        if (force != 0 || (now - last1 >= BuffyTimeout)) {
+          if (SidebarWidth == 0 || !option (OPTMBOXPANE)) {
+            if (STAT_CHECK) {
+              BuffyCount++;
+              tmp->new = 1;
+            }
 #ifdef BUFFY_SIZE
-       else
-       {
-         /* some other program has deleted mail from the folder */
-         tmp->size = (long) sb.st_size;
-       }
+            else
+            {
+              /* some other program has deleted mail from the folder */
+              tmp->size = (long) sb.st_size;
+            }
 #endif
-       if (tmp->newly_created &&
-           (sb.st_ctime != sb.st_mtime || sb.st_ctime != sb.st_atime))
-         tmp->newly_created = 0;
-       }
-       break;
+          } else if (SidebarWidth > 0 && option (OPTMBOXPANE) && 
+                    (STAT_CHECK || tmp->msgcount == 0)) {
+            /* sidebar visible */
+            BuffyCount++;
+            if ((ctx = mx_open_mailbox (tmp->path, M_READONLY | M_QUIET | M_NOSORT, NULL)) != NULL) {
+              tmp->msgcount = ctx->msgcount;
+              tmp->new = ctx->new;
+              tmp->msg_unread = ctx->new;       /* for sidebar, wtf? */
+              tmp->msg_flagged = ctx->flagged;
+              mx_close_mailbox (ctx, 0);
+            }
+          }
+          if (tmp->newly_created &&
+              (sb.st_ctime != sb.st_mtime || sb.st_ctime != sb.st_atime))
+            tmp->newly_created = 0;
+        } else if (tmp->new > 0)
+          BuffyCount++;
+        break;
 
       case M_MAILDIR:
-
-       snprintf (path, sizeof (path), "%s/new", tmp->path);
-       if ((dirp = opendir (path)) == NULL)
-       {
-         tmp->magic = 0;
-         break;
-       }
-       tmp->msgcount = 0;
-       tmp->msg_unread = 0;
-       while ((de = readdir (dirp)) != NULL)
-       {
-         char *p;
-         if (*de->d_name != '.' && 
-             (!(p = strstr (de->d_name, ":2,")) || !strchr (p + 3, 'T')))
-         {
-           /* one new and undeleted message is enough */
-            if (tmp->new != 1)
-           {
-               BuffyCount++;
-              tmp->has_new = tmp->new = 1;
-           }
-           tmp->msgcount++;
-           tmp->msg_unread++;
-         }
-       }
-       closedir (dirp);
-#if 1
-  /* I commented this out because it led to an infite "New mail in ..." loop,
-   * and when looking at the code, the check seems to be overly eager.
-   *   -- ak
-   */
-       snprintf (path, sizeof (path), "%s/cur", tmp->path);
-       if ((dirp = opendir (path)) == NULL)
-       {
-         tmp->magic = 0;
-         break;
-       }
-       while ((de = readdir (dirp)) != NULL)
-       {
-         char *p;
-         if (*de->d_name != '.' && 
-             (!(p = strstr (de->d_name, ":2,")) || !strchr (p + 3, 'T')))
-         {
-           /* one new and undeleted message is enough */
-           BuffyCount++;
-#if 0
-            /* we're checking for read and not new mail; 
-             * seems like copy'n'paste error
-             */
-           tmp->has_new = tmp->new = 1;
-#endif
-            tmp->msgcount++;
-         }
-       }
-       closedir (dirp);
-#endif
-       break;
+        /* only check on force or $mail_check reached */
+        if (force != 0 || (now - last1 >= BuffyTimeout)) {
+          snprintf (path, sizeof (path), "%s/new", tmp->path);
+          if ((dirp = opendir (path)) == NULL)
+          {
+            tmp->magic = 0;
+            break;
+          }
+          tmp->new = 0;
+          tmp->msg_unread = 0;
+          tmp->msgcount = 0;
+          while ((de = readdir (dirp)) != NULL)
+          {
+            char *p;
+            if (*de->d_name != '.' && 
+                (!(p = strstr (de->d_name, ":2,")) || !strchr (p + 3, 'T')))
+            {
+              /* one new and undeleted message is enough */
+              if (tmp->new == 0)
+              {
+                BuffyCount++;
+                tmp->new = 1;
+                if (SidebarWidth == 0 || !option (OPTMBOXPANE))
+                  /* if sidebar invisible -> done */
+                  break;
+              }
+              tmp->msgcount++;
+              tmp->msg_unread++;
+              tmp->new++;
+            }
+          }
+          closedir (dirp);
+
+          if (SidebarWidth > 0 && option (OPTMBOXPANE))
+          {
+            /* only count total mail if sidebar visible */
+            snprintf (path, sizeof (path), "%s/cur", tmp->path);
+            if ((dirp = opendir (path)) == NULL)
+            {
+              tmp->magic = 0;
+              break;
+            }
+            tmp->msg_flagged = 0;
+            while ((de = readdir (dirp)) != NULL)
+            {
+              char *p;
+              if (*de->d_name != '.' && (p = strstr (de->d_name, ":2,")) != NULL) {
+                if (!strchr (p + 3, 'T'))
+                  tmp->msgcount++;
+                if (strchr (p + 3, 'F'))
+                  tmp->msg_flagged++;
+              }
+            }
+            closedir (dirp);
+          }
+        } else if (tmp->new > 0)
+          /* keep current stats if !force and !$mail_check reached */
+          BuffyCount++;
+        break;
 
       case M_MH:
-       {
-      DIR *dp;
-      struct dirent *de;
-         if ((tmp->new = mh_buffy (tmp->path)) > 0)
-           BuffyCount++;
-  
-      if ((dp = opendir (path)) == NULL)
+        /* only check on force or $mail_check reached */
+        if (force != 0 || (now - last1 >= BuffyTimeout)) {
+          if ((tmp->new = mh_buffy (tmp->path)) > 0)
+            BuffyCount++;
+          if (SidebarWidth > 0 && option (OPTMBOXPANE))
+          {
+            DIR *dp;
+            struct dirent *de;
+            if ((dp = opendir (path)) == NULL)
+              break;
+            tmp->new = 0;
+            tmp->msgcount = 0;
+            tmp->msg_unread = 0;
+            while ((de = readdir (dp)))
+            {
+              if (mh_valid_message (de->d_name))
+              {
+                tmp->msgcount++;
+                tmp->msg_unread++;
+                tmp->new++;
+              }
+            }
+            closedir (dp);
+          }
+        } else if (tmp->new > 0)
+          /* keep current stats if !force and !$mail_check reached */
+          BuffyCount++;
         break;
-         tmp->msgcount = 0;
-      while ((de = readdir (dp)))
-      {
-        if (mh_valid_message (de->d_name))
-        {
-                 tmp->msgcount++;
-                 tmp->has_new = tmp->new = 1;
-        }
-      }
-      closedir (dp);
-    }
-       break;
-       
+
 #ifdef USE_IMAP
       case M_IMAP:
-         tmp->msgcount = imap_mailbox_check(tmp->path, 0);
-       if ((tmp->new = imap_mailbox_check (tmp->path, 1)) > 0) {
-         BuffyCount++;
-       }
-       else
-         tmp->new = 0;
-
-       break;
+        /* only check on force or $imap_mail_check reached */
+        if (force != 0 || (now - last2 >= ImapBuffyTimeout)) {
+          tmp->msgcount = imap_mailbox_check (tmp->path, 0);
+          if ((tmp->new = imap_mailbox_check (tmp->path, 1)) > 0) {
+            BuffyCount++;
+            tmp->msg_unread = tmp->new; /* for sidebar; wtf? */
+          }
+          else {
+            tmp->new = 0;
+            tmp->msg_unread = 0;
+          }
+        } else if (tmp->new > 0)
+          /* keep current stats if !force and !$imap_mail_check reached */
+          BuffyCount++;
+        break;
 #endif
 
 #ifdef USE_POP
       case M_POP:
-       break;
+        break;
 #endif
 
 #ifdef USE_NNTP
       case M_NNTP:
-       break;
+        break;
 #endif
       }
     }
@@ -503,13 +534,14 @@ int mutt_buffy_check (int force)
       tmp->size = (long) sb.st_size;   /* update the size */
 #endif
 
-    if (!tmp->new)
+    if (tmp->new <= 0)
       tmp->notified = 0;
     else if (!tmp->notified)
       BuffyNotify++;
+    tmp->has_new = tmp->new > 0;
   }
-
-  BuffyDoneTime = BuffyTime;
+  if (BuffyCount > 0 && force != 2)
+    draw_sidebar (CurrentMenu);
   return (BuffyCount);
 }
 
@@ -520,9 +552,11 @@ int mutt_buffy_list (void)
   char buffylist[160];
   int pos;
   int first;
-
   int have_unnotified = BuffyNotify;
-  
+
+  if (option (OPTFORCEBUFFYCHECK))
+    mutt_buffy_check (1);
+
   pos = 0;
   first = 1;
   buffylist[0] = 0;
@@ -530,7 +564,7 @@ int mutt_buffy_list (void)
   for (tmp = Incoming; tmp; tmp = tmp->next)
   {
     /* Is there new mail in this mailbox? */
-    if (!tmp->new || (have_unnotified && tmp->notified))
+    if (tmp->new <= 0 || (have_unnotified && tmp->notified))
       continue;
 
     strfcpy (path, tmp->path, sizeof (path));
@@ -558,6 +592,8 @@ int mutt_buffy_list (void)
   }
   if (!first)
   {
+    /* on new mail: redraw sidebar */
+    draw_sidebar (CurrentMenu);
     mutt_message ("%s", buffylist);
     return (1);
   }
@@ -598,7 +634,7 @@ void mutt_buffy (char *s, size_t slen)
 
   case 1:
 
-    while (tmp && !tmp->new)
+    while (tmp && tmp->new <= 0)
       tmp = tmp->next;
     if (!tmp)
     {
@@ -617,7 +653,7 @@ void mutt_buffy (char *s, size_t slen)
     {
       if (mutt_strcmp (s, tmp->path) == 0)
        count++;
-      else if (count && tmp->new)
+      else if (count && tmp->new > 0)
        break;
       tmp = tmp->next;
       if (!tmp)