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