Skip to content
Newer
Older
100644 384 lines (337 sloc) 7.38 KB
14c2920 Imported Upstream version 1.5.18
Antonio Radici authored May 24, 2009
1 /*
2 * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #if HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 #include "mutt.h"
24 #include "mutt_curses.h"
25 #include "sort.h"
26 #include "mx.h"
27
28 void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
29 {
30 int changed = h->changed;
31 int deleted = ctx->deleted;
32 int tagged = ctx->tagged;
33 int flagged = ctx->flagged;
34 int update = 0;
35
36 if (ctx->readonly && flag != M_TAG)
37 return; /* don't modify anything if we are read-only */
38
39 switch (flag)
40 {
41 case M_DELETE:
42
43 if (!mutt_bit_isset(ctx->rights,M_ACL_DELETE))
44 return;
45
46 if (bf)
47 {
48 if (!h->deleted && !ctx->readonly)
49 {
50 h->deleted = 1;
51 update = 1;
52 if (upd_ctx) ctx->deleted++;
53 #ifdef USE_IMAP
54 /* deleted messages aren't treated as changed elsewhere so that the
55 * purge-on-sync option works correctly. This isn't applicable here */
56 if (ctx && ctx->magic == M_IMAP)
57 {
58 h->changed = 1;
59 if (upd_ctx) ctx->changed = 1;
60 }
61 #endif
62 }
63 }
64 else if (h->deleted)
65 {
66 h->deleted = 0;
67 update = 1;
68 if (upd_ctx) ctx->deleted--;
69 #ifdef USE_IMAP
70 /* see my comment above */
71 if (ctx->magic == M_IMAP)
72 {
73 h->changed = 1;
74 if (upd_ctx) ctx->changed = 1;
75 }
76 #endif
77 /*
78 * If the user undeletes a message which is marked as
79 * "trash" in the maildir folder on disk, the folder has
80 * been changed, and is marked accordingly. However, we do
81 * _not_ mark the message itself changed, because trashing
82 * is checked in specific code in the maildir folder
83 * driver.
84 */
85 if (ctx->magic == M_MAILDIR && upd_ctx && h->trash)
86 ctx->changed = 1;
87 }
88 break;
89
90 case M_NEW:
91
92 if (!mutt_bit_isset(ctx->rights,M_ACL_SEEN))
93 return;
94
95 if (bf)
96 {
97 if (h->read || h->old)
98 {
99 update = 1;
100 h->old = 0;
101 if (upd_ctx) ctx->new++;
102 if (h->read)
103 {
104 h->read = 0;
105 if (upd_ctx) ctx->unread++;
106 }
107 h->changed = 1;
108 if (upd_ctx) ctx->changed = 1;
109 }
110 }
111 else if (!h->read)
112 {
113 update = 1;
114 if (!h->old)
115 if (upd_ctx) ctx->new--;
116 h->read = 1;
117 if (upd_ctx) ctx->unread--;
118 h->changed = 1;
119 if (upd_ctx) ctx->changed = 1;
120 }
121 break;
122
123 case M_OLD:
124
125 if (!mutt_bit_isset(ctx->rights,M_ACL_SEEN))
126 return;
127
128 if (bf)
129 {
130 if (!h->old)
131 {
132 update = 1;
133 h->old = 1;
134 if (!h->read)
135 if (upd_ctx) ctx->new--;
136 h->changed = 1;
137 if (upd_ctx) ctx->changed = 1;
138 }
139 }
140 else if (h->old)
141 {
142 update = 1;
143 h->old = 0;
144 if (!h->read)
145 if (upd_ctx) ctx->new++;
146 h->changed = 1;
147 if (upd_ctx) ctx->changed = 1;
148 }
149 break;
150
151 case M_READ:
152
153 if (!mutt_bit_isset(ctx->rights,M_ACL_SEEN))
154 return;
155
156 if (bf)
157 {
158 if (!h->read)
159 {
160 update = 1;
161 h->read = 1;
162 if (upd_ctx) ctx->unread--;
163 if (!h->old)
164 if (upd_ctx) ctx->new--;
165 h->changed = 1;
166 if (upd_ctx) ctx->changed = 1;
167 }
168 }
169 else if (h->read)
170 {
171 update = 1;
172 h->read = 0;
173 if (upd_ctx) ctx->unread++;
174 if (!h->old)
175 if (upd_ctx) ctx->new++;
176 h->changed = 1;
177 if (upd_ctx) ctx->changed = 1;
178 }
179 break;
180
181 case M_REPLIED:
182
183 if (!mutt_bit_isset(ctx->rights,M_ACL_WRITE))
184 return;
185
186 if (bf)
187 {
188 if (!h->replied)
189 {
190 update = 1;
191 h->replied = 1;
192 if (!h->read)
193 {
194 h->read = 1;
195 if (upd_ctx) ctx->unread--;
196 if (!h->old)
197 if (upd_ctx) ctx->new--;
198 }
199 h->changed = 1;
200 if (upd_ctx) ctx->changed = 1;
201 }
202 }
203 else if (h->replied)
204 {
205 update = 1;
206 h->replied = 0;
207 h->changed = 1;
208 if (upd_ctx) ctx->changed = 1;
209 }
210 break;
211
212 case M_FLAG:
213
214 if (!mutt_bit_isset(ctx->rights,M_ACL_WRITE))
215 return;
216
217 if (bf)
218 {
219 if (!h->flagged)
220 {
221 update = 1;
222 h->flagged = bf;
223 if (upd_ctx) ctx->flagged++;
224 h->changed = 1;
225 if (upd_ctx) ctx->changed = 1;
226 }
227 }
228 else if (h->flagged)
229 {
230 update = 1;
231 h->flagged = 0;
232 if (upd_ctx) ctx->flagged--;
233 h->changed = 1;
234 if (upd_ctx) ctx->changed = 1;
235 }
236 break;
237
238 case M_TAG:
239 if (bf)
240 {
241 if (!h->tagged)
242 {
243 update = 1;
244 h->tagged = 1;
245 if (upd_ctx) ctx->tagged++;
246 }
247 }
248 else if (h->tagged)
249 {
250 update = 1;
251 h->tagged = 0;
252 if (upd_ctx) ctx->tagged--;
253 }
254 break;
255 }
256
257 if (update)
258 mutt_set_header_color(ctx, h);
259
260 /* if the message status has changed, we need to invalidate the cached
261 * search results so that any future search will match the current status
262 * of this message and not what it was at the time it was last searched.
263 */
264 if (h->searched && (changed != h->changed || deleted != ctx->deleted || tagged != ctx->tagged || flagged != ctx->flagged))
265 h->searched = 0;
266 }
267
268 void mutt_tag_set_flag (int flag, int bf)
269 {
270 int j;
271
272 for (j = 0; j < Context->vcount; j++)
273 if (Context->hdrs[Context->v2r[j]]->tagged)
274 mutt_set_flag (Context, Context->hdrs[Context->v2r[j]], flag, bf);
275 }
276 int mutt_thread_set_flag (HEADER *hdr, int flag, int bf, int subthread)
277 {
278 THREAD *start, *cur = hdr->thread;
279
280 if ((Sort & SORT_MASK) != SORT_THREADS)
281 {
282 mutt_error _("Threading is not enabled.");
283 return (-1);
284 }
285
286 if (!subthread)
287 while (cur->parent)
288 cur = cur->parent;
289 start = cur;
290
291 if (cur->message)
292 mutt_set_flag (Context, cur->message, flag, bf);
293
294 if ((cur = cur->child) == NULL)
295 return (0);
296
297 FOREVER
298 {
299 if (cur->message)
300 mutt_set_flag (Context, cur->message, flag, bf);
301
302 if (cur->child)
303 cur = cur->child;
304 else if (cur->next)
305 cur = cur->next;
306 else
307 {
308 while (!cur->next)
309 {
310 cur = cur->parent;
311 if (cur == start)
312 return (0);
313 }
314 cur = cur->next;
315 }
316 }
317 /* not reached */
318 }
319
320 int mutt_change_flag (HEADER *h, int bf)
321 {
322 int i, flag;
323 event_t event;
324
325 mvprintw (LINES - 1, 0, "%s? (D/N/O/r/*/!): ", bf ? _("Set flag") : _("Clear flag"));
326 clrtoeol ();
327
328 event = mutt_getch();
329 i = event.ch;
19304f7 Imported Upstream version 1.5.19
Antonio Radici authored May 24, 2009
330 if (i < 0)
14c2920 Imported Upstream version 1.5.18
Antonio Radici authored May 24, 2009
331 {
332 CLEARLINE (LINES-1);
333 return (-1);
334 }
335
336 CLEARLINE (LINES-1);
337
338 switch (i)
339 {
340 case 'd':
341 case 'D':
342 flag = M_DELETE;
343 break;
344
345 case 'N':
346 case 'n':
347 flag = M_NEW;
348 break;
349
350 case 'o':
351 case 'O':
352 if (h)
353 mutt_set_flag (Context, h, M_READ, !bf);
354 else
355 mutt_tag_set_flag (M_READ, !bf);
356 flag = M_OLD;
357 break;
358
359 case 'r':
360 case 'R':
361 flag = M_REPLIED;
362 break;
363
364 case '*':
365 flag = M_TAG;
366 break;
367
368 case '!':
369 flag = M_FLAG;
370 break;
371
372 default:
373 BEEP ();
374 return (-1);
375 }
376
377 if (h)
378 mutt_set_flag (Context, h, flag, bf);
379 else
380 mutt_tag_set_flag (flag, bf);
381
382 return 0;
383 }
Something went wrong with that request. Please try again.