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