1 /* ConfigWindow - main eMail config window 2 ** 3 ** Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved. 4 */ 5 6 7 #include "ConfigWindow.h" 8 #include "CenterContainer.h" 9 #include "Account.h" 10 11 #include <Application.h> 12 #include <ListView.h> 13 #include <ScrollView.h> 14 #include <StringView.h> 15 #include <Button.h> 16 #include <CheckBox.h> 17 #include <MenuField.h> 18 #include <TextControl.h> 19 #include <TextView.h> 20 #include <MenuItem.h> 21 #include <Screen.h> 22 #include <PopUpMenu.h> 23 #include <MenuBar.h> 24 #include <TabView.h> 25 #include <Box.h> 26 #include <Alert.h> 27 #include <Bitmap.h> 28 #include <Roster.h> 29 #include <Resources.h> 30 #include <Region.h> 31 32 #include <Entry.h> 33 #include <Directory.h> 34 #include <FindDirectory.h> 35 #include <Path.h> 36 #include <AppFileInfo.h> 37 38 #include <MailSettings.h> 39 40 #include <stdio.h> 41 #include <string.h> 42 43 #include <MDRLanguage.h> 44 45 // define if you want to have an apply button 46 //#define HAVE_APPLY_BUTTON 47 48 const char *kEMail = "bemaildaemon-talk@bug-br.org.br"; 49 const char *kMailto = "mailto:bemaildaemon-talk@bug-br.org.br"; 50 const char *kBugsitePretty = "Bug-Tracker at SourceForge.net"; 51 const char *kBugsite = "http://sourceforge.net/tracker/?func=add&group_id=26926&atid=388726"; 52 const char *kWebsite = "http://www.haiku-os.org"; 53 const rgb_color kLinkColor = {40,40,180}; 54 55 56 const uint32 kMsgAccountSelected = 'acsl'; 57 const uint32 kMsgAddAccount = 'adac'; 58 const uint32 kMsgRemoveAccount = 'rmac'; 59 60 const uint32 kMsgIntervalUnitChanged = 'iuch'; 61 62 const uint32 kMsgShowStatusWindowChanged = 'shst'; 63 const uint32 kMsgStatusLookChanged = 'lkch'; 64 const uint32 kMsgStatusWorkspaceChanged = 'wsch'; 65 66 const uint32 kMsgApplySettings = 'apst'; 67 const uint32 kMsgSaveSettings = 'svst'; 68 const uint32 kMsgRevertSettings = 'rvst'; 69 const uint32 kMsgCancelSettings = 'cnst'; 70 71 class AccountsListView : public BListView { 72 public: 73 AccountsListView(BRect rect) : BListView(rect,NULL,B_SINGLE_SELECTION_LIST,B_FOLLOW_ALL) {} 74 virtual void KeyDown(const char *bytes, int32 numBytes) { 75 if (numBytes != 1) 76 return; 77 78 if ((*bytes == B_DELETE) || (*bytes == B_BACKSPACE)) 79 Window()->PostMessage(kMsgRemoveAccount); 80 81 BListView::KeyDown(bytes,numBytes); 82 } 83 }; 84 85 class BitmapView : public BView 86 { 87 public: 88 BitmapView(BBitmap *bitmap) : BView(bitmap->Bounds(),NULL,B_FOLLOW_NONE,B_WILL_DRAW) 89 { 90 fBitmap = bitmap; 91 92 SetDrawingMode(B_OP_ALPHA); 93 } 94 95 ~BitmapView() 96 { 97 delete fBitmap; 98 } 99 100 virtual void AttachedToWindow() 101 { 102 SetViewColor(Parent()->ViewColor()); 103 104 MoveTo((Parent()->Bounds().Width() - Bounds().Width()) / 2,Frame().top); 105 } 106 107 virtual void Draw(BRect updateRect) 108 { 109 DrawBitmap(fBitmap,updateRect,updateRect); 110 } 111 112 private: 113 BBitmap *fBitmap; 114 }; 115 116 117 class AboutTextView : public BTextView 118 { 119 public: 120 AboutTextView(BRect rect) : BTextView(rect,NULL,rect.OffsetToCopy(B_ORIGIN),B_FOLLOW_NONE,B_WILL_DRAW) 121 { 122 int32 major = 0,middle = 0,minor = 0,variety = 0,internal = 1; 123 124 // get version information for app 125 126 app_info appInfo; 127 if (be_app->GetAppInfo(&appInfo) == B_OK) 128 { 129 BFile file(&appInfo.ref,B_READ_ONLY); 130 if (file.InitCheck() == B_OK) 131 { 132 BAppFileInfo info(&file); 133 if (info.InitCheck() == B_OK) 134 { 135 version_info versionInfo; 136 if (info.GetVersionInfo(&versionInfo,B_APP_VERSION_KIND) == B_OK) 137 { 138 major = versionInfo.major; 139 middle = versionInfo.middle; 140 minor = versionInfo.minor; 141 variety = versionInfo.variety; 142 internal = versionInfo.internal; 143 } 144 } 145 } 146 } 147 // prepare version variety string 148 const char *varietyStrings[] = {"Development","Alpha","Beta","Gamma","Golden master","Final"}; 149 char varietyString[32]; 150 strcpy(varietyString,varietyStrings[variety % 6]); 151 if (variety < 5) 152 sprintf(varietyString + strlen(varietyString),"/%li",internal); 153 154 char s[512]; 155 sprintf(s, "Mail Daemon Replacement\n\n" 156 "by Haiku, Inc. All rights reserved.\n\n" 157 "Version %ld.%ld.%ld %s\n\n" 158 "See LICENSE file included in the installation package for more information.\n\n\n\n" 159 "You can contact us at:\n" 160 "%s\n\n" 161 "Please submit bug reports using the %s\n\n" 162 "Project homepage at:\n%s", 163 major,middle,minor,varietyString, 164 kEMail,kBugsitePretty,kWebsite); 165 166 SetText(s); 167 MakeEditable(false); 168 MakeSelectable(false); 169 170 SetAlignment(B_ALIGN_CENTER); 171 SetStylable(true); 172 173 // aethetical changes 174 BFont font; 175 GetFont(&font); 176 font.SetSize(24); 177 SetFontAndColor(0,23,&font,B_FONT_SIZE); 178 179 // center the view vertically 180 rect = TextRect(); rect.OffsetTo(0,(Bounds().Height() - TextHeight(0,42)) / 2); 181 SetTextRect(rect); 182 183 // set the link regions 184 int start = strstr(s,kEMail) - s; 185 int finish = start + strlen(kEMail); 186 GetTextRegion(start,finish,&fMail); 187 SetFontAndColor(start,finish,NULL,0,&kLinkColor); 188 189 start = strstr(s,kBugsitePretty) - s; 190 finish = start + strlen(kBugsitePretty); 191 GetTextRegion(start,finish,&fBugsite); 192 SetFontAndColor(start,finish,NULL,0,&kLinkColor); 193 194 start = strstr(s,kWebsite) - s; 195 finish = start + strlen(kWebsite); 196 GetTextRegion(start,finish,&fWebsite); 197 SetFontAndColor(start,finish,NULL,0,&kLinkColor); 198 } 199 200 virtual void Draw(BRect updateRect) 201 { 202 BTextView::Draw(updateRect); 203 204 BRect rect(fMail.Frame()); 205 StrokeLine(BPoint(rect.left,rect.bottom-2),BPoint(rect.right,rect.bottom-2)); 206 rect = fBugsite.Frame(); 207 StrokeLine(BPoint(rect.left,rect.bottom-2),BPoint(rect.right,rect.bottom-2)); 208 rect = fWebsite.Frame(); 209 StrokeLine(BPoint(rect.left,rect.bottom-2),BPoint(rect.right,rect.bottom-2)); 210 } 211 212 virtual void MouseDown(BPoint point) 213 { 214 if (fMail.Contains(point)) { 215 char *arg[] = {(char *)kMailto,NULL}; 216 be_roster->Launch("text/x-email",1,arg); 217 } else if (fBugsite.Contains(point)) { 218 char *arg[] = {(char *)kBugsite,NULL}; 219 be_roster->Launch("text/html",1,arg); 220 } else if (fWebsite.Contains(point)) { 221 char *arg[] = {(char *)kWebsite, NULL}; 222 be_roster->Launch("text/html", 1, arg); 223 } 224 } 225 226 private: 227 BRegion fWebsite,fMail,fBugsite; 228 }; 229 230 231 //-------------------------------------------------------------------------------------- 232 // #pragma mark - 233 234 235 ConfigWindow::ConfigWindow() 236 : BWindow(BRect(200.0, 200.0, 640.0, 640.0), 237 "E-mail", B_TITLED_WINDOW, 238 B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_NOT_RESIZABLE), 239 fLastSelectedAccount(NULL), 240 fSaveSettings(false) 241 { 242 /*** create controls ***/ 243 244 BRect rect(Bounds()); 245 BView *top = new BView(rect,NULL,B_FOLLOW_ALL,0); 246 top->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 247 AddChild(top); 248 249 // determine font height 250 font_height fontHeight; 251 top->GetFontHeight(&fontHeight); 252 int32 height = (int32)(fontHeight.ascent + fontHeight.descent + fontHeight.leading) + 5; 253 254 rect.InsetBy(5,5); rect.bottom -= 11 + height; 255 BTabView *tabView = new BTabView(rect,NULL); 256 257 BView *view; 258 rect = tabView->Bounds(); rect.bottom -= tabView->TabHeight() + 4; 259 tabView->AddTab(view = new BView(rect,NULL,B_FOLLOW_ALL,0)); 260 tabView->TabAt(0)->SetLabel(MDR_DIALECT_CHOICE ("Accounts","アカウント")); 261 view->SetViewColor(top->ViewColor()); 262 263 // accounts listview 264 265 rect = view->Bounds().InsetByCopy(8,8); 266 rect.right = 140 - B_V_SCROLL_BAR_WIDTH; 267 rect.bottom -= height + 12; 268 fAccountsListView = new AccountsListView(rect); 269 view->AddChild(new BScrollView(NULL,fAccountsListView,B_FOLLOW_ALL,0,false,true)); 270 rect.right += B_V_SCROLL_BAR_WIDTH; 271 272 rect.top = rect.bottom + 8; rect.bottom = rect.top + height; 273 BRect sizeRect = rect; 274 sizeRect.right = sizeRect.left + 30 + view->StringWidth(MDR_DIALECT_CHOICE ("Add","追加")); 275 view->AddChild(new BButton(sizeRect,NULL,MDR_DIALECT_CHOICE ("Add","追加"), 276 new BMessage(kMsgAddAccount),B_FOLLOW_BOTTOM)); 277 278 sizeRect.left = sizeRect.right+3; 279 sizeRect.right = sizeRect.left + 30 + view->StringWidth(MDR_DIALECT_CHOICE ("Remove","削除")); 280 view->AddChild(fRemoveButton = new BButton(sizeRect,NULL,MDR_DIALECT_CHOICE ("Remove","削除"), 281 new BMessage(kMsgRemoveAccount),B_FOLLOW_BOTTOM)); 282 283 // accounts config view 284 rect = view->Bounds(); 285 rect.left = fAccountsListView->Frame().right + B_V_SCROLL_BAR_WIDTH + 16; 286 rect.right -= 10; 287 view->AddChild(fConfigView = new CenterContainer(rect)); 288 289 MakeHowToView(); 290 291 // general settings 292 293 rect = tabView->Bounds(); rect.bottom -= tabView->TabHeight() + 4; 294 tabView->AddTab(view = new CenterContainer(rect)); 295 tabView->TabAt(1)->SetLabel(MDR_DIALECT_CHOICE ("General","一般")); 296 297 rect = view->Bounds().InsetByCopy(8,8); 298 rect.right -= 1; rect.bottom = rect.top + height * 5 + 15; 299 BBox *box = new BBox(rect); 300 box->SetLabel(MDR_DIALECT_CHOICE ("Retrieval Frequency","メールチェック間隔")); 301 view->AddChild(box); 302 303 rect = box->Bounds().InsetByCopy(8,8); 304 rect.top += 7; rect.bottom = rect.top + height + 5; 305 BRect tile = rect.OffsetByCopy(0,1); 306 int32 labelWidth = (int32)view->StringWidth(MDR_DIALECT_CHOICE ("Check every:","メールチェック間隔:"))+6; 307 tile.right = 80 + labelWidth; 308 fIntervalControl = new BTextControl(tile,"time",MDR_DIALECT_CHOICE ("Check every:","メールチェック間隔:"), 309 NULL,NULL); 310 fIntervalControl->SetDivider(labelWidth); 311 box->AddChild(fIntervalControl); 312 313 BPopUpMenu *frequencyPopUp = new BPopUpMenu(B_EMPTY_STRING); 314 const char *frequencyStrings[] = { 315 MDR_DIALECT_CHOICE ("Never","チェックしない"), 316 MDR_DIALECT_CHOICE ("Minutes","分毎チェック"), 317 MDR_DIALECT_CHOICE ("Hours","時間毎チェック"), 318 MDR_DIALECT_CHOICE ("Days","日間毎チェック")}; 319 BMenuItem *item; 320 for (int32 i = 0;i < 4;i++) 321 { 322 frequencyPopUp->AddItem(item = new BMenuItem(frequencyStrings[i],new BMessage(kMsgIntervalUnitChanged))); 323 if (i == 1) 324 item->SetMarked(true); 325 } 326 tile.left = tile.right + 5; tile.right = rect.right; 327 tile.OffsetBy(0,-1); 328 fIntervalUnitField = new BMenuField(tile,"frequency", B_EMPTY_STRING, frequencyPopUp); 329 fIntervalUnitField->SetDivider(0.0); 330 box->AddChild(fIntervalUnitField); 331 332 rect.OffsetBy(0,height + 9); rect.bottom -= 2; 333 fPPPActiveCheckBox = new BCheckBox(rect,"ppp active", 334 MDR_DIALECT_CHOICE ("only when PPP is active","PPP接続中時のみ"), NULL); 335 box->AddChild(fPPPActiveCheckBox); 336 337 rect.OffsetBy(0,height + 9); rect.bottom -= 2; 338 fPPPActiveSendCheckBox = new BCheckBox(rect,"ppp activesend", 339 MDR_DIALECT_CHOICE ("Queue outgoing mail when PPP is inactive","PPP切断時、送信メールを送信箱に入れる"), NULL); 340 box->AddChild(fPPPActiveSendCheckBox); 341 342 rect = box->Frame(); rect.bottom = rect.top + 4*height + 20; 343 box = new BBox(rect); 344 box->SetLabel(MDR_DIALECT_CHOICE ("Status Window","送受信状況の表示")); 345 view->AddChild(box); 346 347 BPopUpMenu *statusPopUp = new BPopUpMenu(B_EMPTY_STRING); 348 const char *statusModes[] = { 349 MDR_DIALECT_CHOICE ("Never","表示しない"), 350 MDR_DIALECT_CHOICE ("While Sending","送信時"), 351 MDR_DIALECT_CHOICE ("While Sending / Fetching","送受信時"), 352 MDR_DIALECT_CHOICE ("Always","常に表示")}; 353 BMessage *msg; 354 for (int32 i = 0;i < 4;i++) 355 { 356 statusPopUp->AddItem(item = new BMenuItem(statusModes[i],msg = new BMessage(kMsgShowStatusWindowChanged))); 357 msg->AddInt32("ShowStatusWindow",i); 358 if (i == 0) 359 item->SetMarked(true); 360 } 361 rect = box->Bounds().InsetByCopy(8,8); 362 rect.top += 7; rect.bottom = rect.top + height + 5; 363 labelWidth = (int32)view->StringWidth( 364 MDR_DIALECT_CHOICE ("Show Status Window:","ステータスの表示:")) + 8; 365 fStatusModeField = new BMenuField(rect,"show status", 366 MDR_DIALECT_CHOICE ("Show Status Window:","ステータスの表示:"), 367 statusPopUp); 368 fStatusModeField->SetDivider(labelWidth); 369 box->AddChild(fStatusModeField); 370 371 BPopUpMenu *lookPopUp = new BPopUpMenu(B_EMPTY_STRING); 372 const char *windowLookStrings[] = { 373 MDR_DIALECT_CHOICE ("Normal, With Tab","タブ付通常"), 374 MDR_DIALECT_CHOICE ("Normal, Border Only","ボーダーのみ通常"), 375 MDR_DIALECT_CHOICE ("Floating","フローティング"), 376 MDR_DIALECT_CHOICE ("Thin Border","細いボーダー"), 377 MDR_DIALECT_CHOICE ("No Border","ボーダー無し")}; 378 for (int32 i = 0;i < 5;i++) 379 { 380 lookPopUp->AddItem(item = new BMenuItem(windowLookStrings[i],msg = new BMessage(kMsgStatusLookChanged))); 381 msg->AddInt32("StatusWindowLook",i); 382 if (i == 0) 383 item->SetMarked(true); 384 } 385 rect.OffsetBy(0, height + 6); 386 fStatusLookField = new BMenuField(rect,"status look", 387 MDR_DIALECT_CHOICE ("Window Look:","ウィンドウ外観:"),lookPopUp); 388 fStatusLookField->SetDivider(labelWidth); 389 box->AddChild(fStatusLookField); 390 391 BPopUpMenu *workspacesPopUp = new BPopUpMenu(B_EMPTY_STRING); 392 workspacesPopUp->AddItem(item = new BMenuItem( 393 MDR_DIALECT_CHOICE ("Current Workspace","使用中ワークスペース"), 394 msg = new BMessage(kMsgStatusWorkspaceChanged))); 395 msg->AddInt32("StatusWindowWorkSpace", 0); 396 workspacesPopUp->AddItem(item = new BMenuItem( 397 MDR_DIALECT_CHOICE ("All Workspaces","全てのワークスペース"), 398 msg = new BMessage(kMsgStatusWorkspaceChanged))); 399 msg->AddInt32("StatusWindowWorkSpace", -1); 400 401 rect.OffsetBy(0,height + 6); 402 fStatusWorkspaceField = new BMenuField(rect,"status workspace", 403 MDR_DIALECT_CHOICE ("Window visible on:","表示場所:"),workspacesPopUp); 404 fStatusWorkspaceField->SetDivider(labelWidth); 405 box->AddChild(fStatusWorkspaceField); 406 407 rect = box->Frame(); rect.bottom = rect.top + 3*height + 13; 408 box = new BBox(rect); 409 box->SetLabel(MDR_DIALECT_CHOICE ("Deskbar Icon","デスクバーアイコンリンク")); 410 view->AddChild(box); 411 412 rect = box->Bounds().InsetByCopy(8,8); 413 rect.top += 7; rect.bottom = rect.top + height + 5; 414 BStringView *stringView = new BStringView(rect,B_EMPTY_STRING, MDR_DIALECT_CHOICE ( 415 "The menu links are links to folders in a real folder like the Be menu.", 416 "デスクバーで表示する項目の設定")); 417 box->AddChild(stringView); 418 stringView->SetAlignment(B_ALIGN_CENTER); 419 stringView->ResizeToPreferred(); 420 // BStringView::ResizeToPreferred() changes the width, so that the 421 // alignment has no effect anymore 422 stringView->ResizeTo(rect.Width(), stringView->Bounds().Height()); 423 424 rect.left += 100; rect.right -= 100; 425 rect.OffsetBy(0,height + 1); 426 BButton *button = new BButton(rect,B_EMPTY_STRING, 427 MDR_DIALECT_CHOICE ("Configure Menu Links","メニューリンクの設定"), 428 msg = new BMessage(B_REFS_RECEIVED)); 429 box->AddChild(button); 430 button->SetTarget(BMessenger("application/x-vnd.Be-TRAK")); 431 432 BPath path; 433 find_directory(B_USER_SETTINGS_DIRECTORY, &path); 434 path.Append("Mail/Menu Links"); 435 BEntry entry(path.Path()); 436 if (entry.InitCheck() == B_OK && entry.Exists()) { 437 entry_ref ref; 438 entry.GetRef(&ref); 439 msg->AddRef("refs", &ref); 440 } 441 else 442 button->SetEnabled(false); 443 444 rect = box->Frame(); rect.bottom = rect.top + 2*height + 6; 445 box = new BBox(rect); 446 box->SetLabel(MDR_DIALECT_CHOICE ("Misc.","その他の設定")); 447 view->AddChild(box); 448 449 rect = box->Bounds().InsetByCopy(8,8); 450 rect.top += 7; rect.bottom = rect.top + height + 5; 451 fAutoStartCheckBox = new BCheckBox(rect,"start daemon", 452 MDR_DIALECT_CHOICE ("Auto-Start Mail Daemon","Mail Daemonを自動起動"),NULL); 453 box->AddChild(fAutoStartCheckBox); 454 455 // about page 456 457 rect = tabView->Bounds(); rect.bottom -= tabView->TabHeight() + 4; 458 tabView->AddTab(view = new BView(rect,NULL,B_FOLLOW_ALL,0)); 459 tabView->TabAt(2)->SetLabel(MDR_DIALECT_CHOICE ("About","情報")); 460 view->SetViewColor(top->ViewColor()); 461 462 AboutTextView *about = new AboutTextView(rect); 463 about->SetViewColor(top->ViewColor()); 464 view->AddChild(about); 465 466 // save/cancel/revert buttons 467 468 top->AddChild(tabView); 469 470 rect = tabView->Frame(); 471 rect.top = rect.bottom + 5; rect.bottom = rect.top + height + 5; 472 BButton *saveButton = new BButton(rect,"save", 473 MDR_DIALECT_CHOICE ("Save","保存"), 474 new BMessage(kMsgSaveSettings)); 475 float w,h; 476 saveButton->GetPreferredSize(&w,&h); 477 saveButton->ResizeTo(w,h); 478 saveButton->MoveTo(rect.right - w, rect.top); 479 top->AddChild(saveButton); 480 481 BButton *cancelButton = new BButton(rect,"cancel", 482 MDR_DIALECT_CHOICE ("Cancel","中止"), 483 new BMessage(kMsgCancelSettings)); 484 cancelButton->GetPreferredSize(&w,&h); 485 cancelButton->ResizeTo(w,h); 486 #ifdef HAVE_APPLY_BUTTON 487 cancelButton->MoveTo(saveButton->Frame().left - w - 5,rect.top); 488 #else 489 cancelButton->MoveTo(saveButton->Frame().left - w - 20,rect.top); 490 #endif 491 top->AddChild(cancelButton); 492 493 #ifdef HAVE_APPLY_BUTTON 494 BButton *applyButton = new BButton(rect,"apply", 495 MDR_DIALECT_CHOICE ("Apply","適用"), 496 new BMessage(kMsgApplySettings)); 497 applyButton->GetPreferredSize(&w,&h); 498 applyButton->ResizeTo(w,h); 499 applyButton->MoveTo(cancelButton->Frame().left - w - 20,rect.top); 500 top->AddChild(applyButton); 501 #endif 502 503 BButton *revertButton = new BButton(rect,"revert", 504 MDR_DIALECT_CHOICE ("Revert","復元"), 505 new BMessage(kMsgRevertSettings)); 506 revertButton->GetPreferredSize(&w,&h); 507 revertButton->ResizeTo(w,h); 508 #ifdef HAVE_APPLY_BUTTON 509 revertButton->MoveTo(applyButton->Frame().left - w - 5,rect.top); 510 #else 511 revertButton->MoveTo(cancelButton->Frame().left - w - 6,rect.top); 512 #endif 513 top->AddChild(revertButton); 514 515 LoadSettings(); 516 517 fAccountsListView->SetSelectionMessage(new BMessage(kMsgAccountSelected)); 518 } 519 520 521 ConfigWindow::~ConfigWindow() 522 { 523 } 524 525 526 void 527 ConfigWindow::MakeHowToView() 528 { 529 BResources *resources = BApplication::AppResources(); 530 if (resources) 531 { 532 size_t length; 533 char *buffer = (char *)resources->FindResource('ICON',101,&length); 534 if (buffer) 535 { 536 BBitmap *bitmap = new BBitmap(BRect(0,0,63,63),B_CMAP8); 537 if (bitmap && bitmap->InitCheck() == B_OK) 538 { 539 // copy and enlarge a 32x32 8-bit bitmap 540 char *bits = (char *)bitmap->Bits(); 541 for (int32 i=0, j=-64; i<(int32)length; i++) 542 { 543 if ((i % 32) == 0) 544 j += 64; 545 546 char *b = bits + (i << 1) + j; 547 b[0] = b[1] = b[64] = b[65] = buffer[i]; 548 } 549 fConfigView->AddChild(new BitmapView(bitmap)); 550 } 551 else 552 delete bitmap; 553 } 554 } 555 556 BRect rect = fConfigView->Bounds(); 557 BTextView *text = new BTextView(rect,NULL,rect,B_FOLLOW_NONE,B_WILL_DRAW); 558 text->SetViewColor(fConfigView->Parent()->ViewColor()); 559 text->SetAlignment(B_ALIGN_CENTER); 560 text->SetText( 561 MDR_DIALECT_CHOICE ("\n\nCreate a new account using the \"Add\" button.\n\n" 562 "Delete accounts (or only the inbound/outbound) by using the \"Remove\" button on the selected item.\n\n" 563 "Select an item in the list to edit its configuration.", 564 "\n\nアカウントの新規作成は\"追加\"ボタンを\n使います。" 565 "\n\nアカウント自体またはアカウントの\n送受信設定を削除するには\n項目を選択して\"削除\"ボタンを使います。" 566 "\n\nアカウント内容の変更は、\nマウスで項目をクリックしてください。")); 567 rect = text->Bounds(); 568 text->ResizeTo(rect.Width(),text->TextHeight(0,42)); 569 text->SetTextRect(rect); 570 571 text->MakeEditable(false); 572 text->MakeSelectable(false); 573 574 fConfigView->AddChild(text); 575 576 static_cast<CenterContainer *>(fConfigView)->Layout(); 577 } 578 579 580 void 581 ConfigWindow::LoadSettings() 582 { 583 Accounts::Delete(); 584 Accounts::Create(fAccountsListView,fConfigView); 585 586 // load in general settings 587 BMailSettings *settings = new BMailSettings(); 588 status_t status = SetToGeneralSettings(settings); 589 if (status == B_OK) 590 { 591 // adjust own window frame 592 BScreen screen(this); 593 BRect screenFrame(screen.Frame().InsetByCopy(0,5)); 594 BRect frame(settings->ConfigWindowFrame()); 595 596 if (screenFrame.Contains(frame.LeftTop())) 597 MoveTo(frame.LeftTop()); 598 else // center on screen 599 MoveTo((screenFrame.Width() - frame.Width()) / 2,(screenFrame.Height() - frame.Height()) / 2); 600 } 601 else 602 fprintf(stderr, MDR_DIALECT_CHOICE ( 603 "Error retrieving general settings: %s\n", 604 "一般設定の収得に失敗: %s\n"), 605 strerror(status)); 606 607 delete settings; 608 } 609 610 611 void 612 ConfigWindow::SaveSettings() 613 { 614 // remove config views 615 ((CenterContainer *)fConfigView)->DeleteChildren(); 616 617 /*** save general settings ***/ 618 619 // figure out time interval 620 float interval; 621 sscanf(fIntervalControl->Text(),"%f",&interval); 622 float multiplier = 0; 623 switch (fIntervalUnitField->Menu()->IndexOf(fIntervalUnitField->Menu()->FindMarked())) { 624 case 1: // minutes 625 multiplier = 60; 626 break; 627 case 2: // hours 628 multiplier = 60 * 60; 629 break; 630 case 3: // days 631 multiplier = 24 * 60 * 60; 632 break; 633 } 634 time_t time = (time_t)(multiplier * interval); 635 636 // apply and save general settings 637 BMailSettings settings; 638 if (fSaveSettings) { 639 settings.SetAutoCheckInterval(time * 1e6); 640 settings.SetCheckOnlyIfPPPUp(fPPPActiveCheckBox->Value() == B_CONTROL_ON); 641 settings.SetSendOnlyIfPPPUp(fPPPActiveSendCheckBox->Value() == B_CONTROL_ON); 642 settings.SetDaemonAutoStarts(fAutoStartCheckBox->Value() == B_CONTROL_ON); 643 644 // status mode (alway, fetching/retrieving, ...) 645 int32 index = fStatusModeField->Menu()->IndexOf(fStatusModeField->Menu()->FindMarked()); 646 settings.SetShowStatusWindow(index); 647 648 // status look (border style, ...) 649 index = fStatusLookField->Menu()->IndexOf(fStatusLookField->Menu()->FindMarked()); 650 settings.SetStatusWindowLook(index); 651 652 // status workspaces 653 index = fStatusWorkspaceField->Menu()->IndexOf(fStatusWorkspaceField->Menu()->FindMarked()); 654 uint32 workspaces = 0; 655 if (index == 0) { 656 // current workspace 657 workspaces = Workspaces(); 658 // ToDo: correct would be to ask the status window which workspace it is on 659 } else 660 workspaces = B_ALL_WORKSPACES; 661 662 settings.SetStatusWindowWorkspaces(workspaces); 663 } else { 664 // restore status window look 665 settings.SetStatusWindowLook(settings.StatusWindowLook()); 666 } 667 668 settings.SetConfigWindowFrame(Frame()); 669 settings.Save(); 670 671 /*** save accounts ***/ 672 673 if (fSaveSettings) 674 Accounts::Save(); 675 676 // start the mail_daemon if auto start was selected 677 if (fSaveSettings && fAutoStartCheckBox->Value() == B_CONTROL_ON 678 && !be_roster->IsRunning("application/x-vnd.Be-POST")) 679 { 680 be_roster->Launch("application/x-vnd.Be-POST"); 681 } 682 } 683 684 685 bool 686 ConfigWindow::QuitRequested() 687 { 688 SaveSettings(); 689 690 Accounts::Delete(); 691 692 be_app->PostMessage(B_QUIT_REQUESTED); 693 return true; 694 } 695 696 697 void 698 ConfigWindow::MessageReceived(BMessage *msg) 699 { 700 switch (msg->what) { 701 case kMsgAccountSelected: 702 { 703 int32 index; 704 if (msg->FindInt32("index", &index) != B_OK || index < 0) { 705 // deselect current item 706 ((CenterContainer *)fConfigView)->DeleteChildren(); 707 MakeHowToView(); 708 break; 709 } 710 AccountItem *item = (AccountItem *)fAccountsListView->ItemAt(index); 711 if (item) 712 item->account->Selected(item->type); 713 break; 714 } 715 case kMsgAddAccount: 716 { 717 Accounts::NewAccount(); 718 break; 719 } 720 case kMsgRemoveAccount: 721 { 722 int32 index = fAccountsListView->CurrentSelection(); 723 if (index >= 0) { 724 AccountItem *item = (AccountItem *)fAccountsListView->ItemAt(index); 725 if (item) { 726 item->account->Remove(item->type); 727 MakeHowToView(); 728 } 729 } 730 break; 731 } 732 733 case kMsgIntervalUnitChanged: 734 { 735 int32 index; 736 if (msg->FindInt32("index",&index) == B_OK) 737 fIntervalControl->SetEnabled(index != 0); 738 break; 739 } 740 741 case kMsgShowStatusWindowChanged: 742 case kMsgStatusLookChanged: 743 case kMsgStatusWorkspaceChanged: 744 { 745 // the status window stuff is the only "live" setting 746 BMessenger messenger("application/x-vnd.Be-POST"); 747 if (messenger.IsValid()) 748 messenger.SendMessage(msg); 749 break; 750 } 751 752 case kMsgRevertSettings: 753 RevertToLastSettings(); 754 break; 755 case kMsgApplySettings: 756 fSaveSettings = true; 757 SaveSettings(); 758 MakeHowToView(); 759 break; 760 case kMsgSaveSettings: 761 fSaveSettings = true; 762 PostMessage(B_QUIT_REQUESTED); 763 break; 764 case kMsgCancelSettings: 765 fSaveSettings = false; 766 PostMessage(B_QUIT_REQUESTED); 767 break; 768 769 default: 770 BWindow::MessageReceived(msg); 771 break; 772 } 773 } 774 775 776 status_t 777 ConfigWindow::SetToGeneralSettings(BMailSettings *settings) 778 { 779 if (!settings) 780 return B_BAD_VALUE; 781 782 status_t status = settings->InitCheck(); 783 if (status != B_OK) 784 return status; 785 786 // retrieval frequency 787 788 time_t interval = time_t(settings->AutoCheckInterval() / 1e6L); 789 char text[25]; 790 text[0] = 0; 791 int timeIndex = 0; 792 if (interval >= 60) { 793 timeIndex = 1; 794 sprintf(text, "%ld", interval / (60)); 795 } 796 if (interval >= (60*60)) { 797 timeIndex = 2; 798 sprintf(text, "%ld", interval / (60*60)); 799 } 800 if (interval >= (60*60*24)) { 801 timeIndex = 3; 802 sprintf(text, "%ld", interval / (60*60*24)); 803 } 804 fIntervalControl->SetText(text); 805 806 if (BMenuItem *item = fIntervalUnitField->Menu()->ItemAt(timeIndex)) 807 item->SetMarked(true); 808 fIntervalControl->SetEnabled(timeIndex != 0); 809 810 fPPPActiveCheckBox->SetValue(settings->CheckOnlyIfPPPUp()); 811 fPPPActiveSendCheckBox->SetValue(settings->SendOnlyIfPPPUp()); 812 813 fAutoStartCheckBox->SetValue(settings->DaemonAutoStarts()); 814 815 if (BMenuItem *item = fStatusModeField->Menu()->ItemAt(settings->ShowStatusWindow())) 816 item->SetMarked(true); 817 if (BMenuItem *item = fStatusLookField->Menu()->ItemAt(settings->StatusWindowLook())) 818 item->SetMarked(true); 819 if (BMenuItem *item = fStatusWorkspaceField->Menu()->ItemAt((uint32)settings->StatusWindowWorkspaces() != B_ALL_WORKSPACES ? 0 : 1)) 820 item->SetMarked(true); 821 822 BMessenger messenger("application/x-vnd.Be-POST"); 823 if (messenger.IsValid()) 824 { 825 BMessage msg(kMsgStatusLookChanged); 826 msg.AddInt32("look", settings->StatusWindowLook()); 827 messenger.SendMessage(&msg); 828 } 829 830 return B_OK; 831 } 832 833 834 void 835 ConfigWindow::RevertToLastSettings() 836 { 837 // revert general settings 838 BMailSettings settings; 839 840 // restore status window look 841 settings.SetStatusWindowLook(settings.StatusWindowLook()); 842 843 status_t status = SetToGeneralSettings(&settings); 844 if (status != B_OK) 845 { 846 char text[256]; 847 sprintf(text, 848 MDR_DIALECT_CHOICE ("\nThe general settings couldn't be reverted.\n\n" 849 "Error retrieving general settings:\n%s\n", 850 "\n一般設定を戻せませんでした。\n\n一般設定収得エラー:\n%s\n"), 851 strerror(status)); 852 (new BAlert("Error",text,"Ok",NULL,NULL,B_WIDTH_AS_USUAL,B_WARNING_ALERT))->Go(); 853 } 854 855 // revert account data 856 857 if (fAccountsListView->CurrentSelection() != -1) 858 ((CenterContainer *)fConfigView)->DeleteChildren(); 859 860 Accounts::Delete(); 861 Accounts::Create(fAccountsListView,fConfigView); 862 863 if (fConfigView->CountChildren() == 0) 864 MakeHowToView(); 865 } 866 867