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