xref: /haiku/src/apps/terminal/AppearPrefView.cpp (revision 4e3137c085bae361922078f123dceb92da700640)
1 /*
2  * Copyright 2001-2015, Haiku, Inc.
3  * Copyright 2003-2004 Kian Duffy, myob@users.sourceforge.net
4  * Parts Copyright 1998-1999 Kazuho Okui and Takashi Murai.
5  * All rights reserved. Distributed under the terms of the MIT license.
6  */
7 
8 
9 #include "AppearPrefView.h"
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 
14 #include <Button.h>
15 #include <Catalog.h>
16 #include <CharacterSet.h>
17 #include <CharacterSetRoster.h>
18 #include <CheckBox.h>
19 #include <ColorControl.h>
20 #include <LayoutBuilder.h>
21 #include <Locale.h>
22 #include <Menu.h>
23 #include <MenuField.h>
24 #include <MenuItem.h>
25 #include <PopUpMenu.h>
26 #include <TextControl.h>
27 #include <View.h>
28 
29 #include "Colors.h"
30 #include "Globals.h"
31 #include "PrefHandler.h"
32 #include "TermConst.h"
33 #include "TermWindow.h"
34 
35 
36 #undef B_TRANSLATION_CONTEXT
37 #define B_TRANSLATION_CONTEXT "Terminal AppearancePrefView"
38 
39 
40 
41 // #pragma mark -
42 
43 
44 AppearancePrefView::AppearancePrefView(const char* name,
45 		const BMessenger& messenger)
46 	:
47 	BGroupView(name, B_VERTICAL, 5),
48 	fTerminalMessenger(messenger)
49 {
50 	const char* kColorTable[] = {
51 		B_TRANSLATE_MARK("Text"),
52 		B_TRANSLATE_MARK("Background"),
53 		B_TRANSLATE_MARK("Cursor"),
54 		B_TRANSLATE_MARK("Text under cursor"),
55 		B_TRANSLATE_MARK("Selected text"),
56 		B_TRANSLATE_MARK("Selected background"),
57 		NULL
58 	};
59 
60 	fBlinkCursor = new BCheckBox(
61 		B_TRANSLATE("Blinking cursor"),
62 			new BMessage(MSG_BLINK_CURSOR_CHANGED));
63 
64 	fBrightInsteadOfBold = new BCheckBox(
65 		B_TRANSLATE("Use bright instead of bold text"),
66 			new BMessage(MSG_BRIGHT_INSTEAD_OF_BOLD_CHANGED));
67 
68 	fWarnOnExit = new BCheckBox(
69 		B_TRANSLATE("Confirm exit if active programs exist"),
70 			new BMessage(MSG_WARN_ON_EXIT_CHANGED));
71 
72 	BMenu* fontMenu = _MakeFontMenu(MSG_HALF_FONT_CHANGED,
73 		PrefHandler::Default()->getString(PREF_HALF_FONT_FAMILY),
74 		PrefHandler::Default()->getString(PREF_HALF_FONT_STYLE));
75 	fFontField = new BMenuField(B_TRANSLATE("Font:"), fontMenu);
76 
77 	BMenu* sizeMenu = new (std::nothrow) BPopUpMenu(
78 		B_TRANSLATE_COMMENT("Custom", "Window size"));
79 	if (sizeMenu != NULL) {
80 		TermWindow::MakeWindowSizeMenu(sizeMenu);
81 		sizeMenu->SetLabelFromMarked(true);
82 	}
83 	fWindowSizeField = new BMenuField(B_TRANSLATE("Window size:"), sizeMenu);
84 
85 	BMenu* encodingMenu = new (std::nothrow) BPopUpMenu("Text encoding");
86 	if (encodingMenu != NULL) {
87 		TermWindow::MakeEncodingMenu(encodingMenu);
88 		encodingMenu->SetLabelFromMarked(true);
89 	}
90 	fEncodingField = new BMenuField(B_TRANSLATE("Encoding:"), encodingMenu);
91 
92 	BPopUpMenu* schemesPopUp = _MakeColorSchemeMenu(MSG_COLOR_SCHEME_CHANGED,
93 		gPredefinedColorSchemes, gPredefinedColorSchemes[0]);
94 	fColorSchemeField = new BMenuField(B_TRANSLATE("Color scheme:"),
95 		schemesPopUp);
96 
97 	BPopUpMenu* colorsPopUp = _MakeMenu(MSG_COLOR_FIELD_CHANGED, kColorTable,
98 		kColorTable[0]);
99 
100 	fColorField = new BMenuField(B_TRANSLATE("Color:"), colorsPopUp);
101 
102 	fTabTitle = new BTextControl("tabTitle", B_TRANSLATE("Tab title:"), "",
103 		NULL);
104 	fTabTitle->SetModificationMessage(
105 		new BMessage(MSG_TAB_TITLE_SETTING_CHANGED));
106 	fTabTitle->SetToolTip(BString(B_TRANSLATE(
107 		"The pattern specifying the tab titles. The following placeholders\n"
108 		"can be used:")) << "\n" << kTooTipSetTabTitlePlaceholders
109 		<< "\n" << kToolTipCommonTitlePlaceholders);
110 
111 	fWindowTitle = new BTextControl("windowTitle", B_TRANSLATE("Window title:"),
112 		"", NULL);
113 	fWindowTitle->SetModificationMessage(
114 		new BMessage(MSG_WINDOW_TITLE_SETTING_CHANGED));
115 	fWindowTitle->SetToolTip(BString(B_TRANSLATE(
116 		"The pattern specifying the window titles. The following placeholders\n"
117 		"can be used:")) << "\n" << kTooTipSetWindowTitlePlaceholders
118 		<< "\n" << kToolTipCommonTitlePlaceholders);
119 
120 	BLayoutBuilder::Group<>(this)
121 		.SetInsets(5, 5, 5, 5)
122 		.AddGrid(5, 5)
123 			.Add(fTabTitle->CreateLabelLayoutItem(), 0, 0)
124 			.Add(fTabTitle->CreateTextViewLayoutItem(), 1, 0)
125 			.Add(fWindowTitle->CreateLabelLayoutItem(), 0, 1)
126 			.Add(fWindowTitle->CreateTextViewLayoutItem(), 1, 1)
127 			.Add(fWindowSizeField->CreateLabelLayoutItem(), 0, 2)
128 			.Add(fWindowSizeField->CreateMenuBarLayoutItem(), 1, 2)
129 			.Add(fFontField->CreateLabelLayoutItem(), 0, 3)
130 			.Add(fFontField->CreateMenuBarLayoutItem(), 1, 3)
131 			.Add(fEncodingField->CreateLabelLayoutItem(), 0, 4)
132 			.Add(fEncodingField->CreateMenuBarLayoutItem(), 1, 4)
133 			.Add(fColorSchemeField->CreateLabelLayoutItem(), 0, 5)
134 			.Add(fColorSchemeField->CreateMenuBarLayoutItem(), 1, 5)
135 			.Add(fColorField->CreateLabelLayoutItem(), 0, 6)
136 			.Add(fColorField->CreateMenuBarLayoutItem(), 1, 6)
137 			.End()
138 		.AddGlue()
139 		.Add(fColorControl = new BColorControl(BPoint(10, 10),
140 			B_CELLS_32x8, 8.0, "", new BMessage(MSG_COLOR_CHANGED)))
141 		.Add(fBlinkCursor)
142 		.Add(fBrightInsteadOfBold)
143 		.Add(fWarnOnExit);
144 
145 	fTabTitle->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
146 	fWindowTitle->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
147 	fFontField->SetAlignment(B_ALIGN_RIGHT);
148 	fWindowSizeField->SetAlignment(B_ALIGN_RIGHT);
149 	fEncodingField->SetAlignment(B_ALIGN_RIGHT);
150 	fColorField->SetAlignment(B_ALIGN_RIGHT);
151 	fColorSchemeField->SetAlignment(B_ALIGN_RIGHT);
152 
153 	Revert();
154 
155 	BTextControl* redInput = (BTextControl*)fColorControl->ChildAt(0);
156 	BTextControl* greenInput = (BTextControl*)fColorControl->ChildAt(1);
157 	BTextControl* blueInput = (BTextControl*)fColorControl->ChildAt(2);
158 
159 	redInput->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
160 	greenInput->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
161 	blueInput->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
162 }
163 
164 
165 void
166 AppearancePrefView::Revert()
167 {
168 	PrefHandler* pref = PrefHandler::Default();
169 
170 	fTabTitle->SetText(pref->getString(PREF_TAB_TITLE));
171 	fWindowTitle->SetText(pref->getString(PREF_WINDOW_TITLE));
172 
173 	fBlinkCursor->SetValue(pref->getBool(PREF_BLINK_CURSOR));
174 	fBrightInsteadOfBold->SetValue(pref->getBool(PREF_BRIGHT_INSTEAD_OF_BOLD));
175 	fWarnOnExit->SetValue(pref->getBool(PREF_WARN_ON_EXIT));
176 
177 	_SetCurrentColorScheme();
178 	_SetEncoding(pref->getString(PREF_TEXT_ENCODING));
179 	_SetWindowSize(pref->getInt32(PREF_ROWS), pref->getInt32(PREF_COLS));
180 	fColorControl->SetValue(pref->getRGB(PREF_TEXT_FORE_COLOR));
181 
182 	const char* family = pref->getString(PREF_HALF_FONT_FAMILY);
183 	const char* style = pref->getString(PREF_HALF_FONT_STYLE);
184 	const char* size = pref->getString(PREF_HALF_FONT_SIZE);
185 
186 	_MarkSelectedFont(family, style, size);
187 }
188 
189 
190 void
191 AppearancePrefView::AttachedToWindow()
192 {
193 	fTabTitle->SetTarget(this);
194 	fWindowTitle->SetTarget(this);
195 	fBlinkCursor->SetTarget(this);
196 	fBrightInsteadOfBold->SetTarget(this);
197 	fWarnOnExit->SetTarget(this);
198 
199 	fFontField->Menu()->SetTargetForItems(this);
200 	for (int32 i = 0; i < fFontField->Menu()->CountItems(); i++) {
201 		BMenu* fontSizeMenu = fFontField->Menu()->SubmenuAt(i);
202 		if (fontSizeMenu == NULL)
203 			continue;
204 
205 		fontSizeMenu->SetTargetForItems(this);
206 	}
207 
208 	fColorControl->SetTarget(this);
209 	fColorField->Menu()->SetTargetForItems(this);
210 	fColorSchemeField->Menu()->SetTargetForItems(this);
211 	fWindowSizeField->Menu()->SetTargetForItems(this);
212 	fEncodingField->Menu()->SetTargetForItems(this);
213 
214 	_SetCurrentColorScheme();
215 }
216 
217 
218 void
219 
220 AppearancePrefView::MessageReceived(BMessage* msg)
221 {
222 	bool modified = false;
223 
224 	switch (msg->what) {
225 		case MSG_HALF_FONT_CHANGED:
226 		{
227 			const char* family = NULL;
228 			const char* style = NULL;
229 			const char* size = NULL;
230 			if (msg->FindString("font_family", &family) != B_OK
231 				|| msg->FindString("font_style", &style) != B_OK
232 				|| msg->FindString("font_size", &size) != B_OK) {
233 				break;
234 			}
235 
236 			PrefHandler* pref = PrefHandler::Default();
237 			const char* currentFamily
238 				= pref->getString(PREF_HALF_FONT_FAMILY);
239 			const char* currentStyle
240 				= pref->getString(PREF_HALF_FONT_STYLE);
241 			const char* currentSize
242 				= pref->getString(PREF_HALF_FONT_SIZE);
243 
244 			if (currentFamily == NULL || strcmp(currentFamily, family) != 0
245 				|| currentStyle == NULL || strcmp(currentStyle, style) != 0
246 				|| currentSize == NULL || strcmp(currentSize, size) != 0) {
247 				pref->setString(PREF_HALF_FONT_FAMILY, family);
248 				pref->setString(PREF_HALF_FONT_STYLE, style);
249 				pref->setString(PREF_HALF_FONT_SIZE, size);
250 				_MarkSelectedFont(family, style, size);
251 				modified = true;
252 			}
253 			break;
254 		}
255 
256 		case MSG_COLOR_CHANGED:
257 		{
258 			const BMessage* itemMessage
259 				= fColorField->Menu()->FindMarked()->Message();
260 			const char* label = NULL;
261 			if (itemMessage->FindString("label", &label) != B_OK)
262 				break;
263 			rgb_color oldColor = PrefHandler::Default()->getRGB(label);
264 			if (oldColor != fColorControl->ValueAsColor()) {
265 				BMenuItem* item = fColorSchemeField->Menu()->FindMarked();
266 				if (strcmp(item->Label(), gCustomColorScheme.name) != 0) {
267 					item->SetMarked(false);
268 					item = fColorSchemeField->Menu()->FindItem(
269 						gCustomColorScheme.name);
270 					if (item)
271 						item->SetMarked(true);
272 				}
273 
274 				PrefHandler::Default()->setRGB(label,
275 					fColorControl->ValueAsColor());
276 				modified = true;
277 			}
278 			break;
279 		}
280 
281 		case MSG_COLOR_SCHEME_CHANGED:
282 		{
283 			color_scheme* newScheme = NULL;
284 			if (msg->FindPointer("color_scheme",
285 					(void**)&newScheme) == B_OK) {
286 				_ChangeColorScheme(newScheme);
287 				const char* label = NULL;
288 				if (fColorField->Menu()->FindMarked()->Message()->FindString(
289 						"label", &label) == B_OK)
290 					fColorControl->SetValue(
291 						PrefHandler::Default()->getRGB(label));
292 				modified = true;
293 			}
294 			break;
295 		}
296 
297 		case MSG_COLOR_FIELD_CHANGED:
298 		{
299 			const char* label = NULL;
300 			if (msg->FindString("label", &label) == B_OK)
301 				fColorControl->SetValue(PrefHandler::Default()->getRGB(label));
302 			break;
303 		}
304 
305 		case MSG_COLS_CHANGED:
306 		{
307 			int rows = msg->FindInt32("rows");
308 			int columns = msg->FindInt32("columns");
309 			_SetWindowSize(rows, columns);
310 			PrefHandler* handler = PrefHandler::Default();
311 			if (handler->getInt32(PREF_ROWS) != rows) {
312 				PrefHandler::Default()->setInt32(PREF_ROWS, rows);
313 				modified = true;
314 			}
315 			if (handler->getInt32(PREF_COLS) != columns) {
316 				PrefHandler::Default()->setInt32(PREF_COLS, columns);
317 				modified = true;
318 			}
319 
320 			break;
321 		}
322 
323 		case MSG_BLINK_CURSOR_CHANGED:
324 			if (PrefHandler::Default()->getBool(PREF_BLINK_CURSOR)
325 				!= fBlinkCursor->Value()) {
326 					PrefHandler::Default()->setBool(PREF_BLINK_CURSOR,
327 						fBlinkCursor->Value());
328 					modified = true;
329 			}
330 			break;
331 
332 		case MSG_BRIGHT_INSTEAD_OF_BOLD_CHANGED:
333 			if (PrefHandler::Default()->getBool(PREF_BRIGHT_INSTEAD_OF_BOLD)
334 				!= fBrightInsteadOfBold->Value()) {
335 					PrefHandler::Default()->setBool(PREF_BRIGHT_INSTEAD_OF_BOLD,
336 						fBrightInsteadOfBold->Value());
337 					modified = true;
338 			}
339 			break;
340 
341 		case MSG_WARN_ON_EXIT_CHANGED:
342 			if (PrefHandler::Default()->getBool(PREF_WARN_ON_EXIT)
343 				!= fWarnOnExit->Value()) {
344 					PrefHandler::Default()->setBool(PREF_WARN_ON_EXIT,
345 						fWarnOnExit->Value());
346 					modified = true;
347 			}
348 			break;
349 
350 		case MSG_TAB_TITLE_SETTING_CHANGED:
351 		{
352 			BString oldValue(PrefHandler::Default()->getString(PREF_TAB_TITLE));
353 			if (oldValue != fTabTitle->Text()) {
354 				PrefHandler::Default()->setString(PREF_TAB_TITLE,
355 					fTabTitle->Text());
356 				modified = true;
357 			}
358 			break;
359 		}
360 
361 		case MSG_WINDOW_TITLE_SETTING_CHANGED:
362 		{
363 			BString oldValue(PrefHandler::Default()->getString(
364 				PREF_WINDOW_TITLE));
365 			if (oldValue != fWindowTitle->Text()) {
366 				PrefHandler::Default()->setString(PREF_WINDOW_TITLE,
367 					fWindowTitle->Text());
368 				modified = true;
369 			}
370 			break;
371 		}
372 
373 		default:
374 			BView::MessageReceived(msg);
375 			return;
376 	}
377 
378 	if (modified) {
379 		fTerminalMessenger.SendMessage(msg);
380 
381 		BMessenger messenger(this);
382 		messenger.SendMessage(MSG_PREF_MODIFIED);
383 	}
384 }
385 
386 
387 void
388 AppearancePrefView::_ChangeColorScheme(color_scheme* scheme)
389 {
390 	PrefHandler* pref = PrefHandler::Default();
391 
392 	pref->setRGB(PREF_TEXT_FORE_COLOR, scheme->text_fore_color);
393 	pref->setRGB(PREF_TEXT_BACK_COLOR, scheme->text_back_color);
394 	pref->setRGB(PREF_SELECT_FORE_COLOR, scheme->select_fore_color);
395 	pref->setRGB(PREF_SELECT_BACK_COLOR, scheme->select_back_color);
396 	pref->setRGB(PREF_CURSOR_FORE_COLOR, scheme->cursor_fore_color);
397 	pref->setRGB(PREF_CURSOR_BACK_COLOR, scheme->cursor_back_color);
398 }
399 
400 
401 void
402 AppearancePrefView::_SetCurrentColorScheme()
403 {
404 	PrefHandler* pref = PrefHandler::Default();
405 
406 	gCustomColorScheme.text_fore_color = pref->getRGB(PREF_TEXT_FORE_COLOR);
407 	gCustomColorScheme.text_back_color = pref->getRGB(PREF_TEXT_BACK_COLOR);
408 	gCustomColorScheme.select_fore_color = pref->getRGB(PREF_SELECT_FORE_COLOR);
409 	gCustomColorScheme.select_back_color = pref->getRGB(PREF_SELECT_BACK_COLOR);
410 	gCustomColorScheme.cursor_fore_color = pref->getRGB(PREF_CURSOR_FORE_COLOR);
411 	gCustomColorScheme.cursor_back_color = pref->getRGB(PREF_CURSOR_BACK_COLOR);
412 
413 	const char* currentSchemeName = NULL;
414 
415 	for (const color_scheme** schemes = gPredefinedColorSchemes;
416 			*schemes != NULL; schemes++) {
417 		if (gCustomColorScheme == **schemes) {
418 			currentSchemeName = (*schemes)->name;
419 			break;
420 		}
421 	}
422 
423 	// If the scheme is not one of the known ones, assume a custom one.
424 	if (currentSchemeName == NULL)
425 		currentSchemeName = "Custom";
426 
427 	for (int32 i = 0; i < fColorSchemeField->Menu()->CountItems(); i++) {
428 		BMenuItem* item = fColorSchemeField->Menu()->ItemAt(i);
429 		if (strcmp(item->Label(), currentSchemeName) == 0) {
430 			item->SetMarked(true);
431 			break;
432 		}
433 	}
434 }
435 
436 
437 void
438 AppearancePrefView::_SetEncoding(const char* name)
439 {
440 	const BPrivate::BCharacterSet* charset
441 		= BPrivate::BCharacterSetRoster::FindCharacterSetByName(name);
442 	if (charset == NULL)
443 		return;
444 	int code = charset->GetConversionID();
445 	for (int32 i = 0; i < fEncodingField->Menu()->CountItems(); i++) {
446 		BMenuItem* item = fEncodingField->Menu()->ItemAt(i);
447 		BMessage* msg = item->Message();
448 		if (msg->FindInt32("op") == code) {
449 			item->SetMarked(true);
450 			break;
451 		}
452 	}
453 }
454 
455 
456 void
457 AppearancePrefView::_SetWindowSize(int rows, int cols)
458 {
459 	for (int32 i = 0; i < fWindowSizeField->Menu()->CountItems(); i++) {
460 		BMenuItem* item = fWindowSizeField->Menu()->ItemAt(i);
461 		BMessage* msg = item->Message();
462 		if (msg->FindInt32("rows") == rows && msg->FindInt32("columns") == cols) {
463 			item->SetMarked(true);
464 			break;
465 		}
466 	}
467 }
468 
469 
470 /*static*/ BMenu*
471 AppearancePrefView::_MakeFontMenu(uint32 command,
472 	const char* defaultFamily, const char* defaultStyle)
473 {
474 	BPopUpMenu* menu = new BPopUpMenu("");
475 	int32 numFamilies = count_font_families();
476 	for (int32 i = 0; i < numFamilies; i++) {
477 		font_family family;
478 		uint32 flags;
479 		if (get_font_family(i, &family, &flags) == B_OK) {
480 			BFont font;
481 			font_style style;
482 			int32 numStyles = count_font_styles(family);
483 			for (int32 j = 0; j < numStyles; j++) {
484 				if (get_font_style(family, j, &style) == B_OK) {
485 					font.SetFamilyAndStyle(family, style);
486 					if (IsFontUsable(font)) {
487 						BMessage* message = new BMessage(command);
488 						const char* size
489 							= PrefHandler::Default()->getString(PREF_HALF_FONT_SIZE);
490 						message->AddString("font_family", family);
491 						message->AddString("font_style", style);
492 						message->AddString("font_size", size);
493 						char fontMenuLabel[134];
494 						snprintf(fontMenuLabel, sizeof(fontMenuLabel),
495 							"%s - %s", family, style);
496 						BMenu* fontSizeMenu = _MakeFontSizeMenu(fontMenuLabel,
497 							MSG_HALF_FONT_CHANGED, family, style, size);
498 						BMenuItem* item = new BMenuItem(fontSizeMenu, message);
499 						menu->AddItem(item);
500 						if (strcmp(defaultFamily, family) == 0
501 							&& strcmp(defaultStyle, style) == 0)
502 							item->SetMarked(true);
503 					}
504 				}
505 			}
506 		}
507 	}
508 
509 	if (menu->FindMarked() == NULL)
510 		menu->ItemAt(0)->SetMarked(true);
511 
512 	return menu;
513 }
514 
515 
516 /*static*/ BMenu*
517 AppearancePrefView::_MakeFontSizeMenu(const char* label, uint32 command,
518 	const char* family, const char* style, const char* size)
519 {
520 	BMenu* menu = new BMenu(label);
521 	menu->SetRadioMode(true);
522 	menu->SetLabelFromMarked(false);
523 
524 	int32 sizes[] = {
525 		8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 0
526 	};
527 
528 	bool found = false;
529 
530 	for (uint32 i = 0; sizes[i]; i++) {
531 		BString fontSize;
532 		fontSize << sizes[i];
533 		BMessage* message = new BMessage(command);
534 		message->AddString("font_family", family);
535 		message->AddString("font_style", style);
536 		message->AddString("font_size", fontSize.String());
537 		BMenuItem* item = new BMenuItem(fontSize.String(), message);
538 		menu->AddItem(item);
539 		if (sizes[i] == atoi(size)) {
540 			item->SetMarked(true);
541 			found = true;
542 		}
543 	}
544 
545 	if (!found) {
546 		for (uint32 i = 0; sizes[i]; i++) {
547 			if (sizes[i] > atoi(size)) {
548 				BMessage* message = new BMessage(command);
549 				message->AddString("font_family", family);
550 				message->AddString("font_style", style);
551 				message->AddString("font_size", size);
552 				BMenuItem* item = new BMenuItem(size, message);
553 				item->SetMarked(true);
554 				menu->AddItem(item, i);
555 				break;
556 			}
557 		}
558 	}
559 
560 	return menu;
561 }
562 
563 
564 /*static*/ BPopUpMenu*
565 AppearancePrefView::_MakeMenu(uint32 msg, const char** items,
566 	const char* defaultItemName)
567 {
568 	BPopUpMenu* menu = new BPopUpMenu("");
569 
570 	while (*items) {
571 		if (strcmp((*items), "") == 0)
572 			menu->AddSeparatorItem();
573 		else {
574 			BMessage* message = new BMessage(msg);
575 			message->AddString("label", *items);
576 			BMenuItem* item = new BMenuItem(B_TRANSLATE(*items), message);
577 			menu->AddItem(item);
578 			if (strcmp(*items, defaultItemName) == 0)
579 				item->SetMarked(true);
580 		}
581 
582 		items++;
583 	}
584 
585 	return menu;
586 }
587 
588 
589 /*static*/ BPopUpMenu*
590 AppearancePrefView::_MakeColorSchemeMenu(uint32 msg, const color_scheme** items,
591 	const color_scheme* defaultItemName)
592 {
593 	BPopUpMenu* menu = new BPopUpMenu("");
594 
595 	int32 i = 0;
596 	while (*items) {
597 		if (strcmp((*items)->name, "") == 0)
598 			menu->AddSeparatorItem();
599 		else {
600 			BMessage* message = new BMessage(msg);
601 			message->AddPointer("color_scheme", (const void*)*items);
602 			menu->AddItem(new BMenuItem((*items)->name, message));
603 		}
604 
605 		items++;
606 		i++;
607 	}
608 	return menu;
609 }
610 
611 
612 void
613 AppearancePrefView::_MarkSelectedFont(const char* family, const char* style,
614 	const char* size)
615 {
616 	char fontMenuLabel[134];
617 	snprintf(fontMenuLabel, sizeof(fontMenuLabel), "%s - %s", family, style);
618 
619 	// mark the selected font
620 	BMenuItem* selectedFont = fFontField->Menu()->FindItem(fontMenuLabel);
621 	if (selectedFont != NULL)
622 		selectedFont->SetMarked(true);
623 
624 	// mark the selected font size on all font menus
625 	for (int32 i = 0; i < fFontField->Menu()->CountItems(); i++) {
626 		BMenu* fontSizeMenu = fFontField->Menu()->SubmenuAt(i);
627 		if (fontSizeMenu == NULL)
628 			continue;
629 
630 		BMenuItem* item = fontSizeMenu->FindItem(size);
631 		if (item != NULL)
632 			item->SetMarked(true);
633 	}
634 }
635