mutt stable branch with some hacks
at jcs 416 lines 8.4 kB view raw
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 "mutt_menu.h" 26#include "sort.h" 27#include "mx.h" 28 29void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx) 30{ 31 int changed = h->changed; 32 int deleted = ctx->deleted; 33 int tagged = ctx->tagged; 34 int flagged = ctx->flagged; 35 int update = 0; 36 37 if (ctx->readonly && flag != MUTT_TAG) 38 return; /* don't modify anything if we are read-only */ 39 40 switch (flag) 41 { 42 case MUTT_DELETE: 43 44 if (!mutt_bit_isset(ctx->rights,MUTT_ACL_DELETE)) 45 return; 46 47 if (bf) 48 { 49 if (!h->deleted && !ctx->readonly 50 && (!h->flagged || !option(OPTFLAGSAFE))) 51 { 52 h->deleted = 1; 53 update = 1; 54 if (upd_ctx) ctx->deleted++; 55#ifdef USE_IMAP 56 /* deleted messages aren't treated as changed elsewhere so that the 57 * purge-on-sync option works correctly. This isn't applicable here */ 58 if (ctx && ctx->magic == MUTT_IMAP) 59 { 60 h->changed = 1; 61 if (upd_ctx) ctx->changed = 1; 62 } 63#endif 64 } 65 } 66 else if (h->deleted) 67 { 68 h->deleted = 0; 69 update = 1; 70 if (upd_ctx) ctx->deleted--; 71#ifdef USE_IMAP 72 /* see my comment above */ 73 if (ctx->magic == MUTT_IMAP) 74 { 75 h->changed = 1; 76 if (upd_ctx) ctx->changed = 1; 77 } 78#endif 79 /* 80 * If the user undeletes a message which is marked as 81 * "trash" in the maildir folder on disk, the folder has 82 * been changed, and is marked accordingly. However, we do 83 * _not_ mark the message itself changed, because trashing 84 * is checked in specific code in the maildir folder 85 * driver. 86 */ 87 if (ctx->magic == MUTT_MAILDIR && upd_ctx && h->trash) 88 ctx->changed = 1; 89 } 90 break; 91 92 case MUTT_PURGE: 93 94 if (!mutt_bit_isset(ctx->rights,MUTT_ACL_DELETE)) 95 return; 96 97 if (bf) 98 { 99 if (!h->purge && !ctx->readonly) 100 h->purge = 1; 101 } 102 else if (h->purge) 103 h->purge = 0; 104 break; 105 106 case MUTT_NEW: 107 108 if (!mutt_bit_isset(ctx->rights,MUTT_ACL_SEEN)) 109 return; 110 111 if (bf) 112 { 113 if (h->read || h->old) 114 { 115 update = 1; 116 h->old = 0; 117 if (upd_ctx) ctx->new++; 118 if (h->read) 119 { 120 h->read = 0; 121 if (upd_ctx) ctx->unread++; 122 } 123 h->changed = 1; 124 if (upd_ctx) ctx->changed = 1; 125 } 126 } 127 else if (!h->read) 128 { 129 update = 1; 130 if (!h->old) 131 if (upd_ctx) ctx->new--; 132 h->read = 1; 133 if (upd_ctx) ctx->unread--; 134 h->changed = 1; 135 if (upd_ctx) ctx->changed = 1; 136 } 137 break; 138 139 case MUTT_OLD: 140 141 if (!mutt_bit_isset(ctx->rights,MUTT_ACL_SEEN)) 142 return; 143 144 if (bf) 145 { 146 if (!h->old) 147 { 148 update = 1; 149 h->old = 1; 150 if (!h->read) 151 if (upd_ctx) ctx->new--; 152 h->changed = 1; 153 if (upd_ctx) ctx->changed = 1; 154 } 155 } 156 else if (h->old) 157 { 158 update = 1; 159 h->old = 0; 160 if (!h->read) 161 if (upd_ctx) ctx->new++; 162 h->changed = 1; 163 if (upd_ctx) ctx->changed = 1; 164 } 165 break; 166 167 case MUTT_READ: 168 169 if (!mutt_bit_isset(ctx->rights,MUTT_ACL_SEEN)) 170 return; 171 172 if (bf) 173 { 174 if (!h->read) 175 { 176 update = 1; 177 h->read = 1; 178 if (upd_ctx) ctx->unread--; 179 if (!h->old) 180 if (upd_ctx) ctx->new--; 181 h->changed = 1; 182 if (upd_ctx) ctx->changed = 1; 183 } 184 } 185 else if (h->read) 186 { 187 update = 1; 188 h->read = 0; 189 if (upd_ctx) ctx->unread++; 190 if (!h->old) 191 if (upd_ctx) ctx->new++; 192 h->changed = 1; 193 if (upd_ctx) ctx->changed = 1; 194 } 195 break; 196 197 case MUTT_REPLIED: 198 199 if (!mutt_bit_isset(ctx->rights,MUTT_ACL_WRITE)) 200 return; 201 202 if (bf) 203 { 204 if (!h->replied) 205 { 206 update = 1; 207 h->replied = 1; 208 if (!h->read) 209 { 210 h->read = 1; 211 if (upd_ctx) ctx->unread--; 212 if (!h->old) 213 if (upd_ctx) ctx->new--; 214 } 215 h->changed = 1; 216 if (upd_ctx) ctx->changed = 1; 217 } 218 } 219 else if (h->replied) 220 { 221 update = 1; 222 h->replied = 0; 223 h->changed = 1; 224 if (upd_ctx) ctx->changed = 1; 225 } 226 break; 227 228 case MUTT_FLAG: 229 230 if (!mutt_bit_isset(ctx->rights,MUTT_ACL_WRITE)) 231 return; 232 233 if (bf) 234 { 235 if (!h->flagged) 236 { 237 update = 1; 238 h->flagged = bf; 239 if (upd_ctx) ctx->flagged++; 240 h->changed = 1; 241 if (upd_ctx) ctx->changed = 1; 242 } 243 } 244 else if (h->flagged) 245 { 246 update = 1; 247 h->flagged = 0; 248 if (upd_ctx) ctx->flagged--; 249 h->changed = 1; 250 if (upd_ctx) ctx->changed = 1; 251 } 252 break; 253 254 case MUTT_TAG: 255 if (bf) 256 { 257 if (!h->tagged) 258 { 259 update = 1; 260 h->tagged = 1; 261 if (upd_ctx) ctx->tagged++; 262 } 263 } 264 else if (h->tagged) 265 { 266 update = 1; 267 h->tagged = 0; 268 if (upd_ctx) ctx->tagged--; 269 } 270 break; 271 } 272 273 if (update) 274 { 275 mutt_set_header_color(ctx, h); 276#ifdef USE_SIDEBAR 277 mutt_set_current_menu_redraw (REDRAW_SIDEBAR); 278#endif 279 } 280 281 /* if the message status has changed, we need to invalidate the cached 282 * search results so that any future search will match the current status 283 * of this message and not what it was at the time it was last searched. 284 */ 285 if (h->searched && (changed != h->changed || deleted != ctx->deleted || tagged != ctx->tagged || flagged != ctx->flagged)) 286 h->searched = 0; 287} 288 289void mutt_tag_set_flag (int flag, int bf) 290{ 291 int j; 292 293 for (j = 0; j < Context->vcount; j++) 294 if (Context->hdrs[Context->v2r[j]]->tagged) 295 mutt_set_flag (Context, Context->hdrs[Context->v2r[j]], flag, bf); 296} 297int mutt_thread_set_flag (HEADER *hdr, int flag, int bf, int subthread) 298{ 299 THREAD *start, *cur = hdr->thread; 300 301 if ((Sort & SORT_MASK) != SORT_THREADS) 302 { 303 mutt_error _("Threading is not enabled."); 304 return (-1); 305 } 306 307 if (!subthread) 308 while (cur->parent) 309 cur = cur->parent; 310 start = cur; 311 312 if (cur->message) 313 mutt_set_flag (Context, cur->message, flag, bf); 314 315 if ((cur = cur->child) == NULL) 316 return (0); 317 318 FOREVER 319 { 320 if (cur->message) 321 mutt_set_flag (Context, cur->message, flag, bf); 322 323 if (cur->child) 324 cur = cur->child; 325 else if (cur->next) 326 cur = cur->next; 327 else 328 { 329 while (!cur->next) 330 { 331 cur = cur->parent; 332 if (cur == start) 333 return (0); 334 } 335 cur = cur->next; 336 } 337 } 338 /* not reached */ 339} 340 341int mutt_change_flag (HEADER *h, int bf) 342{ 343 int i, flag; 344 event_t event; 345 346 mutt_window_mvprintw (MuttMessageWindow, 0, 0, 347 "%s? (D/N/O/r/*/!): ", bf ? _("Set flag") : _("Clear flag")); 348 mutt_window_clrtoeol (MuttMessageWindow); 349 mutt_refresh (); 350 351 do 352 { 353 event = mutt_getch(); 354 } while (event.ch == -2); 355 i = event.ch; 356 if (i < 0) 357 { 358 mutt_window_clearline (MuttMessageWindow, 0); 359 return (-1); 360 } 361 362 mutt_window_clearline (MuttMessageWindow, 0); 363 364 switch (i) 365 { 366 case 'd': 367 case 'D': 368 if (!bf) 369 { 370 if (h) 371 mutt_set_flag (Context, h, MUTT_PURGE, bf); 372 else 373 mutt_tag_set_flag (MUTT_PURGE, bf); 374 } 375 flag = MUTT_DELETE; 376 break; 377 378 case 'N': 379 case 'n': 380 flag = MUTT_NEW; 381 break; 382 383 case 'o': 384 case 'O': 385 if (h) 386 mutt_set_flag (Context, h, MUTT_READ, !bf); 387 else 388 mutt_tag_set_flag (MUTT_READ, !bf); 389 flag = MUTT_OLD; 390 break; 391 392 case 'r': 393 case 'R': 394 flag = MUTT_REPLIED; 395 break; 396 397 case '*': 398 flag = MUTT_TAG; 399 break; 400 401 case '!': 402 flag = MUTT_FLAG; 403 break; 404 405 default: 406 BEEP (); 407 return (-1); 408 } 409 410 if (h) 411 mutt_set_flag (Context, h, flag, bf); 412 else 413 mutt_tag_set_flag (flag, bf); 414 415 return 0; 416}