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