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