1 /* 2 * Copyright 2007-2016 Haiku, Inc. All rights reserved. 3 * Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9 //! Main E-Mail config window 10 11 12 #include "ConfigWindow.h" 13 14 #include <new> 15 #include <stdio.h> 16 #include <string.h> 17 18 #include <Alert.h> 19 #include <AppFileInfo.h> 20 #include <Application.h> 21 #include <Bitmap.h> 22 #include <Box.h> 23 #include <Button.h> 24 #include <Catalog.h> 25 #include <CheckBox.h> 26 #include <ControlLook.h> 27 #include <Directory.h> 28 #include <Entry.h> 29 #include <FindDirectory.h> 30 #include <LayoutBuilder.h> 31 #include <ListView.h> 32 #include <Locale.h> 33 #include <MailDaemon.h> 34 #include <MailSettings.h> 35 #include <MenuBar.h> 36 #include <MenuField.h> 37 #include <MenuItem.h> 38 #include <Path.h> 39 #include <PopUpMenu.h> 40 #include <Region.h> 41 #include <Resources.h> 42 #include <Roster.h> 43 #include <Screen.h> 44 #include <ScrollView.h> 45 #include <SeparatorView.h> 46 #include <StringView.h> 47 #include <TabView.h> 48 #include <TextControl.h> 49 #include <TextView.h> 50 51 #include <MailPrivate.h> 52 53 #include "AutoConfigWindow.h" 54 55 56 #undef B_TRANSLATION_CONTEXT 57 #define B_TRANSLATION_CONTEXT "Config Window" 58 59 60 using std::nothrow; 61 62 // define if you want to have an apply button 63 //#define HAVE_APPLY_BUTTON 64 65 66 const uint32 kMsgAccountsRightClicked = 'arcl'; 67 const uint32 kMsgAccountSelected = 'acsl'; 68 const uint32 kMsgAddAccount = 'adac'; 69 const uint32 kMsgRemoveAccount = 'rmac'; 70 71 const uint32 kMsgIntervalUnitChanged = 'iuch'; 72 73 const uint32 kMsgShowStatusWindowChanged = 'shst'; 74 const uint32 kMsgStatusLookChanged = 'lkch'; 75 const uint32 kMsgStatusWorkspaceChanged = 'wsch'; 76 77 const uint32 kMsgSaveSettings = 'svst'; 78 const uint32 kMsgRevertSettings = 'rvst'; 79 const uint32 kMsgCancelSettings = 'cnst'; 80 81 82 83 AccountItem::AccountItem(const char* label, BMailAccountSettings* account, 84 item_types type) 85 : 86 BStringItem(label), 87 fAccount(account), 88 fType(type) 89 { 90 } 91 92 93 void 94 AccountItem::Update(BView* owner, const BFont* font) 95 { 96 if (fType == ACCOUNT_ITEM) 97 font = be_bold_font; 98 99 BStringItem::Update(owner, font); 100 } 101 102 103 void 104 AccountItem::DrawItem(BView* owner, BRect rect, bool complete) 105 { 106 owner->PushState(); 107 if (fType == ACCOUNT_ITEM) 108 owner->SetFont(be_bold_font); 109 110 BStringItem::DrawItem(owner, rect, complete); 111 owner->PopState(); 112 } 113 114 115 // #pragma mark - 116 117 118 class AccountsListView : public BListView { 119 public: 120 AccountsListView(BHandler* target) 121 : 122 BListView(NULL, B_SINGLE_SELECTION_LIST), 123 fTarget(target) 124 { 125 } 126 127 void 128 KeyDown(const char *bytes, int32 numBytes) 129 { 130 if (numBytes != 1) 131 return; 132 133 if ((*bytes == B_DELETE) || (*bytes == B_BACKSPACE)) 134 Window()->PostMessage(kMsgRemoveAccount); 135 136 BListView::KeyDown(bytes,numBytes); 137 } 138 139 void 140 MouseDown(BPoint point) 141 { 142 BListView::MouseDown(point); 143 144 BPoint dummy; 145 uint32 buttons; 146 GetMouse(&dummy, &buttons); 147 if (buttons != B_SECONDARY_MOUSE_BUTTON) 148 return; 149 150 int32 index = IndexOf(point); 151 if (index < 0) 152 return; 153 154 BMessage message(kMsgAccountsRightClicked); 155 ConvertToScreen(&point); 156 message.AddPoint("point", point); 157 message.AddInt32("index", index); 158 BMessenger messenger(fTarget); 159 messenger.SendMessage(&message); 160 } 161 162 private: 163 BHandler* fTarget; 164 }; 165 166 167 class BitmapView : public BView { 168 public: 169 BitmapView(BBitmap *bitmap) 170 : 171 BView(NULL, B_WILL_DRAW) 172 { 173 fBitmap = bitmap; 174 175 SetDrawingMode(B_OP_ALPHA); 176 SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); 177 SetExplicitSize(bitmap->Bounds().Size()); 178 } 179 180 ~BitmapView() 181 { 182 delete fBitmap; 183 } 184 185 virtual void AttachedToWindow() 186 { 187 AdoptParentColors(); 188 } 189 190 virtual void Draw(BRect updateRect) 191 { 192 DrawBitmap(fBitmap, updateRect, updateRect); 193 } 194 195 private: 196 BBitmap *fBitmap; 197 }; 198 199 200 // #pragma mark - 201 202 203 ConfigWindow::ConfigWindow() 204 : 205 BWindow(BRect(100, 100, 600, 540), B_TRANSLATE_SYSTEM_NAME("E-mail"), 206 B_TITLED_WINDOW, 207 B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS), 208 fLastSelectedAccount(NULL), 209 fSaveSettings(false) 210 { 211 BTabView* tabView = new BTabView("tab", B_WIDTH_FROM_WIDEST); 212 tabView->SetBorder(B_NO_BORDER); 213 214 // accounts listview 215 216 BView* view = new BView("accounts", 0); 217 tabView->AddTab(view); 218 tabView->TabAt(0)->SetLabel(B_TRANSLATE("Accounts")); 219 220 fAccountsListView = new AccountsListView(this); 221 fAccountsListView->SetExplicitPreferredSize(BSize( 222 fAccountsListView->StringWidth("W") * 22, B_SIZE_UNSET)); 223 224 BButton* addButton = new BButton(NULL, B_TRANSLATE("Add"), 225 new BMessage(kMsgAddAccount)); 226 fRemoveButton = new BButton(NULL, B_TRANSLATE("Remove"), 227 new BMessage(kMsgRemoveAccount)); 228 229 fConfigView = new BView(NULL, 0); 230 fConfigView->SetLayout(new BGroupLayout(B_VERTICAL)); 231 fConfigView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); 232 fConfigView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 233 234 BScrollView* scroller = new BScrollView(NULL, fAccountsListView, 0, 235 false, true); 236 237 BLayoutBuilder::Group<>(view, B_HORIZONTAL) 238 .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, 239 B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) 240 .AddGroup(B_VERTICAL) 241 .Add(scroller) 242 .AddGroup(B_HORIZONTAL) 243 .Add(addButton) 244 .Add(fRemoveButton) 245 .End() 246 .End() 247 .Add(fConfigView, 2.0f); 248 249 _ReplaceConfigView(_BuildHowToView()); 250 251 // general settings 252 253 view = new BView("general", 0); 254 view->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); 255 tabView->AddTab(view); 256 tabView->TabAt(1)->SetLabel(B_TRANSLATE("Settings")); 257 258 fCheckMailCheckBox = new BCheckBox("check", B_TRANSLATE("Check every"), 259 NULL); 260 fIntervalControl = new BTextControl("time", B_TRANSLATE("minutes"), NULL, 261 NULL); 262 263 BPopUpMenu* statusPopUp = new BPopUpMenu(B_EMPTY_STRING); 264 const char* statusModes[] = { 265 B_TRANSLATE_COMMENT("Never", "show status window"), 266 B_TRANSLATE("While sending"), 267 B_TRANSLATE("While sending and receiving")}; 268 for (size_t i = 0; i < sizeof(statusModes) / sizeof(statusModes[0]); i++) { 269 BMessage* msg = new BMessage(kMsgShowStatusWindowChanged); 270 BMenuItem* item = new BMenuItem(statusModes[i], msg); 271 statusPopUp->AddItem(item); 272 msg->AddInt32("ShowStatusWindow", i); 273 } 274 275 fStatusModeField = new BMenuField("show status", 276 B_TRANSLATE("Show notifications:"), statusPopUp); 277 278 BMessage* msg = new BMessage(B_REFS_RECEIVED); 279 BButton* editMenuButton = new BButton(B_EMPTY_STRING, 280 B_TRANSLATE("Edit mailbox menu…"), msg); 281 editMenuButton->SetTarget(BMessenger("application/x-vnd.Be-TRAK")); 282 283 BPath path; 284 find_directory(B_USER_SETTINGS_DIRECTORY, &path); 285 path.Append("Mail/Menu Links"); 286 BEntry entry(path.Path()); 287 if (entry.InitCheck() == B_OK && entry.Exists()) { 288 entry_ref ref; 289 entry.GetRef(&ref); 290 msg->AddRef("refs", &ref); 291 } else 292 editMenuButton->SetEnabled(false); 293 294 BLayoutBuilder::Group<>(view, B_VERTICAL) 295 .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING, 296 B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING) 297 // .AddGlue() 298 .AddGroup(B_HORIZONTAL, 0.f) 299 .AddGlue() 300 .Add(fCheckMailCheckBox) 301 .AddStrut(be_control_look->DefaultLabelSpacing()) 302 .Add(fIntervalControl->CreateTextViewLayoutItem()) 303 .AddStrut(be_control_look->DefaultLabelSpacing()) 304 .Add(fIntervalControl->CreateLabelLayoutItem()) 305 .AddGlue() 306 .End() 307 .AddGroup(B_HORIZONTAL, 0.f) 308 .AddGlue() 309 .Add(fStatusModeField->CreateLabelLayoutItem()) 310 .Add(fStatusModeField->CreateMenuBarLayoutItem()) 311 .AddGlue() 312 .End() 313 .Add(editMenuButton) 314 .AddGlue(); 315 316 // save/revert buttons 317 318 BButton* applyButton = new BButton("apply", B_TRANSLATE("Apply"), 319 new BMessage(kMsgSaveSettings)); 320 BButton* revertButton = new BButton("revert", B_TRANSLATE("Revert"), 321 new BMessage(kMsgRevertSettings)); 322 323 BLayoutBuilder::Group<>(this, B_VERTICAL, 0) 324 .SetInsets(0, B_USE_DEFAULT_SPACING, 0, B_USE_WINDOW_SPACING) 325 .Add(tabView) 326 .Add(new BSeparatorView(B_HORIZONTAL)) 327 .AddGroup(B_HORIZONTAL, 0) 328 .Add(revertButton) 329 .AddGlue() 330 .Add(applyButton) 331 .SetInsets(B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING, 332 B_USE_WINDOW_SPACING, 0); 333 334 _LoadSettings(); 335 336 fAccountsListView->SetSelectionMessage(new BMessage(kMsgAccountSelected)); 337 fAccountsListView->MakeFocus(true); 338 339 ResizeToPreferred(); 340 CenterOnScreen(); 341 } 342 343 344 ConfigWindow::~ConfigWindow() 345 { 346 while (fAccounts.CountItems() > 0) 347 _RemoveAccount(fAccounts.ItemAt(0)); 348 for (int32 i = 0; i < fToDeleteAccounts.CountItems(); i++) 349 delete fToDeleteAccounts.ItemAt(i); 350 } 351 352 353 BView* 354 ConfigWindow::_BuildHowToView() 355 { 356 BView* groupView = new BView("howTo", 0); 357 358 BitmapView* bitmapView = NULL; 359 app_info info; 360 if (be_app->GetAppInfo(&info) == B_OK) { 361 BFile appFile(&info.ref, B_READ_ONLY); 362 BAppFileInfo appFileInfo(&appFile); 363 if (appFileInfo.InitCheck() == B_OK) { 364 BBitmap* bitmap = new (std::nothrow) BBitmap(BRect(0, 0, 63, 63), 365 B_RGBA32); 366 if (appFileInfo.GetIcon(bitmap, B_LARGE_ICON) == B_OK) 367 bitmapView = new BitmapView(bitmap); 368 else 369 delete bitmap; 370 } 371 } 372 373 fHowToTextView = new BTextView(NULL, B_WILL_DRAW); 374 fHowToTextView->SetAlignment(B_ALIGN_CENTER); 375 fHowToTextView->SetText(B_TRANSLATE( 376 "Create a new account with the Add button.\n\n" 377 "Remove an account with the Remove button on the selected item.\n\n" 378 "Select an item in the list to change its settings.")); 379 380 fHowToTextView->MakeEditable(false); 381 fHowToTextView->MakeSelectable(false); 382 383 BFont font(be_plain_font); 384 float fontFactor = font.Size() / 12.0f; 385 386 fHowToTextView->SetExplicitPreferredSize( 387 BSize(300 * fontFactor,400 * fontFactor)); 388 389 rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR); 390 fHowToTextView->SetFontAndColor(&font, B_FONT_ALL, &textColor); 391 392 BLayoutBuilder::Group<>(groupView, B_VERTICAL) 393 .AddGlue() 394 .Add(fHowToTextView) 395 .AddGlue(); 396 397 if (bitmapView != NULL) 398 groupView->GetLayout()->AddView(1, bitmapView); 399 400 fHowToTextView->AdoptSystemColors(); 401 402 return groupView; 403 } 404 405 406 void 407 ConfigWindow::_LoadSettings() 408 { 409 // load accounts 410 for (int i = 0; i < fAccounts.CountItems(); i++) 411 delete fAccounts.ItemAt(i); 412 fAccounts.MakeEmpty(); 413 414 _LoadAccounts(); 415 416 // load in general settings 417 BMailSettings settings; 418 status_t status = _SetToGeneralSettings(&settings); 419 if (status != B_OK) { 420 fprintf(stderr, B_TRANSLATE("Error retrieving general settings: %s\n"), 421 strerror(status)); 422 } 423 } 424 425 426 void 427 ConfigWindow::_LoadAccounts() 428 { 429 BMailAccounts accounts; 430 for (int32 i = 0; i < accounts.CountAccounts(); i++) 431 fAccounts.AddItem(new BMailAccountSettings(*accounts.AccountAt(i))); 432 433 for (int i = 0; i < fAccounts.CountItems(); i++) { 434 BMailAccountSettings* account = fAccounts.ItemAt(i); 435 _AddAccountToView(account); 436 } 437 } 438 439 440 void 441 ConfigWindow::_SaveSettings() 442 { 443 // collect changed accounts 444 BMessage changedAccounts(BPrivate::kMsgAccountsChanged); 445 for (int32 i = 0; i < fAccounts.CountItems(); i++) { 446 BMailAccountSettings* account = fAccounts.ItemAt(i); 447 if (account && account->HasBeenModified()) 448 changedAccounts.AddInt32("account", account->AccountID()); 449 } 450 for (int32 i = 0; i < fToDeleteAccounts.CountItems(); i++) { 451 BMailAccountSettings* account = fToDeleteAccounts.ItemAt(i); 452 changedAccounts.AddInt32("account", account->AccountID()); 453 } 454 455 // cleanup account directory 456 for (int32 i = 0; i < fToDeleteAccounts.CountItems(); i++) { 457 BMailAccountSettings* account = fToDeleteAccounts.ItemAt(i); 458 BEntry entry(account->AccountFile()); 459 entry.Remove(); 460 delete account; 461 } 462 fToDeleteAccounts.MakeEmpty(); 463 464 // Apply and save general settings 465 466 BMailSettings settings; 467 if (fSaveSettings) { 468 bigtime_t interval = 0; 469 if (fCheckMailCheckBox->Value() == B_CONTROL_ON) { 470 // figure out time interval 471 float floatInterval; 472 sscanf(fIntervalControl->Text(), "%f", &floatInterval); 473 interval = bigtime_t(60000000L * floatInterval); 474 } 475 476 settings.SetAutoCheckInterval(interval); 477 settings.SetDaemonAutoStarts(!fAccounts.IsEmpty()); 478 479 // status mode (alway, fetching/retrieving, ...) 480 int32 index = fStatusModeField->Menu()->IndexOf( 481 fStatusModeField->Menu()->FindMarked()); 482 settings.SetShowStatusWindow(index); 483 484 settings.Save(); 485 } 486 487 // Save accounts 488 489 if (fSaveSettings) { 490 for (int i = 0; i < fAccounts.CountItems(); i++) 491 fAccounts.ItemAt(i)->Save(); 492 } 493 494 BMessenger messenger(B_MAIL_DAEMON_SIGNATURE); 495 if (messenger.IsValid()) { 496 // server should reload general settings 497 messenger.SendMessage(BPrivate::kMsgSettingsUpdated); 498 // notify server about changed accounts 499 messenger.SendMessage(&changedAccounts); 500 } 501 502 // Start/stop the mail_daemon depending on the settings 503 BMailDaemon daemon; 504 if (fSaveSettings) { 505 if (settings.DaemonAutoStarts() && !daemon.IsRunning()) 506 daemon.Launch(); 507 else if (!settings.DaemonAutoStarts() && daemon.IsRunning()) 508 daemon.Quit(); 509 } 510 } 511 512 513 bool 514 ConfigWindow::QuitRequested() 515 { 516 _SaveSettings(); 517 518 be_app->PostMessage(B_QUIT_REQUESTED); 519 return true; 520 } 521 522 523 void 524 ConfigWindow::MessageReceived(BMessage *msg) 525 { 526 float fontFactor = be_plain_font->Size() / 12.0f; 527 BRect autoConfigRect(0, 0, 400 * fontFactor, 300 * fontFactor); 528 BRect frame; 529 530 AutoConfigWindow *autoConfigWindow = NULL; 531 switch (msg->what) { 532 case B_COLORS_UPDATED: 533 { 534 rgb_color textColor; 535 if (msg->FindColor(ui_color_name(B_PANEL_TEXT_COLOR), &textColor) 536 == B_OK) { 537 BFont font; 538 fHowToTextView->SetFontAndColor(&font, 0, &textColor); 539 } 540 break; 541 } 542 543 case kMsgAccountsRightClicked: 544 { 545 BPoint point; 546 msg->FindPoint("point", &point); 547 int32 index = msg->FindInt32("index"); 548 AccountItem* clickedItem = dynamic_cast<AccountItem*>( 549 fAccountsListView->ItemAt(index)); 550 if (clickedItem == NULL || clickedItem->Type() != ACCOUNT_ITEM) 551 break; 552 553 BPopUpMenu rightClickMenu("accounts", false, false); 554 555 BMenuItem* inMenuItem = new BMenuItem(B_TRANSLATE("Incoming"), 556 NULL); 557 BMenuItem* outMenuItem = new BMenuItem(B_TRANSLATE("Outgoing"), 558 NULL); 559 rightClickMenu.AddItem(inMenuItem); 560 rightClickMenu.AddItem(outMenuItem); 561 562 BMailAccountSettings* settings = clickedItem->Account(); 563 if (settings->IsInboundEnabled()) 564 inMenuItem->SetMarked(true); 565 if (settings->IsOutboundEnabled()) 566 outMenuItem->SetMarked(true); 567 568 BMenuItem* selectedItem = rightClickMenu.Go(point); 569 if (selectedItem == NULL) 570 break; 571 if (selectedItem == inMenuItem) { 572 AccountItem* item = dynamic_cast<AccountItem*>( 573 fAccountsListView->ItemAt(index + 1)); 574 if (item == NULL) 575 break; 576 if (settings->IsInboundEnabled()) { 577 settings->SetInboundEnabled(false); 578 item->SetEnabled(false); 579 } else { 580 settings->SetInboundEnabled(true); 581 item->SetEnabled(true); 582 } 583 } else { 584 AccountItem* item = dynamic_cast<AccountItem*>( 585 fAccountsListView->ItemAt(index + 2)); 586 if (item == NULL) 587 break; 588 if (settings->IsOutboundEnabled()) { 589 settings->SetOutboundEnabled(false); 590 item->SetEnabled(false); 591 } else { 592 settings->SetOutboundEnabled(true); 593 item->SetEnabled(true); 594 } 595 } 596 } 597 598 case kMsgAccountSelected: 599 { 600 int32 index; 601 if (msg->FindInt32("index", &index) != B_OK || index < 0) { 602 // deselect current item 603 _ReplaceConfigView(_BuildHowToView()); 604 break; 605 } 606 AccountItem* item = (AccountItem*)fAccountsListView->ItemAt(index); 607 if (item != NULL) 608 _AccountSelected(item); 609 break; 610 } 611 612 case kMsgAddAccount: 613 { 614 frame = Frame(); 615 autoConfigRect.OffsetTo( 616 frame.left + (frame.Width() - autoConfigRect.Width()) / 2, 617 frame.top + (frame.Width() - autoConfigRect.Height()) / 2); 618 autoConfigWindow = new AutoConfigWindow(autoConfigRect, this); 619 autoConfigWindow->Show(); 620 break; 621 } 622 623 case kMsgRemoveAccount: 624 { 625 int32 index = fAccountsListView->CurrentSelection(); 626 if (index >= 0) { 627 AccountItem *item = (AccountItem *)fAccountsListView->ItemAt( 628 index); 629 if (item != NULL) { 630 _RemoveAccount(item->Account()); 631 _ReplaceConfigView(_BuildHowToView()); 632 } 633 } 634 break; 635 } 636 637 case kMsgIntervalUnitChanged: 638 { 639 int32 index; 640 if (msg->FindInt32("index",&index) == B_OK) 641 fIntervalControl->SetEnabled(index != 0); 642 break; 643 } 644 645 case kMsgShowStatusWindowChanged: 646 { 647 // the status window stuff is the only "live" setting 648 BMessenger messenger("application/x-vnd.Be-POST"); 649 if (messenger.IsValid()) 650 messenger.SendMessage(msg); 651 break; 652 } 653 654 case kMsgRevertSettings: 655 _RevertToLastSettings(); 656 break; 657 658 case kMsgSaveSettings: 659 fSaveSettings = true; 660 _SaveSettings(); 661 AccountUpdated(fLastSelectedAccount); 662 _ReplaceConfigView(_BuildHowToView()); 663 fAccountsListView->DeselectAll(); 664 break; 665 666 default: 667 BWindow::MessageReceived(msg); 668 break; 669 } 670 } 671 672 673 BMailAccountSettings* 674 ConfigWindow::AddAccount() 675 { 676 BMailAccountSettings* account = new BMailAccountSettings; 677 if (!account) 678 return NULL; 679 fAccounts.AddItem(account); 680 _AddAccountToView(account); 681 return account; 682 } 683 684 685 void 686 ConfigWindow::AccountUpdated(BMailAccountSettings* account) 687 { 688 if (account == NULL) 689 return; 690 691 for (int i = 0; i < fAccountsListView->CountItems(); i++) { 692 AccountItem* item = (AccountItem*)fAccountsListView->ItemAt(i); 693 if (item->Account() == account) { 694 if (item->Type() == ACCOUNT_ITEM) { 695 item->SetText(account->Name()); 696 fAccountsListView->Invalidate(); 697 } 698 } 699 } 700 } 701 702 703 status_t 704 ConfigWindow::_SetToGeneralSettings(BMailSettings* settings) 705 { 706 if (settings == NULL) 707 return B_BAD_VALUE; 708 709 status_t status = settings->InitCheck(); 710 if (status != B_OK) 711 return status; 712 713 // retrieval frequency 714 uint32 interval = uint32(settings->AutoCheckInterval() / 60000000L); 715 fCheckMailCheckBox->SetValue(interval != 0 ? B_CONTROL_ON : B_CONTROL_OFF); 716 717 if (interval == 0) 718 interval = 5; 719 720 BString intervalText; 721 intervalText.SetToFormat("%" B_PRIu32, interval); 722 fIntervalControl->SetText(intervalText.String()); 723 724 int32 showStatusIndex = settings->ShowStatusWindow(); 725 BMenuItem* item = fStatusModeField->Menu()->ItemAt(showStatusIndex); 726 if (item != NULL) { 727 item->SetMarked(true); 728 // send live update to the server by simulating a menu click 729 BMessage msg(kMsgShowStatusWindowChanged); 730 msg.AddInt32("ShowStatusWindow", showStatusIndex); 731 PostMessage(&msg); 732 } 733 734 return B_OK; 735 } 736 737 738 void 739 ConfigWindow::_RevertToLastSettings() 740 { 741 // revert general settings 742 BMailSettings settings; 743 744 status_t status = _SetToGeneralSettings(&settings); 745 if (status != B_OK) { 746 char text[256]; 747 sprintf(text, B_TRANSLATE( 748 "\nThe general settings couldn't be reverted.\n\n" 749 "Error retrieving general settings:\n%s\n"), 750 strerror(status)); 751 BAlert* alert = new BAlert(B_TRANSLATE("Error"), text, 752 B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); 753 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 754 alert->Go(); 755 } 756 757 // revert account data 758 759 if (fAccountsListView->CurrentSelection() != -1) 760 _ReplaceConfigView(_BuildHowToView()); 761 762 for (int32 i = 0; i < fAccounts.CountItems(); i++) { 763 BMailAccountSettings* account = fAccounts.ItemAt(i); 764 _RemoveAccountFromListView(account); 765 delete account; 766 } 767 768 fAccounts.MakeEmpty(); 769 _LoadAccounts(); 770 } 771 772 773 void 774 ConfigWindow::_AddAccountToView(BMailAccountSettings* account) 775 { 776 BString label; 777 label << account->Name(); 778 779 AccountItem* item; 780 item = new AccountItem(label, account, ACCOUNT_ITEM); 781 fAccountsListView->AddItem(item); 782 783 item = new AccountItem(B_TRANSLATE("\t\t· Incoming"), account, INBOUND_ITEM); 784 fAccountsListView->AddItem(item); 785 if (!account->IsInboundEnabled()) 786 item->SetEnabled(false); 787 788 item = new AccountItem(B_TRANSLATE("\t\t· Outgoing"), account, 789 OUTBOUND_ITEM); 790 fAccountsListView->AddItem(item); 791 if (!account->IsOutboundEnabled()) 792 item->SetEnabled(false); 793 794 item = new AccountItem(B_TRANSLATE("\t\t· E-mail filters"), account, 795 FILTER_ITEM); 796 fAccountsListView->AddItem(item); 797 } 798 799 800 void 801 ConfigWindow::_RemoveAccount(BMailAccountSettings* account) 802 { 803 _RemoveAccountFromListView(account); 804 fAccounts.RemoveItem(account); 805 fToDeleteAccounts.AddItem(account); 806 } 807 808 809 void 810 ConfigWindow::_RemoveAccountFromListView(BMailAccountSettings* account) 811 { 812 if (fLastSelectedAccount == account) { 813 _ReplaceConfigView(_BuildHowToView()); 814 fLastSelectedAccount = NULL; 815 } 816 817 for (int i = fAccountsListView->CountItems(); i-- > 0;) { 818 AccountItem* item = (AccountItem*)fAccountsListView->ItemAt(i); 819 if (item->Account() == account) { 820 fAccountsListView->RemoveItem(i); 821 delete item; 822 } 823 } 824 } 825 826 827 void 828 ConfigWindow::_AccountSelected(AccountItem* item) 829 { 830 AccountUpdated(fLastSelectedAccount); 831 832 BMailAccountSettings* account = item->Account(); 833 fLastSelectedAccount = account; 834 835 BView* view = NULL; 836 switch (item->Type()) { 837 case ACCOUNT_ITEM: 838 view = new AccountConfigView(account); 839 break; 840 841 case INBOUND_ITEM: 842 view = new ProtocolSettingsView(account->InboundAddOnRef(), 843 *account, account->InboundSettings()); 844 break; 845 846 case OUTBOUND_ITEM: 847 view = new ProtocolSettingsView(account->OutboundAddOnRef(), 848 *account, account->OutboundSettings()); 849 break; 850 851 case FILTER_ITEM: 852 view = new FiltersConfigView(*account); 853 break; 854 } 855 856 _ReplaceConfigView(view); 857 } 858 859 860 void 861 ConfigWindow::_ReplaceConfigView(BView* view) 862 { 863 while (BView* child = fConfigView->ChildAt(0)) { 864 fConfigView->RemoveChild(child); 865 delete child; 866 } 867 868 if (view != NULL) 869 fConfigView->AddChild(view); 870 } 871