Changeset 25364
- Timestamp:
- 05/08/08 06:27:55 (7 months ago)
- Location:
- haiku/trunk/src/apps/mail
- Files:
-
- 3 modified
-
Content.cpp (modified) (15 diffs)
-
Content.h (modified) (9 diffs)
-
MailWindow.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
haiku/trunk/src/apps/mail/Content.cpp
r22122 r25364 90 90 const rgb_color kHeaderColor = {72, 72, 72, 255}; 91 91 92 const rgb_color kQuoteColors[] = 93 { 94 {0, 0, 0x80, 0}, // 3rd, 6th, ... quote level color 95 {0, 0x80, 0, 0}, // 1st, 4th, ... quote level color 96 {0x80, 0, 0, 0} // 2nd, ... 92 const rgb_color kQuoteColors[] = { 93 {0, 0, 0x80, 0}, // 3rd, 6th, ... quote level color (blue) 94 {0, 0x80, 0, 0}, // 1st, 4th, ... quote level color (green) 95 {0x80, 0, 0, 0} // 2nd, ... (red) 97 96 }; 98 97 const int32 kNumQuoteColors = 3; 98 99 const rgb_color kDiffColors[] = { 100 {0xb0, 0, 0, 0}, // '-', red 101 {0, 0x90, 0, 0}, // '+', green 102 {0x6a, 0x6a, 0x6a, 0} // '@@', dark grey 103 }; 99 104 100 105 void Unicode2UTF8(int32 c, char **out); … … 423 428 424 429 430 int32 431 diff_mode(char c) 432 { 433 if (c == '+') 434 return 2; 435 if (c == '-') 436 return 1; 437 if (c == '@') 438 return 3; 439 if (c == ' ') 440 return 0; 441 442 // everything else ends the diff mode 443 return -1; 444 } 445 446 425 447 bool 426 448 is_quote_char(char c) … … 430 452 431 453 432 /** Fills the specified text_run_array with the correct values for the 433 * specified text. 434 * If "view" is NULL, it will assume that "line" lies on a line break, 435 * if not, it will correctly retrieve the number of quotes the current 436 * line already has. 437 */ 438 454 /*! Fills the specified text_run_array with the correct values for the 455 specified text. 456 If "view" is NULL, it will assume that "line" lies on a line break, 457 if not, it will correctly retrieve the number of quotes the current 458 line already has. 459 */ 439 460 void 440 FillInQuoteTextRuns(BTextView *view, const char *line, int32 length, const BFont &font,441 text_run_array *style, int32 maxStyles)442 { 443 text_run *runs = style->runs;461 FillInQuoteTextRuns(BTextView* view, quote_context* context, const char* line, 462 int32 length, const BFont& font, text_run_array* style, int32 maxStyles) 463 { 464 text_run* runs = style->runs; 444 465 int32 index = style->count; 445 466 bool begin; 446 467 int32 pos = 0; 468 int32 diffMode = 0; 469 bool inDiff = false; 470 bool wasDiff = false; 447 471 int32 level = 0; 448 472 449 473 // get index to the beginning of the current line 450 474 451 if (view != NULL) { 475 if (context != NULL) { 476 level = context->level; 477 diffMode = context->diff_mode; 478 begin = context->begin; 479 inDiff = context->in_diff; 480 wasDiff = context->was_diff; 481 } else if (view != NULL) { 452 482 int32 start, end; 453 483 view->GetSelection(&end, &end); 454 484 455 begin = view->TextLength() == 0 || view->ByteAt(view->TextLength() - 1) == '\n'; 456 457 // the following line works only reliable when text wrapping is set to off; 458 // so the complicated version actually used here is necessary: 485 begin = view->TextLength() == 0 486 || view->ByteAt(view->TextLength() - 1) == '\n'; 487 488 // the following line works only reliable when text wrapping is set to 489 // off; so the complicated version actually used here is necessary: 459 490 // start = view->OffsetAt(view->CurrentLine()); 460 491 … … 473 504 474 505 if (!begin && start < end) { 475 begin = true; // if there was no text in this line, there may come more nested quotes 476 477 for (int32 i = start; i < end; i++) { 478 if (is_quote_char(text[i])) 479 level++; 480 else if (text[i] != ' ' && text[i] != '\t') { 481 begin = false; 482 break; 483 } 484 } 485 if (begin) // skip leading spaces (tabs & newlines aren't allowed here) 506 begin = true; 507 // if there was no text in this line, there may come 508 // more nested quotes 509 510 diffMode = diff_mode(text[start]); 511 if (diffMode == 0) { 512 for (int32 i = start; i < end; i++) { 513 if (is_quote_char(text[i])) 514 level++; 515 else if (text[i] != ' ' && text[i] != '\t') { 516 begin = false; 517 break; 518 } 519 } 520 } else 521 inDiff = true; 522 523 if (begin) { 524 // skip leading spaces (tabs & newlines aren't allowed here) 486 525 while (line[pos] == ' ') 487 526 pos++; 527 } 488 528 } 489 529 } else … … 495 535 int32 next; 496 536 if (begin && is_quote_char(line[pos])) { 537 begin = false; 538 497 539 while (pos < length && line[pos] != '\n') { 540 // insert style for each quote level 498 541 level++; 499 542 … … 503 546 || line[next] == '\n') 504 547 break; 505 else if ( line[next] != ' ' && line[next] != '\t')548 else if (search && line[next] != ' ' && line[next] != '\t') 506 549 search = false; 507 550 } … … 509 552 runs[index].offset = pos; 510 553 runs[index].font = font; 511 runs[index].color = level > 0 ? kQuoteColors[level % kNumQuoteColors] : kNormalTextColor; 554 runs[index].color = level > 0 555 ? kQuoteColors[level % kNumQuoteColors] : kNormalTextColor; 512 556 513 557 pos = next; … … 516 560 } 517 561 } else { 562 if (begin) { 563 if (!inDiff) { 564 inDiff = !strncmp(&line[pos], "--- ", 4); 565 wasDiff = false; 566 } 567 if (inDiff) { 568 diffMode = diff_mode(line[pos]); 569 if (diffMode < 0) { 570 inDiff = false; 571 wasDiff = true; 572 } 573 } 574 } 575 518 576 runs[index].offset = pos; 519 577 runs[index].font = font; 520 runs[index].color = level > 0 ? kQuoteColors[level % kNumQuoteColors] : kNormalTextColor; 578 if (wasDiff) 579 runs[index].color = kDiffColors[diff_mode('@') - 1]; 580 else if (diffMode <= 0) { 581 runs[index].color = level > 0 582 ? kQuoteColors[level % kNumQuoteColors] : kNormalTextColor; 583 } else 584 runs[index].color = kDiffColors[diffMode - 1]; 585 586 begin = false; 587 588 for (next = pos; next < length; next++) { 589 if (line[next] == '\n') { 590 begin = true; 591 wasDiff = false; 592 break; 593 } 594 } 595 596 pos = next; 521 597 index++; 522 523 for (next = pos; next < length; next++) { 524 if (line[next] == '\n') 525 break; 526 } 527 pos = next; 598 } 599 600 if (pos < length) 601 begin = line[pos] == '\n'; 602 603 if (begin) { 604 pos++; 605 level = 0; 606 wasDiff = false; 607 608 // skip one leading space (tabs & newlines aren't allowed here) 609 if (!inDiff && pos < length && line[pos] == ' ') 610 pos++; 528 611 } 529 612 530 613 if (index >= maxStyles) 531 614 break; 532 533 level = 0;534 535 if (pos < length && line[pos] == '\n') {536 pos++;537 begin = true;538 539 // skip leading spaces (tabs & newlines aren't allowed here)540 while (pos < length && line[pos] == ' ')541 pos++;542 }543 615 } 544 616 style->count = index; 617 618 if (context) { 619 // update context for next run 620 context->level = level; 621 context->diff_mode = diffMode; 622 context->begin = begin; 623 context->in_diff = inDiff; 624 context->was_diff = wasDiff; 625 } 545 626 } 546 627 … … 2172 2253 2173 2254 2174 //--------------------------------------------------------------------2175 2255 // #pragma mark - 2176 2256 2177 2257 2178 TTextView::Reader::Reader(bool header, bool raw, bool quote, bool incoming, bool stripHeader, 2179 bool mime, TTextView *view, BEmailMessage *mail, BList *list, sem_id sem) 2258 TTextView::Reader::Reader(bool header, bool raw, bool quote, bool incoming, 2259 bool stripHeader, bool mime, TTextView *view, BEmailMessage *mail, 2260 BList *list, sem_id sem) 2180 2261 : 2181 2262 fHeader(header), … … 2194 2275 2195 2276 bool 2196 TTextView::Reader::ParseMail(BMailContainer *container, BTextMailComponent *ignore) 2277 TTextView::Reader::ParseMail(BMailContainer *container, 2278 BTextMailComponent *ignore) 2197 2279 { 2198 2280 int32 count = 0; … … 2338 2420 2339 2421 bool 2340 TTextView::Reader::Insert(const char *line, int32 count, bool isHyperLink, bool isHeader) 2422 TTextView::Reader::Insert(const char *line, int32 count, bool isHyperLink, 2423 bool isHeader) 2341 2424 { 2342 2425 if (!count) … … 2346 2429 TextRunArray style(count / 8 + 8); 2347 2430 2348 if (fView->fColoredQuotes && !isHeader && !isHyperLink) 2349 FillInQuoteTextRuns(fView, line, count, font, &style.Array(), style.MaxEntries()); 2350 else { 2431 if (fView->fColoredQuotes && !isHeader && !isHyperLink) { 2432 FillInQuoteTextRuns(fView, &fQuoteContext, line, count, font, 2433 &style.Array(), style.MaxEntries()); 2434 } else { 2351 2435 text_run_array &array = style.Array(); 2352 2436 array.count = 1; … … 2355 2439 array.runs[0].color = isHyperLink ? kHyperLinkColor : kHeaderColor; 2356 2440 font.SetSize(font.Size() * 0.9); 2357 } else 2358 array.runs[0].color = isHyperLink ? kHyperLinkColor : kNormalTextColor; 2441 } else { 2442 array.runs[0].color = isHyperLink 2443 ? kHyperLinkColor : kNormalTextColor; 2444 } 2359 2445 array.runs[0].font = font; 2360 2446 } … … 3062 3148 TextRunArray style(targetLength / 8 + 8); 3063 3149 3064 FillInQuoteTextRuns(NULL, target, targetLength, font, &style.Array(), style.MaxEntries()); 3150 FillInQuoteTextRuns(NULL, NULL, target, targetLength, font, 3151 &style.Array(), style.MaxEntries()); 3065 3152 Insert(target, targetLength, &style.Array()); 3066 3153 } else … … 3139 3226 TextRunArray style(length / 8 + 8); 3140 3227 3141 FillInQuoteTextRuns(NULL, target, length, font, &style.Array(), style.MaxEntries()); 3228 FillInQuoteTextRuns(NULL, NULL, target, length, font, 3229 &style.Array(), style.MaxEntries()); 3142 3230 Insert(target, length, &style.Array()); 3143 3231 } else -
haiku/trunk/src/apps/mail/Content.h
r22122 r25364 32 32 All rights reserved. 33 33 */ 34 35 //--------------------------------------------------------------------36 //37 // Content.h38 //39 //--------------------------------------------------------------------40 41 34 #ifndef _CONTENT_H 42 35 #define _CONTENT_H … … 73 66 struct text_run_array; 74 67 75 typedef struct 76 { 68 typedef struct { 77 69 bool header; 78 70 bool raw; … … 87 79 } reader_info; 88 80 89 enum ENCLOSURE_TYPE 90 { 81 enum ENCLOSURE_TYPE { 91 82 TYPE_ENCLOSURE = 100, 92 83 TYPE_BE_ENCLOSURE, … … 114 105 //==================================================================== 115 106 116 class TContentView : public BView 117 { 107 class TContentView : public BView { 118 108 public: 119 109 TContentView(BRect, bool incoming, BEmailMessage *mail, BFont*, … … 139 129 }; 140 130 141 class TTextView : public BTextView 142 { 131 struct quote_context { 132 quote_context() 133 : 134 level(0), 135 diff_mode(0), 136 begin(true), 137 in_diff(false), 138 was_diff(false) 139 { 140 } 141 142 int32 level; 143 int32 diff_mode; 144 bool begin; 145 bool in_diff; 146 bool was_diff; 147 }; 148 149 class TTextView : public BTextView { 143 150 public: 144 151 TTextView(BRect, BRect, bool incoming, BEmailMessage *mail, … … 221 228 bool fCursor; 222 229 223 struct spell_mark 224 { 230 struct spell_mark { 225 231 spell_mark *next; 226 232 int32 start; … … 231 237 spell_mark *fFirstSpellMark; 232 238 233 class Reader 234 { 239 class Reader { 235 240 public: 236 Reader(bool header,bool raw,bool quote,bool incoming,bool stripHeaders,bool mime, 237 TTextView *view,BEmailMessage *mail,BList *list,sem_id sem); 238 239 static status_t Run(void *); 241 Reader(bool header, bool raw, bool quote, bool incoming, 242 bool stripHeaders, bool mime, TTextView* view, 243 BEmailMessage* mail, BList* list, sem_id sem); 244 245 static status_t Run(void* _dummy); 240 246 241 247 private: 242 bool ParseMail(BMailContainer *container,BTextMailComponent *ignore); 243 bool Process(const char *data, int32 len, bool isHeader = false); 244 bool Insert(const char *line, int32 count, bool isHyperLink, bool isHeader = false); 248 bool ParseMail(BMailContainer* container, 249 BTextMailComponent* ignore); 250 bool Process(const char* data, int32 length, 251 bool isHeader = false); 252 bool Insert(const char* line, int32 count, bool isHyperLink, 253 bool isHeader = false); 245 254 246 255 bool Lock(); … … 250 259 bool fRaw; 251 260 bool fQuote; 261 quote_context fQuoteContext; 252 262 bool fIncoming; 253 263 bool fStripHeader; 254 264 bool fMime; 255 TTextView *fView;256 BEmailMessage *fMail;265 TTextView* fView; 266 BEmailMessage* fMail; 257 267 BList *fEnclosures; 258 268 sem_id fStopSem; … … 289 299 }; 290 300 291 extern void FillInQuoteTextRuns(BTextView *view, const char *line, int32 length, 292 const BFont &font, text_run_array *style, int32 maxStyles = 5); 301 extern void FillInQuoteTextRuns(BTextView* view, quote_context* context, 302 const char* line, int32 length, const BFont& font, text_run_array* style, 303 int32 maxStyles = 5); 293 304 294 305 #endif /* #ifndef _CONTENT_H */ -
haiku/trunk/src/apps/mail/MailWindow.cpp
r24851 r25364 2170 2170 TextRunArray style(length / 8 + 8); 2171 2171 2172 FillInQuoteTextRuns(fContentView->fTextView, fContentView->fTextView->Text(), 2173 length, font, &style.Array(), style.MaxEntries()); 2172 FillInQuoteTextRuns(fContentView->fTextView, NULL, 2173 fContentView->fTextView->Text(), length, font, &style.Array(), 2174 style.MaxEntries()); 2174 2175 2175 2176 fContentView->fTextView->SetRunArray(0, length, &style.Array());
