1/*
2Open Tracker License
3
4Terms and Conditions
5
6Copyright (c) 1991-2001, Be Incorporated. All rights reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining a copy of
9this software and associated documentation files (the "Software"), to deal in
10the Software without restriction, including without limitation the rights to
11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12of the Software, and to permit persons to whom the Software is furnished to do
13so, subject to the following conditions:
14
15The above copyright notice and this permission notice applies to all licensees
16and shall be included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN
23CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25Except as contained in this notice, the name of Be Incorporated shall not be
26used in advertising or otherwise to promote the sale, use or other dealings in
27this Software without prior written authorization from Be Incorporated.
28
29BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or
30registered trademarks of Be Incorporated in the United States and other
31countries. Other brand product names are registered trademarks or trademarks
32of their respective holders. All rights reserved.
33*/
34
35
36#include "Prefs.h"
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41
42#include <Application.h>
43#include <CharacterSet.h>
44#include <CharacterSetRoster.h>
45#include <E-mail.h>
46#include <GridView.h>
47#include <GroupLayoutBuilder.h>
48#include <InterfaceKit.h>
49#include <Locale.h>
50#include <MailSettings.h>
51#include <mail_encoding.h>
52#include <StorageKit.h>
53#include <String.h>
54
55using namespace BPrivate;
56
57#include "MailApp.h"
58#include "MailSupport.h"
59#include "MailWindow.h"
60#include "Messages.h"
61#include "Signature.h"
62
63
64#define B_TRANSLATION_CONTEXT "Mail"
65
66#define BUTTON_WIDTH		70
67#define BUTTON_HEIGHT		20
68#define ITEM_SPACE			6
69
70#define OK_BUTTON_X1		(PREF_WIDTH - BUTTON_WIDTH - 6)
71#define OK_BUTTON_X2		(OK_BUTTON_X1 + BUTTON_WIDTH)
72
73#define REVERT_BUTTON_X1	8
74#define REVERT_BUTTON_X2	(REVERT_BUTTON_X1 + BUTTON_WIDTH)
75
76enum	P_MESSAGES			{P_OK = 128, P_CANCEL, P_REVERT, P_FONT,
77							 P_SIZE, P_LEVEL, P_WRAP, P_ATTACH_ATTRIBUTES,
78							 P_SIG, P_ENC, P_WARN_UNENCODABLE,
79							 P_SPELL_CHECK_START_ON, P_BUTTON_BAR,
80							 P_ACCOUNT, P_REPLYTO, P_REPLY_PREAMBLE,
81							 P_COLORED_QUOTES, P_MARK_READ};
82
83extern BPoint	prefs_window;
84
85//#pragma mark -
86
87
88static inline void
89add_menu_to_layout(BMenuField* menu, BGridLayout* layout, int32& row)
90{
91	menu->SetAlignment(B_ALIGN_RIGHT);
92	layout->AddItem(menu->CreateLabelLayoutItem(), 0, row);
93	layout->AddItem(menu->CreateMenuBarLayoutItem(), 1, row, 2);
94	row++;
95}
96
97
98TPrefsWindow::TPrefsWindow(BRect rect, BFont* font, int32* level, bool* wrap,
99	bool* attachAttributes, bool* cquotes, int32* account, int32* replyTo,
100	char** preamble, char** sig, uint32* encoding, bool* warnUnencodable,
101	bool* spellCheckStartOn, bool* autoMarkRead, uint8* buttonBar)
102	:
103	BWindow(rect, B_TRANSLATE("Mail preferences"),
104		B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE
105			| B_AUTO_UPDATE_SIZE_LIMITS),
106
107	fNewWrap(wrap),
108	fWrap(*fNewWrap),
109
110	fNewAttachAttributes(attachAttributes),
111	fAttachAttributes(*fNewAttachAttributes),
112
113	fNewButtonBar(buttonBar),
114	fButtonBar(*fNewButtonBar),
115
116	fNewColoredQuotes(cquotes),
117	fColoredQuotes(*fNewColoredQuotes),
118
119	fNewAccount(account),
120	fAccount(*fNewAccount),
121
122	fNewReplyTo(replyTo),
123	fReplyTo(*fNewReplyTo),
124
125	fNewPreamble(preamble),
126
127	fNewSignature(sig),
128	fSignature((char*)malloc(strlen(*fNewSignature) + 1)),
129
130	fNewFont(font),
131	fFont(*fNewFont),
132
133	fNewEncoding(encoding),
134	fEncoding(*fNewEncoding),
135
136	fNewWarnUnencodable(warnUnencodable),
137	fWarnUnencodable(*fNewWarnUnencodable),
138
139	fNewSpellCheckStartOn(spellCheckStartOn),
140	fSpellCheckStartOn(*fNewSpellCheckStartOn),
141
142	fNewAutoMarkRead(autoMarkRead),
143	fAutoMarkRead(*autoMarkRead)
144{
145	strcpy(fSignature, *fNewSignature);
146
147	BMenuField* menu;
148
149	// group boxes
150
151	const float kSpacing = 8;
152
153	BGridView* interfaceView = new BGridView(kSpacing, kSpacing);
154	BGridLayout* interfaceLayout = interfaceView->GridLayout();
155	interfaceLayout->SetInsets(kSpacing, kSpacing, kSpacing, kSpacing);
156	BGridView* mailView = new BGridView(kSpacing, kSpacing);
157	BGridLayout* mailLayout = mailView->GridLayout();
158	mailLayout->SetInsets(kSpacing, kSpacing, kSpacing, kSpacing);
159
160	interfaceLayout->AlignLayoutWith(mailLayout, B_HORIZONTAL);
161
162	BBox* interfaceBox = new BBox(B_FANCY_BORDER, interfaceView);
163	interfaceBox->SetLabel(B_TRANSLATE("User interface"));
164	BBox* mailBox = new BBox(B_FANCY_BORDER, mailView);
165	mailBox->SetLabel(B_TRANSLATE("Mailing"));
166
167	// revert, ok & cancel
168
169	BButton* okButton = new BButton("ok", B_TRANSLATE("OK"),
170		new BMessage(P_OK));
171	okButton->MakeDefault(true);
172
173	BButton* cancelButton = new BButton("cancel", B_TRANSLATE("Cancel"),
174		new BMessage(P_CANCEL));
175
176	fRevert = new BButton("revert", B_TRANSLATE("Revert"),
177		new BMessage(P_REVERT));
178	fRevert->SetEnabled(false);
179
180	// User Interface
181	int32 layoutRow = 0;
182
183	fButtonBarMenu = _BuildButtonBarMenu(*buttonBar);
184	menu = new BMenuField("bar", B_TRANSLATE("Button bar:"), fButtonBarMenu);
185	add_menu_to_layout(menu, interfaceLayout, layoutRow);
186
187	fFontMenu = _BuildFontMenu(font);
188	menu = new BMenuField("font", B_TRANSLATE("Font:"), fFontMenu);
189	add_menu_to_layout(menu, interfaceLayout, layoutRow);
190
191	fSizeMenu = _BuildSizeMenu(font);
192	menu = new BMenuField("size", B_TRANSLATE("Size:"), fSizeMenu);
193	add_menu_to_layout(menu, interfaceLayout, layoutRow);
194
195	fColoredQuotesMenu = _BuildColoredQuotesMenu(fColoredQuotes);
196	menu = new BMenuField("cquotes", B_TRANSLATE("Colored quotes:"),
197		fColoredQuotesMenu);
198	add_menu_to_layout(menu, interfaceLayout, layoutRow);
199
200	fSpellCheckStartOnMenu = _BuildSpellCheckStartOnMenu(fSpellCheckStartOn);
201	menu = new BMenuField("spellCheckStartOn",
202		B_TRANSLATE("Initial spell check mode:"),
203		fSpellCheckStartOnMenu);
204	add_menu_to_layout(menu, interfaceLayout, layoutRow);
205
206	fAutoMarkReadMenu = _BuildAutoMarkReadMenu(fAutoMarkRead);
207	menu = new BMenuField("autoMarkRead",
208		B_TRANSLATE("Automatically mark mail as read:"),
209		fAutoMarkReadMenu);
210	add_menu_to_layout(menu, interfaceLayout, layoutRow);
211	// Mail Accounts
212
213	layoutRow = 0;
214
215	fAccountMenu = _BuildAccountMenu(fAccount);
216	menu = new BMenuField("account", B_TRANSLATE("Default account:"),
217		fAccountMenu);
218	add_menu_to_layout(menu, mailLayout, layoutRow);
219
220	fReplyToMenu = _BuildReplyToMenu(fReplyTo);
221	menu = new BMenuField("replyTo", B_TRANSLATE("Reply account:"),
222		fReplyToMenu);
223	add_menu_to_layout(menu, mailLayout, layoutRow);
224
225	// Mail Contents
226
227	fReplyPreamble = new BTextControl("replytext",
228		B_TRANSLATE("Reply preamble:"),
229		*preamble, new BMessage(P_REPLY_PREAMBLE));
230	fReplyPreamble->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
231
232	fReplyPreambleMenu = _BuildReplyPreambleMenu();
233	menu = new BMenuField("replyPreamble", NULL, fReplyPreambleMenu);
234	menu->SetExplicitMaxSize(BSize(27, B_SIZE_UNSET));
235
236	mailLayout->AddItem(fReplyPreamble->CreateLabelLayoutItem(), 0, layoutRow);
237	mailLayout->AddItem(fReplyPreamble->CreateTextViewLayoutItem(), 1,
238		layoutRow);
239	mailLayout->AddView(menu, 2, layoutRow);
240	layoutRow++;
241
242	fSignatureMenu = _BuildSignatureMenu(*sig);
243	menu = new BMenuField("sig", B_TRANSLATE("Auto signature:"),
244		fSignatureMenu);
245	add_menu_to_layout(menu, mailLayout, layoutRow);
246
247	fEncodingMenu = _BuildEncodingMenu(fEncoding);
248	menu = new BMenuField("enc", B_TRANSLATE("Encoding:"), fEncodingMenu);
249	add_menu_to_layout(menu, mailLayout, layoutRow);
250
251	fWarnUnencodableMenu = _BuildWarnUnencodableMenu(fWarnUnencodable);
252	menu = new BMenuField("warnUnencodable", B_TRANSLATE("Warn unencodable:"),
253		fWarnUnencodableMenu);
254	add_menu_to_layout(menu, mailLayout, layoutRow);
255
256	fWrapMenu = _BuildWrapMenu(*wrap);
257	menu = new BMenuField("wrap", B_TRANSLATE("Text wrapping:"), fWrapMenu);
258	add_menu_to_layout(menu, mailLayout, layoutRow);
259
260	fAttachAttributesMenu = _BuildAttachAttributesMenu(*attachAttributes);
261	menu = new BMenuField("attachAttributes", B_TRANSLATE("Attach attributes:"),
262		fAttachAttributesMenu);
263	add_menu_to_layout(menu, mailLayout, layoutRow);
264
265	SetLayout(new BGroupLayout(B_HORIZONTAL));
266
267	AddChild(BGroupLayoutBuilder(B_VERTICAL, kSpacing)
268		.Add(interfaceBox)
269		.Add(mailBox)
270		.Add(BGroupLayoutBuilder(B_HORIZONTAL, kSpacing)
271			.Add(fRevert)
272			.AddGlue()
273			.Add(cancelButton)
274			.Add(okButton)
275		)
276		.SetInsets(kSpacing, kSpacing, kSpacing, kSpacing)
277	);
278
279	Show();
280}
281
282
283TPrefsWindow::~TPrefsWindow()
284{
285	BMessage msg(WINDOW_CLOSED);
286	msg.AddInt32("kind", PREFS_WINDOW);
287	msg.AddPoint("window pos", Frame().LeftTop());
288	be_app->PostMessage(&msg);
289}
290
291
292void
293TPrefsWindow::MessageReceived(BMessage* msg)
294{
295	bool revert = true;
296	const char* family;
297	const char* signature;
298	const char* style;
299	char label[256];
300	int32 new_size;
301	int32 old_size;
302	font_family new_family;
303	font_family old_family;
304	font_style new_style;
305	font_style old_style;
306	BMenuItem* item;
307	BMessage message;
308
309	switch (msg->what) {
310		case P_OK:
311			if (strcmp(fReplyPreamble->Text(), *fNewPreamble)) {
312				free(*fNewPreamble);
313				*fNewPreamble
314					= (char *)malloc(strlen(fReplyPreamble->Text()) + 1);
315				strcpy(*fNewPreamble, fReplyPreamble->Text());
316			}
317			be_app->PostMessage(PREFS_CHANGED);
318			Quit();
319			break;
320
321		case P_CANCEL:
322			revert = false;
323			// supposed to fall through
324		case P_REVERT:
325			fFont.GetFamilyAndStyle(&old_family, &old_style);
326			fNewFont->GetFamilyAndStyle(&new_family, &new_style);
327			old_size = (int32)fFont.Size();
328			new_size = (int32)fNewFont->Size();
329			if (strcmp(old_family, new_family) || strcmp(old_style, new_style)
330				|| old_size != new_size) {
331				fNewFont->SetFamilyAndStyle(old_family, old_style);
332				if (revert) {
333					sprintf(label, "%s %s", old_family, old_style);
334					item = fFontMenu->FindItem(label);
335					if (item != NULL)
336						item->SetMarked(true);
337				}
338
339				fNewFont->SetSize(old_size);
340				if (revert) {
341					sprintf(label, "%ld", old_size);
342					item = fSizeMenu->FindItem(label);
343					if (item != NULL)
344						item->SetMarked(true);
345				}
346				message.what = M_FONT;
347				be_app->PostMessage(&message);
348			}
349			*fNewWrap = fWrap;
350			*fNewAttachAttributes = fAttachAttributes;
351
352			if (strcmp(fSignature, *fNewSignature)) {
353				free(*fNewSignature);
354				*fNewSignature = (char*)malloc(strlen(fSignature) + 1);
355				strcpy(*fNewSignature, fSignature);
356			}
357
358			*fNewEncoding = fEncoding;
359			*fNewWarnUnencodable = fWarnUnencodable;
360			*fNewSpellCheckStartOn = fSpellCheckStartOn;
361			*fNewAutoMarkRead = fAutoMarkRead;
362			*fNewButtonBar = fButtonBar;
363
364			be_app->PostMessage(PREFS_CHANGED);
365
366			if (revert) {
367				for (int i = fAccountMenu->CountItems(); --i > 0;) {
368					BMenuItem *item = fAccountMenu->ItemAt(i);
369					BMessage* itemMessage = item->Message();
370					if (itemMessage != NULL
371						&& itemMessage->FindInt32("id") == *(int32 *)&fAccount) {
372						item->SetMarked(true);
373						break;
374					}
375				}
376
377				strcpy(label,fReplyTo == ACCOUNT_USE_DEFAULT
378					? B_TRANSLATE("Use default account")
379					: B_TRANSLATE("Account from mail"));
380				if ((item = fReplyToMenu->FindItem(label)) != NULL)
381					item->SetMarked(true);
382
383				strcpy(label, fWrap ? B_TRANSLATE("On") : B_TRANSLATE("Off"));
384				if ((item = fWrapMenu->FindItem(label)) != NULL)
385					item->SetMarked(true);
386
387				strcpy(label, fAttachAttributes
388					? B_TRANSLATE("Include file attributes in attachments")
389					: B_TRANSLATE("No file attributes, just plain data"));
390				if ((item = fAttachAttributesMenu->FindItem(label)) != NULL)
391					item->SetMarked(true);
392
393				strcpy(label, fColoredQuotes ? B_TRANSLATE("On") : B_TRANSLATE("Off"));
394				if ((item = fColoredQuotesMenu->FindItem(label)) != NULL)
395					item->SetMarked(true);
396
397				if (strcmp(fReplyPreamble->Text(), *fNewPreamble))
398					fReplyPreamble->SetText(*fNewPreamble);
399
400				item = fSignatureMenu->FindItem(fSignature);
401				if (item)
402					item->SetMarked(true);
403
404				uint32 index = 0;
405				while ((item = fEncodingMenu->ItemAt(index++)) != NULL) {
406					BMessage* itemMessage = item->Message();
407					if (itemMessage == NULL)
408						continue;
409
410					int32 encoding;
411					if (itemMessage->FindInt32("encoding", &encoding) == B_OK
412						&& (uint32)encoding == *fNewEncoding) {
413						item->SetMarked(true);
414						break;
415					}
416				}
417
418				strcpy(label, fWarnUnencodable ? B_TRANSLATE("On") : B_TRANSLATE("Off"));
419				if ((item = fWarnUnencodableMenu->FindItem(label)) != NULL)
420					item->SetMarked(true);
421
422				strcpy(label, fSpellCheckStartOn ? B_TRANSLATE("On") : B_TRANSLATE("Off"));
423				if ((item = fSpellCheckStartOnMenu->FindItem(label)) != NULL)
424					item->SetMarked(true);
425			} else
426				Quit();
427			break;
428
429		case P_FONT:
430			family = NULL;
431			style = NULL;
432			int32 family_menu_index;
433			if (msg->FindString("font", &family) == B_OK) {
434				msg->FindString("style", &style);
435				fNewFont->SetFamilyAndStyle(family, style);
436				message.what = M_FONT;
437				be_app->PostMessage(&message);
438			}
439
440			/* grab this little tidbit so we can set the correct Family */
441			if (msg->FindInt32("parent_index", &family_menu_index) == B_OK)
442				fFontMenu->ItemAt(family_menu_index)->SetMarked(true);
443			break;
444
445		case P_SIZE:
446			old_size = (int32) fNewFont->Size();
447			msg->FindInt32("size", &new_size);
448			if (old_size != new_size) {
449				fNewFont->SetSize(new_size);
450				message.what = M_FONT;
451				be_app->PostMessage(&message);
452			}
453			break;
454
455		case P_WRAP:
456			msg->FindBool("wrap", fNewWrap);
457			break;
458		case P_ATTACH_ATTRIBUTES:
459			msg->FindBool("attachAttributes", fNewAttachAttributes);
460			break;
461		case P_COLORED_QUOTES:
462			msg->FindBool("cquotes", fNewColoredQuotes);
463			break;
464		case P_ACCOUNT:
465			msg->FindInt32("id",(int32*)fNewAccount);
466			break;
467		case P_REPLYTO:
468			msg->FindInt32("replyTo", fNewReplyTo);
469			break;
470		case P_REPLY_PREAMBLE:
471		{
472			int32 index = -1;
473			if (msg->FindInt32("index", &index) < B_OK)
474				break;
475			BMenuItem *item = fReplyPreambleMenu->ItemAt(index);
476			if (item == NULL) {
477				msg->PrintToStream();
478				break;
479			}
480
481			BTextView *text = fReplyPreamble->TextView();
482			int32 selectionStart;
483			int32 selectionEnd;
484			text->GetSelection(&selectionStart, &selectionEnd);
485			if (selectionStart != selectionEnd)
486				text->Delete(selectionStart, selectionEnd);
487			text->Insert(item->Label(), 2);
488		}
489		case P_SIG:
490			free(*fNewSignature);
491			if (msg->FindString("signature", &signature) == B_NO_ERROR) {
492				*fNewSignature = (char*)malloc(strlen(signature) + 1);
493				strcpy(*fNewSignature, signature);
494			} else {
495				*fNewSignature = (char*)malloc(
496					strlen(B_TRANSLATE("None")) + 1);
497				strcpy(*fNewSignature, B_TRANSLATE("None"));
498			}
499			break;
500		case P_ENC:
501			msg->FindInt32("encoding", (int32*)fNewEncoding);
502			break;
503		case P_WARN_UNENCODABLE:
504			msg->FindBool("warnUnencodable", fNewWarnUnencodable);
505			break;
506		case P_SPELL_CHECK_START_ON:
507			msg->FindBool("spellCheckStartOn", fNewSpellCheckStartOn);
508			break;
509		case P_MARK_READ:
510			msg->FindBool("autoMarkRead", fNewAutoMarkRead);
511			be_app->PostMessage(PREFS_CHANGED);
512			break;
513		case P_BUTTON_BAR:
514			msg->FindInt8("bar", (int8*)fNewButtonBar);
515			be_app->PostMessage(PREFS_CHANGED);
516			break;
517
518		default:
519			BWindow::MessageReceived(msg);
520	}
521
522	fFont.GetFamilyAndStyle(&old_family, &old_style);
523	fNewFont->GetFamilyAndStyle(&new_family, &new_style);
524	old_size = (int32) fFont.Size();
525	new_size = (int32) fNewFont->Size();
526	bool changed = old_size != new_size
527		|| fWrap != *fNewWrap
528		|| fAttachAttributes != *fNewAttachAttributes
529		|| fColoredQuotes != *fNewColoredQuotes
530		|| fAccount != *fNewAccount
531		|| fReplyTo != *fNewReplyTo
532		|| strcmp(old_family, new_family)
533		|| strcmp(old_style, new_style)
534		|| strcmp(fReplyPreamble->Text(), *fNewPreamble)
535		|| strcmp(fSignature, *fNewSignature)
536		|| fEncoding != *fNewEncoding
537		|| fWarnUnencodable != *fNewWarnUnencodable
538		|| fSpellCheckStartOn != *fNewSpellCheckStartOn
539		|| fAutoMarkRead != *fNewAutoMarkRead
540		|| fButtonBar != *fNewButtonBar;
541	fRevert->SetEnabled(changed);
542}
543
544
545BPopUpMenu*
546TPrefsWindow::_BuildFontMenu(BFont* font)
547{
548	font_family	def_family;
549	font_style	def_style;
550	font_family	f_family;
551	font_style	f_style;
552
553	BPopUpMenu *menu = new BPopUpMenu("");
554	font->GetFamilyAndStyle(&def_family, &def_style);
555
556	int32 family_menu_index = 0;
557	int family_count = count_font_families();
558	for (int family_loop = 0; family_loop < family_count; family_loop++) {
559		get_font_family(family_loop, &f_family);
560		BMenu *family_menu = new BMenu(f_family);
561
562		int style_count = count_font_styles(f_family);
563		for (int style_loop = 0; style_loop < style_count; style_loop++) {
564			get_font_style(f_family, style_loop, &f_style);
565
566			BMessage *msg = new BMessage(P_FONT);
567			msg->AddString("font", f_family);
568			msg->AddString("style", f_style);
569			// we send this to make setting the Family easier when things
570			// change
571			msg->AddInt32("parent_index", family_menu_index);
572
573			BMenuItem *item = new BMenuItem(f_style, msg);
574			family_menu->AddItem(item);
575			if ((strcmp(def_family, f_family) == 0)
576				&& (strcmp(def_style, f_style) == 0)) {
577				item->SetMarked(true);
578			}
579
580			item->SetTarget(this);
581		}
582
583		menu->AddItem(family_menu);
584		BMenuItem *item = menu->ItemAt(family_menu_index);
585		BMessage *msg = new BMessage(P_FONT);
586		msg->AddString("font", f_family);
587
588		item->SetMessage(msg);
589		item->SetTarget(this);
590		if (strcmp(def_family, f_family) == 0)
591			item->SetMarked(true);
592
593		family_menu_index++;
594	}
595	return menu;
596}
597
598
599BPopUpMenu*
600TPrefsWindow::_BuildLevelMenu(int32 level)
601{
602	BMenuItem* item;
603	BMessage* msg;
604	BPopUpMenu* menu;
605
606	menu = new BPopUpMenu("");
607	msg = new BMessage(P_LEVEL);
608	msg->AddInt32("level", L_BEGINNER);
609	menu->AddItem(item = new BMenuItem(B_TRANSLATE("Beginner"), msg));
610	if (level == L_BEGINNER)
611		item->SetMarked(true);
612
613	msg = new BMessage(P_LEVEL);
614	msg->AddInt32("level", L_EXPERT);
615	menu->AddItem(item = new BMenuItem(B_TRANSLATE("Expert"), msg));
616	if (level == L_EXPERT)
617		item->SetMarked(true);
618
619	return menu;
620}
621
622
623BPopUpMenu*
624TPrefsWindow::_BuildAccountMenu(int32 account)
625{
626	BPopUpMenu* menu = new BPopUpMenu("");
627	BMenuItem* item;
628
629	//menu->SetRadioMode(true);
630	BMailAccounts accounts;
631	if (accounts.CountAccounts() == 0) {
632		menu->AddItem(item = new BMenuItem(B_TRANSLATE("<no account found>"), NULL));
633		item->SetEnabled(false);
634		return menu;
635	}
636
637	BMessage* msg;
638	for (int32 i = 0; i < accounts.CountAccounts(); i++) {
639		BMailAccountSettings* settings = accounts.AccountAt(i);
640		item = new BMenuItem(settings->Name(), msg = new BMessage(P_ACCOUNT));
641
642		msg->AddInt32("id", settings->AccountID());
643
644		if (account == settings->AccountID())
645			item->SetMarked(true);
646
647		menu->AddItem(item);
648	}
649	return menu;
650}
651
652
653BPopUpMenu*
654TPrefsWindow::_BuildReplyToMenu(int32 account)
655{
656	BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING);
657
658	BMenuItem* item;
659	BMessage* msg;
660	menu->AddItem(item = new BMenuItem(B_TRANSLATE("Use default account"),
661		msg = new BMessage(P_REPLYTO)));
662	msg->AddInt32("replyTo", ACCOUNT_USE_DEFAULT);
663	if (account == ACCOUNT_USE_DEFAULT)
664		item->SetMarked(true);
665
666	menu->AddItem(item = new BMenuItem(B_TRANSLATE("Account from mail"),
667		msg = new BMessage(P_REPLYTO)));
668	msg->AddInt32("replyTo", ACCOUNT_FROM_MAIL);
669	if (account == ACCOUNT_FROM_MAIL)
670		item->SetMarked(true);
671
672	return menu;
673}
674
675
676BMenu*
677TPrefsWindow::_BuildReplyPreambleMenu()
678{
679	BMenu *menu = new BMenu(B_EMPTY_STRING);
680
681	menu->AddItem(new BMenuItem(B_TRANSLATE("%n - Full name"),
682		new BMessage(P_REPLY_PREAMBLE)));
683
684	menu->AddItem(new BMenuItem(B_TRANSLATE("%e - E-mail address"),
685		new BMessage(P_REPLY_PREAMBLE)));
686
687	menu->AddItem(new BMenuItem(B_TRANSLATE("%d - Date"),
688		new BMessage(P_REPLY_PREAMBLE)));
689
690	menu->AddSeparatorItem();
691
692	menu->AddItem(new BMenuItem(B_TRANSLATE("\\n - Newline"),
693		new BMessage(P_REPLY_PREAMBLE)));
694
695	return menu;
696}
697
698
699BPopUpMenu*
700TPrefsWindow::_BuildSignatureMenu(char* sig)
701{
702	char name[B_FILE_NAME_LENGTH];
703	BEntry entry;
704	BFile file;
705	BMenuItem* item;
706	BMessage* msg;
707	BQuery query;
708	BVolume vol;
709	BVolumeRoster volume;
710
711	BPopUpMenu* menu = new BPopUpMenu("");
712
713	msg = new BMessage(P_SIG);
714	msg->AddString("signature", B_TRANSLATE("None"));
715	menu->AddItem(item = new BMenuItem(B_TRANSLATE("None"), msg));
716	if (!strcmp(sig, B_TRANSLATE("None")))
717		item->SetMarked(true);
718
719	msg = new BMessage(P_SIG);
720	msg->AddString("signature", B_TRANSLATE("Random"));
721	menu->AddItem(item = new BMenuItem(B_TRANSLATE("Random"), msg));
722	if (!strcmp(sig, B_TRANSLATE("Random")))
723		item->SetMarked(true);
724	menu->AddSeparatorItem();
725
726	volume.GetBootVolume(&vol);
727	query.SetVolume(&vol);
728	query.SetPredicate("_signature = *");
729	query.Fetch();
730
731	while (query.GetNextEntry(&entry) == B_NO_ERROR) {
732		file.SetTo(&entry, O_RDONLY);
733		if (file.InitCheck() == B_NO_ERROR) {
734			msg = new BMessage(P_SIG);
735			file.ReadAttr("_signature", B_STRING_TYPE, 0, name, sizeof(name));
736			msg->AddString("signature", name);
737			menu->AddItem(item = new BMenuItem(name, msg));
738			if (!strcmp(sig, name))
739				item->SetMarked(true);
740		}
741	}
742	return menu;
743}
744
745
746BPopUpMenu*
747TPrefsWindow::_BuildSizeMenu(BFont* font)
748{
749	char label[16];
750	uint32 loop;
751	int32 sizes[] = {9, 10, 11, 12, 14, 18, 24};
752	float size;
753	BMenuItem* item;
754	BMessage* msg;
755	BPopUpMenu* menu;
756
757	menu = new BPopUpMenu("");
758	size = font->Size();
759	for (loop = 0; loop < sizeof(sizes) / sizeof(int32); loop++) {
760		msg = new BMessage(P_SIZE);
761		msg->AddInt32("size", sizes[loop]);
762		sprintf(label, "%ld", sizes[loop]);
763		menu->AddItem(item = new BMenuItem(label, msg));
764		if (sizes[loop] == (int32)size)
765			item->SetMarked(true);
766	}
767	return menu;
768}
769
770
771BPopUpMenu*
772TPrefsWindow::_BuildBoolMenu(uint32 what, const char* boolItem, bool isTrue)
773{
774	BMenuItem* item;
775	BMessage* msg;
776	BPopUpMenu* menu;
777
778	menu = new BPopUpMenu("");
779	msg = new BMessage(what);
780	msg->AddBool(boolItem, true);
781	menu->AddItem(item = new BMenuItem(B_TRANSLATE("On"), msg));
782	if (isTrue)
783		item->SetMarked(true);
784
785	msg = new BMessage(what);
786	msg->AddInt32(boolItem, false);
787	menu->AddItem(item = new BMenuItem(B_TRANSLATE("Off"), msg));
788	if (!isTrue)
789		item->SetMarked(true);
790
791	return menu;
792}
793
794
795BPopUpMenu*
796TPrefsWindow::_BuildWrapMenu(bool wrap)
797{
798	return _BuildBoolMenu(P_WRAP, "wrap", wrap);
799}
800
801
802BPopUpMenu*
803TPrefsWindow::_BuildAttachAttributesMenu(bool attachAttributes)
804{
805	BMenuItem* item;
806	BMessage* msg;
807	BPopUpMenu* menu;
808
809	menu = new BPopUpMenu("");
810	msg = new BMessage(P_ATTACH_ATTRIBUTES);
811	msg->AddBool("attachAttributes", true);
812	menu->AddItem(item = new BMenuItem(
813		B_TRANSLATE("Include file attributes in attachments"), msg));
814	if (attachAttributes)
815		item->SetMarked(true);
816
817	msg = new BMessage(P_ATTACH_ATTRIBUTES);
818	msg->AddInt32("attachAttributes", false);
819	menu->AddItem(item = new BMenuItem(
820		B_TRANSLATE("No file attributes, just plain data"), msg));
821	if (!attachAttributes)
822		item->SetMarked(true);
823
824	return menu;
825}
826
827
828BPopUpMenu*
829TPrefsWindow::_BuildColoredQuotesMenu(bool quote)
830{
831	return _BuildBoolMenu(P_COLORED_QUOTES, "cquotes", quote);
832}
833
834
835BPopUpMenu*
836TPrefsWindow::_BuildEncodingMenu(uint32 encoding)
837{
838	BMenuItem* item;
839	BMessage* msg;
840	BPopUpMenu* menu;
841
842	menu = new BPopUpMenu("");
843
844	BCharacterSetRoster roster;
845	BCharacterSet charset;
846	while (roster.GetNextCharacterSet(&charset) == B_NO_ERROR) {
847		BString name(charset.GetPrintName());
848		const char* mime = charset.GetMIMEName();
849		if (mime)
850			name << " (" << mime << ")";
851		msg = new BMessage(P_ENC);
852		uint32 convert_id;
853		if ((mime == 0) || (strcasecmp(mime, "UTF-8") != 0))
854			convert_id = charset.GetConversionID();
855		else
856			convert_id = B_MAIL_UTF8_CONVERSION;
857		msg->AddInt32("encoding", convert_id);
858		menu->AddItem(item = new BMenuItem(name.String(), msg));
859		if (convert_id == encoding)
860			item->SetMarked(true);
861	}
862
863	msg = new BMessage(P_ENC);
864	msg->AddInt32("encoding", B_MAIL_US_ASCII_CONVERSION);
865	menu->AddItem(item = new BMenuItem("US-ASCII", msg));
866	if (encoding == B_MAIL_US_ASCII_CONVERSION)
867		item->SetMarked(true);
868
869	return menu;
870}
871
872
873BPopUpMenu*
874TPrefsWindow::_BuildWarnUnencodableMenu(bool warnUnencodable)
875{
876	return _BuildBoolMenu(P_WARN_UNENCODABLE, "warnUnencodable",
877		warnUnencodable);
878}
879
880
881BPopUpMenu*
882TPrefsWindow::_BuildSpellCheckStartOnMenu(bool spellCheckStartOn)
883{
884	return _BuildBoolMenu(P_SPELL_CHECK_START_ON, "spellCheckStartOn",
885		spellCheckStartOn);
886}
887
888
889BPopUpMenu*
890TPrefsWindow::_BuildAutoMarkReadMenu(bool autoMarkRead)
891{
892	return _BuildBoolMenu(P_MARK_READ, "autoMarkRead",
893		autoMarkRead);
894}
895
896
897BPopUpMenu*
898TPrefsWindow::_BuildButtonBarMenu(uint8 show)
899{
900	BMenuItem* item;
901	BMessage* msg;
902	BPopUpMenu* menu = new BPopUpMenu("");
903
904	msg = new BMessage(P_BUTTON_BAR);
905	msg->AddInt8("bar", 1);
906	menu->AddItem(item = new BMenuItem(
907		B_TRANSLATE("Show icons & labels"), msg));
908	if (show & 1)
909		item->SetMarked(true);
910
911	msg = new BMessage(P_BUTTON_BAR);
912	msg->AddInt8("bar", 2);
913	menu->AddItem(item = new BMenuItem(B_TRANSLATE("Show icons only"), msg));
914	if (show & 2)
915		item->SetMarked(true);
916
917	msg = new BMessage(P_BUTTON_BAR);
918	msg->AddInt8("bar", 0);
919	menu->AddItem(item = new BMenuItem(B_TRANSLATE("Hide"), msg));
920	if (!show)
921		item->SetMarked(true);
922
923	return menu;
924}
925
926