1 /* 2 Open Tracker License 3 4 Terms and Conditions 5 6 Copyright (c) 1991-2001, Be Incorporated. All rights reserved. 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy of 9 this software and associated documentation files (the "Software"), to deal in 10 the Software without restriction, including without limitation the rights to 11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 of the Software, and to permit persons to whom the Software is furnished to do 13 so, subject to the following conditions: 14 15 The above copyright notice and this permission notice applies to all licensees 16 and shall be included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN 23 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 Except as contained in this notice, the name of Be Incorporated shall not be 26 used in advertising or otherwise to promote the sale, use or other dealings in 27 this Software without prior written authorization from Be Incorporated. 28 29 BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or 30 registered trademarks of Be Incorporated in the United States and other 31 countries. Other brand product names are registered trademarks or trademarks 32 of their respective holders. All rights reserved. 33 */ 34 35 36 #include "Prefs.h" 37 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 42 #include <Application.h> 43 #include <CharacterSet.h> 44 #include <CharacterSetRoster.h> 45 #include <E-mail.h> 46 #include <GridView.h> 47 #include <GroupLayoutBuilder.h> 48 #include <InterfaceKit.h> 49 #include <Locale.h> 50 #include <MailSettings.h> 51 #include <mail_encoding.h> 52 #include <StorageKit.h> 53 #include <String.h> 54 55 using namespace BPrivate; 56 57 #include "MailApp.h" 58 #include "MailSupport.h" 59 #include "MailWindow.h" 60 #include "Messages.h" 61 #include "Signature.h" 62 63 64 #define B_TRANSLATE_CONTEXT "Mail" 65 66 #define BUTTON_WIDTH 70 67 #define BUTTON_HEIGHT 20 68 #define ITEM_SPACE 6 69 70 #define OK_BUTTON_X1 (PREF_WIDTH - BUTTON_WIDTH - 6) 71 #define OK_BUTTON_X2 (OK_BUTTON_X1 + BUTTON_WIDTH) 72 73 #define REVERT_BUTTON_X1 8 74 #define REVERT_BUTTON_X2 (REVERT_BUTTON_X1 + BUTTON_WIDTH) 75 76 enum P_MESSAGES {P_OK = 128, P_CANCEL, P_REVERT, P_FONT, 77 P_SIZE, P_LEVEL, P_WRAP, P_ATTACH_ATTRIBUTES, 78 P_SIG, P_ENC, P_WARN_UNENCODABLE, 79 P_SPELL_CHECK_START_ON, P_BUTTON_BAR, 80 P_ACCOUNT, P_REPLYTO, P_REPLY_PREAMBLE, 81 P_COLORED_QUOTES, P_MARK_READ}; 82 83 extern BPoint prefs_window; 84 85 //#pragma mark - 86 87 88 static inline void 89 add_menu_to_layout(BMenuField* menu, BGridLayout* layout, int32& row) 90 { 91 menu->SetAlignment(B_ALIGN_RIGHT); 92 layout->AddItem(menu->CreateLabelLayoutItem(), 0, row); 93 layout->AddItem(menu->CreateMenuBarLayoutItem(), 1, row, 2); 94 row++; 95 } 96 97 98 TPrefsWindow::TPrefsWindow(BRect rect, BFont* font, int32* level, bool* wrap, 99 bool* attachAttributes, bool* cquotes, uint32* account, int32* replyTo, 100 char** preamble, char** sig, uint32* encoding, bool* warnUnencodable, 101 bool* spellCheckStartOn, bool* autoMarkRead, uint8* buttonBar) 102 : 103 BWindow(rect, B_TRANSLATE("Mail preferences"), 104 B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE 105 | B_AUTO_UPDATE_SIZE_LIMITS), 106 107 fNewWrap(wrap), 108 fWrap(*fNewWrap), 109 110 fNewAttachAttributes(attachAttributes), 111 fAttachAttributes(*fNewAttachAttributes), 112 113 fNewButtonBar(buttonBar), 114 fButtonBar(*fNewButtonBar), 115 116 fNewColoredQuotes(cquotes), 117 fColoredQuotes(*fNewColoredQuotes), 118 119 fNewAccount(account), 120 fAccount(*fNewAccount), 121 122 fNewReplyTo(replyTo), 123 fReplyTo(*fNewReplyTo), 124 125 fNewPreamble(preamble), 126 127 fNewSignature(sig), 128 fSignature((char*)malloc(strlen(*fNewSignature) + 1)), 129 130 fNewFont(font), 131 fFont(*fNewFont), 132 133 fNewEncoding(encoding), 134 fEncoding(*fNewEncoding), 135 136 fNewWarnUnencodable(warnUnencodable), 137 fWarnUnencodable(*fNewWarnUnencodable), 138 139 fNewSpellCheckStartOn(spellCheckStartOn), 140 fSpellCheckStartOn(*fNewSpellCheckStartOn), 141 142 fNewAutoMarkRead(autoMarkRead), 143 fAutoMarkRead(*fNewAutoMarkRead) 144 { 145 strcpy(fSignature, *fNewSignature); 146 147 BMenuField* menu; 148 149 // group boxes 150 151 const float kSpacing = 8; 152 153 BGridView* interfaceView = new BGridView(kSpacing, kSpacing); 154 BGridLayout* interfaceLayout = interfaceView->GridLayout(); 155 interfaceLayout->SetInsets(kSpacing, kSpacing, kSpacing, kSpacing); 156 BGridView* mailView = new BGridView(kSpacing, kSpacing); 157 BGridLayout* mailLayout = mailView->GridLayout(); 158 mailLayout->SetInsets(kSpacing, kSpacing, kSpacing, kSpacing); 159 160 interfaceLayout->AlignLayoutWith(mailLayout, B_HORIZONTAL); 161 162 BBox* interfaceBox = new BBox(B_FANCY_BORDER, interfaceView); 163 interfaceBox->SetLabel(B_TRANSLATE("User interface")); 164 BBox* mailBox = new BBox(B_FANCY_BORDER, mailView); 165 mailBox->SetLabel(B_TRANSLATE("Mailing")); 166 167 // revert, ok & cancel 168 169 BButton* okButton = new BButton("ok", B_TRANSLATE("OK"), 170 new BMessage(P_OK)); 171 okButton->MakeDefault(true); 172 173 BButton* cancelButton = new BButton("cancel", B_TRANSLATE("Cancel"), 174 new BMessage(P_CANCEL)); 175 176 fRevert = new BButton("revert", B_TRANSLATE("Revert"), 177 new BMessage(P_REVERT)); 178 fRevert->SetEnabled(false); 179 180 // User Interface 181 int32 layoutRow = 0; 182 183 fButtonBarMenu = _BuildButtonBarMenu(*buttonBar); 184 menu = new BMenuField("bar", B_TRANSLATE("Button bar:"), 185 fButtonBarMenu, NULL); 186 add_menu_to_layout(menu, interfaceLayout, layoutRow); 187 188 fFontMenu = _BuildFontMenu(font); 189 menu = new BMenuField("font", B_TRANSLATE("Font:"), 190 fFontMenu, NULL); 191 add_menu_to_layout(menu, interfaceLayout, layoutRow); 192 193 fSizeMenu = _BuildSizeMenu(font); 194 menu = new BMenuField("size", B_TRANSLATE("Size:"), fSizeMenu, NULL); 195 add_menu_to_layout(menu, interfaceLayout, layoutRow); 196 197 fColoredQuotesMenu = _BuildColoredQuotesMenu(fColoredQuotes); 198 menu = new BMenuField("cquotes", B_TRANSLATE("Colored quotes:"), 199 fColoredQuotesMenu, NULL); 200 add_menu_to_layout(menu, interfaceLayout, layoutRow); 201 202 fSpellCheckStartOnMenu = _BuildSpellCheckStartOnMenu(fSpellCheckStartOn); 203 menu = new BMenuField("spellCheckStartOn", 204 B_TRANSLATE("Initial spell check mode:"), 205 fSpellCheckStartOnMenu, NULL); 206 add_menu_to_layout(menu, interfaceLayout, layoutRow); 207 208 fAutoMarkReadMenu = _BuildAutoMarkReadMenu(fAutoMarkRead); 209 menu = new BMenuField("autoMarkRead", 210 B_TRANSLATE("Automatically mark mail as read:"), 211 fAutoMarkReadMenu, NULL); 212 add_menu_to_layout(menu, interfaceLayout, layoutRow); 213 // Mail Accounts 214 215 layoutRow = 0; 216 217 fAccountMenu = _BuildAccountMenu(fAccount); 218 menu = new BMenuField("account", B_TRANSLATE("Default account:"), 219 fAccountMenu, NULL); 220 add_menu_to_layout(menu, mailLayout, layoutRow); 221 222 fReplyToMenu = _BuildReplyToMenu(fReplyTo); 223 menu = new BMenuField("replyTo", B_TRANSLATE("Reply account:"), 224 fReplyToMenu, NULL); 225 add_menu_to_layout(menu, mailLayout, layoutRow); 226 227 // Mail Contents 228 229 fReplyPreamble = new BTextControl("replytext", 230 B_TRANSLATE("Reply preamble:"), 231 *preamble, new BMessage(P_REPLY_PREAMBLE)); 232 fReplyPreamble->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); 233 234 fReplyPreambleMenu = _BuildReplyPreambleMenu(); 235 menu = new BMenuField("replyPreamble", NULL, fReplyPreambleMenu, NULL); 236 menu->SetExplicitMaxSize(BSize(27, B_SIZE_UNSET)); 237 238 mailLayout->AddItem(fReplyPreamble->CreateLabelLayoutItem(), 0, layoutRow); 239 mailLayout->AddItem(fReplyPreamble->CreateTextViewLayoutItem(), 1, 240 layoutRow); 241 mailLayout->AddView(menu, 2, layoutRow); 242 layoutRow++; 243 244 fSignatureMenu = _BuildSignatureMenu(*sig); 245 menu = new BMenuField("sig", B_TRANSLATE("Auto signature:"), 246 fSignatureMenu, NULL); 247 add_menu_to_layout(menu, mailLayout, layoutRow); 248 249 fEncodingMenu = _BuildEncodingMenu(fEncoding); 250 menu = new BMenuField("enc", B_TRANSLATE("Encoding:"), 251 fEncodingMenu, NULL); 252 add_menu_to_layout(menu, mailLayout, layoutRow); 253 254 fWarnUnencodableMenu = _BuildWarnUnencodableMenu(fWarnUnencodable); 255 menu = new BMenuField("warnUnencodable", B_TRANSLATE("Warn unencodable:"), 256 fWarnUnencodableMenu, NULL); 257 add_menu_to_layout(menu, mailLayout, layoutRow); 258 259 fWrapMenu = _BuildWrapMenu(*wrap); 260 menu = new BMenuField("wrap", B_TRANSLATE("Text wrapping:"), 261 fWrapMenu, NULL); 262 add_menu_to_layout(menu, mailLayout, layoutRow); 263 264 fAttachAttributesMenu = _BuildAttachAttributesMenu(*attachAttributes); 265 menu = new BMenuField("attachAttributes", 266 B_TRANSLATE("Attach attributes:"), 267 fAttachAttributesMenu, NULL); 268 add_menu_to_layout(menu, mailLayout, layoutRow); 269 270 SetLayout(new BGroupLayout(B_HORIZONTAL)); 271 272 AddChild(BGroupLayoutBuilder(B_VERTICAL, kSpacing) 273 .Add(interfaceBox) 274 .Add(mailBox) 275 .Add(BGroupLayoutBuilder(B_HORIZONTAL, kSpacing) 276 .Add(fRevert) 277 .AddGlue() 278 .Add(cancelButton) 279 .Add(okButton) 280 ) 281 .SetInsets(kSpacing, kSpacing, kSpacing, kSpacing) 282 ); 283 284 Show(); 285 } 286 287 288 TPrefsWindow::~TPrefsWindow() 289 { 290 BMessage msg(WINDOW_CLOSED); 291 msg.AddInt32("kind", PREFS_WINDOW); 292 msg.AddPoint("window pos", Frame().LeftTop()); 293 be_app->PostMessage(&msg); 294 } 295 296 297 void 298 TPrefsWindow::MessageReceived(BMessage* msg) 299 { 300 bool revert = true; 301 const char* family; 302 const char* signature; 303 const char* style; 304 char label[256]; 305 int32 new_size; 306 int32 old_size; 307 font_family new_family; 308 font_family old_family; 309 font_style new_style; 310 font_style old_style; 311 BMenuItem* item; 312 BMessage message; 313 314 switch (msg->what) { 315 case P_OK: 316 if (strcmp(fReplyPreamble->Text(), *fNewPreamble)) { 317 free(*fNewPreamble); 318 *fNewPreamble 319 = (char *)malloc(strlen(fReplyPreamble->Text()) + 1); 320 strcpy(*fNewPreamble, fReplyPreamble->Text()); 321 } 322 be_app->PostMessage(PREFS_CHANGED); 323 Quit(); 324 break; 325 326 case P_CANCEL: 327 revert = false; 328 // supposed to fall through 329 case P_REVERT: 330 fFont.GetFamilyAndStyle(&old_family, &old_style); 331 fNewFont->GetFamilyAndStyle(&new_family, &new_style); 332 old_size = (int32)fFont.Size(); 333 new_size = (int32)fNewFont->Size(); 334 if (strcmp(old_family, new_family) || strcmp(old_style, new_style) 335 || old_size != new_size) { 336 fNewFont->SetFamilyAndStyle(old_family, old_style); 337 if (revert) { 338 sprintf(label, "%s %s", old_family, old_style); 339 item = fFontMenu->FindItem(label); 340 if (item != NULL) 341 item->SetMarked(true); 342 } 343 344 fNewFont->SetSize(old_size); 345 if (revert) { 346 sprintf(label, "%ld", old_size); 347 item = fSizeMenu->FindItem(label); 348 if (item != NULL) 349 item->SetMarked(true); 350 } 351 message.what = M_FONT; 352 be_app->PostMessage(&message); 353 } 354 *fNewWrap = fWrap; 355 *fNewAttachAttributes = fAttachAttributes; 356 357 if (strcmp(fSignature, *fNewSignature)) { 358 free(*fNewSignature); 359 *fNewSignature = (char*)malloc(strlen(fSignature) + 1); 360 strcpy(*fNewSignature, fSignature); 361 } 362 363 *fNewEncoding = fEncoding; 364 *fNewWarnUnencodable = fWarnUnencodable; 365 *fNewSpellCheckStartOn = fSpellCheckStartOn; 366 *fNewAutoMarkRead = fAutoMarkRead; 367 *fNewButtonBar = fButtonBar; 368 369 be_app->PostMessage(PREFS_CHANGED); 370 371 if (revert) { 372 for (int i = fAccountMenu->CountItems(); --i > 0;) { 373 BMenuItem *item = fAccountMenu->ItemAt(i); 374 BMessage* itemMessage = item->Message(); 375 if (itemMessage != NULL 376 && itemMessage->FindInt32("id") == *(int32 *)&fAccount) { 377 item->SetMarked(true); 378 break; 379 } 380 } 381 382 strcpy(label,fReplyTo == ACCOUNT_USE_DEFAULT 383 ? B_TRANSLATE("Use default account") 384 : B_TRANSLATE("Account from mail")); 385 if ((item = fReplyToMenu->FindItem(label)) != NULL) 386 item->SetMarked(true); 387 388 strcpy(label, fWrap ? "On" : "Off"); 389 if ((item = fWrapMenu->FindItem(label)) != NULL) 390 item->SetMarked(true); 391 392 strcpy(label, fAttachAttributes 393 ? B_TRANSLATE("Include file attributes in attachments") 394 : B_TRANSLATE("No file attributes, just plain data")); 395 if ((item = fAttachAttributesMenu->FindItem(label)) != NULL) 396 item->SetMarked(true); 397 398 strcpy(label, fColoredQuotes ? "On" : "Off"); 399 if ((item = fColoredQuotesMenu->FindItem(label)) != NULL) 400 item->SetMarked(true); 401 402 if (strcmp(fReplyPreamble->Text(), *fNewPreamble)) 403 fReplyPreamble->SetText(*fNewPreamble); 404 405 item = fSignatureMenu->FindItem(fSignature); 406 if (item) 407 item->SetMarked(true); 408 409 uint32 index = 0; 410 while ((item = fEncodingMenu->ItemAt(index++)) != NULL) { 411 BMessage* itemMessage = item->Message(); 412 if (itemMessage == NULL) 413 continue; 414 415 int32 encoding; 416 if (itemMessage->FindInt32("encoding", &encoding) == B_OK 417 && (uint32)encoding == *fNewEncoding) { 418 item->SetMarked(true); 419 break; 420 } 421 } 422 423 strcpy(label, fWarnUnencodable ? "On" : "Off"); 424 if ((item = fWarnUnencodableMenu->FindItem(label)) != NULL) 425 item->SetMarked(true); 426 427 strcpy(label, fSpellCheckStartOn ? "On" : "Off"); 428 if ((item = fSpellCheckStartOnMenu->FindItem(label)) != NULL) 429 item->SetMarked(true); 430 } else 431 Quit(); 432 break; 433 434 case P_FONT: 435 family = NULL; 436 style = NULL; 437 int32 family_menu_index; 438 if (msg->FindString("font", &family) == B_OK) { 439 msg->FindString("style", &style); 440 fNewFont->SetFamilyAndStyle(family, style); 441 message.what = M_FONT; 442 be_app->PostMessage(&message); 443 } 444 445 /* grab this little tidbit so we can set the correct Family */ 446 if (msg->FindInt32("parent_index", &family_menu_index) == B_OK) 447 fFontMenu->ItemAt(family_menu_index)->SetMarked(true); 448 break; 449 450 case P_SIZE: 451 old_size = (int32) fNewFont->Size(); 452 msg->FindInt32("size", &new_size); 453 if (old_size != new_size) { 454 fNewFont->SetSize(new_size); 455 message.what = M_FONT; 456 be_app->PostMessage(&message); 457 } 458 break; 459 460 case P_WRAP: 461 msg->FindBool("wrap", fNewWrap); 462 break; 463 case P_ATTACH_ATTRIBUTES: 464 msg->FindBool("attachAttributes", fNewAttachAttributes); 465 break; 466 case P_COLORED_QUOTES: 467 msg->FindBool("cquotes", fNewColoredQuotes); 468 break; 469 case P_ACCOUNT: 470 msg->FindInt32("id",(int32*)fNewAccount); 471 break; 472 case P_REPLYTO: 473 msg->FindInt32("replyTo", fNewReplyTo); 474 break; 475 case P_REPLY_PREAMBLE: 476 { 477 int32 index = -1; 478 if (msg->FindInt32("index", &index) < B_OK) 479 break; 480 BMenuItem *item = fReplyPreambleMenu->ItemAt(index); 481 if (item == NULL) { 482 msg->PrintToStream(); 483 break; 484 } 485 486 BTextView *text = fReplyPreamble->TextView(); 487 // To do: insert at selection point rather than at the end. 488 text->Insert(text->TextLength(), item->Label(), 2); 489 } 490 case P_SIG: 491 free(*fNewSignature); 492 if (msg->FindString("signature", &signature) == B_NO_ERROR) { 493 *fNewSignature = (char*)malloc(strlen(signature) + 1); 494 strcpy(*fNewSignature, signature); 495 } else { 496 *fNewSignature = (char*)malloc( 497 strlen(B_TRANSLATE("None")) + 1); 498 strcpy(*fNewSignature, B_TRANSLATE("None")); 499 } 500 break; 501 case P_ENC: 502 msg->FindInt32("encoding", (int32*)fNewEncoding); 503 break; 504 case P_WARN_UNENCODABLE: 505 msg->FindBool("warnUnencodable", fNewWarnUnencodable); 506 break; 507 case P_SPELL_CHECK_START_ON: 508 msg->FindBool("spellCheckStartOn", fNewSpellCheckStartOn); 509 break; 510 case P_MARK_READ: 511 msg->FindBool("autoMarkRead", fNewAutoMarkRead); 512 be_app->PostMessage(PREFS_CHANGED); 513 break; 514 case P_BUTTON_BAR: 515 msg->FindInt8("bar", (int8*)fNewButtonBar); 516 be_app->PostMessage(PREFS_CHANGED); 517 break; 518 519 default: 520 BWindow::MessageReceived(msg); 521 } 522 523 fFont.GetFamilyAndStyle(&old_family, &old_style); 524 fNewFont->GetFamilyAndStyle(&new_family, &new_style); 525 old_size = (int32) fFont.Size(); 526 new_size = (int32) fNewFont->Size(); 527 bool changed = old_size != new_size 528 || fWrap != *fNewWrap 529 || fAttachAttributes != *fNewAttachAttributes 530 || fColoredQuotes != *fNewColoredQuotes 531 || fAccount != *fNewAccount 532 || fReplyTo != *fNewReplyTo 533 || strcmp(old_family, new_family) 534 || strcmp(old_style, new_style) 535 || strcmp(fReplyPreamble->Text(), *fNewPreamble) 536 || strcmp(fSignature, *fNewSignature) 537 || fEncoding != *fNewEncoding 538 || fWarnUnencodable != *fNewWarnUnencodable 539 || fSpellCheckStartOn != *fNewSpellCheckStartOn 540 || fAutoMarkRead != *fNewAutoMarkRead 541 || fButtonBar != *fNewButtonBar; 542 fRevert->SetEnabled(changed); 543 } 544 545 546 BPopUpMenu* 547 TPrefsWindow::_BuildFontMenu(BFont* font) 548 { 549 font_family def_family; 550 font_style def_style; 551 font_family f_family; 552 font_style f_style; 553 554 BPopUpMenu *menu = new BPopUpMenu(""); 555 font->GetFamilyAndStyle(&def_family, &def_style); 556 557 int32 family_menu_index = 0; 558 int family_count = count_font_families(); 559 for (int family_loop = 0; family_loop < family_count; family_loop++) { 560 get_font_family(family_loop, &f_family); 561 BMenu *family_menu = new BMenu(f_family); 562 563 int style_count = count_font_styles(f_family); 564 for (int style_loop = 0; style_loop < style_count; style_loop++) { 565 get_font_style(f_family, style_loop, &f_style); 566 567 BMessage *msg = new BMessage(P_FONT); 568 msg->AddString("font", f_family); 569 msg->AddString("style", f_style); 570 // we send this to make setting the Family easier when things 571 // change 572 msg->AddInt32("parent_index", family_menu_index); 573 574 BMenuItem *item = new BMenuItem(f_style, msg); 575 family_menu->AddItem(item); 576 if ((strcmp(def_family, f_family) == 0) 577 && (strcmp(def_style, f_style) == 0)) { 578 item->SetMarked(true); 579 } 580 581 item->SetTarget(this); 582 } 583 584 menu->AddItem(family_menu); 585 BMenuItem *item = menu->ItemAt(family_menu_index); 586 BMessage *msg = new BMessage(P_FONT); 587 msg->AddString("font", f_family); 588 589 item->SetMessage(msg); 590 item->SetTarget(this); 591 if (strcmp(def_family, f_family) == 0) 592 item->SetMarked(true); 593 594 family_menu_index++; 595 } 596 return menu; 597 } 598 599 600 BPopUpMenu* 601 TPrefsWindow::_BuildLevelMenu(int32 level) 602 { 603 BMenuItem* item; 604 BMessage* msg; 605 BPopUpMenu* menu; 606 607 menu = new BPopUpMenu(""); 608 msg = new BMessage(P_LEVEL); 609 msg->AddInt32("level", L_BEGINNER); 610 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Beginner"), msg)); 611 if (level == L_BEGINNER) 612 item->SetMarked(true); 613 614 msg = new BMessage(P_LEVEL); 615 msg->AddInt32("level", L_EXPERT); 616 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Expert"), msg)); 617 if (level == L_EXPERT) 618 item->SetMarked(true); 619 620 return menu; 621 } 622 623 624 BPopUpMenu* 625 TPrefsWindow::_BuildAccountMenu(uint32 account) 626 { 627 BPopUpMenu* menu = new BPopUpMenu(""); 628 BMenuItem* item; 629 630 //menu->SetRadioMode(true); 631 BList chains; 632 if (GetOutboundMailChains(&chains) < B_OK) { 633 menu->AddItem(item = new BMenuItem("<no account found>", NULL)); 634 item->SetEnabled(false); 635 return menu; 636 } 637 638 BMessage* msg; 639 for (int32 i = 0; i < chains.CountItems(); i++) { 640 BMailChain* chain = (BMailChain*)chains.ItemAt(i); 641 item = new BMenuItem(chain->Name(), msg = new BMessage(P_ACCOUNT)); 642 643 msg->AddInt32("id",chain->ID()); 644 645 if (account == chain->ID()) 646 item->SetMarked(true); 647 648 menu->AddItem(item); 649 delete chain; 650 } 651 return menu; 652 } 653 654 655 BPopUpMenu* 656 TPrefsWindow::_BuildReplyToMenu(int32 account) 657 { 658 BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING); 659 660 BMenuItem* item; 661 BMessage* msg; 662 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Use default account"), 663 msg = new BMessage(P_REPLYTO))); 664 msg->AddInt32("replyTo", ACCOUNT_USE_DEFAULT); 665 if (account == ACCOUNT_USE_DEFAULT) 666 item->SetMarked(true); 667 668 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Account from mail"), 669 msg = new BMessage(P_REPLYTO))); 670 msg->AddInt32("replyTo", ACCOUNT_FROM_MAIL); 671 if (account == ACCOUNT_FROM_MAIL) 672 item->SetMarked(true); 673 674 return menu; 675 } 676 677 678 BMenu* 679 TPrefsWindow::_BuildReplyPreambleMenu() 680 { 681 const char *substitutes[] = { 682 /* To do: Not yet working, leave out for 2.0.0 beta 4: 683 "%f - First name", 684 "%l - Last name", 685 */ 686 B_TRANSLATE("%n - Full name"), 687 B_TRANSLATE("%e - E-mail address"), 688 B_TRANSLATE("%d - Date"), 689 "", 690 B_TRANSLATE("\\n - Newline"), 691 NULL 692 }; 693 694 BMenu *menu = new BMenu(B_EMPTY_STRING); 695 696 for (int32 i = 0; substitutes[i]; i++) { 697 if (*substitutes[i] == '\0') { 698 menu->AddSeparatorItem(); 699 } else { 700 menu->AddItem(new BMenuItem(substitutes[i], 701 new BMessage(P_REPLY_PREAMBLE))); 702 } 703 } 704 705 return menu; 706 } 707 708 709 BPopUpMenu* 710 TPrefsWindow::_BuildSignatureMenu(char* sig) 711 { 712 char name[B_FILE_NAME_LENGTH]; 713 BEntry entry; 714 BFile file; 715 BMenuItem* item; 716 BMessage* msg; 717 BQuery query; 718 BVolume vol; 719 BVolumeRoster volume; 720 721 BPopUpMenu* menu = new BPopUpMenu(""); 722 723 msg = new BMessage(P_SIG); 724 msg->AddString("signature", B_TRANSLATE("None")); 725 menu->AddItem(item = new BMenuItem(B_TRANSLATE("None"), msg)); 726 if (!strcmp(sig, B_TRANSLATE("None"))) 727 item->SetMarked(true); 728 729 msg = new BMessage(P_SIG); 730 msg->AddString("signature", B_TRANSLATE("Random")); 731 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Random"), msg)); 732 if (!strcmp(sig, B_TRANSLATE("Random"))) 733 item->SetMarked(true); 734 menu->AddSeparatorItem(); 735 736 volume.GetBootVolume(&vol); 737 query.SetVolume(&vol); 738 query.SetPredicate("_signature = *"); 739 query.Fetch(); 740 741 while (query.GetNextEntry(&entry) == B_NO_ERROR) { 742 file.SetTo(&entry, O_RDONLY); 743 if (file.InitCheck() == B_NO_ERROR) { 744 msg = new BMessage(P_SIG); 745 file.ReadAttr("_signature", B_STRING_TYPE, 0, name, sizeof(name)); 746 msg->AddString("signature", name); 747 menu->AddItem(item = new BMenuItem(name, msg)); 748 if (!strcmp(sig, name)) 749 item->SetMarked(true); 750 } 751 } 752 return menu; 753 } 754 755 756 BPopUpMenu* 757 TPrefsWindow::_BuildSizeMenu(BFont* font) 758 { 759 char label[16]; 760 uint32 loop; 761 int32 sizes[] = {9, 10, 11, 12, 14, 18, 24}; 762 float size; 763 BMenuItem* item; 764 BMessage* msg; 765 BPopUpMenu* menu; 766 767 menu = new BPopUpMenu(""); 768 size = font->Size(); 769 for (loop = 0; loop < sizeof(sizes) / sizeof(int32); loop++) { 770 msg = new BMessage(P_SIZE); 771 msg->AddInt32("size", sizes[loop]); 772 sprintf(label, "%ld", sizes[loop]); 773 menu->AddItem(item = new BMenuItem(label, msg)); 774 if (sizes[loop] == (int32)size) 775 item->SetMarked(true); 776 } 777 return menu; 778 } 779 780 781 BPopUpMenu* 782 TPrefsWindow::_BuildBoolMenu(uint32 what, const char* boolItem, bool isTrue) 783 { 784 BMenuItem* item; 785 BMessage* msg; 786 BPopUpMenu* menu; 787 788 menu = new BPopUpMenu(""); 789 msg = new BMessage(what); 790 msg->AddBool(boolItem, true); 791 menu->AddItem(item = new BMenuItem("On", msg)); 792 if (isTrue) 793 item->SetMarked(true); 794 795 msg = new BMessage(what); 796 msg->AddInt32(boolItem, false); 797 menu->AddItem(item = new BMenuItem("Off", msg)); 798 if (!isTrue) 799 item->SetMarked(true); 800 801 return menu; 802 } 803 804 805 BPopUpMenu* 806 TPrefsWindow::_BuildWrapMenu(bool wrap) 807 { 808 return _BuildBoolMenu(P_WRAP, "wrap", wrap); 809 } 810 811 812 BPopUpMenu* 813 TPrefsWindow::_BuildAttachAttributesMenu(bool attachAttributes) 814 { 815 BMenuItem* item; 816 BMessage* msg; 817 BPopUpMenu* menu; 818 819 menu = new BPopUpMenu(""); 820 msg = new BMessage(P_ATTACH_ATTRIBUTES); 821 msg->AddBool("attachAttributes", true); 822 menu->AddItem(item = new BMenuItem( 823 B_TRANSLATE("Include file attributes in attachments"), msg)); 824 if (attachAttributes) 825 item->SetMarked(true); 826 827 msg = new BMessage(P_ATTACH_ATTRIBUTES); 828 msg->AddInt32("attachAttributes", false); 829 menu->AddItem(item = new BMenuItem( 830 B_TRANSLATE("No file attributes, just plain data"), msg)); 831 if (!attachAttributes) 832 item->SetMarked(true); 833 834 return menu; 835 } 836 837 838 BPopUpMenu* 839 TPrefsWindow::_BuildColoredQuotesMenu(bool quote) 840 { 841 return _BuildBoolMenu(P_COLORED_QUOTES, "cquotes", quote); 842 } 843 844 845 BPopUpMenu* 846 TPrefsWindow::_BuildEncodingMenu(uint32 encoding) 847 { 848 BMenuItem* item; 849 BMessage* msg; 850 BPopUpMenu* menu; 851 852 menu = new BPopUpMenu(""); 853 854 BCharacterSetRoster roster; 855 BCharacterSet charset; 856 while (roster.GetNextCharacterSet(&charset) == B_NO_ERROR) { 857 BString name(charset.GetPrintName()); 858 const char* mime = charset.GetMIMEName(); 859 if (mime) 860 name << " (" << mime << ")"; 861 msg = new BMessage(P_ENC); 862 uint32 convert_id; 863 if ((mime == 0) || (strcasecmp(mime, "UTF-8") != 0)) 864 convert_id = charset.GetConversionID(); 865 else 866 convert_id = B_MAIL_UTF8_CONVERSION; 867 msg->AddInt32("encoding", convert_id); 868 menu->AddItem(item = new BMenuItem(name.String(), msg)); 869 if (convert_id == encoding) 870 item->SetMarked(true); 871 } 872 873 msg = new BMessage(P_ENC); 874 msg->AddInt32("encoding", B_MAIL_US_ASCII_CONVERSION); 875 menu->AddItem(item = new BMenuItem("US-ASCII", msg)); 876 if (encoding == B_MAIL_US_ASCII_CONVERSION) 877 item->SetMarked(true); 878 879 return menu; 880 } 881 882 883 BPopUpMenu* 884 TPrefsWindow::_BuildWarnUnencodableMenu(bool warnUnencodable) 885 { 886 return _BuildBoolMenu(P_WARN_UNENCODABLE, "warnUnencodable", 887 warnUnencodable); 888 } 889 890 891 BPopUpMenu* 892 TPrefsWindow::_BuildSpellCheckStartOnMenu(bool spellCheckStartOn) 893 { 894 return _BuildBoolMenu(P_SPELL_CHECK_START_ON, "spellCheckStartOn", 895 spellCheckStartOn); 896 } 897 898 899 BPopUpMenu* 900 TPrefsWindow::_BuildAutoMarkReadMenu(bool autoMarkRead) 901 { 902 return _BuildBoolMenu(P_MARK_READ, "autoMarkRead", 903 autoMarkRead); 904 } 905 906 907 BPopUpMenu* 908 TPrefsWindow::_BuildButtonBarMenu(uint8 show) 909 { 910 BMenuItem* item; 911 BMessage* msg; 912 BPopUpMenu* menu = new BPopUpMenu(""); 913 914 msg = new BMessage(P_BUTTON_BAR); 915 msg->AddInt8("bar", 1); 916 menu->AddItem(item = new BMenuItem( 917 B_TRANSLATE("Show icons & labels"), msg)); 918 if (show & 1) 919 item->SetMarked(true); 920 921 msg = new BMessage(P_BUTTON_BAR); 922 msg->AddInt8("bar", 2); 923 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Show icons only"), msg)); 924 if (show & 2) 925 item->SetMarked(true); 926 927 msg = new BMessage(P_BUTTON_BAR); 928 msg->AddInt8("bar", 0); 929 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Hide"), msg)); 930 if (!show) 931 item->SetMarked(true); 932 933 return menu; 934 } 935 936