Nico Golde:
[apps/madmutt.git] / thread.c
index 03409ea..675f011 100644 (file)
--- a/thread.c
+++ b/thread.c
  *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  */ 
 
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include "mutt.h"
 #include "sort.h"
 
@@ -41,6 +45,10 @@ static int need_display_subject (CONTEXT *ctx, HEADER *hdr)
 {
   THREAD *tmp, *tree = hdr->thread;
 
+  /* if the user disabled subject hiding, display it */
+  if (!option (OPTHIDETHREADSUBJECT))
+    return (1);
+
   /* if our subject is different from our parent's, display it */
   if (hdr->subject_changed)
     return (1);
@@ -1336,3 +1344,105 @@ HASH *mutt_make_subj_hash (CONTEXT *ctx)
 
   return hash;
 }
+
+static void clean_references (THREAD *brk, THREAD *cur)
+{
+  THREAD *p;
+  LIST *ref = NULL;
+  int done = 0;
+
+  for (; cur; cur = cur->next, done = 0)
+  {
+    /* parse subthread recursively */
+    clean_references (brk, cur->child);
+
+    if (!cur->message)
+      break; /* skip pseudo-message */
+
+    /* Looking for the first bad reference according to the new threading.
+     * Optimal since Mutt stores the references in reverse order, and the
+     * first loop should match immediatly for mails respecting RFC2822. */
+    for (p = brk; !done && p; p = p->parent)
+      for (ref = cur->message->env->references; p->message && ref; ref = ref->next)
+       if (!mutt_strcasecmp (ref->data, p->message->env->message_id))
+       {
+         done = 1;
+         break;
+       }
+
+    if (done)
+    {
+      HEADER *h = cur->message;
+
+      /* clearing the References: header from obsolete Message-Id(s) */
+      mutt_free_list (&ref->next);
+
+#ifdef IMAP_EDIT_THREADS
+      if (h->new_env)
+       mutt_free_list (&h->new_env->references);
+      else
+       h->new_env = mutt_new_envelope ();
+
+      h->new_env->references = mutt_copy_list (h->env->references);
+#endif
+
+      h->refs_changed = h->changed = 1;
+    }
+  }
+}
+
+void mutt_break_thread (HEADER *hdr)
+{
+  mutt_free_list (&hdr->env->in_reply_to);
+  mutt_free_list (&hdr->env->references);
+  hdr->irt_changed = hdr->refs_changed = hdr->changed = 1;
+
+#ifdef IMAP_EDIT_THREADS
+  if (hdr->new_env)
+  {
+    mutt_free_list (&hdr->new_env->in_reply_to);
+    mutt_free_list (&hdr->new_env->references);
+  }
+  else
+    hdr->new_env = mutt_new_envelope ();
+#endif
+
+  clean_references (hdr->thread, hdr->thread->child);
+}
+
+static int link_threads (HEADER *parent, HEADER *child, CONTEXT *ctx)
+{
+  if (child == parent)
+    return 0;
+
+  mutt_break_thread (child);
+
+  child->env->in_reply_to = mutt_new_list ();
+  child->env->in_reply_to->data = safe_strdup (parent->env->message_id);
+
+#ifdef IMAP_EDIT_THREADS
+  child->new_env->in_reply_to = mutt_new_list ();
+  child->new_env->in_reply_to->data = safe_strdup (parent->env->message_id);
+#endif
+  
+  mutt_set_flag (ctx, child, M_TAG, 0);
+  
+  child->irt_changed = child->changed = 1;
+  return 1;
+}
+
+int mutt_link_threads (HEADER *cur, HEADER *last, CONTEXT *ctx)
+{
+  int i, changed = 0;
+
+  if (!last)
+  {
+    for (i = 0; i < ctx->vcount; i++)
+      if (ctx->hdrs[Context->v2r[i]]->tagged)
+       changed |= link_threads (cur, ctx->hdrs[Context->v2r[i]], ctx);
+  }
+  else
+    changed = link_threads (cur, last, ctx);
+
+  return changed;
+}