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 CONNECTION 23 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 registered trademarks 30 of Be Incorporated in the United States and other countries. Other brand product 31 names are registered trademarks or trademarks of their respective holders. 32 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 #ifdef __HAIKU__ 47 # include <GridView.h> 48 # include <GroupLayoutBuilder.h> 49 #endif // __HAIKU__ 50 51 #include <MailSettings.h> 52 #include <mail_encoding.h> 53 #include <MDRLanguage.h> 54 55 #include <String.h> 56 #include <CharacterSet.h> 57 #include <CharacterSetRoster.h> 58 59 using namespace BPrivate; 60 61 #include "MailApp.h" 62 #include "MailSupport.h" 63 #include "MailWindow.h" 64 #include "Messages.h" 65 66 #define BUTTON_WIDTH 70 67 #define BUTTON_HEIGHT 20 68 #define ITEM_SPACE 6 69 70 #define FONT_TEXT MDR_DIALECT_CHOICE ("Font:", "フォント:") 71 #define SIZE_TEXT MDR_DIALECT_CHOICE ("Size:", "サイズ:") 72 #define LEVEL_TEXT MDR_DIALECT_CHOICE ("User Level:", "ユーザーレベル:") 73 #define WRAP_TEXT MDR_DIALECT_CHOICE ("Text Wrapping:", "テキスト・ラップ:") 74 #define ATTACH_ATTRIBUTES_TEXT MDR_DIALECT_CHOICE ("Attach Attributes:", "ファイル属性情報:") 75 #define QUOTES_TEXT MDR_DIALECT_CHOICE ("Colored Quotes:", "引用部分の着色:") 76 #define ACCOUNT_TEXT MDR_DIALECT_CHOICE ("Default Account:", "標準アカウント:") 77 #define REPLYTO_TEXT MDR_DIALECT_CHOICE ("Reply Account:", "返信用アカウント:") 78 #define REPLYTO_USE_DEFAULT_TEXT MDR_DIALECT_CHOICE ("Use Default Account", "標準アカウントを使う") 79 #define REPLYTO_FROM_MAIL_TEXT MDR_DIALECT_CHOICE ("Account From Mail", "メールのアカウントを使う") 80 #define REPLY_PREAMBLE_TEXT MDR_DIALECT_CHOICE ("Reply Preamble:", "返信へ追加:") 81 #define SIGNATURE_TEXT MDR_DIALECT_CHOICE ("Auto Signature:", "自動署名:") 82 #define ENCODING_TEXT MDR_DIALECT_CHOICE ("Encoding:", "エンコード形式:") 83 #define WARN_UNENCODABLE_TEXT MDR_DIALECT_CHOICE ("Warn Unencodable:", "警告: エンコードできません") 84 #define SPELL_CHECK_START_ON_TEXT MDR_DIALECT_CHOICE ("Initial Spell Check Mode:", "編集時スペルチェック:") 85 86 #define BUTTONBAR_TEXT MDR_DIALECT_CHOICE ("Button Bar:", "ボタンバー:") 87 88 #define OK_BUTTON_X1 (PREF_WIDTH - BUTTON_WIDTH - 6) 89 #define OK_BUTTON_X2 (OK_BUTTON_X1 + BUTTON_WIDTH) 90 #define OK_BUTTON_TEXT MDR_DIALECT_CHOICE ("OK", "設定") 91 #define CANCEL_BUTTON_TEXT MDR_DIALECT_CHOICE ("Cancel", "中止") 92 93 #define REVERT_BUTTON_X1 8 94 #define REVERT_BUTTON_X2 (REVERT_BUTTON_X1 + BUTTON_WIDTH) 95 #define REVERT_BUTTON_TEXT MDR_DIALECT_CHOICE ("Revert", "復元") 96 97 enum P_MESSAGES {P_OK = 128, P_CANCEL, P_REVERT, P_FONT, 98 P_SIZE, P_LEVEL, P_WRAP, P_ATTACH_ATTRIBUTES, 99 P_SIG, P_ENC, P_WARN_UNENCODABLE, 100 P_SPELL_CHECK_START_ON, P_BUTTON_BAR, 101 P_ACCOUNT, P_REPLYTO, P_REPLY_PREAMBLE, 102 P_COLORED_QUOTES}; 103 104 #define ICON_LABEL_TEXT MDR_DIALECT_CHOICE ("Show Icons & Labels", "アイコンとラベル") 105 #define ICON_TEXT MDR_DIALECT_CHOICE ("Show Icons Only", "アイコンのみ") 106 #define HIDE_TEXT MDR_DIALECT_CHOICE ("Hide", "隠す") 107 108 109 extern BPoint prefs_window; 110 111 #define ATTRIBUTE_ON_TEXT MDR_DIALECT_CHOICE ("Include BeOS Attributes in Attachments", "BeOSの属性を付ける") 112 #define ATTRIBUTE_OFF_TEXT MDR_DIALECT_CHOICE ("No BeOS Attributes, just Plain Data", "BeOSの属性を付けない(データのみ)") 113 114 //#pragma mark - 115 116 117 #ifdef __HAIKU__ 118 # define USE_LAYOUT_MANAGEMENT 1 119 #else 120 # define USE_LAYOUT_MANAGEMENT 0 121 #endif 122 123 124 #if USE_LAYOUT_MANAGEMENT 125 static inline void 126 add_menu_to_layout(BMenuField* menu, BGridLayout* layout, int32& row) 127 { 128 menu->SetAlignment(B_ALIGN_RIGHT); 129 layout->AddItem(menu->CreateLabelLayoutItem(), 0, row); 130 layout->AddItem(menu->CreateMenuBarLayoutItem(), 1, row, 2); 131 row++; 132 } 133 #endif 134 135 136 TPrefsWindow::TPrefsWindow(BRect rect, BFont* font, int32* level, bool* wrap, 137 bool* attachAttributes, bool* cquotes, uint32* account, int32* replyTo, 138 char** preamble, char** sig, uint32* encoding, bool* warnUnencodable, 139 bool* spellCheckStartOn, uint8* buttonBar) 140 : 141 #if USE_LAYOUT_MANAGEMENT 142 BWindow(rect, MDR_DIALECT_CHOICE ("Mail Preferences", "Mailの設定"), 143 B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE 144 | B_AUTO_UPDATE_SIZE_LIMITS), 145 #else 146 BWindow(rect, MDR_DIALECT_CHOICE ("Mail Preferences", "Mailの設定"), 147 B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE), 148 #endif 149 150 fNewWrap(wrap), 151 fWrap(*fNewWrap), 152 153 fNewAttachAttributes(attachAttributes), 154 fAttachAttributes(*fNewAttachAttributes), 155 156 fNewButtonBar(buttonBar), 157 fButtonBar(*fNewButtonBar), 158 159 fNewColoredQuotes(cquotes), 160 fColoredQuotes(*fNewColoredQuotes), 161 162 fNewAccount(account), 163 fAccount(*fNewAccount), 164 165 fNewReplyTo(replyTo), 166 fReplyTo(*fNewReplyTo), 167 168 fNewPreamble(preamble), 169 170 fNewSignature(sig), 171 fSignature((char*)malloc(strlen(*fNewSignature) + 1)), 172 173 fNewFont(font), 174 fFont(*fNewFont), 175 176 fNewEncoding(encoding), 177 fEncoding(*fNewEncoding), 178 179 fNewWarnUnencodable(warnUnencodable), 180 fWarnUnencodable(*fNewWarnUnencodable), 181 182 fNewSpellCheckStartOn(spellCheckStartOn), 183 fSpellCheckStartOn(*fNewSpellCheckStartOn) 184 { 185 strcpy(fSignature, *fNewSignature); 186 187 BMenuField* menu; 188 189 #if USE_LAYOUT_MANAGEMENT 190 // group boxes 191 192 const float kSpacing = 8; 193 194 BGridView* interfaceView = new BGridView(kSpacing, kSpacing); 195 BGridLayout* interfaceLayout = interfaceView->GridLayout(); 196 interfaceLayout->SetInsets(kSpacing, kSpacing, kSpacing, kSpacing); 197 BGridView* mailView = new BGridView(kSpacing, kSpacing); 198 BGridLayout* mailLayout = mailView->GridLayout(); 199 mailLayout->SetInsets(kSpacing, kSpacing, kSpacing, kSpacing); 200 201 interfaceLayout->AlignLayoutWith(mailLayout, B_HORIZONTAL); 202 203 BBox* interfaceBox = new BBox(B_FANCY_BORDER, interfaceView); 204 interfaceBox->SetLabel(MDR_DIALECT_CHOICE ("User Interface", 205 "ユーザーインターフェース")); 206 BBox* mailBox = new BBox(B_FANCY_BORDER, mailView); 207 mailBox->SetLabel(MDR_DIALECT_CHOICE ("Mailing", "メール関係")); 208 209 // revert, ok & cancel 210 211 BButton* okButton = new BButton("ok", OK_BUTTON_TEXT, new BMessage(P_OK)); 212 okButton->MakeDefault(true); 213 214 BButton* cancelButton = new BButton("cancel", CANCEL_BUTTON_TEXT, 215 new BMessage(P_CANCEL)); 216 217 fRevert = new BButton("revert", REVERT_BUTTON_TEXT, 218 new BMessage(P_REVERT)); 219 fRevert->SetEnabled(false); 220 221 // User Interface 222 int32 layoutRow = 0; 223 224 fButtonBarMenu = _BuildButtonBarMenu(*buttonBar); 225 menu = new BMenuField("bar", BUTTONBAR_TEXT, fButtonBarMenu, NULL); 226 add_menu_to_layout(menu, interfaceLayout, layoutRow); 227 228 fFontMenu = _BuildFontMenu(font); 229 menu = new BMenuField("font", FONT_TEXT, fFontMenu, NULL); 230 add_menu_to_layout(menu, interfaceLayout, layoutRow); 231 232 fSizeMenu = _BuildSizeMenu(font); 233 menu = new BMenuField("size", SIZE_TEXT, fSizeMenu, NULL); 234 add_menu_to_layout(menu, interfaceLayout, layoutRow); 235 236 fColoredQuotesMenu = _BuildColoredQuotesMenu(fColoredQuotes); 237 menu = new BMenuField("cquotes", QUOTES_TEXT, fColoredQuotesMenu, NULL); 238 add_menu_to_layout(menu, interfaceLayout, layoutRow); 239 240 fSpellCheckStartOnMenu = _BuildSpellCheckStartOnMenu(fSpellCheckStartOn); 241 menu = new BMenuField("spellCheckStartOn", SPELL_CHECK_START_ON_TEXT, 242 fSpellCheckStartOnMenu, NULL); 243 add_menu_to_layout(menu, interfaceLayout, layoutRow); 244 245 246 // Mail Accounts 247 248 layoutRow = 0; 249 250 fAccountMenu = _BuildAccountMenu(fAccount); 251 menu = new BMenuField("account", ACCOUNT_TEXT, fAccountMenu, NULL); 252 add_menu_to_layout(menu, mailLayout, layoutRow); 253 254 fReplyToMenu = _BuildReplyToMenu(fReplyTo); 255 menu = new BMenuField("replyTo", REPLYTO_TEXT, fReplyToMenu, NULL); 256 add_menu_to_layout(menu, mailLayout, layoutRow); 257 258 // Mail Contents 259 260 fReplyPreamble = new BTextControl("replytext", REPLY_PREAMBLE_TEXT, 261 *preamble, new BMessage(P_REPLY_PREAMBLE)); 262 fReplyPreamble->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); 263 264 fReplyPreambleMenu = _BuildReplyPreambleMenu(); 265 menu = new BMenuField("replyPreamble", NULL, fReplyPreambleMenu, NULL); 266 menu->SetExplicitMaxSize(BSize(27, B_SIZE_UNSET)); 267 268 mailLayout->AddItem(fReplyPreamble->CreateLabelLayoutItem(), 0, layoutRow); 269 mailLayout->AddItem(fReplyPreamble->CreateTextViewLayoutItem(), 1, 270 layoutRow); 271 mailLayout->AddView(menu, 2, layoutRow); 272 layoutRow++; 273 274 fSignatureMenu = _BuildSignatureMenu(*sig); 275 menu = new BMenuField("sig", SIGNATURE_TEXT, fSignatureMenu, NULL); 276 add_menu_to_layout(menu, mailLayout, layoutRow); 277 278 fEncodingMenu = _BuildEncodingMenu(fEncoding); 279 menu = new BMenuField("enc", ENCODING_TEXT, fEncodingMenu, NULL); 280 add_menu_to_layout(menu, mailLayout, layoutRow); 281 282 fWarnUnencodableMenu = _BuildWarnUnencodableMenu(fWarnUnencodable); 283 menu = new BMenuField("warnUnencodable", WARN_UNENCODABLE_TEXT, 284 fWarnUnencodableMenu, NULL); 285 add_menu_to_layout(menu, mailLayout, layoutRow); 286 287 fWrapMenu = _BuildWrapMenu(*wrap); 288 menu = new BMenuField("wrap", WRAP_TEXT, fWrapMenu, NULL); 289 add_menu_to_layout(menu, mailLayout, layoutRow); 290 291 fAttachAttributesMenu = _BuildAttachAttributesMenu(*attachAttributes); 292 menu = new BMenuField("attachAttributes", ATTACH_ATTRIBUTES_TEXT, 293 fAttachAttributesMenu, NULL); 294 add_menu_to_layout(menu, mailLayout, layoutRow); 295 296 SetLayout(new BGroupLayout(B_HORIZONTAL)); 297 298 AddChild(BGroupLayoutBuilder(B_VERTICAL, kSpacing) 299 .Add(interfaceBox) 300 .Add(mailBox) 301 .Add(BGroupLayoutBuilder(B_HORIZONTAL, kSpacing) 302 .Add(fRevert) 303 .AddGlue() 304 .Add(cancelButton) 305 .Add(okButton) 306 ) 307 .SetInsets(kSpacing, kSpacing, kSpacing, kSpacing) 308 ); 309 310 Show(); 311 312 #else // #if !USE_LAYOUT_MANAGEMENT 313 314 BRect r = Bounds(); 315 BView *view = new BView(r, NULL, B_FOLLOW_ALL, B_FRAME_EVENTS); 316 view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 317 AddChild(view); 318 319 // determine font height 320 font_height fontHeight; 321 view->GetFontHeight(&fontHeight); 322 int32 height = (int32)(fontHeight.ascent + fontHeight.descent 323 + fontHeight.leading) + 6; 324 int32 labelWidth = (int32)view->StringWidth(SPELL_CHECK_START_ON_TEXT) 325 + SEPARATOR_MARGIN; 326 327 // group boxes 328 329 r.Set(8, 4, Bounds().right - 8, 4 + 6 * (height + ITEM_SPACE)); 330 BBox* interfaceBox = new BBox(r , NULL,B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP); 331 interfaceBox->SetLabel(MDR_DIALECT_CHOICE ("User Interface", 332 "ユーザーインターフェース")); 333 view->AddChild(interfaceBox); 334 335 r.top = r.bottom + 8; 336 r.bottom = r.top + 9 * (height + ITEM_SPACE); 337 BBox* mailBox = new BBox(r,NULL,B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP); 338 mailBox->SetLabel(MDR_DIALECT_CHOICE ("Mailing", "メール関係")); 339 view->AddChild(mailBox); 340 341 // revert, ok & cancel 342 343 r.top = r.bottom + 10; 344 r.bottom = r.top + height; 345 r.left = OK_BUTTON_X1; 346 r.right = OK_BUTTON_X2; 347 BButton* button = new BButton(r, "ok", OK_BUTTON_TEXT, new BMessage(P_OK)); 348 button->MakeDefault(true); 349 view->AddChild(button); 350 351 r.OffsetBy(-(OK_BUTTON_X2 - OK_BUTTON_X1 + 10), 0); 352 button = new BButton(r, "cancel", CANCEL_BUTTON_TEXT, 353 new BMessage(P_CANCEL)); 354 view->AddChild(button); 355 356 r.left = REVERT_BUTTON_X1; r.right = REVERT_BUTTON_X2; 357 fRevert = new BButton(r, "revert", REVERT_BUTTON_TEXT, 358 new BMessage(P_REVERT)); 359 fRevert->SetEnabled(false); 360 view->AddChild(fRevert); 361 362 // User Interface 363 364 r = interfaceBox->Bounds(); 365 r.left += 8; 366 r.right -= 8; 367 r.top = height; 368 r.bottom = r.top + height - 3; 369 fButtonBarMenu = _BuildButtonBarMenu(*buttonBar); 370 menu = new BMenuField(r, "bar", BUTTONBAR_TEXT, fButtonBarMenu, 371 B_FOLLOW_ALL, B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 372 menu->SetDivider(labelWidth); 373 menu->SetAlignment(B_ALIGN_RIGHT); 374 interfaceBox->AddChild(menu); 375 376 r.OffsetBy(0, height + ITEM_SPACE); 377 fFontMenu = _BuildFontMenu(font); 378 menu = new BMenuField(r, "font", FONT_TEXT, fFontMenu, 379 B_FOLLOW_ALL, B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 380 menu->SetDivider(labelWidth); 381 menu->SetAlignment(B_ALIGN_RIGHT); 382 interfaceBox->AddChild(menu); 383 384 r.OffsetBy(0, height + ITEM_SPACE); 385 fSizeMenu = _BuildSizeMenu(font); 386 menu = new BMenuField(r, "size", SIZE_TEXT, fSizeMenu, 387 B_FOLLOW_ALL, B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 388 menu->SetDivider(labelWidth); 389 menu->SetAlignment(B_ALIGN_RIGHT); 390 interfaceBox->AddChild(menu); 391 392 r.OffsetBy(0, height + ITEM_SPACE); 393 fColoredQuotesMenu = _BuildColoredQuotesMenu(fColoredQuotes); 394 menu = new BMenuField(r, "cquotes", QUOTES_TEXT, fColoredQuotesMenu, 395 B_FOLLOW_ALL, B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 396 menu->SetDivider(labelWidth); 397 menu->SetAlignment(B_ALIGN_RIGHT); 398 interfaceBox->AddChild(menu); 399 400 r.OffsetBy(0, height + ITEM_SPACE); 401 fSpellCheckStartOnMenu = _BuildSpellCheckStartOnMenu(fSpellCheckStartOn); 402 menu = new BMenuField(r, "spellCheckStartOn", SPELL_CHECK_START_ON_TEXT, 403 fSpellCheckStartOnMenu, B_FOLLOW_ALL, 404 B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 405 menu->SetDivider(labelWidth); 406 menu->SetAlignment(B_ALIGN_RIGHT); 407 interfaceBox->AddChild(menu); 408 409 410 // Mail Accounts 411 412 r = mailBox->Bounds(); 413 r.left += 8; 414 r.right -= 8; 415 r.top = height; 416 r.bottom = r.top + height - 3; 417 fAccountMenu = _BuildAccountMenu(fAccount); 418 menu = new BMenuField(r, "account", ACCOUNT_TEXT, fAccountMenu, 419 B_FOLLOW_ALL, B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 420 menu->SetDivider(labelWidth); 421 menu->SetAlignment(B_ALIGN_RIGHT); 422 mailBox->AddChild(menu); 423 424 r.OffsetBy(0, height + ITEM_SPACE); 425 fReplyToMenu = _BuildReplyToMenu(fReplyTo); 426 menu = new BMenuField(r, "replyTo", REPLYTO_TEXT, fReplyToMenu, 427 B_FOLLOW_ALL, B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 428 menu->SetDivider(labelWidth); 429 menu->SetAlignment(B_ALIGN_RIGHT); 430 mailBox->AddChild(menu); 431 432 // Mail Contents 433 434 r.OffsetBy(0, height + ITEM_SPACE); 435 r.right -= 25; 436 fReplyPreamble = new BTextControl(r, "replytext", REPLY_PREAMBLE_TEXT, 437 *preamble, new BMessage(P_REPLY_PREAMBLE), B_FOLLOW_ALL, 438 B_WILL_DRAW | B_NAVIGABLE); 439 fReplyPreamble->SetDivider(labelWidth); 440 fReplyPreamble->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); 441 mailBox->AddChild(fReplyPreamble); 442 443 BRect popRect = r; 444 popRect.left = r.right + 6; 445 r.right += 25; 446 popRect.right = r.right; 447 fReplyPreambleMenu = _BuildReplyPreambleMenu(); 448 menu = new BMenuField(popRect, "replyPreamble", B_EMPTY_STRING, 449 fReplyPreambleMenu, B_FOLLOW_ALL, 450 B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 451 menu->SetDivider(0); 452 mailBox->AddChild(menu); 453 454 r.OffsetBy(0, height + ITEM_SPACE); 455 fSignatureMenu = _BuildSignatureMenu(*sig); 456 menu = new BMenuField(r, "sig", SIGNATURE_TEXT, fSignatureMenu, 457 B_FOLLOW_ALL, B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 458 menu->SetDivider(labelWidth); 459 menu->SetAlignment(B_ALIGN_RIGHT); 460 mailBox->AddChild(menu); 461 462 r.OffsetBy(0, height + ITEM_SPACE); 463 fEncodingMenu = _BuildEncodingMenu(fEncoding); 464 menu = new BMenuField(r, "enc", ENCODING_TEXT, fEncodingMenu, 465 B_FOLLOW_ALL, B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 466 menu->SetDivider(labelWidth); 467 menu->SetAlignment(B_ALIGN_RIGHT); 468 mailBox->AddChild(menu); 469 470 r.OffsetBy(0, height + ITEM_SPACE); 471 fWarnUnencodableMenu = _BuildWarnUnencodableMenu(fWarnUnencodable); 472 menu = new BMenuField(r, "warnUnencodable", WARN_UNENCODABLE_TEXT, 473 fWarnUnencodableMenu, B_FOLLOW_ALL, 474 B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 475 menu->SetDivider(labelWidth); 476 menu->SetAlignment(B_ALIGN_RIGHT); 477 mailBox->AddChild(menu); 478 479 r.OffsetBy(0, height + ITEM_SPACE); 480 fWrapMenu = _BuildWrapMenu(*wrap); 481 menu = new BMenuField(r, "wrap", WRAP_TEXT, fWrapMenu, B_FOLLOW_ALL, 482 B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 483 menu->SetDivider(labelWidth); 484 menu->SetAlignment(B_ALIGN_RIGHT); 485 mailBox->AddChild(menu); 486 487 r.OffsetBy(0, height + ITEM_SPACE); 488 fAttachAttributesMenu = _BuildAttachAttributesMenu(*attachAttributes); 489 menu = new BMenuField(r, "attachAttributes", ATTACH_ATTRIBUTES_TEXT, 490 fAttachAttributesMenu, B_FOLLOW_ALL, 491 B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); 492 menu->SetDivider(labelWidth); 493 menu->SetAlignment(B_ALIGN_RIGHT); 494 mailBox->AddChild(menu); 495 496 ResizeTo(Frame().Width(), fRevert->Frame().bottom + 8); 497 498 Show(); 499 500 #endif // #if !USE_LAYOUT_MANAGEMENT 501 } 502 503 504 TPrefsWindow::~TPrefsWindow() 505 { 506 BMessage msg(WINDOW_CLOSED); 507 msg.AddInt32("kind", PREFS_WINDOW); 508 msg.AddPoint("window pos", Frame().LeftTop()); 509 be_app->PostMessage(&msg); 510 } 511 512 513 void 514 TPrefsWindow::MessageReceived(BMessage* msg) 515 { 516 bool revert = true; 517 const char* family; 518 const char* signature; 519 const char* style; 520 char label[256]; 521 int32 new_size; 522 int32 old_size; 523 font_family new_family; 524 font_family old_family; 525 font_style new_style; 526 font_style old_style; 527 BMenuItem* item; 528 BMessage message; 529 530 switch (msg->what) { 531 case P_OK: 532 if (strcmp(fReplyPreamble->Text(), *fNewPreamble)) { 533 free(*fNewPreamble); 534 *fNewPreamble 535 = (char *)malloc(strlen(fReplyPreamble->Text()) + 1); 536 strcpy(*fNewPreamble, fReplyPreamble->Text()); 537 } 538 be_app->PostMessage(PREFS_CHANGED); 539 Quit(); 540 break; 541 542 case P_CANCEL: 543 revert = false; 544 // supposed to fall through 545 case P_REVERT: 546 fFont.GetFamilyAndStyle(&old_family, &old_style); 547 fNewFont->GetFamilyAndStyle(&new_family, &new_style); 548 old_size = (int32)fFont.Size(); 549 new_size = (int32)fNewFont->Size(); 550 if (strcmp(old_family, new_family) || strcmp(old_style, new_style) 551 || old_size != new_size) { 552 fNewFont->SetFamilyAndStyle(old_family, old_style); 553 if (revert) { 554 sprintf(label, "%s %s", old_family, old_style); 555 item = fFontMenu->FindItem(label); 556 if (item != NULL) 557 item->SetMarked(true); 558 } 559 560 fNewFont->SetSize(old_size); 561 if (revert) { 562 sprintf(label, "%ld", old_size); 563 item = fSizeMenu->FindItem(label); 564 if (item != NULL) 565 item->SetMarked(true); 566 } 567 message.what = M_FONT; 568 be_app->PostMessage(&message); 569 } 570 *fNewWrap = fWrap; 571 *fNewAttachAttributes = fAttachAttributes; 572 573 if (strcmp(fSignature, *fNewSignature)) { 574 free(*fNewSignature); 575 *fNewSignature = (char*)malloc(strlen(fSignature) + 1); 576 strcpy(*fNewSignature, fSignature); 577 } 578 579 *fNewEncoding = fEncoding; 580 *fNewWarnUnencodable = fWarnUnencodable; 581 *fNewSpellCheckStartOn = fSpellCheckStartOn; 582 *fNewButtonBar = fButtonBar; 583 584 be_app->PostMessage(PREFS_CHANGED); 585 586 if (revert) { 587 for (int i = fAccountMenu->CountItems(); --i > 0;) { 588 BMenuItem *item = fAccountMenu->ItemAt(i); 589 BMessage* itemMessage = item->Message(); 590 if (itemMessage != NULL 591 && itemMessage->FindInt32("id") == *(int32 *)&fAccount) { 592 item->SetMarked(true); 593 break; 594 } 595 } 596 597 strcpy(label,fReplyTo == ACCOUNT_USE_DEFAULT 598 ? REPLYTO_USE_DEFAULT_TEXT : REPLYTO_FROM_MAIL_TEXT); 599 if ((item = fReplyToMenu->FindItem(label)) != NULL) 600 item->SetMarked(true); 601 602 strcpy(label, fWrap ? "On" : "Off"); 603 if ((item = fWrapMenu->FindItem(label)) != NULL) 604 item->SetMarked(true); 605 606 strcpy(label, fAttachAttributes 607 ? ATTRIBUTE_ON_TEXT : ATTRIBUTE_OFF_TEXT); 608 if ((item = fAttachAttributesMenu->FindItem(label)) != NULL) 609 item->SetMarked(true); 610 611 strcpy(label, fColoredQuotes ? "On" : "Off"); 612 if ((item = fColoredQuotesMenu->FindItem(label)) != NULL) 613 item->SetMarked(true); 614 615 if (strcmp(fReplyPreamble->Text(), *fNewPreamble)) 616 fReplyPreamble->SetText(*fNewPreamble); 617 618 item = fSignatureMenu->FindItem(fSignature); 619 if (item) 620 item->SetMarked(true); 621 622 uint32 index = 0; 623 while ((item = fEncodingMenu->ItemAt(index++)) != NULL) { 624 BMessage* itemMessage = item->Message(); 625 if (itemMessage == NULL) 626 continue; 627 628 int32 encoding; 629 if (itemMessage->FindInt32("encoding", &encoding) == B_OK 630 && (uint32)encoding == *fNewEncoding) { 631 item->SetMarked(true); 632 break; 633 } 634 } 635 636 strcpy(label, fWarnUnencodable ? "On" : "Off"); 637 if ((item = fWarnUnencodableMenu->FindItem(label)) != NULL) 638 item->SetMarked(true); 639 640 strcpy(label, fSpellCheckStartOn ? "On" : "Off"); 641 if ((item = fSpellCheckStartOnMenu->FindItem(label)) != NULL) 642 item->SetMarked(true); 643 } else 644 Quit(); 645 break; 646 647 case P_FONT: 648 family = NULL; 649 style = NULL; 650 int32 family_menu_index; 651 if (msg->FindString("font", &family) == B_OK) { 652 msg->FindString("style", &style); 653 fNewFont->SetFamilyAndStyle(family, style); 654 message.what = M_FONT; 655 be_app->PostMessage(&message); 656 } 657 658 /* grab this little tidbit so we can set the correct Family */ 659 if (msg->FindInt32("parent_index", &family_menu_index) == B_OK) 660 fFontMenu->ItemAt(family_menu_index)->SetMarked(true); 661 break; 662 663 case P_SIZE: 664 old_size = (int32) fNewFont->Size(); 665 msg->FindInt32("size", &new_size); 666 if (old_size != new_size) { 667 fNewFont->SetSize(new_size); 668 message.what = M_FONT; 669 be_app->PostMessage(&message); 670 } 671 break; 672 673 case P_WRAP: 674 msg->FindBool("wrap", fNewWrap); 675 break; 676 case P_ATTACH_ATTRIBUTES: 677 msg->FindBool("attachAttributes", fNewAttachAttributes); 678 break; 679 case P_COLORED_QUOTES: 680 msg->FindBool("cquotes", fNewColoredQuotes); 681 break; 682 case P_ACCOUNT: 683 msg->FindInt32("id",(int32*)fNewAccount); 684 break; 685 case P_REPLYTO: 686 msg->FindInt32("replyTo", fNewReplyTo); 687 break; 688 case P_REPLY_PREAMBLE: 689 { 690 int32 index = -1; 691 if (msg->FindInt32("index", &index) < B_OK) 692 break; 693 BMenuItem *item = fReplyPreambleMenu->ItemAt(index); 694 if (item == NULL) { 695 msg->PrintToStream(); 696 break; 697 } 698 699 BTextView *text = fReplyPreamble->TextView(); 700 // To do: insert at selection point rather than at the end. 701 text->Insert(text->TextLength(), item->Label(), 2); 702 } 703 case P_SIG: 704 free(*fNewSignature); 705 if (msg->FindString("signature", &signature) == B_NO_ERROR) { 706 *fNewSignature = (char *)malloc(strlen(signature) + 1); 707 strcpy(*fNewSignature, signature); 708 } else { 709 *fNewSignature = (char *)malloc(strlen(SIG_NONE) + 1); 710 strcpy(*fNewSignature, SIG_NONE); 711 } 712 break; 713 case P_ENC: 714 msg->FindInt32("encoding", (int32 *)fNewEncoding); 715 break; 716 case P_WARN_UNENCODABLE: 717 msg->FindBool("warnUnencodable", fNewWarnUnencodable); 718 break; 719 case P_SPELL_CHECK_START_ON: 720 msg->FindBool("spellCheckStartOn", fNewSpellCheckStartOn); 721 break; 722 case P_BUTTON_BAR: 723 msg->FindInt8("bar", (int8 *)fNewButtonBar); 724 be_app->PostMessage(PREFS_CHANGED); 725 break; 726 727 default: 728 BWindow::MessageReceived(msg); 729 } 730 731 fFont.GetFamilyAndStyle(&old_family, &old_style); 732 fNewFont->GetFamilyAndStyle(&new_family, &new_style); 733 old_size = (int32) fFont.Size(); 734 new_size = (int32) fNewFont->Size(); 735 bool changed = old_size != new_size 736 || fWrap != *fNewWrap 737 || fAttachAttributes != *fNewAttachAttributes 738 || fColoredQuotes != *fNewColoredQuotes 739 || fAccount != *fNewAccount 740 || fReplyTo != *fNewReplyTo 741 || strcmp(old_family, new_family) 742 || strcmp(old_style, new_style) 743 || strcmp(fReplyPreamble->Text(), *fNewPreamble) 744 || strcmp(fSignature, *fNewSignature) 745 || fEncoding != *fNewEncoding 746 || fWarnUnencodable != *fNewWarnUnencodable 747 || fSpellCheckStartOn != *fNewSpellCheckStartOn 748 || fButtonBar != *fNewButtonBar; 749 fRevert->SetEnabled(changed); 750 } 751 752 753 BPopUpMenu* 754 TPrefsWindow::_BuildFontMenu(BFont* font) 755 { 756 font_family def_family; 757 font_style def_style; 758 font_family f_family; 759 font_style f_style; 760 761 BPopUpMenu *menu = new BPopUpMenu(""); 762 font->GetFamilyAndStyle(&def_family, &def_style); 763 764 int32 family_menu_index = 0; 765 int family_count = count_font_families(); 766 for (int family_loop = 0; family_loop < family_count; family_loop++) { 767 get_font_family(family_loop, &f_family); 768 BMenu *family_menu = new BMenu(f_family); 769 770 int style_count = count_font_styles(f_family); 771 for (int style_loop = 0; style_loop < style_count; style_loop++) { 772 get_font_style(f_family, style_loop, &f_style); 773 774 BMessage *msg = new BMessage(P_FONT); 775 msg->AddString("font", f_family); 776 msg->AddString("style", f_style); 777 // we send this to make setting the Family easier when things 778 // change 779 msg->AddInt32("parent_index", family_menu_index); 780 781 BMenuItem *item = new BMenuItem(f_style, msg); 782 family_menu->AddItem(item); 783 if ((strcmp(def_family, f_family) == 0) 784 && (strcmp(def_style, f_style) == 0)) { 785 item->SetMarked(true); 786 } 787 788 item->SetTarget(this); 789 } 790 791 menu->AddItem(family_menu); 792 BMenuItem *item = menu->ItemAt(family_menu_index); 793 BMessage *msg = new BMessage(P_FONT); 794 msg->AddString("font", f_family); 795 796 item->SetMessage(msg); 797 item->SetTarget(this); 798 if (strcmp(def_family, f_family) == 0) 799 item->SetMarked(true); 800 801 family_menu_index++; 802 } 803 return menu; 804 } 805 806 807 BPopUpMenu* 808 TPrefsWindow::_BuildLevelMenu(int32 level) 809 { 810 BMenuItem* item; 811 BMessage* msg; 812 BPopUpMenu* menu; 813 814 menu = new BPopUpMenu(""); 815 msg = new BMessage(P_LEVEL); 816 msg->AddInt32("level", L_BEGINNER); 817 menu->AddItem(item = new BMenuItem(MDR_DIALECT_CHOICE ("Beginner","初心者"), 818 msg)); 819 if (level == L_BEGINNER) 820 item->SetMarked(true); 821 822 msg = new BMessage(P_LEVEL); 823 msg->AddInt32("level", L_EXPERT); 824 menu->AddItem(item = new BMenuItem(MDR_DIALECT_CHOICE ("Expert","上級者"), 825 msg)); 826 if (level == L_EXPERT) 827 item->SetMarked(true); 828 829 return menu; 830 } 831 832 833 BPopUpMenu* 834 TPrefsWindow::_BuildAccountMenu(uint32 account) 835 { 836 BPopUpMenu* menu = new BPopUpMenu(""); 837 BMenuItem* item; 838 839 //menu->SetRadioMode(true); 840 BList chains; 841 if (GetOutboundMailChains(&chains) < B_OK) { 842 menu->AddItem(item = new BMenuItem("<no account found>", NULL)); 843 item->SetEnabled(false); 844 return menu; 845 } 846 847 BMessage* msg; 848 for (int32 i = 0; i < chains.CountItems(); i++) { 849 BMailChain* chain = (BMailChain*)chains.ItemAt(i); 850 item = new BMenuItem(chain->Name(), msg = new BMessage(P_ACCOUNT)); 851 852 msg->AddInt32("id",chain->ID()); 853 854 if (account == chain->ID()) 855 item->SetMarked(true); 856 857 menu->AddItem(item); 858 delete chain; 859 } 860 return menu; 861 } 862 863 864 BPopUpMenu* 865 TPrefsWindow::_BuildReplyToMenu(int32 account) 866 { 867 BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING); 868 869 BMenuItem* item; 870 BMessage* msg; 871 menu->AddItem(item = new BMenuItem(REPLYTO_USE_DEFAULT_TEXT, 872 msg = new BMessage(P_REPLYTO))); 873 msg->AddInt32("replyTo", ACCOUNT_USE_DEFAULT); 874 if (account == ACCOUNT_USE_DEFAULT) 875 item->SetMarked(true); 876 877 menu->AddItem(item = new BMenuItem(REPLYTO_FROM_MAIL_TEXT, 878 msg = new BMessage(P_REPLYTO))); 879 msg->AddInt32("replyTo", ACCOUNT_FROM_MAIL); 880 if (account == ACCOUNT_FROM_MAIL) 881 item->SetMarked(true); 882 883 return menu; 884 } 885 886 887 BMenu* 888 TPrefsWindow::_BuildReplyPreambleMenu() 889 { 890 const char *substitutes[] = { 891 /* To do: Not yet working, leave out for 2.0.0 beta 4: 892 "%f - First name", 893 "%l - Last name", 894 */ 895 MDR_DIALECT_CHOICE ("%n - Full name", "%n - フルネーム"), 896 MDR_DIALECT_CHOICE ("%e - E-mail address", "%e - E-mailアドレス"), 897 MDR_DIALECT_CHOICE ("%d - Date", "%d - 日付"), 898 "", 899 MDR_DIALECT_CHOICE ("\\n - Newline", "\\n - 空行"), 900 NULL 901 }; 902 903 BMenu *menu = new BMenu(B_EMPTY_STRING); 904 905 for (int32 i = 0; substitutes[i]; i++) { 906 if (*substitutes[i] == '\0') { 907 menu->AddSeparatorItem(); 908 } else { 909 menu->AddItem(new BMenuItem(substitutes[i], 910 new BMessage(P_REPLY_PREAMBLE))); 911 } 912 } 913 914 return menu; 915 } 916 917 918 BPopUpMenu* 919 TPrefsWindow::_BuildSignatureMenu(char* sig) 920 { 921 char name[B_FILE_NAME_LENGTH]; 922 BEntry entry; 923 BFile file; 924 BMenuItem* item; 925 BMessage* msg; 926 BQuery query; 927 BVolume vol; 928 BVolumeRoster volume; 929 930 BPopUpMenu* menu = new BPopUpMenu(""); 931 932 msg = new BMessage(P_SIG); 933 msg->AddString("signature", SIG_NONE); 934 menu->AddItem(item = new BMenuItem(SIG_NONE, msg)); 935 if (!strcmp(sig, SIG_NONE)) 936 item->SetMarked(true); 937 938 msg = new BMessage(P_SIG); 939 msg->AddString("signature", SIG_RANDOM); 940 menu->AddItem(item = new BMenuItem(SIG_RANDOM, msg)); 941 if (!strcmp(sig, SIG_RANDOM)) 942 item->SetMarked(true); 943 menu->AddSeparatorItem(); 944 945 volume.GetBootVolume(&vol); 946 query.SetVolume(&vol); 947 query.SetPredicate("_signature = *"); 948 query.Fetch(); 949 950 while (query.GetNextEntry(&entry) == B_NO_ERROR) { 951 file.SetTo(&entry, O_RDONLY); 952 if (file.InitCheck() == B_NO_ERROR) { 953 msg = new BMessage(P_SIG); 954 file.ReadAttr("_signature", B_STRING_TYPE, 0, name, sizeof(name)); 955 msg->AddString("signature", name); 956 menu->AddItem(item = new BMenuItem(name, msg)); 957 if (!strcmp(sig, name)) 958 item->SetMarked(true); 959 } 960 } 961 return menu; 962 } 963 964 965 BPopUpMenu* 966 TPrefsWindow::_BuildSizeMenu(BFont* font) 967 { 968 char label[16]; 969 uint32 loop; 970 int32 sizes[] = {9, 10, 11, 12, 14, 18, 24}; 971 float size; 972 BMenuItem* item; 973 BMessage* msg; 974 BPopUpMenu* menu; 975 976 menu = new BPopUpMenu(""); 977 size = font->Size(); 978 for (loop = 0; loop < sizeof(sizes) / sizeof(int32); loop++) { 979 msg = new BMessage(P_SIZE); 980 msg->AddInt32("size", sizes[loop]); 981 sprintf(label, "%ld", sizes[loop]); 982 menu->AddItem(item = new BMenuItem(label, msg)); 983 if (sizes[loop] == (int32)size) 984 item->SetMarked(true); 985 } 986 return menu; 987 } 988 989 990 BPopUpMenu* 991 TPrefsWindow::_BuildBoolMenu(uint32 what, const char* boolItem, bool isTrue) 992 { 993 BMenuItem* item; 994 BMessage* msg; 995 BPopUpMenu* menu; 996 997 menu = new BPopUpMenu(""); 998 msg = new BMessage(what); 999 msg->AddBool(boolItem, true); 1000 menu->AddItem(item = new BMenuItem("On", msg)); 1001 if (isTrue) 1002 item->SetMarked(true); 1003 1004 msg = new BMessage(what); 1005 msg->AddInt32(boolItem, false); 1006 menu->AddItem(item = new BMenuItem("Off", msg)); 1007 if (!isTrue) 1008 item->SetMarked(true); 1009 1010 return menu; 1011 } 1012 1013 1014 BPopUpMenu* 1015 TPrefsWindow::_BuildWrapMenu(bool wrap) 1016 { 1017 return _BuildBoolMenu(P_WRAP, "wrap", wrap); 1018 } 1019 1020 1021 BPopUpMenu* 1022 TPrefsWindow::_BuildAttachAttributesMenu(bool attachAttributes) 1023 { 1024 BMenuItem* item; 1025 BMessage* msg; 1026 BPopUpMenu* menu; 1027 1028 menu = new BPopUpMenu(""); 1029 msg = new BMessage(P_ATTACH_ATTRIBUTES); 1030 msg->AddBool("attachAttributes", true); 1031 menu->AddItem(item = new BMenuItem(ATTRIBUTE_ON_TEXT, msg)); 1032 if (attachAttributes) 1033 item->SetMarked(true); 1034 1035 msg = new BMessage(P_ATTACH_ATTRIBUTES); 1036 msg->AddInt32("attachAttributes", false); 1037 menu->AddItem(item = new BMenuItem(ATTRIBUTE_OFF_TEXT, msg)); 1038 if (!attachAttributes) 1039 item->SetMarked(true); 1040 1041 return menu; 1042 } 1043 1044 1045 BPopUpMenu* 1046 TPrefsWindow::_BuildColoredQuotesMenu(bool quote) 1047 { 1048 return _BuildBoolMenu(P_COLORED_QUOTES, "cquotes", quote); 1049 } 1050 1051 1052 BPopUpMenu* 1053 TPrefsWindow::_BuildEncodingMenu(uint32 encoding) 1054 { 1055 BMenuItem* item; 1056 BMessage* msg; 1057 BPopUpMenu* menu; 1058 1059 menu = new BPopUpMenu(""); 1060 1061 BCharacterSetRoster roster; 1062 BCharacterSet charset; 1063 while (roster.GetNextCharacterSet(&charset) == B_NO_ERROR) { 1064 BString name(charset.GetPrintName()); 1065 const char* mime = charset.GetMIMEName(); 1066 if (mime) 1067 name << " (" << mime << ")"; 1068 msg = new BMessage(P_ENC); 1069 uint32 convert_id; 1070 if ((mime == 0) || (strcasecmp(mime, "UTF-8") != 0)) 1071 convert_id = charset.GetConversionID(); 1072 else 1073 convert_id = B_MAIL_UTF8_CONVERSION; 1074 msg->AddInt32("encoding", convert_id); 1075 menu->AddItem(item = new BMenuItem(name.String(), msg)); 1076 if (convert_id == encoding) 1077 item->SetMarked(true); 1078 } 1079 1080 msg = new BMessage(P_ENC); 1081 msg->AddInt32("encoding", B_MAIL_US_ASCII_CONVERSION); 1082 menu->AddItem(item = new BMenuItem("US-ASCII", msg)); 1083 if (encoding == B_MAIL_US_ASCII_CONVERSION) 1084 item->SetMarked(true); 1085 1086 return menu; 1087 } 1088 1089 1090 BPopUpMenu* 1091 TPrefsWindow::_BuildWarnUnencodableMenu(bool warnUnencodable) 1092 { 1093 return _BuildBoolMenu(P_WARN_UNENCODABLE, "warnUnencodable", 1094 warnUnencodable); 1095 } 1096 1097 1098 BPopUpMenu* 1099 TPrefsWindow::_BuildSpellCheckStartOnMenu(bool spellCheckStartOn) 1100 { 1101 return _BuildBoolMenu(P_SPELL_CHECK_START_ON, "spellCheckStartOn", 1102 spellCheckStartOn); 1103 } 1104 1105 1106 BPopUpMenu* 1107 TPrefsWindow::_BuildButtonBarMenu(uint8 show) 1108 { 1109 BMenuItem* item; 1110 BMessage* msg; 1111 BPopUpMenu* menu = new BPopUpMenu(""); 1112 1113 msg = new BMessage(P_BUTTON_BAR); 1114 msg->AddInt8("bar", 1); 1115 menu->AddItem(item = new BMenuItem(ICON_LABEL_TEXT, msg)); 1116 if (show & 1) 1117 item->SetMarked(true); 1118 1119 msg = new BMessage(P_BUTTON_BAR); 1120 msg->AddInt8("bar", 2); 1121 menu->AddItem(item = new BMenuItem(ICON_TEXT, msg)); 1122 if (show & 2) 1123 item->SetMarked(true); 1124 1125 msg = new BMessage(P_BUTTON_BAR); 1126 msg->AddInt8("bar", 0); 1127 menu->AddItem(item = new BMenuItem(HIDE_TEXT, msg)); 1128 if (!show) 1129 item->SetMarked(true); 1130 1131 return menu; 1132 } 1133