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 <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"); 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 the mail_daemon if auto start was selected 503 BMailDaemon daemon; 504 if (fSaveSettings && settings.DaemonAutoStarts() && !daemon.IsRunning()) 505 daemon.Launch(); 506 } 507 508 509 bool 510 ConfigWindow::QuitRequested() 511 { 512 _SaveSettings(); 513 514 be_app->PostMessage(B_QUIT_REQUESTED); 515 return true; 516 } 517 518 519 void 520 ConfigWindow::MessageReceived(BMessage *msg) 521 { 522 float fontFactor = be_plain_font->Size() / 12.0f; 523 BRect autoConfigRect(0, 0, 400 * fontFactor, 300 * fontFactor); 524 BRect frame; 525 526 AutoConfigWindow *autoConfigWindow = NULL; 527 switch (msg->what) { 528 case B_COLORS_UPDATED: 529 { 530 rgb_color textColor; 531 if (msg->FindColor(ui_color_name(B_PANEL_TEXT_COLOR), &textColor) 532 == B_OK) { 533 BFont font; 534 fHowToTextView->SetFontAndColor(&font, 0, &textColor); 535 } 536 break; 537 } 538 539 case kMsgAccountsRightClicked: 540 { 541 BPoint point; 542 msg->FindPoint("point", &point); 543 int32 index = msg->FindInt32("index"); 544 AccountItem* clickedItem = dynamic_cast<AccountItem*>( 545 fAccountsListView->ItemAt(index)); 546 if (clickedItem == NULL || clickedItem->Type() != ACCOUNT_ITEM) 547 break; 548 549 BPopUpMenu rightClickMenu("accounts", false, false); 550 551 BMenuItem* inMenuItem = new BMenuItem(B_TRANSLATE("Incoming"), 552 NULL); 553 BMenuItem* outMenuItem = new BMenuItem(B_TRANSLATE("Outgoing"), 554 NULL); 555 rightClickMenu.AddItem(inMenuItem); 556 rightClickMenu.AddItem(outMenuItem); 557 558 BMailAccountSettings* settings = clickedItem->Account(); 559 if (settings->IsInboundEnabled()) 560 inMenuItem->SetMarked(true); 561 if (settings->IsOutboundEnabled()) 562 outMenuItem->SetMarked(true); 563 564 BMenuItem* selectedItem = rightClickMenu.Go(point); 565 if (selectedItem == NULL) 566 break; 567 if (selectedItem == inMenuItem) { 568 AccountItem* item = dynamic_cast<AccountItem*>( 569 fAccountsListView->ItemAt(index + 1)); 570 if (item == NULL) 571 break; 572 if (settings->IsInboundEnabled()) { 573 settings->SetInboundEnabled(false); 574 item->SetEnabled(false); 575 } else { 576 settings->SetInboundEnabled(true); 577 item->SetEnabled(true); 578 } 579 } else { 580 AccountItem* item = dynamic_cast<AccountItem*>( 581 fAccountsListView->ItemAt(index + 2)); 582 if (item == NULL) 583 break; 584 if (settings->IsOutboundEnabled()) { 585 settings->SetOutboundEnabled(false); 586 item->SetEnabled(false); 587 } else { 588 settings->SetOutboundEnabled(true); 589 item->SetEnabled(true); 590 } 591 } 592 } 593 594 case kMsgAccountSelected: 595 { 596 int32 index; 597 if (msg->FindInt32("index", &index) != B_OK || index < 0) { 598 // deselect current item 599 _ReplaceConfigView(_BuildHowToView()); 600 break; 601 } 602 AccountItem* item = (AccountItem*)fAccountsListView->ItemAt(index); 603 if (item != NULL) 604 _AccountSelected(item); 605 break; 606 } 607 608 case kMsgAddAccount: 609 { 610 frame = Frame(); 611 autoConfigRect.OffsetTo( 612 frame.left + (frame.Width() - autoConfigRect.Width()) / 2, 613 frame.top + (frame.Width() - autoConfigRect.Height()) / 2); 614 autoConfigWindow = new AutoConfigWindow(autoConfigRect, this); 615 autoConfigWindow->Show(); 616 break; 617 } 618 619 case kMsgRemoveAccount: 620 { 621 int32 index = fAccountsListView->CurrentSelection(); 622 if (index >= 0) { 623 AccountItem *item = (AccountItem *)fAccountsListView->ItemAt( 624 index); 625 if (item != NULL) { 626 _RemoveAccount(item->Account()); 627 _ReplaceConfigView(_BuildHowToView()); 628 } 629 } 630 break; 631 } 632 633 case kMsgIntervalUnitChanged: 634 { 635 int32 index; 636 if (msg->FindInt32("index",&index) == B_OK) 637 fIntervalControl->SetEnabled(index != 0); 638 break; 639 } 640 641 case kMsgShowStatusWindowChanged: 642 { 643 // the status window stuff is the only "live" setting 644 BMessenger messenger("application/x-vnd.Be-POST"); 645 if (messenger.IsValid()) 646 messenger.SendMessage(msg); 647 break; 648 } 649 650 case kMsgRevertSettings: 651 _RevertToLastSettings(); 652 break; 653 654 case kMsgSaveSettings: 655 fSaveSettings = true; 656 _SaveSettings(); 657 AccountUpdated(fLastSelectedAccount); 658 _ReplaceConfigView(_BuildHowToView()); 659 fAccountsListView->DeselectAll(); 660 break; 661 662 default: 663 BWindow::MessageReceived(msg); 664 break; 665 } 666 } 667 668 669 BMailAccountSettings* 670 ConfigWindow::AddAccount() 671 { 672 BMailAccountSettings* account = new BMailAccountSettings; 673 if (!account) 674 return NULL; 675 fAccounts.AddItem(account); 676 _AddAccountToView(account); 677 return account; 678 } 679 680 681 void 682 ConfigWindow::AccountUpdated(BMailAccountSettings* account) 683 { 684 if (account == NULL) 685 return; 686 687 for (int i = 0; i < fAccountsListView->CountItems(); i++) { 688 AccountItem* item = (AccountItem*)fAccountsListView->ItemAt(i); 689 if (item->Account() == account) { 690 if (item->Type() == ACCOUNT_ITEM) { 691 item->SetText(account->Name()); 692 fAccountsListView->Invalidate(); 693 } 694 } 695 } 696 } 697 698 699 status_t 700 ConfigWindow::_SetToGeneralSettings(BMailSettings* settings) 701 { 702 if (settings == NULL) 703 return B_BAD_VALUE; 704 705 status_t status = settings->InitCheck(); 706 if (status != B_OK) 707 return status; 708 709 // retrieval frequency 710 uint32 interval = uint32(settings->AutoCheckInterval() / 60000000L); 711 fCheckMailCheckBox->SetValue(interval != 0 ? B_CONTROL_ON : B_CONTROL_OFF); 712 713 if (interval == 0) 714 interval = 5; 715 716 BString intervalText; 717 intervalText.SetToFormat("%" B_PRIu32, interval); 718 fIntervalControl->SetText(intervalText.String()); 719 720 int32 showStatusIndex = settings->ShowStatusWindow(); 721 BMenuItem* item = fStatusModeField->Menu()->ItemAt(showStatusIndex); 722 if (item != NULL) { 723 item->SetMarked(true); 724 // send live update to the server by simulating a menu click 725 BMessage msg(kMsgShowStatusWindowChanged); 726 msg.AddInt32("ShowStatusWindow", showStatusIndex); 727 PostMessage(&msg); 728 } 729 730 return B_OK; 731 } 732 733 734 void 735 ConfigWindow::_RevertToLastSettings() 736 { 737 // revert general settings 738 BMailSettings settings; 739 740 status_t status = _SetToGeneralSettings(&settings); 741 if (status != B_OK) { 742 char text[256]; 743 sprintf(text, B_TRANSLATE( 744 "\nThe general settings couldn't be reverted.\n\n" 745 "Error retrieving general settings:\n%s\n"), 746 strerror(status)); 747 BAlert* alert = new BAlert(B_TRANSLATE("Error"), text, 748 B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); 749 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 750 alert->Go(); 751 } 752 753 // revert account data 754 755 if (fAccountsListView->CurrentSelection() != -1) 756 _ReplaceConfigView(_BuildHowToView()); 757 758 for (int32 i = 0; i < fAccounts.CountItems(); i++) { 759 BMailAccountSettings* account = fAccounts.ItemAt(i); 760 _RemoveAccountFromListView(account); 761 delete account; 762 } 763 764 fAccounts.MakeEmpty(); 765 _LoadAccounts(); 766 } 767 768 769 void 770 ConfigWindow::_AddAccountToView(BMailAccountSettings* account) 771 { 772 BString label; 773 label << account->Name(); 774 775 AccountItem* item; 776 item = new AccountItem(label, account, ACCOUNT_ITEM); 777 fAccountsListView->AddItem(item); 778 779 item = new AccountItem(B_TRANSLATE("\t\t· Incoming"), account, INBOUND_ITEM); 780 fAccountsListView->AddItem(item); 781 if (!account->IsInboundEnabled()) 782 item->SetEnabled(false); 783 784 item = new AccountItem(B_TRANSLATE("\t\t· Outgoing"), account, 785 OUTBOUND_ITEM); 786 fAccountsListView->AddItem(item); 787 if (!account->IsOutboundEnabled()) 788 item->SetEnabled(false); 789 790 item = new AccountItem(B_TRANSLATE("\t\t· E-mail filters"), account, 791 FILTER_ITEM); 792 fAccountsListView->AddItem(item); 793 } 794 795 796 void 797 ConfigWindow::_RemoveAccount(BMailAccountSettings* account) 798 { 799 _RemoveAccountFromListView(account); 800 fAccounts.RemoveItem(account); 801 fToDeleteAccounts.AddItem(account); 802 } 803 804 805 void 806 ConfigWindow::_RemoveAccountFromListView(BMailAccountSettings* account) 807 { 808 if (fLastSelectedAccount == account) { 809 _ReplaceConfigView(_BuildHowToView()); 810 fLastSelectedAccount = NULL; 811 } 812 813 for (int i = fAccountsListView->CountItems(); i-- > 0;) { 814 AccountItem* item = (AccountItem*)fAccountsListView->ItemAt(i); 815 if (item->Account() == account) { 816 fAccountsListView->RemoveItem(i); 817 delete item; 818 } 819 } 820 } 821 822 823 void 824 ConfigWindow::_AccountSelected(AccountItem* item) 825 { 826 AccountUpdated(fLastSelectedAccount); 827 828 BMailAccountSettings* account = item->Account(); 829 fLastSelectedAccount = account; 830 831 BView* view = NULL; 832 switch (item->Type()) { 833 case ACCOUNT_ITEM: 834 view = new AccountConfigView(account); 835 break; 836 837 case INBOUND_ITEM: 838 view = new ProtocolSettingsView(account->InboundAddOnRef(), 839 *account, account->InboundSettings()); 840 break; 841 842 case OUTBOUND_ITEM: 843 view = new ProtocolSettingsView(account->OutboundAddOnRef(), 844 *account, account->OutboundSettings()); 845 break; 846 847 case FILTER_ITEM: 848 view = new FiltersConfigView(*account); 849 break; 850 } 851 852 _ReplaceConfigView(view); 853 } 854 855 856 void 857 ConfigWindow::_ReplaceConfigView(BView* view) 858 { 859 while (BView* child = fConfigView->ChildAt(0)) { 860 fConfigView->RemoveChild(child); 861 delete child; 862 } 863 864 if (view != NULL) 865 fConfigView->AddChild(view); 866 } 867