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