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