⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 3 页
字号:
  ctx->tree = top.child;  check_subjects (ctx, init);  if (!option (OPTSTRICTTHREADS))    pseudo_threads (ctx);  if (ctx->tree)  {    ctx->tree = mutt_sort_subthreads (ctx->tree, init);    /* restore the oldsort order. */    Sort = oldsort;        /* Put the list into an array. */    linearize_tree (ctx);    /* Draw the thread tree. */    mutt_draw_tree (ctx);  }}static HEADER *find_virtual (THREAD *cur, int reverse){  THREAD *top;  if (cur->message && cur->message->virtual >= 0)    return (cur->message);  top = cur;  if ((cur = cur->child) == NULL)    return (NULL);  while (reverse && cur->next)    cur = cur->next;  FOREVER  {    if (cur->message && cur->message->virtual >= 0)      return (cur->message);    if (cur->child)    {      cur = cur->child;      while (reverse && cur->next)	cur = cur->next;    }    else if (reverse ? cur->prev : cur->next)      cur = reverse ? cur->prev : cur->next;    else    {      while (!(reverse ? cur->prev : cur->next))      {	cur = cur->parent;	if (cur == top)	  return (NULL);      }      cur = reverse ? cur->prev : cur->next;    }    /* not reached */  }}int _mutt_aside_thread (HEADER *hdr, short dir, short subthreads){  THREAD *cur;  HEADER *tmp;  if ((Sort & SORT_MASK) != SORT_THREADS)  {    mutt_error _("Threading is not enabled.");    return (hdr->virtual);  }  cur = hdr->thread;  if (!subthreads)  {    while (cur->parent)      cur = cur->parent;  }  else  {    if ((dir != 0) ^ ((Sort & SORT_REVERSE) != 0))    {      while (!cur->next && cur->parent)	cur = cur->parent;    }    else    {      while (!cur->prev && cur->parent)	cur = cur->parent;    }  }  if ((dir != 0) ^ ((Sort & SORT_REVERSE) != 0))  {    do    {       cur = cur->next;      if (!cur)	return (-1);      tmp = find_virtual (cur, 0);    } while (!tmp);  }  else  {    do    {       cur = cur->prev;      if (!cur)	return (-1);      tmp = find_virtual (cur, 1);    } while (!tmp);  }  return (tmp->virtual);}int mutt_parent_message (CONTEXT *ctx, HEADER *hdr){  THREAD *thread;  if ((Sort & SORT_MASK) != SORT_THREADS)  {    mutt_error _("Threading is not enabled.");    return (hdr->virtual);  }  for (thread = hdr->thread->parent; thread; thread = thread->parent)  {    if ((hdr = thread->message) != NULL)    {      if (VISIBLE (hdr, ctx))	return (hdr->virtual);      else      {	mutt_error _("Parent message is not visible in this limited view.");	return (-1);      }    }  }    mutt_error _("Parent message is not available.");  return (-1);}void mutt_set_virtual (CONTEXT *ctx){  int i;  HEADER *cur;  ctx->vcount = 0;  ctx->vsize = 0;  for (i = 0; i < ctx->msgcount; i++)  {    cur = ctx->hdrs[i];    if (cur->virtual >= 0)    {      cur->virtual = ctx->vcount;      ctx->v2r[ctx->vcount] = i;      ctx->vcount++;      ctx->vsize += cur->content->length + cur->content->offset - cur->content->hdr_offset;      cur->num_hidden = mutt_get_hidden (ctx, cur);    }  }}int _mutt_traverse_thread (CONTEXT *ctx, HEADER *cur, int flag){  THREAD *thread, *top;  HEADER *roothdr = NULL;  int final, reverse = (Sort & SORT_REVERSE), minmsgno;  int num_hidden = 0, new = 0, old = 0;  int min_unread_msgno = INT_MAX, min_unread = cur->virtual;#define CHECK_LIMIT (!ctx->pattern || cur->limited)  if ((Sort & SORT_MASK) != SORT_THREADS && !(flag & M_THREAD_GET_HIDDEN))  {    mutt_error (_("Threading is not enabled."));    return (cur->virtual);  }  final = cur->virtual;  thread = cur->thread;  while (thread->parent)    thread = thread->parent;  top = thread;  while (!thread->message)    thread = thread->child;  cur = thread->message;  minmsgno = cur->msgno;  if (!cur->read && CHECK_LIMIT)  {    if (cur->old)      old = 2;    else      new = 1;    if (cur->msgno < min_unread_msgno)    {      min_unread = cur->virtual;      min_unread_msgno = cur->msgno;    }  }  if (cur->virtual == -1 && CHECK_LIMIT)    num_hidden++;  if (flag & (M_THREAD_COLLAPSE | M_THREAD_UNCOLLAPSE))  {    cur->pair = 0; /* force index entry's color to be re-evaluated */    cur->collapsed = flag & M_THREAD_COLLAPSE;    if (cur->virtual != -1)    {      roothdr = cur;      if (flag & M_THREAD_COLLAPSE)	final = roothdr->virtual;    }  }  if (thread == top && (thread = thread->child) == NULL)  {    /* return value depends on action requested */    if (flag & (M_THREAD_COLLAPSE | M_THREAD_UNCOLLAPSE))      return (final);    else if (flag & M_THREAD_UNREAD)      return ((old && new) ? new : (old ? old : new));    else if (flag & M_THREAD_GET_HIDDEN)      return (num_hidden);    else if (flag & M_THREAD_NEXT_UNREAD)      return (min_unread);  }    FOREVER  {    cur = thread->message;    if (cur)    {      if (flag & (M_THREAD_COLLAPSE | M_THREAD_UNCOLLAPSE))      {	cur->pair = 0; /* force index entry's color to be re-evaluated */	cur->collapsed = flag & M_THREAD_COLLAPSE;	if (!roothdr && CHECK_LIMIT)	{	  roothdr = cur;	  if (flag & M_THREAD_COLLAPSE)	    final = roothdr->virtual;	}	if (reverse && (flag & M_THREAD_COLLAPSE) && (cur->msgno < minmsgno) && CHECK_LIMIT)	{	  minmsgno = cur->msgno;	  final = cur->virtual;	}	if (flag & M_THREAD_COLLAPSE)	{	  if (cur != roothdr)	    cur->virtual = -1;	}	else 	{	  if (CHECK_LIMIT)	    cur->virtual = cur->msgno;	}      }      if (!cur->read && CHECK_LIMIT)      {	if (cur->old)	  old = 2;	else	  new = 1;	if (cur->msgno < min_unread_msgno)	{	  min_unread = cur->virtual;	  min_unread_msgno = cur->msgno;	}      }      if (cur->virtual == -1 && CHECK_LIMIT)	num_hidden++;    }    if (thread->child)      thread = thread->child;    else if (thread->next)      thread = thread->next;    else    {      int done = 0;      while (!thread->next)      {	thread = thread->parent;	if (thread == top)	{	  done = 1;	  break;	}      }      if (done)	break;      thread = thread->next;    }  }  /* return value depends on action requested */  if (flag & (M_THREAD_COLLAPSE | M_THREAD_UNCOLLAPSE))    return (final);  else if (flag & M_THREAD_UNREAD)    return ((old && new) ? new : (old ? old : new));  else if (flag & M_THREAD_GET_HIDDEN)    return (num_hidden+1);  else if (flag & M_THREAD_NEXT_UNREAD)    return (min_unread);  return (0);#undef CHECK_LIMIT}/* if flag is 0, we want to know how many messages * are in the thread.  if flag is 1, we want to know * our position in the thread. */int mutt_messages_in_thread (CONTEXT *ctx, HEADER *hdr, int flag){  THREAD *threads[2];  int i, rc;  if ((Sort & SORT_MASK) != SORT_THREADS || !hdr->thread)    return (1);  threads[0] = hdr->thread;  while (threads[0]->parent)    threads[0] = threads[0]->parent;  threads[1] = flag ? hdr->thread : threads[0]->next;  for (i = 0; i < ((flag || !threads[1]) ? 1 : 2); i++)  {    while (!threads[i]->message)      threads[i] = threads[i]->child;  }   if (Sort & SORT_REVERSE)    rc = threads[0]->message->msgno - (threads[1] ? threads[1]->message->msgno : -1);  else    rc = (threads[1] ? threads[1]->message->msgno : ctx->msgcount) - threads[0]->message->msgno;    if (flag)    rc += 1;    return (rc);}HASH *mutt_make_id_hash (CONTEXT *ctx){  int i;  HEADER *hdr;  HASH *hash;  hash = hash_create (ctx->msgcount * 2);  for (i = 0; i < ctx->msgcount; i++)  {    hdr = ctx->hdrs[i];    if (hdr->env->message_id)      hash_insert (hash, hdr->env->message_id, hdr, 0);  }  return hash;}HASH *mutt_make_subj_hash (CONTEXT *ctx){  int i;  HEADER *hdr;  HASH *hash;  hash = hash_create (ctx->msgcount * 2);  for (i = 0; i < ctx->msgcount; i++)  {    hdr = ctx->hdrs[i];    if (hdr->env->real_subj)      hash_insert (hash, hdr->env->real_subj, hdr, 1);  }  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);      h->env->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->env->irt_changed = hdr->env->refs_changed = hdr->changed = 1;  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);    mutt_set_flag (ctx, child, M_TAG, 0);    child->env->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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -