1 /*
2  * $Id: msgno.h 1142 2008-08-13 17:22:21Z hubert@u.washington.edu $
3  *
4  * ========================================================================
5  * Copyright 2013-2021 Eduardo Chappa
6  * Copyright 2006 University of Washington
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * ========================================================================
15  */
16 
17 #ifndef PITH_MSGNO_INCLUDED
18 #define PITH_MSGNO_INCLUDED
19 
20 
21 #include "../pith/sorttype.h"
22 
23 
24 /*
25  * Macros to support anything you'd ever want to do with a message
26  * number...
27  */
28 #define	mn_init(P, m)		msgno_init((P), (m), \
29 					   ps_global->def_sort, ps_global->def_sort_rev)
30 
31 #define	mn_get_cur(p)		(((p) && (p)->select) 			      \
32 				  ? (p)->select[(p)->sel_cur] : -1)
33 
34 #define	mn_set_cur(p, m)	do{					      \
35 				  if(p){				      \
36 				    (p)->select[(p)->sel_cur] = (m);	      \
37 				  }					      \
38 				}while(0)
39 
40 #define	mn_inc_cur(s, p, f)	msgno_inc(s, p, f)
41 
42 #define	mn_dec_cur(s, p, f)	msgno_dec(s, p, f)
43 
44 #define	mn_add_cur(p, m)	do{					      \
45 				  if(p){				      \
46 				      if((p)->sel_cnt+1L > (p)->sel_size){    \
47 					  (p)->sel_size += 10L;		      \
48 					  fs_resize((void **)&((p)->select),  \
49 						    (size_t)(p)->sel_size     \
50 						             * sizeof(long)); \
51 				      }					      \
52 				      (p)->select[((p)->sel_cnt)++] = (m);    \
53 				  }					      \
54 				}while(0)
55 
56 #define	mn_total_cur(p)		((p) ? (p)->sel_cnt : 0L)
57 
58 #define	mn_first_cur(p)		(((p) && (p)->sel_cnt > 0L)		      \
59 				  ? (p)->select[(p)->sel_cur = 0] : 0L)
60 
61 #define	mn_next_cur(p)		(((p) && ((p)->sel_cur + 1) < (p)->sel_cnt)   \
62 				  ? (p)->select[++((p)->sel_cur)] : -1L)
63 
64 #define	mn_is_cur(p, m)		msgno_in_select((p), (m))
65 
66 #define	mn_reset_cur(p, m)	do{					      \
67 				  if(p){				      \
68 				      (p)->sel_cur  = 0L;		      \
69 				      (p)->sel_cnt  = 1L;		      \
70 				      (p)->sel_size = 8L;		      \
71 				      fs_resize((void **)&((p)->select),      \
72 					(size_t)(p)->sel_size * sizeof(long));\
73 				      (p)->select[0] = (m);		      \
74 				  }					      \
75 			        }while(0)
76 
77 #define	mn_m2raw(p, m)		(((p) && (p)->sort && (m) > 0 		      \
78 				  && (m) <= mn_get_total(p)) 		      \
79 				   ? (p)->sort[m] : 0L)
80 
81 #define	mn_raw2m(p, m)		(((p) && (p)->isort && (m) > 0 		      \
82 				  && (m) <= mn_get_nmsgs(p)) 		      \
83 				   ? (p)->isort[m] : 0L)
84 
85 #define	mn_get_total(p)		((p) ? (p)->max_msgno : 0L)
86 
87 #define	mn_set_total(p, m)	do{ if(p) (p)->max_msgno = (m); }while(0)
88 
89 #define	mn_get_nmsgs(p)		((p) ? (p)->nmsgs : 0L)
90 
91 #define	mn_set_nmsgs(p, m)	do{ if(p) (p)->nmsgs = (m); }while(0)
92 
93 #define	mn_add_raw(p, m)	msgno_add_raw((p), (m))
94 
95 #define	mn_flush_raw(p, m)	msgno_flush_raw((p), (m))
96 
97 #define	mn_get_sort(p)		((p) ? (p)->sort_order : SortArrival)
98 
99 #define	mn_set_sort(p, t)	msgno_set_sort((p), (t))
100 
101 #define	mn_get_revsort(p)	((p) ? (p)->reverse_sort : 0)
102 
103 #define	mn_set_revsort(p, t)	do{					      \
104 				  if(p)					      \
105 				    (p)->reverse_sort = (t);		      \
106 				}while(0)
107 
108 #define	mn_get_mansort(p)	((p) ? (p)->manual_sort : 0)
109 
110 #define	mn_set_mansort(p, t)	do{					      \
111 				  if(p)					      \
112 				    (p)->manual_sort = (t);		      \
113 				}while(0)
114 
115 #define	mn_give(P)		msgno_give(P)
116 
117 
118 /*
119  * This is *the* struct that keeps track of the pine message number to
120  * raw c-client sequence number mappings.  The mapping is necessary
121  * because pine may re-sort or even hide (exclude) c-client numbers
122  * from the displayed list of messages.  See mailindx.c:msgno_* and
123  * the mn_* macros above for how this things gets used.  See
124  * mailcmd.c:pseudo_selected for an explanation of the funny business
125  * going on with the "hilited" field...
126  */
127 typedef struct msg_nos {
128     long      *select,				/* selected message array  */
129 	       sel_cur,				/* current interesting msg */
130 	       sel_cnt,				/* its size		   */
131 	       sel_size,			/* its size		   */
132               *sort,				/* sorted array of msgno's */
133                sort_size,			/* its size		   */
134               *isort,				/* inverse of sort array   */
135                isort_size,			/* its size		   */
136 	       max_msgno,			/* total messages in table */
137 	       nmsgs,				/* total msgs in folder    */
138 	       hilited,				/* holder for "current" msg*/
139 	       top,				/* message at top of screen*/
140 	       max_thrdno,
141 	       top_after_thrd;			/* top after thrd view     */
142     SortOrder  sort_order;			/* list's current sort     */
143     unsigned   reverse_sort:1;			/* whether that's reversed */
144     unsigned   manual_sort:1;			/* sorted with $ command   */
145     long       flagged_hid,			/* hidden count		   */
146 	       flagged_exld,			/* excluded count	   */
147 	       flagged_coll,			/* collapsed count	   */
148 	       flagged_chid,			/* collapsed-hidden count  */
149 	       flagged_chid2,			/* */
150 	       flagged_usor,			/* new unsorted mail	   */
151 	       flagged_tmp,			/* tmp flagged count	   */
152 	       flagged_stmp,			/* stmp flagged count	   */
153 	       flagged_invisible,		/* this one's different    */
154 	       flagged_srch,			/* search result/not slctd */
155 	       visible_threads;			/* so is this one          */
156 } MSGNO_S;
157 
158 
159 #define	MSG_EX_DELETE	  0x0001	/* part is deleted */
160 #define	MSG_EX_RECENT	  0x0002
161 #define	MSG_EX_TESTED	  0x0004	/* filtering has been run on this msg */
162 #define	MSG_EX_FILTERED	  0x0008	/* msg has actually been filtered away*/
163 #define	MSG_EX_FILED	  0x0010	/* msg has been filed */
164 #define	MSG_EX_FILTONCE	  0x0020
165 #define	MSG_EX_FILEONCE	  0x0040	/* These last two mean that the
166 					   message has been filtered or filed
167 					   already but the filter rule was
168 					   non-terminating so it is still
169 					   possible it will get filtered
170 					   again. When we're done, we flip
171 					   these two to EX_FILTERED and
172 					   EX_FILED, the permanent versions. */
173 #define	MSG_EX_PEND_EXLD  0x0080	/* pending exclusion */
174 #define	MSG_EX_MANUNDEL   0x0100	/* has been manually undeleted */
175 #define	MSG_EX_STATECHG	  0x0200	/* state change since filtering */
176 
177 /* msgno_include flags */
178 #define	MI_NONE		0x00
179 #define	MI_REFILTERING	0x01
180 #define	MI_STATECHGONLY	0x02
181 #define	MI_CLOSING	0x04
182 
183 
184 /* exported prototypes */
185 void	    msgno_init(MSGNO_S **, long, SortOrder, int);
186 void        msgno_reset_isort(MSGNO_S *);
187 void	    msgno_give(MSGNO_S **);
188 void	    msgno_inc(MAILSTREAM *, MSGNO_S *, int);
189 void	    msgno_dec(MAILSTREAM *, MSGNO_S *, int);
190 void	    msgno_exclude_deleted(MAILSTREAM *, MSGNO_S *, char *);
191 void	    msgno_exclude(MAILSTREAM *, MSGNO_S *, long, int);
192 int	    msgno_include(MAILSTREAM *, MSGNO_S *, int);
193 void	    msgno_add_raw(MSGNO_S *, long);
194 void	    msgno_flush_raw(MSGNO_S *, long);
195 void        msgno_flush_selected(MSGNO_S *, long);
196 void	    msgno_set_sort(MSGNO_S *, SortOrder);
197 int	    msgno_in_select(MSGNO_S *, long);
198 int	    msgno_exceptions(MAILSTREAM *, long, char *, int *, int);
199 int	    msgno_any_deletedparts(MAILSTREAM *, MSGNO_S *);
200 int	    msgno_part_deleted(MAILSTREAM *, long, char *);
201 long        get_msg_score(MAILSTREAM *, long);
202 void        clear_msg_score(MAILSTREAM *, long);
203 void        clear_folder_scores(MAILSTREAM *);
204 int         calculate_some_scores(MAILSTREAM *, SEARCHSET *, int);
205 void	    free_pine_elt(void **);
206 
207 
208 #endif /* PITH_MSGNO_INCLUDED */
209