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
AccountItem(const char * label,BMailAccountSettings * account,item_types type)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
Update(BView * owner,const BFont * font)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
DrawItem(BView * owner,BRect rect,bool complete)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:
AccountsListView(BHandler * target)120 AccountsListView(BHandler* target)
121 :
122 BListView(NULL, B_SINGLE_SELECTION_LIST),
123 fTarget(target)
124 {
125 }
126
127 void
KeyDown(const char * bytes,int32 numBytes)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
MouseDown(BPoint point)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:
BitmapView(BBitmap * bitmap)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
~BitmapView()180 ~BitmapView()
181 {
182 delete fBitmap;
183 }
184
AttachedToWindow()185 virtual void AttachedToWindow()
186 {
187 AdoptParentColors();
188 }
189
Draw(BRect updateRect)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
ConfigWindow()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
~ConfigWindow()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*
_BuildHowToView()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
_LoadSettings()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
_LoadAccounts()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
_SaveSettings()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
QuitRequested()514 ConfigWindow::QuitRequested()
515 {
516 _SaveSettings();
517
518 be_app->PostMessage(B_QUIT_REQUESTED);
519 return true;
520 }
521
522
523 void
MessageReceived(BMessage * msg)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*
AddAccount()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
AccountUpdated(BMailAccountSettings * account)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
_SetToGeneralSettings(BMailSettings * settings)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
_RevertToLastSettings()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
_AddAccountToView(BMailAccountSettings * account)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
_RemoveAccount(BMailAccountSettings * account)801 ConfigWindow::_RemoveAccount(BMailAccountSettings* account)
802 {
803 _RemoveAccountFromListView(account);
804 fAccounts.RemoveItem(account);
805 fToDeleteAccounts.AddItem(account);
806 }
807
808
809 void
_RemoveAccountFromListView(BMailAccountSettings * account)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
_AccountSelected(AccountItem * item)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
_ReplaceConfigView(BView * view)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